hermes-agent/hermes_cli
brooklyn! 87d3fa6f1c
feat(tui): opt-in auto-resume of the most recent session (#17130)
* feat(tui): opt-in auto-resume of the most recent session

`hermes --tui` always forges a fresh session at startup unless the user
sets `HERMES_TUI_RESUME=<id>`.  Disconnects, terminal-window crashes,
and accidental Ctrl+D therefore lose every piece of in-flight context
even though `state.db` still has the full history a `/resume` away.

Add an opt-in path that mirrors classic CLI's `hermes -c` muscle
memory: when `display.tui_auto_resume_recent: true` is set in
`~/.hermes/config.yaml`, the TUI looks up the most recent human-facing
session and resumes it instead of starting fresh.  Default off so
existing users aren't surprised; explicit `HERMES_TUI_RESUME` always
wins.

Wires:

* New `session.most_recent` JSON-RPC in `tui_gateway/server.py` that
  returns the first non-`tool` row from `list_sessions_rich`, or
  `{"session_id": null}` when none.  Uses the same deny-list as
  `session.list` so sub-agent rows can't sneak in.
* `createGatewayEventHandler.handleReady` re-ordered: explicit
  `STARTUP_RESUME_ID` first (unchanged), then conditional auto-resume
  via `config.get full → display.tui_auto_resume_recent`, then the
  legacy `newSession()` fallback.  Failures of either RPC fall back
  to `newSession()` so the path is always finite.
* Default `display.tui_auto_resume_recent: False` added to
  `DEFAULT_CONFIG` in `hermes_cli/config.py` (no `_config_version`
  bump per AGENTS.md — deep-merge handles the additive key).

Tests:

* 4 new vitest cases in `createGatewayEventHandler.test.ts` cover
  every gate-and-fallback combination (env wins, config off, config
  on with hit, config on with miss).
* 3 new pytest cases for `session.most_recent` (denied row skip,
  tool-only → null, db-unavailable → null).

Validation:
  scripts/run_tests.sh tests/test_tui_gateway_server.py — 93/93.
  cd ui-tui && npm run type-check — clean; npm test --run — 393/393.

* review(copilot): fold session.most_recent errors into null + extend ConfigDisplayConfig

* review(copilot): cover RPC-rejection fallbacks in auto-resume tests
2026-04-28 16:53:38 -05:00
..
__init__.py
auth_commands.py Add native Spotify tools with PKCE auth 2026-04-24 05:20:38 -07:00
auth.py feat(agent): add lmstudio integration 2026-04-28 12:27:36 -07:00
azure_detect.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
backup.py feat(claw-migrate): harden OpenClaw import with plan-first apply, redaction, and pre-migration backup (#16911) 2026-04-28 01:50:23 -07:00
banner.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
callbacks.py
claw.py feat(claw-migrate): harden OpenClaw import with plan-first apply, redaction, and pre-migration backup (#16911) 2026-04-28 01:50:23 -07:00
cli_output.py
clipboard.py
codex_models.py
colors.py
commands.py feat(agent): add lmstudio integration 2026-04-28 12:27:36 -07:00
completion.py
config.py feat(tui): opt-in auto-resume of the most recent session (#17130) 2026-04-28 16:53:38 -05:00
copilot_auth.py
cron.py
curses_ui.py
debug.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
default_soul.py
dingtalk_auth.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
doctor.py feat(agent): add lmstudio integration 2026-04-28 12:27:36 -07:00
dump.py fix(gemini): fail fast on missing API key + surface it in hermes dump (#15133) 2026-04-24 05:35:17 -07:00
env_loader.py refactor: consolidate symlink-safe atomic replace into shared helper 2026-04-28 04:58:22 -07:00
fallback_cmd.py feat(cli): add 'hermes fallback' command to manage fallback providers (#16052) 2026-04-26 06:19:04 -07:00
gateway.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
hooks.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
logs.py
main.py feat(agent): add lmstudio integration 2026-04-28 12:27:36 -07:00
mcp_config.py
memory_setup.py
model_catalog.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
model_normalize.py fix(model-normalize): pass DeepSeek V-series IDs through instead of folding to deepseek-chat 2026-04-24 05:24:54 -07:00
model_switch.py feat(agent): add lmstudio integration 2026-04-28 12:27:36 -07:00
models.py fix: follow-up for salvaged PR #17061 2026-04-28 12:27:36 -07:00
nous_subscription.py fix(cli): coerce use_gateway config flags in tool routing 2026-04-26 19:02:55 -07:00
oneshot.py fix(cli): honor user-defined providers via chat --provider and -m <alias> 2026-04-28 01:47:20 -07:00
pairing.py
platforms.py yuanbao platform (#16298) 2026-04-26 18:50:49 -07:00
plugins_cmd.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
plugins.py feat(plugins): add pre_approval_request / post_approval_response hooks (#16776) 2026-04-27 20:08:33 -07:00
profiles.py fix(profiles): migrate Honcho host on rename 2026-04-28 05:37:09 -07:00
providers.py feat(agent): add lmstudio integration 2026-04-28 12:27:36 -07:00
pty_bridge.py fix: mobile chat in new layout 2026-04-24 12:07:46 -04:00
runtime_provider.py fix: follow-up for salvaged PR #17061 2026-04-28 12:27:36 -07:00
setup.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
skills_config.py
skills_hub.py feat(skills): install skills from a direct HTTP(S) URL (#16323) 2026-04-26 20:57:10 -07:00
skin_engine.py
slack_cli.py feat(slack): register every gateway command as a native slash (Discord/Telegram parity) (#16164) 2026-04-26 11:38:32 -07:00
status.py feat(agent): add lmstudio integration 2026-04-28 12:27:36 -07:00
timeouts.py refactor(timeouts): drop redundant ImportError in except clause 2026-04-26 20:48:20 -07:00
tips.py remove: BOOT.md built-in hook (#17093) 2026-04-28 09:50:27 -07:00
tools_config.py fix(browser): detect missing Chromium and fail fast with actionable error (#17039) 2026-04-28 07:03:44 -07:00
uninstall.py
voice.py
web_server.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
webhook.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00