@stigmer/runner 3.0.9-dev.20260616060535 → 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 +10 -0
- package/dist/activities/execute-deep-agent/hitl.js +5 -1
- 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 +370 -56
- 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 +11 -5
- package/dist/activities/execute-deep-agent/status-builder.js +6 -2
- 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 +6 -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 +2 -5
- 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 +12 -11
- 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 +15 -1
- package/src/activities/execute-deep-agent/index.ts +434 -64
- 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 +19 -7
- 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 +8 -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
package/src/shared/status.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
import type { StigmerClient } from "../client/stigmer-client.js";
|
|
22
22
|
import {
|
|
23
23
|
offloadOversizedToolOutputs,
|
|
24
|
+
offloadCandidateChangesToFit,
|
|
24
25
|
enforceStatusSizeLimit,
|
|
25
26
|
STATUS_PAYLOAD_HARD_LIMIT_BYTES,
|
|
26
27
|
type ToolOutputOffloadContext,
|
|
@@ -112,6 +113,18 @@ export async function persistStatus(
|
|
|
112
113
|
} catch (err) {
|
|
113
114
|
console.warn(`[persistStatus] ${executionId}: tool-output offload failed (non-fatal): ${err}`);
|
|
114
115
|
}
|
|
116
|
+
// File-review ledger: if the status still exceeds the soft cap after per-item
|
|
117
|
+
// offload, offload the largest still-inline captured bodies to retrievable
|
|
118
|
+
// refs so those files stay REVIEWABLE (lazily fetched) instead of being
|
|
119
|
+
// dropped by the backstop below. Guarded on the presence of file-review
|
|
120
|
+
// events so an ordinary (non-review) turn pays nothing. Non-fatal.
|
|
121
|
+
if (status.fileReviewEventStream?.events?.length) {
|
|
122
|
+
try {
|
|
123
|
+
await offloadCandidateChangesToFit(status, offload);
|
|
124
|
+
} catch (err) {
|
|
125
|
+
console.warn(`[persistStatus] ${executionId}: file-review offload-to-fit failed (non-fatal): ${err}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
115
128
|
}
|
|
116
129
|
if (enforceStatusSizeLimit(status)) {
|
|
117
130
|
console.warn(
|
package/src/shared/tool-kind.ts
CHANGED
|
@@ -89,3 +89,36 @@ export function classifyTool(name: string, mcpServerSlug?: string): ToolKind {
|
|
|
89
89
|
}
|
|
90
90
|
return ToolKind.UNSPECIFIED;
|
|
91
91
|
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The coarse, cross-taxonomy approval category of a gated built-in tool, or
|
|
95
|
+
* undefined for tools that are not gated by category (read-only built-ins, MCP
|
|
96
|
+
* tools, and unknown names).
|
|
97
|
+
*
|
|
98
|
+
* FILE_WRITE and FILE_EDIT both collapse to "write" on purpose: the Cursor
|
|
99
|
+
* preToolUse hook reports every file mutation — create or edit — as `Write`,
|
|
100
|
+
* while the SDK stream names them `edit`/`write`. The category is therefore the
|
|
101
|
+
* only tool identity that is stable across the hook and stream taxonomies, which
|
|
102
|
+
* is exactly what the Cursor approval grant (and the Phase-2 coarse approval
|
|
103
|
+
* fingerprint) must match on. Built on {@link classifyTool} so this collapse is
|
|
104
|
+
* defined once.
|
|
105
|
+
*
|
|
106
|
+
* This is the single source of truth for the approval category;
|
|
107
|
+
* execute-cursor/approval-policy.ts re-exports it so the two harnesses cannot
|
|
108
|
+
* drift.
|
|
109
|
+
*/
|
|
110
|
+
export type ToolApprovalCategory = "write" | "delete" | "shell";
|
|
111
|
+
|
|
112
|
+
export function toolApprovalCategory(name: string): ToolApprovalCategory | undefined {
|
|
113
|
+
switch (classifyTool(name)) {
|
|
114
|
+
case ToolKind.FILE_WRITE:
|
|
115
|
+
case ToolKind.FILE_EDIT:
|
|
116
|
+
return "write";
|
|
117
|
+
case ToolKind.FILE_DELETE:
|
|
118
|
+
return "delete";
|
|
119
|
+
case ToolKind.SHELL:
|
|
120
|
+
return "shell";
|
|
121
|
+
default:
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness-agnostic helpers for a transcript tool-call row's file-review
|
|
3
|
+
* presentation.
|
|
4
|
+
*
|
|
5
|
+
* When file edits are reviewed as a captured `FileChangeSet` (the apply-then-
|
|
6
|
+
* review model), each flowed file-edit row STAYS visible at its transcript
|
|
7
|
+
* position as an observational/audit record — "the agent edited this file,
|
|
8
|
+
* here" — and is stamped with the change set id it contributed to
|
|
9
|
+
* ({@link stampFileEditRow}). The ledger remains the single DECISION surface;
|
|
10
|
+
* the row is never one (the research report's "transcript row references
|
|
11
|
+
* change_set_id" / "tool-call rows are observational/audit-only for file
|
|
12
|
+
* tools"). Both harnesses (Cursor deny-gate + deep-agent middleware) stamp rows
|
|
13
|
+
* the same way, so the operation lives here.
|
|
14
|
+
*
|
|
15
|
+
* {@link hideToolCallRow} / {@link isToolCallRowHidden} remain for the OTHER
|
|
16
|
+
* collapse consumer — a superseded same-turn denial twin — and as the render
|
|
17
|
+
* shape of legacy (pre-stamping) sessions whose flowed edit rows were hidden.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
21
|
+
import type { ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
22
|
+
import type { SubAgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/subagent_pb";
|
|
23
|
+
import { extractFilePath } from "./file-tools.js";
|
|
24
|
+
import { isSecretLikePath } from "./filereview/secret-paths.js";
|
|
25
|
+
import { utcTimestamp } from "./status.js";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Stamp a flowed file-edit row with the change set that captured its turn.
|
|
29
|
+
* PRESENTATION/AUDIT-ONLY (see `ToolCall.file_change_set_id`): clients badge
|
|
30
|
+
* the row with the set's review state and anchor the set's decision surface
|
|
31
|
+
* after the turn's last stamped row. Never a correlation or enforcement key.
|
|
32
|
+
*
|
|
33
|
+
* Additive by design — the row keeps its args/result/status so the per-edit
|
|
34
|
+
* diff the user watched stream stays rendered in place. The captured net diff
|
|
35
|
+
* on the ledger is the only REVIEWED artifact; the row is a historical record.
|
|
36
|
+
*
|
|
37
|
+
* An already-stamped row is left untouched. This is load-bearing, not hygiene:
|
|
38
|
+
* the turn-boundary pass re-walks the whole transcript, which on a resume
|
|
39
|
+
* includes the prior turn's seeded rows — without this guard, turn N would
|
|
40
|
+
* re-stamp turn N-1's rows with its own per-turn change set id (silent
|
|
41
|
+
* mis-attribution).
|
|
42
|
+
*
|
|
43
|
+
* Defensive secret clear (DD-12 D4 belt-and-braces): flowed rows are never
|
|
44
|
+
* secret in practice — the Cursor hook hard-denies secret-like writes before
|
|
45
|
+
* they flow — but a write to a TRACKED secret-like path (e.g. a committed
|
|
46
|
+
* credentials file) is outside the hook's gitignored scope. Such a row keeps
|
|
47
|
+
* its path (a filename is not itself the secret) and is stripped of content
|
|
48
|
+
* (`args` body, `result` diff, `args_preview`). Fail-closed: a file row whose
|
|
49
|
+
* path cannot be determined is stripped rather than trusted.
|
|
50
|
+
*/
|
|
51
|
+
export function stampFileEditRow(tc: ToolCall, changeSetId: string): void {
|
|
52
|
+
if (tc.fileChangeSetId) return;
|
|
53
|
+
tc.fileChangeSetId = changeSetId;
|
|
54
|
+
|
|
55
|
+
const path = extractFilePath((tc.args ?? {}) as Record<string, unknown>) ?? "";
|
|
56
|
+
if (isSecretLikePath(path)) {
|
|
57
|
+
tc.args = path ? { path } : undefined;
|
|
58
|
+
tc.result = "";
|
|
59
|
+
tc.argsPreview = "";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Collapse a tool-call row to the hidden shape the SDK renders as absent: a
|
|
65
|
+
* SKIPPED row with no approval state, result, error, preview, or args.
|
|
66
|
+
* Idempotent (re-running yields the same shape).
|
|
67
|
+
*
|
|
68
|
+
* `args` is cleared, not just `args_preview`. A hidden row is redundant with the
|
|
69
|
+
* `file_change_set` (the single review surface), so its content must not linger
|
|
70
|
+
* anywhere: for a file-mutating tool `args` holds the full write body, which for
|
|
71
|
+
* a secret-like path would otherwise persist into the transcript / Temporal
|
|
72
|
+
* history in violation of the never-persist-secret-contents contract (design
|
|
73
|
+
* doc 12, D4). Dropping it is safe at resume — identity is carried by
|
|
74
|
+
* `approval_content_digest`, deliberately immune to `args` being absent (the
|
|
75
|
+
* size-limit elision already drops `args`); no consumer reads a hidden row's
|
|
76
|
+
* `args`.
|
|
77
|
+
*/
|
|
78
|
+
export function hideToolCallRow(tc: ToolCall): void {
|
|
79
|
+
tc.status = ToolCallStatus.TOOL_CALL_SKIPPED;
|
|
80
|
+
tc.requiresApproval = false;
|
|
81
|
+
tc.approvalRequestedAt = "";
|
|
82
|
+
tc.approvalMessage = "";
|
|
83
|
+
tc.error = "";
|
|
84
|
+
tc.result = "";
|
|
85
|
+
tc.argsPreview = "";
|
|
86
|
+
tc.args = undefined;
|
|
87
|
+
if (!tc.completedAt) tc.completedAt = utcTimestamp();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Whether a tool-call row is already collapsed/hidden (the SDK's absent-row
|
|
92
|
+
* predicate). Used to keep {@link hideToolCallRow} idempotent across re-persists
|
|
93
|
+
* and activity retries.
|
|
94
|
+
*/
|
|
95
|
+
export function isToolCallRowHidden(tc: ToolCall): boolean {
|
|
96
|
+
return (
|
|
97
|
+
tc.status === ToolCallStatus.TOOL_CALL_SKIPPED &&
|
|
98
|
+
!tc.requiresApproval &&
|
|
99
|
+
tc.args === undefined &&
|
|
100
|
+
!tc.result &&
|
|
101
|
+
!tc.error
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Collect every tool-call id present in a set of sub-agent executions.
|
|
107
|
+
*
|
|
108
|
+
* Used by both harnesses to snapshot, BEFORE a turn's stream, the sub-agent
|
|
109
|
+
* tool-call ids that already existed — so the turn-boundary stamp can scope
|
|
110
|
+
* itself to rows CREATED this turn (a tool-call id absent from the snapshot).
|
|
111
|
+
*
|
|
112
|
+
* Why tool-call-id novelty is the current-turn signal for sub-agent rows (and
|
|
113
|
+
* not the `{unstamped}` heuristic the top-level pass uses): a top-level flowed
|
|
114
|
+
* edit row is guaranteed to be from this turn because prior turns' rows are
|
|
115
|
+
* either already stamped or hidden. Sub-agent rows have neither shield — before
|
|
116
|
+
* sub-agent stamping existed, ALL of them are unstamped and never hidden — so a
|
|
117
|
+
* naive `{unstamped}` walk would mis-attribute a resumed execution's prior
|
|
118
|
+
* sub-agent rows to the current change set. Keying on tool-call-id novelty is
|
|
119
|
+
* also correct for a sub-agent that spans invocations (an internal tool gate):
|
|
120
|
+
* its id pre-exists on resume, but its continuation edit rows carry fresh ids
|
|
121
|
+
* and stamp with the completing turn's set. It is likewise independent of how
|
|
122
|
+
* each harness seeds prior sub-agents (deep-agent replaces per-turn and holds
|
|
123
|
+
* none; Cursor clones them in) — the snapshot reflects whatever is present.
|
|
124
|
+
*/
|
|
125
|
+
export function collectSubAgentToolCallIds(
|
|
126
|
+
subAgents: readonly SubAgentExecution[],
|
|
127
|
+
): Set<string> {
|
|
128
|
+
const ids = new Set<string>();
|
|
129
|
+
for (const sa of subAgents) {
|
|
130
|
+
for (const msg of sa.messages) {
|
|
131
|
+
for (const tc of msg.toolCalls) ids.add(tc.id);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return ids;
|
|
135
|
+
}
|
|
@@ -18,11 +18,50 @@
|
|
|
18
18
|
import { join } from "node:path";
|
|
19
19
|
import { mkdir } from "node:fs/promises";
|
|
20
20
|
import { homedir } from "node:os";
|
|
21
|
+
import { createHash } from "node:crypto";
|
|
22
|
+
|
|
23
|
+
/** The runner-owned `~/.stigmer` root (overridable via HOME for tests/sandboxes). */
|
|
24
|
+
function getStigmerHome(): string {
|
|
25
|
+
return process.env.HOME || process.env.USERPROFILE || homedir();
|
|
26
|
+
}
|
|
21
27
|
|
|
22
28
|
/** Root of a session's runner-owned directory tree (outside the workspace). */
|
|
23
29
|
function getSessionDir(sessionId: string): string {
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
return join(getStigmerHome(), ".stigmer", "sessions", sessionId);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Compute the WORKSPACE-scoped HITL gate directory — the home for the STABLE
|
|
35
|
+
* hook script and the per-turn "active turn" pointer.
|
|
36
|
+
*
|
|
37
|
+
* Why workspace-scoped, not session-scoped: the Cursor SDK loads the workspace's
|
|
38
|
+
* `.cursor/hooks.json` (the hook script PATH) ONCE per runner process and caches
|
|
39
|
+
* it; later per-execution rewrites are ignored. A per-session hook script (with
|
|
40
|
+
* per-session baked state/ledger paths) therefore gets cached at the FIRST
|
|
41
|
+
* execution and reused for every later one — so later executions' denials are
|
|
42
|
+
* recorded to the FIRST session's ledger and the current runner reads its own
|
|
43
|
+
* empty ledger, silently completing instead of pausing for approval.
|
|
44
|
+
*
|
|
45
|
+
* The fix is a single STABLE script per workspace (so the SDK's cached path is
|
|
46
|
+
* always correct) that resolves the CURRENT turn's state/ledger/runner from an
|
|
47
|
+
* atomically-updated pointer the script re-reads on every invocation. This dir
|
|
48
|
+
* holds both. It is keyed by a hash of the absolute workspace path so distinct
|
|
49
|
+
* workspaces never collide, and lives under `~/.stigmer` (never the repo, per
|
|
50
|
+
* issue #173). Pure function — performs no I/O.
|
|
51
|
+
*/
|
|
52
|
+
export function getHitlGateDir(workspaceRoot: string): string {
|
|
53
|
+
const key = createHash("sha256").update(workspaceRoot).digest("hex").slice(0, 16);
|
|
54
|
+
return join(getStigmerHome(), ".stigmer", "hitl-gate", key);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Ensure the workspace-scoped HITL gate directory exists and return its path.
|
|
59
|
+
* Idempotent — safe across executions, HITL reinvocations, and activity retries.
|
|
60
|
+
*/
|
|
61
|
+
export async function ensureHitlGateDir(workspaceRoot: string): Promise<string> {
|
|
62
|
+
const dir = getHitlGateDir(workspaceRoot);
|
|
63
|
+
await mkdir(dir, { recursive: true });
|
|
64
|
+
return dir;
|
|
26
65
|
}
|
|
27
66
|
|
|
28
67
|
/**
|
|
@@ -385,7 +385,7 @@ describe("Golden Execution — Tier 1d: Advanced Tasks", () => {
|
|
|
385
385
|
const state = createState();
|
|
386
386
|
state.input = { pr_number: 7, repo: "acme/app", diff: "--- a/main.ts" };
|
|
387
387
|
|
|
388
|
-
const mockCallAgent = vi.fn(async () => ({
|
|
388
|
+
const mockCallAgent = vi.fn<TaskExecutionContext["callAgent"]>(async () => ({
|
|
389
389
|
structured: { severity: "low", category: "style", customer_impact: false },
|
|
390
390
|
final_text: "LGTM",
|
|
391
391
|
agent_execution_id: "aex-verify",
|
|
@@ -434,7 +434,7 @@ describe("Golden Execution — Tier 1d: Advanced Tasks", () => {
|
|
|
434
434
|
const model = loadWorkflowFromYaml(crossOrgYaml);
|
|
435
435
|
const state = createState();
|
|
436
436
|
|
|
437
|
-
const mockCallAgent = vi.fn(async () => ({
|
|
437
|
+
const mockCallAgent = vi.fn<TaskExecutionContext["callAgent"]>(async () => ({
|
|
438
438
|
final_text: "done",
|
|
439
439
|
}));
|
|
440
440
|
const ctx = makeCtx({ callAgent: mockCallAgent });
|
|
@@ -678,9 +678,11 @@ describe("Golden Execution — Structured Output Pipeline", () => {
|
|
|
678
678
|
await executeDoTasks(model.do, null, state, model, evaluateExpressionBatch, ctx);
|
|
679
679
|
|
|
680
680
|
expect(mockCallAgent).toHaveBeenCalledOnce();
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
expect(
|
|
681
|
+
// `$context` is dynamic (typed `unknown` in production); narrow to the shape this golden produces.
|
|
682
|
+
const context = state.context as { analyze: { dau: number; executive_summary: string; cohorts: unknown[] } };
|
|
683
|
+
expect(context.analyze.dau).toBe(7175);
|
|
684
|
+
expect(context.analyze.executive_summary).toBe("DAU stable at 7175");
|
|
685
|
+
expect(context.analyze.cohorts).toHaveLength(2);
|
|
684
686
|
expect(state.data.report_dau).toBe(7175);
|
|
685
687
|
expect(state.data.cohort_count).toBe(2);
|
|
686
688
|
expect(state.data.first_cohort).toBe("D1 New Players");
|
|
@@ -838,8 +840,10 @@ describe("Golden Execution — Structured Output Pipeline", () => {
|
|
|
838
840
|
|
|
839
841
|
await executeDoTasks(model.do, null, state, model, evaluateExpressionBatch, ctx);
|
|
840
842
|
|
|
841
|
-
|
|
842
|
-
|
|
843
|
+
// `$context` is dynamic (typed `unknown` in production); narrow to the shape this golden produces.
|
|
844
|
+
const context = state.context as { analyze: { dau: number; executive_summary: string } };
|
|
845
|
+
expect(context.analyze.dau).toBe(7175);
|
|
846
|
+
expect(context.analyze.executive_summary).toBe("DAU stable at 7175");
|
|
843
847
|
expect(state.data.report_dau).toBe(7175);
|
|
844
848
|
expect(state.data.summary).toBe("DAU stable at 7175");
|
|
845
849
|
});
|
|
@@ -979,9 +983,11 @@ describe("Golden Execution — Structured Output Pipeline", () => {
|
|
|
979
983
|
|
|
980
984
|
await executeDoTasks(model.do, null, state, model, evaluateExpressionBatch, ctx);
|
|
981
985
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
expect(
|
|
986
|
+
// `$context` is dynamic (typed `unknown` in production); narrow to the shape this golden produces.
|
|
987
|
+
const context = state.context as { analyze: { dau: number; cohorts: unknown[]; anomalies: unknown[] } };
|
|
988
|
+
expect(context.analyze.dau).toBe(7175);
|
|
989
|
+
expect(context.analyze.cohorts).toHaveLength(2);
|
|
990
|
+
expect(context.analyze.anomalies).toHaveLength(1);
|
|
985
991
|
expect(state.data.summary).toBe("Garden Design Makeover DAU remains stable at 7,175");
|
|
986
992
|
expect(state.data.anomaly_count).toBe(1);
|
|
987
993
|
});
|
|
@@ -991,7 +997,7 @@ describe("Golden Execution — Structured Output Pipeline", () => {
|
|
|
991
997
|
const state = createState();
|
|
992
998
|
state.env = { NOTIFICATION_DATE: "2026-05-26" };
|
|
993
999
|
|
|
994
|
-
const mockCallAgent = vi.fn(async () => ({
|
|
1000
|
+
const mockCallAgent = vi.fn<TaskExecutionContext["callAgent"]>(async () => ({
|
|
995
1001
|
structured: {
|
|
996
1002
|
executive_summary: "Garden Design Makeover DAU stable at 7,185",
|
|
997
1003
|
dau: 7185,
|
|
@@ -1019,13 +1025,22 @@ describe("Golden Execution — Structured Output Pipeline", () => {
|
|
|
1019
1025
|
expect(mockCallAgent).toHaveBeenCalledOnce();
|
|
1020
1026
|
const [config, env, metadata] = mockCallAgent.mock.calls[0];
|
|
1021
1027
|
|
|
1022
|
-
// Schema must survive expression resolution
|
|
1023
|
-
|
|
1028
|
+
// Schema must survive expression resolution. `output.schema` is an arbitrary
|
|
1029
|
+
// JSON schema (typed `Record<string, unknown>` in production); narrow to the
|
|
1030
|
+
// concrete shape this golden asserts against.
|
|
1031
|
+
if (!config.output) throw new Error("expected an output contract on the agent call");
|
|
1032
|
+
const schema = config.output.schema as {
|
|
1033
|
+
required: string[];
|
|
1034
|
+
properties: {
|
|
1035
|
+
cohorts: { items: { required: string[] } };
|
|
1036
|
+
anomalies: { items: { properties: { severity: { enum: string[] } } } };
|
|
1037
|
+
};
|
|
1038
|
+
};
|
|
1024
1039
|
expect(config.output.schema).toBeDefined();
|
|
1025
|
-
expect(
|
|
1026
|
-
expect(
|
|
1040
|
+
expect(schema.required).toEqual(["executive_summary", "cohorts", "anomalies"]);
|
|
1041
|
+
expect(schema.properties.cohorts.items.required)
|
|
1027
1042
|
.toEqual(["name", "size", "action_needed"]);
|
|
1028
|
-
expect(
|
|
1043
|
+
expect(schema.properties.anomalies.items.properties.severity.enum)
|
|
1029
1044
|
.toEqual(["warning", "critical"]);
|
|
1030
1045
|
expect(config.output.on_invalid).toBe("ON_INVALID_FAIL");
|
|
1031
1046
|
|
|
@@ -1040,8 +1055,10 @@ describe("Golden Execution — Structured Output Pipeline", () => {
|
|
|
1040
1055
|
expect(metadata.taskName).toBe("analyze_player_data");
|
|
1041
1056
|
|
|
1042
1057
|
// Structured output exported to context and consumed downstream
|
|
1043
|
-
|
|
1044
|
-
|
|
1058
|
+
// `$context` is dynamic (typed `unknown` in production); narrow to the shape this golden produces.
|
|
1059
|
+
const context = state.context as { analyze_player_data: { dau: number; executive_summary: string } };
|
|
1060
|
+
expect(context.analyze_player_data.dau).toBe(7185);
|
|
1061
|
+
expect(context.analyze_player_data.executive_summary).toContain("7,185");
|
|
1045
1062
|
expect(state.data.final_dau).toBe(7185);
|
|
1046
1063
|
expect(state.data.anomaly_count).toBe(1);
|
|
1047
1064
|
});
|
|
@@ -554,7 +554,7 @@ describe("executeTryTask — retryContext propagation", () => {
|
|
|
554
554
|
|
|
555
555
|
let capturedRetryContext: unknown = undefined;
|
|
556
556
|
const spyEmitEvents = vi.fn(async function (this: TaskExecutionContext, events: WorkflowEventDescriptor[]) {
|
|
557
|
-
capturedRetryContext =
|
|
557
|
+
capturedRetryContext = this.retryContext;
|
|
558
558
|
});
|
|
559
559
|
|
|
560
560
|
let callCount = 0;
|