Summary
Running the packaged v1.14.1 build on macOS with Claude Code as the agent, the sidebar "waiting for you" tray never appeared while a task sat blocked on a permission dialog. The tray is the pinned group under the New Task button (NeedsInputTray, src/components/Sidebar.tsx:290).
I have not root-caused it. This is a write-up of what has been ruled out, so whoever picks it up doesn't repeat the elimination.
Ruled out
The feature is present in the release. src/store/sidebar-attention.ts exists at both v1.14.0 and v1.14.1 (checked via the contents API). An earlier conclusion that the feature was unmerged was wrong — it came from testing containment against a local main that was 27 commits behind upstream/main.
The setting is on. sidebarNeedsInputFirst defaults to true (src/store/core.ts:53), and persistence falls back to true when the key is absent (src/store/persistence.ts:511). The actual persisted value in ~/Library/Application Support/parallel-code/state.json on the affected machine is true, so the tray's dismiss button (Sidebar.tsx:314, which sets it to false permanently) was not the cause.
The mobile ranking path is healthy. I simulated the phone overview's ordering end to end — getTaskAttentionState → Remote_UpdateTaskStatus → main-process cache → buildAgentList → ws → sortedAgents — with the rank table extracted directly from src/remote/AgentList.tsx so the simulation can't drift from source. All checks passed: needs_input promoted to the top, stable order within a rank, error ranked below needs_input, attention surviving a bare status message, shell agents excluded, rebroadcast on every real change. Note this only clears the mobile list; the desktop tray uses a different source (below).
Remaining suspect
The desktop tray does not read the prioritized attention state. computeNeedsInputTasks builds membership from getTaskOpenQuestion(taskId) directly (src/store/sidebar-attention.ts), which requires the agent to be in the questionAgents set with an onset recorded in questionSinceByAgent (taskStatus.ts:486-501).
That set is fed by looksLikeQuestion, which suppresses detection when a main input prompt is visible (taskStatus.ts:373-380):
if (
chunkContainsAgentPrompt(readyProbe) ||
recentLines.some(looksLikeBareAgentPrompt) ||
/[❯›]\s*$/.test(lastLine) ||
looksLikeBareShellPrompt(lastLine)
) {
return false;
}
The reasoning is sound — a visible bare prompt means an earlier dialog was already answered. The open question is whether a Claude Code permission dialog can trip one of these arms while genuinely waiting. Worth noting that in src/store/taskStatus.test.ts the cases asserting true for a dialog ending in ❯ are all trust dialogs, which win via a separate trust fast path. There is no test covering a non-trust Claude Code permission dialog (Do you want to proceed? with a ❯ 1. Yes selection cursor inside a box).
Not verified
- No capture of the real terminal output. Every hypothesis about what Claude Code actually emitted while waiting is inference from source, not from a recording. This is the gap that matters most.
looksLikeQuestion was never executed. The repo has no node_modules installed, so driving the real exported function under vitest would need a full npm ci. It was not run.
Suggested next steps
- Capture the PTY tail (last ~1000 chars, ANSI intact) while a Claude Code permission dialog is open and unanswered.
- Feed it to the exported
looksLikeQuestion — it is already exported and directly unit-tested, so this is a one-line test.
- If it returns
false, identify which of the four suppression arms fired and add a regression case alongside the existing trust-dialog tests.
- If it returns
true, move upstream to whether the agent is in runningAgentIds at that moment (taskStatus.ts:491 filters on store.agents[id]?.status === 'running').
Unrelated observation
On the same machine desktopNotificationsEnabled is false in state.json, so the "Task Needs Input" desktop notification would not have fired either. Separate mechanism from the tray, but it means two independent signals for the same condition were both silent — worth keeping in mind when judging severity.
Summary
Running the packaged v1.14.1 build on macOS with Claude Code as the agent, the sidebar "waiting for you" tray never appeared while a task sat blocked on a permission dialog. The tray is the pinned group under the New Task button (
NeedsInputTray,src/components/Sidebar.tsx:290).I have not root-caused it. This is a write-up of what has been ruled out, so whoever picks it up doesn't repeat the elimination.
Ruled out
The feature is present in the release.
src/store/sidebar-attention.tsexists at bothv1.14.0andv1.14.1(checked via the contents API). An earlier conclusion that the feature was unmerged was wrong — it came from testing containment against a localmainthat was 27 commits behindupstream/main.The setting is on.
sidebarNeedsInputFirstdefaults totrue(src/store/core.ts:53), and persistence falls back totruewhen the key is absent (src/store/persistence.ts:511). The actual persisted value in~/Library/Application Support/parallel-code/state.jsonon the affected machine istrue, so the tray's dismiss button (Sidebar.tsx:314, which sets it tofalsepermanently) was not the cause.The mobile ranking path is healthy. I simulated the phone overview's ordering end to end —
getTaskAttentionState→Remote_UpdateTaskStatus→ main-process cache →buildAgentList→ ws →sortedAgents— with the rank table extracted directly fromsrc/remote/AgentList.tsxso the simulation can't drift from source. All checks passed:needs_inputpromoted to the top, stable order within a rank,errorranked belowneeds_input, attention surviving a barestatusmessage, shell agents excluded, rebroadcast on every real change. Note this only clears the mobile list; the desktop tray uses a different source (below).Remaining suspect
The desktop tray does not read the prioritized attention state.
computeNeedsInputTasksbuilds membership fromgetTaskOpenQuestion(taskId)directly (src/store/sidebar-attention.ts), which requires the agent to be in thequestionAgentsset with an onset recorded inquestionSinceByAgent(taskStatus.ts:486-501).That set is fed by
looksLikeQuestion, which suppresses detection when a main input prompt is visible (taskStatus.ts:373-380):The reasoning is sound — a visible bare prompt means an earlier dialog was already answered. The open question is whether a Claude Code permission dialog can trip one of these arms while genuinely waiting. Worth noting that in
src/store/taskStatus.test.tsthe cases assertingtruefor a dialog ending in❯are all trust dialogs, which win via a separate trust fast path. There is no test covering a non-trust Claude Code permission dialog (Do you want to proceed?with a❯ 1. Yesselection cursor inside a box).Not verified
looksLikeQuestionwas never executed. The repo has nonode_modulesinstalled, so driving the real exported function under vitest would need a fullnpm ci. It was not run.Suggested next steps
looksLikeQuestion— it is already exported and directly unit-tested, so this is a one-line test.false, identify which of the four suppression arms fired and add a regression case alongside the existing trust-dialog tests.true, move upstream to whether the agent is inrunningAgentIdsat that moment (taskStatus.ts:491filters onstore.agents[id]?.status === 'running').Unrelated observation
On the same machine
desktopNotificationsEnabledisfalseinstate.json, so the "Task Needs Input" desktop notification would not have fired either. Separate mechanism from the tray, but it means two independent signals for the same condition were both silent — worth keeping in mind when judging severity.