Skip to content

fix(cli): wire /sessions slash command in the classic CLI - #25987

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-85af9812
May 14, 2026
Merged

fix(cli): wire /sessions slash command in the classic CLI#25987
teknium1 merged 2 commits into
mainfrom
hermes/hermes-85af9812

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Salvage of #25231 by @explainanalyze, cherry-picked onto current main with authorship preserved.

Summary

Wires /sessions into the classic CLI's process_command() dispatcher. The command has been in COMMAND_REGISTRY since #20805 and surfaces in /help + tab-completion, but the legacy CLI never grew an elif canonical == "sessions" branch — so it fell through and printed Unknown command: sessions in both Windows and WSL/Linux CLI (reproduced by @gille).

Changes

  • cli.py: _handle_sessions_command() + dispatch branch. No-arg / list / ls / browse → recent-sessions table (same one /resume prints). Other args → delegate to _handle_resume_command(f"/resume {arg}").
  • tests/cli/test_cli_init.py: 4 regression tests covering bare /sessions, /sessions list, target delegation, and dispatcher wiring.
  • scripts/release.py: AUTHOR_MAP entry for @explainanalyze (separate commit).

Validation

  • scripts/run_tests.sh tests/cli/test_cli_init.py -k sessions → 6/6 pass.
  • E2E in isolated HERMES_HOME: /sessions prints recent table, /sessions list works, /sessions <target> delegates to _handle_resume_command("/resume <target>").

Closes #25231 via salvage. Original commit authored by Phil Thomas phil.thomas@gametime.co.

explainanalyze and others added 2 commits May 14, 2026 15:59
The 'sessions' command has been registered in the central command
registry since #20805 (May 2025) and surfaces in /help and tab-completion,
but the classic CLI's process_command() never had an elif branch for it.
The canonical name fell through and printed 'Unknown command: sessions'.
The TUI side was wired up correctly via the SessionPicker overlay; only
the legacy CLI was missing the dispatch.

Adds _handle_sessions_command() which mirrors /resume's no-arg behavior
inline (the CLI has no overlay primitive equivalent to the TUI picker):

- /sessions and /sessions list  → print the recent-sessions table
- /sessions <id_or_title>       → delegates to _handle_resume_command

Includes regression tests covering the dispatcher wiring (the original
bug) plus the three handler branches.
@teknium1
teknium1 merged commit 55622b5 into main May 14, 2026
13 of 15 checks passed
@teknium1
teknium1 deleted the hermes/hermes-85af9812 branch May 14, 2026 23:01
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-85af9812 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8424 on HEAD, 8374 on base (🆕 +50)

🆕 New issues (34):

Rule Count
unresolved-attribute 25
invalid-assignment 6
invalid-argument-type 3
First entries
tests/run_agent/test_compressor_fallback_update.py:71: [unresolved-attribute] unresolved-attribute: Attribute `context_length` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:13216: [invalid-assignment] invalid-assignment: Object of type `Literal[False]` is not assignable to attribute `_context_probed` on type `None | Unknown | ContextCompressor`
tests/run_agent/test_compressor_fallback_update.py:67: [unresolved-attribute] unresolved-attribute: Attribute `model` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:12106: [unresolved-attribute] unresolved-attribute: Attribute `protect_first_n` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:15010: [unresolved-attribute] unresolved-attribute: Attribute `last_prompt_tokens` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:10422: [unresolved-attribute] unresolved-attribute: Attribute `compress` is not defined on `None` in union `None | Unknown | ContextCompressor`
cli.py:8953: [unresolved-attribute] unresolved-attribute: Attribute `context_length` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:14197: [unresolved-attribute] unresolved-attribute: Attribute `update_model` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:13748: [invalid-argument-type] invalid-argument-type: Argument to function `_is_oauth_token` is incorrect: Expected `str`, found `str | dict[Unknown, Unknown] | Any | ... omitted 3 union elements`
run_agent.py:13206: [unresolved-attribute] unresolved-attribute: Attribute `update_from_response` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:3293: [invalid-assignment] invalid-assignment: Object of type `int | float` is not assignable to attribute `threshold_percent` on type `None | Unknown | ContextCompressor`
run_agent.py:12107: [unresolved-attribute] unresolved-attribute: Attribute `protect_last_n` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:14120: [unresolved-attribute] unresolved-attribute: Attribute `context_length` is not defined on `None` in union `None | Unknown | ContextCompressor`
tests/run_agent/test_compressor_fallback_update.py:69: [unresolved-attribute] unresolved-attribute: Attribute `api_key` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:10550: [invalid-assignment] invalid-assignment: Object of type `int` is not assignable to attribute `last_prompt_tokens` on type `None | Unknown | ContextCompressor`
tests/run_agent/test_compressor_fallback_update.py:72: [unresolved-attribute] unresolved-attribute: Attribute `threshold_tokens` is not defined on `None` in union `None | Unknown | ContextCompressor`
tests/run_agent/test_compressor_fallback_update.py:68: [unresolved-attribute] unresolved-attribute: Attribute `base_url` is not defined on `None` in union `None | Unknown | ContextCompressor`
tests/run_agent/test_switch_model_context.py:61: [unresolved-attribute] unresolved-attribute: Attribute `context_length` is not defined on `None` in union `None | Unknown | ContextCompressor`
cli.py:8955: [unresolved-attribute] unresolved-attribute: Attribute `compression_count` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:10551: [invalid-assignment] invalid-assignment: Object of type `Literal[0]` is not assignable to attribute `last_completion_tokens` on type `None | Unknown | ContextCompressor`
tests/run_agent/test_switch_model_context.py:60: [unresolved-attribute] unresolved-attribute: Attribute `model` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:15006: [unresolved-attribute] unresolved-attribute: Attribute `should_compress` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:3287: [invalid-assignment] invalid-assignment: Object of type `int` is not assignable to attribute `threshold_tokens` on type `None | Unknown | ContextCompressor`
cli.py:8952: [unresolved-attribute] unresolved-attribute: Attribute `last_prompt_tokens` is not defined on `None` in union `None | Unknown | ContextCompressor`
run_agent.py:13217: [invalid-assignment] invalid-assignment: Object of type `Literal[False]` is not assignable to attribute `_context_probe_persistable` on type `None | Unknown | ContextCompressor`
... and 9 more

✅ Fixed issues (3):

Rule Count
invalid-argument-type 3
First entries
run_agent.py:13748: [invalid-argument-type] invalid-argument-type: Argument to function `_is_oauth_token` is incorrect: Expected `str`, found `str | dict[Unknown | str, Unknown | str | dict[str, str]] | Any | ... omitted 3 union elements`
run_agent.py:7480: [invalid-argument-type] invalid-argument-type: Argument to function `build_anthropic_client` is incorrect: Expected `str`, found `str | dict[Unknown | str, Unknown | str | dict[str, str]] | Any | ... omitted 3 union elements`
run_agent.py:13751: [invalid-argument-type] invalid-argument-type: Argument to function `len` is incorrect: Expected `Sized`, found `(str & ~AlwaysFalsy) | (dict[Unknown | str, Unknown | str | dict[str, str]] & ~AlwaysFalsy) | (Any & ~AlwaysFalsy) | ... omitted 3 union elements`

Unchanged: 4405 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard duplicate This issue or pull request already exists labels May 14, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #25986 — same salvage of #25231, same files changed, both merged within ~1 minute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants