@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-storage.js","sourceRoot":"","sources":["../../src/shared/artifact-storage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"artifact-storage.js","sourceRoot":"","sources":["../../src/shared/artifact-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure path + binary-detection helpers shared by the native (deepagents) and
|
|
3
|
+
* Cursor harnesses' file-review capture.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately dependency-free and side-effect-free: no file IO, no diff
|
|
6
|
+
* computation, no proto knowledge. `resolveWorkspacePath` normalizes a touched
|
|
7
|
+
* path to (display path, absolute path); `looksBinary`/`bytesLookBinary` are the
|
|
8
|
+
* single definition of "binary" across every capture substrate.
|
|
9
|
+
*
|
|
10
|
+
* @since First-Class Diff Review (#186)
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Heuristic binary detection: a NUL byte never appears in valid UTF-8 text. This
|
|
14
|
+
* is a safety net, not a feature — the native edit/write tools are string-based,
|
|
15
|
+
* so captured content is text in practice.
|
|
16
|
+
*/
|
|
17
|
+
export declare function looksBinary(content: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Byte-level binary detection: a NUL byte never appears in valid UTF-8 text. The
|
|
20
|
+
* single definition of "binary" shared by every substrate that reads raw bytes
|
|
21
|
+
* (the git substrate's blob reads and the CAS substrate's captured bodies), so
|
|
22
|
+
* "what is binary" is decided one way across the whole file-review subsystem.
|
|
23
|
+
*
|
|
24
|
+
* Prefer this over {@link looksBinary} whenever the raw bytes are in hand: it is
|
|
25
|
+
* exact, whereas scanning a UTF-8-decoded string can miss a NUL that a lossy
|
|
26
|
+
* decode dropped.
|
|
27
|
+
*/
|
|
28
|
+
export declare function bytesLookBinary(bytes: Uint8Array): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Derive the workspace-root-relative display path and the absolute on-disk path
|
|
31
|
+
* for a file a tool touched.
|
|
32
|
+
*
|
|
33
|
+
* `virtualRoot` distinguishes the two harness path conventions:
|
|
34
|
+
* - native (deepagents) addresses files against a virtual root where a leading
|
|
35
|
+
* "/" denotes the workspace root — mirrors `InlinePublisher.normalizePath`;
|
|
36
|
+
* - Cursor passes real filesystem paths that may be absolute.
|
|
37
|
+
*
|
|
38
|
+
* A path that is absolute but outside `rootDir` is displayed as-is (we never
|
|
39
|
+
* surface an escaping `../../` relative path).
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveWorkspacePath(rawPath: string, rootDir: string, virtualRoot: boolean): {
|
|
42
|
+
path: string;
|
|
43
|
+
absolutePath: string;
|
|
44
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure path + binary-detection helpers shared by the native (deepagents) and
|
|
3
|
+
* Cursor harnesses' file-review capture.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately dependency-free and side-effect-free: no file IO, no diff
|
|
6
|
+
* computation, no proto knowledge. `resolveWorkspacePath` normalizes a touched
|
|
7
|
+
* path to (display path, absolute path); `looksBinary`/`bytesLookBinary` are the
|
|
8
|
+
* single definition of "binary" across every capture substrate.
|
|
9
|
+
*
|
|
10
|
+
* @since First-Class Diff Review (#186)
|
|
11
|
+
*/
|
|
12
|
+
import { isAbsolute, join, relative } from "node:path";
|
|
13
|
+
/**
|
|
14
|
+
* Heuristic binary detection: a NUL byte never appears in valid UTF-8 text. This
|
|
15
|
+
* is a safety net, not a feature — the native edit/write tools are string-based,
|
|
16
|
+
* so captured content is text in practice.
|
|
17
|
+
*/
|
|
18
|
+
export function looksBinary(content) {
|
|
19
|
+
return content.includes("\u0000");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Byte-level binary detection: a NUL byte never appears in valid UTF-8 text. The
|
|
23
|
+
* single definition of "binary" shared by every substrate that reads raw bytes
|
|
24
|
+
* (the git substrate's blob reads and the CAS substrate's captured bodies), so
|
|
25
|
+
* "what is binary" is decided one way across the whole file-review subsystem.
|
|
26
|
+
*
|
|
27
|
+
* Prefer this over {@link looksBinary} whenever the raw bytes are in hand: it is
|
|
28
|
+
* exact, whereas scanning a UTF-8-decoded string can miss a NUL that a lossy
|
|
29
|
+
* decode dropped.
|
|
30
|
+
*/
|
|
31
|
+
export function bytesLookBinary(bytes) {
|
|
32
|
+
return bytes.includes(0);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Derive the workspace-root-relative display path and the absolute on-disk path
|
|
36
|
+
* for a file a tool touched.
|
|
37
|
+
*
|
|
38
|
+
* `virtualRoot` distinguishes the two harness path conventions:
|
|
39
|
+
* - native (deepagents) addresses files against a virtual root where a leading
|
|
40
|
+
* "/" denotes the workspace root — mirrors `InlinePublisher.normalizePath`;
|
|
41
|
+
* - Cursor passes real filesystem paths that may be absolute.
|
|
42
|
+
*
|
|
43
|
+
* A path that is absolute but outside `rootDir` is displayed as-is (we never
|
|
44
|
+
* surface an escaping `../../` relative path).
|
|
45
|
+
*/
|
|
46
|
+
export function resolveWorkspacePath(rawPath, rootDir, virtualRoot) {
|
|
47
|
+
if (virtualRoot || !isAbsolute(rawPath)) {
|
|
48
|
+
const rel = rawPath.replace(/^\/+/, "").replace(/^\.\//, "");
|
|
49
|
+
return { path: rel, absolutePath: join(rootDir, rel) };
|
|
50
|
+
}
|
|
51
|
+
const rel = relative(rootDir, rawPath);
|
|
52
|
+
if (rel && !rel.startsWith("..") && !isAbsolute(rel)) {
|
|
53
|
+
return { path: rel, absolutePath: rawPath };
|
|
54
|
+
}
|
|
55
|
+
return { path: rawPath, absolutePath: rawPath };
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=file-change.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-change.js","sourceRoot":"","sources":["../../src/shared/file-change.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEvD;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAe,EACf,OAAe,EACf,WAAoB;IAEpB,IAAI,WAAW,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC7D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;IACzD,CAAC;IACD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACvC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;IAC9C,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Introspection of file-modifying tools, shared by every runner surface that
|
|
3
|
+
* reacts to a file edit: the native (deepagents) streaming side-effects (publish,
|
|
4
|
+
* git writeback, post-exec file-change capture), the Cursor streaming capture,
|
|
5
|
+
* and BOTH harnesses' approval-gate pre-execution capture (shared/gate-file-change.ts).
|
|
6
|
+
*
|
|
7
|
+
* This is the single source of truth for "which tools mutate files" and "where
|
|
8
|
+
* their path / whole-file content / edit replacement lives in the tool
|
|
9
|
+
* arguments". It is deliberately pure — no IO, no proto knowledge — so the same
|
|
10
|
+
* identification logic is used whether args come from a streamed `on_tool_*`
|
|
11
|
+
* event, a v3 protocol event, an AI-message tool call read out of graph state at
|
|
12
|
+
* an interrupt, or the Cursor preToolUse hook's captured `tool_input`.
|
|
13
|
+
*
|
|
14
|
+
* Both taxonomies are covered in one place on purpose: the deepagents harness
|
|
15
|
+
* names a file write `write_file`/`write`, the Cursor SDK stream names it
|
|
16
|
+
* `edit`/`write`, and the Cursor preToolUse hook names it `Write`/`StrReplace`/
|
|
17
|
+
* `EditNotebook`. The four extractors below span every arg-field name these
|
|
18
|
+
* surfaces use, so a single capture path is correct for all of them.
|
|
19
|
+
*
|
|
20
|
+
* @since First-Class Diff Review (#186); cross-harness gate unification (HITL diff)
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* The file-modifying tools, across both harness taxonomies.
|
|
24
|
+
*
|
|
25
|
+
* - deepagents (native): `write_file`/`edit_file`/`create_file` (stream) and
|
|
26
|
+
* `write`/`edit`/`create`/`str_replace_editor` (SDK names);
|
|
27
|
+
* - Cursor: `write`/`edit` (SDK stream, shared with native) and
|
|
28
|
+
* `Write`/`StrReplace`/`EditNotebook` (preToolUse hook + tool names).
|
|
29
|
+
*
|
|
30
|
+
* Delete is intentionally absent: it has no whole-file content or hunk to
|
|
31
|
+
* preview, so it is not "file-modifying" in the diff-capture sense.
|
|
32
|
+
*/
|
|
33
|
+
export declare const FILE_MODIFYING_TOOLS: ReadonlySet<string>;
|
|
34
|
+
/** Whether `toolName` is a file-modifying tool in either harness taxonomy. */
|
|
35
|
+
export declare function isFileModifyingTool(toolName: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Extract the target file path from a file-modifying tool's arguments. Returns
|
|
38
|
+
* `null` when no recognized path key is present. The key set is the union across
|
|
39
|
+
* both taxonomies: deepagents/Cursor write+edit use `path`/`file_path`; a Cursor
|
|
40
|
+
* notebook edit uses `target_notebook`; the rest are defensive against drift.
|
|
41
|
+
*/
|
|
42
|
+
export declare function extractFilePath(args: Record<string, unknown>): string | null;
|
|
43
|
+
/**
|
|
44
|
+
* Top-level arg keys, in priority order, that carry a write-family tool's
|
|
45
|
+
* WHOLE-FILE body, across both harness taxonomies (Cursor `Write` uses
|
|
46
|
+
* `content`; the SDK stream uses `contents`). Exported so the generated Cursor
|
|
47
|
+
* hook injects the SAME list into its inline content-digest extractor — the
|
|
48
|
+
* field names diverge across the hook/stream layers, so a single shared list is
|
|
49
|
+
* what keeps the runner-side and hook-side digests byte-identical.
|
|
50
|
+
*/
|
|
51
|
+
export declare const WRITE_CONTENT_FIELDS: readonly ["content", "contents", "file_content"];
|
|
52
|
+
/**
|
|
53
|
+
* Extract the WHOLE-FILE content from a write-family tool's arguments. Returns
|
|
54
|
+
* `null` for an edit-family call (which carries `old_string`/`new_string`, not a
|
|
55
|
+
* whole-file body) or when no content key is present. An empty string is a real
|
|
56
|
+
* value (an empty file) and is preserved.
|
|
57
|
+
*
|
|
58
|
+
* Critical: this is kept strictly separate from {@link extractEditNewString}.
|
|
59
|
+
* `new_string` is an edit replacement fragment, NOT whole-file content;
|
|
60
|
+
* conflating the two would make an edit look like a whole-file capture and read
|
|
61
|
+
* the wrong `before` at the gate.
|
|
62
|
+
*/
|
|
63
|
+
export declare function extractWriteContent(args: Record<string, unknown>): string | null;
|
|
64
|
+
/**
|
|
65
|
+
* Top-level arg keys for an edit-family tool's pre-/post-edit fragments, across
|
|
66
|
+
* both taxonomies. Exported for the same reason as {@link WRITE_CONTENT_FIELDS}:
|
|
67
|
+
* the Cursor hook injects them into its inline digest extractor so its content
|
|
68
|
+
* digest matches the runner's byte-for-byte.
|
|
69
|
+
*/
|
|
70
|
+
export declare const EDIT_OLD_FIELDS: readonly ["old_string", "old_text", "oldText"];
|
|
71
|
+
export declare const EDIT_NEW_FIELDS: readonly ["new_string", "new_text", "newText", "replacement"];
|
|
72
|
+
/**
|
|
73
|
+
* Extract an edit-family tool's pre-edit fragment (`old_string` and its
|
|
74
|
+
* variants). Returns `null` when absent; an empty string is preserved (an
|
|
75
|
+
* insertion has an empty `old_string`), matching the native gate capture.
|
|
76
|
+
*/
|
|
77
|
+
export declare function extractEditOldString(args: Record<string, unknown>): string | null;
|
|
78
|
+
/**
|
|
79
|
+
* Extract an edit-family tool's post-edit fragment (`new_string` and its
|
|
80
|
+
* variants, including `replacement`). Returns `null` when absent; an empty
|
|
81
|
+
* string is preserved (a deletion has an empty `new_string`).
|
|
82
|
+
*/
|
|
83
|
+
export declare function extractEditNewString(args: Record<string, unknown>): string | null;
|
|
84
|
+
/**
|
|
85
|
+
* Stable content digest of a file-mutating tool call's arguments — the content
|
|
86
|
+
* discriminator the deny-only Cursor HITL identity adds on top of
|
|
87
|
+
* (category, path) so a DIFFERENT edit to the same file re-gates rather than
|
|
88
|
+
* riding an earlier approval through.
|
|
89
|
+
*
|
|
90
|
+
* It hashes ONLY the edit content, never the path (the path is the identity's
|
|
91
|
+
* "salient" already). A whole-file write hashes its body; an edit hashes its
|
|
92
|
+
* (old, new) fragment pair. Returns "" for a call with no recoverable edit
|
|
93
|
+
* content — a shell command, a delete, a read, an MCP tool, or the hook's
|
|
94
|
+
* grep-fallback denial — which keep the coarse (category, salient) identity
|
|
95
|
+
* (already content-exact for a command / delete path).
|
|
96
|
+
*
|
|
97
|
+
* THE FORMAT IS A CROSS-LAYER CONTRACT. The Cursor preToolUse hook recomputes
|
|
98
|
+
* this digest inline from `tool_input`, running the SAME Node binary as the
|
|
99
|
+
* runner (see buildContentDigestScript in execute-cursor/hook-script.ts), so the
|
|
100
|
+
* two values must be byte-identical — any change here MUST be mirrored there.
|
|
101
|
+
* JSON.stringify of a fixed-shape string array is deterministic and identical on
|
|
102
|
+
* both sides; the leading tag ("w"/"e") keeps a write body from ever colliding
|
|
103
|
+
* with an edit pair, and the union field lists above are injected into the hook
|
|
104
|
+
* so both extract the same value despite the file_path/path & content/contents
|
|
105
|
+
* cross-layer name divergence.
|
|
106
|
+
*/
|
|
107
|
+
export declare function contentDigest(args: Record<string, unknown>): string;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Introspection of file-modifying tools, shared by every runner surface that
|
|
3
|
+
* reacts to a file edit: the native (deepagents) streaming side-effects (publish,
|
|
4
|
+
* git writeback, post-exec file-change capture), the Cursor streaming capture,
|
|
5
|
+
* and BOTH harnesses' approval-gate pre-execution capture (shared/gate-file-change.ts).
|
|
6
|
+
*
|
|
7
|
+
* This is the single source of truth for "which tools mutate files" and "where
|
|
8
|
+
* their path / whole-file content / edit replacement lives in the tool
|
|
9
|
+
* arguments". It is deliberately pure — no IO, no proto knowledge — so the same
|
|
10
|
+
* identification logic is used whether args come from a streamed `on_tool_*`
|
|
11
|
+
* event, a v3 protocol event, an AI-message tool call read out of graph state at
|
|
12
|
+
* an interrupt, or the Cursor preToolUse hook's captured `tool_input`.
|
|
13
|
+
*
|
|
14
|
+
* Both taxonomies are covered in one place on purpose: the deepagents harness
|
|
15
|
+
* names a file write `write_file`/`write`, the Cursor SDK stream names it
|
|
16
|
+
* `edit`/`write`, and the Cursor preToolUse hook names it `Write`/`StrReplace`/
|
|
17
|
+
* `EditNotebook`. The four extractors below span every arg-field name these
|
|
18
|
+
* surfaces use, so a single capture path is correct for all of them.
|
|
19
|
+
*
|
|
20
|
+
* @since First-Class Diff Review (#186); cross-harness gate unification (HITL diff)
|
|
21
|
+
*/
|
|
22
|
+
import { createHash } from "node:crypto";
|
|
23
|
+
/**
|
|
24
|
+
* The file-modifying tools, across both harness taxonomies.
|
|
25
|
+
*
|
|
26
|
+
* - deepagents (native): `write_file`/`edit_file`/`create_file` (stream) and
|
|
27
|
+
* `write`/`edit`/`create`/`str_replace_editor` (SDK names);
|
|
28
|
+
* - Cursor: `write`/`edit` (SDK stream, shared with native) and
|
|
29
|
+
* `Write`/`StrReplace`/`EditNotebook` (preToolUse hook + tool names).
|
|
30
|
+
*
|
|
31
|
+
* Delete is intentionally absent: it has no whole-file content or hunk to
|
|
32
|
+
* preview, so it is not "file-modifying" in the diff-capture sense.
|
|
33
|
+
*/
|
|
34
|
+
export const FILE_MODIFYING_TOOLS = new Set([
|
|
35
|
+
// deepagents (native) taxonomy
|
|
36
|
+
"write_file", "edit_file", "create_file",
|
|
37
|
+
"write", "edit", "create",
|
|
38
|
+
"str_replace_editor",
|
|
39
|
+
// Cursor taxonomy (PascalCase preToolUse hook + tool names; `write`/`edit`
|
|
40
|
+
// above are shared with the SDK stream).
|
|
41
|
+
"Write", "StrReplace", "EditNotebook",
|
|
42
|
+
]);
|
|
43
|
+
/** Whether `toolName` is a file-modifying tool in either harness taxonomy. */
|
|
44
|
+
export function isFileModifyingTool(toolName) {
|
|
45
|
+
return FILE_MODIFYING_TOOLS.has(toolName);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Extract the target file path from a file-modifying tool's arguments. Returns
|
|
49
|
+
* `null` when no recognized path key is present. The key set is the union across
|
|
50
|
+
* both taxonomies: deepagents/Cursor write+edit use `path`/`file_path`; a Cursor
|
|
51
|
+
* notebook edit uses `target_notebook`; the rest are defensive against drift.
|
|
52
|
+
*/
|
|
53
|
+
export function extractFilePath(args) {
|
|
54
|
+
if (typeof args.path === "string")
|
|
55
|
+
return args.path;
|
|
56
|
+
if (typeof args.file_path === "string")
|
|
57
|
+
return args.file_path;
|
|
58
|
+
if (typeof args.filePath === "string")
|
|
59
|
+
return args.filePath;
|
|
60
|
+
if (typeof args.filename === "string")
|
|
61
|
+
return args.filename;
|
|
62
|
+
if (typeof args.file === "string")
|
|
63
|
+
return args.file;
|
|
64
|
+
if (typeof args.target_notebook === "string")
|
|
65
|
+
return args.target_notebook;
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Top-level arg keys, in priority order, that carry a write-family tool's
|
|
70
|
+
* WHOLE-FILE body, across both harness taxonomies (Cursor `Write` uses
|
|
71
|
+
* `content`; the SDK stream uses `contents`). Exported so the generated Cursor
|
|
72
|
+
* hook injects the SAME list into its inline content-digest extractor — the
|
|
73
|
+
* field names diverge across the hook/stream layers, so a single shared list is
|
|
74
|
+
* what keeps the runner-side and hook-side digests byte-identical.
|
|
75
|
+
*/
|
|
76
|
+
export const WRITE_CONTENT_FIELDS = ["content", "contents", "file_content"];
|
|
77
|
+
/**
|
|
78
|
+
* Extract the WHOLE-FILE content from a write-family tool's arguments. Returns
|
|
79
|
+
* `null` for an edit-family call (which carries `old_string`/`new_string`, not a
|
|
80
|
+
* whole-file body) or when no content key is present. An empty string is a real
|
|
81
|
+
* value (an empty file) and is preserved.
|
|
82
|
+
*
|
|
83
|
+
* Critical: this is kept strictly separate from {@link extractEditNewString}.
|
|
84
|
+
* `new_string` is an edit replacement fragment, NOT whole-file content;
|
|
85
|
+
* conflating the two would make an edit look like a whole-file capture and read
|
|
86
|
+
* the wrong `before` at the gate.
|
|
87
|
+
*/
|
|
88
|
+
export function extractWriteContent(args) {
|
|
89
|
+
for (const field of WRITE_CONTENT_FIELDS) {
|
|
90
|
+
const v = args[field];
|
|
91
|
+
if (typeof v === "string")
|
|
92
|
+
return v;
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Top-level arg keys for an edit-family tool's pre-/post-edit fragments, across
|
|
98
|
+
* both taxonomies. Exported for the same reason as {@link WRITE_CONTENT_FIELDS}:
|
|
99
|
+
* the Cursor hook injects them into its inline digest extractor so its content
|
|
100
|
+
* digest matches the runner's byte-for-byte.
|
|
101
|
+
*/
|
|
102
|
+
export const EDIT_OLD_FIELDS = ["old_string", "old_text", "oldText"];
|
|
103
|
+
export const EDIT_NEW_FIELDS = ["new_string", "new_text", "newText", "replacement"];
|
|
104
|
+
/**
|
|
105
|
+
* Extract an edit-family tool's pre-edit fragment (`old_string` and its
|
|
106
|
+
* variants). Returns `null` when absent; an empty string is preserved (an
|
|
107
|
+
* insertion has an empty `old_string`), matching the native gate capture.
|
|
108
|
+
*/
|
|
109
|
+
export function extractEditOldString(args) {
|
|
110
|
+
for (const field of EDIT_OLD_FIELDS) {
|
|
111
|
+
const v = args[field];
|
|
112
|
+
if (typeof v === "string")
|
|
113
|
+
return v;
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Extract an edit-family tool's post-edit fragment (`new_string` and its
|
|
119
|
+
* variants, including `replacement`). Returns `null` when absent; an empty
|
|
120
|
+
* string is preserved (a deletion has an empty `new_string`).
|
|
121
|
+
*/
|
|
122
|
+
export function extractEditNewString(args) {
|
|
123
|
+
for (const field of EDIT_NEW_FIELDS) {
|
|
124
|
+
const v = args[field];
|
|
125
|
+
if (typeof v === "string")
|
|
126
|
+
return v;
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Stable content digest of a file-mutating tool call's arguments — the content
|
|
132
|
+
* discriminator the deny-only Cursor HITL identity adds on top of
|
|
133
|
+
* (category, path) so a DIFFERENT edit to the same file re-gates rather than
|
|
134
|
+
* riding an earlier approval through.
|
|
135
|
+
*
|
|
136
|
+
* It hashes ONLY the edit content, never the path (the path is the identity's
|
|
137
|
+
* "salient" already). A whole-file write hashes its body; an edit hashes its
|
|
138
|
+
* (old, new) fragment pair. Returns "" for a call with no recoverable edit
|
|
139
|
+
* content — a shell command, a delete, a read, an MCP tool, or the hook's
|
|
140
|
+
* grep-fallback denial — which keep the coarse (category, salient) identity
|
|
141
|
+
* (already content-exact for a command / delete path).
|
|
142
|
+
*
|
|
143
|
+
* THE FORMAT IS A CROSS-LAYER CONTRACT. The Cursor preToolUse hook recomputes
|
|
144
|
+
* this digest inline from `tool_input`, running the SAME Node binary as the
|
|
145
|
+
* runner (see buildContentDigestScript in execute-cursor/hook-script.ts), so the
|
|
146
|
+
* two values must be byte-identical — any change here MUST be mirrored there.
|
|
147
|
+
* JSON.stringify of a fixed-shape string array is deterministic and identical on
|
|
148
|
+
* both sides; the leading tag ("w"/"e") keeps a write body from ever colliding
|
|
149
|
+
* with an edit pair, and the union field lists above are injected into the hook
|
|
150
|
+
* so both extract the same value despite the file_path/path & content/contents
|
|
151
|
+
* cross-layer name divergence.
|
|
152
|
+
*/
|
|
153
|
+
export function contentDigest(args) {
|
|
154
|
+
const content = extractWriteContent(args);
|
|
155
|
+
if (content !== null) {
|
|
156
|
+
return sha256Hex(JSON.stringify(["w", content]));
|
|
157
|
+
}
|
|
158
|
+
const oldString = extractEditOldString(args);
|
|
159
|
+
const newString = extractEditNewString(args);
|
|
160
|
+
if (oldString !== null || newString !== null) {
|
|
161
|
+
return sha256Hex(JSON.stringify(["e", oldString ?? "", newString ?? ""]));
|
|
162
|
+
}
|
|
163
|
+
return "";
|
|
164
|
+
}
|
|
165
|
+
function sha256Hex(s) {
|
|
166
|
+
return createHash("sha256").update(s, "utf8").digest("hex");
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=file-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-tools.js","sourceRoot":"","sources":["../../src/shared/file-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness-agnostic capture-mode turn orchestration for the apply-then-review
|
|
3
|
+
* HITL subsystem. This is the glue between the git snapshot/restore substrate
|
|
4
|
+
* ({@link ./git-substrate.js}) and the file-review ledger ({@link ./events.js}):
|
|
5
|
+
* it turns "the agent edited files freely this turn" into the append-only
|
|
6
|
+
* `file_review` events the server folds into `file_change_sets` (the single
|
|
7
|
+
* review surface), and on resume reconciles the tree to the user's decisions.
|
|
8
|
+
*
|
|
9
|
+
* It is parameterized by `harnessId` (stamped onto the BASELINE payload, which is
|
|
10
|
+
* the projection's source of truth for `turn_id`/`harness_id`) and `excludePaths`
|
|
11
|
+
* (the runner-owned files a harness writes into the workspace), so the Cursor and
|
|
12
|
+
* deep-agent harnesses author IDENTICAL ledger entries through this one seam. Each
|
|
13
|
+
* harness keeps only its presentation concerns (e.g. hiding flowed transcript
|
|
14
|
+
* rows) in its own adapter.
|
|
15
|
+
*
|
|
16
|
+
* Identity: the change set id is `${executionId}:${turnSeq}` (one turn = one
|
|
17
|
+
* change set), minted by the caller; each file's stable id is
|
|
18
|
+
* `${changeSetId}:${pathAfter||pathBefore}` so the resume can map a per-file
|
|
19
|
+
* decision back to its path without depending on any other identity.
|
|
20
|
+
*/
|
|
21
|
+
import { FileCaptureClass } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
22
|
+
import type { AgentExecutionStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
23
|
+
import type { FileChangeSet, TurnCommandProvenance } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/filereview_pb";
|
|
24
|
+
import { type GitSubstrateChange as GitCapturedChange } from "./git-substrate.js";
|
|
25
|
+
import type { ArtifactStorage } from "../artifact-storage.js";
|
|
26
|
+
import { type BlobReader, type CasPathCapture } from "./cas-substrate.js";
|
|
27
|
+
/**
|
|
28
|
+
* Whether a turn runs in apply-then-review CAPTURE mode (file edits flow and are
|
|
29
|
+
* reviewed post-hoc) rather than the classic pre-write DENY-GATE. Shared by BOTH
|
|
30
|
+
* harnesses (Cursor and deep-agent) so the capture-vs-deny-gate decision is made
|
|
31
|
+
* one way everywhere — the single point where a workspace's substrate availability
|
|
32
|
+
* decides the HITL model.
|
|
33
|
+
*
|
|
34
|
+
* Capture needs a primary workspace AND a substrate to capture into:
|
|
35
|
+
* - a git work tree captures tracked edits from the git diff (no storage needed);
|
|
36
|
+
* - a NON-git workspace captures every write via the path-scoped CAS substrate,
|
|
37
|
+
* which needs artifact storage to persist blobs.
|
|
38
|
+
*
|
|
39
|
+
* So a non-git workspace with NO artifact storage — or no workspace at all — has
|
|
40
|
+
* no capture substrate and falls back to the deny-gate: the agent still runs, but
|
|
41
|
+
* file writes gate pre-execution instead of flowing. In the Cursor harness that
|
|
42
|
+
* fallback is also the ONLY branch that arms the resume-time exact-apply guarantee
|
|
43
|
+
* (see execute-cursor/exact-apply.ts); the deep-agent harness re-applies an
|
|
44
|
+
* approved write via LangGraph checkpoint replay and needs no exact-apply. Keeping
|
|
45
|
+
* this the single, named, truth-table-tested decision pins exactly when the
|
|
46
|
+
* no-storage deny-gate engages in either harness.
|
|
47
|
+
*/
|
|
48
|
+
export declare function deriveCaptureMode(primaryWorkspaceDir: string | undefined, gitWorkspace: boolean, hasArtifactStorage: boolean): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Turn start: pin the pre-turn working tree behind the baseline ref and author
|
|
51
|
+
* the BASELINE_CAPTURED event. The projection reads `turn_id`/`harness_id` ONLY
|
|
52
|
+
* from this payload, so `turnId == changeSetId` (one turn = one change set) and
|
|
53
|
+
* `harnessId` identifies the producer. Returns the baseline tree sha for the
|
|
54
|
+
* turn-end diff. Appends onto `status.fileReviewEventStream`; the event rides the
|
|
55
|
+
* next persist.
|
|
56
|
+
*
|
|
57
|
+
* `gitWorkspace=false` (a non-git workspace, DD-21 D2) has no whole-tree baseline
|
|
58
|
+
* to pin — a file's pre-edit bytes are captured per-path by the CAS observer at
|
|
59
|
+
* mutation time, and the reconcile sources them from the durable CAS manifest,
|
|
60
|
+
* not this snapshot. The BASELINE event is still authored (it is the projection's
|
|
61
|
+
* sole source for `turn_id`/`harness_id`), carrying a `CAS_MANIFEST` snapshot with
|
|
62
|
+
* no manifest yet (the manifest is authored at candidate time). Returns "".
|
|
63
|
+
*/
|
|
64
|
+
export declare function captureBaselineToLedger(opts: {
|
|
65
|
+
readonly status: AgentExecutionStatus;
|
|
66
|
+
readonly gitRoot: string;
|
|
67
|
+
readonly executionId: string;
|
|
68
|
+
readonly changeSetId: string;
|
|
69
|
+
readonly harnessId: string;
|
|
70
|
+
readonly excludePaths?: readonly string[];
|
|
71
|
+
/** True (default) for a git work tree; false for a CAS-only non-git workspace. */
|
|
72
|
+
readonly gitWorkspace?: boolean;
|
|
73
|
+
}): Promise<string>;
|
|
74
|
+
/**
|
|
75
|
+
* Turn end: capture the change set, LEAVE the working tree in its applied
|
|
76
|
+
* ("after") state (the user reviews the real change; nothing is committed and the
|
|
77
|
+
* next turn is blocked until they decide), and author the CANDIDATE_CAPTURED
|
|
78
|
+
* event. The pinned baseline/after refs are the authoritative source for the
|
|
79
|
+
* resume-time reconcile ({@link applyCaptureDecisions}).
|
|
80
|
+
*
|
|
81
|
+
* Presentation (hiding the harness's flowed transcript rows so `file_change_sets`
|
|
82
|
+
* is the single review surface) is the harness adapter's concern, not this seam's.
|
|
83
|
+
* Returns the captured changes. No-op authoring when the turn changed nothing.
|
|
84
|
+
*/
|
|
85
|
+
export declare function captureCandidateToLedger(opts: {
|
|
86
|
+
readonly status: AgentExecutionStatus;
|
|
87
|
+
readonly gitRoot: string;
|
|
88
|
+
readonly executionId: string;
|
|
89
|
+
readonly changeSetId: string;
|
|
90
|
+
readonly baselineTree: string;
|
|
91
|
+
readonly harnessId: string;
|
|
92
|
+
readonly excludePaths?: readonly string[];
|
|
93
|
+
/**
|
|
94
|
+
* Ignored / non-git paths captured this turn (before/after bytes the harness
|
|
95
|
+
* recorded at mutation time). When present, they are stored as content-
|
|
96
|
+
* addressed CAS blobs and composed with the git-tracked changes into ONE
|
|
97
|
+
* hybrid change set (design doc 11). Omit for a git-only turn — existing
|
|
98
|
+
* callers are unaffected.
|
|
99
|
+
*/
|
|
100
|
+
readonly casCaptures?: readonly CasPathCapture[];
|
|
101
|
+
/** The CAS blob store; required when {@link casCaptures} is non-empty. */
|
|
102
|
+
readonly storage?: ArtifactStorage;
|
|
103
|
+
/**
|
|
104
|
+
* Gitignored paths whose bytes are deliberately NOT captured — the DD-E secret
|
|
105
|
+
* gate refused them. Each is authored as a content-less `DIFF_UNREVIEWABLE`
|
|
106
|
+
* change entry (`diff_complete=false`, no before/after) so the change set is
|
|
107
|
+
* PARTIAL_BLOCKED (approval blocked) and the path is honestly surfaced, while
|
|
108
|
+
* its content never enters the ledger or storage. Never overlaps `casCaptures`.
|
|
109
|
+
*/
|
|
110
|
+
readonly unreviewablePaths?: readonly string[];
|
|
111
|
+
/**
|
|
112
|
+
* Capture class stamped on the content-less DIFF_UNREVIEWABLE entries — the CAS
|
|
113
|
+
* class of THIS turn's substrate: `GIT_IGNORED_CAPTURED` for a git work tree's
|
|
114
|
+
* ignored paths, `NON_GIT_CAS` for a non-git workspace. Content-addressed
|
|
115
|
+
* `casCaptures` carry their own per-item class; this only labels the blocked
|
|
116
|
+
* (content-less) ones so a non-git blocked secret is not mislabeled "gitignored".
|
|
117
|
+
* Defaults to `GIT_IGNORED_CAPTURED` (git callers are unaffected).
|
|
118
|
+
*/
|
|
119
|
+
readonly unreviewableCaptureClass?: FileCaptureClass;
|
|
120
|
+
/**
|
|
121
|
+
* True (default) for a git work tree — git-tracked edits are diffed from the
|
|
122
|
+
* pinned baseline/after trees and composed with any CAS captures. False for a
|
|
123
|
+
* CAS-only non-git workspace (DD-21 D2): there is no git tree to diff, so the
|
|
124
|
+
* change set is sourced ENTIRELY from `casCaptures` (+ `unreviewablePaths`) and
|
|
125
|
+
* the snapshot is `CAS_MANIFEST`, not `GIT_TREE_REF`/`HYBRID`.
|
|
126
|
+
*/
|
|
127
|
+
readonly gitWorkspace?: boolean;
|
|
128
|
+
/**
|
|
129
|
+
* The harness's approved-command turn facts (DD-28): present only when the
|
|
130
|
+
* turn's sole mutation source was consented shell commands. Carried verbatim
|
|
131
|
+
* on the CANDIDATE event for the backend to verify and — on success — author
|
|
132
|
+
* the policy auto-keep decision. Omitted → the set reviews manually.
|
|
133
|
+
*/
|
|
134
|
+
readonly commandProvenance?: TurnCommandProvenance;
|
|
135
|
+
}): Promise<readonly GitCapturedChange[]>;
|
|
136
|
+
/** Outcome of reconciling a DECIDED change set's decisions on resume. */
|
|
137
|
+
export interface CaptureResumeResult {
|
|
138
|
+
/** False when this resume is not a capture turn (no capture ref present). */
|
|
139
|
+
readonly isCaptureTurn: boolean;
|
|
140
|
+
/** Repo-relative paths applied (approved) to the working tree. */
|
|
141
|
+
readonly approvedPaths: readonly string[];
|
|
142
|
+
/** Repo-relative paths discarded (rejected / undecided-then-skipped). */
|
|
143
|
+
readonly rejectedPaths: readonly string[];
|
|
144
|
+
/** True when at least one file was rejected. */
|
|
145
|
+
readonly hadReject: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* True when an approved file's on-disk bytes no longer hash to the digest the
|
|
148
|
+
* user approved: a FileReviewFailure(HASH_MISMATCH) was authored and NOTHING
|
|
149
|
+
* was applied (what-you-approve-is-what-applies is a hard gate).
|
|
150
|
+
*/
|
|
151
|
+
readonly failed: boolean;
|
|
152
|
+
/** Human-readable detail when {@link failed} (the diverged paths). */
|
|
153
|
+
readonly failureDetail?: string;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Resume: reconcile the working tree to the change set's DECIDED decisions
|
|
157
|
+
* (projected server-side onto `FileChangeSet.decisions`), sourced entirely from
|
|
158
|
+
* the pinned baseline/after refs — approved files are ensured at their "after"
|
|
159
|
+
* bytes (uncommitted; normally already on disk from the review window, re-asserted
|
|
160
|
+
* idempotently), rejected/undecided files are snapped back to baseline. Then
|
|
161
|
+
* author RECONCILED with the post-reconcile approved snapshot and release the
|
|
162
|
+
* refs. Because both sides are ref-sourced, the result is correct regardless of
|
|
163
|
+
* the tree's current contents (idempotent under a Temporal retry or a tree reset).
|
|
164
|
+
*
|
|
165
|
+
* Scope precedence is runner-owned, most-specific-wins: the CHANGE_SET decision
|
|
166
|
+
* (if any) seeds every file, then per-file FILE decisions override it.
|
|
167
|
+
*
|
|
168
|
+
* Enforcement ("what you approve is what applies"): before keeping an approved
|
|
169
|
+
* file, the recomputed bytes must still hash to the reviewed digest. Any mismatch
|
|
170
|
+
* authors a FileReviewFailure(HASH_MISMATCH) and applies NOTHING.
|
|
171
|
+
*
|
|
172
|
+
* Mutates `status.fileReviewEventStream` in place (authors RECONCILED / FAILED).
|
|
173
|
+
*/
|
|
174
|
+
export declare function applyCaptureDecisions(opts: {
|
|
175
|
+
readonly status: AgentExecutionStatus;
|
|
176
|
+
readonly gitRoot: string;
|
|
177
|
+
readonly executionId: string;
|
|
178
|
+
readonly changeSet: FileChangeSet;
|
|
179
|
+
readonly harnessId: string;
|
|
180
|
+
readonly excludePaths?: readonly string[];
|
|
181
|
+
/**
|
|
182
|
+
* The CAS blob reader, used to reconcile ignored / non-git (CAS) files from the
|
|
183
|
+
* durable manifest — approved after-blobs re-written (hash-verified), rejected
|
|
184
|
+
* files snapped back to their before-blobs. Whether the CAS branch runs at all
|
|
185
|
+
* is decided by the change set's CANDIDATE snapshot (a git-only turn carries no
|
|
186
|
+
* CAS ref), NOT by probing storage. Omit for a harness with no artifact storage;
|
|
187
|
+
* a CAS/HYBRID change set then cannot be reconciled.
|
|
188
|
+
*
|
|
189
|
+
* `storage` is accepted so callers can pass the store they derived `readBlob`
|
|
190
|
+
* from (via {@link casBlobReader}); the reconcile itself reads only through
|
|
191
|
+
* `readBlob` and never probes `storage`.
|
|
192
|
+
*/
|
|
193
|
+
readonly storage?: ArtifactStorage;
|
|
194
|
+
readonly readBlob?: BlobReader;
|
|
195
|
+
/**
|
|
196
|
+
* True (default) for a git work tree; false for a CAS-only non-git workspace
|
|
197
|
+
* (DD-21 D2). When false, git refs are never consulted — the reconcile is driven
|
|
198
|
+
* entirely by the durable CAS manifest, and RECONCILED carries a `CAS_MANIFEST`
|
|
199
|
+
* snapshot instead of a re-pinned git tree.
|
|
200
|
+
*/
|
|
201
|
+
readonly gitWorkspace?: boolean;
|
|
202
|
+
}): Promise<CaptureResumeResult>;
|