@sema-agent/core 7.54.1 → 7.56.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/CHANGELOG.md +950 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cascade.js +1 -1
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +139 -0
- package/dist/agents/cc-peer-wire.d.ts +105 -0
- package/dist/agents/cc-peer-wire.js +98 -0
- package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
- package/dist/agents/cc-uds-peer-channel.js +457 -0
- package/dist/agents/child-model-seat.d.ts +0 -11
- package/dist/agents/child-model-seat.js +0 -3
- package/dist/agents/cross-session-envelope.d.ts +4 -1
- package/dist/agents/cross-session-envelope.js +8 -1
- package/dist/agents/cross-session-judge.d.ts +2 -2
- package/dist/agents/list-agents-tool.d.ts +3 -1
- package/dist/agents/list-agents-tool.js +9 -8
- package/dist/agents/observer.d.ts +4 -5
- package/dist/agents/observer.js +2 -1
- package/dist/agents/peer-admission.d.ts +6 -0
- package/dist/agents/peer-admission.js +4 -1
- package/dist/agents/peer-directory.d.ts +65 -13
- package/dist/agents/peer-directory.js +90 -25
- package/dist/agents/peer-notices.d.ts +1 -1
- package/dist/agents/peer-session-drain.d.ts +3 -1
- package/dist/agents/peer-session-drain.js +3 -2
- package/dist/agents/read-inbox-tool.js +2 -1
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/retain-ledger.d.ts +1 -1
- package/dist/agents/roster-store.d.ts +1 -1
- package/dist/agents/send-message-tool.d.ts +10 -0
- package/dist/agents/send-message-tool.js +37 -8
- package/dist/agents/subagent.d.ts +39 -82
- package/dist/agents/subagent.js +109 -106
- package/dist/agents/tool-filter.d.ts +31 -46
- package/dist/agents/tool-filter.js +13 -33
- package/dist/agents/verify.d.ts +6 -5
- package/dist/agents/verify.js +3 -3
- package/dist/brain/anthropic.js +43 -81
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- package/dist/brain/media-degrade.d.ts +18 -7
- package/dist/brain/media-degrade.js +13 -2
- package/dist/brain/model-capability.d.ts +37 -0
- package/dist/brain/model-capability.js +34 -0
- package/dist/brain/model-presets.d.ts +6 -12
- package/dist/brain/model-presets.js +1 -6
- package/dist/brain/open-responses.js +27 -35
- package/dist/brain/openai.js +30 -98
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning-request.d.ts +96 -0
- package/dist/brain/reasoning-request.js +174 -0
- package/dist/brain/reasoning.d.ts +12 -12
- package/dist/brain/reasoning.js +4 -3
- package/dist/brain/request-params.d.ts +62 -9
- package/dist/brain/request-params.js +42 -7
- package/dist/brain/retry.d.ts +1 -1
- package/dist/brain/route-adjudicator.d.ts +15 -0
- package/dist/brain/route-adjudicator.js +15 -0
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/brain/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/a2a.d.ts +2 -1
- package/dist/core/a2a.js +19 -13
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +17 -8
- package/dist/core/allow-entry.d.ts +69 -36
- package/dist/core/allow-entry.js +81 -52
- package/dist/core/allow-rule-shadow.d.ts +10 -3
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +127 -29
- package/dist/core/ask-origin.js +87 -25
- package/dist/core/ask-question.d.ts +51 -8
- package/dist/core/ask-question.js +12 -7
- package/dist/core/ask-unresolvable-notice.d.ts +8 -3
- package/dist/core/ask-unresolvable-notice.js +16 -2
- package/dist/core/auto-compaction.d.ts +11 -8
- package/dist/core/auto-compaction.js +4 -2
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/auto-mode-defaults.d.ts +8 -8
- package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
- package/dist/core/auto-mode-prompt.d.ts +1 -1
- package/dist/core/auto-mode.d.ts +17 -9
- package/dist/core/auto-mode.js +9 -6
- package/dist/core/background-agent-store.d.ts +3 -3
- package/dist/core/canonical-json.d.ts +1 -1
- package/dist/core/canonical-json.js +2 -2
- package/dist/core/checkpoint-generation.d.ts +53 -0
- package/dist/core/checkpoint-generation.js +35 -0
- package/dist/core/checkpoint-queries.d.ts +180 -0
- package/dist/core/checkpoint-queries.js +272 -0
- package/dist/core/checkpoint-requirements.d.ts +19 -4
- package/dist/core/checkpoint-requirements.js +8 -14
- package/dist/core/checkpoint-store.d.ts +165 -72
- package/dist/core/checkpoint-store.js +79 -82
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +3 -16
- package/dist/core/compliance.d.ts +2 -2
- package/dist/core/context-edit.d.ts +6 -7
- package/dist/core/cross-boundary-taint.d.ts +11 -4
- package/dist/core/cross-boundary-taint.js +3 -3
- package/dist/core/decision-receipt.d.ts +37 -3
- package/dist/core/decision-receipt.js +19 -19
- package/dist/core/delegation-not-started.d.ts +6 -0
- package/dist/core/delegation-not-started.js +17 -0
- package/dist/core/effective-path-target.d.ts +1 -1
- package/dist/core/engine-attestation.d.ts +93 -0
- package/dist/core/engine-attestation.js +70 -0
- package/dist/core/engine-capabilities.d.ts +4 -1
- package/dist/core/engine-capabilities.js +1 -1
- package/dist/core/engine-notice.d.ts +45 -12
- package/dist/core/exec-output-tail.d.ts +1 -1
- package/dist/core/file-history-retention.d.ts +1 -1
- package/dist/core/file-history-store.d.ts +147 -21
- package/dist/core/file-history-store.js +58 -32
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +24 -11
- package/dist/core/gate-lanes.js +81 -68
- package/dist/core/gate-outcome.d.ts +40 -6
- package/dist/core/gate-outcome.js +56 -0
- package/dist/core/governance-codes.d.ts +17 -3
- package/dist/core/governance-codes.js +16 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +21 -20
- package/dist/core/hooks.js +3 -1
- package/dist/core/host-floor.d.ts +128 -0
- package/dist/core/host-floor.js +206 -0
- package/dist/core/host-target.d.ts +84 -0
- package/dist/core/host-target.js +92 -0
- package/dist/core/image-downsample.d.ts +1 -1
- package/dist/core/lsp-diagnostics.d.ts +4 -4
- package/dist/core/lsp.d.ts +3 -3
- package/dist/core/mailbox-store.d.ts +4 -0
- package/dist/core/mcp-connection-pool.d.ts +18 -2
- package/dist/core/mcp-connection-pool.js +53 -6
- package/dist/core/mcp-failure.d.ts +23 -4
- package/dist/core/mcp-failure.js +26 -11
- package/dist/core/mcp-listing-drift.d.ts +10 -0
- package/dist/core/mcp-listing-drift.js +6 -0
- package/dist/core/mcp-server-link.d.ts +173 -0
- package/dist/core/mcp-server-link.js +127 -0
- package/dist/core/mcp-server-spec.d.ts +4 -2
- package/dist/core/mcp-session-end.d.ts +26 -0
- package/dist/core/mcp-session-end.js +29 -0
- package/dist/core/mcp-startup-request.d.ts +17 -0
- package/dist/core/mcp-startup-request.js +17 -0
- package/dist/core/mcp.d.ts +17 -13
- package/dist/core/mcp.js +240 -189
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- package/dist/core/memory-engine/engine.d.ts +9 -9
- package/dist/core/memory-engine/engine.js +4 -4
- package/dist/core/memory-engine/layout.d.ts +60 -8
- package/dist/core/memory-engine/layout.js +65 -6
- package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
- package/dist/core/memory-engine/tools.js +4 -1
- package/dist/core/mode-policy.d.ts +1 -1
- package/dist/core/model-seat.d.ts +10 -3
- package/dist/core/mods/classic-events.d.ts +67 -0
- package/dist/core/mods/classic-events.js +1 -0
- package/dist/core/mods/dollar.d.ts +13 -0
- package/dist/core/mods/extension-call.d.ts +31 -0
- package/dist/core/mods/extension-call.js +43 -0
- package/dist/core/mods/kernel/dispatch.d.ts +20 -3
- package/dist/core/mods/kernel/dispatch.js +140 -69
- package/dist/core/mods/kernel/events.d.ts +47 -11
- package/dist/core/mods/kernel/events.js +66 -42
- package/dist/core/mods/kernel/index.d.ts +4 -4
- package/dist/core/mods/kernel/index.js +2 -2
- package/dist/core/mods/kernel/receive.d.ts +39 -5
- package/dist/core/mods/kernel/receive.js +290 -17
- package/dist/core/mods/kernel/registration.d.ts +33 -2
- package/dist/core/mods/kernel/registration.js +6 -7
- package/dist/core/mods/kernel/site-rules.d.ts +44 -16
- package/dist/core/mods/kernel/site-rules.js +24 -42
- package/dist/core/mods/spec-seats.d.ts +69 -0
- package/dist/core/mods/spec-seats.js +114 -0
- package/dist/core/mods/stations.d.ts +28 -8
- package/dist/core/mods/stations.js +29 -13
- package/dist/core/mods/tool-call.d.ts +79 -0
- package/dist/core/mods/tool-call.js +152 -0
- package/dist/core/namespaced-rule-name.d.ts +44 -24
- package/dist/core/namespaced-rule-name.js +50 -43
- package/dist/core/output-style.d.ts +1 -1
- package/dist/core/param-rule-reach.d.ts +15 -0
- package/dist/core/param-rule-reach.js +30 -0
- package/dist/core/parent-spec-seat.d.ts +13 -1
- package/dist/core/parent-spec-seat.js +6 -0
- package/dist/core/park-selfcheck.js +1 -0
- package/dist/core/pause-registry.d.ts +16 -5
- package/dist/core/pause-registry.js +6 -2
- package/dist/core/peer-channel.d.ts +70 -0
- package/dist/core/peer-channel.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +30 -5
- package/dist/core/permission-rule-consent.js +147 -50
- package/dist/core/permission-rule-model.d.ts +245 -65
- package/dist/core/permission-rule-model.js +421 -107
- package/dist/core/permission-rule-org.d.ts +6 -2
- package/dist/core/permission-rule-org.js +7 -3
- package/dist/core/permission-rule-provider.d.ts +6 -2
- package/dist/core/permission-rule-provider.js +41 -11
- package/dist/core/permission-rule-store.d.ts +22 -26
- package/dist/core/permission-rule-store.js +12 -6
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +11 -3
- package/dist/core/permission-rule-syntax.d.ts +5 -4
- package/dist/core/permission-rule-syntax.js +2 -2
- package/dist/core/permission-rules.d.ts +53 -15
- package/dist/core/permission-rules.js +125 -100
- package/dist/core/persisted-rule-arms.d.ts +6 -4
- package/dist/core/persisted-rule-arms.js +10 -12
- package/dist/core/present-plan-tool.js +3 -1
- package/dist/core/principal-name.d.ts +20 -0
- package/dist/core/principal-name.js +22 -0
- package/dist/core/prompt-section-seat.js +4 -6
- package/dist/core/protocol-http-auth.d.ts +26 -5
- package/dist/core/protocol-http-auth.js +137 -4
- package/dist/core/protocol-naming.d.ts +2 -2
- package/dist/core/read-only-shell-table.d.ts +1 -1
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/retired-keys.d.ts +16 -0
- package/dist/core/retired-keys.js +16 -4
- package/dist/core/rewrite-rejudge.d.ts +60 -0
- package/dist/core/rewrite-rejudge.js +36 -0
- package/dist/core/roles.d.ts +34 -3
- package/dist/core/roles.js +66 -53
- package/dist/core/rule-lane-reads.d.ts +20 -15
- package/dist/core/rule-lane-reads.js +45 -17
- package/dist/core/rule-offer-read.d.ts +53 -0
- package/dist/core/rule-offer-read.js +146 -0
- package/dist/core/rule-owner.d.ts +46 -0
- package/dist/core/rule-owner.js +29 -0
- package/dist/core/runner/advisor-instructions.d.ts +70 -0
- package/dist/core/runner/advisor-instructions.js +61 -0
- package/dist/core/runner/advisor-tool.d.ts +33 -0
- package/dist/core/runner/advisor-tool.js +112 -0
- package/dist/core/runner/announce-once-ledger.d.ts +18 -26
- package/dist/core/runner/announce-once-ledger.js +19 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +2 -1
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/call-hook-stations.d.ts +3 -2
- package/dist/core/runner/caller-roster.d.ts +21 -2
- package/dist/core/runner/caller-roster.js +38 -0
- package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
- package/dist/core/runner/capability-withheld-seat.js +24 -0
- package/dist/core/runner/classifier-ladder.d.ts +33 -13
- package/dist/core/runner/classifier-ladder.js +15 -14
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +40 -33
- package/dist/core/runner/conversation-segment.d.ts +28 -0
- package/dist/core/runner/conversation-segment.js +42 -0
- package/dist/core/runner/cross-boundary-lane.d.ts +21 -16
- package/dist/core/runner/cross-boundary-lane.js +58 -34
- package/dist/core/runner/decide-continuation.d.ts +7 -4
- package/dist/core/runner/decide-continuation.js +2 -2
- package/dist/core/runner/denial-limit-arms.d.ts +4 -4
- package/dist/core/runner/denial-limit-arms.js +1 -1
- package/dist/core/runner/derived-route-fallback.d.ts +24 -24
- package/dist/core/runner/derived-route-fallback.js +9 -7
- package/dist/core/runner/file-history-request.d.ts +18 -0
- package/dist/core/runner/file-history-request.js +21 -13
- package/dist/core/runner/file-history-restore.d.ts +45 -0
- package/dist/core/runner/file-history-restore.js +46 -0
- package/dist/core/runner/gate-exit.d.ts +9 -3
- package/dist/core/runner/gate-exit.js +11 -5
- package/dist/core/runner/image.d.ts +7 -17
- package/dist/core/runner/image.js +9 -60
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +6 -6
- package/dist/core/runner/permission-rule-lanes.js +38 -15
- package/dist/core/runner/person-path-rows.d.ts +12 -9
- package/dist/core/runner/person-path-rows.js +19 -8
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
- package/dist/core/runner/prepare-ask-lane.js +5 -2
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
- package/dist/core/runner/prepare-caps-and-workflow.js +5 -4
- package/dist/core/runner/prepare-config-doors.d.ts +31 -38
- package/dist/core/runner/prepare-config-doors.js +57 -34
- package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
- package/dist/core/runner/prepare-defer-classify.js +7 -8
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +1 -1
- package/dist/core/runner/prepare-file-history.d.ts +48 -8
- package/dist/core/runner/prepare-file-history.js +41 -73
- package/dist/core/runner/prepare-gate-stations.d.ts +2 -5
- package/dist/core/runner/prepare-gate-stations.js +12 -8
- package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
- package/dist/core/runner/prepare-hands-readface.js +15 -14
- package/dist/core/runner/prepare-inherited-gate.d.ts +11 -7
- package/dist/core/runner/prepare-inherited-gate.js +8 -6
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.js +12 -12
- package/dist/core/runner/prepare-policy-chain.d.ts +7 -4
- package/dist/core/runner/prepare-policy-chain.js +68 -81
- package/dist/core/runner/prepare-project-context.d.ts +5 -2
- package/dist/core/runner/prepare-project-context.js +6 -3
- package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
- package/dist/core/runner/prepare-prompt-assembly.js +10 -8
- package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
- package/dist/core/runner/prepare-prompt-inputs.js +4 -6
- package/dist/core/runner/prepare-protocol-tools.d.ts +4 -2
- package/dist/core/runner/prepare-protocol-tools.js +5 -4
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -23
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
- package/dist/core/runner/prepare-suspend-saga.js +5 -6
- package/dist/core/runner/prepare-task.d.ts +1 -1
- package/dist/core/runner/prepare-task.js +41 -35
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +24 -18
- package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
- package/dist/core/runner/prepare-turn-wiring.js +2 -7
- package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -4
- package/dist/core/runner/prepare-wiring-manifest.js +3 -3
- package/dist/core/runner/resume-admission.js +1 -1
- package/dist/core/runner/resume-apply.js +11 -12
- package/dist/core/runner/resume-checkpoint-screen.js +3 -0
- package/dist/core/runner/resume-claim.d.ts +4 -2
- package/dist/core/runner/resume-claim.js +15 -8
- package/dist/core/runner/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +2 -1
- package/dist/core/runner/rewind-files.d.ts +15 -0
- package/dist/core/runner/rewind-files.js +132 -0
- package/dist/core/runner/run-attachment-seats.js +2 -2
- package/dist/core/runner/run-brain-sinks.d.ts +4 -1
- package/dist/core/runner/run-brain-sinks.js +4 -2
- package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
- package/dist/core/runner/run-compaction-machinery.js +2 -12
- package/dist/core/runner/run-git-lane.d.ts +1 -0
- package/dist/core/runner/run-harness-handlers.js +14 -7
- package/dist/core/runner/run-leg.d.ts +1 -1
- package/dist/core/runner/run-leg.js +43 -18
- package/dist/core/runner/run-settle-and-teardown.js +3 -2
- package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
- package/dist/core/runner/run-turn-boundary.d.ts +1 -0
- package/dist/core/runner/run-turn-boundary.js +15 -22
- package/dist/core/runner/runtask.d.ts +3 -0
- package/dist/core/runner/runtask.js +8 -9
- package/dist/core/runner/session-read-file-states.d.ts +15 -0
- package/dist/core/runner/session-read-file-states.js +28 -0
- package/dist/core/runner/session-rule-policy.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +17 -31
- package/dist/core/runner/shell-env-withheld.d.ts +33 -0
- package/dist/core/runner/shell-env-withheld.js +51 -0
- package/dist/core/runner/side-call-account.d.ts +32 -8
- package/dist/core/runner/side-call-account.js +23 -1
- package/dist/core/runner/skills-seat.js +6 -2
- package/dist/core/runner/stream-settle-backstop.js +1 -1
- package/dist/core/runner/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -6
- package/dist/core/runner/synthetic-tools.d.ts +16 -13
- package/dist/core/runner/synthetic-tools.js +8 -3
- package/dist/core/runner/tool-disclosure.d.ts +10 -12
- package/dist/core/runner/tool-disclosure.js +3 -4
- package/dist/core/runner/tool-end-body.d.ts +1 -1
- package/dist/core/runner/tool-end-body.js +10 -9
- package/dist/core/runner/tool-face-overlay.d.ts +2 -1
- package/dist/core/runner/tool-face-overlay.js +17 -1
- package/dist/core/runner/tool-not-executed.d.ts +5 -0
- package/dist/core/runner/tool-not-executed.js +11 -0
- package/dist/core/runner/tool-occurrence.d.ts +8 -0
- package/dist/core/runner/tool-occurrence.js +7 -0
- package/dist/core/runner/tool-progress-lane.d.ts +2 -2
- package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
- package/dist/core/runner/turn-attachments.d.ts +91 -80
- package/dist/core/runner/turn-attachments.js +62 -37
- package/dist/core/runner-deps.d.ts +42 -42
- package/dist/core/runtime-caps.d.ts +4 -4
- package/dist/core/safety-axis-vocab.d.ts +6 -4
- package/dist/core/safety-axis-vocab.js +6 -5
- package/dist/core/safety-merge-corpus.js +26 -2
- package/dist/core/same-plain-value.d.ts +40 -0
- package/dist/core/same-plain-value.js +49 -0
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/secret-env.d.ts +26 -3
- package/dist/core/secret-env.js +44 -8
- package/dist/core/select-model.js +3 -3
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +102 -35
- package/dist/core/session-policy-store.js +210 -48
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +106 -37
- package/dist/core/session-store.js +165 -91
- package/dist/core/session.d.ts +101 -57
- package/dist/core/session.js +53 -0
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- package/dist/core/shell-read-silence.d.ts +11 -12
- package/dist/core/shell-read-silence.js +9 -5
- package/dist/core/shell-run-candidates.js +3 -1
- package/dist/core/shell-wrapper-projection.js +1 -1
- package/dist/core/shell-wrapper-table.d.ts +14 -7
- package/dist/core/shell-wrapper-table.js +5 -4
- package/dist/core/side-query.d.ts +10 -0
- package/dist/core/side-query.js +15 -1
- package/dist/core/skill-grant.d.ts +7 -2
- package/dist/core/skill-grant.js +5 -0
- package/dist/core/skills-directory.js +6 -2
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +168 -3
- package/dist/core/store-contracts/file-history-store-contract.js +74 -4
- package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
- package/dist/core/store-contracts/peer-directory-contract.js +14 -2
- package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
- package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
- package/dist/core/store-contracts/session-repo-contract.js +176 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +6 -8
- package/dist/core/store-contracts/session-store-contract.js +361 -51
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/synthetic-read-verdict.js +3 -3
- package/dist/core/task-event.d.ts +42 -8
- package/dist/core/task-notification.d.ts +19 -15
- package/dist/core/task-registry-agent.d.ts +4 -4
- package/dist/core/task-registry-shared.d.ts +4 -4
- package/dist/core/task-registry-shared.js +1 -0
- package/dist/core/task-registry.d.ts +13 -4
- package/dist/core/task-registry.js +14 -2
- package/dist/core/task-result.d.ts +21 -3
- package/dist/core/task-spec.d.ts +69 -64
- package/dist/core/task-stream.d.ts +6 -6
- package/dist/core/task-tool-shape.d.ts +4 -4
- package/dist/core/tighten-task-spec.d.ts +1 -1
- package/dist/core/tighten-task-spec.js +2 -1
- package/dist/core/tool-catalog-entries.d.ts +36 -2
- package/dist/core/tool-catalog-entries.js +69 -43
- package/dist/core/tool-check-reading.d.ts +11 -0
- package/dist/core/tool-check-reading.js +11 -6
- package/dist/core/tool-conformance.js +1 -0
- package/dist/core/tool-errors.d.ts +2 -2
- package/dist/core/tool-face-reader.js +5 -3
- package/dist/core/tool-face.d.ts +21 -2
- package/dist/core/tool-face.js +1 -1
- package/dist/core/tool-model-gate.d.ts +5 -5
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +22 -4
- package/dist/core/tool-name-readings.d.ts +10 -43
- package/dist/core/tool-name-readings.js +2 -11
- package/dist/core/tool-policy.d.ts +85 -196
- package/dist/core/tool-policy.js +150 -175
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +5 -1
- package/dist/core/tool-roster.d.ts +57 -33
- package/dist/core/tool-roster.js +56 -68
- package/dist/core/tool-spec-members.js +8 -3
- package/dist/core/tool-spec.d.ts +53 -31
- package/dist/core/tools.js +51 -10
- package/dist/core/trace.d.ts +6 -2
- package/dist/core/types.d.ts +1 -1
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/user-attachment.d.ts +8 -1
- package/dist/core/user-attachment.js +64 -4
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +58 -0
- package/dist/core/wiring-manifest.js +14 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +78 -2
- package/dist/core/workflow-run-store.d.ts +6 -0
- package/dist/core/workflow-run-store.js +2 -0
- package/dist/engine/compaction/compaction.d.ts +9 -9
- package/dist/engine/compaction/compaction.js +3 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +26 -8
- package/dist/engine/execution-env/node-execution-env.js +54 -24
- package/dist/engine/harness/agent-harness.d.ts +39 -9
- package/dist/engine/harness/agent-harness.js +87 -33
- package/dist/engine/harness/types.d.ts +58 -9
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +36 -19
- package/dist/engine/llm/validation.d.ts +4 -1
- package/dist/engine/llm/validation.js +13 -1
- package/dist/engine/loop/agent-loop.d.ts +23 -1
- package/dist/engine/loop/agent-loop.js +26 -34
- package/dist/engine/loop/types.d.ts +31 -19
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +18 -12
- package/dist/engine/session/memory-repo.js +24 -9
- package/dist/engine/session/parent-chain-guard.d.ts +3 -2
- package/dist/engine/session/parent-chain-guard.js +1 -1
- package/dist/engine/session/repo-utils.d.ts +32 -3
- package/dist/engine/session/repo-utils.js +50 -5
- package/dist/index.d.ts +47 -23
- package/dist/index.js +35 -17
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +3 -3
- package/dist/internal/harness.js +2 -2
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +8 -6
- package/dist/orchestration/run-workflow-tool.js +10 -6
- package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
- package/dist/orchestration/workflow-types.d.ts +18 -0
- package/dist/orchestration/workflow-types.js +6 -0
- package/dist/orchestration/workflow.d.ts +5 -13
- package/dist/orchestration/workflow.js +57 -49
- package/dist/prompt-assembly/artifact.d.ts +2 -2
- package/dist/prompt-assembly/artifact.js +5 -3
- package/dist/prompt-assembly/assemble.d.ts +3 -2
- package/dist/prompt-assembly/assemble.js +1 -1
- package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
- package/dist/prompt-assembly/catalog/schema.js +34 -2
- package/dist/prompt-assembly/catalog/sections.js +0 -1
- package/dist/prompt-assembly/composer.d.ts +3 -1
- package/dist/prompt-assembly/composer.js +1 -1
- package/dist/prompt-assembly/event-registry.js +2 -0
- package/dist/prompt-assembly/overlay.js +3 -3
- package/dist/prompt-assembly/renderers.d.ts +1 -1
- package/dist/prompt-assembly/renderers.js +0 -3
- package/dist/prompt-assembly/role-base.d.ts +15 -0
- package/dist/prompt-assembly/role-base.js +9 -0
- package/dist/prompt-assembly/select.d.ts +39 -14
- package/dist/prompt-assembly/select.js +47 -16
- package/dist/prompt-assembly/sugar.d.ts +17 -11
- package/dist/prompt-assembly/sugar.js +8 -3
- package/dist/prompt-assembly/tool-catalog.d.ts +39 -2
- package/dist/prompt-assembly/tool-catalog.js +117 -4
- package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
- package/dist/prompt-assembly/turn-snapshot.js +0 -3
- package/dist/prompt-assembly/types.d.ts +0 -7
- package/dist/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +15 -15
- package/dist/scenarios/full-body.js +4 -3
- package/dist/shell/lex.js +10 -1
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +27 -33
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +9 -17
- package/dist/stores/file/checkpoint-store.d.ts +24 -0
- package/dist/stores/file/checkpoint-store.js +45 -7
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +157 -141
- package/dist/stores/file/fs-atomic.d.ts +15 -0
- package/dist/stores/file/fs-atomic.js +89 -14
- package/dist/stores/file/index.d.ts +1 -1
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/mailbox-store.d.ts +3 -0
- package/dist/stores/file/mailbox-store.js +3 -1
- package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
- package/dist/stores/file/permission-rule-adopt.js +18 -18
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +31 -18
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +54 -16
- package/dist/stores/file/session-store.js +114 -85
- package/dist/stores/file/workflow-journal-store.d.ts +10 -4
- package/dist/stores/file/workflow-journal-store.js +28 -13
- package/dist/tools/artifact/artifact-text.d.ts +1 -1
- package/dist/tools/artifact/artifact-tool.js +5 -3
- package/dist/tools/fs/bash-program-position.d.ts +19 -2
- package/dist/tools/fs/bash-program-position.js +56 -9
- package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
- package/dist/tools/fs/fs-bash.d.ts +2 -2
- package/dist/tools/fs/fs-bash.js +8 -6
- package/dist/tools/fs/fs-glob.d.ts +86 -0
- package/dist/tools/fs/fs-glob.js +226 -0
- package/dist/tools/fs/fs-read.js +14 -14
- package/dist/tools/fs/fs-search-tools.js +7 -7
- package/dist/tools/fs/fs-shared.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
- package/dist/tools/fs/notebook.d.ts +2 -2
- package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
- package/dist/tools/fs/pattern-kill-guard.js +397 -0
- package/dist/tools/fs/pdf.d.ts +9 -6
- package/dist/tools/fs/pdf.js +3 -3
- package/dist/tools/fs/program-read-model.d.ts +57 -7
- package/dist/tools/fs/program-read-model.js +11 -1
- package/dist/tools/fs/program-read-model.rows.js +78 -21
- package/dist/tools/fs/read-deny-home.js +3 -2
- package/dist/tools/fs/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +18 -8
- package/dist/tools/fs/removal-targets.js +47 -20
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +16 -6
- package/dist/tools/fs/search.js +20 -26
- package/dist/tools/fs/shell-read-argv.js +89 -12
- package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
- package/dist/tools/fs/shell-read-bindings.js +41 -0
- package/dist/tools/fs/shell-read-check.js +12 -20
- package/dist/tools/fs/shell-read-environment.d.ts +5 -1
- package/dist/tools/fs/shell-read-environment.js +3 -2
- package/dist/tools/fs/shell-read-establish.d.ts +15 -0
- package/dist/tools/fs/shell-read-establish.js +19 -20
- package/dist/tools/fs/shell-read-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -2
- package/dist/tools/fs/shell-read-plan.js +24 -16
- package/dist/tools/fs/shell-read-start.d.ts +6 -1
- package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
- package/dist/tools/fs/shell-read-write-targets.js +2 -3
- package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
- package/dist/tools/fs/shell-reentry-text.js +40 -2
- package/dist/tools/loop-tick.d.ts +2 -2
- package/dist/tools/scheduler-tools.js +5 -1
- package/dist/tools/task-list.d.ts +7 -7
- package/dist/tools/task-list.js +5 -1
- package/dist/tools/todo.js +65 -64
- package/dist/tools/web.d.ts +20 -15
- package/dist/tools/web.js +55 -69
- package/dist/tools/worktree.d.ts +3 -3
- package/dist/tools/worktree.js +3 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +5894 -5638
- package/wire-changes/core@7.55.0.json +3318 -0
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
- package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
|
@@ -150,11 +150,16 @@ function readHandsFact(fact) {
|
|
|
150
150
|
}
|
|
151
151
|
return mounted ? { mounted } : { mounted, reason };
|
|
152
152
|
}
|
|
153
|
-
function
|
|
154
|
-
if (word
|
|
155
|
-
throw new Error(`the
|
|
153
|
+
function readWordFact(word, words, label) {
|
|
154
|
+
if (!words.includes(word))
|
|
155
|
+
throw new Error(`the ${label} wiring fact ${JSON.stringify(word)} is not one of ${words.join("|")}`);
|
|
156
156
|
return word;
|
|
157
157
|
}
|
|
158
|
+
function readSessionRulesFact(fact) {
|
|
159
|
+
if (typeof fact !== "boolean")
|
|
160
|
+
throw new Error(`the session-rules wiring fact ${JSON.stringify(fact)} is not a boolean`);
|
|
161
|
+
return { childrenReadLive: fact };
|
|
162
|
+
}
|
|
158
163
|
export function deriveWiringManifest(facts) {
|
|
159
164
|
if (facts.half === "static" && facts.leg !== undefined) {
|
|
160
165
|
throw new Error("a static wiring manifest has no leg — leg identity is an effective-half fact");
|
|
@@ -219,14 +224,18 @@ export function deriveWiringManifest(facts) {
|
|
|
219
224
|
? { readDeny: { builtinTiers: [...facts.readDenyBuiltinTiersActive] } }
|
|
220
225
|
: {}),
|
|
221
226
|
...(facts.half === "effective" && facts.autoConsolidationOnRecommendation === true ? { autoConsolidation: { onRecommendation: true } } : {}),
|
|
222
|
-
...(facts.half === "effective" && facts.fileHistory !== undefined ? { fileHistory:
|
|
227
|
+
...(facts.half === "effective" && facts.fileHistory !== undefined ? { fileHistory: readWordFact(facts.fileHistory, ["on", "disabled"], "file-history") } : {}),
|
|
228
|
+
...(facts.half === "effective" && facts.projectMemory !== undefined ? { projectMemory: readWordFact(facts.projectMemory, ["on", "disabled", "absent"], "project-memory") } : {}),
|
|
229
|
+
...(facts.half === "effective" && facts.sessionRulesChildrenReadLive !== undefined ? { sessionRules: readSessionRulesFact(facts.sessionRulesChildrenReadLive) } : {}),
|
|
230
|
+
...(facts.half === "effective" && facts.advisor !== undefined ? { advisor: { ...facts.advisor, ...(facts.advisor.hold !== undefined ? { hold: { ...facts.advisor.hold } } : {}) } } : {}),
|
|
231
|
+
...(facts.half === "effective" && facts.hostFloor !== undefined ? { hostFloor: { onlyMode: facts.hostFloor.onlyMode, denyCount: facts.hostFloor.denyCount, onlyCount: facts.hostFloor.onlyCount } } : {}),
|
|
223
232
|
...(facts.half === "effective" && facts.teamRole !== undefined ? { teamRole: facts.teamRole } : {}),
|
|
224
233
|
...(facts.half === "effective" && facts.peerPresence !== undefined && (facts.peerPresence.agent !== undefined || facts.peerPresence.intent !== undefined)
|
|
225
234
|
? { peerPresence: { ...(facts.peerPresence.agent !== undefined ? { agent: facts.peerPresence.agent } : {}), ...(facts.peerPresence.intent !== undefined ? { intent: facts.peerPresence.intent } : {}) } }
|
|
226
235
|
: {}),
|
|
227
236
|
};
|
|
228
237
|
if (facts.half === "effective") {
|
|
229
|
-
const { leg: _leg, mcp: _mcp, tools: _tools, lsp: _lsp, mods: _mods, teamRole: _teamRole, peerPresence: _peerPresence, fileHistory: _fileHistory, permissionMode: _permissionMode, ...assembly } = manifest;
|
|
238
|
+
const { leg: _leg, mcp: _mcp, tools: _tools, lsp: _lsp, mods: _mods, teamRole: _teamRole, peerPresence: _peerPresence, fileHistory: _fileHistory, projectMemory: _projectMemory, permissionMode: _permissionMode, sessionRules: _sessionRules, advisor: _advisor, ...assembly } = manifest;
|
|
230
239
|
const { provenance: _askSeat, ...askForHash } = assembly.ask;
|
|
231
240
|
const { provenance: _questionSeat, ...questionForHash } = assembly.question;
|
|
232
241
|
manifest.configFingerprint = createHash("sha256")
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TaskResult } from "./types.js";
|
|
2
|
+
import { type CorruptBodyForm } from "./store-contracts/read-back-shape-contract.js";
|
|
2
3
|
/**
|
|
3
4
|
* design/97 CORE-7 — one recorded `ctx.agent` result in a workflow's RESUME journal. Unlike the observation-only
|
|
4
5
|
* {@link WorkflowRunStore} (best-effort, swallowed on throw), the journal is LOAD-BEARING: a resume replays the
|
|
@@ -30,6 +31,67 @@ export type WorkflowJournalEntry = {
|
|
|
30
31
|
}>;
|
|
31
32
|
};
|
|
32
33
|
};
|
|
34
|
+
/** What {@link readWorkflowJournalEntry} answers: the entry, or the corrupt form the row takes plus a clause
|
|
35
|
+
* naming what is wrong with it (worded to follow "journal entry #N"; it quotes no stored value). */
|
|
36
|
+
export type WorkflowJournalEntryReading = {
|
|
37
|
+
entry: WorkflowJournalEntry;
|
|
38
|
+
} | {
|
|
39
|
+
corrupt: CorruptBodyForm;
|
|
40
|
+
why: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The ONE reading of a journal row read back from a store: which arm it is, and whether the arm carries what a
|
|
44
|
+
* resume reads from it — an object result, or a paused terminal with its checkpoint token (the payload's other
|
|
45
|
+
* members, `sessionId` / `gate` / `stats` among them, are not judged here). `raw` is the DECODED LOGICAL ROW — an object carrying
|
|
46
|
+
* `callKey` and exactly one of `result` / `parked`; how a backend encodes that row on its medium (a JSONL
|
|
47
|
+
* line with its own `scope` / `ordinal` members, a SQL column holding an envelope) is the backend's format
|
|
48
|
+
* and is decoded before this is asked. Members other than those three are not read and are not carried into
|
|
49
|
+
* the entry, which is minted fresh from them.
|
|
50
|
+
*
|
|
51
|
+
* Corrupt, by form:
|
|
52
|
+
* - `not-an-object` — the row is not an object;
|
|
53
|
+
* - `missing-required` — no `callKey`; neither arm; a parked arm whose result carries no `terminal`, or
|
|
54
|
+
* whose paused terminal carries no `token`;
|
|
55
|
+
* - `wrong-type` — a non-string `callKey`; BOTH arms (the union admits one); a `result` that is not an
|
|
56
|
+
* object; a `parked` that is not an object; a parked arm whose terminal is not `paused`, or whose token
|
|
57
|
+
* is not a non-empty string.
|
|
58
|
+
*
|
|
59
|
+
* The parked arm's paused terminal and its checkpoint token are judged here because the type requires them
|
|
60
|
+
* and the arm is load-bearing: a row that says it parked but holds no paused result with a token can neither
|
|
61
|
+
* be driven nor be replayed as a finished call, and answering it as either would let a resume run that
|
|
62
|
+
* ordinal again beside the child pinned under its pending checkpoint. Whether a COMPLETED result carries a
|
|
63
|
+
* terminal cause the engine can replay is the resume's own admission (a journal written before
|
|
64
|
+
* `TaskResult.terminal` is incompatible, not damaged).
|
|
65
|
+
*/
|
|
66
|
+
export declare function readWorkflowJournalEntry(raw: unknown): WorkflowJournalEntryReading;
|
|
67
|
+
/**
|
|
68
|
+
* Clamp an externally-supplied run identifier before it lands in a persisted field or an error message:
|
|
69
|
+
* `resumeFromRunId` is LLM-controlled text and a resume claim's `holder` is store-supplied, so neither may
|
|
70
|
+
* carry control characters / unbounded length into a record a human or a model reads.
|
|
71
|
+
*/
|
|
72
|
+
export declare function clampRunIdText(raw: string): string;
|
|
73
|
+
/** The code of {@link WorkflowJournalIncompatibleError} — the word the journal store kit asserts on a refused `load`. */
|
|
74
|
+
export declare const JOURNAL_INCOMPATIBLE_ERROR_CODE = "workflow.journal_incompatible";
|
|
75
|
+
/** A resume journal entry the resume cannot admit is INCOMPATIBLE, and the resume is refused before any work is
|
|
76
|
+
* dispatched: a row whose result carries no terminal cause (a journal written before `TaskResult.terminal`), or
|
|
77
|
+
* a row {@link readWorkflowJournalEntry} reads as corrupt — refused by the engine's admission, or by a store's
|
|
78
|
+
* own `load` (the journal store kit holds a backend's refused `load` to this code). The alternative (letting the
|
|
79
|
+
* entry diverge into a live re-run) would execute the already-completed prefix again, side effects included.
|
|
80
|
+
*
|
|
81
|
+
* `entry` is the row as read: when the journal reader finds it corrupt, the message carries that reader's clause
|
|
82
|
+
* (fixed text that quotes no stored value), so no caller-supplied text reaches it; absent, or a row the reader
|
|
83
|
+
* admits, the clause is the missing terminal cause. A backend whose own medium holds a line that is not one of the
|
|
84
|
+
* run's records refuses with {@link WorkflowJournalIncompatibleError.ledgerLine}. `ordinal` is `-1` when the refusal
|
|
85
|
+
* names no entry ordinal: a row with no readable call key, or a ledger line. The run id is clamped here. */
|
|
86
|
+
export declare class WorkflowJournalIncompatibleError extends Error {
|
|
87
|
+
readonly ordinal: number;
|
|
88
|
+
readonly code = "workflow.journal_incompatible";
|
|
89
|
+
readonly fromRunId: string;
|
|
90
|
+
constructor(fromRunId: string, ordinal: number, entry?: unknown);
|
|
91
|
+
/** The refusal for line `line` (1-based) of a backend's ledger that is not one of the run's records, judged `form`
|
|
92
|
+
* by the backend's line reader: dropping it would leave whatever it held looking never journaled. */
|
|
93
|
+
static ledgerLine(fromRunId: string, line: number, form: CorruptBodyForm): WorkflowJournalIncompatibleError;
|
|
94
|
+
}
|
|
33
95
|
/** REF-D5: the resume-claim key triple — ONE shape for the interface pair and every implementation
|
|
34
96
|
* (it was re-inlined seven times; a key-field rename must red every leg at once). */
|
|
35
97
|
export interface ResumeClaimArgs {
|
|
@@ -1,4 +1,72 @@
|
|
|
1
1
|
import { terminalProjection } from "./runner/terminal-projection.js";
|
|
2
|
+
import { CORRUPT_BODY_FORMS } from "./store-contracts/read-back-shape-contract.js";
|
|
3
|
+
const isRecordShaped = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
4
|
+
const ownMember = (o, key) => (Object.hasOwn(o, key) ? o[key] : undefined);
|
|
5
|
+
export function readWorkflowJournalEntry(raw) {
|
|
6
|
+
if (!isRecordShaped(raw))
|
|
7
|
+
return { corrupt: "not-an-object", why: "is not a journal entry (not an object)" };
|
|
8
|
+
const callKey = ownMember(raw, "callKey");
|
|
9
|
+
if (callKey === undefined)
|
|
10
|
+
return { corrupt: "missing-required", why: "carries no call key" };
|
|
11
|
+
if (typeof callKey !== "string")
|
|
12
|
+
return { corrupt: "wrong-type", why: "has a call key that is not a string" };
|
|
13
|
+
const result = ownMember(raw, "result");
|
|
14
|
+
const parked = ownMember(raw, "parked");
|
|
15
|
+
if (result === undefined && parked === undefined)
|
|
16
|
+
return { corrupt: "missing-required", why: "carries neither a result nor a parked arm" };
|
|
17
|
+
if (result !== undefined && parked !== undefined)
|
|
18
|
+
return { corrupt: "wrong-type", why: "carries both a result and a parked arm" };
|
|
19
|
+
if (parked === undefined) {
|
|
20
|
+
if (!isRecordShaped(result))
|
|
21
|
+
return { corrupt: "wrong-type", why: "has a result that is not an object" };
|
|
22
|
+
return { entry: { callKey, result: result } };
|
|
23
|
+
}
|
|
24
|
+
if (!isRecordShaped(parked))
|
|
25
|
+
return { corrupt: "wrong-type", why: "is recorded as parked but its parked arm is not an object" };
|
|
26
|
+
const terminal = ownMember(parked, "terminal");
|
|
27
|
+
if (terminal === undefined)
|
|
28
|
+
return { corrupt: "missing-required", why: "is recorded as parked but its parked result carries no terminal" };
|
|
29
|
+
if (!isRecordShaped(terminal) || ownMember(terminal, "kind") !== "paused") {
|
|
30
|
+
return { corrupt: "wrong-type", why: "is recorded as parked but its terminal is not a paused one" };
|
|
31
|
+
}
|
|
32
|
+
const token = ownMember(terminal, "token");
|
|
33
|
+
if (token === undefined)
|
|
34
|
+
return { corrupt: "missing-required", why: "is recorded as parked but its paused terminal carries no checkpoint token" };
|
|
35
|
+
if (typeof token !== "string" || token.length === 0)
|
|
36
|
+
return { corrupt: "wrong-type", why: "is recorded as parked but its paused terminal carries no checkpoint token" };
|
|
37
|
+
return { entry: { callKey, parked: parked } };
|
|
38
|
+
}
|
|
39
|
+
export function clampRunIdText(raw) {
|
|
40
|
+
return raw.replace(/[^A-Za-z0-9_.:-]/g, "").slice(0, 64);
|
|
41
|
+
}
|
|
42
|
+
export const JOURNAL_INCOMPATIBLE_ERROR_CODE = "workflow.journal_incompatible";
|
|
43
|
+
export class WorkflowJournalIncompatibleError extends Error {
|
|
44
|
+
ordinal;
|
|
45
|
+
code = JOURNAL_INCOMPATIBLE_ERROR_CODE;
|
|
46
|
+
fromRunId;
|
|
47
|
+
constructor(fromRunId, ordinal, entry) {
|
|
48
|
+
const runIdText = clampRunIdText(fromRunId);
|
|
49
|
+
super(`workflow run "${runIdText}": ${refusedSubjectOf(ordinal, entry)} — this journal cannot be resumed. ${REPAIR_COST}`);
|
|
50
|
+
this.ordinal = ordinal;
|
|
51
|
+
this.fromRunId = runIdText;
|
|
52
|
+
this.name = "WorkflowJournalIncompatibleError";
|
|
53
|
+
}
|
|
54
|
+
static ledgerLine(fromRunId, line, form) {
|
|
55
|
+
return new WorkflowJournalIncompatibleError(fromRunId, -1, { [LEDGER_LINE]: { line, form } });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const REPAIR_COST = "Deleting what is damaged does not repair it (whatever goes missing runs again, live); restoring it needs a copy of the ledger kept outside the engine; a fresh run executes every step again, side effects included.";
|
|
59
|
+
const LEDGER_LINE = Symbol("ledgerLine");
|
|
60
|
+
function refusedSubjectOf(ordinal, entry) {
|
|
61
|
+
const at = isRecordShaped(entry) ? entry[LEDGER_LINE] : undefined;
|
|
62
|
+
if (at !== undefined) {
|
|
63
|
+
const line = Number.isSafeInteger(at.line) && at.line > 0 ? at.line : "?";
|
|
64
|
+
const form = CORRUPT_BODY_FORMS.includes(at.form) ? at.form : "unreadable";
|
|
65
|
+
return `ledger line ${String(line)} is not one of the run's records (${String(form)})`;
|
|
66
|
+
}
|
|
67
|
+
const read = entry === undefined ? undefined : readWorkflowJournalEntry(entry);
|
|
68
|
+
return `journal entry #${ordinal} ${read !== undefined && "corrupt" in read ? read.why : "carries no terminal cause (a journal written before TaskResult.terminal, or a malformed entry)"}`;
|
|
69
|
+
}
|
|
2
70
|
export const MAX_JOURNAL_RESULT_BYTES = 5 * 1024 * 1024;
|
|
3
71
|
export function oversizeJournalResult(serialized) {
|
|
4
72
|
return Buffer.byteLength(serialized, "utf8") > MAX_JOURNAL_RESULT_BYTES;
|
|
@@ -34,7 +102,7 @@ export function journalOversizeTombstone(result, bytes) {
|
|
|
34
102
|
taskId: result.taskId,
|
|
35
103
|
sessionId: result.sessionId,
|
|
36
104
|
terminal: { kind: "failed", code: JOURNAL_OVERSIZE_ERROR_CODE, message },
|
|
37
|
-
result: message,
|
|
105
|
+
result: message, resultEntryIds: [],
|
|
38
106
|
stats: result.stats,
|
|
39
107
|
};
|
|
40
108
|
}
|
|
@@ -80,7 +148,15 @@ export class InMemoryWorkflowJournalStore {
|
|
|
80
148
|
const rec = this.runs.get(runId);
|
|
81
149
|
if (!rec || rec.scope !== scope)
|
|
82
150
|
return [];
|
|
83
|
-
|
|
151
|
+
const out = [];
|
|
152
|
+
for (const [ordinal, e] of [...rec.byOrdinal.entries()].sort((a, b) => a[0] - b[0])) {
|
|
153
|
+
const row = snapshot(e);
|
|
154
|
+
const read = readWorkflowJournalEntry(row);
|
|
155
|
+
if ("corrupt" in read)
|
|
156
|
+
throw new WorkflowJournalIncompatibleError(runId, ordinal, row);
|
|
157
|
+
out.push(read.entry);
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
84
160
|
}
|
|
85
161
|
async append(runId, scope, entry) {
|
|
86
162
|
assertJournalEntryFits(entry);
|
|
@@ -46,6 +46,12 @@ export interface WorkflowRunSummary {
|
|
|
46
46
|
description?: string;
|
|
47
47
|
/** Lifecycle status ({@link WorkflowRun.status}): running / completed / failed. */
|
|
48
48
|
status: WorkflowRunStatus;
|
|
49
|
+
/** `true` while the run is still `running` AND at least one leg is parked at an approval gate — somebody is being
|
|
50
|
+
* waited on while `status` still says `running` ({@link runParkedOf}). ABSENT otherwise, never `false`: a run
|
|
51
|
+
* that has since suspended on the park reads `failed` + `errorCode: "workflow.agent_parked"` (that code is its
|
|
52
|
+
* "awaiting approval" word; a consumer shows both arms the same way), and a settled record never carries it.
|
|
53
|
+
* DERIVED from the agent rows on every projection — not stored on the run, so no second copy to drift. */
|
|
54
|
+
parked?: true;
|
|
49
55
|
/** The MACHINE code of the failure that ended the run ({@link WorkflowRun.errorCode}) — the same word,
|
|
50
56
|
* in the same vocabulary, that the full run carries; never re-derived and never a second taxonomy.
|
|
51
57
|
* The fourth member of the same family as {@link agentFailures} / {@link budgetOvershoot} /
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { runParkedOf } from "../orchestration/workflow-types.js";
|
|
1
2
|
import { assertRetentionPolicy } from "./retention-policy.js";
|
|
2
3
|
export function summarizeWorkflowRun(run) {
|
|
3
4
|
const latestPhase = run.phases.at(-1);
|
|
@@ -8,6 +9,7 @@ export function summarizeWorkflowRun(run) {
|
|
|
8
9
|
...(run.name !== undefined ? { name: run.name } : {}),
|
|
9
10
|
...(run.description !== undefined ? { description: run.description } : {}),
|
|
10
11
|
status: run.status,
|
|
12
|
+
...(runParkedOf(run) ? { parked: true } : {}),
|
|
11
13
|
...(run.errorCode !== undefined ? { errorCode: run.errorCode } : {}),
|
|
12
14
|
...(run.agentFailures !== undefined ? { agentFailures: run.agentFailures } : {}),
|
|
13
15
|
...(run.budgetOvershoot !== undefined ? { budgetOvershoot: { ...run.budgetOvershoot } } : {}),
|
|
@@ -17,7 +17,7 @@ export interface CompactionDetails {
|
|
|
17
17
|
*/
|
|
18
18
|
modifiedFilesByRecency?: string[];
|
|
19
19
|
/**
|
|
20
|
-
* Invoked-skill retention area
|
|
20
|
+
* Invoked-skill retention area: the skills invoked in the COMPACTED range
|
|
21
21
|
* (merged over the previous compaction's retained set), most recent invocation first, already
|
|
22
22
|
* budgeted (per-skill truncation marker + total-area skip semantics — see compaction/utils.ts).
|
|
23
23
|
* Rendered onto the compaction summary message by `buildSessionContext`; kept OUT of the summary
|
|
@@ -131,7 +131,7 @@ export declare const DEFAULT_CLAMP_TOLERANCE = 0.1;
|
|
|
131
131
|
* [new user]`, and a within-turn boundary keeps `[emitting assistant][its tool results]` because
|
|
132
132
|
* a trailing tool-result batch pulls the floor back to its call site.
|
|
133
133
|
*
|
|
134
|
-
* That is the CC posture, arrived at through a different knob.
|
|
134
|
+
* That is the CC posture, arrived at through a different knob. the reference's LOCAL threshold
|
|
135
135
|
* compaction always routes to the reactive pipeline (`y9s` :432704 — the `GNo` full-compaction
|
|
136
136
|
* branch with `messagesToKeep: []` :431788 is reached only for a remote/in-process runner, and a
|
|
137
137
|
* `source:"auto"` window makes the local threshold not fire at all, `hky` :432687 / `aYe` :242816).
|
|
@@ -159,7 +159,7 @@ export declare const DEFAULT_COMPACTION_SETTINGS: CompactionSettings;
|
|
|
159
159
|
* never split (estimate vs cut-point vs defense); per-model override via `Model.charsPerToken`.
|
|
160
160
|
*
|
|
161
161
|
* 4 → 3 (design/374 slice 4, ruled 2026-08-28) — this is a RE-ANCHORING, not a divergence.
|
|
162
|
-
* CC's coefficient is a two-branch function, not a constant: `sf(model)`
|
|
162
|
+
* CC's coefficient is a two-branch function, not a constant: `sf(model)` is
|
|
163
163
|
* `Z6.has(family) ? 4 : 3`
|
|
164
164
|
* where `Z6` lists exactly the OLD families (claude-3.x, opus-4-0/4-1/4-5/4-6, sonnet-4-0/4-5/4-6,
|
|
165
165
|
* haiku-4-5). **3 is CC's DEFAULT branch; 4 is the whitelist hit** — and CC's own current generation
|
|
@@ -189,7 +189,7 @@ export declare function calculateContextTokens(usage: Usage): number;
|
|
|
189
189
|
*
|
|
190
190
|
* design/123 D1 stale-anchor note (fable-m2, same-family point): this scans RAW session entries, so
|
|
191
191
|
* unlike `buildSessionContext` (which shallow-strips the usage of kept-tail assistants replayed
|
|
192
|
-
* across a compaction boundary — the anchor "naturally disappears"
|
|
192
|
+
* across a compaction boundary — the anchor "naturally disappears") it CAN still see
|
|
193
193
|
* a pre-compaction anchor. Any consumer using this across a compaction boundary must treat such an
|
|
194
194
|
* anchor as STALE: it reflects the pre-compaction request and overestimates the post-compaction
|
|
195
195
|
* context. (Currently exported with no in-repo production consumer.)
|
|
@@ -265,7 +265,7 @@ export declare const SUMMARIZATION_SYSTEM_PROMPT = "You are a context summarizat
|
|
|
265
265
|
*/
|
|
266
266
|
export declare function contextInstructionFilesSection(contextInstructionFiles?: string): string;
|
|
267
267
|
/**
|
|
268
|
-
* design/169-A
|
|
268
|
+
* design/169-A — the CC-form FORK context for a summary
|
|
269
269
|
* request: the main lane's latest REAL request. When present (and the summary model IS the main
|
|
270
270
|
* model), the summary request is the main conversation itself — same `systemPrompt` bytes, same
|
|
271
271
|
* message-list byte PREFIX, same tools — plus ONE appended user-role instruction message. The
|
|
@@ -310,7 +310,7 @@ export declare function extractForkSummaryEnvelope(text: string): string | undef
|
|
|
310
310
|
* messages above, un-serialized) + the fork-only instruction-file authority clause (see
|
|
311
311
|
* {@link FORK_CONTEXT_INSTRUCTION_AUTHORITY}) + the fork-only summary envelope (see
|
|
312
312
|
* {@link FORK_SUMMARY_ENVELOPE_DEMAND}; the independent form keeps its envelope-free contract).
|
|
313
|
-
* Instructions inject in the same
|
|
313
|
+
* Instructions inject in the same shape as the independent form so every channel keeps
|
|
314
314
|
* one injection grammar. */
|
|
315
315
|
export declare function forkSummarizationInstruction(customInstructions?: string, contextInstructionFiles?: string): string;
|
|
316
316
|
/**
|
|
@@ -327,7 +327,7 @@ export declare function forkSummarizationInstruction(customInstructions?: string
|
|
|
327
327
|
* base = settings.summaryOutputBudgetTokens ?? settings.reserveTokens (explicit knob wins)
|
|
328
328
|
* effective = min(base, summary model's max output) (never budget output
|
|
329
329
|
* the model can't emit)
|
|
330
|
-
*
|
|
330
|
+
* Contrast: the reference's summary output cap is purely model-derived (its summary call runs at
|
|
331
331
|
* the model's max output) and fully separate from the trigger deduction — the `min(model.maxTokens,…)`
|
|
332
332
|
* leg IS that posture. The base deliberately stays reserve-derived rather than jumping to the raw
|
|
333
333
|
* model max: sema (unlike CC) clamps the summarization INPUT pre-send, and the clamp budgets
|
|
@@ -396,7 +396,7 @@ export interface SummarizationClampDryRun {
|
|
|
396
396
|
* "prior summary + new increment", not the original history.
|
|
397
397
|
*/
|
|
398
398
|
export declare function dryRunSummarizationClamp(preparation: CompactionPreparation, model: Model, customInstructions?: string, charsPerToken?: number): SummarizationClampDryRun;
|
|
399
|
-
/**
|
|
399
|
+
/** The marker inserted where the oldest conversation groups were dropped. */
|
|
400
400
|
export declare const COMPACTION_PTL_RETRY_MARKER = "[earlier conversation truncated for compaction retry]";
|
|
401
401
|
/** Generate or update a conversation summary for compaction.
|
|
402
402
|
* `summaryBudgetTokens` — the OUTPUT budget base (history leg = 0.8× it). Callers going through
|
|
@@ -488,6 +488,6 @@ export declare function compact(preparation: CompactionPreparation, model: Model
|
|
|
488
488
|
* the main model; an independent compaction model has no main prefix to share. */
|
|
489
489
|
forkContext?: CompactionForkContext): Promise<Result<CompactionResult, CompactionError>>;
|
|
490
490
|
/** The prefix leg's base prompt, with the caller's instructions injected in the SAME shape the
|
|
491
|
-
* history leg uses (`\n\nAdditional Instructions:\n${…}
|
|
491
|
+
* history leg uses (`\n\nAdditional Instructions:\n${…}`). Single source so the
|
|
492
492
|
* dry-run clamp charges exactly what the real call sends. */
|
|
493
493
|
export declare function turnPrefixSummarizationPrompt(customInstructions?: string): string;
|
|
@@ -7,6 +7,7 @@ import { budgetInvokedSkillsRetention, computeFileLists, createFileOps, extractF
|
|
|
7
7
|
import { ENGINE_AUTHORITY_ENVELOPE_TAGS, sanitizeUntrustedText } from "../../core/untrusted-text.js";
|
|
8
8
|
import { sliceHeadSafe } from "../../core/surrogate-safe-slice.js";
|
|
9
9
|
import { thrownText } from "../../core/thrown-value.js";
|
|
10
|
+
import { capabilityHeld } from "../../brain/model-capability.js";
|
|
10
11
|
function safeJsonStringify(value) {
|
|
11
12
|
try {
|
|
12
13
|
return JSON.stringify(value) ?? "undefined";
|
|
@@ -576,7 +577,7 @@ First, inside an <analysis>...</analysis> block, note what is new since the prev
|
|
|
576
577
|
Keep each section concise. Preserve exact file paths, function names, and error messages.`;
|
|
577
578
|
function createSummarizationOptions(model, maxTokens, apiKey, headers, signal, thinkingLevel) {
|
|
578
579
|
const options = { maxTokens, signal, apiKey, headers };
|
|
579
|
-
if (model
|
|
580
|
+
if (capabilityHeld(model, "reasoning") && thinkingLevel) {
|
|
580
581
|
options.reasoning = thinkingLevel;
|
|
581
582
|
}
|
|
582
583
|
return options;
|
|
@@ -868,7 +869,7 @@ async function summarizeWithLengthRecovery(label, model, context, baseMaxTokens,
|
|
|
868
869
|
? Math.max(baseMaxTokens, model.contextWindow - estimateSummarizationInputTokens(context, cpt) - SUMMARY_WINDOW_MARGIN)
|
|
869
870
|
: Number.POSITIVE_INFINITY;
|
|
870
871
|
const cap = Math.min(modelCap, windowCap);
|
|
871
|
-
let maxTokens = Math.min(cap, model
|
|
872
|
+
let maxTokens = Math.min(cap, capabilityHeld(model, "reasoning") ? Math.max(baseMaxTokens, SUMMARY_REASONING_FLOOR) : baseMaxTokens);
|
|
872
873
|
for (let attempt = 0;; attempt++) {
|
|
873
874
|
const canEscalate = attempt < SUMMARY_MAX_ESCALATIONS && maxTokens < cap;
|
|
874
875
|
const response = await completeSummarization(model, context, createSummarizationOptions(model, maxTokens, apiKey, headers, signal, thinkingLevel), streamFn, runtime);
|
|
@@ -88,9 +88,13 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
88
88
|
/** `ExecutionEnv.cdPath` = the `CDPATH` the shell child receives, read LIVE off the same merge each exec gets (never the
|
|
89
89
|
* engine process's own environment): its entries, `[]` when the child gets none. Residual: a per-exec `env.CDPATH`. */
|
|
90
90
|
get cdPath(): readonly string[];
|
|
91
|
-
/**
|
|
92
|
-
* `
|
|
93
|
-
|
|
91
|
+
/** `ExecutionEnv.withheldEnv` = what the same merge withholds from the shell child (an entry `shellEnv` re-supplies is
|
|
92
|
+
* no loss), read LIVE; `[]` when no child would be spawned at all. Residual: a per-exec `env` re-supplying one. */
|
|
93
|
+
get withheldEnv(): readonly SecretEnvFinding[];
|
|
94
|
+
/** The environment the next shell child would receive, for a READ (the scrub seat is the reader's collector or a
|
|
95
|
+
* no-op: a read announces nothing). `undefined` when no child would be spawned at all — the policy is refused against
|
|
96
|
+
* the own credentials declared since construction, and every spawn throws that reason — so a reader sees "the child
|
|
97
|
+
* gets none", never a throw. */
|
|
94
98
|
private childEnvForRead;
|
|
95
99
|
private shellPath?;
|
|
96
100
|
private shellEnv?;
|
|
@@ -101,8 +105,12 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
101
105
|
private readonly retainBackgroundProcesses;
|
|
102
106
|
private readonly onSecretEnvScrub?;
|
|
103
107
|
private readonly onNotice?;
|
|
104
|
-
/** design/128 T1-1:
|
|
108
|
+
/** design/128 T1-1: the env-owned spool dir (mkdtemp under os tmp — unpredictable, never the cwd). It exists only while
|
|
109
|
+
* {@link spoolPairs} is non-empty: the last pair's release removes it, the next mint makes a fresh one. */
|
|
105
110
|
private bgSpoolDir?;
|
|
111
|
+
/** The `outPath` of every spool pair this env minted and has not released — the one fact the dir's lifetime reads. A
|
|
112
|
+
* retain-lane bg pair is never released (its files outlive the run by design), so it keeps the dir. */
|
|
113
|
+
private readonly spoolPairs;
|
|
106
114
|
readonly backgroundCapabilities: BackgroundShellCapability["backgroundCapabilities"];
|
|
107
115
|
constructor(options: {
|
|
108
116
|
cwd: string;
|
|
@@ -127,7 +135,8 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
127
135
|
* env lane; `TaskSpec.retainBackgroundProcesses` is the task lane, without this spooling guarantee on
|
|
128
136
|
* every platform — docs/background-process-lifetime.md). The 2h bg-timeout reaper and `killBackground` still work
|
|
129
137
|
* while the host lives; after host exit, cleanup is the deployment's responsibility (e.g. the TB
|
|
130
|
-
* container teardown)
|
|
138
|
+
* container teardown) — the retained shells' spool files, and the dir holding them, are never released
|
|
139
|
+
* by the env (every other spool pair is, and the dir goes with the last one). v1 covers processes spawned via `execBackground` only (a detach-adopted
|
|
131
140
|
* foreground exec keeps pipe stdio — best-effort survival). Incompatible with durable-suspend
|
|
132
141
|
* deployments (their pre-suspend dispose becomes a no-op too — do not combine).
|
|
133
142
|
*/
|
|
@@ -157,8 +166,8 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
157
166
|
abortSignal?: AbortSignal;
|
|
158
167
|
}): Promise<Result<string[], FileError>>;
|
|
159
168
|
readBinaryFile(path: string, abortSignal?: AbortSignal): Promise<Result<Uint8Array, FileError>>;
|
|
160
|
-
/** RB-221: whole-file replace via same-directory staging + fsync + rename
|
|
161
|
-
*
|
|
169
|
+
/** RB-221: whole-file replace via same-directory staging + fsync + rename.
|
|
170
|
+
* The former single-step `writeFile` was an in-place O_TRUNC: an abort mid-write
|
|
162
171
|
* (Esc during a large Write — ctx.signal reaches here directly), ENOSPC, or a crash left the target as
|
|
163
172
|
* a torn prefix of the NEW content with the original unrecoverable. Post-fix contract: the target is
|
|
164
173
|
* either fully old or fully new; `aborted` means it was never touched. Known semantic change (same as
|
|
@@ -251,10 +260,19 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
251
260
|
* the file), while poll slicing keeps using the logical stream totalBytes; the two advance in
|
|
252
261
|
* lockstep here but are NOT interchangeable after a rotation. */
|
|
253
262
|
private syncSpool;
|
|
263
|
+
/** The one seat that opens a spool pair (foreground exec and background spawn alike), inside the env's spool dir: made on
|
|
264
|
+
* the first mint after the dir was last removed, so a command never runs against a dir an idle reap or a temp cleaner took. */
|
|
265
|
+
private mintSpoolPair;
|
|
266
|
+
/** The one seat that gives a spool pair back: unlinks both files (a descendant still writing keeps its fd into the unlinked
|
|
267
|
+
* inode — no EPIPE), forgets the pair, and removes the dir once no pair is left in it. Idempotent. */
|
|
268
|
+
private releaseSpoolPair;
|
|
269
|
+
/** Removes the spool dir (and whatever a failed unlink stranded in it) when no pair of this env lives in it. A retain-lane
|
|
270
|
+
* bg pair is never released, so it keeps its dir; the rest is gone with its last pair. Best-effort, never throws. */
|
|
271
|
+
private reapSpoolDirIfIdle;
|
|
254
272
|
/** +: reclaim an EPHEMERAL spool (detach-adopted, or any non-retain bg
|
|
255
273
|
* spawn — the whole unix bg lane is spool-backed now) — fold the final residue into the tails,
|
|
256
274
|
* unlink both files, and drop the spool reference (later syncs become no-ops). Idempotent;
|
|
257
|
-
* never touches design/128 retain-lane
|
|
275
|
+
* never touches the spool of a design/128 retain-lane shell that has a process (no `ephemeral` flag). A still-writing detached
|
|
258
276
|
* descendant keeps its fd into the unlinked inode (RB-26 posture — no EPIPE, auto-reclaim at
|
|
259
277
|
* its exit). */
|
|
260
278
|
private reclaimEphemeralSpool;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
-
import { closeSync, constants, createReadStream, mkdtempSync, openSync, readSync, statSync, truncateSync, unlinkSync } from "node:fs";
|
|
3
|
+
import { closeSync, constants, createReadStream, mkdtempSync, openSync, readSync, rmSync, statSync, truncateSync, unlinkSync } from "node:fs";
|
|
4
4
|
import { access, appendFile, lstat, mkdir, mkdtemp, open, readdir, readFile, readlink, rename, rm, stat, unlink, writeFile, } from "node:fs/promises";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { isAbsolute, join, resolve } from "node:path";
|
|
@@ -116,6 +116,10 @@ function toFileError(error, path) {
|
|
|
116
116
|
return new FileError("not_directory", message, path, cause);
|
|
117
117
|
case "EISDIR":
|
|
118
118
|
return new FileError("is_directory", message, path, cause);
|
|
119
|
+
case "ENAMETOOLONG":
|
|
120
|
+
if (path !== undefined && path.split(/[\\/]/).some((part) => Buffer.byteLength(part, "utf8") > 255))
|
|
121
|
+
return new FileError("name_too_long", message, path, cause);
|
|
122
|
+
break;
|
|
119
123
|
case "EINVAL":
|
|
120
124
|
return new FileError("invalid", message, path, cause);
|
|
121
125
|
default:
|
|
@@ -321,10 +325,15 @@ export class NodeExecutionEnv {
|
|
|
321
325
|
const value = this.childEnvForRead()?.CDPATH;
|
|
322
326
|
return value === undefined || value === "" ? [] : value.split(":");
|
|
323
327
|
}
|
|
324
|
-
|
|
328
|
+
get withheldEnv() {
|
|
329
|
+
let withheld = [];
|
|
330
|
+
this.childEnvForRead((f) => (withheld = f));
|
|
331
|
+
return withheld;
|
|
332
|
+
}
|
|
333
|
+
childEnvForRead(collect = () => { }) {
|
|
325
334
|
if (inheritEnvPolicyProblem(this.inheritEnv) !== undefined)
|
|
326
335
|
return undefined;
|
|
327
|
-
return getShellEnv(this.inheritEnv, this.shellEnv, undefined,
|
|
336
|
+
return getShellEnv(this.inheritEnv, this.shellEnv, undefined, collect);
|
|
328
337
|
}
|
|
329
338
|
shellPath;
|
|
330
339
|
shellEnv;
|
|
@@ -336,6 +345,7 @@ export class NodeExecutionEnv {
|
|
|
336
345
|
onSecretEnvScrub;
|
|
337
346
|
onNotice;
|
|
338
347
|
bgSpoolDir;
|
|
348
|
+
spoolPairs = new Set();
|
|
339
349
|
backgroundCapabilities;
|
|
340
350
|
constructor(options) {
|
|
341
351
|
this.cwd = options.cwd;
|
|
@@ -465,13 +475,7 @@ export class NodeExecutionEnv {
|
|
|
465
475
|
if (spoolPumpRef.current)
|
|
466
476
|
clearInterval(spoolPumpRef.current);
|
|
467
477
|
if (execSpoolRef.current && !(result.ok && result.value.detached !== undefined)) {
|
|
468
|
-
|
|
469
|
-
try {
|
|
470
|
-
unlinkSync(path);
|
|
471
|
-
}
|
|
472
|
-
catch {
|
|
473
|
-
}
|
|
474
|
-
}
|
|
478
|
+
this.releaseSpoolPair(execSpoolRef.current);
|
|
475
479
|
execSpoolRef.current = undefined;
|
|
476
480
|
}
|
|
477
481
|
resolvePromise(result);
|
|
@@ -479,9 +483,7 @@ export class NodeExecutionEnv {
|
|
|
479
483
|
let execSpoolFds;
|
|
480
484
|
if (process.platform !== "win32") {
|
|
481
485
|
try {
|
|
482
|
-
|
|
483
|
-
this.bgSpoolDir = mkdtempSync(join(tmpdir(), "sema-bg-"));
|
|
484
|
-
const pair = openSpoolPair(join(this.bgSpoolDir, `fg_${randomUUID()}`));
|
|
486
|
+
const pair = this.mintSpoolPair(`fg_${randomUUID()}`);
|
|
485
487
|
execSpoolRef.current = { outPath: pair.outPath, errPath: pair.errPath };
|
|
486
488
|
execSpoolFds = pair.fds;
|
|
487
489
|
}
|
|
@@ -1309,9 +1311,7 @@ export class NodeExecutionEnv {
|
|
|
1309
1311
|
let spoolFds;
|
|
1310
1312
|
if (this.retainBackgroundProcesses || process.platform !== "win32") {
|
|
1311
1313
|
try {
|
|
1312
|
-
|
|
1313
|
-
this.bgSpoolDir = mkdtempSync(join(tmpdir(), "sema-bg-"));
|
|
1314
|
-
const pair = openSpoolPair(join(this.bgSpoolDir, `bg_${this.bgCounter + 1}_${randomUUID()}`));
|
|
1314
|
+
const pair = this.mintSpoolPair(`bg_${this.bgCounter + 1}_${randomUUID()}`);
|
|
1315
1315
|
spool = {
|
|
1316
1316
|
outPath: pair.outPath,
|
|
1317
1317
|
errPath: pair.errPath,
|
|
@@ -1345,6 +1345,8 @@ export class NodeExecutionEnv {
|
|
|
1345
1345
|
}
|
|
1346
1346
|
}
|
|
1347
1347
|
}
|
|
1348
|
+
if (spool)
|
|
1349
|
+
this.releaseSpoolPair(spool);
|
|
1348
1350
|
const cause = toError(error);
|
|
1349
1351
|
return err(new BackgroundShellError("spawn_failed", cause.message, cause));
|
|
1350
1352
|
}
|
|
@@ -1533,23 +1535,51 @@ export class NodeExecutionEnv {
|
|
|
1533
1535
|
}
|
|
1534
1536
|
}
|
|
1535
1537
|
}
|
|
1538
|
+
mintSpoolPair(name) {
|
|
1539
|
+
this.bgSpoolDir ??= mkdtempSync(join(tmpdir(), "sema-bg-"));
|
|
1540
|
+
try {
|
|
1541
|
+
const pair = openSpoolPair(join(this.bgSpoolDir, name));
|
|
1542
|
+
this.spoolPairs.add(pair.outPath);
|
|
1543
|
+
return pair;
|
|
1544
|
+
}
|
|
1545
|
+
catch (error) {
|
|
1546
|
+
this.reapSpoolDirIfIdle();
|
|
1547
|
+
throw error;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
releaseSpoolPair(pair) {
|
|
1551
|
+
for (const path of [pair.outPath, pair.errPath]) {
|
|
1552
|
+
try {
|
|
1553
|
+
unlinkSync(path);
|
|
1554
|
+
}
|
|
1555
|
+
catch {
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
this.spoolPairs.delete(pair.outPath);
|
|
1559
|
+
this.reapSpoolDirIfIdle();
|
|
1560
|
+
}
|
|
1561
|
+
reapSpoolDirIfIdle() {
|
|
1562
|
+
const dir = this.bgSpoolDir;
|
|
1563
|
+
if (dir === undefined || this.spoolPairs.size > 0)
|
|
1564
|
+
return;
|
|
1565
|
+
this.bgSpoolDir = undefined;
|
|
1566
|
+
try {
|
|
1567
|
+
rmSync(dir, { recursive: true, force: true });
|
|
1568
|
+
}
|
|
1569
|
+
catch {
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1536
1572
|
reclaimEphemeralSpool(entry) {
|
|
1537
1573
|
if (entry.spoolPump !== undefined) {
|
|
1538
1574
|
clearInterval(entry.spoolPump);
|
|
1539
1575
|
entry.spoolPump = undefined;
|
|
1540
1576
|
}
|
|
1541
1577
|
const spool = entry.spool;
|
|
1542
|
-
if (!spool
|
|
1578
|
+
if (!spool || (!spool.ephemeral && entry.child.pid !== undefined))
|
|
1543
1579
|
return;
|
|
1544
1580
|
this.syncSpool(entry);
|
|
1545
1581
|
entry.spool = undefined;
|
|
1546
|
-
|
|
1547
|
-
try {
|
|
1548
|
-
unlinkSync(path);
|
|
1549
|
-
}
|
|
1550
|
-
catch {
|
|
1551
|
-
}
|
|
1552
|
-
}
|
|
1582
|
+
this.releaseSpoolPair(spool);
|
|
1553
1583
|
}
|
|
1554
1584
|
async disposeBackgroundShells(opts) {
|
|
1555
1585
|
if (this.retainBackgroundProcesses)
|