Skip to content

refactor(mcp): move workflow orchestration to the CLI - #142

Open
Waishnav wants to merge 4 commits into
codex/dw-cli-contractfrom
codex/dw-cli-only-surface
Open

refactor(mcp): move workflow orchestration to the CLI#142
Waishnav wants to merge 4 commits into
codex/dw-cli-contractfrom
codex/dw-cli-only-surface

Conversation

@Waishnav

@Waishnav Waishnav commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Dedicated MCP workflow tools duplicated the CLI contract and tied long-running orchestration to a request-response transport. This layer removes those execution tools and their live workflow dashboard while keeping the host as the visible orchestrator through ordinary shell or process tools.

open_workspace remains model-useful but small: usable provider names, profile name and description, and active workflow id, name, status, plus running, completed, and failed call counts. Active runs are scoped by workspace identity so separate workspaces on the same checkout do not leak into each other.

Verified with npm run typecheck, focused workspace-summary tests, and the full test suite.

Summary by CodeRabbit

  • Improvements

    • Workspace dashboards now show active workflows with clear status and agent-call counts.
    • Agent and provider details are presented in a simpler, more focused format.
    • Workspace views load faster by removing detailed workflow monitoring, diagnostics, and refresh polling.
  • Changes

    • Dedicated workflow launch, monitoring, cancellation, and detailed workflow views are no longer available.
    • Workspace capability responses now omit skill diagnostics and focus on supported agents, profiles, and active workflows.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change replaces workflow tools and detailed workflow views with active workflow summaries. The server exposes simplified agent and workflow data. The workspace UI removes workflow polling and renders summary information directly.

Changes

Workflow summary integration

Layer / File(s) Summary
Active workflow summary API
src/workflow-summary.ts, src/workflow-summary.test.ts, package.json
loadActiveWorkflowSummaries filters active runs and aggregates running, completed, and failed call counts. Tests cover workspace scoping and cleanup. The test script runs workflow-view.test.ts.
Workspace capability contract
src/server.ts, src/open-workspace-capabilities.test.ts
Workspace responses expose simplified provider and agent data, active workflow counts, and only starting or running workflows. skillDiagnostics and legacy workflow tool registration are removed. The capability test validates the new schema.

Workspace UI simplification

