hermes-agent/hermes_cli
brooklyn! fabca0bdd8
feat(tui): single /model command + unified Sessions overlay (#37112)
* feat(tui): single /model command + unified Sessions overlay

Collapse the redundant `/provider` alias so `/model` is the only name
everywhere (it already drove the same 2-step ModelPicker in the TUI).

Merge the separate `/resume` (cold history browser) and `/sessions` (live
switcher) surfaces into one Sessions overlay reached by `/resume`,
`/sessions`, `/session`, and `/switch`. It pins a "+ new" row at the top
(always visible), lists live sessions with status, and lists resumable
history below — dispatching session.activate for live rows vs resume for
cold ones, with close/delete in place. Fixes `/session` opening an empty
live-only switcher and the hidden new-session affordance.

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix(tui): address Copilot review on the Sessions overlay

- Track the armed history-delete by session id instead of row index so the
  1.5s live-status poll re-indexing rows can't redirect the second `d` to a
  different session.
- Re-add the busy-session guard to immediate `/resume <id>` and `/sessions new`
  actions (browsing the bare overlay stays allowed) so resuming/switching can't
  corrupt an in-flight turn's streaming/busy state.

* fix(tui): guard cold-resume (not live-switch/new) from the Sessions overlay

Copilot flagged that overlay actions bypassed the busy guard. Only cold
resume actually closes the current session, so only it is guarded — both
from the slash path and now from the overlay (appActions.resumeById).
Switching between live sessions and starting a `+ new` live session keep
the current session running in the background, so they stay unguarded:
that concurrency is the orchestrator's whole purpose. Also dropped the
over-broad guard on `/sessions new` for the same reason.

* fix(tui): address Copilot review (history dedup + desktop /provider)

- The 1.5s poll now re-derives the resumable list from the RAW session.list
  results (rawHistoryRef) against the current live set, so a session hidden
  while live reappears in history once it closes — instead of being lost
  until a full reload. Delete also prunes the raw ref.
- Drop the dead `/provider` entry from the desktop PICKER_OWNED_COMMANDS now
  that the alias is gone, so the desktop client no longer advertises it.

* fix(tui): surface session.list errors + keep selection stable across polls

- A garbled session.list response now surfaces an error and preserves the
  last good raw history, instead of silently blanking the resumable section.
- The 1.5s poll re-anchors the selection to the same row by session id
  (live or history) when the live list grows/shrinks, so the highlight no
  longer drifts to a different row mid-interaction.

* fix(tui): degrade session.list independently + cover overlay helpers

- Fetch active_list and session.list via Promise.allSettled so a failing
  session.list no longer rejects the whole load: live sessions still render
  and only the resumable history degrades (with an error).
- Add unit tests for the new helpers (sessionRowKindAt row ordering,
  resumableHistory dedupe, sessionsCountLabel, relativeSessionAge).

* test(tui-gateway): assert /provider alias is gone, /model remains

The CI test_complete_slash_includes_provider_alias asserted the removed
`/provider` alias still autocompleted. Flip it to lock in the removal:
`/pro` no longer offers `provider`, and `/mod` still completes `model`.

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-01 22:28:36 -04:00
..
dashboard_auth fix(dashboard-auth): drop /api/* paths from OAuth next= round trip (#36244) 2026-06-01 15:10:20 +10:00
proxy chore: remove dead code — 28 unused functions/classes across 16 files 2026-05-29 04:22:27 -07:00
__init__.py chore: release v0.15.1 (2026.5.29) (#34222) 2026-05-28 18:11:49 -07:00
_parser.py Fix CLI verbose tool progress config fallback 2026-05-23 21:03:51 -07:00
_subprocess_compat.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
auth.py feat(cli): ranked fuzzy search in the curses model picker 2026-06-01 16:58:58 -07:00
auth_commands.py refactor(auth): remove vestigial Nous min_key_ttl/inference_auth_mode params 2026-05-29 02:24:48 -07:00
azure_detect.py feat(azure-foundry): add Microsoft Entra ID auth 2026-05-18 10:14:38 -07:00
backup.py fix(cron): restore jobs.json emptied by config migration on update 2026-05-29 13:22:54 -07:00
banner.py perf(tui): stop slow/dead MCP servers from freezing TUI startup 2026-05-30 02:53:37 -07:00
browser_connect.py feat: auto-launch Chromium-family browser for CDP 2026-05-19 22:34:05 -07:00
build_info.py fix(docker): bake build-time git SHA into the image 2026-05-28 15:14:05 +10:00
bundles.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
callbacks.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
checkpoints.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
claw.py chore: ruff auto-fix PLR6201 — tuple → set in membership tests (#23937) 2026-05-11 11:13:25 -07:00
cli_output.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
clipboard.py fix(clipboard): only read PNG signature bytes, not entire file 2026-05-13 22:54:21 -07:00
codex_models.py fix(codex): drop dead model slugs that HTTP 400 on ChatGPT Pro (#33424) 2026-05-27 12:16:15 -07:00
codex_runtime_plugin_migration.py fix(codex-runtime): de-dup [plugins.X] tables and stop leaking HERMES_HOME into config.toml 2026-05-15 02:31:30 -07:00
codex_runtime_switch.py chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) 2026-05-17 02:29:41 -07:00
colors.py feat: respect NO_COLOR env var and TERM=dumb (#4079) 2026-03-30 17:07:21 -07:00
commands.py feat(tui): single /model command + unified Sessions overlay (#37112) 2026-06-01 22:28:36 -04:00
completion.py test(cli): strengthen zsh completion regression coverage 2026-05-13 09:34:15 -07:00
config.py feat(curator): prune built-in skills after inactivity + track usage for all skills (#36701) 2026-06-01 02:07:32 -07:00
container_boot.py fix(docker): seed s6 gateway state for legacy run cmd (#34829) 2026-06-01 11:28:56 +10:00
copilot_auth.py chore: ruff auto-fix PLR6201 — tuple → set in membership tests (#23937) 2026-05-11 11:13:25 -07:00
cron.py fix(gateway,cron): reuse existing _HERMES_GATEWAY marker; tighten cron regex 2026-05-30 23:05:56 -07:00
curator.py chore: ruff auto-fix PLR6201 — tuple → set in membership tests (#23937) 2026-05-11 11:13:25 -07:00
curses_ui.py feat(cli): ranked fuzzy search in the curses model picker 2026-06-01 16:58:58 -07:00
debug.py style: restore PEP8 blank-line separation after dead-code removal 2026-05-29 04:22:27 -07:00
default_soul.py fix: reset default SOUL.md to baseline identity text (#3159) 2026-03-26 01:34:27 -07:00
dep_ensure.py feat(dep_ensure): complete Windows bootstrap — dep_ensure + install.ps1 + detection (#27845) 2026-05-18 16:34:24 +05:30
dingtalk_auth.py chore: ruff auto-fix PLR6201 — tuple → set in membership tests (#23937) 2026-05-11 11:13:25 -07:00
doctor.py fix: detect pyproject.toml / __init__.py version drift in hermes doctor (#35142) 2026-05-30 00:32:05 -07:00
dump.py fix(docker): bake build-time git SHA into the image 2026-05-28 15:14:05 +10:00
env_loader.py fix(secrets): only apply external secrets once per HERMES_HOME per process (#32271) 2026-05-25 15:18:55 -07:00
fallback_cmd.py fix(fallback): merge fallback_providers with legacy fallback_model configurations 2026-05-23 05:24:57 -07:00
fallback_config.py fix(fallback): merge fallback_providers with legacy fallback_model configurations 2026-05-23 05:24:57 -07:00
gateway.py fix(gateway): fall back to in-process heartbeat when s6 sleep is missing (#36208) (#37120) 2026-06-02 11:59:27 +10:00
gateway_windows.py fix(gateway): drain on Windows hermes gateway stop so sessions survive restart (#33798) 2026-05-28 03:25:32 -07:00
goals.py feat(kanban): goal_mode cards run workers in a /goal loop (#35710) 2026-05-31 01:16:33 -07:00
hooks.py chore: ruff auto-fix PLR6201 — tuple → set in membership tests (#23937) 2026-05-11 11:13:25 -07:00
inventory.py Add Hermes desktop app (#20059) 2026-05-31 17:46:56 -05:00
kanban.py feat(kanban): goal_mode cards run workers in a /goal loop (#35710) 2026-05-31 01:16:33 -07:00
kanban_db.py feat(kanban): goal_mode cards run workers in a /goal loop (#35710) 2026-05-31 01:16:33 -07:00
kanban_decompose.py fix(kanban): close kanban.db FD after every connect() in long-lived processes 2026-05-27 22:07:49 -07:00
kanban_diagnostics.py chore: remove dead code — 28 unused functions/classes across 16 files 2026-05-29 04:22:27 -07:00
kanban_specify.py fix(kanban): close kanban.db FD after every connect() in long-lived processes 2026-05-27 22:07:49 -07:00
kanban_swarm.py fix(kanban): CLI dispatch honors max_in_progress/max_spawn from config; swap missing 'avoid-ai-writing' skill for bundled humanizer (#33488, #29415) (#34337) 2026-05-28 21:00:46 -07:00
logs.py Add Hermes desktop app (#20059) 2026-05-31 17:46:56 -05:00
main.py feat(cli): ranked fuzzy search in the curses model picker 2026-06-01 16:58:58 -07:00
mcp_catalog.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
mcp_config.py fix(mcp): stop reporting false OAuth success when no token was obtained (#34807) 2026-05-29 12:32:19 -07:00
mcp_picker.py feat(mcp): Nous-approved MCP catalog with interactive picker (#30870) 2026-05-26 12:48:14 -07:00
mcp_startup.py perf(cli): stop eager MCP discovery from blocking agent-capable startup 2026-05-30 07:45:26 -07:00
memory_setup.py fix(honcho): harden self-hosted setup paths 2026-05-29 22:29:48 -07:00
migrate.py feat(cli): hermes migrate xai [--apply] [--no-backup] 2026-05-20 09:18:23 -07:00
model_catalog.py feat(models): refresh model catalog hourly instead of daily (#35756) 2026-05-31 00:29:40 -07:00
model_normalize.py remove Vercel AI Gateway and Vercel Sandbox (#33067) 2026-05-27 00:43:32 -07:00
model_switch.py Add Hermes desktop app (#20059) 2026-05-31 17:46:56 -05:00
models.py fix(models): add gemini-3.5-flash to Gemini OAuth + API-key pickers (#37046) 2026-06-01 16:31:13 -07:00
nous_account.py feat(tools): surface the free tool pool in entitlement + setup (#36153) 2026-06-01 06:32:48 +05:30
nous_subscription.py feat(tools): surface the free tool pool in entitlement + setup (#36153) 2026-06-01 06:32:48 +05:30
oneshot.py fix(cli): surface oneshot agent exceptions to stderr with rc=1 2026-05-30 07:31:48 -07:00
pairing.py fix(pairing): enforce lockout on approve_code, not just generate_code (#10195) (#21325) 2026-05-07 07:18:21 -07:00
partial_compress.py Inspired by Claude Code: /compress here [N] — boundary-aware 'summarize up to here' (#35048) 2026-05-29 17:49:15 -07:00
platforms.py feat: complete plugin platform parity — all 12 integration points 2026-04-29 21:56:51 -07:00
plugins.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
plugins_cmd.py Add Hermes desktop app (#20059) 2026-05-31 17:46:56 -05:00
portal_cli.py style: restore PEP8 blank-line separation after dead-code removal 2026-05-29 04:22:27 -07:00
profile_describer.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
profile_distribution.py fix(profile): reject symlinks in distributions (#25292) 2026-05-25 05:07:58 -07:00
profiles.py fix(honcho): harden self-hosted setup paths 2026-05-29 22:29:48 -07:00
prompt_size.py feat(cli): add hermes prompt-size diagnostic (#35276) 2026-05-30 02:53:42 -07:00
providers.py remove Vercel AI Gateway and Vercel Sandbox (#33067) 2026-05-27 00:43:32 -07:00
psutil_android.py fix(android): reject unsafe tar members in psutil compatibility installer 2026-05-28 02:36:09 -07:00
pt_input_extras.py fix(cli): ignore terminal focus reports (salvage of #16780) 2026-05-29 00:31:44 -07:00
pty_bridge.py chore: ruff auto-fix PLR6201 — tuple → set in membership tests (#23937) 2026-05-11 11:13:25 -07:00
relaunch.py fix(windows): prefer npm.cmd over npm.ps1, skip .py argv0 in relaunch 2026-05-08 14:27:40 -07:00
runtime_provider.py refactor(auth): remove vestigial Nous min_key_ttl/inference_auth_mode params 2026-05-29 02:24:48 -07:00
secret_prompt.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
secrets_cli.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
security_advisories.py fix(stt,tts): restore mistralai — 2.4.8 is clean, ban lifted (#34841) 2026-05-29 13:24:12 -07:00
security_audit.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
send_cmd.py fix(review): address Copilot follow-up on sanitizer and file decode errors 2026-05-16 23:00:58 -05:00
service_manager.py Remove prviliges drop when you never ran as root (#34837) 2026-06-01 13:54:18 +10:00
session_recap.py chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) 2026-05-17 02:29:41 -07:00
setup.py feat: explain Quick Setup vs Full setup inline in the first-time setup menu (#36227) 2026-06-01 01:58:30 -07:00
skills_config.py refactor(config): migrate remaining 33 cfg_get call sites (#17311) 2026-04-29 04:03:03 -07:00
skills_hub.py feat(skills): blank-slate skills — install --no-skills + opt-out/opt-in (#36228) 2026-06-01 02:57:57 -07:00
skin_engine.py fix(tui): improve charizard completion menu contrast 2026-05-18 20:05:23 -07:00
slack_cli.py fix(slack): enable writable app home DMs in manifest 2026-05-08 17:01:12 -07:00
status.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
stdio.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
timeouts.py perf(agent-loop): cut 47% of per-conversation function calls via 3 targeted hot-path optimizations (#28866) 2026-05-19 14:25:10 -07:00
tips.py fix(gateway): stop system tips from auto-uploading local files 2026-05-30 18:58:46 -07:00
tools_config.py feat(tools): surface the free tool pool in entitlement + setup (#36153) 2026-06-01 06:32:48 +05:30
uninstall.py fix(cli): remove Hermes-managed node/npm/npx symlinks on uninstall 2026-05-29 17:24:38 -07:00
voice.py fix(tui): restore voice push-to-talk parity (#20897) 2026-05-06 15:49:59 -07:00
web_server.py feat(desktop): session hygiene, archive, media streaming + connecting overlay (#37099) 2026-06-01 20:41:34 -05:00
webhook.py fix(state): restrict sensitive store file permissions 2026-05-24 04:55:18 -07:00
xai_retirement.py fix(xai): align migrate retirement map with docs 2026-05-20 09:18:23 -07:00