@stigmer/runner 3.15.3-dev.20260914121148 → 3.16.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/README.md +2 -1
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/approval-contract/types.d.ts +1 -1
- package/dist/__test-utils__/hermetic-activity.d.ts +61 -7
- package/dist/__test-utils__/hermetic-activity.js +100 -9
- package/dist/__test-utils__/hermetic-activity.js.map +1 -1
- package/dist/__test-utils__/model-registry-fixture.d.ts +22 -3
- package/dist/__test-utils__/model-registry-fixture.js +22 -7
- package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.d.ts +2 -2
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +2 -2
- package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +61 -0
- package/dist/activities/execute-cursor/__test-utils__/fold.js +94 -0
- package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +1 -1
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +47 -12
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +41 -10
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +15 -6
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +17 -4
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -1
- package/dist/activities/execute-cursor/adapter.d.ts +4 -4
- package/dist/activities/execute-cursor/adapter.js +4 -4
- package/dist/activities/execute-cursor/approval-policy.d.ts +10 -10
- package/dist/activities/execute-cursor/approval-policy.js +12 -23
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +35 -1
- package/dist/activities/execute-cursor/approval-state.js +65 -0
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/{message-translator.d.ts → boundary-rows.d.ts} +45 -341
- package/dist/activities/execute-cursor/boundary-rows.js +1018 -0
- package/dist/activities/execute-cursor/boundary-rows.js.map +1 -0
- package/dist/activities/execute-cursor/cursor-capabilities.d.ts +1 -1
- package/dist/activities/execute-cursor/cursor-capabilities.js +1 -1
- package/dist/activities/execute-cursor/cursor-event-recorder.d.ts +33 -14
- package/dist/activities/execute-cursor/cursor-event-recorder.js +43 -21
- package/dist/activities/execute-cursor/cursor-event-recorder.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +3 -3
- package/dist/activities/execute-cursor/prompt-builder.js +4 -4
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/service-tier.js +1 -2
- package/dist/activities/execute-cursor/service-tier.js.map +1 -1
- package/dist/activities/execute-cursor/sub-agent-steps.d.ts +79 -0
- package/dist/activities/execute-cursor/sub-agent-steps.js +180 -0
- package/dist/activities/execute-cursor/sub-agent-steps.js.map +1 -0
- package/dist/activities/execute-cursor/tool-result.d.ts +49 -0
- package/dist/activities/execute-cursor/tool-result.js +130 -0
- package/dist/activities/execute-cursor/tool-result.js.map +1 -0
- package/dist/activities/execute-cursor/translator.d.ts +178 -0
- package/dist/activities/execute-cursor/translator.js +485 -0
- package/dist/activities/execute-cursor/translator.js.map +1 -0
- package/dist/activities/execute-cursor/turn-boundary.d.ts +15 -5
- package/dist/activities/execute-cursor/turn-boundary.js +10 -14
- package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
- package/dist/activities/execute-cursor/turn-settle.d.ts +11 -7
- package/dist/activities/execute-cursor/turn-settle.js +47 -34
- package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
- package/dist/activities/execute-cursor/turn-setup.d.ts +2 -2
- package/dist/activities/execute-cursor/turn-setup.js +5 -5
- package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
- package/dist/activities/execute-cursor/turn-stream.d.ts +23 -14
- package/dist/activities/execute-cursor/turn-stream.js +41 -28
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-cursor/turn.d.ts +4 -4
- package/dist/activities/execute-cursor/turn.js +5 -5
- package/dist/activities/execute-cursor/usage-pricing.d.ts +2 -2
- package/dist/activities/execute-cursor/usage-pricing.js +2 -2
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +2 -2
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +2 -2
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +16 -11
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -10
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +2 -3
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +2 -3
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +12 -3
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +18 -4
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.d.ts +10 -1
- package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js +24 -11
- package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js.map +1 -1
- package/dist/activities/execute-deep-agent/adapter.d.ts +1 -1
- package/dist/activities/execute-deep-agent/adapter.js +1 -1
- package/dist/activities/execute-deep-agent/approval-file-change.d.ts +19 -19
- package/dist/activities/execute-deep-agent/approval-file-change.js +16 -15
- package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -1
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +2 -2
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +2 -2
- package/dist/activities/execute-deep-agent/hitl.d.ts +2 -2
- package/dist/activities/execute-deep-agent/hitl.js +2 -2
- package/dist/activities/execute-deep-agent/inline-publisher.d.ts +13 -3
- package/dist/activities/execute-deep-agent/inline-publisher.js +3 -3
- package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +3 -3
- package/dist/activities/execute-deep-agent/prompt-builder.js +6 -7
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +16 -8
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +20 -33
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +3 -3
- package/dist/activities/execute-deep-agent/subagent-transformer.js +1 -1
- package/dist/activities/execute-deep-agent/translator.d.ts +134 -0
- package/dist/activities/execute-deep-agent/translator.js +418 -0
- package/dist/activities/execute-deep-agent/translator.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-settle.d.ts +13 -7
- package/dist/activities/execute-deep-agent/turn-settle.js +34 -45
- package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-setup.d.ts +8 -8
- package/dist/activities/execute-deep-agent/turn-setup.js +7 -7
- package/dist/activities/execute-deep-agent/turn-stream.d.ts +13 -10
- package/dist/activities/execute-deep-agent/turn-stream.js +44 -41
- package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn.d.ts +3 -3
- package/dist/activities/execute-deep-agent/turn.js +3 -3
- package/dist/activities/generate-session-subject.d.ts +25 -4
- package/dist/activities/generate-session-subject.js +17 -7
- package/dist/activities/generate-session-subject.js.map +1 -1
- package/dist/client/stigmer-client.d.ts +17 -6
- package/dist/client/stigmer-client.js +47 -14
- package/dist/client/stigmer-client.js.map +1 -1
- package/dist/config.d.ts +6 -3
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/harness/approval-decisions.d.ts +1 -1
- package/dist/harness/approval-decisions.js +1 -1
- package/dist/harness/capabilities.d.ts +21 -11
- package/dist/harness/capabilities.js +2 -2
- package/dist/harness/capture.d.ts +4 -4
- package/dist/harness/capture.js +4 -4
- package/dist/harness/persist-chokepoint.d.ts +3 -3
- package/dist/harness/persist-chokepoint.js +3 -3
- package/dist/harness/registry.d.ts +2 -2
- package/dist/harness/registry.js +2 -2
- package/dist/harness/run-turn.d.ts +6 -4
- package/dist/harness/run-turn.js +31 -9
- package/dist/harness/run-turn.js.map +1 -1
- package/dist/harness/stop-controller.d.ts +1 -1
- package/dist/harness/stop-controller.js +1 -1
- package/dist/harness/terminal-table.d.ts +7 -7
- package/dist/harness/terminal-table.js +7 -7
- package/dist/harness/transcript/builder.d.ts +182 -0
- package/dist/harness/transcript/builder.js +693 -0
- package/dist/harness/transcript/builder.js.map +1 -0
- package/dist/harness/transcript/events.d.ts +218 -0
- package/dist/harness/transcript/events.js +50 -0
- package/dist/harness/transcript/events.js.map +1 -0
- package/dist/harness/transcript/state.d.ts +110 -0
- package/dist/harness/transcript/state.js +148 -0
- package/dist/harness/transcript/state.js.map +1 -0
- package/dist/harness/turn-context.d.ts +54 -38
- package/dist/harness/turn-context.js +42 -43
- package/dist/harness/turn-context.js.map +1 -1
- package/dist/harness/types.d.ts +63 -22
- package/dist/harness/types.js +12 -11
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage-accumulator.d.ts +2 -2
- package/dist/harness/usage-accumulator.js +2 -2
- package/dist/harness-adapters.d.ts +5 -4
- package/dist/harness-adapters.js +5 -4
- package/dist/harness-adapters.js.map +1 -1
- package/dist/interceptors/run-credential-activity.d.ts +28 -0
- package/dist/interceptors/run-credential-activity.js +56 -0
- package/dist/interceptors/run-credential-activity.js.map +1 -0
- package/dist/middleware/approval-gate.d.ts +6 -0
- package/dist/middleware/approval-gate.js +7 -57
- package/dist/middleware/approval-gate.js.map +1 -1
- package/dist/middleware/cost-advisory.d.ts +3 -3
- package/dist/middleware/cost-advisory.js +3 -3
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/runner-manager.js +10 -4
- package/dist/runner-manager.js.map +1 -1
- package/dist/shared/activity-input.d.ts +9 -0
- package/dist/shared/activity-input.js +17 -0
- package/dist/shared/activity-input.js.map +1 -1
- package/dist/shared/approval-policy.d.ts +53 -0
- package/dist/shared/approval-policy.js +76 -0
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/shared/args-preview.d.ts +45 -22
- package/dist/shared/args-preview.js +51 -41
- package/dist/shared/args-preview.js.map +1 -1
- package/dist/shared/attachment-resolver.d.ts +4 -4
- package/dist/shared/attachment-resolver.js +4 -4
- package/dist/shared/attachment-zip.d.ts +2 -2
- package/dist/shared/attachment-zip.js +2 -2
- package/dist/shared/channel-attachment.d.ts +8 -5
- package/dist/shared/channel-attachment.js +10 -6
- package/dist/shared/channel-attachment.js.map +1 -1
- package/dist/shared/cost-guard.d.ts +2 -2
- package/dist/shared/cost-guard.js +2 -2
- package/dist/shared/exact-apply.d.ts +1 -1
- package/dist/shared/exact-apply.js +1 -1
- package/dist/shared/execution-context.d.ts +2 -2
- package/dist/shared/execution-context.js +2 -2
- package/dist/shared/extract-structured-output.d.ts +2 -2
- package/dist/shared/extract-structured-output.js +2 -2
- package/dist/shared/filereview/cas-touched.d.ts +2 -2
- package/dist/shared/filereview/cas-touched.js +2 -2
- package/dist/shared/filereview/progress.d.ts +13 -0
- package/dist/shared/filereview/progress.js +13 -0
- package/dist/shared/filereview/progress.js.map +1 -1
- package/dist/shared/heartbeat.d.ts +1 -1
- package/dist/shared/heartbeat.js +1 -1
- package/dist/shared/llm-backend.d.ts +0 -4
- package/dist/shared/llm-backend.js +0 -4
- package/dist/shared/llm-backend.js.map +1 -1
- package/dist/shared/memory-attachment.d.ts +16 -9
- package/dist/shared/memory-attachment.js +18 -10
- package/dist/shared/memory-attachment.js.map +1 -1
- package/dist/shared/model-error.d.ts +1 -2
- package/dist/shared/model-error.js +1 -2
- package/dist/shared/model-error.js.map +1 -1
- package/dist/shared/persist-decision.d.ts +18 -24
- package/dist/shared/persist-decision.js +19 -11
- package/dist/shared/persist-decision.js.map +1 -1
- package/dist/shared/prompt-sections.d.ts +4 -4
- package/dist/shared/prompt-sections.js +4 -4
- package/dist/shared/run-credential-store.d.ts +32 -0
- package/dist/shared/run-credential-store.js +39 -0
- package/dist/shared/run-credential-store.js.map +1 -0
- package/dist/shared/run-credential.d.ts +61 -0
- package/dist/shared/run-credential.js +68 -0
- package/dist/shared/run-credential.js.map +1 -0
- package/dist/shared/skill-resolver.d.ts +3 -3
- package/dist/shared/skill-resolver.js +3 -3
- package/dist/shared/status-offload.d.ts +1 -1
- package/dist/shared/status-offload.js +2 -2
- package/dist/shared/status-offload.js.map +1 -1
- package/dist/shared/streaming-scheduler.d.ts +2 -7
- package/dist/shared/streaming-scheduler.js +6 -14
- package/dist/shared/streaming-scheduler.js.map +1 -1
- package/dist/shared/subagent-rows.d.ts +2 -2
- package/dist/shared/subagent-rows.js +2 -2
- package/dist/shared/synthesized-attachment.d.ts +30 -3
- package/dist/shared/synthesized-attachment.js +26 -0
- package/dist/shared/synthesized-attachment.js.map +1 -1
- package/dist/shared/todos.d.ts +3 -3
- package/dist/shared/todos.js +3 -3
- package/dist/shared/tool-row.d.ts +19 -1
- package/dist/shared/tool-row.js +36 -2
- package/dist/shared/tool-row.js.map +1 -1
- package/dist/shared/worker-shutdown.d.ts +1 -1
- package/dist/shared/worker-shutdown.js +1 -1
- package/dist/shared/workspace/session-provision.d.ts +1 -1
- package/dist/shared/workspace/session-provision.js +1 -1
- package/dist/shared/workspace/sources/empty.d.ts +1 -1
- package/dist/shared/workspace/sources/empty.js +1 -2
- package/dist/shared/workspace/sources/empty.js.map +1 -1
- package/dist/shared/workspace/sources/git.js +4 -4
- package/dist/shared/workspace/sources/git.js.map +1 -1
- package/dist/shared/workspace/sources/local-path.js +6 -6
- package/dist/shared/workspace/sources/local-path.js.map +1 -1
- package/dist/shared/workspace/stigmer-link.d.ts +1 -1
- package/dist/shared/workspace/stigmer-link.js +1 -1
- package/dist/shared/workspace/types.d.ts +2 -5
- package/dist/shared/workspace/types.js +0 -6
- package/dist/shared/workspace/types.js.map +1 -1
- package/dist/shared/workspace/writeback-coordinator.d.ts +17 -4
- package/dist/shared/workspace/writeback-coordinator.js +7 -9
- package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
- package/dist/worker.js +10 -3
- package/dist/worker.js.map +1 -1
- package/dist/workflow-source.d.ts +10 -0
- package/dist/workflow-source.js +12 -0
- package/dist/workflow-source.js.map +1 -1
- package/dist/workflows/execute-from-execution.d.ts +15 -0
- package/dist/workflows/execute-from-execution.js +11 -0
- package/dist/workflows/execute-from-execution.js.map +1 -1
- package/dist/workflows/index.d.ts +5 -3
- package/dist/workflows/index.js +5 -3
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/interceptors/run-credential.d.ts +34 -0
- package/dist/workflows/interceptors/run-credential.js +71 -0
- package/dist/workflows/interceptors/run-credential.js.map +1 -0
- package/package.json +4 -4
- package/src/__test-utils__/__tests__/execution-record-barrier.test.ts +70 -0
- package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +35 -1
- package/src/__test-utils__/approval-contract/contract.ts +1 -1
- package/src/__test-utils__/approval-contract/types.ts +1 -1
- package/src/__test-utils__/harness-boot-order-child.ts +1 -1
- package/src/__test-utils__/harness-contract/contract.ts +8 -8
- package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
- package/src/__test-utils__/harness-contract/runtime-contract.ts +52 -16
- package/src/__test-utils__/harness-contract/scripted-adapter.ts +47 -43
- package/src/__test-utils__/hermetic-activity.ts +113 -9
- package/src/__test-utils__/model-registry-fixture.ts +31 -7
- package/src/__test-utils__/module-specifiers.ts +32 -3
- package/src/__tests__/harness-boot-order.test.ts +1 -1
- package/src/__tests__/harness-contract.test.ts +1 -1
- package/src/__tests__/run-credential-e2e.test.ts +233 -0
- package/src/__tests__/run-credential-registration.test.ts +80 -0
- package/src/__tests__/runner-manager.test.ts +1 -1
- package/src/activities/__tests__/generate-session-subject-wire.test.ts +119 -0
- package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +1 -1
- package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +2 -2
- package/src/activities/execute-cursor/__test-utils__/fold.ts +116 -0
- package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +1 -1
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +67 -17
- package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +19 -5
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/approval-state.test.ts +14 -21
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +3 -3
- package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/cursor-event-recorder.test.ts +142 -0
- package/src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts +19 -8
- package/src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts +10 -8
- package/src/activities/execute-cursor/__tests__/cursor-transcript-live.test.ts +298 -0
- package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +4 -2
- package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/deny-and-retry.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/mcp-tool-call.status.json +71 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-task-note.status.json +73 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +78 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +72 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +72 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sub-agent-delegation.status.json +109 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/thinking-turn.status.json +78 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/todo-write.status.json +119 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-error.status.json +68 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-only-step.status.json +67 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +7 -7
- package/src/activities/execute-cursor/__tests__/hermetic/mcp-tool-call.test.ts +146 -0
- package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +5 -5
- package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/hermetic/sdk-task-note.test.ts +122 -0
- package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +276 -0
- package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +8 -8
- package/src/activities/execute-cursor/__tests__/hermetic/sub-agent-delegation.test.ts +196 -0
- package/src/activities/execute-cursor/__tests__/hermetic/thinking-turn.test.ts +145 -0
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/todo-write.test.ts +165 -0
- package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +3 -3
- package/src/activities/execute-cursor/__tests__/hermetic/tool-error.test.ts +138 -0
- package/src/activities/execute-cursor/__tests__/hermetic/tool-only-step.test.ts +130 -0
- package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +13 -1
- package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +2 -2
- package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +43 -60
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +23 -28
- package/src/activities/execute-cursor/__tests__/hook-script.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +5 -5
- package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +11 -13
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +8 -11
- package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +8 -22
- package/src/activities/execute-cursor/__tests__/translator.test.ts +594 -0
- package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +8 -5
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +87 -63
- package/src/activities/execute-cursor/adapter.ts +4 -4
- package/src/activities/execute-cursor/approval-policy.ts +12 -24
- package/src/activities/execute-cursor/approval-state.ts +66 -1
- package/src/activities/execute-cursor/boundary-rows.ts +1132 -0
- package/src/activities/execute-cursor/cursor-capabilities.ts +1 -1
- package/src/activities/execute-cursor/cursor-event-recorder.ts +57 -28
- package/src/activities/execute-cursor/fetch-interceptor.ts +1 -1
- package/src/activities/execute-cursor/http2-interceptor.ts +1 -1
- package/src/activities/execute-cursor/prompt-builder.ts +6 -6
- package/src/activities/execute-cursor/service-tier.ts +1 -2
- package/src/activities/execute-cursor/sub-agent-steps.ts +188 -0
- package/src/activities/execute-cursor/tool-result.ts +128 -0
- package/src/activities/execute-cursor/translator.ts +541 -0
- package/src/activities/execute-cursor/turn-boundary.ts +21 -14
- package/src/activities/execute-cursor/turn-settle.ts +46 -34
- package/src/activities/execute-cursor/turn-setup.ts +5 -5
- package/src/activities/execute-cursor/turn-stream.ts +49 -46
- package/src/activities/execute-cursor/turn.ts +5 -5
- package/src/activities/execute-cursor/usage-pricing.ts +2 -2
- package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +2 -2
- package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +23 -11
- package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +1 -1
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +2 -3
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +25 -4
- package/src/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.ts +25 -11
- package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +6 -17
- package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +25 -8
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +2 -7
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +4 -14
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +4 -7
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +2 -9
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +2 -9
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +109 -76
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +2 -10
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +2 -10
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +3 -6
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/write-todos.status.json +92 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +3 -3
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +9 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +3 -3
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +3 -3
- package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +7 -6
- package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +10 -11
- package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +4 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +9 -8
- package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +21 -13
- package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +7 -7
- package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +28 -12
- package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +21 -21
- package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +5 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/write-todos.test.ts +160 -0
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +35 -30
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +3 -4
- package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +12 -10
- package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +13 -3
- package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +26 -18
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/{subagent-tracker.test.ts → translator-subagents.test.ts} +76 -57
- package/src/activities/execute-deep-agent/__tests__/{v3-status-builder.test.ts → translator-through-builder.test.ts} +213 -299
- package/src/activities/execute-deep-agent/__tests__/translator.test.ts +505 -0
- package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +11 -29
- package/src/activities/execute-deep-agent/adapter.ts +1 -1
- package/src/activities/execute-deep-agent/approval-file-change.ts +20 -22
- package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +2 -2
- package/src/activities/execute-deep-agent/hitl.ts +2 -2
- package/src/activities/execute-deep-agent/inline-publisher.ts +16 -5
- package/src/activities/execute-deep-agent/prompt-builder.ts +6 -7
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +22 -31
- package/src/activities/execute-deep-agent/subagent-transformer.ts +3 -3
- package/src/activities/execute-deep-agent/translator.ts +463 -0
- package/src/activities/execute-deep-agent/turn-settle.ts +35 -43
- package/src/activities/execute-deep-agent/turn-setup.ts +8 -8
- package/src/activities/execute-deep-agent/turn-stream.ts +53 -51
- package/src/activities/execute-deep-agent/turn.ts +3 -3
- package/src/activities/generate-session-subject.ts +29 -4
- package/src/client/__tests__/stigmer-client.test.ts +92 -0
- package/src/client/stigmer-client.ts +48 -14
- package/src/config.ts +6 -3
- package/src/harness/README.md +335 -0
- package/src/harness/__tests__/approval-decisions.test.ts +2 -2
- package/src/harness/__tests__/capture.test.ts +3 -3
- package/src/harness/__tests__/import-direction.test.ts +3 -2
- package/src/harness/__tests__/mount-skills.test.ts +4 -1
- package/src/harness/__tests__/readme-index.test.ts +339 -0
- package/src/harness/__tests__/run-turn.test.ts +131 -6
- package/src/harness/__tests__/transcript-is-engine-free.test.ts +83 -0
- package/src/harness/__tests__/transcript-writers.test.ts +191 -0
- package/src/harness/__tests__/turn-attachments-vision.test.ts +5 -2
- package/src/harness/__tests__/turn-context.test.ts +5 -5
- package/src/harness/approval-decisions.ts +1 -1
- package/src/harness/capabilities.ts +21 -11
- package/src/harness/capture.ts +4 -4
- package/src/harness/persist-chokepoint.ts +3 -3
- package/src/harness/registry.ts +2 -2
- package/src/harness/run-turn.ts +33 -9
- package/src/harness/stop-controller.ts +1 -1
- package/src/harness/terminal-table.ts +7 -7
- package/src/harness/transcript/__tests__/builder.test.ts +975 -0
- package/src/harness/transcript/__tests__/state.test.ts +143 -0
- package/src/harness/transcript/builder.ts +755 -0
- package/src/harness/transcript/events.ts +262 -0
- package/src/harness/transcript/state.ts +167 -0
- package/src/harness/turn-context.ts +61 -46
- package/src/harness/types.ts +64 -22
- package/src/harness/usage-accumulator.ts +2 -2
- package/src/harness-adapters.ts +5 -4
- package/src/interceptors/__tests__/run-credential-activity.test.ts +133 -0
- package/src/interceptors/run-credential-activity.ts +67 -0
- package/src/middleware/__tests__/cost-advisory.test.ts +2 -2
- package/src/middleware/approval-gate.ts +7 -74
- package/src/middleware/cost-advisory.ts +3 -3
- package/src/middleware/index.ts +1 -1
- package/src/runner-manager.ts +14 -4
- package/src/shared/__tests__/approval-policy.test.ts +45 -0
- package/src/shared/__tests__/args-preview.test.ts +40 -20
- package/src/shared/__tests__/attachment-naming.test.ts +1 -1
- package/src/shared/__tests__/attachment-resolver.test.ts +5 -5
- package/src/shared/__tests__/attachment-zip.test.ts +1 -1
- package/src/shared/__tests__/blueprint-resolver.test.ts +1 -1
- package/src/shared/__tests__/channel-attachment.test.ts +12 -0
- package/src/shared/__tests__/cost-guard.test.ts +1 -1
- package/src/shared/__tests__/exact-apply.test.ts +2 -1
- package/src/shared/__tests__/memory-attachment.test.ts +17 -0
- package/src/shared/__tests__/persist-decision.test.ts +19 -33
- package/src/shared/__tests__/prompt-sections.test.ts +1 -1
- package/src/shared/__tests__/run-credential.test.ts +111 -0
- package/src/shared/__tests__/stamp-flowed-rows.test.ts +1 -1
- package/src/shared/__tests__/status-offload.test.ts +1 -1
- package/src/shared/__tests__/streaming-scheduler.test.ts +8 -9
- package/src/shared/__tests__/todos.test.ts +1 -1
- package/src/shared/__tests__/tool-row.test.ts +1 -1
- package/src/shared/activity-input.ts +21 -0
- package/src/shared/approval-policy.ts +95 -0
- package/src/shared/args-preview.ts +51 -42
- package/src/shared/attachment-resolver.ts +4 -4
- package/src/shared/attachment-zip.ts +2 -2
- package/src/shared/channel-attachment.ts +14 -6
- package/src/shared/cost-guard.ts +2 -2
- package/src/shared/exact-apply.ts +1 -1
- package/src/shared/execution-context.ts +2 -2
- package/src/shared/extract-structured-output.ts +2 -2
- package/src/shared/filereview/__tests__/capture.test.ts +9 -5
- package/src/shared/filereview/__tests__/git-substrate.test.ts +4 -1
- package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +3 -3
- package/src/shared/filereview/cas-touched.ts +2 -2
- package/src/shared/filereview/progress.ts +13 -0
- package/src/shared/heartbeat.ts +1 -1
- package/src/shared/llm-backend.ts +0 -4
- package/src/shared/memory-attachment.ts +22 -10
- package/src/shared/model-error.ts +1 -2
- package/src/shared/persist-decision.ts +19 -28
- package/src/shared/prompt-sections.ts +4 -4
- package/src/shared/run-credential-store.ts +45 -0
- package/src/shared/run-credential.ts +70 -0
- package/src/shared/skill-resolver.ts +3 -3
- package/src/shared/status-offload.ts +2 -2
- package/src/shared/streaming-scheduler.ts +8 -13
- package/src/shared/subagent-rows.ts +2 -2
- package/src/shared/synthesized-attachment.ts +38 -3
- package/src/shared/todos.ts +3 -3
- package/src/shared/tool-row.ts +38 -2
- package/src/shared/worker-shutdown.ts +1 -1
- package/src/shared/workspace/__tests__/git-source.test.ts +3 -3
- package/src/shared/workspace/__tests__/provisioner.test.ts +5 -5
- package/src/shared/workspace/__tests__/session-provision.test.ts +2 -2
- package/src/shared/workspace/__tests__/writeback-coordinator.integration.test.ts +8 -9
- package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +25 -25
- package/src/shared/workspace/provisioner.ts +1 -1
- package/src/shared/workspace/session-provision.ts +1 -1
- package/src/shared/workspace/sources/empty.ts +2 -2
- package/src/shared/workspace/sources/git.ts +3 -4
- package/src/shared/workspace/sources/local-path.ts +5 -6
- package/src/shared/workspace/stigmer-link.ts +1 -1
- package/src/shared/workspace/types.ts +2 -5
- package/src/shared/workspace/writeback-coordinator.ts +23 -12
- package/src/worker.ts +15 -3
- package/src/workflow-source.ts +15 -0
- package/src/workflows/__tests__/run-credential-interceptor.test.ts +178 -0
- package/src/workflows/execute-from-execution.ts +17 -0
- package/src/workflows/index.ts +5 -3
- package/src/workflows/interceptors/run-credential.ts +101 -0
- package/dist/activities/execute-cursor/delta-enricher.d.ts +0 -87
- package/dist/activities/execute-cursor/delta-enricher.js +0 -265
- package/dist/activities/execute-cursor/delta-enricher.js.map +0 -1
- package/dist/activities/execute-cursor/message-translator.js +0 -2040
- package/dist/activities/execute-cursor/message-translator.js.map +0 -1
- package/dist/activities/execute-cursor/todo-tracker.d.ts +0 -40
- package/dist/activities/execute-cursor/todo-tracker.js +0 -80
- package/dist/activities/execute-cursor/todo-tracker.js.map +0 -1
- package/dist/activities/execute-deep-agent/execution-state.d.ts +0 -54
- package/dist/activities/execute-deep-agent/execution-state.js +0 -68
- package/dist/activities/execute-deep-agent/execution-state.js.map +0 -1
- package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +0 -65
- package/dist/activities/execute-deep-agent/status-builder-shared.js +0 -90
- package/dist/activities/execute-deep-agent/status-builder-shared.js.map +0 -1
- package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +0 -113
- package/dist/activities/execute-deep-agent/subagent-tracker.js +0 -400
- package/dist/activities/execute-deep-agent/subagent-tracker.js.map +0 -1
- package/dist/activities/execute-deep-agent/v3-events.d.ts +0 -102
- package/dist/activities/execute-deep-agent/v3-events.js +0 -35
- package/dist/activities/execute-deep-agent/v3-events.js.map +0 -1
- package/dist/activities/execute-deep-agent/v3-protocol-normalizer.d.ts +0 -15
- package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js +0 -235
- package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js.map +0 -1
- package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +0 -111
- package/dist/activities/execute-deep-agent/v3-status-builder.js +0 -457
- package/dist/activities/execute-deep-agent/v3-status-builder.js.map +0 -1
- package/dist/shared/execution-status-writer.d.ts +0 -31
- package/dist/shared/execution-status-writer.js +0 -43
- package/dist/shared/execution-status-writer.js.map +0 -1
- package/src/activities/execute-cursor/__tests__/delta-enricher.test.ts +0 -310
- package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -1033
- package/src/activities/execute-cursor/__tests__/todo-tracker.test.ts +0 -498
- package/src/activities/execute-cursor/delta-enricher.ts +0 -307
- package/src/activities/execute-cursor/message-translator.ts +0 -2319
- package/src/activities/execute-cursor/todo-tracker.ts +0 -91
- package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -148
- package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -154
- package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +0 -47
- package/src/activities/execute-deep-agent/__tests__/v3-protocol-normalizer.test.ts +0 -324
- package/src/activities/execute-deep-agent/execution-state.ts +0 -78
- package/src/activities/execute-deep-agent/status-builder-shared.ts +0 -142
- package/src/activities/execute-deep-agent/subagent-tracker.ts +0 -479
- package/src/activities/execute-deep-agent/v3-events.ts +0 -153
- package/src/activities/execute-deep-agent/v3-protocol-normalizer.ts +0 -264
- package/src/activities/execute-deep-agent/v3-status-builder.ts +0 -565
- package/src/shared/execution-status-writer.ts +0 -56
|
@@ -42,6 +42,18 @@
|
|
|
42
42
|
* the SDK double (`ScriptedSdkOptions`); an SDK-side cancel or a mid-stream
|
|
43
43
|
* wedge as an `effect` step on the run. Nothing here is a switch in production
|
|
44
44
|
* code — every knob is a value the production path already reads.
|
|
45
|
+
*
|
|
46
|
+
* Two postures, two entries, one turn runner. `beginCursorScenario` is the
|
|
47
|
+
* hermetic posture: the SDK doubled by the scenario file's `vi.mock`, the
|
|
48
|
+
* clock scripted, goldens byte-stable. `beginLiveCursorScenario` is the live
|
|
49
|
+
* posture (#1097's live-run gate): the scenario file mocks ONLY the
|
|
50
|
+
* client, the real `@cursor/sdk` runs under the real activity on the real
|
|
51
|
+
* clock with a real member key, and what the activity persists is read back
|
|
52
|
+
* from the same record. A live scenario therefore has no `sdk` and no `clock`
|
|
53
|
+
* — the type says which posture a file is in — and `runCursorTurn` reads only
|
|
54
|
+
* what both have. The registry fixture's `live` pass-through and the
|
|
55
|
+
* environment's `eventRecordingDir` are the live posture's two other
|
|
56
|
+
* seams, each on the module that owns the concern.
|
|
45
57
|
*/
|
|
46
58
|
|
|
47
59
|
import { execFileSync } from "node:child_process";
|
|
@@ -216,20 +228,27 @@ export function resetCursorModuleState(): void {
|
|
|
216
228
|
_resetRegistryCache();
|
|
217
229
|
}
|
|
218
230
|
|
|
219
|
-
|
|
231
|
+
/** What both postures share: the environment, the record the activity persists into, the runner's `Config`. */
|
|
232
|
+
export interface CursorScenarioBase {
|
|
220
233
|
readonly env: HermeticEnvironment;
|
|
221
|
-
readonly clock: ScriptedClock;
|
|
222
234
|
readonly record: ExecutionRecord;
|
|
223
|
-
readonly sdk: ScriptedCursorSdk;
|
|
224
235
|
/** The runner this scenario runs on: the OSS posture plus the scenario's knobs. */
|
|
225
236
|
readonly config: Config;
|
|
226
237
|
}
|
|
227
238
|
|
|
228
|
-
|
|
229
|
-
|
|
239
|
+
/** The hermetic posture: the SDK double and the scripted clock beside the shared three. */
|
|
240
|
+
export interface CursorScenario extends CursorScenarioBase {
|
|
230
241
|
readonly clock: ScriptedClock;
|
|
242
|
+
readonly sdk: ScriptedCursorSdk;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** The live posture (header): the shared three and nothing doubled but the client. */
|
|
246
|
+
export type LiveCursorScenario = CursorScenarioBase;
|
|
247
|
+
|
|
248
|
+
/** The options both postures take. */
|
|
249
|
+
interface CursorScenarioBaseOptions {
|
|
250
|
+
readonly env: HermeticEnvironment;
|
|
231
251
|
readonly record: ExecutionRecord;
|
|
232
|
-
readonly sdk: ScriptedSdkOptions;
|
|
233
252
|
/**
|
|
234
253
|
* Control-plane facets the scenario opts INTO, or faults it injects, over
|
|
235
254
|
* the record's everyday answers (`ExecutionRecord.client`): a rejecting
|
|
@@ -245,21 +264,50 @@ export interface CursorScenarioOptions {
|
|
|
245
264
|
readonly config?: Partial<Config>;
|
|
246
265
|
}
|
|
247
266
|
|
|
248
|
-
|
|
249
|
-
|
|
267
|
+
export interface CursorScenarioOptions extends CursorScenarioBaseOptions {
|
|
268
|
+
readonly clock: ScriptedClock;
|
|
269
|
+
readonly sdk: ScriptedSdkOptions;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export interface LiveCursorScenarioOptions extends CursorScenarioBaseOptions {
|
|
273
|
+
/** The real member key the real SDK authenticates with; becomes `config.cursorApiKey`. */
|
|
274
|
+
readonly apiKey: string;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* What every scenario begins with: the harness caches dropped, the record
|
|
279
|
+
* bound as the control plane the activity will talk to, the OSS `Config`
|
|
280
|
+
* over the environment with the scenario's knobs laid on top.
|
|
281
|
+
*/
|
|
282
|
+
function beginScenarioBase(options: CursorScenarioBaseOptions): CursorScenarioBase {
|
|
250
283
|
resetCursorModuleState();
|
|
251
|
-
const sdk = new ScriptedCursorSdk(options.sdk);
|
|
252
|
-
bindScriptedSdk(sdk);
|
|
253
284
|
bindHermeticClient(options.record.client(options.clientOverrides));
|
|
254
285
|
return {
|
|
255
286
|
env: options.env,
|
|
256
|
-
clock: options.clock,
|
|
257
287
|
record: options.record,
|
|
258
|
-
sdk,
|
|
259
288
|
config: { ...hermeticCursorConfig(options.env), ...options.config },
|
|
260
289
|
};
|
|
261
290
|
}
|
|
262
291
|
|
|
292
|
+
/** Bind the record and the SDK double for a hermetic scenario; resets the harness caches first. */
|
|
293
|
+
export function beginCursorScenario(options: CursorScenarioOptions): CursorScenario {
|
|
294
|
+
const base = beginScenarioBase(options);
|
|
295
|
+
const sdk = new ScriptedCursorSdk(options.sdk);
|
|
296
|
+
bindScriptedSdk(sdk);
|
|
297
|
+
return { ...base, clock: options.clock, sdk };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Bind the record for a live scenario; resets the harness caches first. No
|
|
302
|
+
* SDK double is built or bound — the scenario file must NOT mock `@cursor/sdk`
|
|
303
|
+
* — and no clock is installed. The key lands on the `Config` exactly where
|
|
304
|
+
* the OSS runner's direct mode reads it (`turn-setup.ts`, `config.cursorApiKey`).
|
|
305
|
+
*/
|
|
306
|
+
export function beginLiveCursorScenario(options: LiveCursorScenarioOptions): LiveCursorScenario {
|
|
307
|
+
const base = beginScenarioBase(options);
|
|
308
|
+
return { ...base, config: { ...base.config, cursorApiKey: options.apiKey } };
|
|
309
|
+
}
|
|
310
|
+
|
|
263
311
|
export interface CursorTurnOptions {
|
|
264
312
|
/** Empty for a first invocation; the agent id for a HITL reinvocation. */
|
|
265
313
|
readonly threadId?: string;
|
|
@@ -269,13 +317,15 @@ export interface CursorTurnOptions {
|
|
|
269
317
|
}
|
|
270
318
|
|
|
271
319
|
/**
|
|
272
|
-
* Run ONE `ExecuteCursor` invocation for the scenario: the
|
|
273
|
-
* adapter under the real turn runtime, as the composition roots
|
|
274
|
-
* Built per invocation (the registry constructs its client, which
|
|
275
|
-
* bound at `
|
|
320
|
+
* Run ONE `ExecuteCursor` invocation for the scenario — either posture: the
|
|
321
|
+
* real Cursor adapter under the real turn runtime, as the composition roots
|
|
322
|
+
* wire them. Built per invocation (the registry constructs its client, which
|
|
323
|
+
* is the one bound at `begin*CursorScenario`; the adapter boots on the
|
|
324
|
+
* scenario's config). Reads only the record and the config, which both
|
|
325
|
+
* postures have.
|
|
276
326
|
*/
|
|
277
327
|
export async function runCursorTurn(
|
|
278
|
-
scenario:
|
|
328
|
+
scenario: CursorScenarioBase,
|
|
279
329
|
options: CursorTurnOptions = {},
|
|
280
330
|
): Promise<ActivityInvocation> {
|
|
281
331
|
// Imported lazily so the scenario file's `vi.mock` declarations are in
|
|
@@ -15,7 +15,12 @@
|
|
|
15
15
|
* So a turn is a SCRIPT of ordered steps, one of four kinds:
|
|
16
16
|
*
|
|
17
17
|
* - `event(SDKMessage)` — yielded from `stream()`
|
|
18
|
-
* - `delta(update)` — fired through `onDelta
|
|
18
|
+
* - `delta(update)` — fired through `onDelta`: any `InteractionUpdate`
|
|
19
|
+
* (the `turn-ended` usage the loop prices; the
|
|
20
|
+
* tool-call timings, shell output and completion
|
|
21
|
+
* status the transcript folds — #1097 widened
|
|
22
|
+
* the step from `turn-ended` alone so the delta
|
|
23
|
+
* channel has an end-to-end net)
|
|
19
24
|
* - `effect(fn)` — the side effect the SDK would have performed
|
|
20
25
|
* (run the real hook, write a workspace file,
|
|
21
26
|
* cancel the activity from the outside)
|
|
@@ -25,10 +30,10 @@
|
|
|
25
30
|
* (`ScriptStep`, driven in order), applied to the SDK's event surface.
|
|
26
31
|
*
|
|
27
32
|
* Typing: `SDKMessage`, `Run`, `RunResult`, `SDKAgent` and the delta channel's
|
|
28
|
-
* `
|
|
29
|
-
* `messages.d.ts` / `run.d.ts` / `agent.d.ts` / the vendored `delta-types`),
|
|
33
|
+
* `InteractionUpdate` are the SDK's own types (`@cursor/sdk` 1.0.31, concrete
|
|
34
|
+
* in `messages.d.ts` / `run.d.ts` / `agent.d.ts` / the vendored `delta-types`),
|
|
30
35
|
* so a script that drifts from the real event shape fails `tsc`. (At 1.0.13
|
|
31
|
-
* the delta types resolved to `any` and the one delta this double
|
|
36
|
+
* the delta types resolved to `any` and the one delta this double emitted was
|
|
32
37
|
* typed locally; stigmer/stigmer#1053 closed that gap.)
|
|
33
38
|
*
|
|
34
39
|
* Cancellation: `run.cancel()` is how the harness stops a turn (first denial,
|
|
@@ -48,6 +53,7 @@
|
|
|
48
53
|
import type {
|
|
49
54
|
AgentUsage,
|
|
50
55
|
GetUsageOptions,
|
|
56
|
+
InteractionUpdate,
|
|
51
57
|
ModelSelection,
|
|
52
58
|
Run,
|
|
53
59
|
RunOperation,
|
|
@@ -73,7 +79,7 @@ export interface EffectContext {
|
|
|
73
79
|
|
|
74
80
|
export type ScriptStep =
|
|
75
81
|
| { readonly kind: "event"; readonly event: SDKMessage }
|
|
76
|
-
| { readonly kind: "delta"; readonly update:
|
|
82
|
+
| { readonly kind: "delta"; readonly update: InteractionUpdate }
|
|
77
83
|
| { readonly kind: "effect"; readonly label: string; readonly run: (ctx: EffectContext) => void | Promise<void> }
|
|
78
84
|
| { readonly kind: "result"; readonly result: Omit<RunResult, "id"> };
|
|
79
85
|
|
|
@@ -85,6 +91,10 @@ export const step = {
|
|
|
85
91
|
event(event: SDKMessage): ScriptStep {
|
|
86
92
|
return { kind: "event", event };
|
|
87
93
|
},
|
|
94
|
+
/** Any delta the SDK fires through `onDelta` between stream events: tool-call timings, shell output, a completion's status. */
|
|
95
|
+
delta(update: InteractionUpdate): ScriptStep {
|
|
96
|
+
return { kind: "delta", update };
|
|
97
|
+
},
|
|
88
98
|
/** The `turn-ended` delta `turn-stream.ts` prices; the SDK's shape, all four counts stated. */
|
|
89
99
|
turnEnded(usage: NonNullable<TurnEndedUpdate["usage"]>): ScriptStep {
|
|
90
100
|
return { kind: "delta", update: { type: "turn-ended", usage } };
|
|
@@ -130,6 +140,10 @@ export function sdkEvents(agentId: string, runId: string) {
|
|
|
130
140
|
status(status: "CREATING" | "RUNNING" | "FINISHED" | "ERROR" | "CANCELLED" | "EXPIRED", message?: string): SDKMessage {
|
|
131
141
|
return { type: "status", ...base, status, message };
|
|
132
142
|
},
|
|
143
|
+
/** The SDK's `task` event: a status line about the run in the agent's own voice, which the transcript shows as a SYSTEM message. */
|
|
144
|
+
task(text: string, status?: string): SDKMessage {
|
|
145
|
+
return { type: "task", ...base, text, status };
|
|
146
|
+
},
|
|
133
147
|
};
|
|
134
148
|
}
|
|
135
149
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @regression file-hitl-phase0 — pins
|
|
2
|
+
* @regression file-hitl-phase0 — pins content-exact approval identity: approving
|
|
3
|
+
* one edit never lets a DIFFERENT edit to the same path ride the grant.
|
|
3
4
|
*
|
|
4
5
|
* Unit tests for the Cursor-harness HITL approval gate logic.
|
|
5
6
|
*
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @regression file-hitl-phase0 — pins
|
|
2
|
+
* @regression file-hitl-phase0 — pins content-exact approval identity: approving
|
|
3
|
+
* one edit never lets a DIFFERENT edit to the same path ride the grant.
|
|
3
4
|
*
|
|
4
5
|
* Resume-grant identity round-trip — the H1 lock.
|
|
5
6
|
*
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
* - the resume grant via {@link buildApprovalGrants} -> parseArgs(argsPreview)
|
|
22
23
|
* (the JSON-string preview only).
|
|
23
24
|
* They agree today only because both derive from the same stream `event.args`.
|
|
24
|
-
* This suite drives the REAL stream path (
|
|
25
|
+
* This suite drives the REAL stream path (the translator into the builder) so any
|
|
25
26
|
* future change that lets the dual path diverge fails here, loudly, per category.
|
|
26
27
|
*
|
|
27
28
|
* Deterministic; no Cursor API key, no bash. The hook-side half of the equality
|
|
@@ -42,11 +43,9 @@ import {
|
|
|
42
43
|
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
43
44
|
import type { SDKMessage } from "@cursor/sdk";
|
|
44
45
|
|
|
45
|
-
import {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
toolCallIdentityToken,
|
|
49
|
-
} from "../message-translator.js";
|
|
46
|
+
import { reconcileDeniedToolCalls } from "../boundary-rows.js";
|
|
47
|
+
import { builderOver, foldCursorEvents } from "../__test-utils__/fold.js";
|
|
48
|
+
import { toolCallIdentityToken } from "../approval-state.js";
|
|
50
49
|
import {
|
|
51
50
|
buildApprovalGrants,
|
|
52
51
|
buildApprovalState,
|
|
@@ -96,7 +95,7 @@ function mcpEvent(
|
|
|
96
95
|
* and return the two identities that must be equal: the token the hook recorded
|
|
97
96
|
* when it denied the gated call, and the grant token a resume mints after the
|
|
98
97
|
* user approves it. Mirrors the activity's real sequence:
|
|
99
|
-
*
|
|
98
|
+
* translator + builder (stream) -> deny overlay (reconcileDeniedToolCalls) ->
|
|
100
99
|
* persist APPROVE -> reconstructAdjudicatedApprovals -> buildApprovalGrants.
|
|
101
100
|
*/
|
|
102
101
|
async function roundTrip(event: Extract<SDKMessage, { type: "tool_call" }>): Promise<{
|
|
@@ -105,7 +104,7 @@ async function roundTrip(event: Extract<SDKMessage, { type: "tool_call" }>): Pro
|
|
|
105
104
|
resumeStateToken: string | undefined;
|
|
106
105
|
grant: ApprovalGrant;
|
|
107
106
|
}> {
|
|
108
|
-
const tc =
|
|
107
|
+
const tc = foldCursorEvents([event]).rows()[0];
|
|
109
108
|
|
|
110
109
|
// The gated turn: the hook denies the call, recording its identity token. The
|
|
111
110
|
// runner's overlay (reconcileDeniedToolCalls) flips the same call to
|
|
@@ -120,7 +119,8 @@ async function roundTrip(event: Extract<SDKMessage, { type: "tool_call" }>): Pro
|
|
|
120
119
|
toolCalls: [tc],
|
|
121
120
|
});
|
|
122
121
|
const ledger: DeniedLedgerEntry[] = [{ toolName: tc.name, token: denialToken }];
|
|
123
|
-
const
|
|
122
|
+
const messages: AgentMessage[] = [msg];
|
|
123
|
+
const denied = await reconcileDeniedToolCalls(messages, builderOver(messages), ledger);
|
|
124
124
|
expect(denied, "the overlay must match the denial token and surface the gate").toHaveLength(1);
|
|
125
125
|
|
|
126
126
|
// The user approves; the backend persists the decision on the tool call.
|
|
@@ -130,7 +130,6 @@ async function roundTrip(event: Extract<SDKMessage, { type: "tool_call" }>): Pro
|
|
|
130
130
|
// transcript (pending_approvals is already cleared by this point) and mint the
|
|
131
131
|
// grants the next turn's hook reads. The content digest threads through so the
|
|
132
132
|
// grant reproduces the content-exact denial identity.
|
|
133
|
-
const messages: AgentMessage[] = [msg];
|
|
134
133
|
const { pendingApprovals, decisions, contentDigests } = reconstructAdjudicatedApprovals(messages);
|
|
135
134
|
const grants = buildApprovalGrants(pendingApprovals, decisions, contentDigests);
|
|
136
135
|
expect(grants, "an approved tool must yield exactly one grant").toHaveLength(1);
|
|
@@ -234,12 +233,8 @@ describe("Cursor resume-grant identity round-trip (H1 lock)", () => {
|
|
|
234
233
|
// The exact bug this change fixes: approving the rename must NOT authorize
|
|
235
234
|
// the TODO edit. They share a path (same coarse token) but differ in content,
|
|
236
235
|
// so the content-exact identity distinguishes them.
|
|
237
|
-
const rename =
|
|
238
|
-
|
|
239
|
-
);
|
|
240
|
-
const todo = buildToolCallProto(
|
|
241
|
-
builtInEvent("c2", "edit", { path: "/work/notes.md", old_string: "", new_string: "## TODO\n" }),
|
|
242
|
-
);
|
|
236
|
+
const rename = foldCursorEvents([builtInEvent("c1", "edit", { path: "/work/notes.md", old_string: "Planton Cloud", new_string: "Planton" })]).rows()[0];
|
|
237
|
+
const todo = foldCursorEvents([builtInEvent("c2", "edit", { path: "/work/notes.md", old_string: "", new_string: "## TODO\n" })]).rows()[0];
|
|
243
238
|
const renameToken = toolCallIdentityToken(rename);
|
|
244
239
|
const todoToken = toolCallIdentityToken(todo);
|
|
245
240
|
|
|
@@ -252,9 +247,7 @@ describe("Cursor resume-grant identity round-trip (H1 lock)", () => {
|
|
|
252
247
|
);
|
|
253
248
|
// Re-issuing the SAME rename content reproduces its identity (identical
|
|
254
249
|
// re-attempt is allowed; a drifted one re-gates).
|
|
255
|
-
const renameAgain =
|
|
256
|
-
builtInEvent("c3", "edit", { path: "/work/notes.md", old_string: "Planton Cloud", new_string: "Planton" }),
|
|
257
|
-
);
|
|
250
|
+
const renameAgain = foldCursorEvents([builtInEvent("c3", "edit", { path: "/work/notes.md", old_string: "Planton Cloud", new_string: "Planton" })]).rows()[0];
|
|
258
251
|
expect(toolCallIdentityToken(renameAgain)).toBe(renameToken);
|
|
259
252
|
});
|
|
260
253
|
|
|
@@ -263,7 +256,7 @@ describe("Cursor resume-grant identity round-trip (H1 lock)", () => {
|
|
|
263
256
|
event: Extract<SDKMessage, { type: "tool_call" }>,
|
|
264
257
|
action: ApprovalAction,
|
|
265
258
|
): AgentMessage {
|
|
266
|
-
const tc =
|
|
259
|
+
const tc = foldCursorEvents([event]).rows()[0];
|
|
267
260
|
tc.status = ToolCallStatus.TOOL_CALL_WAITING_APPROVAL;
|
|
268
261
|
tc.requiresApproval = true;
|
|
269
262
|
tc.approvalAction = action;
|
|
@@ -544,7 +544,7 @@ describe("attachments on a resumed turn (T04 — the mid-session WhatsApp case)"
|
|
|
544
544
|
],
|
|
545
545
|
}),
|
|
546
546
|
);
|
|
547
|
-
// The size precedes the disclosure (the shared line,
|
|
547
|
+
// The size precedes the disclosure (the shared line, since #1096).
|
|
548
548
|
expect(prompt).toContain(
|
|
549
549
|
"- `.stigmer/inputs/report-2.pdf` (1024 bytes) (renamed from duplicate 'report.pdf')",
|
|
550
550
|
);
|
|
@@ -778,8 +778,8 @@ describe("buildReinvocationPrompt", () => {
|
|
|
778
778
|
expect(prompt).toContain("Continue the rest of the task");
|
|
779
779
|
});
|
|
780
780
|
|
|
781
|
-
it("names a REJECTED action as a refusal, apart from the skipped ones, and still continues the task (stigmer#197
|
|
782
|
-
// A REJECT denies the tool and the run continues; before
|
|
781
|
+
it("names a REJECTED action as a refusal, apart from the skipped ones, and still continues the task (stigmer#197)", () => {
|
|
782
|
+
// A REJECT denies the tool and the run continues; before #1096 the
|
|
783
783
|
// runtime failed the reinvocation before this prompt was ever built, so
|
|
784
784
|
// the prompt had no REJECT arm.
|
|
785
785
|
const decisions = new Map<string, ApprovalAction>([
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @regression file-hitl-phase0 — pins
|
|
2
|
+
* @regression file-hitl-phase0 — pins content-exact approval identity: approving
|
|
3
|
+
* one edit never lets a DIFFERENT edit to the same path ride the grant.
|
|
3
4
|
*
|
|
4
5
|
* Slice D — the Cursor grant token / fingerprint as the substrate-coarsened
|
|
5
6
|
* projection of the shared canonical action.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Cursor event recorder's contract (`cursor-event-recorder.ts`): off when
|
|
3
|
+
* no directory is named; both SDK channels in ONE file under ONE arrival
|
|
4
|
+
* counter, each line saying which channel it came from; the file named by the
|
|
5
|
+
* execution; a cyclic payload recorded as a marker rather than failing the
|
|
6
|
+
* flush. The native recorder's `v3-event-recorder.test.ts` is the sibling.
|
|
7
|
+
*
|
|
8
|
+
* The ordering arm is the reason the recorder exists in this shape: a delta
|
|
9
|
+
* that arrives between two stream events must read between them in the file,
|
|
10
|
+
* because "does `tool-call-completed` precede the stream's own completion" is
|
|
11
|
+
* a question only the arrival order can answer.
|
|
12
|
+
*/
|
|
13
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
14
|
+
import { mkdtemp, readFile, readdir } from "node:fs/promises";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { tmpdir } from "node:os";
|
|
17
|
+
import type { InteractionUpdate, SDKMessage } from "@cursor/sdk";
|
|
18
|
+
import { createCursorEventRecorder } from "../cursor-event-recorder.js";
|
|
19
|
+
|
|
20
|
+
/** A stream event carrying only what the recorder reads; the rest is payload. */
|
|
21
|
+
function streamEvent(type: string, extra: Record<string, unknown> = {}): SDKMessage {
|
|
22
|
+
return { type, agent_id: "agent-1", run_id: "run-1", ...extra } as unknown as SDKMessage;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function delta(type: string, extra: Record<string, unknown> = {}): InteractionUpdate {
|
|
26
|
+
return { type, ...extra } as unknown as InteractionUpdate;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface RecordedLine {
|
|
30
|
+
readonly seq: number;
|
|
31
|
+
readonly capturedAt: string;
|
|
32
|
+
readonly channel: "stream" | "delta";
|
|
33
|
+
readonly type: string;
|
|
34
|
+
readonly agent_id?: string;
|
|
35
|
+
readonly run_id?: string;
|
|
36
|
+
readonly event?: Record<string, unknown>;
|
|
37
|
+
readonly update?: Record<string, unknown>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function readLines(dir: string, executionId: string): Promise<RecordedLine[]> {
|
|
41
|
+
const content = await readFile(join(dir, `${executionId}.cursor-events.jsonl`), "utf-8");
|
|
42
|
+
return content
|
|
43
|
+
.split("\n")
|
|
44
|
+
.filter((line) => line.length > 0)
|
|
45
|
+
.map((line) => JSON.parse(line) as RecordedLine);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
describe("createCursorEventRecorder", () => {
|
|
49
|
+
it("returns undefined when no directory is named (recording off)", () => {
|
|
50
|
+
expect(createCursorEventRecorder("exec-1", undefined)).toBeUndefined();
|
|
51
|
+
expect(createCursorEventRecorder("exec-1", "")).toBeUndefined();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("returns a recorder with both channels and a flush when a directory is named", () => {
|
|
55
|
+
const recorder = createCursorEventRecorder("exec-1", "/tmp/unused");
|
|
56
|
+
expect(recorder).toBeDefined();
|
|
57
|
+
expect(recorder!.record).toBeInstanceOf(Function);
|
|
58
|
+
expect(recorder!.recordDelta).toBeInstanceOf(Function);
|
|
59
|
+
expect(recorder!.flush).toBeInstanceOf(Function);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe("CursorEventRecorder", () => {
|
|
64
|
+
let dir: string;
|
|
65
|
+
|
|
66
|
+
beforeEach(async () => {
|
|
67
|
+
dir = await mkdtemp(join(tmpdir(), "cursor-recorder-test-"));
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("flush writes nothing when nothing was recorded", async () => {
|
|
71
|
+
const recorder = createCursorEventRecorder("exec-empty", dir)!;
|
|
72
|
+
await recorder.flush();
|
|
73
|
+
expect(await readdir(dir)).toHaveLength(0);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("sequences both channels in ONE file in arrival order, each line naming its channel", async () => {
|
|
77
|
+
const recorder = createCursorEventRecorder("exec-order", dir)!;
|
|
78
|
+
|
|
79
|
+
recorder.record(streamEvent("tool_call", { subtype: "started", call_id: "c1" }));
|
|
80
|
+
recorder.recordDelta(delta("shell-output-delta", { event: { chunk: "hook probe\n" } }));
|
|
81
|
+
recorder.recordDelta(delta("tool-call-completed", { toolCall: { id: "c1" } }));
|
|
82
|
+
recorder.record(streamEvent("tool_call", { subtype: "completed", call_id: "c1" }));
|
|
83
|
+
recorder.record(streamEvent("result"));
|
|
84
|
+
|
|
85
|
+
await recorder.flush();
|
|
86
|
+
const lines = await readLines(dir, "exec-order");
|
|
87
|
+
|
|
88
|
+
expect(lines.map((l) => l.seq)).toEqual([0, 1, 2, 3, 4]);
|
|
89
|
+
expect(lines.map((l) => `${l.channel}:${l.type}`)).toEqual([
|
|
90
|
+
"stream:tool_call",
|
|
91
|
+
"delta:shell-output-delta",
|
|
92
|
+
"delta:tool-call-completed",
|
|
93
|
+
"stream:tool_call",
|
|
94
|
+
"stream:result",
|
|
95
|
+
]);
|
|
96
|
+
for (const line of lines) expect(line.capturedAt).toBeTruthy();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("a stream line carries the event's agent and run ids and the whole event; a delta line the whole update", async () => {
|
|
100
|
+
const recorder = createCursorEventRecorder("exec-shape", dir)!;
|
|
101
|
+
|
|
102
|
+
recorder.record(streamEvent("assistant", { content: "hi" }));
|
|
103
|
+
recorder.recordDelta(delta("turn-ended", { usage: { inputTokens: 12 } }));
|
|
104
|
+
|
|
105
|
+
await recorder.flush();
|
|
106
|
+
const [stream, deltaLine] = await readLines(dir, "exec-shape");
|
|
107
|
+
|
|
108
|
+
expect(stream!.agent_id).toBe("agent-1");
|
|
109
|
+
expect(stream!.run_id).toBe("run-1");
|
|
110
|
+
expect(stream!.event).toMatchObject({ type: "assistant", content: "hi" });
|
|
111
|
+
expect(stream!.update).toBeUndefined();
|
|
112
|
+
|
|
113
|
+
expect(deltaLine!.update).toEqual({ type: "turn-ended", usage: { inputTokens: 12 } });
|
|
114
|
+
expect(deltaLine!.event).toBeUndefined();
|
|
115
|
+
expect(deltaLine!.agent_id).toBeUndefined();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("names the file by execution id and creates the directory if it does not exist", async () => {
|
|
119
|
+
const nested = join(dir, "nested", "deep");
|
|
120
|
+
const recorder = createCursorEventRecorder("exec-mkdir", nested)!;
|
|
121
|
+
|
|
122
|
+
recorder.record(streamEvent("system"));
|
|
123
|
+
await recorder.flush();
|
|
124
|
+
|
|
125
|
+
expect(await readdir(nested)).toEqual(["exec-mkdir.cursor-events.jsonl"]);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("records a cyclic payload as a serialization marker instead of failing the flush", async () => {
|
|
129
|
+
const recorder = createCursorEventRecorder("exec-cyclic", dir)!;
|
|
130
|
+
|
|
131
|
+
const cyclic: Record<string, unknown> = { type: "custom", a: 1 };
|
|
132
|
+
cyclic.self = cyclic;
|
|
133
|
+
recorder.record(cyclic as unknown as SDKMessage);
|
|
134
|
+
|
|
135
|
+
await recorder.flush();
|
|
136
|
+
const [line] = await readLines(dir, "exec-cyclic");
|
|
137
|
+
|
|
138
|
+
expect(line!.type).toBe("custom");
|
|
139
|
+
expect(line!.event).toMatchObject({ _serializationError: true });
|
|
140
|
+
expect((line!.event as { keys: string[] }).keys).toContain("a");
|
|
141
|
+
});
|
|
142
|
+
});
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Live probe: which of the SDK's calls a `globalThis.fetch` interceptor can
|
|
3
|
+
* see. A fetch wrapper that notes any call to a cursor.sh / cursor.com URL is
|
|
4
|
+
* installed, then `Agent.create()` runs (local mode, no model named).
|
|
3
5
|
*
|
|
4
|
-
*
|
|
5
|
-
* to
|
|
6
|
+
* What the one arm proves: `Agent.create()` completes WITHOUT a global-fetch
|
|
7
|
+
* call to a Cursor URL — its transport is connect-node over Node's HTTP/2, so
|
|
8
|
+
* a fetch-level interceptor alone cannot rewrite it. That is why the adapter
|
|
9
|
+
* installs BOTH interceptors in proxy mode (`fetch-interceptor.ts` and
|
|
10
|
+
* `http2-interceptor.ts`). Measured true at SDK 1.0.31 on 2026-09-16 (#1097's
|
|
11
|
+
* live run, 1/1).
|
|
6
12
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
13
|
+
* What it does NOT prove: that the fetch interceptor is useless. A reading of
|
|
14
|
+
* the 1.0.31 bundle the same day found the SDK's cloud-api client and its
|
|
15
|
+
* token exchange on global `fetch`, on paths this arm never exercises; the
|
|
16
|
+
* fetch interceptor exists for those.
|
|
17
|
+
*
|
|
18
|
+
* Skipped without `CURSOR_API_KEY`; the suite never runs it. Run it by hand:
|
|
19
|
+
* CURSOR_API_KEY=<key> npx vitest run src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts
|
|
9
20
|
*/
|
|
10
21
|
|
|
11
22
|
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
@@ -39,7 +50,7 @@ describeWithCursorKey("Fetch Interceptor vs Connect-Node Transport", () => {
|
|
|
39
50
|
globalThis.fetch = originalFetch;
|
|
40
51
|
});
|
|
41
52
|
|
|
42
|
-
it("Agent.create()
|
|
53
|
+
it("Agent.create() completes without a globalThis.fetch call to a Cursor URL", async () => {
|
|
43
54
|
const { Agent } = await import("@cursor/sdk");
|
|
44
55
|
const { SqliteLocalAgentStore } = await import("@cursor/sdk/sqlite");
|
|
45
56
|
|
|
@@ -58,8 +69,8 @@ describeWithCursorKey("Fetch Interceptor vs Connect-Node Transport", () => {
|
|
|
58
69
|
expect(agent.agentId).toBeTruthy();
|
|
59
70
|
console.log(`Agent created: ${agent.agentId}, interceptCalled=${interceptCalled}`);
|
|
60
71
|
|
|
61
|
-
//
|
|
62
|
-
//
|
|
72
|
+
// The create path is connect-node over Node's HTTP/2, not globalThis.fetch;
|
|
73
|
+
// see the header for what this does and does not say about proxy mode.
|
|
63
74
|
expect(interceptCalled).toBe(false);
|
|
64
75
|
}, 30_000);
|
|
65
76
|
});
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Live smoke: the Cursor SDK authenticates and completes a round trip on a
|
|
3
|
+
* real member key. Three arms, each isolating one fact:
|
|
4
|
+
* 1. `Agent.create()` with a model named succeeds — the key is valid;
|
|
5
|
+
* 2. `agent.send()` runs to a completed result — the agent executes and the
|
|
6
|
+
* transport completes the round trip;
|
|
7
|
+
* 3. `Agent.create()` with no model named succeeds — the catalog default
|
|
8
|
+
* resolves.
|
|
3
9
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 3. The connect-node transport works end-to-end
|
|
8
|
-
*
|
|
9
|
-
* Run with: CURSOR_API_KEY=<key> npx tsx --test this-file.ts
|
|
10
|
-
* Or via the test script: npm run test:cursor-auth
|
|
10
|
+
* Skipped without `CURSOR_API_KEY`; the suite never runs it. Run it by hand:
|
|
11
|
+
* CURSOR_API_KEY=<key> npx vitest run src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts
|
|
12
|
+
* Last run green 3/3 on 2026-09-16 at SDK 1.0.31 (#1097's live run).
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
15
|
import { describe, it, expect } from "vitest";
|