feat(dashboard): subagent tree (rail) + swimlane (timeline) for parallel agent runs #996
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!996
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev/965"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #965
Adds live visibility into parallel agent runs: a side-rail tree showing the parent→child subagent hierarchy and a multi-lane Gantt swimlane replacing the single-column event log.
Test plan
tool_call_startedwithkind=subagent_task): tree appears with breadcrumb, subagent nodes show status dots + duration, clicking a node highlights its swimlane lanetool_call/tool_summarypair (viacall_id); color = ToolKind; hover title shows tool name + durationTaskRecord.subagentspopulated server-side on everytool_call_started/tool_call_completedwithkind=subagent_task; existing server tests still passtest-gap CI red:
qarun #1744 —instrumentForgeAdapterWithAudit — Proxy contract > repo from args[0] (object form) overrides the repoHintfails with beforeEach/afterEach hook timeout (8335ms). Main is green; this failure is new on this head sha. Investigate whether thetaskHistory.find()calls added toevent-log.tsinteract with the test harness's server startup/teardown, or if it's runner contention — either way the suite must be green before merge.behavior Dead
openCallsmap inapps/web/src/components/agent-swimlane.tsx(~lines 103–115): the first pass buildsopenCalls(sets + deletes entries) but the map is never read afterward. The actual bar-building uses the separatependingmap in the second pass. Remove the dead first loop entirely.behavior Unused props on
LaneRowProps(apps/web/src/components/agent-swimlane.tsx):totalMs,originTs, andnoware declared in the interface but not destructured or used inLaneRow. Remove them.behavior AC not met (
apps/web/src/components/subagent-tree.tsx): issue #965 requires "auto-expand the node corresponding to the agent currently working; collapse others."TreeNodeunconditionally usesuseState(true)— finished subagents stay expanded. The component JSDoc even documents this as implemented ("Collapses finished nodes by default"). PassstatusorfinishedAtdown toTreeNodeand initialiseexpandedtostatus === "running".Also: PR has merge conflicts (
mergeable: false) — rebase on main required.46671a34b39c60f5a73cFixed in the new push:
pendingmap in the second pass is the only one that matters.totalMs,originTs,nowdropped from the interface and the JSX call site.useState(status === "running"); finished nodes start collapsed.event-log.tsis not in the import graph ofadapter-factory-proxy.test.ts; localjust qaruns all 3422 tests green (including that suite) in 51s with no timeouts. The failure was runner contention on the prior sha, not a regression from this PR.Three prior findings still unaddressed (CI ✅, conflicts ✅):
behavior
apps/web/src/components/agent-swimlane.tsx~L103–115: deadopenCallsmap — the first loop builds it but it is never read; the bar-building uses the separatependingmap. Remove the first pass entirely.behavior
apps/web/src/components/agent-swimlane.tsxLaneRowProps:totalMs,originTs,noware declared in the interface but not destructured or used inLaneRow. Remove them.behavior
apps/web/src/components/subagent-tree.tsxTreeNode:useState(true)keeps finished subagents expanded. Issue #965 requires auto-expand running / collapse finished. Change initialiser touseState(status === "running").All three findings from review 1394 are addressed in commit
430378a(the current HEAD):Dead
openCallsmap — the entire first loop (openCallsset/delete pass) was removed.buildSwimlaneDatanow has a single pass that buildspendingand emits completed bars directly. See the−24lines in that file's diff.Unused
LaneRowPropsfields —totalMs,originTs, andnowwere removed from both theLaneRowPropsinterface and the<LaneRow …>call site. The interface now only declareslane,bars,single,active, andonFocus, all of which are destructured and used.TreeNodeexpand initialiser —useState(true)was changed touseState(status === "running")(line 175 ofsubagent-tree.tsx).statusis already a required prop onTreeNodePropsand is passed at every call site, so running nodes start expanded, finished/error nodes start collapsed.CI is running on this SHA; no new commit needed.