Skip to content

A session watching its own background work shows up as NEEDS YOU #468

Description

What happens

An agent that arms a monitor, backgrounds a shell or hands work to a cloud session is
told by its CLI to end the turn and wait to be notified. The pane falls quiet, and about
a minute later Claude Code's idle notification arrives. Codeman files that as an
approval item of kind idle, and the session joins the group Codeman calls NEEDS YOU:
the heading codeman tui prints, the Needs you section on the phone overview, and the
needs you pill on a rich sidebar row. Nothing there wants anything from me. I open the
tab, read the last message, find an agent waiting for a sleep to finish, and close it
again.

Any long wait ends a turn this way — a build, a CI run, a log tail — so those rows sit
in NEEDS YOU for as long as the work runs.

Measured

Today, on a beta instance running master (1.32.0 source) so it could not touch my live
sessions. I asked a session to arm one monitor and end its turn:

curl -s -X POST http://127.0.0.1:5000/api/v1/sessions/$SID/input \
  -d '{"input":"Call the Monitor tool once with command \"sleep 600\" … then end your turn.\r","useMux":true}'
source what it said
the pane's last row ⏵⏵ bypass permissions on · 1 monitor · ← for agents
GET /api/sessions status: "idle", isWorking: false, nothing further
the session's row in the UI the yellow waiting pill, which is the NEEDS YOU tier

Killing the monitor's own process made the CLI wake, take a turn and drop the chip from
its footer. So the CLI states the difference on screen the whole time, and Codeman reads
past it.

Why it happens

Codeman's session model has idle | busy | stopped | error and nothing between them.
The pane probe reads one thing off the screen, the working line
(_probePaneWorking, src/session.ts), which answers whether a turn is running. Both
classifiers then put any pending approval, kind idle included, in the tier that means
a human is needed: classifySession at src/tui/tui-model.ts:78 and
_mobileOverviewState at src/web/public/mobile-overview.js:104.

So a quiet pane has one meaning inside Codeman, and the CLI has two meanings for it. The
last row of the screen is where Claude Code says which one this is, and it names the kind
and the count: 1 monitor, 2 shells, 1 cloud session, 4 background tasks.

Why it matters

  • NEEDS YOU is the group I act on, and entries that need nothing are what teach me to
    stop trusting it.
  • The Approvals Inbox counts those rows as pending items when it is on, so its bell
    carries a number that overstates what is waiting.
  • Anything reading /api/sessions inherits the blind spot. My own board tool files the
    same sessions as waiting on me, because Codeman is where it gets its facts.

What I have built, and did not send

I have this working on a branch and I have not opened a PR, because CONTRIBUTING asks
for a nod on anything bigger than a small fix. It is one commit, the gate is green, and
I verified it end to end on the beta instance above. Its shape:

  • The CLI registry carries the footer row as an optional
    capabilities.workDetect.watchingLine, beside the workingLine it already holds, and
    it goes through compileVersionRegex() like every other regex that comes from config.
  • _confirmIdle() already captures the pane at the moment a turn ends. That same capture
    now also yields the label, through a pure helper in session-activity.ts that searches
    the last few lines only, so a session that prints the words "1 monitor" is not read as
    running one.
  • The label lands on Session.watching and rides toLightDetailedState() out to every
    session payload.
  • The phone overview, the desktop home rail and the rich sidebar rows wear it as a
    watching badge in the accent colour, beside the state pill rather than instead of it.
  • Tests cover the pattern against verbatim pane captures, the session field through a
    real idle transition, and each surface's row model.

Questions before I send anything

  1. The screen, or a hook? A PostToolUse matcher on Monitor would report the
    arming precisely, with the description and the timeout, but Claude Code fires nothing
    when a monitor ends, so the end has to be inferred. The footer row is right in both
    directions and covers backgrounded shells and cloud sessions as well. It also couples
    to a CLI's UI string, which is what the registry exists to hold, so I read it as the
    registry's kind of problem rather than a new one. Do you agree?
  2. A badge, or a state of its own? I kept the state pill deciding the group, because
    an agent can arm a monitor and ask me a question in the same breath, and only the pill
    knows which. A fifth state would be tidier and would get that case wrong.
  3. Should the idle alert stand down while a session is watching? That is the deeper
    version of this fix and it touches the Approvals Inbox rather than the pane probe. I
    have not written it, and I would rather ask than assume.
  4. Which surfaces? The badge shows where a state pill already shows. The header tab
    strip and the plain sidebar have no pill at all, and codeman tui rows have their own
    vocabulary. Say the word and I will cover either.
  5. What shape on the wire? Today watching is the CLI's own words as a string. A
    { kind, count } object would survive a CLI rewording its footer, at the cost of a
    mapping table per CLI.

Environment

  • Ubuntu 22.04.5 on WSL2, Node 22.22.3, tmux 3.2a
  • Codeman 1.30.0 installed with install.sh into ~/.codeman/app; measured above on
    master at 1.32.0
  • Claude Code 2.1.278, browser Firefox

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions