Visual debugger canvas for Node.js. Pause at a breakpoint, see the local scope as a graph, fork it, replay it with edited inputs, and let Anthropic's Sonnet write the patch.
Stage turns a paused Node.js debug session into a parallel-timelines canvas. When you hit a breakpoint inside a forkable function, Stage opens a webview that shows the real local scope as an editable graph (powered by React Flow). You can:
- Edit primitive values in place. Stage writes them back into the
live debug session via DAP
setExpression/setVariable, so continuing execution sees your new values. - Fork the timeline to explore counterfactuals without disturbing the
paused process. Forked timelines re-run the captured function in a
worker_threadssandbox with whatever edits you make. - Commit a timeline to extract a fix. Stage sends the function
source, your edits, and the observed state delta to Claude Sonnet 4.6
and opens a
vscode.diffview with the proposed change.
-
Install from VSIX (or from the Marketplace once published):
# latest VSIX is attached to every GitHub Release gh release download v0.1.0 --pattern '*.vsix' --repo Ijtihed/stage code --install-extension stage-0.1.0.vsix
-
Open the bundled demo workspace:
cd fixture-refund npm install -
Set a breakpoint on the
calculated_amount = …line infixture-refund/src/refund.tsand run Debug refund tests from the Run and Debug panel. Stage opens automatically. -
Click
tax_rate, type-0.05, press Enter, then Cmd+F to fork, Cmd+R to run. The fork should return95instead of105. -
Cmd+Enter to commit. Stage asks Sonnet to produce a one-line fix (flipping
+to-) and opens it invscode.diff. Apply, re-runnpm test, green line.
Stage uses VS Code's SecretStorage (OS keychain) for the API key.
Run Stage: Set Anthropic API Key from the command palette and paste
your key. Stage also falls back to the ANTHROPIC_API_KEY environment
variable when no secret is stored.
Run Stage: Clear Anthropic API Key to remove the stored key.
| Setting | Default | Description |
|---|---|---|
stage.maxTimelines |
4 |
Maximum number of parallel timelines visible on the canvas. |
stage.model |
claude-sonnet-4-6 |
Anthropic model id used for commit / fix proposals. |
stage.sandbox.timeoutMs |
30000 |
Wall-clock budget for a sandboxed timeline run (ms). |
stage.anthropicApiKey |
"" |
Deprecated. Prefer the Stage: Set Anthropic API Key command. |
| Action | Mac | Windows / Linux |
|---|---|---|
| Fork timeline | Cmd+F | Ctrl+F |
| Run timeline | Cmd+R | Ctrl+R |
| Commit / propose fix | Cmd+↵ | Ctrl+↵ |
Shortcuts only fire when the Stage canvas has focus.
The v0.1 sandbox profile accepts a narrow but useful slice of functions:
- Synchronous (no
async/await) - Plain identifier parameters (no destructuring or rest)
- No
fetch,fs,crypto, timers, dynamicimport(), orrequire() - Body under 200 lines
- Source on disk in the open workspace (not
node_modules, not virtual)
When a frame isn't forkable, the canvas surfaces the reason and the Fork / Run buttons stay disabled for that frame. Async, IO replay, and timer virtualization are tracked for v0.2.
The worker_threads sandbox is for crash containment (so an infinite
loop in your code can't freeze the extension host), not for isolating
untrusted code. Stage only runs source from your own workspace.
npm install
npm run lint
npm test # 34 Vitest tests across 9 files
npm run build # tsc + vite → out/ and media/webview.{js,css}
npm run test:extension # @vscode/test-electron headless smoke
npx vsce package # produces stage-0.1.0.vsixPress F5 with this repo open in VS Code to launch an
Extension Development Host preloaded with the fixture-refund
workspace.
Automated tests cover protocol, executor state machine, sandbox replay, LLM client shape, and headless extension activation. The full live-debug loop is best validated by hand once per release:
F5in this repo → launches Extension Dev Host withfixture-refund.- Set a breakpoint on the
calculated_amountline inrefund.ts. - Run Debug refund tests in the dev host's debug panel.
- Verify the Stage canvas auto-opens and renders
order,subtotal,tax_rate,calculated_amountwith their real DAP values. - Click
tax_rate, type-0.05, press Enter. Confirm VS Code's own Variables view reflects the new value (proves DAP write-back). - Cmd+F → Cmd+R. Confirm the forked pane shows
returnValue: 95. - Cmd+Enter without an API key set → confirm the "Set Anthropic API Key" message.
- Run Stage: Set Anthropic API Key, paste a real key,
Cmd+Enter again → confirm a
vscode.diffopens with the proposed operator fix.
