Repository navigation
Open
Labels
enhancementNew feature or requestNew feature or request
Description
This was generated by AI during triage.
Summary
Two connected parts:
- A "working" state per session: the agent is actively doing something (thinking, running tools, streaming a reply). It sits alongside the existing waiting for input (green) and waiting for approval (orange) states, with its own graphical indicator in the sidebar row and the terminal toolbar.
- An activity timeline / dashboard: which sessions were active, when, and for how long. For example, one swimlane or heatmap row per session across the day or week.
Motivation
With many sessions open, the question "which agents are busy right now, and which have been idle all afternoon?" has no answer at a glance. Today:
AlertDetectorknows only two states,InputRequiredandToolApproval. Nothing marks "working". A session that is busy looks exactly like one that is idle.- Subtle pulse animation on sidebar tabs when their session is emitting output #60 proposes a pulse driven by raw PTY byte rate. That can't tell an agent apart from a build,
npm installortail -f. - Add Workspace Overview view: status cards with activity + output preview #57 (Workspace Overview) wants an idle / running / waiting badge, but has nothing to drive "running".
- feat: usage statistics view — analyse Claude Code agent logs #151 (usage statistics) answers how much (tokens, cost), not when.
Proposed behaviour
Part 1: working-state detection + indicator
- Add a
SessionViewModel.IsWorking(or anAgentStateenum:Idle | Working | WaitingForInput | WaitingForApproval). Bind the sidebar and toolbar dots to it. - The indicator should be visibly distinct from the waiting dots, e.g. an animated accent ring or spinner glyph. Remember that nothing WPF can be drawn over a terminal pane (WebView2 is an
HwndHost; see CLAUDE.md "Session Spinners"), so it has to live in the sidebar row or the toolbar chrome. - The state clears when an alert fires (the agent stopped and is now waiting) or after N seconds of silence.
- Make Subtle pulse animation on sidebar tabs when their session is emitting output #60's pulse use this state instead of a byte-rate threshold, with the byte-rate version as the fallback for non-agent sessions (see the comment on Subtle pulse animation on sidebar tabs when their session is emitting output #60).
Part 2: activity timeline
- v1, no new collection needed:
session_outputalready storessession_id+tsfor every indexed line (Terminal/OutputIndexer.cs). Bucket lines per session per N minutes, and render a heatmap or swimlane view (e.g. last 24h / 7d) with one row per session, including dormant ones. - v2, true working time: record
Workingintervals from Part 1 (session_id, start, end) in a small new table, so the timeline shows agent time rather than "bytes were printed". It could also total "agent-hours per session / per group / per day". - Where it lives is open: a section of Add Workspace Overview view: status cards with activity + output preview #57's Workspace Overview, a tab in feat: usage statistics view — analyse Claude Code agent logs #151's statistics view, or its own panel.
Open decisions (why this is not ready for an agent yet)
- How to detect "working". Two candidates:
- Screen heuristic: Claude Code paints a recognisable live status line while working (spinner + an interrupt hint). Matching it in
AlertDetectorneeds no setup, but it breaks whenever the CLI changes its TUI wording, and it is Claude-specific. - Claude Code hooks (
UserPromptSubmit→ working,Stop/Notification→ idle): precise and robust to UI changes. But they need configuration in the user's Claude settings, and a way to get the signal back to CSM. Hook stdout goes to Claude, not to the terminal, so the OSC 9001 channel isn't directly reachable. Options: a local named pipe or file keyed by session id, or the MCP server from Host one MCP server for all sessions: self-control, fleet overview, and orchestration #132. - Possibly both: hooks when present, the heuristic otherwise.
- Screen heuristic: Claude Code paints a recognisable live status line while working (spinner + an interrupt hint). Matching it in
- Non-Claude sessions: do they get a "working" state at all, or only the Subtle pulse animation on sidebar tabs when their session is emitting output #60 byte-rate pulse?
- Dashboard placement and scope: standalone, inside Add Workspace Overview view: status cards with activity + output preview #57, or inside feat: usage statistics view — analyse Claude Code agent logs #151? A time window of 24h or 7d? Live and dormant sessions only, or also closed ones from
session_history? - Retention: v1 inherits
output.db's 30-day prune (and Cap output.db by size with FIFO eviction — the 30-day prune never reclaims disk space #124's size cap), so the timeline can't reach further back than that.
Related
- Subtle pulse animation on sidebar tabs when their session is emitting output #60: activity pulse (byte-rate based). It should be driven by Part 1.
- Add Workspace Overview view: status cards with activity + output preview #57: Workspace Overview. A natural host for the per-session state and the timeline.
- feat: usage statistics view — analyse Claude Code agent logs #151: usage statistics. Tokens/cost, complementary to time-based activity.
- Tray icon: keep running when the window is closed, and show session status #149: tray icon session status. It could show a "N working" count.
- Host one MCP server for all sessions: self-control, fleet overview, and orchestration #132: CSM-hosted MCP server. A possible return channel for hook signals.
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request
Activity
AThraen commentedon Nov 5, 2026
Input from Herdr v0.9.x for the "how to detect working" decision
Herdr combines both of the candidate approaches listed above, and its experience suggests we need both too:
agent explaindebug view. Its Claude Code integration reports only session identity via aSessionStarthook; working/idle/blocked still come from the screen.pane report-agent --state working|idle|blocked --seq N). It wins while the reporter holds the pane.donevsidle: "finished, not yet looked at" vs "finished and seen". This is a cleaner attention signal than a single alert badge, and it slots straight into this issue's indicator.Filed as separate issues so each can move on its own: self-reported state + env vars, data-driven detection rules, and the env-leak bug they both build on (links below).
docs(comparison): correct the Herdr column and add a working-state row (
mortenaslo commentedon Nov 6, 2026
Detecting "working": OSC 7501 (Program Status Protocol)
This answers open decision 1. It is a better third option than either the screen heuristic or hooks.
What it is. OSC 7501 is a terminal escape sequence a program uses to report its own state through the PTY. It was proposed in October 2026; spec: https://www.superlogical.com/rex/docs/build/program-status
state:idle,workingorblocked(each with optionalprogress0–100 exceptidle),done,error, orclear.kind: only withblocked; one ofpermission,question,auth.id, a slash-separated path. Each report replaces its record, andclearremoves a record and its children.[A-Za-z0-9_.,+/=-],msg/titlein base64, hard size limits, and a report that breaks any rule is dropped whole.Claude Code already supports it, but only if the terminal answers. Checked in the installed
claude.exe2.1.319: it containsPROGRAM_STATUS:7501. At startup it sends the probeOSC 7501 ; ?. If nothing answers it logsprobe: no reply to OSC 7501 ; ?and never reports state. CSM doesn't answer today, so we have never received any. Supporting it means replying to the probe, not just listening for reports.No hooks or user configuration are needed, and the TUI wording no longer matters. It also works for any other program that adopts it.
Mapping (agreed)
working(+progress)blocked+permissionIsWaitingForApproval(orange)blocked+question/authIsWaitingForInput(green)done/errorNeedsAttentionbadge / toastidle/clearIt also gives Part 2 v2 exact
Workingintervals to record, and #60 a real signal instead of byte rate.Fallback: keep today's detection
OSC 7501 is new, and Rex is the only terminal the spec names as implementing it. So keep
AlertDetector's regex detection as the fallback:Either way the information can only improve, especially for Claude sessions.
Implementation sketch
terminal-init.js: addregisterOscHandler(7501, …)next to the 9001 one. Reply to?withOSC 7501 ; ? ST(written back to the PTY by the host: app-authored, soSendToTerminal). Post reports to the host.Services/ProgramStatusPayload: a WPF-free parser and validator with tests, likeShellIntegrationPayload. It handles the alphabet, base64 + control-character rejection, the limits, and the record tree withclearsemantics.SessionViewModel: keeps anAgentStatederived from the records, and standsAlertDetectordown once 7501 is seen.working/blockedrecords drop when the process exits or a new prompt starts (OSC 133A).HwndHost).feat(status): OSC 7501 program status — working state, exact waiting …
feat(status): OSC 7501 program status — working state, exact waiting …
AThraen commentedon Nov 10, 2026
Status update: Part 1 shipped in #190 (v0.11.0). Sessions now report their state through OSC 7501, and the regex detection is kept as a fallback when a session reports nothing. The sidebar and toolbar show
⟳ working · N%, with exact waiting dots and badges when a session becomes blocked, done or errors. Claude Code reports its state on its own, because CSM now answers its probe.Still open: Part 2, the activity timeline and dashboard. The data it needs now exists for each session (
AgentState,WorkProgress,ProgramStatusMessage), but nothing records it over time. A timeline needs those state transitions stored with timestamps, for example as a small table inoutput.dbnext to the output index. The per-project board in #161 reads the same state.