Skip to content

cc-status shim paints subagent seats in their own colours - #97

Merged
hadees merged 6 commits into
mainfrom
feat/cc-status-seats
Oct 14, 2026
Merged

hadees merged 6 commits into
mainfrom
feat/cc-status-seats

Conversation

@hadees

@hadees hadees commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Stacked on #96 — fix-plan steps 2–5.

  • Seat colours (step 2). Hooks fired inside a subagent carry agent_type, so an in-seat PreToolUse/PostToolUse is painted by the shim in that seat's colour instead of cc-status's orange; SubagentStart/SubagentStop keep a one-line-per-seat state file under ${XDG_STATE_HOME:-~/.local/state}/tabstatus/<session_id>.seats, so a parent's Stop over a still-running background seat shows the seat's colour with the active count. Defaults: plan-fable #d787ff, unstick-fable #ff5faf, review-fable #af87ff, work-sonnet #00afaf, scout-haiku #87af5f; override or add any agent type with git config tabstatus.color.<agent_type> '#rrggbb'. The repo name (basename of cwd) prefixes every detail the shim writes. The three status words are unchanged, so the panel's sorting and watches keep working.
  • tabstatus full field set (step 3). tabstatus idle|working|waiting now sends cc-status's colour pair and, for idle, a zero count — the one-command manual reset for a stuck row (it2 set-status keeps every field it is not given).
  • Doctor lines (step 4). claude-doctor: tabstatus: shim on <n>/11 events, raw cc-status on <m>, none on <k> in <settings>; shim: <path|MISSING>; seats live: <n>. iterm2-doctor: cc-status: ~/.config/iterm2/cc-status -> <target> (<state>); it2: <where>. Nothing executed, readlink and -x only.
  • Question at turn end. A Stop whose last message ends on a question (last non-empty line ends with ?) paints waiting in yellow (tabstatus.color.question, default #ffd75f) with the question line as the detail — cc-status alone paints that turn idle with the message's opening, so a session asking you something looked finished. Never on SubagentStop; nothing when work is still active.
  • Stalled shell tasks. A quiet shell task is probed without root: lsof finds the operator-owned shell holding its output file, one ps sums the CPU time of that process tree (children may be root's; ps shows them anyway), and a task whose file and CPU have both stood still for tabstatus.stall-minutes (default 15), or whose holder is gone, paints waiting in red (tabstatus.color.stalled, default #ff5f5f) as "stalled N min: …". The quiet paint now says how long ("quiet M min") and "(cpu busy)" when a silent task is still computing. Live-checked against a download that sat 88 minutes at 0% CPU today.
  • Docs (step 5). The CLAUDE.md passage rewritten as one coherent account; docs/private-overlays.md gains "Session Status wiring" describing the stat-gated template rule the overlays use and the eleventh event (SubagentStart) to add.

Unverified until the first live run: that SubagentStart/SubagentStop and in-seat tool hooks carry agent_type in the compact shape the sh gate matches (documented, not yet captured); a mismatch falls open to today's behaviour.

Tests: full suite 618/618 locally (bash and dash for the shim file).

🤖 Generated with Claude Code

@hadees hadees self-assigned this Oct 6, 2026
hadees and others added 4 commits October 6, 2026 14:48
A tab now says which seat is working: plan-fable, unstick-fable,
review-fable, work-sonnet and scout-haiku each get a dot and text colour
(tabstatus.color.<agent_type> overrides one or adds a seat), while the
status stays one of cc-status's three words, which the Session Status tool
sorts by.

Hooks fired inside a subagent carry agent_type. An in-seat
PreToolUse/PostToolUse is painted by the shim instead of cc-status's plain
orange; PermissionRequest and Notification pass through, since waiting
outranks a colour. SubagentStart and SubagentStop keep a per-session state
file under $XDG_STATE_HOME/tabstatus, deleted on SessionStart/SessionEnd and
ignored past a day, so a Stop over a still-running background seat repaints
its colour instead of orange. Every detail the shim writes now starts with
the repo, the basename of the payload's cwd.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`it2 set-status` leaves fields it is not given unchanged, so a bare
`tabstatus idle` over a stuck orange row left the dot orange, and an idle
that did not store a background-task count of 0 was revived to "working"
by cc-status's idle_prompt handler a minute after Stop.

`tabstatus idle|working|waiting` now appends cc-status's dot/text colour
pair (unless a colour flag is given) and, for idle, `--background-tasks 0`
(unless a count is given), making it the manual reset for a stuck row.
Free-text status words and the no-argument clear are unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-doctor gains a tabstatus: line counting, from a profile's
settings.json, how many of the eleven hook events run the shim, how many
still run iTerm2's raw cc-status and how many neither, with the shim's
deploy path and the live seat lines. iterm2-doctor gains a cc-status: line
reading the app's symlink and where it2 is, by readlink and -x only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Rewrite the CLAUDE.md Session Status passage as one account: quiet vs
active by output-file mtime, why the stored count is 0, amber not blue,
the full field set, seat colours, the eleven wired events and what
Reinstall/Uninstall do to them, the 3.7.3 expanded-path rule, cost,
what the shim cannot see, and cc-status explain as the diagnostic.

Add "Session Status wiring" to the private-overlays guide: the
stat-gated template rule with chezmoi.homeDir, adding SubagentStart,
and claude-doctor's tabstatus line as the check.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@hadees
hadees force-pushed the feat/cc-status-seats branch from 760acad to 4cde696 Compare October 6, 2026 19:53
hadees and others added 2 commits October 6, 2026 15:19
…iting

A session that ends its turn by asking the operator something in prose
showed as idle, with only the message's opening as the detail: cc-status
reserves "waiting" for PermissionRequest and AskUserQuestion and paints a
plain Stop idle. On Stop and StopFailure with nothing active, the shim now
takes the last non-empty line of last_assistant_message, strips leading
bullets and quotes, and when it ends in ? or U+FF1F paints waiting in
yellow (tabstatus.color.question, default #ffd75f) with that line as the
detail. The paint follows cc-status's and outranks the quiet-task idle;
SubagentStop never fires it. The sh gate now hands such Stops to python,
so python runs on most Stops; explain prints a question= line.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A backgrounded installer sat 75 minutes on one download at 0% CPU and the
row still said working; quiet alone cannot tell that from a long compile
that prints nothing. For each quiet shell task the shim now finds the
holders of its output file with lsof -t and sums the CPU of their process
trees from one ps, keeping the last reading per task beside the seats file.
A task nothing holds, or one whose CPU and file have not moved for
tabstatus.stall-minutes, is stalled and paints waiting in red; the quiet
paint gains its age and a (cpu busy) mark. No lsof means unknown, never
stalled.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Base automatically changed from feat/cc-status-shim to main October 8, 2026 01:19
@hadees
hadees merged commit 4078f8a into main Oct 14, 2026
5 checks passed
@hadees
hadees deleted the feat/cc-status-seats branch October 14, 2026 20:53
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