Skip to content

Agent-aware live session status in /resume - #202

Merged
raiseCatError merged 1 commit into
devfrom
feature/174-agent-aware-status
Sep 29, 2026
Merged

raiseCatError merged 1 commit into
devfrom
feature/174-agent-aware-status

Conversation

@raiseCatError

Copy link
Copy Markdown
Owner

Closes #174

Behavior

/resume LIVE rows and nmsh --list show evidence-based status for each live session:

  • Running: running <command> · <elapsed>, followed by:
    • a known CLI's name (Claude Code, Codex, Aider, Gemini CLI, OpenCode, Goose, Cursor Agent, Amp, Crush, Qwen Code), matched from the command's program word or the foreground process;
    • otherwise process <name> when the foreground process differs from the command (for example npm test → process node).
  • Output: active if the session wrote within 10 s, otherwise quiet <age>. Nothing is shown when there's no output evidence.
  • needs attention <age>: the running program itself asked for attention with a terminal notification (OSC 9 excluding 9;4 progress, OSC 777 notify) or a bell. It clears when someone types into the session or the command ends.
  • fullscreen while the program holds the alternate screen, and the program's own title (OSC 0/2, control characters removed, at most 80 characters stored and 40 shown).
  • Idle: idle <age> plus last command succeeded or last command failed (exit N).
  • Home-directory paths show as ~/… in /resume, sharing the startup picker's helper, so the status fits.

Detection and lifecycle

  • SessionEvidence, one per service session, observes the output stream it already receives: the last-output time, the title, attention (only while a command runs) and the last exit. It resets on exec and prompt, and input clears attention. Split OSC sequences are handled, and a BEL ending an OSC isn't a bell.
  • The foreground process comes from node-pty's pty.process, read only when sessions are listed. There's no polling and no process-tree walk.
  • Everything lives in the service, so it survives detach and reattach. Attention clears once someone types after reattaching.
  • The protocol is unchanged in version: the new SessionInfo fields are optional, older services decode fine, and the rows just show less.

False positives and unsupported agents

  • The known-CLI table only supplies display names. Recognized or not, every program gets the same states. An unrecognized agent shows its command and process and the same evidence, just without a name.
  • NMSh never states what a program is thinking or waiting for. Waiting for input and waiting for approval from Agent-aware live session status in /resume #174 aren't shown, because nothing generic can evidence them without screen scraping or agent integrations. The closest honest signal is needs attention, which the program itself sent.
  • A plain bell from any running command (for example a failed completion inside a REPL) also counts as needs attention, since it's a genuine terminal request for attention. Bells at the shell prompt are ignored.

Tests

  • tests/liveStatus.test.ts:
    • Evidence parsing: split and ST-terminated OSC, progress vs notification, sanitizing and bounding titles, ignoring malformed OSC, attention only while running, clearing on input, resetting on prompt.
    • Status for ordinary and non-agent commands (idle with success or failure, npm test with a node process, quiet make, fullscreen vim with a title, no evidence means no claim).
    • Known CLIs by command and by process, an unrecognized agent, and never claiming intent.
    • /resume and --list text, and the protocol round trip, including an older service without the fields.
    • End to end with a real frontend, service and zsh: a fake claude sets a title and sends a notification, the status survives a detach, shows in another window's /resume, and reattaching and typing clears attention and records the exit.
  • The existing /resume, startup restore/discovery, lifecycle and service tests pass.
  • Layout (Bottom/Top/Flow) and presentation (Normal/Chat) are untouched. Status only appears in /resume panel rows and --list.
  • Build, typecheck and git diff --check are clean. The full suite passed 591/591 twice locally.

Limitations

  • For compound command lines (cd x && claude) the name comes from the first program word or the foreground process only.
  • The foreground process name depends on node-pty and platform support. Scripts show their interpreter (sh, node, python3).
  • nmsh --list shows the status clauses in place of the previous running: <command>.
  • Physical validation is deferred to the v0.6 test pass.

/resume LIVE rows and nmsh --list now say what each live session is
doing, from evidence the service already sees rather than guesses. Per
session the service records when output last arrived, the title the
running program set (OSC 0/2), whether it asked for attention (an OSC 9
or OSC 777 notification, or a bell, while a command runs; cleared by
typing or by the command ending) and the last exit code. The foreground
process name is read from node-pty only when sessions are listed, so
nothing polls.

A pure liveStatusParts turns that into factual clauses: running command
and elapsed time, a known CLI's display name or the foreground process,
active or quiet output, needs attention, fullscreen, the program's title,
and the last command's result while idle. Known CLIs (Claude Code, Codex,
Aider, ...) only get a display name; every program gets the same states,
and nothing claims what a program is thinking or waiting for.

The new SessionInfo fields are optional, so older services still decode.
Paths under the home directory show as ~/... in /resume rows, sharing the
startup picker's helper.
@raiseCatError
raiseCatError merged commit cb2b37c into dev Sep 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant