The hidden flag is a durable visibility marker set by surfaces that own
their sessions (Bot Mode plumbing rows, plugins, REST PATCH), but until
now there was no way back out: a stale or wrongly-adopted pointer left
an ordinary conversation hidden from every listing with no CLI, UI or
documented recovery short of raw SQL on state.db.
- sessions unhide <id...>: clears the flag via set_session_hidden(False),
which flips the whole compression lineage as a unit — mirroring the
existing pin/unpin CLI surface exactly (resolve_session_id, exit codes,
output format).
- sessions list --include-hidden: discovery affordance so users can find
hidden ids without a SQL probe.
E2E-verified against a synthetic HERMES_HOME through the real CLI entry
point (hide -> invisible, include-hidden -> visible, unhide -> restored).
Sabotage check: all 4 new tests fail with the pre-fix implementation.
Summary
Add
hermes sessions unhide <id...>and--include-hiddentosessions list— the recovery affordance for the durablehiddensession flag.Problem
hiddenis a legitimate durable write path: plugin-owned sessions (Bot Mode plumbing rows —Bot Chat,Agent Inbox,Group: ...), the REST PATCH onapi_server, and thesession.set_hiddenRPC all set it. But there is no way back out from any surface:UPDATE sessions SET hidden=0 ...)A stale or wrongly-adopted pointer can therefore strand an ordinary user conversation hidden from every listing while remaining fully resumable — invisible but alive. This is the exact failure class behind the in-flight #89901: Bot Mode adopts an ordinary session as a bot's canonical chat and the startup reconciliation sweep hides it. #89901 prevents new wrongful hides; this PR recovers sessions already hidden — a gap neither #89901 nor any other current surface fills, and the reason
sessions repairdescribes hidden sessions needing to "reappear" as a schema-level repair rather than a flag operation.Changes
sessions unhide <id...>— clears the flag viaset_session_hidden(id, False), which flips the whole compression lineage as a unit (existing DB-layer behavior). Mirrors the existingpin/unpinCLI surface exactly:resolve_session_id(prefix + alias resolution), title in output, per-id failure counting, exit 1 on any miss.sessions list --include-hidden— discovery affordance so users can find hidden ids without a SQL probe (list_sessions_richalready accepted the parameter; the CLI just never exposed it).Scope
Edges only — two CLI parser args + one dispatch branch + one flag passthrough. No core surface, no new RPC, no DB schema change. Every line reuses an existing primitive.
Verification
All real-path, not mocked:
scripts/run_tests.sh tests/hermes_cli/test_sessions_unhide.py tests/hermes_cli/test_sessions_pin.py— 8/8 passed (4 new unhide/list tests + 4 existing pin tests unchanged).hermes sessionsentry point: hide → invisible in default list → visible with--include-hidden→unhideby unique prefix → restored in default list,hidden=0read back from the DB.