@stigmer/runner 3.15.0 → 3.15.2-dev.20260913223433
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 -4
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/execution-record-fixture.d.ts +14 -0
- package/dist/__test-utils__/execution-record-fixture.js +4 -0
- package/dist/__test-utils__/execution-record-fixture.js.map +1 -1
- package/dist/__test-utils__/file-review-projection.d.ts +40 -0
- package/dist/__test-utils__/file-review-projection.js +136 -0
- package/dist/__test-utils__/file-review-projection.js.map +1 -0
- package/dist/__test-utils__/harness-contract/types.d.ts +23 -1
- package/dist/__test-utils__/harness-contract/types.js +15 -0
- package/dist/__test-utils__/harness-contract/types.js.map +1 -1
- package/dist/__test-utils__/hermetic-activity.d.ts +44 -12
- package/dist/__test-utils__/hermetic-activity.js +52 -14
- package/dist/__test-utils__/hermetic-activity.js.map +1 -1
- package/dist/__test-utils__/model-registry-fixture.d.ts +32 -7
- package/dist/__test-utils__/model-registry-fixture.js +31 -7
- package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
- package/dist/__test-utils__/turn-input-fixture.d.ts +1 -1
- package/dist/__test-utils__/turn-input-fixture.js +1 -1
- package/dist/__test-utils__/turn-input-fixture.js.map +1 -1
- package/dist/activities/call-agent.js +2 -2
- package/dist/activities/call-agent.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +45 -3
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +0 -9
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +2 -41
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/adapter.d.ts +7 -5
- package/dist/activities/execute-cursor/adapter.js +7 -5
- package/dist/activities/execute-cursor/adapter.js.map +1 -1
- package/dist/activities/execute-cursor/approval-policy.d.ts +5 -2
- package/dist/activities/execute-cursor/approval-policy.js +5 -2
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +16 -8
- package/dist/activities/execute-cursor/approval-state.js +6 -3
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/cas-observations.d.ts +14 -2
- package/dist/activities/execute-cursor/cas-observations.js +19 -2
- package/dist/activities/execute-cursor/cas-observations.js.map +1 -1
- package/dist/activities/execute-cursor/cursor-capabilities.d.ts +8 -4
- package/dist/activities/execute-cursor/cursor-capabilities.js +21 -4
- package/dist/activities/execute-cursor/cursor-capabilities.js.map +1 -1
- package/dist/activities/execute-cursor/message-translator.d.ts +12 -20
- package/dist/activities/execute-cursor/message-translator.js +19 -32
- package/dist/activities/execute-cursor/message-translator.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +48 -58
- package/dist/activities/execute-cursor/prompt-builder.js +76 -95
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/turn-boundary.d.ts +27 -55
- package/dist/activities/execute-cursor/turn-boundary.js +30 -90
- 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 +37 -49
- package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
- package/dist/activities/execute-cursor/turn-setup.d.ts +16 -24
- package/dist/activities/execute-cursor/turn-setup.js +29 -59
- package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
- package/dist/activities/execute-cursor/turn-stream.d.ts +3 -8
- package/dist/activities/execute-cursor/turn-stream.js +9 -22
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-cursor/turn.js +5 -1
- package/dist/activities/execute-cursor/turn.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +93 -0
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +348 -0
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +170 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +225 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.d.ts +24 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +41 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +54 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +72 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +187 -23
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +238 -27
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
- package/dist/activities/execute-deep-agent/adapter.d.ts +41 -0
- package/dist/activities/execute-deep-agent/adapter.js +78 -0
- package/dist/activities/execute-deep-agent/adapter.js.map +1 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.d.ts +8 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js +9 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js.map +1 -1
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +31 -0
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +40 -0
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js.map +1 -0
- package/dist/activities/execute-deep-agent/execution-state.d.ts +4 -11
- package/dist/activities/execute-deep-agent/execution-state.js +4 -12
- package/dist/activities/execute-deep-agent/execution-state.js.map +1 -1
- package/dist/activities/execute-deep-agent/hitl.d.ts +49 -47
- package/dist/activities/execute-deep-agent/hitl.js +77 -103
- package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +51 -23
- package/dist/activities/execute-deep-agent/prompt-builder.js +115 -76
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +18 -32
- package/dist/activities/execute-deep-agent/status-builder-shared.js +10 -65
- package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +10 -8
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +12 -14
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +36 -13
- package/dist/activities/execute-deep-agent/subagent-tracker.js +76 -39
- package/dist/activities/execute-deep-agent/subagent-tracker.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +25 -28
- package/dist/activities/execute-deep-agent/subagent-transformer.js +29 -82
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +3 -2
- package/dist/activities/execute-deep-agent/subagent-wiring.js +2 -2
- package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-settle.d.ts +42 -0
- package/dist/activities/execute-deep-agent/turn-settle.js +146 -0
- package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-setup.d.ts +212 -0
- package/dist/activities/execute-deep-agent/turn-setup.js +430 -0
- package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-stream.d.ts +97 -0
- package/dist/activities/execute-deep-agent/turn-stream.js +242 -0
- package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn.d.ts +42 -0
- package/dist/activities/execute-deep-agent/turn.js +116 -0
- package/dist/activities/execute-deep-agent/turn.js.map +1 -0
- package/dist/activities/execute-deep-agent/v3-event-recorder.d.ts +6 -5
- package/dist/activities/execute-deep-agent/v3-event-recorder.js +6 -5
- package/dist/activities/execute-deep-agent/v3-event-recorder.js.map +1 -1
- package/dist/activities/execute-deep-agent/v3-events.d.ts +1 -1
- package/dist/activities/execute-deep-agent/v3-events.js +1 -1
- package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +60 -17
- package/dist/activities/execute-deep-agent/v3-status-builder.js +72 -57
- package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
- package/dist/harness/approval-decisions.d.ts +61 -0
- package/dist/harness/approval-decisions.js +102 -0
- package/dist/harness/approval-decisions.js.map +1 -0
- package/dist/harness/capabilities.d.ts +16 -5
- package/dist/harness/capabilities.js +9 -0
- package/dist/harness/capabilities.js.map +1 -1
- package/dist/harness/capture.d.ts +144 -0
- package/dist/harness/capture.js +219 -0
- package/dist/harness/capture.js.map +1 -0
- package/dist/harness/persist-chokepoint.d.ts +19 -4
- package/dist/harness/persist-chokepoint.js +17 -4
- package/dist/harness/persist-chokepoint.js.map +1 -1
- package/dist/harness/run-turn.js +115 -29
- package/dist/harness/run-turn.js.map +1 -1
- package/dist/harness/terminal-table.d.ts +40 -11
- package/dist/harness/terminal-table.js +58 -19
- package/dist/harness/terminal-table.js.map +1 -1
- package/dist/harness/turn-context.d.ts +141 -76
- package/dist/harness/turn-context.js +194 -99
- package/dist/harness/turn-context.js.map +1 -1
- package/dist/harness/types.d.ts +65 -12
- package/dist/harness/types.js +8 -2
- package/dist/harness/types.js.map +1 -1
- package/dist/harness-adapters.d.ts +12 -8
- package/dist/harness-adapters.js +17 -9
- package/dist/harness-adapters.js.map +1 -1
- package/dist/middleware/approval-gate.d.ts +1 -1
- package/dist/middleware/approval-gate.js +1 -1
- package/dist/middleware/approval-gate.js.map +1 -1
- package/dist/middleware/cost-advisory.d.ts +39 -0
- package/dist/middleware/{cost-cap.js → cost-advisory.js} +37 -55
- package/dist/middleware/cost-advisory.js.map +1 -0
- package/dist/middleware/index.d.ts +23 -12
- package/dist/middleware/index.js +26 -18
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/types.d.ts +3 -2
- package/dist/runner-manager.js +1 -5
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.js +1 -5
- package/dist/runner.js.map +1 -1
- package/dist/shared/attachment-resolver.d.ts +41 -18
- package/dist/shared/attachment-resolver.js +178 -46
- package/dist/shared/attachment-resolver.js.map +1 -1
- package/dist/shared/attachment-zip.d.ts +85 -0
- package/dist/shared/attachment-zip.js +185 -0
- package/dist/shared/attachment-zip.js.map +1 -0
- package/dist/shared/connect-backfill.js +5 -4
- package/dist/shared/connect-backfill.js.map +1 -1
- package/dist/shared/cost-guard.d.ts +3 -3
- package/dist/shared/cost-guard.js +3 -3
- package/dist/shared/execution-status-writer.d.ts +5 -5
- package/dist/shared/execution-status-writer.js +5 -5
- package/dist/shared/extract-structured-output.d.ts +8 -7
- package/dist/shared/extract-structured-output.js +8 -7
- package/dist/shared/extract-structured-output.js.map +1 -1
- package/dist/shared/filereview/cas-progress.d.ts +1 -18
- package/dist/shared/filereview/cas-progress.js +4 -0
- package/dist/shared/filereview/cas-progress.js.map +1 -1
- package/dist/shared/filereview/cas-touched.d.ts +56 -0
- package/dist/shared/filereview/cas-touched.js +63 -0
- package/dist/shared/filereview/cas-touched.js.map +1 -0
- package/dist/shared/filereview/index.d.ts +2 -1
- package/dist/shared/filereview/index.js +2 -1
- package/dist/shared/filereview/index.js.map +1 -1
- package/dist/shared/mcp-resolver.d.ts +4 -5
- package/dist/shared/mcp-resolver.js +4 -5
- package/dist/shared/mcp-resolver.js.map +1 -1
- package/dist/shared/persist-decision.d.ts +3 -4
- package/dist/shared/persist-decision.js +3 -4
- package/dist/shared/persist-decision.js.map +1 -1
- package/dist/shared/plan-mode-permissions.d.ts +2 -2
- package/dist/shared/plan-mode-permissions.js +2 -2
- package/dist/shared/plan-mode-prompt.d.ts +1 -1
- package/dist/shared/plan-mode-prompt.js +1 -1
- package/dist/shared/prompt-sections.d.ts +163 -0
- package/dist/shared/prompt-sections.js +164 -0
- package/dist/shared/prompt-sections.js.map +1 -0
- package/dist/shared/skill-resolver.d.ts +4 -2
- package/dist/shared/skill-resolver.js +4 -2
- package/dist/shared/skill-resolver.js.map +1 -1
- package/dist/shared/tool-rounds.d.ts +32 -0
- package/dist/shared/tool-rounds.js +43 -0
- package/dist/shared/tool-rounds.js.map +1 -1
- package/dist/shared/tool-row.d.ts +34 -0
- package/dist/shared/tool-row.js +52 -0
- package/dist/shared/tool-row.js.map +1 -1
- package/dist/shared/workspace/session-provision.d.ts +3 -3
- package/dist/shared/workspace/session-provision.js +3 -3
- package/dist/shared/workspace/stigmer-link.d.ts +3 -3
- package/dist/shared/workspace/stigmer-link.js +3 -3
- package/dist/shared/workspace/writeback-coordinator.d.ts +15 -22
- package/dist/shared/workspace/writeback-coordinator.js +16 -53
- package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +1 -1
- package/package.json +4 -4
- package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +1 -0
- package/src/__test-utils__/execution-record-fixture.ts +18 -2
- package/src/__test-utils__/file-review-projection.ts +156 -0
- package/src/__test-utils__/git-workspace-fixture.ts +58 -0
- package/src/__test-utils__/harness-boot-order-child.ts +7 -2
- package/src/__test-utils__/harness-contract/contract.ts +33 -20
- package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
- package/src/__test-utils__/harness-contract/runtime-contract.ts +328 -10
- package/src/__test-utils__/harness-contract/scripted-adapter.ts +38 -6
- package/src/__test-utils__/harness-contract/types.ts +27 -3
- package/src/__test-utils__/hermetic-activity.ts +52 -14
- package/src/__test-utils__/model-registry-fixture.ts +32 -7
- package/src/__test-utils__/module-specifiers.ts +24 -0
- package/src/__test-utils__/turn-input-fixture.ts +2 -2
- package/src/__tests__/harness-boot-order.test.ts +9 -2
- package/src/activities/call-agent.ts +2 -2
- package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +47 -3
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +2 -48
- package/src/activities/execute-cursor/__tests__/approval-decisions-agree.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +6 -1
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +52 -27
- package/src/activities/execute-cursor/__tests__/cas-observations.test.ts +25 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.everything.prompt.md +166 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.plan-mode.prompt.md +186 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.recovery.prompt.md +191 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.reinvocation.prompt.md +13 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.prefixed.prompt.md +32 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.raw.prompt.md +1 -0
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-error-at-create.status.json +4 -0
- package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +24 -4
- package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +6 -5
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +9 -0
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +11 -8
- package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +229 -0
- package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +3 -3
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +2 -2
- package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +78 -234
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +1 -26
- package/src/activities/execute-cursor/adapter.ts +7 -5
- package/src/activities/execute-cursor/approval-policy.ts +5 -2
- package/src/activities/execute-cursor/approval-state.ts +16 -8
- package/src/activities/execute-cursor/cas-observations.ts +20 -2
- package/src/activities/execute-cursor/cursor-capabilities.ts +24 -5
- package/src/activities/execute-cursor/message-translator.ts +29 -41
- package/src/activities/execute-cursor/prompt-builder.ts +99 -157
- package/src/activities/execute-cursor/turn-boundary.ts +34 -140
- package/src/activities/execute-cursor/turn-settle.ts +37 -51
- package/src/activities/execute-cursor/turn-setup.ts +30 -70
- package/src/activities/execute-cursor/turn-stream.ts +8 -31
- package/src/activities/execute-cursor/turn.ts +5 -1
- package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +391 -0
- package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +313 -0
- package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +48 -0
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +85 -0
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +383 -36
- package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +76 -0
- package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +47 -0
- package/src/activities/execute-deep-agent/__tests__/adapter.test.ts +80 -0
- package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -2
- package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -3
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.build-from-plan.prompt.md +172 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.everything.prompt.md +167 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.minimal.prompt.md +36 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.plan-mode.prompt.md +178 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.skills-below-threshold.prompt.md +158 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +210 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +74 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +104 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +78 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +138 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +68 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +154 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +116 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +69 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +67 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/plain-turn.status.json +47 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +68 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +280 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +77 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/resolution-error.status.json +18 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +99 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +109 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +76 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.text-fallback.status.json +51 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tier2.status.json +51 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tool-strategy.status.json +56 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +90 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +70 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +71 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +144 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +184 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +203 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +170 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +175 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +206 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +142 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +126 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +139 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +122 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +236 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +161 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +157 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +152 -0
- package/src/activities/execute-deep-agent/__tests__/hitl.test.ts +50 -122
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +8 -6
- package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +35 -35
- package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +247 -0
- package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +329 -0
- package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +1 -20
- package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +78 -0
- package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/subagent-plan-mode-permissions.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/subagent-tracker.test.ts +57 -31
- package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +19 -79
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +15 -15
- package/src/activities/execute-deep-agent/__tests__/summarization-verification.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +391 -0
- package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +343 -38
- package/src/activities/execute-deep-agent/__tests__/vision-input.test.ts +5 -5
- package/src/activities/execute-deep-agent/adapter.ts +94 -0
- package/src/activities/execute-deep-agent/cas-capture-observer.ts +11 -0
- package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +43 -0
- package/src/activities/execute-deep-agent/execution-state.ts +4 -13
- package/src/activities/execute-deep-agent/hitl.ts +100 -123
- package/src/activities/execute-deep-agent/prompt-builder.ts +141 -115
- package/src/activities/execute-deep-agent/status-builder-shared.ts +21 -84
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +13 -19
- package/src/activities/execute-deep-agent/subagent-tracker.ts +77 -42
- package/src/activities/execute-deep-agent/subagent-transformer.ts +46 -105
- package/src/activities/execute-deep-agent/subagent-wiring.ts +5 -4
- package/src/activities/execute-deep-agent/turn-settle.ts +164 -0
- package/src/activities/execute-deep-agent/turn-setup.ts +541 -0
- package/src/activities/execute-deep-agent/turn-stream.ts +313 -0
- package/src/activities/execute-deep-agent/turn.ts +131 -0
- package/src/activities/execute-deep-agent/v3-event-recorder.ts +6 -5
- package/src/activities/execute-deep-agent/v3-events.ts +1 -1
- package/src/activities/execute-deep-agent/v3-status-builder.ts +84 -63
- package/src/harness/__tests__/approval-decisions.test.ts +116 -0
- package/src/harness/__tests__/capture.test.ts +268 -0
- package/src/harness/__tests__/mount-skills.test.ts +169 -0
- package/src/harness/__tests__/persist-chokepoint.test.ts +38 -2
- package/src/harness/__tests__/run-turn-deterministic.test.ts +94 -0
- package/src/harness/__tests__/run-turn.test.ts +39 -23
- package/src/harness/__tests__/turn-attachments-vision.test.ts +80 -0
- package/src/harness/__tests__/turn-context.test.ts +73 -26
- package/src/harness/approval-decisions.ts +104 -0
- package/src/harness/capabilities.ts +16 -5
- package/src/harness/capture.ts +301 -0
- package/src/harness/persist-chokepoint.ts +24 -4
- package/src/harness/run-turn.ts +120 -29
- package/src/harness/terminal-table.ts +61 -20
- package/src/harness/turn-context.ts +208 -111
- package/src/harness/types.ts +66 -12
- package/src/harness-adapters.ts +17 -9
- package/src/middleware/__tests__/approval-gate.test.ts +1 -1
- package/src/middleware/__tests__/cost-advisory.test.ts +113 -0
- package/src/middleware/approval-gate.ts +2 -2
- package/src/middleware/{cost-cap.ts → cost-advisory.ts} +40 -70
- package/src/middleware/index.ts +29 -29
- package/src/middleware/types.ts +3 -2
- package/src/runner-manager.ts +0 -8
- package/src/runner.ts +0 -8
- package/src/shared/__tests__/attachment-naming.test.ts +6 -19
- package/src/shared/__tests__/attachment-resolver.test.ts +158 -8
- package/src/shared/__tests__/attachment-zip.test.ts +236 -0
- package/src/shared/__tests__/bedrock-adapter.test.ts +1 -1
- package/src/shared/__tests__/blueprint-resolver.test.ts +43 -0
- package/src/shared/__tests__/cost-guard.test.ts +3 -3
- package/src/shared/__tests__/prompt-sections.test.ts +167 -0
- package/src/shared/__tests__/secret-leak-scan.test.ts +2 -2
- package/src/{activities/execute-deep-agent → shared}/__tests__/stamp-flowed-rows.test.ts +33 -10
- package/src/shared/__tests__/vertex-adapter.test.ts +1 -1
- package/src/shared/attachment-resolver.ts +218 -55
- package/src/shared/attachment-zip.ts +281 -0
- package/src/shared/connect-backfill.ts +9 -11
- package/src/shared/cost-guard.ts +3 -3
- package/src/shared/execution-status-writer.ts +5 -5
- package/src/shared/extract-structured-output.ts +8 -7
- package/src/shared/filereview/__tests__/capture.test.ts +86 -4
- package/src/shared/filereview/__tests__/cas-progress.test.ts +2 -1
- package/src/shared/filereview/cas-progress.ts +5 -19
- package/src/shared/filereview/cas-touched.ts +89 -0
- package/src/shared/filereview/index.ts +4 -2
- package/src/shared/mcp-resolver.ts +4 -5
- package/src/shared/persist-decision.ts +3 -4
- package/src/shared/plan-mode-permissions.ts +2 -2
- package/src/shared/plan-mode-prompt.ts +1 -1
- package/src/shared/prompt-sections.ts +256 -0
- package/src/shared/skill-resolver.ts +4 -2
- package/src/shared/tool-rounds.ts +48 -0
- package/src/shared/tool-row.ts +61 -0
- package/src/shared/workspace/__tests__/stigmer-link.test.ts +7 -22
- package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +20 -61
- package/src/shared/workspace/session-provision.ts +3 -3
- package/src/shared/workspace/stigmer-link.ts +3 -3
- package/src/shared/workspace/writeback-coordinator.ts +16 -64
- package/src/tools/index.ts +1 -1
- package/dist/activities/execute-cursor/capture-flow.d.ts +0 -142
- package/dist/activities/execute-cursor/capture-flow.js +0 -285
- package/dist/activities/execute-cursor/capture-flow.js.map +0 -1
- package/dist/activities/execute-cursor/command-provenance.d.ts +0 -48
- package/dist/activities/execute-cursor/command-provenance.js +0 -38
- package/dist/activities/execute-cursor/command-provenance.js.map +0 -1
- package/dist/activities/execute-deep-agent/attachment-injector.d.ts +0 -134
- package/dist/activities/execute-deep-agent/attachment-injector.js +0 -386
- package/dist/activities/execute-deep-agent/attachment-injector.js.map +0 -1
- package/dist/activities/execute-deep-agent/command-provenance.d.ts +0 -61
- package/dist/activities/execute-deep-agent/command-provenance.js +0 -72
- package/dist/activities/execute-deep-agent/command-provenance.js.map +0 -1
- package/dist/activities/execute-deep-agent/environment.d.ts +0 -24
- package/dist/activities/execute-deep-agent/environment.js +0 -58
- package/dist/activities/execute-deep-agent/environment.js.map +0 -1
- package/dist/activities/execute-deep-agent/event-recorder.d.ts +0 -21
- package/dist/activities/execute-deep-agent/event-recorder.js +0 -67
- package/dist/activities/execute-deep-agent/event-recorder.js.map +0 -1
- package/dist/activities/execute-deep-agent/index.d.ts +0 -15
- package/dist/activities/execute-deep-agent/index.js +0 -918
- package/dist/activities/execute-deep-agent/index.js.map +0 -1
- package/dist/activities/execute-deep-agent/mcp-gate.d.ts +0 -28
- package/dist/activities/execute-deep-agent/mcp-gate.js +0 -22
- package/dist/activities/execute-deep-agent/mcp-gate.js.map +0 -1
- package/dist/activities/execute-deep-agent/post-stream.d.ts +0 -23
- package/dist/activities/execute-deep-agent/post-stream.js +0 -71
- package/dist/activities/execute-deep-agent/post-stream.js.map +0 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +0 -136
- package/dist/activities/execute-deep-agent/setup.js +0 -767
- package/dist/activities/execute-deep-agent/setup.js.map +0 -1
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.d.ts +0 -36
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js +0 -56
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js.map +0 -1
- package/dist/activities/execute-deep-agent/status-builder.d.ts +0 -93
- package/dist/activities/execute-deep-agent/status-builder.js +0 -365
- package/dist/activities/execute-deep-agent/status-builder.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming-terminal.d.ts +0 -21
- package/dist/activities/execute-deep-agent/streaming-terminal.js +0 -80
- package/dist/activities/execute-deep-agent/streaming-terminal.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming-v3.d.ts +0 -13
- package/dist/activities/execute-deep-agent/streaming-v3.js +0 -174
- package/dist/activities/execute-deep-agent/streaming-v3.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming.d.ts +0 -81
- package/dist/activities/execute-deep-agent/streaming.js +0 -160
- package/dist/activities/execute-deep-agent/streaming.js.map +0 -1
- package/dist/middleware/cost-cap.d.ts +0 -22
- package/dist/middleware/cost-cap.js.map +0 -1
- package/dist/middleware/graceful-stop.d.ts +0 -17
- package/dist/middleware/graceful-stop.js +0 -63
- package/dist/middleware/graceful-stop.js.map +0 -1
- package/dist/shared/skill-writer.d.ts +0 -75
- package/dist/shared/skill-writer.js +0 -207
- package/dist/shared/skill-writer.js.map +0 -1
- package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +0 -1032
- package/src/activities/execute-cursor/__tests__/command-provenance.test.ts +0 -240
- package/src/activities/execute-cursor/__tests__/progress-substrate.test.ts +0 -169
- package/src/activities/execute-cursor/capture-flow.ts +0 -379
- package/src/activities/execute-cursor/command-provenance.ts +0 -73
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +0 -1161
- package/src/activities/execute-deep-agent/__tests__/command-provenance.test.ts +0 -252
- package/src/activities/execute-deep-agent/__tests__/environment.test.ts +0 -108
- package/src/activities/execute-deep-agent/__tests__/event-recorder.test.ts +0 -150
- package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +0 -226
- package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +0 -318
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +0 -351
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +0 -293
- package/src/activities/execute-deep-agent/__tests__/index.test.ts +0 -99
- package/src/activities/execute-deep-agent/__tests__/mcp-gate.test.ts +0 -44
- package/src/activities/execute-deep-agent/__tests__/post-stream.test.ts +0 -112
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +0 -358
- package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +0 -1933
- package/src/activities/execute-deep-agent/__tests__/streaming-terminal.test.ts +0 -40
- package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +0 -597
- package/src/activities/execute-deep-agent/__tests__/streaming.test.ts +0 -508
- package/src/activities/execute-deep-agent/attachment-injector.ts +0 -627
- package/src/activities/execute-deep-agent/command-provenance.ts +0 -102
- package/src/activities/execute-deep-agent/environment.ts +0 -76
- package/src/activities/execute-deep-agent/event-recorder.ts +0 -95
- package/src/activities/execute-deep-agent/index.ts +0 -1072
- package/src/activities/execute-deep-agent/mcp-gate.ts +0 -37
- package/src/activities/execute-deep-agent/post-stream.ts +0 -109
- package/src/activities/execute-deep-agent/setup.ts +0 -1081
- package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +0 -64
- package/src/activities/execute-deep-agent/status-builder.ts +0 -481
- package/src/activities/execute-deep-agent/streaming-terminal.ts +0 -106
- package/src/activities/execute-deep-agent/streaming-v3.ts +0 -277
- package/src/activities/execute-deep-agent/streaming.ts +0 -313
- package/src/middleware/__tests__/cost-cap.test.ts +0 -192
- package/src/middleware/__tests__/graceful-stop.test.ts +0 -105
- package/src/middleware/graceful-stop.ts +0 -86
- package/src/shared/__tests__/skill-writer.test.ts +0 -372
- package/src/shared/skill-writer.ts +0 -266
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
* ResolvedMcpServer format.
|
|
4
4
|
*
|
|
5
5
|
* THE single resolver for both harnesses (oss#387 retired the Cursor
|
|
6
|
-
* harness's near-duplicate): the
|
|
7
|
-
* (
|
|
8
|
-
* (execute-cursor/index.ts), the connect backfill
|
|
6
|
+
* harness's near-duplicate): the turn runtime's MCP phase
|
|
7
|
+
* (harness/turn-context.ts, serving both adapters), the connect backfill
|
|
9
8
|
* (shared/connect-backfill.ts), and the discovery activity
|
|
10
9
|
* (activities/discover-mcp-server.ts, via mcpServerToResolved) all consume
|
|
11
10
|
* it. Each harness maps the result into its SDK format at the last hop:
|
|
@@ -217,8 +216,8 @@ export function mcpServerToResolved(
|
|
|
217
216
|
* - If both reference the same slug, session-level takes precedence —
|
|
218
217
|
* the WHOLE usage, including enabled_tools and approval overrides
|
|
219
218
|
*
|
|
220
|
-
* Shared by both harnesses (blueprint-resolver.ts
|
|
221
|
-
*
|
|
219
|
+
* Shared by both harnesses (through blueprint-resolver.ts, the turn
|
|
220
|
+
* runtime's blueprint phase) so a duplicate slug
|
|
222
221
|
* resolves identically everywhere: exactly one usage per server, whose
|
|
223
222
|
* enabled_tools is the one the enforcement filter honors.
|
|
224
223
|
*/
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Streaming persist decision for a harness turn.
|
|
3
3
|
*
|
|
4
|
-
* Harness-agnostic
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Mirrors the native deep-agent harness (execute-deep-agent/streaming.ts):
|
|
4
|
+
* Harness-agnostic, and both adapters' stream loops read it
|
|
5
|
+
* (`execute-cursor/turn-stream.ts`, `execute-deep-agent/turn-stream.ts`; the
|
|
6
|
+
* native orchestrator's own copy of the rule retired with it at S3 M2b):
|
|
8
7
|
* `shouldPersist = forceFlush || scheduler.shouldSendUpdate(eventCount)`.
|
|
9
8
|
* Both harnesses thus share one cadence model — discrete state changes flush
|
|
10
9
|
* immediately, high-frequency token deltas ride a bounded time cadence.
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
* (shared/workspace/stigmer-link.ts), an in-root path string in either
|
|
23
23
|
* dialect.
|
|
24
24
|
*
|
|
25
|
-
* Applied in execute-deep-agent/setup.ts to the parent graph AND threaded
|
|
25
|
+
* Applied in execute-deep-agent/turn-setup.ts to the parent graph AND threaded
|
|
26
26
|
* into every compiled sub-agent graph: deepagents' parent-permission
|
|
27
27
|
* inheritance covers only spec-style sub-agents, and ours are pre-built
|
|
28
28
|
* CompiledSubAgents, so each sub-agent graph must carry the rules itself
|
|
29
29
|
* (issue #255). Kept as its own side-effect-free module so tests can pin the
|
|
30
|
-
* production rules without dragging in
|
|
30
|
+
* production rules without dragging in the engine build's import graph.
|
|
31
31
|
*
|
|
32
32
|
* Invariant: never combine these rules with a shell-capable (sandbox)
|
|
33
33
|
* backend — deepagents rejects that pairing at graph construction (see the
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* is house style; the words are shared.
|
|
17
17
|
*
|
|
18
18
|
* Enforcement is separate from instruction: the native harness ALSO denies
|
|
19
|
-
* filesystem writes at the tool layer (see execute-deep-agent/setup.ts), so
|
|
19
|
+
* filesystem writes at the tool layer (see execute-deep-agent/turn-setup.ts), so
|
|
20
20
|
* for it this directive is guidance toward a well-formed plan, not the
|
|
21
21
|
* enforcement mechanism. The Cursor harness has no tool-level lever (the
|
|
22
22
|
* Cursor SDK exposes no mode parameter), so there this directive is the
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The prompt glue both harnesses share: WHICH sections, in WHAT order, with
|
|
3
|
+
* WHICH lines — never the framing, never the placement.
|
|
4
|
+
*
|
|
5
|
+
* The doctrine is `plan-mode-prompt.ts`'s: "the framing is house style; the
|
|
6
|
+
* words are shared." Every section BODY already has one home
|
|
7
|
+
* (`sender-identity.ts`, `declared-preferences.ts`, `recalled-memories.ts`,
|
|
8
|
+
* `session-context.ts`, `context-bridge.ts`, `attachment-vision.ts`,
|
|
9
|
+
* `attachment-download-urls.ts`). What the two prompt builders duplicated
|
|
10
|
+
* until S3 M5 (Q-S3-10, Q-M2b-8) was the glue around those bodies: the order
|
|
11
|
+
* the five standing sections read in, with the same doctrine comments written
|
|
12
|
+
* twice; the input-files bullet and disclosure lines; which skills a prompt
|
|
13
|
+
* highlights when there are many. This module is that glue, written once.
|
|
14
|
+
*
|
|
15
|
+
* What stays with each harness, on purpose:
|
|
16
|
+
* - Framing and placement. The native harness renders `## Heading` sections
|
|
17
|
+
* into a system prompt rebuilt on every turn; the Cursor harness renders
|
|
18
|
+
* `<xml_tag>` sections into the FIRST user message of a session
|
|
19
|
+
* (`capabilities.systemPrompt` is the declared reason). Each builder maps a
|
|
20
|
+
* section `kind` to its own label (`Record<StandingSectionKind, string>`,
|
|
21
|
+
* exhaustive by the compiler) and wraps the body itself. This module never
|
|
22
|
+
* learns a heading or a tag.
|
|
23
|
+
* - Words that quote an engine's tools: the native `## Skills` activation
|
|
24
|
+
* protocol (`read`, `execute(...)`) and Cursor's `<available_skills>` line
|
|
25
|
+
* (`the Read tool`); the response rules; the sub-agent rules; the
|
|
26
|
+
* structured-output directives (two mechanisms, two texts); Cursor's
|
|
27
|
+
* tool-approval protocol, which exists because of Cursor's gate model and
|
|
28
|
+
* would be false on a harness that interrupts before a tool runs.
|
|
29
|
+
*
|
|
30
|
+
* Fences: nothing under `shared/` imports `harness/` (and
|
|
31
|
+
* `harness/__tests__/import-direction.test.ts` forbids `shared/` reaching
|
|
32
|
+
* `activities/`), so every function here takes a plain struct that both
|
|
33
|
+
* builders' option objects satisfy structurally — never `TurnInput`. Pure:
|
|
34
|
+
* no I/O, no logging (a builder that wants to log what the selection did
|
|
35
|
+
* does so at its own call site).
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import type { ResolvedAttachment } from "./attachment-resolver.js";
|
|
39
|
+
import { visionDisclosureLines, type NotViewableEntry } from "./attachment-vision.js";
|
|
40
|
+
import { downloadUrlDisclosureLine, type DownloadUrlKind } from "./attachment-download-urls.js";
|
|
41
|
+
import { formatContextBridgeText } from "./context-bridge.js";
|
|
42
|
+
import { formatDeclaredPreferencesText, type DeclaredPreferencesContent } from "./declared-preferences.js";
|
|
43
|
+
import { formatRecalledMemoriesText, type RecalledMemoriesContent } from "./recalled-memories.js";
|
|
44
|
+
import { formatSenderIdentityText, type SenderIdentity } from "./sender-identity.js";
|
|
45
|
+
import { formatSessionContextText } from "./session-context.js";
|
|
46
|
+
import { filterSkills } from "./skill-relevance.js";
|
|
47
|
+
import type { SkillMetadata } from "./skill-resolver.js";
|
|
48
|
+
import { STIGMER_LOCAL_STATE_DIR } from "./workspace/stigmer-link.js";
|
|
49
|
+
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// The standing context: five sections, one order
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The standing sections a prompt may carry, in the order they read. A builder
|
|
56
|
+
* labels each kind in its own vocabulary; adding a kind here fails every
|
|
57
|
+
* builder's label map until it names the new section — the point of a closed
|
|
58
|
+
* union over a bag of optional fields.
|
|
59
|
+
*/
|
|
60
|
+
export type StandingSectionKind =
|
|
61
|
+
| "conversation-sender"
|
|
62
|
+
| "declared-preferences"
|
|
63
|
+
| "recalled-memories"
|
|
64
|
+
| "session-context"
|
|
65
|
+
| "previous-conversation";
|
|
66
|
+
|
|
67
|
+
export interface StandingSection {
|
|
68
|
+
readonly kind: StandingSectionKind;
|
|
69
|
+
/** The section's words, from the body's own module; the builder frames them. */
|
|
70
|
+
readonly body: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The standing facts as both builders already hold them (their option
|
|
75
|
+
* objects satisfy this structurally). Every field optional: an absent value
|
|
76
|
+
* renders no section, so a runner predating a fact simply says nothing.
|
|
77
|
+
*/
|
|
78
|
+
export interface StandingPromptContext {
|
|
79
|
+
readonly senderIdentity?: SenderIdentity;
|
|
80
|
+
readonly declaredPreferences?: DeclaredPreferencesContent;
|
|
81
|
+
readonly recalledMemories?: RecalledMemoriesContent;
|
|
82
|
+
readonly sessionContext?: string;
|
|
83
|
+
readonly contextBridge?: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The present standing sections in the one ruled order. The order is the
|
|
88
|
+
* doctrine, stated once:
|
|
89
|
+
*
|
|
90
|
+
* 1. The conversation sender first: standing context about WHO the
|
|
91
|
+
* conversation is with, which everything after may refer back to.
|
|
92
|
+
* 2. Platform-declared standing facts precede embedder-supplied context
|
|
93
|
+
* (DD-002 D3): both are standing background, but the declared preferences
|
|
94
|
+
* are platform-authored while session context is the embedder's overlay —
|
|
95
|
+
* the more specific overlay reads later and naturally refines.
|
|
96
|
+
* 3. Declared-by-humans precedes learned-and-confirmed (DD-006 D4): both are
|
|
97
|
+
* platform-authored standing background, but a preference is the user's
|
|
98
|
+
* exact words while a memory is an agent's confirmed inference — the exact
|
|
99
|
+
* statement reads first.
|
|
100
|
+
* 4. Standing facts about the user (session context) come before the carried
|
|
101
|
+
* conversation (bridge): the bridge may refer back to them.
|
|
102
|
+
*
|
|
103
|
+
* Where the block sits in a prompt, and on which turns, is the builder's
|
|
104
|
+
* (native: every turn, the system prompt is rebuilt; Cursor: the session's
|
|
105
|
+
* first message, the agent's own store carries it after).
|
|
106
|
+
*/
|
|
107
|
+
export function standingContextSections(standing: StandingPromptContext): readonly StandingSection[] {
|
|
108
|
+
const sections: StandingSection[] = [];
|
|
109
|
+
if (standing.senderIdentity) {
|
|
110
|
+
sections.push({ kind: "conversation-sender", body: formatSenderIdentityText(standing.senderIdentity) });
|
|
111
|
+
}
|
|
112
|
+
if (standing.declaredPreferences) {
|
|
113
|
+
sections.push({ kind: "declared-preferences", body: formatDeclaredPreferencesText(standing.declaredPreferences) });
|
|
114
|
+
}
|
|
115
|
+
if (standing.recalledMemories) {
|
|
116
|
+
sections.push({ kind: "recalled-memories", body: formatRecalledMemoriesText(standing.recalledMemories) });
|
|
117
|
+
}
|
|
118
|
+
if (standing.sessionContext) {
|
|
119
|
+
sections.push({ kind: "session-context", body: formatSessionContextText(standing.sessionContext) });
|
|
120
|
+
}
|
|
121
|
+
if (standing.contextBridge) {
|
|
122
|
+
sections.push({ kind: "previous-conversation", body: formatContextBridgeText(standing.contextBridge) });
|
|
123
|
+
}
|
|
124
|
+
return sections;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// The input files: the lines, not the frame
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Which images ride the user message inline (in send order) and which
|
|
133
|
+
* degraded to the file-pointer story — the vision facts a prompt discloses
|
|
134
|
+
* beside its input files (`attachment-vision.ts` owns the wording). Derived
|
|
135
|
+
* per turn from the resolved attachments; never carried across turns.
|
|
136
|
+
*/
|
|
137
|
+
export interface VisionPromptInfo {
|
|
138
|
+
readonly inlineFilenames: readonly string[];
|
|
139
|
+
readonly notViewable: readonly NotViewableEntry[];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* The vision facts as the runtime's attachment phase resolves them (the
|
|
144
|
+
* `TurnInput.attachments` shape, structurally): the inline images in send
|
|
145
|
+
* order and the ones that degraded. `undefined` when the turn has neither, so
|
|
146
|
+
* the section renders no vision lines at all rather than an empty disclosure.
|
|
147
|
+
*/
|
|
148
|
+
export function visionPromptInfoOf(attachments: {
|
|
149
|
+
readonly visionImages: readonly { readonly filename: string }[];
|
|
150
|
+
readonly visionNotViewable: readonly NotViewableEntry[];
|
|
151
|
+
}): VisionPromptInfo | undefined {
|
|
152
|
+
if (attachments.visionImages.length === 0 && attachments.visionNotViewable.length === 0) return undefined;
|
|
153
|
+
return {
|
|
154
|
+
inlineFilenames: attachments.visionImages.map((v) => v.filename),
|
|
155
|
+
notViewable: attachments.visionNotViewable,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** The input-files section's lines; the builder supplies the intro and the frame. */
|
|
160
|
+
export interface InputFileLines {
|
|
161
|
+
/** One bullet per file: path, size, the rename disclosure, the download URL. */
|
|
162
|
+
readonly entries: readonly string[];
|
|
163
|
+
/** The URL hand-off line, present only when some listed file carries a URL. */
|
|
164
|
+
readonly urlHandoff: string | undefined;
|
|
165
|
+
/** The vision disclosure lines; empty when the turn carries no vision facts. */
|
|
166
|
+
readonly vision: readonly string[];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* The input-files lines over the runtime's own `ResolvedAttachment` — one
|
|
171
|
+
* type, one truth (a structural twin once lived in each builder; native's
|
|
172
|
+
* silently dropped the size, Cursor's was deleted at S3 M5, Q-M5-5).
|
|
173
|
+
*
|
|
174
|
+
* Each bullet discloses the size (so the agent can weigh a read — the field's
|
|
175
|
+
* own stated purpose; Cursor's line gained it at S3 M5, Q-M5-3), the original
|
|
176
|
+
* name of a duplicate-renamed file (`attachment-naming.ts`; so the agent can
|
|
177
|
+
* connect "the two report.pdfs" in the user's message to distinct files on
|
|
178
|
+
* disk), and the download URL when one was minted
|
|
179
|
+
* (`attachment-download-urls.ts`; for the remote hand-off story). The URL
|
|
180
|
+
* hand-off line renders only when some listed file actually carries a URL —
|
|
181
|
+
* its wording keys on what kind of URL the storage backend mints. The vision
|
|
182
|
+
* lines tell the model which of these files it can already SEE inline versus
|
|
183
|
+
* which degraded to path-only; without them an agent silently ignores a photo
|
|
184
|
+
* the user believes it can see.
|
|
185
|
+
*/
|
|
186
|
+
export function inputFileLines(
|
|
187
|
+
files: readonly ResolvedAttachment[],
|
|
188
|
+
vision: VisionPromptInfo | undefined,
|
|
189
|
+
downloadUrlKind: DownloadUrlKind | undefined,
|
|
190
|
+
): InputFileLines {
|
|
191
|
+
const entries = files.map((f) => {
|
|
192
|
+
const size = ` (${f.sizeBytes} bytes)`;
|
|
193
|
+
const rename = f.renamedFrom !== undefined ? ` (renamed from duplicate '${f.renamedFrom}')` : "";
|
|
194
|
+
const url = f.downloadUrl !== undefined ? ` — download URL: ${f.downloadUrl}` : "";
|
|
195
|
+
return `- \`${f.relativePath}\`${size}${rename}${url}`;
|
|
196
|
+
});
|
|
197
|
+
const urlHandoff =
|
|
198
|
+
downloadUrlKind !== undefined && files.some((f) => f.downloadUrl !== undefined)
|
|
199
|
+
? downloadUrlDisclosureLine(downloadUrlKind)
|
|
200
|
+
: undefined;
|
|
201
|
+
return {
|
|
202
|
+
entries,
|
|
203
|
+
urlHandoff,
|
|
204
|
+
vision: vision ? visionDisclosureLines(vision.inlineFilenames, vision.notViewable) : [],
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
// The skills: which to highlight
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
|
|
212
|
+
/** Which mounted skills a prompt highlights, and which it only names. */
|
|
213
|
+
export interface SkillSelection {
|
|
214
|
+
/** The skills the prompt describes in full, in the filter's order. */
|
|
215
|
+
readonly highlighted: readonly SkillMetadata[];
|
|
216
|
+
/** The names of the skills left out of the highlighted set; empty below the threshold. */
|
|
217
|
+
readonly alsoAvailable: readonly string[];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* The relevance selection over the turn's message (`skill-relevance.ts`):
|
|
222
|
+
* below `SKILL_COUNT_THRESHOLD` every skill is highlighted; at and above it,
|
|
223
|
+
* the skills the message's terms reach are highlighted and the rest are
|
|
224
|
+
* named, so the agent can still activate one on its own judgement (the Agent
|
|
225
|
+
* Skills spec's progressive disclosure: metadata up front, instructions on
|
|
226
|
+
* demand). The native harness calls this on every turn; the Cursor harness
|
|
227
|
+
* lists every skill today and its adoption is S4's (Q-M5-4).
|
|
228
|
+
*/
|
|
229
|
+
export function selectSkillsForPrompt(userMessage: string, skills: readonly SkillMetadata[]): SkillSelection {
|
|
230
|
+
const filter = filterSkills(
|
|
231
|
+
userMessage,
|
|
232
|
+
skills.map((s) => s.name),
|
|
233
|
+
skills.map((s) => s.description),
|
|
234
|
+
);
|
|
235
|
+
return {
|
|
236
|
+
highlighted: filter.includedIndices.map((i) => skills[i]),
|
|
237
|
+
alsoAvailable: filter.excludedNames,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* The tool-neutral sentence that names the skills a prompt did not highlight
|
|
243
|
+
* (`SkillSelection.alsoAvailable`), so the agent can activate one by reading
|
|
244
|
+
* its SKILL.md at the mounted path. The sentence names no tool, so it serves
|
|
245
|
+
* any harness; the heading above it is the builder's framing. Empty for no
|
|
246
|
+
* names.
|
|
247
|
+
*/
|
|
248
|
+
export function alsoAvailableSkillsNote(excludedNames: readonly string[]): string {
|
|
249
|
+
if (excludedNames.length === 0) return "";
|
|
250
|
+
const names = excludedNames.map((n) => `\`${n}\``).join(", ");
|
|
251
|
+
return (
|
|
252
|
+
`These skills are installed but were not highlighted above: ${names}. ` +
|
|
253
|
+
"If you determine one of them is relevant to your task, " +
|
|
254
|
+
`read its SKILL.md at \`${STIGMER_LOCAL_STATE_DIR}/skills/<name>/SKILL.md\` to activate it.`
|
|
255
|
+
);
|
|
256
|
+
}
|
|
@@ -13,8 +13,10 @@
|
|
|
13
13
|
* platform dir the runtime owns; the harness renders the returned metadata
|
|
14
14
|
* into its prompt in its own placement. Moved from
|
|
15
15
|
* `activities/execute-cursor/` at S2 M3b; the native harness's twin
|
|
16
|
-
* (`skill-writer.ts` `fetchSkillsByRefs` + `mountSkills`)
|
|
17
|
-
*
|
|
16
|
+
* (`skill-writer.ts` `fetchSkillsByRefs` + `mountSkills`) retired at S3 M2b,
|
|
17
|
+
* and the module itself at S3 M5 — the one renderer it kept is
|
|
18
|
+
* `shared/prompt-sections.ts` `alsoAvailableSkillsNote`. This is the one
|
|
19
|
+
* skills path for every harness.
|
|
18
20
|
*
|
|
19
21
|
* The mount is cached by the skill's content-addressed version hash
|
|
20
22
|
* (stigmer/stigmer#672): metadata is fetched on every execution (that keeps
|
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
* The SAME resolved limit must feed both LangGraph's hard stop (the invoke
|
|
14
14
|
* config) and the ExecutionBudgetMiddleware's wrap-up advisory, so the
|
|
15
15
|
* "~80% of budget" warning and the enforcement point can never disagree.
|
|
16
|
+
*
|
|
17
|
+
* The knob and its terminal copy live together (the `cost-guard.ts` shape):
|
|
18
|
+
* when the budget is exhausted the adapter ends its turn `tool_call_limit`
|
|
19
|
+
* and the runtime's `toolCallLimitArm` writes TERMINATED with the copy
|
|
20
|
+
* below — the platform deliberately stopped the run, work is checkpointed,
|
|
21
|
+
* and the conversation continues on the next message.
|
|
16
22
|
*/
|
|
17
23
|
|
|
18
24
|
export const SUPER_STEPS_PER_ROUND = 6;
|
|
@@ -54,3 +60,45 @@ function clampToolRounds(requested: number): number {
|
|
|
54
60
|
}
|
|
55
61
|
return requested;
|
|
56
62
|
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Stable prefix of the tool-call-limit terminal error. This is a cross-repo
|
|
66
|
+
* contract: consumers that need to distinguish "ran out of tool-call budget"
|
|
67
|
+
* from other TERMINATED causes (Stigmer Cloud's channel reply extractor,
|
|
68
|
+
* which shows channel users a friendly limit message instead of generic
|
|
69
|
+
* error copy) match on this prefix with `startsWith`, because
|
|
70
|
+
* AgentExecutionStatus carries no structured termination reason. Do not
|
|
71
|
+
* reword without updating them. `COST_LIMIT_ERROR_PREFIX` (`cost-guard.ts`)
|
|
72
|
+
* mirrors it.
|
|
73
|
+
*/
|
|
74
|
+
export const TOOL_CALL_LIMIT_ERROR_PREFIX = "Agent reached the tool-call limit";
|
|
75
|
+
|
|
76
|
+
/** The terminal `status.error` for a tool-call-limit stop; the prefix is the contract, the rest is prose. */
|
|
77
|
+
export function formatToolCallLimitError(): string {
|
|
78
|
+
return `${TOOL_CALL_LIMIT_ERROR_PREFIX} for this message. Send another message to continue.`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* User-facing system message for a tool-call-limit stop. Honest about the
|
|
83
|
+
* limit, clear that nothing is lost; the cost-cap copy is its parallel.
|
|
84
|
+
*/
|
|
85
|
+
export const TOOL_CALL_LIMIT_USER_COPY =
|
|
86
|
+
"The agent reached the tool-call limit for this message. " +
|
|
87
|
+
"Work completed so far has been saved. " +
|
|
88
|
+
"Send another message to continue where the agent left off.";
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Whether an error thrown out of a LangGraph run is the graph exhausting the
|
|
92
|
+
* recursion limit `resolveRecursionLimit` placed on it — the budget's own
|
|
93
|
+
* signal, not a failure: the adapter ends the turn `tool_call_limit`.
|
|
94
|
+
* Matched by class name and message because the error class is not
|
|
95
|
+
* exported on a stable path across `@langchain/langgraph` versions.
|
|
96
|
+
*/
|
|
97
|
+
export function isGraphRecursionError(err: unknown): boolean {
|
|
98
|
+
if (err instanceof Error) {
|
|
99
|
+
return err.constructor.name === "GraphRecursionError" ||
|
|
100
|
+
err.message.includes("GraphRecursionError") ||
|
|
101
|
+
err.message.includes("Recursion limit");
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
}
|
package/src/shared/tool-row.ts
CHANGED
|
@@ -62,6 +62,67 @@ export function stampFileEditRow(tc: ToolCall, changeSetId: string): void {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* The turn-boundary pass over a transcript: stamp every file-edit row
|
|
67
|
+
* (category write/delete) that FLOWED this turn with the change set id, so
|
|
68
|
+
* the row stays visible in place as an observational record while
|
|
69
|
+
* `file_change_sets` remains the single decision surface (DD-24). Skips:
|
|
70
|
+
*
|
|
71
|
+
* - already-stamped rows — the idempotency AND cross-turn guard: a resume
|
|
72
|
+
* seeds prior turns' rows into this transcript, and re-stamping them with
|
|
73
|
+
* this turn's id would mis-attribute them ({@link stampFileEditRow});
|
|
74
|
+
* - legacy hidden rows (sessions persisted before stamping existed) — they
|
|
75
|
+
* belong to an earlier turn's set;
|
|
76
|
+
* - ids in `skipToolCallIds` — the sub-agent callers' pre-turn snapshot
|
|
77
|
+
* ({@link collectSubAgentToolCallIds}), since sub-agent rows have neither
|
|
78
|
+
* of the two shields above; top-level callers omit it;
|
|
79
|
+
* - rows `flowed` refuses — the caller's evidence that a row did NOT flow
|
|
80
|
+
* (the Cursor deny-gate's ledger tokens; a status rule). Omit to stamp
|
|
81
|
+
* every write/delete row, the deep-agent posture where every such row flowed.
|
|
82
|
+
*
|
|
83
|
+
* One pass for every harness (S3 M4; until then each adapter carried a copy
|
|
84
|
+
* differing only in the `flowed` predicate).
|
|
85
|
+
*/
|
|
86
|
+
export function stampFlowedFileEditRows(
|
|
87
|
+
messages: readonly AgentMessage[],
|
|
88
|
+
changeSetId: string,
|
|
89
|
+
opts: {
|
|
90
|
+
readonly skipToolCallIds?: ReadonlySet<string>;
|
|
91
|
+
readonly flowed?: (tc: ToolCall) => boolean;
|
|
92
|
+
} = {},
|
|
93
|
+
): void {
|
|
94
|
+
for (const msg of messages) {
|
|
95
|
+
for (const tc of msg.toolCalls) {
|
|
96
|
+
if (tc.fileChangeSetId) continue;
|
|
97
|
+
if (opts.skipToolCallIds?.has(tc.id)) continue;
|
|
98
|
+
if (isToolCallRowHidden(tc)) continue;
|
|
99
|
+
const category = toolApprovalCategory(tc.name);
|
|
100
|
+
if (category !== "write" && category !== "delete") continue;
|
|
101
|
+
if (opts.flowed && !opts.flowed(tc)) continue;
|
|
102
|
+
stampFileEditRow(tc, changeSetId);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The same pass over the turn's sub-agent transcripts. Sub-agent writes fold
|
|
109
|
+
* their files into the SAME parent turn set (shared git diff + one shared CAS
|
|
110
|
+
* observation, DD-19), so they carry the parent change set id and badge
|
|
111
|
+
* against the same set the parent's rows do. Scoped to this turn by
|
|
112
|
+
* `priorToolCallIds` (the sub-agent tool-call ids that existed before the
|
|
113
|
+
* turn's stream), because sub-agent rows lack the top-level pass's shields.
|
|
114
|
+
*/
|
|
115
|
+
export function stampFlowedSubAgentFileEditRows(
|
|
116
|
+
subAgents: readonly SubAgentExecution[],
|
|
117
|
+
changeSetId: string,
|
|
118
|
+
priorToolCallIds: ReadonlySet<string>,
|
|
119
|
+
flowed?: (tc: ToolCall) => boolean,
|
|
120
|
+
): void {
|
|
121
|
+
for (const sa of subAgents) {
|
|
122
|
+
stampFlowedFileEditRows(sa.messages, changeSetId, { skipToolCallIds: priorToolCallIds, flowed });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
65
126
|
/**
|
|
66
127
|
* Withhold a file-mutating row's CONTENT while keeping its path visible: reduce
|
|
67
128
|
* `args` to `{ path }` (or `undefined` when the path cannot be determined) and
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
STIGMER_LOCAL_STATE_DIR,
|
|
11
11
|
} from "../stigmer-link.js";
|
|
12
12
|
import { LocalWorkspaceBackend } from "../local-backend.js";
|
|
13
|
-
import { injectAttachments } from "../../../activities/execute-deep-agent/attachment-injector.js";
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* The `.stigmer` symlink is the bridge that makes platform-mounted content
|
|
@@ -114,31 +113,17 @@ describe("stigmer-link", () => {
|
|
|
114
113
|
return agentBackend.read(path) as Promise<{ content?: string; error?: string }>;
|
|
115
114
|
}
|
|
116
115
|
|
|
117
|
-
it("approved plan
|
|
116
|
+
it("an approved plan mounted under .stigmer/inputs is readable by the deepagents backend once the link exists", async () => {
|
|
118
117
|
const planFileName = "notes_ab12cd34.plan.md";
|
|
119
118
|
const planText = "# The Approved Plan\n\nStep 1: do the thing.\n";
|
|
120
|
-
const uploadPath = join(platformDir, "upload-src.md");
|
|
121
|
-
await writeFile(uploadPath, planText);
|
|
122
119
|
|
|
123
|
-
// Write path:
|
|
124
|
-
//
|
|
125
|
-
// the
|
|
120
|
+
// Write path: the attachment lands in the platform dir at the mount
|
|
121
|
+
// path the implement-plan directive tells the model to read — here
|
|
122
|
+
// through the platform-routing backend, the same physical write
|
|
123
|
+
// `shared/attachment-resolver.ts` performs (it ensures the link itself,
|
|
124
|
+
// which is why the link's absence is staged by hand below).
|
|
126
125
|
const workspaceBackend = new LocalWorkspaceBackend(workspaceDir, platformDir);
|
|
127
|
-
|
|
128
|
-
backend: workspaceBackend,
|
|
129
|
-
attachments: [{
|
|
130
|
-
filename: planFileName,
|
|
131
|
-
storageKey: "",
|
|
132
|
-
mountPath: `.stigmer/inputs/${planFileName}`,
|
|
133
|
-
contentType: "text/markdown",
|
|
134
|
-
extract: false,
|
|
135
|
-
localPath: uploadPath,
|
|
136
|
-
$typeName: "ai.stigmer.agentic.agentexecution.v1.Attachment",
|
|
137
|
-
} as any],
|
|
138
|
-
storage: undefined,
|
|
139
|
-
isLocalMode: true,
|
|
140
|
-
});
|
|
141
|
-
expect(injected.map((f) => f.path)).toEqual([`.stigmer/inputs/${planFileName}`]);
|
|
126
|
+
await workspaceBackend.writeFile(`.stigmer/inputs/${planFileName}`, planText);
|
|
142
127
|
|
|
143
128
|
// Without the symlink the agent cannot see the plan — the bug this
|
|
144
129
|
// module fixes for the native harness. Pinned so the link stays
|