🤖 fix: show delegated workflow activity in sidebar#3459
Conversation
Roll descendant task activity up to parent workspace rows so slash workflow launchers stay visibly active without reusing generic streaming copy. Add focused sidebar, row, filtering, and task group tests for delegated activity states.
---
_Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `719628{MUX_COSTS_USD:-unknown}`_
<!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=131.74 -->
|
@codex review Please review the delegated-work sidebar roll-up, status precedence, task-group live fallback, and accessibility wiring. |
|
Codex Review: Didn't find any major issues. Swish! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review Pushed a follow-up test expectation update for the delegated-work active-dot behavior that failed the integration job. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ebe831460
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Addressed Codex finding
|
|
@codex review Please re-review after the resumed-delegated-task fix. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fc08a04d1a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Addressed Codex finding
|
|
@codex review Please re-review after the live-interrupted delegated activity fix. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ab88d3b982
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Addressed Codex finding
|
|
@codex review Please re-review after removing the tracked dogfood artifacts. |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
Adds delegated-work sidebar state for slash-launched workflows so launcher workspaces and collapsed task groups stay visibly active while descendant sub-agents are running, without reusing misleading assistant streaming copy.
Background
Slash workflows run in the background and spawn child task workspaces, so the launcher workspace can otherwise look idle while the workflow is actively faning out. This change keeps the derived state frontend-local and rolls descendant task activity up through workspace metadata.
Implementation
aria-describedbywhile keeping action-oriented row labels stable.reportedAtmetadata from an earlier completed run.dogfood-output/is ignored.Validation
bun test src/browser/utils/ui/workspaceFiltering.test.ts src/browser/components/AgentListItem/AgentListItem.test.tsx src/browser/components/ProjectSidebar/TaskGroupListItem.test.tsx src/browser/components/ProjectSidebar/ProjectSidebar.test.tsxTEST_INTEGRATION=1 bun x jest tests/ui/workspaces/subagents.test.ts --runInBand --silent=falsemake typecheckmake fmt-checkmake lintmake static-checkMUX_ESLINT_CONCURRENCY=1 make static-checkafter the default lint process was killed by local OOM.Dogfooding
Dogfooding was performed with local artifacts under
dogfood-output/workflow-sidebar/(screenshots, video, console, errors). Those artifacts are not tracked in this PR per the repository ignore policy.Risks
Moderate UI-state risk in the sidebar: the roll-up is derived from existing workspace metadata and live sidebar state, but it changes status precedence and grouped-row styling. Targeted unit/integration coverage exercises the precedence, terminal-state, metadata-lag, resumed-task, interrupted-live, and accessibility branches.
📋 Implementation Plan
Plan: Show slash-workflow delegated work in the left sidebar
Context and evidence
When a workflow is launched manually with
/workflow ..., the launcher workspace can look grey/inactive even while workflow-spawned sub-agents are running. The investigation found this is expected with current data flow:src/browser/components/AgentListItem/AgentListItem.tsxderives active row state from the workspace's own sidebar stream/provisioning state (canInterrupt,isStarting,isInitializing), not descendant task/workflow state.src/browser/components/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsxonly renders own workspace question/status/streaming/provisioning text.src/browser/utils/chatCommands.tscallapi.workflows.start({ runInBackground: true, rawCommand, continuationOptions, ... }); the parent workspace is not streaming during the background workflow run.src/node/services/workflows/WorkflowTaskServiceAdapter.ts→src/node/services/taskService.ts; those children carryparentWorkspaceId, optionalworkflowTask, andtaskStatusmetadata.src/browser/components/ProjectSidebar/TaskGroupListItem.tsxalready receives running/queued/completed counts for grouped children, but active groups still read visually muted.Recommendation
Implement a distinct delegated work sidebar state: the parent workspace should look active while descendant sub-agents/workflow tasks are active, but it should not pretend the parent assistant is streaming.
Recommended user-facing behavior:
Workflow running · 2 sub-agents activeor2 sub-agents active.WorkspaceStatusIndicatorstreaming copy is not reused for delegated work, so the UI avoids falsemodel - streaming...language.Net product LoC estimate for the recommended approach: +120 to +190 LoC.
Recommended approach: frontend descendant roll-up
Phase 1 — Model delegated activity in the sidebar
WorkspaceDelegatedActivity:activeCountqueuedCountworkflowActiveCountworkflowQueuedCountProjectSidebar.tsxor a small extracted helper (preferred for tests), derive aMap<string, WorkspaceDelegatedActivity>from the full per-project metadata list before completed-child filtering and task-group coalescing:workspace.idinto aMap<workspaceId, metadata>so multi-project render paths cannot double count a workspace.childrenByParentIdfromparentWorkspaceId.taskStatus === "running" || taskStatus === "awaiting_report"as active.taskStatus === "queued"as queued/pending.workflowOwned = own.workflowTask != null || ancestorWorkflowOwned, so nested descendants of workflow-owned tasks still produce workflow copy.workspaceStore.getWorkspaceSidebarState(child.id)so a live child stream remains active if metadata lags; wrap this read in a safe helper/catch because metadata/store teardown can race.workspaceHasAttention()so project/section headers also wake up when a workspace tree has active delegated work.Quality gate after Phase 1:
computeDelegatedActivityByWorkspaceIdhelper.Phase 2 — Render delegated activity in workspace rows
AgentListItemprops with optional delegated activity, keeping it UI-only and not crossing IPC boundaries.AgentListItem.tsx, computehasActiveDelegatedWorkfrom the prop.agentStatus/todo-derived status so old idle summaries do not hideWorkflow running · .... Concretely, treat own status as stale/inactive only when there is no owncanInterrupt, noisStarting, noawaitingUserQuestion, and no own system error.Workflow running · 2 sub-agents activeWorkflow running · 1 sub-agent active · 2 queued2 sub-agents activeQuality gate after Phase 2:
AgentListItem.test.tsxcovers:Phase 3 — Improve grouped sub-agent rows
TaskGroupListItem.tsx, userunningCount > 0(and optionallyqueuedCount > 0) to apply a clearer in-progress style to collapsed task groups.Quality gate after Phase 3:
runningCount > 0.Alternatives considered
Alternative A — child-row task-status fallback only
Make child rows active when their own
metadata.taskStatusisrunningorawaiting_report, even ifWorkspaceStorestreaming state is missing.Alternative B — backend workflow activity source
Add workflow-run activity to backend/sidebar state so the parent row is active while any workflow run for that workspace is
pending,running, orbackgrounded, even when no child agent is currently running.Alternative C — mark parent workspace streaming during workflow
Force the parent workspace activity snapshot to
streaming: truewhile the workflow runs.model - streaming...), wrong mental model, and likely wrong interrupt/control expectations.Acceptance criteria
streaming...unless the launcher workspace's own assistant turn is actually streaming.agentStatus/todo text does not mask active delegated-work text.Validation plan
Run targeted checks first, then broader static checks:
bun test src/browser/components/AgentListItem/AgentListItem.test.tsxbun test src/browser/components/ProjectSidebar/ProjectSidebar.test.tsxbun test src/browser/utils/ui/workspaceFiltering.test.tsif any shared filtering helper changes.make typecheckmake lintmake testor the closest repo-approved broader suite.Dogfooding plan
Skills read for dogfooding/setup:
dogfood,agent-browser, anddev-server-sandbox.make dev-server-sandbox DEV_SERVER_SANDBOX_ARGS="--clean-projects"VITE_PORTURL as the target URL.agent-browserskill:/workflow <name> <args>from the workspace chat input.screenshots/before.pngscreenshots/workflow-running-parent-active.pngscreenshots/task-group-running.pngif grouped rows applyscreenshots/workflow-completed.pngvideos/slash-workflow-sidebar.webmstreaming....Implementation notes and guardrails
Generated with
mux• Model:openai:gpt-5.5• Thinking:xhigh• Cost:$198.41