🤖 fix: queue busy workspace turn follow-ups#3617
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b71deba993
ℹ️ 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".
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
@codex review Please take another look. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 88454baa34
ℹ️ 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 Please take another look. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a7f766e0ca
ℹ️ 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 Please take another look. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 16df052fae
ℹ️ 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 Please take another look. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c81cd60a8d
ℹ️ 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 Please take another look. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7d312b326a
ℹ️ 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 Please take another look. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2921e7fe31
ℹ️ 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 Please take another look. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 08b110ef7f
ℹ️ 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 Please take another look. |
|
Codex thread response:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 09c95bd0ce
ℹ️ 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 Please take another look. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dfdbf7bb2e
ℹ️ 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 Please take another look. |
|
Codex Review: Didn't find any major issues. Bravo. 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". |
59e38fc to
800e96e
Compare
|
@codex review Rebased on latest main and squashed the final diff; please take another look. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 800e96e168
ℹ️ 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 Please take another look. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d58d894f5b
ℹ️ 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 Please take another look. |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! 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
Queue follow-up messages for busy existing workspace turns instead of failing when the target workspace is already running.
Background
Parent/orchestrator workspaces can target an already-created workspace with
task(kind="workspace", workspace.mode="existing"). That previously failed withexisting workspace is busy; wait until it is idle, even though the chat layer already supports queued follow-up messages.Implementation
workspace.queueDispatchModefor existing workspace turns so orchestrators can choosetool-endorturn-endqueue dispatch.Validation
env MUX_ESLINT_CONCURRENCY=1 make static-checkbun test src/node/services/messageQueue.test.ts src/node/services/tools/task.test.ts src/common/utils/tools/toolDefinitions.test.ts src/node/services/taskService.test.ts --test-name-pattern 'MessageQueue|workspace turn queue dispatch mode|accepts workspace turn queue dispatch mode|createWorkspaceTurn (creates a normal workspace|reprompts only owner-created|queues busy owner-created|reserves a slot before queueing|counts active workspace turns)|uncorrelated stream-end before queued workspace turn prompt'bun test tests/ui/chat/unreadIndicator.test.ts -t "hides Mark unread for already-unread rows"(local check for unrelated Integration CI flake)Risks
Moderate risk in workspace-turn orchestration and queued-message handling. The queue now carries internal callbacks, so the implementation keeps workspace-turn messages single-entry to avoid orphaning task handles or applying metadata to the wrong turn.
Generated with
mux• Model:openai:gpt-5.5• Thinking:xhigh• Cost:$24.67