Skip to content

Architecture Case Study

Workflow Studio

Orchestration engine for autonomous developer tasks and code execution across shared codebases without state collision or branch drift. Built on an isolated task-dispatch engine backed by a local SQLite DAG.

Node.jsTypeScriptReactNext.jsSQLiteTask DAGLive Deployment ↗

1. The Situation

Running multiple coding agents (Claude, Codex, Antigravity) across active worktrees creates constant branch drift, overlapping file edits, and untracked task states.

2. The Constraint & Tension

The engine originally lived coupled inside a VS Code extension, making it impossible to drive from CLI scripts, CI test suites, or headless worker sessions without booting a full editor instance.

3. The Architecture Decision

Decoupled runtime logic into an isolated headless Node.js core engine (@workflow-studio/core) backed by an explicit SQLite task DAG using strict compile-time tsconfig boundaries. Implemented Kahn's algorithm for topological task ordering with strict cycle detection, and distributed task leases with monotonic fencing tokens to reject stale writes.

Consequence & Verified Outcome

Four separate surfaces consume the exact same core engine: the VS Code extension, the CLI, the dashboard SPA, and TradeSense. Headless CI runs the full task loop without mocking the VS Code host.

4. System Architecture

Architecture & Multi-Agent DAG TopologyDAG Kernel
@workflow-studio/coreDAG Engine · SQLite · Local APItypes: ["node"] (strict isolation)VS Code ExtensionTreeViews & CommandsCLI Toolbin/workflow-studio.mjsDashboard SPAworkflow.shivambhaipatelTradeSense Deskpackages/core (isolated import)AUTONOMOUS MULTI-AGENT EXECUTION CYCLE1. Task DAGDependency Tree2. Worker AgentClaude / Gemini3. Reviewer GateReviewer Verification4. Sync & PRGit / Jira Close
Hover nodes to inspect contract isolation

5. Verbatim Code Evidence

Artifact Excerptworkflow-studio/src/workflows/executor.ts:41-44
export function topologicalSort(def: WorkflowDefinition): string[] {
  const adj = new Map<string, string[]>();
  const inDeg = new Map<string, number>();
Artifact Excerptworkflow-studio/src/workflows/executor.ts:79-81
if (order.length !== def.nodes.length) {
    throw new Error('Workflow contains a cycle — not a valid DAG');
  }
Artifact Excerptworkflow-studio/src/taskLeases.ts:79-83
export function isFenceCurrent(store: TaskLeaseStore, taskId: string, epoch: number): boolean {
  const lease = store.leases[normalizeTaskId(taskId)];
  if (!lease) return false;
  return leaseEpochFor(lease) === epoch;
}

6. Trade-offs & What's Left

Extracting the core required duplicating some interface shims between VS Code tree views and CLI output formatters. Maintaining the strict Node-only tsconfig boundary requires careful re-export barrels in packages/core/src/index.ts.

Active Roadmap

  • Native desktop tray distribution
  • Automated tool and runtime prerequisite installer
  • Open-source core package publishing on npm