@stigmer/runner 3.0.9-dev.20260615153829 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/approval-contract/types.d.ts +174 -0
- package/dist/__test-utils__/approval-contract/types.js +24 -0
- package/dist/__test-utils__/approval-contract/types.js.map +1 -0
- package/dist/activities/call-agent-status.d.ts +19 -1
- package/dist/activities/call-agent-status.js +64 -5
- package/dist/activities/call-agent-status.js.map +1 -1
- package/dist/activities/call-llm.js +19 -53
- package/dist/activities/call-llm.js.map +1 -1
- package/dist/activities/classify-tool-approvals.d.ts +24 -0
- package/dist/activities/classify-tool-approvals.js +69 -17
- package/dist/activities/classify-tool-approvals.js.map +1 -1
- package/dist/activities/discover-mcp-server.d.ts +7 -0
- package/dist/activities/discover-mcp-server.js +11 -1
- package/dist/activities/discover-mcp-server.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +140 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +130 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.d.ts +18 -0
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +123 -0
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -0
- package/dist/activities/execute-cursor/approval-policy.d.ts +17 -61
- package/dist/activities/execute-cursor/approval-policy.js +8 -120
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +219 -9
- package/dist/activities/execute-cursor/approval-state.js +233 -17
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/capture-flow.d.ts +127 -0
- package/dist/activities/execute-cursor/capture-flow.js +234 -0
- package/dist/activities/execute-cursor/capture-flow.js.map +1 -0
- package/dist/activities/execute-cursor/cas-observations.d.ts +96 -0
- package/dist/activities/execute-cursor/cas-observations.js +184 -0
- package/dist/activities/execute-cursor/cas-observations.js.map +1 -0
- package/dist/activities/execute-cursor/command-provenance.d.ts +62 -0
- package/dist/activities/execute-cursor/command-provenance.js +128 -0
- package/dist/activities/execute-cursor/command-provenance.js.map +1 -0
- package/dist/activities/execute-cursor/exact-apply.d.ts +110 -0
- package/dist/activities/execute-cursor/exact-apply.js +204 -0
- package/dist/activities/execute-cursor/exact-apply.js.map +1 -0
- package/dist/activities/execute-cursor/hook-script.d.ts +53 -24
- package/dist/activities/execute-cursor/hook-script.js +310 -47
- package/dist/activities/execute-cursor/hook-script.js.map +1 -1
- package/dist/activities/execute-cursor/index.d.ts +8 -1
- package/dist/activities/execute-cursor/index.js +500 -64
- package/dist/activities/execute-cursor/index.js.map +1 -1
- package/dist/activities/execute-cursor/message-translator.d.ts +258 -11
- package/dist/activities/execute-cursor/message-translator.js +836 -90
- package/dist/activities/execute-cursor/message-translator.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +20 -23
- package/dist/activities/execute-cursor/prompt-builder.js +74 -15
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/workspace-setup.d.ts +17 -0
- package/dist/activities/execute-cursor/workspace-setup.js +212 -33
- package/dist/activities/execute-cursor/workspace-setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.d.ts +19 -0
- package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.js +143 -0
- package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +88 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +81 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -0
- package/dist/activities/execute-deep-agent/approval-file-change.d.ts +47 -0
- package/dist/activities/execute-deep-agent/approval-file-change.js +68 -0
- package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -0
- package/dist/activities/execute-deep-agent/attachment-injector.d.ts +8 -1
- package/dist/activities/execute-deep-agent/attachment-injector.js +7 -7
- package/dist/activities/execute-deep-agent/attachment-injector.js.map +1 -1
- package/dist/activities/execute-deep-agent/cas-capture-backend.d.ts +42 -0
- package/dist/activities/execute-deep-agent/cas-capture-backend.js +47 -0
- package/dist/activities/execute-deep-agent/cas-capture-backend.js.map +1 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.d.ts +79 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js +112 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js.map +1 -0
- package/dist/activities/execute-deep-agent/hitl.d.ts +16 -3
- package/dist/activities/execute-deep-agent/hitl.js +11 -3
- package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
- package/dist/activities/execute-deep-agent/index.d.ts +2 -1
- package/dist/activities/execute-deep-agent/index.js +393 -33
- package/dist/activities/execute-deep-agent/index.js.map +1 -1
- package/dist/activities/execute-deep-agent/inline-publisher.d.ts +7 -1
- package/dist/activities/execute-deep-agent/inline-publisher.js +23 -2
- package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +53 -2
- package/dist/activities/execute-deep-agent/setup.js +149 -92
- package/dist/activities/execute-deep-agent/setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.d.ts +36 -0
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js +56 -0
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js.map +1 -0
- package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +34 -1
- package/dist/activities/execute-deep-agent/status-builder-shared.js +26 -25
- package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
- package/dist/activities/execute-deep-agent/status-builder.d.ts +17 -5
- package/dist/activities/execute-deep-agent/status-builder.js +44 -3
- package/dist/activities/execute-deep-agent/status-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +2 -19
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming.js +3 -15
- package/dist/activities/execute-deep-agent/streaming.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +25 -7
- package/dist/activities/execute-deep-agent/subagent-transformer.js +23 -7
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +30 -3
- package/dist/activities/execute-deep-agent/subagent-wiring.js +29 -3
- package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
- package/dist/activities/execute-deep-agent/v3-status-builder.js +32 -2
- package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
- package/dist/claimcheck/payload-codec.js +9 -5
- package/dist/claimcheck/payload-codec.js.map +1 -1
- package/dist/client/stigmer-client.d.ts +2 -0
- package/dist/client/stigmer-client.js +2 -0
- package/dist/client/stigmer-client.js.map +1 -1
- package/dist/middleware/approval-gate.d.ts +85 -4
- package/dist/middleware/approval-gate.js +165 -38
- package/dist/middleware/approval-gate.js.map +1 -1
- package/dist/middleware/types.d.ts +2 -5
- package/dist/shared/activity-input.d.ts +43 -0
- package/dist/shared/activity-input.js +17 -0
- package/dist/shared/activity-input.js.map +1 -0
- package/dist/shared/approval-canonicalize.d.ts +19 -0
- package/dist/shared/approval-canonicalize.js +119 -0
- package/dist/shared/approval-canonicalize.js.map +1 -0
- package/dist/shared/approval-fingerprint.d.ts +106 -0
- package/dist/shared/approval-fingerprint.js +113 -0
- package/dist/shared/approval-fingerprint.js.map +1 -0
- package/dist/shared/approval-policy.d.ts +182 -12
- package/dist/shared/approval-policy.js +213 -27
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/shared/args-preview.d.ts +52 -0
- package/dist/shared/args-preview.js +93 -0
- package/dist/shared/args-preview.js.map +1 -0
- package/dist/shared/artifact-storage.d.ts +19 -1
- package/dist/shared/artifact-storage.js +48 -11
- package/dist/shared/artifact-storage.js.map +1 -1
- package/dist/shared/file-change.d.ts +44 -0
- package/dist/shared/file-change.js +57 -0
- package/dist/shared/file-change.js.map +1 -0
- package/dist/shared/file-tools.d.ts +107 -0
- package/dist/shared/file-tools.js +168 -0
- package/dist/shared/file-tools.js.map +1 -0
- package/dist/shared/filereview/capture.d.ts +202 -0
- package/dist/shared/filereview/capture.js +498 -0
- package/dist/shared/filereview/capture.js.map +1 -0
- package/dist/shared/filereview/cas-substrate.d.ts +190 -0
- package/dist/shared/filereview/cas-substrate.js +284 -0
- package/dist/shared/filereview/cas-substrate.js.map +1 -0
- package/dist/shared/filereview/digest.d.ts +40 -0
- package/dist/shared/filereview/digest.js +66 -0
- package/dist/shared/filereview/digest.js.map +1 -0
- package/dist/shared/filereview/events.d.ts +170 -0
- package/dist/shared/filereview/events.js +298 -0
- package/dist/shared/filereview/events.js.map +1 -0
- package/dist/shared/filereview/git-substrate.d.ts +175 -0
- package/dist/shared/filereview/git-substrate.js +439 -0
- package/dist/shared/filereview/git-substrate.js.map +1 -0
- package/dist/shared/filereview/index.d.ts +11 -0
- package/dist/shared/filereview/index.js +12 -0
- package/dist/shared/filereview/index.js.map +1 -0
- package/dist/shared/filereview/secret-paths.d.ts +63 -0
- package/dist/shared/filereview/secret-paths.js +105 -0
- package/dist/shared/filereview/secret-paths.js.map +1 -0
- package/dist/shared/fingerprint-secret.d.ts +26 -0
- package/dist/shared/fingerprint-secret.js +47 -0
- package/dist/shared/fingerprint-secret.js.map +1 -0
- package/dist/shared/model-client.d.ts +51 -0
- package/dist/shared/model-client.js +77 -0
- package/dist/shared/model-client.js.map +1 -0
- package/dist/shared/plan-artifact.js +0 -2
- package/dist/shared/plan-artifact.js.map +1 -1
- package/dist/shared/status-offload.d.ts +83 -9
- package/dist/shared/status-offload.js +399 -79
- package/dist/shared/status-offload.js.map +1 -1
- package/dist/shared/status.js +14 -1
- package/dist/shared/status.js.map +1 -1
- package/dist/shared/tool-kind.d.ts +19 -0
- package/dist/shared/tool-kind.js +13 -0
- package/dist/shared/tool-kind.js.map +1 -1
- package/dist/shared/tool-row.d.ts +88 -0
- package/dist/shared/tool-row.js +127 -0
- package/dist/shared/tool-row.js.map +1 -0
- package/dist/shared/workspace/platform-dir.d.ts +25 -0
- package/dist/shared/workspace/platform-dir.js +38 -2
- package/dist/shared/workspace/platform-dir.js.map +1 -1
- package/dist/workflows/call-agent-orchestrator.js +56 -7
- package/dist/workflows/call-agent-orchestrator.js.map +1 -1
- package/dist/workflows/connect-mcp-server.d.ts +50 -0
- package/dist/workflows/connect-mcp-server.js +136 -15
- package/dist/workflows/connect-mcp-server.js.map +1 -1
- package/dist/workflows/types.d.ts +8 -0
- package/package.json +2 -2
- package/src/__test-utils__/approval-contract/contract.ts +224 -0
- package/src/__test-utils__/approval-contract/types.ts +179 -0
- package/src/__test-utils__/fake-artifact-storage.ts +72 -0
- package/src/__tests__/approval-gateway-contract.test.ts +29 -0
- package/src/__tests__/claimcheck-codec.test.ts +16 -53
- package/src/__tests__/golden-e2e.test.ts +2 -0
- package/src/__tests__/runner-token-coordinator.test.ts +3 -3
- package/src/activities/__tests__/call-agent-status.test.ts +135 -0
- package/src/activities/__tests__/call-llm.test.ts +1 -1
- package/src/activities/__tests__/classify-tool-approvals.test.ts +208 -1
- package/src/activities/__tests__/discover-mcp-server.test.ts +30 -0
- package/src/activities/__tests__/workflow-event-activities.test.ts +2 -1
- package/src/activities/call-agent-status.ts +74 -4
- package/src/activities/call-llm.ts +18 -63
- package/src/activities/classify-tool-approvals.ts +101 -19
- package/src/activities/discover-mcp-server.ts +29 -1
- package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +216 -0
- package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +148 -0
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +41 -9
- package/src/activities/execute-cursor/__tests__/approval-state.test.ts +292 -0
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +68 -1
- package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +1005 -0
- package/src/activities/execute-cursor/__tests__/cas-observations.test.ts +187 -0
- package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +97 -0
- package/src/activities/execute-cursor/__tests__/command-provenance.test.ts +240 -0
- package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +203 -0
- package/src/activities/execute-cursor/__tests__/exact-apply.test.ts +375 -0
- package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +1294 -24
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +446 -0
- package/src/activities/execute-cursor/__tests__/hook-script.test.ts +384 -110
- package/src/activities/execute-cursor/__tests__/message-translator.test.ts +171 -25
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +189 -0
- package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +44 -23
- package/src/activities/execute-cursor/__tests__/workspace-setup.test.ts +190 -10
- package/src/activities/execute-cursor/approval-policy.ts +28 -159
- package/src/activities/execute-cursor/approval-state.ts +366 -18
- package/src/activities/execute-cursor/capture-flow.ts +323 -0
- package/src/activities/execute-cursor/cas-observations.ts +204 -0
- package/src/activities/execute-cursor/command-provenance.ts +168 -0
- package/src/activities/execute-cursor/exact-apply.ts +253 -0
- package/src/activities/execute-cursor/hook-script.ts +317 -51
- package/src/activities/execute-cursor/index.ts +575 -67
- package/src/activities/execute-cursor/message-translator.ts +963 -89
- package/src/activities/execute-cursor/prompt-builder.ts +80 -14
- package/src/activities/execute-cursor/workspace-setup.ts +257 -42
- package/src/activities/execute-deep-agent/__test-utils__/gateway-substrate.ts +180 -0
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +134 -0
- package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +84 -0
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +11 -24
- package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +64 -0
- package/src/activities/execute-deep-agent/__tests__/cas-capture-observer.test.ts +163 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +8 -5
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +342 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +284 -0
- package/src/activities/execute-deep-agent/__tests__/hitl.test.ts +14 -36
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +31 -13
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +349 -0
- package/src/activities/execute-deep-agent/__tests__/stamp-flowed-rows.test.ts +119 -0
- package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +91 -10
- package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +9 -9
- package/src/activities/execute-deep-agent/__tests__/subagent-approval-propagation.test.ts +160 -0
- package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +213 -0
- package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +3 -6
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +84 -1
- package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +4 -1
- package/src/activities/execute-deep-agent/approval-file-change.ts +80 -0
- package/src/activities/execute-deep-agent/attachment-injector.ts +20 -11
- package/src/activities/execute-deep-agent/cas-capture-backend.ts +66 -0
- package/src/activities/execute-deep-agent/cas-capture-observer.ts +125 -0
- package/src/activities/execute-deep-agent/hitl.ts +23 -7
- package/src/activities/execute-deep-agent/index.ts +463 -40
- package/src/activities/execute-deep-agent/inline-publisher.ts +27 -4
- package/src/activities/execute-deep-agent/setup.ts +223 -125
- package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +64 -0
- package/src/activities/execute-deep-agent/status-builder-shared.ts +62 -23
- package/src/activities/execute-deep-agent/status-builder.ts +63 -8
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +2 -16
- package/src/activities/execute-deep-agent/streaming.ts +3 -13
- package/src/activities/execute-deep-agent/subagent-transformer.ts +53 -13
- package/src/activities/execute-deep-agent/subagent-wiring.ts +50 -3
- package/src/activities/execute-deep-agent/v3-status-builder.ts +36 -2
- package/src/claimcheck/payload-codec.ts +8 -8
- package/src/client/stigmer-client.ts +9 -1
- package/src/middleware/__tests__/approval-gate.test.ts +488 -4
- package/src/middleware/approval-gate.ts +247 -38
- package/src/middleware/types.ts +5 -5
- package/src/shared/__tests__/activity-input.test.ts +78 -0
- package/src/shared/__tests__/approval-canonicalize.test.ts +106 -0
- package/src/shared/__tests__/approval-fingerprint.test.ts +115 -0
- package/src/shared/__tests__/approval-policy.test.ts +274 -40
- package/src/shared/__tests__/args-preview.test.ts +78 -0
- package/src/shared/__tests__/artifact-storage-extended.test.ts +62 -10
- package/src/shared/__tests__/artifact-storage.test.ts +123 -11
- package/src/shared/__tests__/file-change.test.ts +85 -0
- package/src/shared/__tests__/file-tools.test.ts +90 -0
- package/src/shared/__tests__/fingerprint-secret.test.ts +51 -0
- package/src/shared/__tests__/lease-scope-corpus.test.ts +56 -0
- package/src/shared/__tests__/model-client.test.ts +162 -0
- package/src/shared/__tests__/plan-artifact.test.ts +11 -26
- package/src/shared/__tests__/policy-source-corpus.test.ts +58 -0
- package/src/shared/__tests__/status-offload.test.ts +573 -16
- package/src/shared/__tests__/status.test.ts +4 -5
- package/src/shared/__tests__/tool-kind.test.ts +24 -1
- package/src/shared/__tests__/tool-row.test.ts +221 -0
- package/src/shared/activity-input.ts +57 -0
- package/src/shared/approval-canonicalize.ts +159 -0
- package/src/shared/approval-fingerprint.ts +148 -0
- package/src/shared/approval-policy.ts +303 -27
- package/src/shared/args-preview.ts +98 -0
- package/src/shared/artifact-storage.ts +62 -11
- package/src/shared/checkpointer/__tests__/http-saver.test.ts +1 -2
- package/src/shared/file-change.ts +64 -0
- package/src/shared/file-tools.ts +169 -0
- package/src/shared/filereview/__tests__/capture.test.ts +856 -0
- package/src/shared/filereview/__tests__/cas-substrate.test.ts +404 -0
- package/src/shared/filereview/__tests__/digest.test.ts +100 -0
- package/src/shared/filereview/__tests__/events.test.ts +245 -0
- package/src/shared/filereview/__tests__/git-substrate.test.ts +362 -0
- package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +286 -0
- package/src/shared/filereview/__tests__/secret-paths.test.ts +121 -0
- package/src/shared/filereview/capture.ts +727 -0
- package/src/shared/filereview/cas-substrate.ts +401 -0
- package/src/shared/filereview/digest.ts +83 -0
- package/src/shared/filereview/events.ts +449 -0
- package/src/shared/filereview/git-substrate.ts +555 -0
- package/src/shared/filereview/index.ts +60 -0
- package/src/shared/filereview/secret-paths.ts +121 -0
- package/src/shared/fingerprint-secret.ts +53 -0
- package/src/shared/model-client.ts +122 -0
- package/src/shared/plan-artifact.ts +0 -2
- package/src/shared/status-offload.ts +433 -77
- package/src/shared/status.ts +13 -0
- package/src/shared/tool-kind.ts +33 -0
- package/src/shared/tool-row.ts +135 -0
- package/src/shared/workspace/platform-dir.ts +41 -2
- package/src/workflow-engine/__tests__/golden-execution.test.ts +35 -18
- package/src/workflow-engine/__tests__/tasks/try.test.ts +1 -1
- package/src/workflows/__tests__/connect-mcp-server.test.ts +304 -29
- package/src/workflows/call-agent-orchestrator.ts +53 -6
- package/src/workflows/connect-mcp-server.ts +179 -24
- package/src/workflows/types.ts +8 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A capture-mode `FilesystemBackend` that observes gitignored file mutations for
|
|
3
|
+
* CAS review (design docs 08/11/12; the `.gitignored` half of apply-then-review).
|
|
4
|
+
*
|
|
5
|
+
* WHY A BACKEND WRAPPER, NOT THE APPROVAL GATE
|
|
6
|
+
* --------------------------------------------
|
|
7
|
+
* Capture is a property of the TURN, not of authorization — exactly like the git
|
|
8
|
+
* substrate, which snapshots the working tree at the turn boundary regardless of
|
|
9
|
+
* how or whether a tool was gated. File review opens even under the global bypass
|
|
10
|
+
* (`spec.auto_approve_all`), where the approval gate is not installed at all, so
|
|
11
|
+
* sourcing the before-bytes from the gate would let gitignored edits silently
|
|
12
|
+
* escape review under auto-approve-all. Observing at the backend keeps CAS
|
|
13
|
+
* capture gate-independent, so it is symmetric with the git-tracked path.
|
|
14
|
+
*
|
|
15
|
+
* THIS CLASS IS A THIN ADAPTER
|
|
16
|
+
* ----------------------------
|
|
17
|
+
* All capture state and logic live in the shared {@link CasCaptureObserver} (one
|
|
18
|
+
* per turn). The parent graph and every sub-agent graph are each handed a backend
|
|
19
|
+
* pointing at the SAME observer, so their gitignored writes compose into one CAS
|
|
20
|
+
* change set with race-free first-touch-wins (see the observer's docs). This
|
|
21
|
+
* backend only forwards the mutation point to the observer before delegating to
|
|
22
|
+
* the base `FilesystemBackend`.
|
|
23
|
+
*
|
|
24
|
+
* deepagents mutates only via `write` (create/overwrite) and `edit` (modify);
|
|
25
|
+
* there is no backend delete/rename, so this observes CREATE and MODIFY. A
|
|
26
|
+
* gitignored delete can only arrive via shell, which stays on the approval gate.
|
|
27
|
+
*
|
|
28
|
+
* @since File-Change HITL Redesign (Phase 3 — CAS deep-agent wiring); sub-agent
|
|
29
|
+
* gitignored capture parity (Session 26, DD-19)
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { FilesystemBackend } from "deepagents";
|
|
33
|
+
import type { CasCaptureObserver } from "./cas-capture-observer.js";
|
|
34
|
+
|
|
35
|
+
export type { CasBeforeMap } from "./cas-capture-observer.js";
|
|
36
|
+
|
|
37
|
+
type FilesystemBackendOptions = NonNullable<
|
|
38
|
+
ConstructorParameters<typeof FilesystemBackend>[0]
|
|
39
|
+
>;
|
|
40
|
+
|
|
41
|
+
export class CasCaptureFilesystemBackend extends FilesystemBackend {
|
|
42
|
+
private readonly observer: CasCaptureObserver;
|
|
43
|
+
|
|
44
|
+
constructor(
|
|
45
|
+
options: FilesystemBackendOptions,
|
|
46
|
+
deps: { readonly observer: CasCaptureObserver },
|
|
47
|
+
) {
|
|
48
|
+
super(options);
|
|
49
|
+
this.observer = deps.observer;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
override async write(filePath: string, content: string) {
|
|
53
|
+
await this.observer.recordBefore(filePath);
|
|
54
|
+
return super.write(filePath, content);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
override async edit(
|
|
58
|
+
filePath: string,
|
|
59
|
+
oldString: string,
|
|
60
|
+
newString: string,
|
|
61
|
+
replaceAll?: boolean,
|
|
62
|
+
) {
|
|
63
|
+
await this.observer.recordBefore(filePath);
|
|
64
|
+
return super.edit(filePath, oldString, newString, replaceAll);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single owner of one turn's CAS (content-addressed) capture state for the
|
|
3
|
+
* deep-agent activity — the `.gitignored` half of apply-then-review (design docs
|
|
4
|
+
* 08/11/12).
|
|
5
|
+
*
|
|
6
|
+
* WHY ONE SHARED OBSERVER (NOT PER-BACKEND STATE)
|
|
7
|
+
* -----------------------------------------------
|
|
8
|
+
* Capture is a property of the TURN, not of any single graph. The parent graph
|
|
9
|
+
* AND every sub-agent graph run against the same workspace root within one turn,
|
|
10
|
+
* and up to {@link SubAgentGate} sub-agents run CONCURRENTLY. If each filesystem
|
|
11
|
+
* backend held its own before-map + reservation, two graphs touching the same
|
|
12
|
+
* gitignored path could each read a "before" — the later one reading mid-turn
|
|
13
|
+
* (post-write) bytes as the baseline, corrupting the reviewed diff and breaking
|
|
14
|
+
* the "reviewed == applied" invariant.
|
|
15
|
+
*
|
|
16
|
+
* Making ONE observer own the before-map AND the reservation set fixes this by
|
|
17
|
+
* construction: `reserving.add` is synchronous (executes before the first
|
|
18
|
+
* `await` in {@link recordBefore}), so first-touch-wins holds across every
|
|
19
|
+
* backend instance that delegates here — the parent and all sub-agents.
|
|
20
|
+
*
|
|
21
|
+
* WHAT IT OWNS
|
|
22
|
+
* ------------
|
|
23
|
+
* - `before`: the pre-turn bytes of each first-touched gitignored path
|
|
24
|
+
* (`null` = the path did not exist → an ADD), read at the turn boundary to
|
|
25
|
+
* build the CAS `before` side.
|
|
26
|
+
* - `blockedSecretPaths`: gitignored paths the approval gate hard-blocked as
|
|
27
|
+
* secret-like (DD-E) — never applied, never captured; the boundary authors a
|
|
28
|
+
* content-less `DIFF_UNREVIEWABLE` entry for each (path only — the name is not
|
|
29
|
+
* the secret; the CONTENT never leaves the workspace).
|
|
30
|
+
*
|
|
31
|
+
* The AFTER bytes are re-read from disk at the turn boundary (the authoritative
|
|
32
|
+
* net result of the turn), so multiple edits to one path collapse to one
|
|
33
|
+
* before/after. Git-tracked paths are never recorded here — the turn-boundary git
|
|
34
|
+
* diff captures them — so memory is bounded to the gitignored scope.
|
|
35
|
+
*
|
|
36
|
+
* @since File-Change HITL Redesign (Phase 3 — CAS deep-agent wiring); sub-agent
|
|
37
|
+
* gitignored capture parity (Session 26, DD-19)
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
import { readFile } from "node:fs/promises";
|
|
41
|
+
import { resolveWorkspacePath } from "../../shared/file-change.js";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Pre-turn bytes of each first-touched gitignored path, keyed by workspace-root-
|
|
45
|
+
* relative path. `null` means the path did not exist before the turn (an ADD).
|
|
46
|
+
*/
|
|
47
|
+
export type CasBeforeMap = Map<string, Uint8Array | null>;
|
|
48
|
+
|
|
49
|
+
export class CasCaptureObserver {
|
|
50
|
+
private readonly rootDir: string;
|
|
51
|
+
/** Raw (uncached) gitignore predicate; results are memoized in {@link ignoredCache}. */
|
|
52
|
+
private readonly isIgnoredRaw: (relPath: string) => Promise<boolean>;
|
|
53
|
+
|
|
54
|
+
/** Pre-turn bytes of first-touched gitignored paths (see {@link CasBeforeMap}). */
|
|
55
|
+
readonly before: CasBeforeMap = new Map();
|
|
56
|
+
|
|
57
|
+
/** Paths whose before-read is in flight — the synchronous first-touch lock. */
|
|
58
|
+
private readonly reserving = new Set<string>();
|
|
59
|
+
/** Memoized `git check-ignore` results (one classification per distinct path). */
|
|
60
|
+
private readonly ignoredCache = new Map<string, boolean>();
|
|
61
|
+
/** Gitignored paths hard-blocked as secret-like (never applied, never captured). */
|
|
62
|
+
private readonly blocked = new Set<string>();
|
|
63
|
+
|
|
64
|
+
constructor(deps: {
|
|
65
|
+
readonly rootDir: string;
|
|
66
|
+
/** True when the workspace-relative path is gitignored (CAS-owned). Uncached. */
|
|
67
|
+
readonly isIgnored: (relPath: string) => Promise<boolean>;
|
|
68
|
+
}) {
|
|
69
|
+
this.rootDir = deps.rootDir;
|
|
70
|
+
this.isIgnoredRaw = deps.isIgnored;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Gitignored paths the gate refused as secret-like, read at the turn boundary. */
|
|
74
|
+
get blockedSecretPaths(): ReadonlySet<string> {
|
|
75
|
+
return this.blocked;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Record the pre-turn bytes of `rawPath` when it is a first-touched gitignored
|
|
80
|
+
* path. First-touch-wins across ALL backends sharing this observer: the slot is
|
|
81
|
+
* reserved SYNCHRONOUSLY (before the first `await`), so two concurrent
|
|
82
|
+
* mutations of the same path — even from different graphs — cannot both read a
|
|
83
|
+
* post-write "before". Non-gitignored paths (git-tracked) are ignored here; the
|
|
84
|
+
* turn-boundary git diff captures them.
|
|
85
|
+
*/
|
|
86
|
+
async recordBefore(rawPath: string): Promise<void> {
|
|
87
|
+
const { path: relPath, absolutePath } = resolveWorkspacePath(rawPath, this.rootDir, true);
|
|
88
|
+
if (this.before.has(relPath) || this.reserving.has(relPath)) return;
|
|
89
|
+
this.reserving.add(relPath);
|
|
90
|
+
try {
|
|
91
|
+
if (!(await this.isPathIgnored(relPath))) return;
|
|
92
|
+
// Re-check after the await: a concurrent call may have won the slot.
|
|
93
|
+
if (this.before.has(relPath)) return;
|
|
94
|
+
this.before.set(relPath, await readBytesOrNull(absolutePath));
|
|
95
|
+
} finally {
|
|
96
|
+
this.reserving.delete(relPath);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Record a gitignored path the approval gate hard-blocked as secret-like. The
|
|
102
|
+
* raw path is resolved to the same workspace-relative key the CAS reconcile
|
|
103
|
+
* uses, so the boundary can author its `DIFF_UNREVIEWABLE` entry. Idempotent.
|
|
104
|
+
*/
|
|
105
|
+
recordBlockedSecret(rawPath: string): void {
|
|
106
|
+
this.blocked.add(resolveWorkspacePath(rawPath, this.rootDir, true).path);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private async isPathIgnored(relPath: string): Promise<boolean> {
|
|
110
|
+
const cached = this.ignoredCache.get(relPath);
|
|
111
|
+
if (cached !== undefined) return cached;
|
|
112
|
+
const ignored = await this.isIgnoredRaw(relPath);
|
|
113
|
+
this.ignoredCache.set(relPath, ignored);
|
|
114
|
+
return ignored;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Raw bytes of a file, or `null` when it does not exist (an ADD). */
|
|
119
|
+
async function readBytesOrNull(absolutePath: string): Promise<Uint8Array | null> {
|
|
120
|
+
try {
|
|
121
|
+
return await readFile(absolutePath);
|
|
122
|
+
} catch {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -51,6 +51,16 @@ export interface GraphInterrupt {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export interface InterruptValue {
|
|
54
|
+
/**
|
|
55
|
+
* The interrupt's own id — the canonical key LangGraph matches a
|
|
56
|
+
* `Command(resume={...})` map against. For a parent-level tool interrupt this
|
|
57
|
+
* coincides with the owning task id, but for a *nested sub-agent* interrupt
|
|
58
|
+
* the two differ: the sub-agent's interrupt surfaces under the parent task
|
|
59
|
+
* that ran the `task` tool, and ONLY this id routes the resume value back into
|
|
60
|
+
* the sub-agent's `interrupt()`. Keying by `task.id` silently skips sub-agent
|
|
61
|
+
* approvals (verified empirically in subagent-approval-propagation.test.ts).
|
|
62
|
+
*/
|
|
63
|
+
readonly id?: string;
|
|
54
64
|
readonly value: Record<string, unknown>;
|
|
55
65
|
readonly resumeValue?: unknown;
|
|
56
66
|
}
|
|
@@ -61,15 +71,17 @@ export interface InterruptValue {
|
|
|
61
71
|
* Returns a `Command(resume=...)` if there are pending interrupts with
|
|
62
72
|
* matching approval decisions, or a fresh user message input if this is
|
|
63
73
|
* not a resume scenario.
|
|
74
|
+
*
|
|
75
|
+
* The graph checkpoint snapshot is read once by the caller and passed in: the
|
|
76
|
+
* same snapshot also decides whether status must be seeded from the persisted
|
|
77
|
+
* transcript (see `index.ts`), and on the durable (http) saver an extra
|
|
78
|
+
* `getState` is a network round-trip best avoided.
|
|
64
79
|
*/
|
|
65
|
-
export
|
|
80
|
+
export function resolveResumeInput(
|
|
66
81
|
execution: AgentExecution,
|
|
67
|
-
|
|
68
|
-
langgraphConfig: Record<string, unknown>,
|
|
82
|
+
graphState: GraphStateSnapshot,
|
|
69
83
|
userMessage: string,
|
|
70
|
-
):
|
|
71
|
-
const graphState = await agentGraph.getState(langgraphConfig);
|
|
72
|
-
|
|
84
|
+
): ResumeResult {
|
|
73
85
|
const pendingInterrupts = extractPendingInterrupts(graphState);
|
|
74
86
|
if (pendingInterrupts.length === 0) {
|
|
75
87
|
return {
|
|
@@ -152,7 +164,11 @@ function extractPendingInterrupts(state: GraphStateSnapshot): PendingInterrupt[]
|
|
|
152
164
|
if (typeof value === "object" && value !== null) {
|
|
153
165
|
const toolCallId = (value as Record<string, unknown>).tool_call_id;
|
|
154
166
|
if (typeof toolCallId === "string" && toolCallId) {
|
|
155
|
-
|
|
167
|
+
// Key on the interrupt's own id (falling back to task.id for the
|
|
168
|
+
// parent-level case where they coincide). This is what makes a
|
|
169
|
+
// sub-agent approval resume into the nested interrupt rather than
|
|
170
|
+
// being dropped — see InterruptValue.id.
|
|
171
|
+
result.push({ interruptId: intr.id ?? task.id, toolCallId });
|
|
156
172
|
}
|
|
157
173
|
}
|
|
158
174
|
}
|