Layer / File(s) Summary
Workspace UI simplification
src/ui/card-types.ts, src/ui/workflow-dashboard.ts, src/ui/workspace-app.tsx, src/ui/icons.ts, src/ui/tool-display.ts, src/ui/*test.ts
The UI consumes activeWorkflows directly. Detailed workflow monitoring, polling, workflow cards, workflow icons, and workflow-tool display mappings are removed. Agent and provider rendering uses simplified fields.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • Waishnav/devspace#78: Adds the durable WorkflowStore infrastructure used by the new active workflow summaries.
  • Waishnav/devspace#112: Directly overlaps with the workflow dashboard, workflow tools, server integration, and card changes.
  • Waishnav/devspace#118: Modifies the same workspace capability and workflow dashboard data shapes.

Poem

A rabbit hops through summaries bright,
Old workflow tools leave the night.
Counts now run, complete, or fail,
Simple profiles fill the trail.
The workspace blooms with less to show.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: moving workflow orchestration from MCP tools to the CLI.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/dw-cli-only-surface

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Waishnav Waishnav changed the title codex/dw cli only surface refactor(mcp): move workflow orchestration to the CLI Aug 8, 2026
@greptile-apps

greptile-apps Bot commented Aug 8, 2026

Copy link
Copy Markdown

Greptile Summary

This PR makes dynamic workflow orchestration CLI-only, simplifies the workspace application payload, and replaces the detailed workflow UI with compact active-run summaries.

  • Removes MCP workflow launch, status, cancellation, and live-dashboard tools.
  • Reduces exposed agent-provider, agent-profile, diagnostic, and workflow-summary fields.
  • Adds a compact workflow summary loader scoped by workspace identity.
  • Updates workspace-card rendering and related tests for the reduced contract.

Confidence Score: 4/5

The workflow summary scoping defect should be fixed before merging because active CLI-created workflows can disappear from open_workspace results.

open_workspace always supplies a fresh workspace ID, causing the store to ignore the matching project root and exclude active runs created by ordinary CLI sessions; the bundled skill also still advertises the removed MCP tools.

Files Needing Attention: src/server.ts and src/workflow-summary.ts

Important Files Changed

Filename Overview
src/server.ts Removes MCP workflow registration and reduces open_workspace output, but the new workspace-ID scope misses root-only CLI workflow runs.
src/workflow-summary.ts Introduces compact active-workflow summaries with consistent call aggregation, while inheriting workspace-ID-preferred filtering from the store.
src/workflow-tools.ts Deletes the MCP orchestration and workflow-dashboard tool surface as part of the intended CLI-only contract.
src/ui/workspace-app.tsx Removes workflow polling and detailed workflow-card rendering consistently with the deleted MCP UI tools.
src/ui/workflow-dashboard.ts Simplifies the workspace dashboard to render static compact workflow summaries and reduced provider/profile metadata.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[open_workspace] --> B[Generate workspace ID]
  B --> C[loadActiveWorkflowSummaries]
  C --> D{workspaceId present?}
  D -->|Yes| E[Query runs by workspace_id only]
  D -->|No| F[Query runs by workspace_root]
  G[CLI workflow run without injected ID] --> H[Persist run with project root only]
  H -. missed by .-> E
Loading

Reviews (1): Last reviewed commit: "fix(mcp): scope workflow summaries by wo..." | Re-trigger Greptile

Comment thread src/server.ts
Comment thread src/server.ts
@Waishnav
Waishnav force-pushed the codex/dw-cli-only-surface branch from 2c242a6 to f421b2c Compare August 8, 2026 00:57
@Waishnav
Waishnav force-pushed the codex/dw-cli-only-surface branch from f421b2c to 869b57f Compare August 8, 2026 00:59
@Waishnav
Waishnav force-pushed the codex/dw-cli-only-surface branch from 869b57f to 8766c96 Compare August 8, 2026 01:02
@Waishnav
Waishnav force-pushed the codex/dw-cli-only-surface branch from 8766c96 to 7d602ea Compare August 8, 2026 01:10
@Waishnav

Waishnav commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

[gpt-5.4] RESPONDING ON BEHALF OF WAISHNAV

Fixed the workflow visibility issue across 801feb5 and 7d602ea. A workspace-ID scope now includes root-only runs created by standalone CLI harnesses while still excluding runs owned by another workspace ID. Store and workspace-summary tests cover both sides of that boundary.

The stale MCP skill guidance is also valid, but it belongs to the intentionally separate skill layer immediately above this PR. PR #143 removes those MCP instructions and provider internals in e01dd87 and ee2693c, so the complete stack does not advertise the removed tools.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

@Waishnav I will perform a full review of PR #142.

⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 57 minutes.

@Waishnav

Waishnav commented Aug 9, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/server.ts (1)

276-281: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Derive the workflow status enum from the shared constant.

src/workflow-summary.ts line 4 defines ACTIVE_WORKFLOW_STATUSES as the single source of active statuses. Line 279 repeats the same literals. If a status is added to ACTIVE_WORKFLOW_STATUSES, this schema rejects the new value during output validation, and open_workspace fails at runtime instead of at compile time.

Export the constant and build the enum from it, so the two stay in sync.

♻️ Proposed change to remove the duplicated literal set

In src/workflow-summary.ts, export the constant:

-const ACTIVE_WORKFLOW_STATUSES = ["starting", "running"] as const satisfies readonly WorkflowRunStatus[];
+export const ACTIVE_WORKFLOW_STATUSES = ["starting", "running"] as const satisfies readonly WorkflowRunStatus[];

In src/server.ts, import it and derive the enum:

-import { loadActiveWorkflowSummaries } from "./workflow-summary.js";
+import { ACTIVE_WORKFLOW_STATUSES, loadActiveWorkflowSummaries } from "./workflow-summary.js";
 const workflowRunSummaryOutputSchema = z.object({
   id: z.string(),
   name: z.string(),
-  status: z.enum(["starting", "running"]),
+  status: z.enum(ACTIVE_WORKFLOW_STATUSES),
   calls: workflowCallCountsOutputSchema,
 });

Confirm that z.enum() accepts a readonly tuple in zod 4.4.3 before you apply this change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/server.ts` around lines 276 - 281, Export ACTIVE_WORKFLOW_STATUSES from
workflow-summary.ts, then import it in server.ts and derive
workflowRunSummaryOutputSchema.status from that shared constant instead of
duplicating the literals. Confirm the installed Zod version accepts the
constant’s readonly tuple in z.enum(); preserve the existing validation behavior
while keeping future status additions synchronized.
src/workflow-summary.test.ts (1)

51-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for a run owned by the queried workspace ID.

The fixture contains one root-only run and one run owned by workspace-2. The assertion proves that root-only runs are included and foreign runs are excluded. It does not prove that a run created with workspaceId: "workspace-1" is returned. A regression that dropped matching-ID runs would still pass.

Also consider covering failed calls and the from_cache branch in loadActiveWorkflowSummaries, because both aggregation paths are currently unexercised.

💚 Proposed additional fixture and assertion
+  const owned = store.createRun({
+    name: "Owned",
+    source: "named",
+    scriptPath: join(root, "owned.js"),
+    scriptHash: "owned",
+    workspaceRoot,
+    workspaceId: "workspace-1",
+  });
   store.claimRun(run.id, process.pid);
   assert.deepEqual(loadActiveWorkflowSummaries(store, {
     workspaceId: "workspace-1",
     workspaceRoot,
   }), [
+    {
+      id: owned.id,
+      name: "Owned",
+      status: "starting",
+      calls: { running: 0, completed: 0, failed: 0 },
+    },
     {
       id: run.id,
       name: "Review",
       status: "running",
       calls: { running: 1, completed: 1, failed: 0 },
     },
   ]);

Confirm the ordering returned by listRunsForScope before you fix the expected array order.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/workflow-summary.test.ts` around lines 51 - 61, Add test coverage in the
workflow summary fixture for a run explicitly owned by workspace-1, then assert
it is returned by loadActiveWorkflowSummaries alongside the root-owned run while
workspace-2 remains excluded. Confirm listRunsForScope ordering before setting
the expected array order, and extend the assertions to exercise failed call
aggregation and the from_cache branch.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/open-workspace-capabilities.test.ts`:
- Around line 48-73: Update the `skillDiagnostics` assertion in the
`enabledSchema` test to inspect the schema shape via the existing `fields()`
helper, asserting that `skillDiagnostics` is absent from the declared keys. Do
not rely solely on `"skillDiagnostics" in parsed`, since the parsed input does
not include that field; optionally add a parse-level stripping check only if
supported by the project’s Zod version.

In `@src/ui/card-types.ts`:
- Around line 59-64: Use a loose card-side shape for activeWorkflows in
src/ui/card-types.ts lines 59-64, with optional id, name, status, and Partial
calls, while preserving ActiveWorkflowSummary as the server contract. In
src/ui/workflow-dashboard.ts lines 127-141, add nullish fallbacks when reading
run.name and run.status and update summaryCounts to accept optional partial
calls.

---

Nitpick comments:
In `@src/server.ts`:
- Around line 276-281: Export ACTIVE_WORKFLOW_STATUSES from workflow-summary.ts,
then import it in server.ts and derive workflowRunSummaryOutputSchema.status
from that shared constant instead of duplicating the literals. Confirm the
installed Zod version accepts the constant’s readonly tuple in z.enum();
preserve the existing validation behavior while keeping future status additions
synchronized.

In `@src/workflow-summary.test.ts`:
- Around line 51-61: Add test coverage in the workflow summary fixture for a run
explicitly owned by workspace-1, then assert it is returned by
loadActiveWorkflowSummaries alongside the root-owned run while workspace-2
remains excluded. Confirm listRunsForScope ordering before setting the expected
array order, and extend the assertions to exercise failed call aggregation and
the from_cache branch.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 126a3642-992e-49a2-930c-282a0057e49b

📥 Commits

Reviewing files that changed from the base of the PR and between 801feb5 and 7d602ea.

📒 Files selected for processing (15)
  • package.json
  • src/open-workspace-capabilities.test.ts
  • src/server.ts
  • src/ui/card-types.test.ts
  • src/ui/card-types.ts
  • src/ui/icons.ts
  • src/ui/tool-display.test.ts
  • src/ui/tool-display.ts
  • src/ui/workflow-dashboard.ts
  • src/ui/workspace-app.tsx
  • src/workflow-summary.test.ts
  • src/workflow-summary.ts
  • src/workflow-tools.ts
  • src/workflow-ui.test.ts
  • src/workflow-ui.ts
💤 Files with no reviewable changes (7)
  • src/ui/icons.ts
  • src/ui/tool-display.ts
  • src/workflow-tools.ts
  • src/ui/tool-display.test.ts
  • src/workflow-ui.ts
  • src/workflow-ui.test.ts
  • src/ui/card-types.test.ts

Comment on lines +48 to +73
const parsed = enabledSchema.parse({
workspaceId: "workspace-1",
root: process.cwd(),
mode: "checkout",
agentsFiles: [],
availableAgentsFiles: [],
skills: [],
agentProviders: ["codex"],
agents: [{ name: "reviewer", description: "Review changes." }],
activeWorkflows: [{
id: "wfr_1",
name: "Review",
status: "running",
calls: { running: 1, completed: 2, failed: 0 },
}],
instruction: "Reuse this workspace.",
});
assert.deepEqual(parsed.agentProviders, ["codex"]);
assert.deepEqual(parsed.agents, [{ name: "reviewer", description: "Review changes." }]);
assert.deepEqual(parsed.activeWorkflows, [{
id: "wfr_1",
name: "Review",
status: "running",
calls: { running: 1, completed: 2, failed: 0 },
}]);
assert.equal("skillDiagnostics" in parsed, false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Line 73 does not test what it intends to test.

The parsed input at lines 48-64 never contains skillDiagnostics. "skillDiagnostics" in parsed is therefore false no matter what the schema declares. The assertion passes even if openWorkspaceOutputSchema reintroduces the field.

Assert against the schema shape instead. The file already has a fields() helper at lines 16-18 that returns the shape keys.

💚 Proposed stronger assertion
-assert.equal("skillDiagnostics" in parsed, false);
+assert.equal(
+  fields({ ...baseEnv, DEVSPACE_SUBAGENTS: "1", DEVSPACE_WORKFLOWS: "1" }).has("skillDiagnostics"),
+  false,
+);

If you want to keep a parse-level check as well, pass the field in the input and confirm that z.object strips it:

+const stripped = enabledSchema.parse({
+  ...validInput,
+  skillDiagnostics: [{ path: "a", message: "b" }],
+});
+assert.equal("skillDiagnostics" in stripped, false);

Confirm the strip-by-default behavior of z.object in zod 4.4.3 before you rely on the second form.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const parsed = enabledSchema.parse({
workspaceId: "workspace-1",
root: process.cwd(),
mode: "checkout",
agentsFiles: [],
availableAgentsFiles: [],
skills: [],
agentProviders: ["codex"],
agents: [{ name: "reviewer", description: "Review changes." }],
activeWorkflows: [{
id: "wfr_1",
name: "Review",
status: "running",
calls: { running: 1, completed: 2, failed: 0 },
}],
instruction: "Reuse this workspace.",
});
assert.deepEqual(parsed.agentProviders, ["codex"]);
assert.deepEqual(parsed.agents, [{ name: "reviewer", description: "Review changes." }]);
assert.deepEqual(parsed.activeWorkflows, [{
id: "wfr_1",
name: "Review",
status: "running",
calls: { running: 1, completed: 2, failed: 0 },
}]);
assert.equal("skillDiagnostics" in parsed, false);
const parsed = enabledSchema.parse({
workspaceId: "workspace-1",
root: process.cwd(),
mode: "checkout",
agentsFiles: [],
availableAgentsFiles: [],
skills: [],
agentProviders: ["codex"],
agents: [{ name: "reviewer", description: "Review changes." }],
activeWorkflows: [{
id: "wfr_1",
name: "Review",
status: "running",
calls: { running: 1, completed: 2, failed: 0 },
}],
instruction: "Reuse this workspace.",
});
assert.deepEqual(parsed.agentProviders, ["codex"]);
assert.deepEqual(parsed.agents, [{ name: "reviewer", description: "Review changes." }]);
assert.deepEqual(parsed.activeWorkflows, [{
id: "wfr_1",
name: "Review",
status: "running",
calls: { running: 1, completed: 2, failed: 0 },
}]);
assert.equal(
fields({ ...baseEnv, DEVSPACE_SUBAGENTS: "1", DEVSPACE_WORKFLOWS: "1" }).has("skillDiagnostics"),
false,
);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/open-workspace-capabilities.test.ts` around lines 48 - 73, Update the
`skillDiagnostics` assertion in the `enabledSchema` test to inspect the schema
shape via the existing `fields()` helper, asserting that `skillDiagnostics` is
absent from the declared keys. Do not rely solely on `"skillDiagnostics" in
parsed`, since the parsed input does not include that field; optionally add a
parse-level stripping check only if supported by the project’s Zod version.

Comment thread src/ui/card-types.ts
Comment on lines +59 to 64
activeWorkflows?: ActiveWorkflowSummary[];
agentProviders?: string[];
agents?: Array<{
name?: string;
description?: string;
provider?: string;
model?: string;
effort?: string;
}>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Strict ActiveWorkflowSummary type applied to an unvalidated host payload. The card adopts the server-side contract type, which requires id, name, status, and calls. The value arrives through structuredContent from the host, and isToolResultCard only checks that the value is an object. The dashboard then dereferences the required fields, so a malformed entry throws a TypeError before container.replaceChildren(root) runs and the whole workspace dashboard fails to render.

  • src/ui/card-types.ts#L59-L64: declare a loose card-side shape for activeWorkflows with optional id, name, status, and a Partial calls; keep ActiveWorkflowSummary as the server-side contract.
  • src/ui/workflow-dashboard.ts#L127-L141: apply ?? fallbacks for run.name and run.status, and change summaryCounts to accept an optional partial calls object.
📍 Affects 2 files
  • src/ui/card-types.ts#L59-L64 (this comment)
  • src/ui/workflow-dashboard.ts#L127-L141
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/ui/card-types.ts` around lines 59 - 64, Use a loose card-side shape for
activeWorkflows in src/ui/card-types.ts lines 59-64, with optional id, name,
status, and Partial calls, while preserving ActiveWorkflowSummary as the server
contract. In src/ui/workflow-dashboard.ts lines 127-141, add nullish fallbacks
when reading run.name and run.status and update summaryCounts to accept optional
partial calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant