# NousResearch/hermes-agent · '/compress' command not routed correctly in Desktop TUI

## Open now

- Nothing open on GitHub.

Multiple bug reports and fix attempts address the same issue: the /compress command in the Desktop/TUI interface fails because command.dispatch does not route it to the correct handler, instead returning a 'not a quick/plugin/skill command' error. The members represent the bug and various proposed or competing fixes for this routing gap.

## TL;DR

- 13 member(s): 0 open issue(s), 4 closed issue(s), 0 open PR(s), 2 merged PR(s), 7 PR(s) closed without merging.
- A fix was merged to main in PR #60921. Verify it addresses your case.
- **Recommended:** read PR #60921 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `partially_resolved` · deciding PR(s): `pr-60921,pr-68229`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_PARTIAL`): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
- Members outside that structural core may belong to a different underlying problem.
- Pairwise link density `0.14`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #44456: \[Bug\]: Desktop /compress returns "not a quick/plugin/skill command: compress" — TUI command.dispatch doesn't redirect built-ins to slash.exec
- #46556: Desktop GUI: /compress command not recognized (routed to quick/plugin/skill handler)
- #60603: \[Bug\]: When using Hermes Desktop, if you want to actively compress the context during a conversation, you can use the '/compress' command, but it will display '/compress·error: not a quick/plugin/skill command: compress'
- #60705: Desktop: /compress fails with 'not a quick/plugin/skill command: compress'

## Prior & competing PRs

- **#44464: fix(tui-gateway): route /compress through command.dispatch for Desktop/TUI**. closed without merge · fix tier `suggested`
  - maintainer direction: category `superseded_by_pr`; implication `superseded`; refs `#44462`, `#44462`
  - _suggested-tier fix detail withheld; re-request with `?tier=all` to include it._
- **#60834: fix(tui): route /compress through command.dispatch with server-side compression**. closed without merge · fix tier `suggested`
  - maintainer direction: category `superseded_by_pr`; implication `superseded`; refs `#60644`, `#60603`, `#60644`
  - _suggested-tier fix detail withheld; re-request with `?tier=all` to include it._
- **#60921: fix(desktop): register /compress in TUI gateway command.dispatch (salvage #60644)**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`; implication `superseded`
  - files: `tui_gateway/server.py`
  - fix hunks:
  - `tui_gateway/server.py`

    ```diff
    @@ -11428,6 +11428,8 @@ def _(rid, params: dict) -> dict:
             "moa",
             "undo",
             "learn",
    +        "compress",
    +        "compact",
         }
     )
     
    ```

    ```diff
    @@ -12013,6 +12015,72 @@ def _(rid, params: dict) -> dict:
                     },
                 )
     
    +    if name in {"compress", "compact"}:
    +        if not session:
    +            return _err(rid, 4001, "no active session to compress")
    +        if session.get("running"):
    +            return _err(
    +                rid, 4009, "session busy — /interrupt the current turn before /compress"
    +            )
    +        sid = params.get("session_id", "")
    +        try:
    +            from agent.manual_compression_feedback import summarize_manual_compression
    +            from agent.model_metadata import estimate_request_tokens_rough
    +
    +            with session["history_lock"]:
    +                before_messages = list(session.get("history", []))
    +                history_version = int(session.get("history_version", 0))
    +            before_count = len(before_messages)
    +            _agent = session["agent"]
    +            _sys_prompt = getattr(_agent, "_cached_system_prompt", "") or ""
    +            _tools = getattr(_agent, "tools", None) or None
    +            before_tokens = (
    +                estimate_request_tokens_rough(
    +                    before_messages, system_prompt=_sys_prompt, tools=_tools
    +                )
    +                if before_count
    +                else 0
    +            )
    +            removed, usage = _compress_session_history(
    +                session,
    +                arg.strip() or None,
    +                approx_tokens=[redacted:secret-assignment]
    +                before_messages=before_messages,
    +                history_version=history_version,
    +            )
    +            with session["history_lock"]:
    +                after_messages = list(session.get("history", []))
    +            after_count = len(after_messages)
    +            _sys_prompt_after = (
    +                getattr(_agent, "_cached_system_prompt", "") or _sys_prompt
    +            )
    +            _tools_after = getattr(_agent, "tools", None) or _tools
    +            after_tokens = (
    +                estimate_request_tokens_rough(
    +                    after_messages,
    +                    system_prompt=_sys_prompt_after,
    +                    tools=_tools_after,
    +                )
    +                if after_count
    +                else 0
    +            )
    +            _sync_session_key_after_compress(sid, session)
    +            summary = summarize_manual_compression(
    +                before_messages, after_messages, before_tokens, after_tokens
    +            )
    +            _emit("session.info", sid, _session_info(session.get("agent"), session))
    +            return _ok(
    +                rid,
    +                {
    +                    "type": "exec",
    +                    "output": "\n".join(
    +                        filter(None, [summary["headline"], summary["token_line"], summary.get("note")])
    +                    ),
    +                },
    +            )
    +        except Exception as exc:
    +            return _err(rid, 5009, f"compress failed: {exc}")
    +
         return _err(rid, 4018, f"not a quick/plugin/skill command: {name}")
     
     
    ```
- **#68229: fix(desktop): salvage /compress cluster — session.compress RPC + dedicated RPC routing**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`; implication `superseded`
  - files: `apps/desktop/src/app/session/hooks/use-prompt-actions/index.test.tsx`, `apps/desktop/src/app/session/hooks/use-prompt-actions/index.ts`, `apps/desktop/src/app/session/hooks/use-prompt-actions/slash.ts`, `apps/desktop/src/app/session/hooks/use-prompt-actions/utils.test.ts`, `apps/desktop/src/app/session/hooks/use-prompt-actions/utils.ts`, `apps/desktop/src/app/settings/toolset-config-panel.test.tsx`, `apps/desktop/src/app/settings/toolset-config-panel.tsx`, `apps/desktop/src/app/types.ts`, `apps/desktop/src/lib/desktop-git.test.ts`, `apps/desktop/src/lib/desktop-git.ts`, `apps/desktop/src/lib/desktop-slash-commands.test.ts`, `apps/desktop/src/lib/desktop-slash-commands.ts`, `apps/shared/src/json-rpc-gateway.ts`, `tests/test_tui_gateway_server.py`, `tests/tui_gateway/test_compute_host_phase1.py`, `tui_gateway/compute_host.py`, `tui_gateway/host_supervisor.py`, `tui_gateway/server.py`
- **#44462: fix(desktop): route /compress via session.compress and stop masking slash.exec errors behind "not a quick/plugin/skill command"**. closed without merge
  - maintainer direction: category `stale_abandoned`; implication `active`; refs `#44456`
- **#44554: fix(tui): route /compress command to session.compress handler (#44456)**. closed without merge
  - maintainer direction: category `superseded_by_pr`; implication `superseded`; refs `#44462`, `#44456`
- **#53664: fix(desktop): route /compress through session.rpc (superseded)**. closed without merge
  - maintainer direction: category `silent_close`; implication `active`
- **#60644: fix(desktop): register /compress command in TUI gateway dispatch so Desktop can invoke it**. closed without merge
  - maintainer direction: category `merged_via`; implication `superseded`; refs `#60921`, `#60834`, `#60603`
- **#69545: fix(desktop): salvage /compress cluster — session.compress RPC + dedicated-RPC routing**. closed without merge
  - maintainer direction: category `implemented_elsewhere`; implication `superseded`; refs `41e00dcf87`, `#68229`

## Fix status

- Merged to main in PR #60921 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-07-22`.
- Subsystem: `apps/desktop`
