Skip to content

feat(sessions): add unhide subcommand and --include-hidden to list - #90388

Open
zengzheqing wants to merge 1 commit into
NousResearch:mainfrom
zengzheqing:fix/sessions-unhide
Open

feat(sessions): add unhide subcommand and --include-hidden to list#90388
zengzheqing wants to merge 1 commit into
NousResearch:mainfrom
zengzheqing:fix/sessions-unhide

Conversation

@zengzheqing

Copy link
Copy Markdown

Summary

Add hermes sessions unhide <id...> and --include-hidden to sessions list — the recovery affordance for the durable hidden session flag.

Problem

hidden is a legitimate durable write path: plugin-owned sessions (Bot Mode plumbing rows — Bot Chat, Agent Inbox, Group: ...), the REST PATCH on api_server, and the session.set_hidden RPC all set it. But there is no way back out from any surface:

  • no CLI subcommand (pin/unpin and archive all have CLI counterparts; hidden does not)
  • no UI affordance in Desktop
  • the only documented path is raw SQL on state.db (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 repair describes hidden sessions needing to "reappear" as a schema-level repair rather than a flag operation.

Changes

  • sessions unhide <id...> — clears the flag via set_session_hidden(id, False), which flips the whole compression lineage as a unit (existing DB-layer behavior). Mirrors the existing pin/unpin CLI 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_rich already 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.py8/8 passed (4 new unhide/list tests + 4 existing pin tests unchanged).
  • Sabotage check: reverting the implementation makes all 4 new tests fail; restoring makes them pass — the tests bite.
  • E2E against a synthetic HERMES_HOME through the real hermes sessions entry point: hide → invisible in default list → visible with --include-hiddenunhide by unique prefix → restored in default list, hidden=0 read back from the DB.

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.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard area/sessions Session lifecycle, resume, persistence, history sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Aug 20, 2026
@Enough1122

Copy link
Copy Markdown
Contributor

AI code review — automated review for reference; please use your judgment.

  1. hermes_cli/sessions_cmd.py:unhide — Nit worth verifying against the setter's contract: a False return from set_session_hidden(resolved, False) is reported as "Session '' not found." — but if the store setter also returns False for a no-op (session already visible), an idempotent second unhide of the same id prints a misleading error and bumps the failure count toward exit 1. If the setter distinguishes missing-vs-no-change (or returns True on no-op), fine as-is; otherwise map the two cases separately.

  2. Same PR — Positive: this completes the recovery story that fix(state): surface archived+hidden sessions in the archived-only listing #90955 opened at the query layer — the docstring is unusually honest about the bug class ("no CLI, UI or documented recovery short of raw SQL"), lineage-unit unhide mirrors pin/unpin semantics rather than inventing new ones, partial failures still apply the successes before exiting 1, and the tests pin prefix resolution, multi-id behavior, and both list-flag states through the real main() dispatch.

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

Labels

area/sessions Session lifecycle, resume, persistence, history comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants