feat(workflow): CLI worker, worktrees, resume, schema#97
Conversation
Named/file script resolve, agent worktree factory, resume matcher (index+key then consume-once), and Ajv schema enforcement wired into agent(). Adds ajv dependency. Co-Authored-By: Claude <noreply@anthropic.com>
Detached __worker with heartbeat/cancel, real adapters via runLocalAgentProvider, worktree isolation, and resume wiring. setScriptPath persists script after run create. Co-Authored-By: Claude <noreply@anthropic.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
| }); | ||
|
|
||
| const persisted = | ||
| priorScriptPath ?? |
There was a problem hiding this comment.
[P0] Resume reuses the prior mutable script path and does not verify that the new run is in the same repository/workspace/base SHA. This can replay repository A in B, and prior.scriptHash can disagree with edited bytes executed later. Snapshot the exact validated source under the new run ID and require a matching repository identity/base revision (or an explicit override) before replay.
| console.log(formatRunLine(run)); | ||
| if (run.pid && (run.status === "running" || run.status === "starting")) { | ||
| try { | ||
| process.kill(run.pid, "SIGTERM"); |
There was a problem hiding this comment.
[P0] Sending SIGTERM immediately after setting the cooperative flag usually kills the worker before it can observe cancellation, clean up worktrees, or write terminal events. Please centralize CLI/MCP cancellation in a supervisor: request cancel, wait a grace period, then use the cross-platform terminateProcessTree fallback and atomically mark the run cancelled. The supervisor should also schedule reapStale().
| } | ||
| } | ||
|
|
||
| store.completeRun(runId, { resultJson }); |
There was a problem hiding this comment.
[P1] The run becomes completed before run_completed is appended. A status poll can observe terminal state and stop before the terminal event exists. Please update terminal status and append the corresponding terminal event in one SQLite transaction; use the same path for failed and cancelled runs.
| ? basePrompt | ||
| : `${basePrompt}\n\nPrevious JSON failed validation:\n${lastErrors}\nReturn only corrected JSON.`; | ||
|
|
||
| const result = await input.run(prompt); |
There was a problem hiding this comment.
[P1] lastSession is collected but never passed into the next provider call, so every schema retry starts a fresh agent context. Extend the provider input with providerSessionId and feed each attempt's returned ID into the next attempt. Also emit schema_retry only when another attempt will actually run.
There was a problem hiding this comment.
Addressed by PR #99 (a8b8e5a). providerSessionId is now part of the workflow provider input, each schema attempt carries forward the latest returned session ID, and the worker passes it into the provider adapter. schema_retry is emitted only when another attempt will actually run. Regression coverage verifies that attempt 2 receives the session ID from attempt 1.
| source: "export const meta = { name: 'x', description: 'd' }\nreturn 1\n", | ||
| preferredName: "demo", | ||
| }); | ||
| assert.match(path, /workflow-scripts\/wfr_test\/demo\.js$/); |
There was a problem hiding this comment.
[P1] This assertion is path-separator-specific and is the current Windows CI failure. Please compare normalized path segments, or compare against join('workflow-scripts', 'wfr_test', 'demo.js') after normalizing separators.
| function toHit(call: WorkflowAgentCallRecord): WorkflowReplayHit { | ||
| if (call.structuredJson) { | ||
| try { | ||
| return { |
There was a problem hiding this comment.
[P0] Replay restores only the previous return value; it does not recreate filesystem side effects or reconnect the preserved worktree. A cached mutating agent can report success while the new run contains none of its changes. Please make mutating calls non-cacheable by default, or persist/apply a patch or resume the exact worktree as part of the replay contract.
Summary
wf/<runId>/cN)agent({ schema })workflow run|status|cancel|ls|__worker(detached worker, heartbeat/cancel)Stack
PR4 of 5 · base:
pr/dw-3-engineTest plan
tsx src/workflow-files.test.tstsx src/workflow-replay.test.tstsx src/workflow-schema.test.ts./node_modules/.bin/tsx src/cli.ts workflow helpworkflow run --file …with fake/available provider;status/cancelnpm run typecheck