feat: add Workflows right-sidebar tab with live run streaming#3624
Conversation
|
@codex review |
09e6abb to
4b760e3
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4b760e314a
ℹ️ 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".
4b760e3 to
bfa9011
Compare
|
@codex review Addressed the P2: phase assignment now derives each step's first sequence from all step-bearing events ( |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bfa9011e9c
ℹ️ 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".
bfa9011 to
2dd9011
Compare
|
@codex review Addressed all three P2 findings:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2dd9011697
ℹ️ 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".
2dd9011 to
88128f4
Compare
|
@codex review Addressed all three P2 findings:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 88128f464a
ℹ️ 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".
|
@codex review Addressed both P2s: phase and step disclosure now use a shared |
88128f4 to
25e22c2
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 25e22c2685
ℹ️ 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".
25e22c2 to
156bfeb
Compare
|
@codex review Addressed both P2s in the empty-state launcher:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 156bfeb6fa
ℹ️ 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".
|
@codex review Addressed the P2: the launcher's required-field check now ignores required args that declare a default ( |
156bfeb to
efe36ad
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: efe36adac9
ℹ️ 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".
|
@codex review Addressed the P2: required boolean args with no default now block Start until the user sets the checkbox (the required-field predicate handles booleans via |
efe36ad to
fda04fb
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fda04fbc40
ℹ️ 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".
fda04fb to
407b5fc
Compare
|
@codex review Addressed both P2s in the launcher:
|
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ 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". |
407b5fc to
ba87d1b
Compare
|
@codex review Test-only change: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba87d1b309
ℹ️ 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".
|
@codex review Addressed the P3: required boolean args with no default are now seeded to |
ba87d1b to
855d3ad
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 855d3ad618
ℹ️ 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".
Implement the "Workflows Tab" design (imported from claude.ai/design) so a workspace's durable workflow runs get a dedicated, live observation surface in the right sidebar instead of relying on the large in-chat workflow tool card. Backend - workflows.subscribe: push stream (initial snapshot + per-write deltas) of a workspace's top-level runs. WorkflowService is constructed per oRPC request, so it can't be the singleton event source a subscription needs; instead every run mutation already flows through WorkflowRunStore.writeRunFile, which now notifies a module-level workflowRunStreamHub that the subscribe handler listens to. This decouples "who runs the workflow" (chat tool, CLI, background, crash recovery) from "who is watching it". - workflows.listScripts: enumerates runnable workflow scripts (built-in + project + global skills exposing a workflow.js) for the empty-state launcher, reusing the existing resolver/skill discovery and surfacing each script's declared args. Frontend - A pure, unit-tested projector folds the intentionally-lean run record (events + steps; steps carry no phase/title/usage) into the phase->step view the tab renders: phase assignment by event sequence, titles from task events, durations from timestamps, final report/error from events. - Timeline UI: run header (interrupt / resume / retry-from-checkpoint / re-run), phases (collapsed by default so a 20+ step fan-out stays scannable, with expandable phase info objects), expandable steps with per-step output + structured output, run history, and an empty-state launcher with a per-arg input form. The final report is collapsible and renders the full structured output returned to the agent, not just the summary chips. - The tab is gated on the dynamic-workflows experiment (it is that feature's observation surface) and added to the layout via the same per-experiment effect the memory/browser tabs use, with a live active-run count badge on the label. When the tab is available, the in-chat workflow tool card auto-collapses by default (any status); without it the prior behavior (auto-collapse completed runs only) is preserved, so behavior and the existing tests are unchanged when the experiment is off. Deferred deliberately: per-step token/cost (sub-agent usage rolls up into the parent workspace and isn't reliably queryable by task once a step completes) and converting a live foreground run to backgrounded (needs runner detach support; Interrupt covers the stop case). The projector/UI already accept a usage overlay for when per-step usage capture lands. Change-Id: I2bc47dc9c850af7b7d232c36aea18c4464fbdb78 Signed-off-by: Thomas Kosiewski <tk@coder.com>
855d3ad to
9e7c63e
Compare
|
@codex review Addressed both:
|
|
Codex Review: Didn't find any major issues. Another round soon, please! Reviewed commit: ℹ️ 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 Long-lived auto-cleanup PR maintained by the **Auto-Cleanup Agent**. Each pass lands at most one extremely low-risk, behavior-preserving cleanup drawn from recently merged `main` activity, then advances the checkpoint below. Auto-cleanup checkpoint: 620c2a6 This PR currently contains six accumulated cleanups against `main`: 1. `src/node/services/taskService.ts` — dedupe queued-message foreground backgrounding into a private helper. 2. `src/node/services/workflows/workflowScriptResolver.ts` — reuse the `SKILL_SCRIPT_PATH_PREFIX` constant for canonical-path construction. 3. `src/node/services/workflows/WorkflowTaskServiceAdapter.ts` — extract the duplicated agent-task creation arg shape into a shared `WorkflowTaskCreateArgs` type. 4. `src/constants/workspaceTags.ts` (new) — centralize the workspace-turn task tag keys, removing the cross-layer `"mux.taskHandleId"` string duplication. 5. `src/node/services/tools/workflowProgress.ts` — extract the duplicated "latest phase" lookup into a shared `getLatestPhaseEvent` helper. 6. `src/browser/features/RightSidebar/Workflows/WorkflowBadges.tsx` — map workflow run-status glyphs through an exhaustive `Record<WorkflowRunStatus, LucideIcon>` instead of a repeated `if`-chain. ## This pass Rebased the branch onto the latest `origin/main` (clean) and considered the three new commits since the prior checkpoint: - coder#3624 (`feat: add Workflows right-sidebar tab with live run streaming`) - coder#3626 (`tests: add UI primitive stories and fix design-sync previews`) - coder#3627 (`feat: return workflow plan agent results`) coder#3624 added `WorkflowBadges.tsx`, whose `WorkflowStatusIcon` selected a glyph through a four-branch `if`-chain that re-spelled the identical `className="h-3 w-3 shrink-0"` + `style={{ color }}` props in every branch and fell back to a default `<Circle>` for unmatched statuses. Replaced that with a module-level `WORKFLOW_STATUS_ICON: Record<WorkflowRunStatus, LucideIcon>` map (mirroring the existing `WORKFLOW_STATUS_META` / `WORKFLOW_TONE_VAR` records in the same feature) and render the looked-up icon once. Behavior-preserving: the map reproduces the prior mapping exactly (`pending`/`running` → `Circle`, `backgrounded`/`interrupted` → `Pause`, `completed` → `Check`, `failed` → `X`), and using a `Record` makes the mapping exhaustive so a newly added run status is a compile error here rather than a silent fall-through. coder#3626 (Storybook/design-sync, test-only) and coder#3627 (already extracts its own `__muxAgentReturnValue` runtime helper) offered no additional low-risk dedup. <details> <summary>Prior pass — workflowProgress getLatestPhaseEvent helper</summary> coder#3623 added `src/node/services/tools/workflowProgress.ts`, in which both `buildWorkflowProgressSummary` and `formatWorkflowProgressNote` independently re-spelled the same `run.events.findLast((event) => event.type === "phase")` expression to find the latest phase event. Extracted that into a single private `getLatestPhaseEvent(run)` helper and referenced it from both functions, giving the "latest phase" definition one source of truth so the summary builder and the note formatter can't drift. Behavior-preserving: the helper's body and inferred return type are identical to the inline expression, so both call sites compute exactly the same value. </details> <details> <summary>Prior pass — checkpoint-only advance for coder#3621 (Claude Design integration)</summary> coder#3621 is purely additive and lives entirely under `.design-sync/` (plus one `.gitignore` entry); it contains zero production (`src/`) code. `.design-sync/**` is outside both the ESLint scope (`src/**`) and the TypeScript `include`, so `make static-check` cannot validate the behavior-preservation of any refactor there. That pass advanced the checkpoint without a code change. </details> <details> <summary>Prior pass — workspace-turn task tag keys centralization</summary> The workspace-turn task tag key `"mux.taskHandleId"` is **written** by `TaskService.createWorkspaceTurn` (node, coder#3617/coder#3619) and **read** by `findWorkspaceForTaskTarget` in `TaskToolCall.tsx` (browser, coder#3613) — the same magic string duplicated across the node/browser boundary. Extracted the three workspace-turn task tag keys (`handle`, `ownerWorkspaceId`, `turn`) into a new `@/constants/workspaceTags` module and referenced `WORKSPACE_TURN_TASK_TAGS` from both the node write site and the browser read site. Behavior-preserving: the extracted values are byte-identical to the previous literals, so the persisted tag keys and all lookups are unchanged. </details> <details> <summary>Prior pass — WorkflowTaskServiceAdapter WorkflowTaskCreateArgs type</summary> `WorkflowTaskServiceLike` (in `WorkflowTaskServiceAdapter.ts`) declared the agent-task creation argument object **twice** — once inline in `create(args: { ... })` and again inside `createMany?(args: Array<{ ... }>)` — as byte-identical 10-field shapes. Extracted a named `WorkflowTaskCreateArgs` interface and referenced it from both `create` and `createMany`. Behavior-preserving: structurally identical interface, signatures unchanged. </details> <details> <summary>Prior pass — workflowScriptResolver SKILL_SCRIPT_PATH_PREFIX reuse</summary> In `workflowScriptResolver.ts`, the `skill://` prefix is named by the module-level constant `SKILL_SCRIPT_PATH_PREFIX`, but the two canonical-path builders re-spelled the literal `` `skill://${...}` `` instead of reusing the constant. Both builders now interpolate `${SKILL_SCRIPT_PATH_PREFIX}`. Behavior-preserving: `SKILL_SCRIPT_PATH_PREFIX` is exactly `"skill://"`, so the interpolation is byte-identical. </details> <details> <summary>Prior pass — taskService queued-message dedup</summary> Considered coder#3605 (`fix: background foreground waits for prequeued messages`), which open-coded the same queued-message guard at two `TaskService` wait-registration sites. Both sites now delegate to a single private helper `backgroundForegroundWaitIfQueued(shouldBackgroundOnQueuedMessage, requestingWorkspaceId)`. Behavior-preserving: the helper folds in the `requestingWorkspaceId` truthiness guard and the pushed call is unchanged. </details> ## Validation - `make static-check` is green for the touched code (ESLint, `tsconfig` + `tsconfig.main.json`, Prettier). (`fmt-shell-check` is the only non-passing step, solely because the `shfmt` binary is absent in this environment; no shell files are touched.) - Targeted tests pass: `bun test src/browser/features/RightSidebar/Workflows/workflowDisplay.test.ts src/browser/features/RightSidebar/Workflows/projectWorkflowRun.test.ts` (32 tests) cover the same Workflows feature module the change lives in. ## Risks Minimal. All accumulated changes are pure local extractions / constant reuse; no logic, types, or call semantics change. --- _Generated with `mux` • Model: `anthropic:claude-opus-4-8` • Thinking: `xhigh`_ <!-- mux-attribution: model=anthropic:claude-opus-4-8 thinking=xhigh --> --------- Co-authored-by: mux-bot[bot] <264182336+mux-bot[bot]@users.noreply.github.com>
Summary
Adds a Workflows tab to the right sidebar so a workspace's durable workflow runs get a dedicated, live observation surface — instead of relying on the large in-chat workflow tool call card. Implements the imported "Workflows Tab" design.
The tab is gated on the existing dynamic-workflows experiment (it is that feature's observation surface) and shows the focused run live, with run history and an empty-state launcher.
Backend
workflows.subscribe— push stream (initial snapshot + per-write deltas) of a workspace's top-level runs.WorkflowServiceis constructed per oRPC request, so it can't be the singleton event source a subscription needs; instead every run mutation already flows throughWorkflowRunStore.writeRunFile, which now notifies a module-levelworkflowRunStreamHubthat the subscribe handler listens to. This decouples who runs the workflow (chat tool, CLI, background, crash recovery) from who is watching it.workflows.listScripts— enumerates runnable workflow scripts (built-in + project + global skills exposing aworkflow.js) for the empty-state launcher, reusing the existing resolver/skill discovery and surfacing each script's declared args.Frontend
events+steps; steps carry no phase/title/usage) into the phase→step view: phase assignment by event sequence, titles from task events, durations from timestamps, final report/error from events.Behavior change
When the Workflows tab is available, the in-chat workflow tool card auto-collapses by default (any status). Without it, the prior behavior (auto-collapse completed runs only) is preserved — so behavior and existing tests are unchanged when the experiment is off.
Deferred (deliberate)
Testing
make typecheck,make lint, and the workflow suites all green (205 tests across the frontend Workflows + WorkflowRunToolCall + backend workflow + schema tests, including a dedicated projector test).