A local session lights the orange attention state when the CLI asks something (permission prompt, question, elicitation): wireSessionPty parses OSC 9 (main.js ~2170) and app.js ~568 calls setAttention. A remote session that is not attached never does. The descriptor that carries the answer is already pulled every refresh: ~/.claude/sessions/<pid>.json reaches the renderer with status, but applyRemoteDescriptor (public/remote-activity-ui.js ~162) only turns it into liveness (descriptorStatus → alive/dead) and the sidebar's text line.
What waiting means (read from the CLI bundle, 2.1.286)
function Mhe(h){let v=vso(h);if(v!==void 0)return{status:"waiting",waitingFor:v,working:!1};
return{status:h.isLoading||h.delegatedActive?"busy":"idle",...}}
waiting is set whenever a blocking dialog is open and has priority over busy; the prompt at rest is idle, never waiting. A waitingFor field is written beside it: permission prompt (tool permission, plan approval, any dialog without its own label), input needed (MCP elicitation), dialog open, goal proposal, worker request, sandbox request. statusUpdatedAt is rewritten on each status write. This closes the reservation in .ai/contexts/cli-session-state.md ("the waiting branch was never observed").
Why OSC 9 does not cover it on a remote host
In preferredNotifChannel: auto the CLI picks a channel from the detected terminal (iTerm2, kitty, ghostty, Apple Terminal); under tmux on a host none is detected and nothing is emitted. Even an attached remote row therefore stays dark unless the host forces iterm2 and tmux has allow-passthrough on.
Scope
Unverified: a live descriptor observed during a permission prompt on a declared host.
A local session lights the orange attention state when the CLI asks something (permission prompt, question, elicitation):
wireSessionPtyparses OSC 9 (main.js~2170) andapp.js~568 callssetAttention. A remote session that is not attached never does. The descriptor that carries the answer is already pulled every refresh:~/.claude/sessions/<pid>.jsonreaches the renderer withstatus, butapplyRemoteDescriptor(public/remote-activity-ui.js~162) only turns it into liveness (descriptorStatus→ alive/dead) and the sidebar's text line.What
waitingmeans (read from the CLI bundle, 2.1.286)waitingis set whenever a blocking dialog is open and has priority overbusy; the prompt at rest isidle, neverwaiting. AwaitingForfield is written beside it:permission prompt(tool permission, plan approval, any dialog without its own label),input needed(MCP elicitation),dialog open,goal proposal,worker request,sandbox request.statusUpdatedAtis rewritten on each status write. This closes the reservation in.ai/contexts/cli-session-state.md("thewaitingbranch was never observed").Why OSC 9 does not cover it on a remote host
In
preferredNotifChannel: autothe CLI picks a channel from the detected terminal (iTerm2, kitty, ghostty, Apple Terminal); under tmux on a host none is detected and nothing is emitted. Even an attached remote row therefore stays dark unless the host forcesiterm2and tmux hasallow-passthrough on.Scope
waitingForwith the descriptor fields in the remote index.waitingshows the attention state, and loses it when the status leaveswaitingor the descriptor is gone/dead. Attached rows keep their local-pty ownership ((session-state): attached remote row is written by two owners — response-ready flap and a 20 s busy tail after exit #273).Unverified: a live descriptor observed during a permission prompt on a declared host.