[Bug]: Foreground Bash calls promoted to local_bash tasks render with the Bot (subagent) icon while the Agents panel correctly excludes them
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/web
Summary
When a Claude Code foreground Bash call runs longer than ~2 s, Claude Code registers it as a local_bash task and emits task_started / task_completed system messages for it. T3 ingests those as task.started / task.completed activities, correctly stamps them agentKind: "background", and correctly keeps them out of the Agents panel. But the timeline renders the resulting work row with the Bot (robot) icon, because the icon picker keys on "has a taskId" rather than on the agentKind stamp. The user sees a robot row in the transcript, looks for the subagent in the Agents panel, and finds nothing.
So the two surfaces disagree: the Agents panel says "not an agent", the timeline row says "agent". The comment on the icon rule even says these rows are "subagent lifecycle rows", which is only true for agent-kind tasks.
Related but distinct: #9107 is about background-from-start shells being invisible. This report is about foreground shells that get task-promoted showing agent chrome they should not have.
Steps to reproduce
- Open a thread using the Claude Code provider.
- Have the agent run any foreground Bash command that takes more than ~2–3 s, e.g.
sleep 5 && exit 2(a non-zero exit makes the tint obvious, but the icon is wrong either way). - Watch the timeline after the command finishes.
Expected behavior
The task lifecycle row for a local_bash task should render with the same terminal/command chrome as the Bash call it belongs to (or be folded into that Bash row). The Bot icon should be reserved for rows whose task is classified agentKind: "agent", matching what the Agents panel shows.
Actual behavior
A separate collapsed row appears with the Lucide Bot icon, titled with the Bash call's description, and with the same description repeated as the monospace detail line. On a failed exit the icon is tinted with the failed-tool colour, so it reads as an orange/red robot. The Agents panel shows no agent for it.
Activity sequence recorded for one such call (ids elided), all sharing one toolUseId:
tool.started itemType=command_execution title="Command run" (Bash)
tool.updated itemType=command_execution status=inProgress
task.started taskType=local_bash agentKind=background title=<Bash description> detail=<Bash description> (~3 s after tool.started)
task.completed taskType=local_bash agentKind=background status=failed tone=error
tool.updated itemType=command_execution status=failed
tool.completed itemType=command_execution status=failed
The Bash row itself renders fine with the terminal icon. The extra robot row comes from the task.* pair.
Where the icon decision comes from (main @ 223ff44)
- Icon picker falls through to
"bot"for any work entry with ataskId, regardless ofagentKind:
https://github.com/pingdotgg/t3code/blob/223ff4490f764a74ff911589e97b9bbcd595fee8/apps/web/src/components/chat/MessagesTimeline.tsx#L3062-L3065 - Group summary kind does the same (
entry.taskId→"agent-tool"→"bot"):
https://github.com/pingdotgg/t3code/blob/223ff4490f764a74ff911589e97b9bbcd595fee8/packages/client-runtime/src/work-log/presentation.ts#L614
https://github.com/pingdotgg/t3code/blob/223ff4490f764a74ff911589e97b9bbcd595fee8/apps/web/src/components/chat/MessagesTimeline.tsx#L2150-L2151 - The server-side classification already exists and puts
local_bashon the non-agent list:
https://github.com/pingdotgg/t3code/blob/223ff4490f764a74ff911589e97b9bbcd595fee8/packages/contracts/src/providerRuntime.ts#L595-L624 - The client already reads that stamp for the Agents panel and marks the work entry
isBackgroundTask, but nothing in the icon path consults it:
https://github.com/pingdotgg/t3code/blob/223ff4490f764a74ff911589e97b9bbcd595fee8/packages/client-runtime/src/state/subagentRuntime.ts#L119-L121
https://github.com/pingdotgg/t3code/blob/223ff4490f764a74ff911589e97b9bbcd595fee8/apps/web/src/session-logic.ts#L620-L622
Claude Code side, for context: a foreground Bash that passes ~2 s of wall time is registered as a local_bash task (isBackgrounded: false) so it can offer backgrounding; the task_started payload's description is the Bash tool's description argument, which is why title and detail are the same string.
Suggested fix
In workEntryIconName and toolGroupSummaryKind, treat entry.taskId as agent chrome only when the entry is not isBackgroundTask (or when the payload's agentKind === "agent"). Background task rows could use "terminal" when taskType is in MONITOR_TASK_TYPES, or simply fall back to the tone icon. Alternatively, fold local_bash task rows into the parent Bash row keyed by toolUseId, since they carry no information the Bash row does not already have.
Impact
Cosmetic issue
Version or commit
Server: t3 0.0.39-nightly.20260905.1290. Source references above are against main @ 223ff44.
Environment
Linux host running t3 serve, accessed from the web UI in a desktop browser. Claude Code provider (CLI 2.1.263), model claude-fable-5-1.
Workaround
None needed; expanding the row shows it is just the Bash description, and the Agents panel is correct. The confusion is purely the icon.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/web/src/components/chat/MessagesTimeline.tsx and packages/client-runtime/src/work-log/presentation.ts, then trace the existing isBackgroundTask and agentKind handling in subagentRuntime.ts, session-logic.ts, and providerRuntime.ts. Update the icon and group-summary decisions so local_bash background-task rows do not use agent chrome, and verify that agent tasks retain the Bot icon while the reproduced Bash row uses terminal or equivalent non-agent chrome.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100