Skip to content

[Bug]: Desktop/web thread shows no sign of delegated CLI-agent work: silent while it runs, idle-looking when backgrounded, spontaneous wake after #5043

Description

@kakismash

Before submitting

Area

apps/web

Steps to reproduce

Written so an agent can re-run this end-to-end. Prereqs: Claude provider connected, codex CLI installed and authenticated (any second CLI agent works — the point is a long-running child process).

Variant A — foreground delegation (silent while running):

  1. Add any small project and start a thread with the Claude provider, Full access mode.
  2. Send:

    Delegate a code review to the Codex CLI: run this exact shell command and wait for it to finish (it can take a minute or two): codex exec --skip-git-repo-check "Read math.js and write a thorough code review with at least 10 distinct observations. Be verbose." — Then summarize what Codex found in 2 sentences.

  3. While the command runs (confirm out-of-band with ps aux | grep 'codex exec' that the child is alive), observe the thread transcript and sidebar row.

Variant B — background delegation (idle-looking while child works, then spontaneous wake):

  1. In the same or a new Claude thread, send:

    Start this shell command as a BACKGROUND task (run_in_background, do not wait for it, do not poll it): codex exec --skip-git-repo-check "Read math.js and write an extremely thorough code review with at least 15 observations." — After starting it, immediately end your reply with one sentence confirming it is running in the background.

  2. The turn ends within seconds. Verify with ps that codex is still running.
  3. Watch the thread and sidebar until the child exits (1–3 minutes).

Expected behavior

  • While a provider turn is executing a tool call, the transcript shows the in-flight tool call (at minimum its name/command), not just a bare elapsed-time row.
  • While any delegated/background child work belonging to the thread is running, the thread remains visibly Working (sidebar and transcript), and settle logic does not treat the thread as finished.
  • When background work completes, the resulting activity is an expected continuation, not a surprise state flip on a thread that looked finished.

Actual behavior

Verified on a dev build from current main:

  • Variant A: for the full ~2 minutes the child ran, the transcript showed only Working for Ns — no tool row, no command name, no output. The Command run log row appeared only after the call completed. In-flight tool calls render nothing for the Claude provider.
  • Variant B: the parent turn ended in ~8s ("running as background task "), the sidebar Working badge cleared, and for ~2.5 minutes the thread looked completely idle/finished while codex verifiably kept running. No indicator anywhere that background work existed. When the child exited, the thread spontaneously flipped back to Working ("The background Codex task finished — let me read its output") — on a thread the user had every reason to believe was done. Combined with auto-settle, this produces the settled-while-working and settle/un-settle churn described below.

On the released desktop app (0.0.31) the same workflow also intermittently shows the thread getting settled while the delegated agent is still working, then waking after.

Impact

Major degradation or frequent failure — with agent-to-agent delegation you cannot tell working threads from finished ones, and thread state flips by itself.

Version or commit

Desktop 0.0.31 (Alpha); reproduced on a dev build of main (2026-07-30) via the dev-runner web app

Environment

macOS 26.5.1, arm64. Claude provider (Claude Code 2.1.220) delegating to codex CLI 0.146.0.

Logs or stack traces

# During Variant A, while the transcript showed only "Working for 34s" with no tool row:
ps aux | grep 'codex exec' | grep -v grep
# -> codex exec --skip-git-repo-check "Read math.js and write a thorough code review..."  (running, spawned under the thread's Claude session)

Screenshots, recordings, or supporting files

Timeline observed on main (Variant B): turn ends 0:08 → sidebar idle while child runs 0:08–2:40 → child exits → thread flips back to Working by itself.

Workaround

None in-app; you have to check ps to know whether a thread is actually done.

Related

#4962 reports the same gap on mobile. The in-flight orchestration-v2 subagent observability series (#4779 #4629 #4662 #4663 #4664) and #4793 look like the intended fix vehicle; filing this so the desktop/web symptom — including in-flight tool-call invisibility and the settle/wake churn — is tracked against it.

Activity

  1. kelchm commented on Aug 7, 2026

    @kelchm

    I hit the same “only Working for Ns” behavior with a long Claude Bash tool that ran grok (~5.5 min). Server-side activities were present the whole time; the chat timeline filtered them out.

    Evidence from live state DB for one turn

    Time Activity Notes
    T+0 tool.started command_execution, detail Bash: {} (empty input)
    T+17s tool.updated status: "inProgress", full command in data.input.command
    ~T+20s task.started taskType: "local_bash", agentKind: "background", friendly title
    next ~5m nothing no task.progress for pure local_bash
    end task.completed + tool.completed tool row finally appears

    So ingestion is fine. The gap is presentation.

    Why the UI shows nothing while the tool runs

    1. deriveWorkLogEntries drops tool.started and task.started
      (apps/web/src/session-logic.ts)

    2. Live signal is only tool.updated with toolLifecycleStatus: "inProgress".

    3. deriveMessagesTimelineRows then filters out entries where workEntryIndicatesToolNeutralStatus is true
      (apps/web/src/components/chat/MessagesTimeline.logic.ts)

    4. inProgress is treated as not success → neutral → hidden
      (workEntryIndicatesToolSuccess / workEntryIndicatesToolNeutralStatus in session-logic.ts)

    5. Same neutral filter is applied again in WorkGroupSection (MessagesTimeline.tsx).

    6. local_bash background tasks often emit no task.progress while running (unlike local_agent subagents), so the task path also produces no durable live row. (task.started is already omitted by design — see tests: “omits task.started but shows task.progress and task.completed”.)

    Net: only the generic working indicator remains until tool.completed / success path makes the row non-neutral.

    Likely intentional filter, wrong for long tools

    The neutral filter was introduced with scroll-anchoring work in #3564 (24abab78 — “Stabilize chat scroll anchoring after send”). Hiding empty/incomplete rows makes sense; treating legitimate inProgress command_execution the same way matches Variant A exactly (“Command run appears only after completion”).

    Suggested fix (minimal)

    • Do not classify toolLifecycleStatus === "inProgress" as hide-neutral for timeline visibility (show a live tool row: name + truncated command).
    • Optionally also keep task.progress / outstanding background task.* visible (related: [Bug]: Mobile looks idle while background subagents are still working #4962 for mobile settle/badge).
    • Keep filtering truly empty shells (Bash: {} with no input yet) if needed for scroll stability.

    Repro note

    Any long Claude Bash is enough (not only delegated agent CLIs). Background local_bash makes it worse because there is no progress stream—only the filtered inProgress tool event.

  2. t3dotgg commented on Aug 28, 2026

    @t3dotgg
    Member

    Note

    🤖 GPT-5.6 Sol responding on behalf of Theo

    Thanks for the detailed report. We believe the original silent foreground tool activity and missing background-work indicator are fixed by PR #5219 and PR #7152.

    The landed work adds native task and workflow activity, keeps active tool work visible, and shows background liveness after the foreground turn ends. The remaining Variant B settlement bug is not fixed: a local_bash child can still be alive while settlement ignores its backgroundLiveness state. That condition is now preserved in open issue #5476, separate from its open-PR condition.

    I'm closing this as partly fixed and consolidated as part of an automated pass on all open issues. The remaining background-liveness settlement bug is not fixed, and issue #5476 remains open.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions