@sema-agent/core 7.54.1 → 7.55.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 +437 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +138 -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/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.js +2 -1
- 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 +43 -9
- package/dist/agents/peer-directory.js +66 -23
- 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 +1 -0
- package/dist/agents/read-inbox-tool.js +2 -1
- 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 +34 -5
- package/dist/agents/subagent.d.ts +34 -79
- package/dist/agents/subagent.js +45 -46
- package/dist/agents/tool-filter.d.ts +29 -46
- package/dist/agents/tool-filter.js +8 -31
- package/dist/agents/verify.d.ts +3 -3
- package/dist/brain/anthropic.js +14 -9
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- package/dist/brain/model-presets.d.ts +4 -4
- package/dist/brain/open-responses.js +15 -10
- package/dist/brain/openai.js +17 -12
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning.d.ts +1 -1
- package/dist/brain/request-params.d.ts +55 -5
- package/dist/brain/request-params.js +35 -3
- 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/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +7 -8
- package/dist/core/allow-entry.d.ts +49 -23
- package/dist/core/allow-entry.js +57 -32
- package/dist/core/allow-rule-shadow.d.ts +7 -0
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +63 -11
- package/dist/core/ask-origin.js +27 -5
- package/dist/core/ask-question.js +10 -4
- 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-requirements.d.ts +6 -3
- package/dist/core/checkpoint-requirements.js +4 -14
- package/dist/core/checkpoint-store.d.ts +80 -51
- package/dist/core/checkpoint-store.js +56 -74
- 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 +9 -3
- package/dist/core/cross-boundary-taint.js +5 -3
- package/dist/core/decision-receipt.js +2 -2
- package/dist/core/effective-path-target.d.ts +1 -1
- package/dist/core/engine-notice.d.ts +19 -5
- 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 +59 -9
- package/dist/core/file-history-store.js +35 -17
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-lanes.js +12 -8
- package/dist/core/gate-outcome.d.ts +17 -4
- package/dist/core/gate-outcome.js +30 -0
- package/dist/core/governance-codes.d.ts +13 -3
- package/dist/core/governance-codes.js +10 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +4 -4
- package/dist/core/host-target.d.ts +49 -0
- package/dist/core/host-target.js +59 -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 +13 -13
- package/dist/core/mcp.js +187 -162
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/engine.d.ts +9 -9
- 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/namespaced-rule-name.d.ts +33 -7
- package/dist/core/namespaced-rule-name.js +39 -25
- 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 +8 -1
- package/dist/core/parent-spec-seat.js +4 -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 +11 -5
- package/dist/core/permission-rule-consent.js +37 -30
- package/dist/core/permission-rule-model.d.ts +233 -64
- package/dist/core/permission-rule-model.js +384 -85
- package/dist/core/permission-rule-provider.d.ts +2 -1
- package/dist/core/permission-rule-store.d.ts +20 -25
- package/dist/core/permission-rule-store.js +1 -4
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +8 -1
- package/dist/core/permission-rules.d.ts +49 -11
- package/dist/core/permission-rules.js +123 -89
- package/dist/core/persisted-rule-arms.d.ts +4 -2
- package/dist/core/present-plan-tool.js +3 -1
- 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/roles.d.ts +6 -2
- package/dist/core/roles.js +45 -44
- 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 +28 -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 +4 -26
- package/dist/core/runner/announce-once-ledger.js +14 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +1 -1
- package/dist/core/runner/caller-roster.d.ts +7 -0
- package/dist/core/runner/caller-roster.js +11 -0
- package/dist/core/runner/classifier-ladder.d.ts +27 -5
- package/dist/core/runner/classifier-ladder.js +12 -11
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/contracts.d.ts +13 -9
- 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 +6 -5
- package/dist/core/runner/cross-boundary-lane.js +26 -15
- 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 +2 -2
- 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/gate-exit.d.ts +6 -0
- package/dist/core/runner/gate-exit.js +7 -2
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
- package/dist/core/runner/permission-rule-lanes.js +14 -7
- package/dist/core/runner/person-path-rows.js +1 -1
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-config-doors.d.ts +6 -4
- package/dist/core/runner/prepare-config-doors.js +18 -12
- 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.js +39 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
- package/dist/core/runner/prepare-gate-stations.js +2 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
- package/dist/core/runner/prepare-inherited-gate.js +3 -3
- package/dist/core/runner/prepare-park-ask.js +7 -7
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +4 -10
- 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-inputs.js +1 -1
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
- package/dist/core/runner/prepare-protocol-tools.js +3 -2
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -6
- package/dist/core/runner/prepare-task.js +15 -18
- package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +1 -1
- package/dist/core/runner/run-attachment-seats.js +0 -1
- 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 +2 -3
- package/dist/core/runner/run-leg.js +13 -0
- package/dist/core/runner/run-settle-and-teardown.js +1 -1
- 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 +14 -12
- package/dist/core/runner/session-rule-policy.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +13 -28
- 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/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -3
- package/dist/core/runner/synthetic-tools.d.ts +10 -13
- package/dist/core/runner/synthetic-tools.js +4 -2
- package/dist/core/runner/tool-disclosure.js +2 -1
- 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-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 +60 -67
- package/dist/core/runner-deps.d.ts +37 -37
- package/dist/core/runtime-caps.d.ts +4 -4
- package/dist/core/safety-merge-corpus.js +17 -1
- 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/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +77 -22
- package/dist/core/session-policy-store.js +56 -14
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +80 -30
- package/dist/core/session-store.js +118 -76
- package/dist/core/session.d.ts +24 -46
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- package/dist/core/side-query.d.ts +10 -0
- package/dist/core/side-query.js +5 -0
- package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
- package/dist/core/store-contracts/file-history-store-contract.js +43 -3
- 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 +125 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
- package/dist/core/store-contracts/session-store-contract.js +215 -41
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/task-event.d.ts +10 -4
- package/dist/core/task-notification.d.ts +3 -3
- 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 +4 -4
- package/dist/core/task-registry.js +3 -1
- package/dist/core/task-result.d.ts +3 -3
- package/dist/core/task-spec.d.ts +52 -52
- 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/tool-catalog-entries.d.ts +19 -2
- package/dist/core/tool-catalog-entries.js +57 -42
- 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 +3 -3
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +27 -3
- package/dist/core/tool-name-readings.d.ts +5 -8
- package/dist/core/tool-name-readings.js +1 -2
- package/dist/core/tool-policy.d.ts +24 -5
- package/dist/core/tool-policy.js +34 -10
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +2 -1
- package/dist/core/tool-roster.d.ts +47 -18
- package/dist/core/tool-roster.js +53 -32
- package/dist/core/tool-spec-members.js +1 -1
- package/dist/core/tool-spec.d.ts +35 -21
- package/dist/core/tools.js +3 -2
- package/dist/core/trace.d.ts +4 -0
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +49 -0
- package/dist/core/wiring-manifest.js +13 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +77 -1
- 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/execution-env/node-execution-env.d.ts +19 -5
- package/dist/engine/execution-env/node-execution-env.js +43 -22
- package/dist/engine/harness/agent-harness.d.ts +14 -8
- package/dist/engine/harness/agent-harness.js +33 -26
- package/dist/engine/harness/types.d.ts +29 -7
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +9 -9
- 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 +1 -1
- package/dist/engine/loop/agent-loop.js +10 -8
- package/dist/engine/loop/types.d.ts +15 -13
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +10 -11
- package/dist/engine/session/memory-repo.js +13 -8
- 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 +31 -3
- package/dist/engine/session/repo-utils.js +42 -5
- package/dist/index.d.ts +27 -15
- package/dist/index.js +21 -11
- 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 +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +2 -2
- package/dist/orchestration/run-workflow-tool.js +5 -3
- 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 +2 -13
- package/dist/orchestration/workflow.js +21 -31
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
- package/dist/prompt-assembly/tool-catalog.js +3 -0
- package/dist/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +4 -4
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +24 -31
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +6 -15
- package/dist/stores/file/checkpoint-store.d.ts +3 -0
- package/dist/stores/file/checkpoint-store.js +9 -3
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +152 -135
- 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/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 +15 -16
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +21 -14
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +26 -11
- package/dist/stores/file/session-store.js +77 -40
- 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 +2 -1
- 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 +3 -1
- 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/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +1 -1
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +6 -6
- package/dist/tools/fs/shell-read-check.js +6 -1
- package/dist/tools/fs/shell-read-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -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 +2 -1
- package/dist/tools/web.d.ts +1 -1
- package/dist/tools/web.js +40 -37
- 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 +5756 -5638
- package/wire-changes/core@7.55.0.json +3318 -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
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { existsSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
1
|
+
import { closeSync, existsSync, fstatSync, openSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { BaseSessionStorage, StoredSession, SessionError, assertForkTarget, forkRowCells, getEntriesToFork, incarnationCell, uuidv7, validateEntriesForImport, } from "../../internal/harness.js";
|
|
4
|
-
import { canonicalStoreKey, AppendLog, atomicWriteFile, ensureDir, readJsonlRecords, sanitizePathComponent } from "./fs-atomic.js";
|
|
3
|
+
import { BaseSessionStorage, StoredSession, SessionError, assertForkTarget, compareOccupants, forkRowCells, frozenRow, getEntriesToFork, importRowCells, incarnationCell, leafIdAfterEntry, ownerCell, readIncarnationCell, readOwnerCell, uuidv7, validateEntriesForImport, } from "../../internal/harness.js";
|
|
4
|
+
import { canonicalStoreKey, AppendLog, atomicWriteFile, ensureDir, firstJsonlRecord, lastJsonlRecord, readJsonlRecords, sanitizePathComponent, writeThenLink } from "./fs-atomic.js";
|
|
5
5
|
import { guardCorruptSink } from "./corrupt-read-sink.js";
|
|
6
6
|
import { assertAdoptionBootGate } from "./adoption/marker.js";
|
|
7
7
|
import { thrownText } from "../../core/thrown-value.js";
|
|
@@ -9,9 +9,14 @@ const SUFFIX = ".jsonl";
|
|
|
9
9
|
const SESSION_LINE_JUDGE = {
|
|
10
10
|
accepts: (r) => {
|
|
11
11
|
const line = r;
|
|
12
|
-
|
|
12
|
+
if (line.kind === "meta")
|
|
13
|
+
return true;
|
|
14
|
+
if (line.kind !== "entry" || line.entry === null || typeof line.entry !== "object" || Array.isArray(line.entry))
|
|
15
|
+
return false;
|
|
16
|
+
const entry = line.entry;
|
|
17
|
+
return typeof entry.id === "string" && (entry.type !== "leaf" || entry.targetId === null || typeof entry.targetId === "string");
|
|
13
18
|
},
|
|
14
|
-
what: "a session line is neither a meta header nor an entry record",
|
|
19
|
+
what: "a session line is neither a meta header nor an entry record with a string id (and, for a leaf, a string or null target)",
|
|
15
20
|
};
|
|
16
21
|
const sharedSessionStorages = new Map();
|
|
17
22
|
const sessionStorageFinalizer = new FinalizationRegistry(({ canonical, log }) => {
|
|
@@ -31,10 +36,12 @@ class FileSessionStorage extends BaseSessionStorage {
|
|
|
31
36
|
log;
|
|
32
37
|
canonicalPath;
|
|
33
38
|
holders = new Set();
|
|
39
|
+
occupant;
|
|
34
40
|
constructor(log, meta, entries, canonicalPath) {
|
|
35
41
|
super(meta, entries);
|
|
36
42
|
this.log = log;
|
|
37
43
|
this.canonicalPath = canonicalPath;
|
|
44
|
+
this.occupant = { incarnation: meta.incarnation };
|
|
38
45
|
}
|
|
39
46
|
addHolder(holder) {
|
|
40
47
|
this.holders.add(holder);
|
|
@@ -46,6 +53,9 @@ class FileSessionStorage extends BaseSessionStorage {
|
|
|
46
53
|
closeLog() {
|
|
47
54
|
this.log.close();
|
|
48
55
|
}
|
|
56
|
+
isViewOf(row) {
|
|
57
|
+
return this.log.isFileAtPath() && compareOccupants(this.occupant, row) !== "different";
|
|
58
|
+
}
|
|
49
59
|
persistSync(entry) {
|
|
50
60
|
this.log.append({ kind: "entry", entry }, true);
|
|
51
61
|
}
|
|
@@ -91,45 +101,63 @@ export class FileSessionRepo {
|
|
|
91
101
|
tally = info;
|
|
92
102
|
this.onCorruptRead?.({ ...info, sessionId: id });
|
|
93
103
|
}, SESSION_LINE_JUDGE);
|
|
94
|
-
|
|
104
|
+
const meta = this.headerOf(id, path, lines[0], () => ` (${tally?.dropped ?? 0} of ${tally?.total ?? lines.length} records skipped as corrupt)`);
|
|
95
105
|
const entries = [];
|
|
96
|
-
for (const line of lines)
|
|
97
|
-
if (line.kind === "
|
|
98
|
-
meta = line;
|
|
99
|
-
else
|
|
106
|
+
for (const line of lines)
|
|
107
|
+
if (line.kind === "entry")
|
|
100
108
|
entries.push(line.entry);
|
|
109
|
+
return { meta, entries };
|
|
110
|
+
}
|
|
111
|
+
headerOf(id, path, first, skipped = () => "") {
|
|
112
|
+
if (first === undefined || first.kind !== "meta")
|
|
113
|
+
throw new SessionError("corrupt_session", `Session ${id} is unreadable: its log has no meta header${skipped()}`);
|
|
114
|
+
const said = (key) => (detail) => this.disclose(path, `session header ${key}: ${detail}`, id);
|
|
115
|
+
const incarnation = readIncarnationCell(first.incarnation, said("incarnation"));
|
|
116
|
+
const forkedFromIncarnation = readIncarnationCell(first.forkedFromIncarnation, said("forkedFromIncarnation"));
|
|
117
|
+
return {
|
|
118
|
+
id,
|
|
119
|
+
createdAt: first.createdAt,
|
|
120
|
+
...(first.forkedFrom !== undefined ? { forkedFrom: first.forkedFrom } : {}),
|
|
121
|
+
...(first.placement !== undefined ? { placement: first.placement } : {}),
|
|
122
|
+
...(incarnation !== undefined ? { incarnation } : {}),
|
|
123
|
+
...(forkedFromIncarnation !== undefined ? { forkedFromIncarnation } : {}),
|
|
124
|
+
owner: readOwnerCell(first.owner, id),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async headOf(sessionId) {
|
|
128
|
+
const path = this.pathFor(sessionId);
|
|
129
|
+
let fd;
|
|
130
|
+
try {
|
|
131
|
+
fd = openSync(path, "r");
|
|
101
132
|
}
|
|
102
|
-
|
|
103
|
-
|
|
133
|
+
catch (err) {
|
|
134
|
+
if (err.code === "ENOENT")
|
|
135
|
+
return undefined;
|
|
136
|
+
throw err;
|
|
104
137
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
138
|
+
try {
|
|
139
|
+
const size = fstatSync(fd).size;
|
|
140
|
+
const meta = this.headerOf(sessionId, path, firstJsonlRecord(fd, size, SESSION_LINE_JUDGE));
|
|
141
|
+
const last = lastJsonlRecord(fd, size, (r) => r.kind === "entry", SESSION_LINE_JUDGE);
|
|
142
|
+
return { owner: meta.owner ?? null, incarnation: meta.incarnation, leafId: last === undefined ? null : leafIdAfterEntry(last.entry) };
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
closeSync(fd);
|
|
109
146
|
}
|
|
110
|
-
return {
|
|
111
|
-
meta: {
|
|
112
|
-
id,
|
|
113
|
-
createdAt,
|
|
114
|
-
...(forkedFrom !== undefined ? { forkedFrom } : {}),
|
|
115
|
-
...(placement !== undefined ? { placement } : {}),
|
|
116
|
-
...(typeof incarnation === "string" ? { incarnation } : {}),
|
|
117
|
-
...(typeof forkedFromIncarnation === "string" ? { forkedFromIncarnation } : {}),
|
|
118
|
-
},
|
|
119
|
-
entries,
|
|
120
|
-
};
|
|
121
147
|
}
|
|
122
148
|
storage(meta, entries) {
|
|
123
149
|
const { id } = meta;
|
|
124
150
|
const canonical = canonicalStoreKey(this.pathFor(id));
|
|
125
151
|
const live = sharedSessionStorages.get(canonical)?.deref();
|
|
126
|
-
if (live !== undefined) {
|
|
152
|
+
if (live !== undefined && live.isViewOf(meta)) {
|
|
127
153
|
live.addHolder(this);
|
|
128
154
|
this.joined.set(canonical, new WeakRef(live));
|
|
129
155
|
return live;
|
|
130
156
|
}
|
|
157
|
+
if (live !== undefined)
|
|
158
|
+
evictSharedSessionStorage(canonical);
|
|
131
159
|
const log = new AppendLog(this.pathFor(id));
|
|
132
|
-
const created = new FileSessionStorage(log, meta, entries, canonical);
|
|
160
|
+
const created = new FileSessionStorage(log, frozenRow({ ...meta, ...(meta.placement !== undefined ? { placement: { ...meta.placement } } : {}) }), entries, canonical);
|
|
133
161
|
sharedSessionStorages.set(canonical, new WeakRef(created));
|
|
134
162
|
created.addHolder(this);
|
|
135
163
|
this.joined.set(canonical, new WeakRef(created));
|
|
@@ -153,10 +181,17 @@ export class FileSessionRepo {
|
|
|
153
181
|
const createdAt = new Date().toISOString();
|
|
154
182
|
const path = this.pathFor(id);
|
|
155
183
|
if (!existsSync(path)) {
|
|
156
|
-
|
|
184
|
+
const owner = ownerCell(options.owner);
|
|
157
185
|
const placement = options.placement !== undefined ? { ...options.placement, placedAt: options.placement.placedAt ?? Date.now() } : undefined;
|
|
158
|
-
const meta = { id, createdAt, ...(placement !== undefined ? { placement } : {}), ...incarnationCell(undefined) };
|
|
159
|
-
|
|
186
|
+
const meta = { id, createdAt, ...(placement !== undefined ? { placement } : {}), ...incarnationCell(undefined), ...owner };
|
|
187
|
+
try {
|
|
188
|
+
writeThenLink(path, `${JSON.stringify({ kind: "meta", ...meta })}\n`);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
if (err.code === "EEXIST")
|
|
192
|
+
throw new SessionError("conflict", `session ${id} was created by another writer between this create's existence check and its write — refusing to replace or attach to that row`);
|
|
193
|
+
throw err;
|
|
194
|
+
}
|
|
160
195
|
return new StoredSession(this.storage(meta, []));
|
|
161
196
|
}
|
|
162
197
|
const { meta, entries } = this.read(id);
|
|
@@ -248,15 +283,19 @@ export class FileSessionRepo {
|
|
|
248
283
|
return this.read(id).meta;
|
|
249
284
|
}
|
|
250
285
|
catch (err) {
|
|
251
|
-
|
|
286
|
+
if (err instanceof SessionError && err.code === "not_found")
|
|
287
|
+
return undefined;
|
|
288
|
+
throw err;
|
|
252
289
|
}
|
|
253
290
|
}
|
|
254
291
|
async placementOf(sessionId) {
|
|
255
292
|
try {
|
|
256
293
|
return this.read(sessionId).meta.placement;
|
|
257
294
|
}
|
|
258
|
-
catch {
|
|
259
|
-
|
|
295
|
+
catch (err) {
|
|
296
|
+
if (err instanceof SessionError && err.code === "not_found")
|
|
297
|
+
return undefined;
|
|
298
|
+
throw err;
|
|
260
299
|
}
|
|
261
300
|
}
|
|
262
301
|
async delete(metadata) {
|
|
@@ -275,7 +314,7 @@ export class FileSessionRepo {
|
|
|
275
314
|
const id = options.id ?? uuidv7();
|
|
276
315
|
const createdAt = new Date().toISOString();
|
|
277
316
|
const path = this.pathFor(id);
|
|
278
|
-
const meta = { id, createdAt, ...forkRowCells(await source.getMetadata()) };
|
|
317
|
+
const meta = { id, createdAt, ...forkRowCells(await source.getMetadata(), options.owner) };
|
|
279
318
|
const lines = [JSON.stringify({ kind: "meta", ...meta })];
|
|
280
319
|
for (const entry of forked) {
|
|
281
320
|
lines.push(JSON.stringify({ kind: "entry", entry }));
|
|
@@ -288,12 +327,10 @@ export class FileSessionRepo {
|
|
|
288
327
|
return this.read(sessionId).entries;
|
|
289
328
|
}
|
|
290
329
|
async importEntries(sessionId, owner, entries, options) {
|
|
291
|
-
void owner;
|
|
292
330
|
const validated = validateEntriesForImport(entries, options);
|
|
293
|
-
const
|
|
331
|
+
const meta = importRowCells(sessionId, owner, this.priorHeader(sessionId), new Date().toISOString());
|
|
294
332
|
evictSharedSessionStorage(canonicalStoreKey(this.pathFor(sessionId)));
|
|
295
|
-
const
|
|
296
|
-
const lines = [JSON.stringify({ kind: "meta", id: sessionId, createdAt, ...incarnationCell(prior) })];
|
|
333
|
+
const lines = [JSON.stringify({ kind: "meta", ...meta })];
|
|
297
334
|
for (const entry of validated) {
|
|
298
335
|
lines.push(JSON.stringify({ kind: "entry", entry }));
|
|
299
336
|
}
|
|
@@ -48,9 +48,9 @@ export declare const RESUME_CLAIM_SWEEP_INTERVAL_MS = 60000;
|
|
|
48
48
|
*/
|
|
49
49
|
export declare const RESUME_CLAIM_REAP_GRACE_MS: number;
|
|
50
50
|
export interface FileWorkflowJournalStoreOptions {
|
|
51
|
-
/** Disclosure seat for a ledger line
|
|
52
|
-
* with
|
|
53
|
-
*
|
|
51
|
+
/** Disclosure seat for a ledger line that is not one of the run's records (not JSON, not an object, no `scope` /
|
|
52
|
+
* `ordinal`, another scope) and — with the refusal, carrying the ledger's path — for whatever refused a `load`.
|
|
53
|
+
* Never fires on a missing ledger or on a crash's unterminated tail; swallow-guarded. */
|
|
54
54
|
onCorruptRead?: (info: CorruptReadInfo) => void;
|
|
55
55
|
}
|
|
56
56
|
export declare class FileWorkflowJournalStore implements WorkflowJournalStore {
|
|
@@ -79,9 +79,15 @@ export declare class FileWorkflowJournalStore implements WorkflowJournalStore {
|
|
|
79
79
|
/** CC local form: the run's on-disk journal path for the notification diagnostics line.
|
|
80
80
|
* Traversal-shaped ids (LLM-controlled on some paths) degrade to undefined, never throw. */
|
|
81
81
|
locator(runId: string): string | undefined;
|
|
82
|
-
/** Replay a run's ledger: last-writer-wins per ordinal
|
|
82
|
+
/** Replay a run's ledger: last-writer-wins per ordinal, with every line that is not one of the run's records
|
|
83
|
+
* (`notRecords`) and the scope the first record fixes. Rows come back as written — which arm each one is, and
|
|
84
|
+
* whether anything refuses, is {@link load}'s question, so the scope lookup `append` makes refuses on nothing. */
|
|
83
85
|
private replay;
|
|
84
86
|
append(runId: string, scope: string, entry: WorkflowJournalEntry): Promise<void>;
|
|
87
|
+
/** The run's entries, ascending by ordinal, each winning line read through {@link readWorkflowJournalEntry}. A
|
|
88
|
+
* ledger line that is not one of the run's records, or a corrupt row, REFUSES the whole load: dropped, what it
|
|
89
|
+
* held would look never journaled and a resume would run it again. Only the unterminated tail a crash leaves is
|
|
90
|
+
* uncommitted. The location goes to `onCorruptRead`, not into the message; a superseded line is not read. */
|
|
85
91
|
load(runId: string, scope: string): Promise<WorkflowJournalEntry[]>;
|
|
86
92
|
/**
|
|
87
93
|
* RB-242 — the claim file for `(sourceRunId, scope)`. Keyed by BOTH: a cross-scope caller already
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync } from "node:fs";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { callKeyOrdinal } from "../../core/workflow-journal-store.js";
|
|
4
|
+
import { callKeyOrdinal, readWorkflowJournalEntry, WorkflowJournalIncompatibleError, } from "../../core/workflow-journal-store.js";
|
|
5
5
|
import { AppendLog, readJsonlRecords } from "./fs-atomic.js";
|
|
6
6
|
import { guardCorruptSink } from "./corrupt-read-sink.js";
|
|
7
7
|
import { canonicalStoreKey, sanitizePathComponent, writeThenLink } from "./fs-atomic.js";
|
|
8
8
|
import { assertAdoptionBootGate } from "./adoption/marker.js";
|
|
9
9
|
import { assertJournalEntryFits } from "../../core/workflow-journal-store.js";
|
|
10
10
|
export { MAX_JOURNAL_RESULT_BYTES, oversizeJournalResult } from "../../core/workflow-journal-store.js";
|
|
11
|
-
function entryOf(rec) {
|
|
12
|
-
if (rec.parked !== undefined)
|
|
13
|
-
return { callKey: rec.callKey, parked: rec.parked };
|
|
14
|
-
return { callKey: rec.callKey, result: rec.result };
|
|
15
|
-
}
|
|
16
11
|
export const RESUME_CLAIM_TTL_MS = 60 * 60 * 1000;
|
|
17
12
|
export const RESUME_CLAIM_RELEASE_GRACE_MS = 5_000;
|
|
18
13
|
export const RESUME_CLAIM_SWEEP_INTERVAL_MS = 60_000;
|
|
@@ -21,7 +16,7 @@ const sharedJournalDirs = new Map();
|
|
|
21
16
|
const MAX_OPEN_JOURNAL_LOGS = 64;
|
|
22
17
|
function isJournalLine(r) {
|
|
23
18
|
const rec = r;
|
|
24
|
-
return typeof rec.
|
|
19
|
+
return typeof rec.scope === "string" && Number.isFinite(rec.ordinal);
|
|
25
20
|
}
|
|
26
21
|
export class FileWorkflowJournalStore {
|
|
27
22
|
fsyncEnabled;
|
|
@@ -86,11 +81,17 @@ export class FileWorkflowJournalStore {
|
|
|
86
81
|
scope ??= r.scope;
|
|
87
82
|
return r.scope === scope;
|
|
88
83
|
},
|
|
89
|
-
what: "a journal line carries no
|
|
84
|
+
what: "a journal line carries no scope/ordinal pair, or a scope other than its run's first line",
|
|
85
|
+
};
|
|
86
|
+
const notRecords = [];
|
|
87
|
+
const onCorrupt = (info) => {
|
|
88
|
+
if (info.kind === "record")
|
|
89
|
+
notRecords.push(info);
|
|
90
|
+
this.discloseCorrupt?.(info);
|
|
90
91
|
};
|
|
91
|
-
for (const rec of readJsonlRecords(path,
|
|
92
|
-
byOrdinal.set(rec.ordinal,
|
|
93
|
-
return
|
|
92
|
+
for (const rec of readJsonlRecords(path, onCorrupt, judge))
|
|
93
|
+
byOrdinal.set(rec.ordinal, rec);
|
|
94
|
+
return { scope, byOrdinal, notRecords };
|
|
94
95
|
}
|
|
95
96
|
async append(runId, scope, entry) {
|
|
96
97
|
assertJournalEntryFits(entry);
|
|
@@ -126,9 +127,23 @@ export class FileWorkflowJournalStore {
|
|
|
126
127
|
}
|
|
127
128
|
async load(runId, scope) {
|
|
128
129
|
const rec = this.replay(runId);
|
|
129
|
-
if (!rec || rec.scope !== scope)
|
|
130
|
+
if (!rec || (rec.scope !== undefined && rec.scope !== scope))
|
|
130
131
|
return [];
|
|
131
|
-
|
|
132
|
+
const lost = rec.notRecords[0];
|
|
133
|
+
if (lost !== undefined) {
|
|
134
|
+
this.discloseCorrupt?.({ kind: "file", path: this.pathFor(runId), reason: `${lost.form}: ledger line ${lost.line} is not one of the run's records (the run's journal is refused)` });
|
|
135
|
+
throw WorkflowJournalIncompatibleError.ledgerLine(runId, lost.line, lost.form);
|
|
136
|
+
}
|
|
137
|
+
const out = [];
|
|
138
|
+
for (const [ordinal, line] of [...rec.byOrdinal.entries()].sort((a, b) => a[0] - b[0])) {
|
|
139
|
+
const read = readWorkflowJournalEntry(line);
|
|
140
|
+
if ("corrupt" in read) {
|
|
141
|
+
this.discloseCorrupt?.({ kind: "file", path: this.pathFor(runId), reason: `${read.corrupt}: journal entry #${ordinal} ${read.why} (the run's journal is refused)` });
|
|
142
|
+
throw new WorkflowJournalIncompatibleError(runId, ordinal, line);
|
|
143
|
+
}
|
|
144
|
+
out.push(read.entry);
|
|
145
|
+
}
|
|
146
|
+
return out;
|
|
132
147
|
}
|
|
133
148
|
claimPathFor(sourceRunId, scope) {
|
|
134
149
|
const scopeTag = createHash("sha256").update(scope).digest("hex").slice(0, 16);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The model-facing text of the Artifact tool. Every sentence is the upstream tool's wording, taken
|
|
3
|
-
* byte-for-byte from the reference corpus (
|
|
3
|
+
* byte-for-byte from the reference corpus (the line of each constant is
|
|
4
4
|
* noted beside it) with one class of edit: a reference to a hosting product this library does not have
|
|
5
5
|
* (`claude.ai`, its terminal/gallery/Slack surfaces, an `out_dir` save) is replaced by the smallest
|
|
6
6
|
* neutral phrase. The replacement list is registered in the divergence register beside this package.
|
|
@@ -8,7 +8,7 @@ const ARTIFACT_ACTION_LEGS = {
|
|
|
8
8
|
hosted: { publish: ["env", "outside_write"], list: ["outside_read"], read: ["outside_read"], list_files: ["outside_read"], read_file: ["outside_read"] },
|
|
9
9
|
"local-stub": { publish: ["env"], list: [], read: [], list_files: [], read_file: [] },
|
|
10
10
|
};
|
|
11
|
-
import { ARTIFACT_TOOL_NAME, toolFace } from "../../core/tool-catalog-entries.js";
|
|
11
|
+
import { ARTIFACT_TOOL_NAME, mountRuleFace, toolFace } from "../../core/tool-catalog-entries.js";
|
|
12
12
|
import { resolveAsk } from "../../core/tool-policy.js";
|
|
13
13
|
import { NOT_BINDABLE } from "../../core/skill-grant-binding.js";
|
|
14
14
|
import { approvalCardOf } from "../../core/tool-roster.js";
|
|
@@ -448,6 +448,7 @@ export function createArtifactTool(opts) {
|
|
|
448
448
|
return {
|
|
449
449
|
name: ARTIFACT_TOOL_NAME,
|
|
450
450
|
...toolFace("artifact"),
|
|
451
|
+
ruleFace: mountRuleFace("artifact"),
|
|
451
452
|
contentOrigin: ARTIFACT_PLANE_CONTENT_ORIGIN[caps.plane],
|
|
452
453
|
description: artifactDescription(caps.plane, caps.actions),
|
|
453
454
|
parameters: buildSchema(caps),
|
|
@@ -267,9 +267,9 @@ export declare function splitShellCompoundSegments(source: string, options?: {
|
|
|
267
267
|
*
|
|
268
268
|
* The allowlist vets `argv[0]` only, so until this face existed every listed reader could name ANY
|
|
269
269
|
* path: `ls /etc` and `cat /etc/passwd` classified read-only, and a deployment whose manual-mode shell
|
|
270
|
-
* gate auto-allows the read-only verdict served the whole filesystem with no approval prompt.
|
|
271
|
-
* demotes exactly these shapes (its per-command path extractor + working-directory containment check
|
|
272
|
-
*
|
|
270
|
+
* gate auto-allows the read-only verdict served the whole filesystem with no approval prompt. The reference
|
|
271
|
+
* demotes exactly these shapes (its per-command path extractor + working-directory containment check)
|
|
272
|
+
* and renders an approval option naming the directory.
|
|
273
273
|
*
|
|
274
274
|
* Supplying this object turns the check ON; omitting it leaves the classifier byte-identical to its
|
|
275
275
|
* name-only behaviour, so a consumer pinned to an older calling convention is unaffected.
|
|
@@ -35,7 +35,7 @@ export declare function bashReversibilityProbe(allow?: readonly string[], bounda
|
|
|
35
35
|
* fullShellReachable roster assertion (its first load-bearing consumer).
|
|
36
36
|
*/
|
|
37
37
|
export { FULL_SHELL_CONTRACT_ID } from "../../core/tool-catalog-entries.js";
|
|
38
|
-
/** The
|
|
38
|
+
/** The exit-1 interpretation for `command`, or undefined when exit 1 means a real error.
|
|
39
39
|
* Read off the lexer's segments: the last one (the last `;`/`&&`/`||`/newline statement's last `|` piece) → its
|
|
40
40
|
* written command word past the leading assignments bash strips, path prefix stripped;
|
|
41
41
|
* `git grep`/`git diff` special-cased (CC `cLp`). Exported for its unit tests. */
|
|
@@ -110,7 +110,7 @@ export declare function createBashTool(env: ExecutionEnv, rootCanonical: string,
|
|
|
110
110
|
* Is a PERSON's input waiting for this run's next turn boundary? Read on each liveness tick of a
|
|
111
111
|
* running foreground command: `true` on an {@link autoBackgroundOnTimeout}-armed command moves that
|
|
112
112
|
* command into the background (through the SAME detach verb ctrl+b fires) so the message is
|
|
113
|
-
* delivered this turn instead of after the command.
|
|
113
|
+
* delivered this turn instead of after the command. Reference field `backgroundedToDeliverMessage` (cli296.js:134207).
|
|
114
114
|
*
|
|
115
115
|
* The predicate is the HARNESS's own accepted-but-unserved account and deliberately counts only what
|
|
116
116
|
* a PERSON sent: an engine-authored reminder is not somebody waiting, and stepping a build aside for
|
package/dist/tools/fs/fs-bash.js
CHANGED
|
@@ -17,7 +17,7 @@ import { ghRateLimitHint } from "./gh-rate-limit.js";
|
|
|
17
17
|
import { backgroundLifetimeNote } from "./fs-bash-background-text.js";
|
|
18
18
|
import { resolveBashTimeoutCaps, bashTimeoutCapsSec, bashTimeoutArgRefusal, bashTimeoutParamDescription, envErrorDetail, bashMaxOutputChars, clipShellOutput, writeShellOverflowFile, shellRecoveryHint, CWD_SENTINEL, stripCwdSentinel, } from "./fs-shared.js";
|
|
19
19
|
import { bashClassifyDefaultAllow, BASH_READONLY_DEFAULT_ALLOW, coarseReadonlyCheck, classifyBoundedReadonlyPollLoopDetailed, classifyCompoundReadonlyDetailed } from "./bash-readonly-classifier.js";
|
|
20
|
-
import { toolFace } from "../../core/tool-catalog-entries.js";
|
|
20
|
+
import { mountRuleFace, toolFace } from "../../core/tool-catalog-entries.js";
|
|
21
21
|
import { argvOf, compoundValueHidesRun, expansionHidesRun, expansionsInHeredocBody, lexShell } from "../../shell/lex.js";
|
|
22
22
|
import { arithmeticAssignedNames } from "./shell-read-bindings.js";
|
|
23
23
|
import { thrownText } from "../../core/thrown-value.js";
|
|
@@ -812,6 +812,7 @@ export function createEnvTaskOutputTool(env) {
|
|
|
812
812
|
return defineTool({
|
|
813
813
|
name: TASK_OUTPUT_TOOL_NAME,
|
|
814
814
|
...toolFace("task-output-hands"),
|
|
815
|
+
ruleFace: mountRuleFace("task-output-hands"),
|
|
815
816
|
description: composeTaskOutputDescription(ENV_DIRECT_TASK_TOOL_CAPS),
|
|
816
817
|
parameters: composeTaskOutputParams(ENV_DIRECT_TASK_TOOL_CAPS),
|
|
817
818
|
execute: async (args) => {
|
|
@@ -849,6 +850,7 @@ export function createEnvTaskStopTool(env, registry = defaultTaskRegistry) {
|
|
|
849
850
|
return defineTool({
|
|
850
851
|
name: TASK_STOP_TOOL_NAME,
|
|
851
852
|
...toolFace("task-stop-hands"),
|
|
853
|
+
ruleFace: mountRuleFace("task-stop-hands"),
|
|
852
854
|
description: composeTaskStopDescription(ENV_DIRECT_TASK_TOOL_CAPS),
|
|
853
855
|
parameters: TASK_STOP_PARAMS,
|
|
854
856
|
execute: async (args) => {
|
|
@@ -25,14 +25,14 @@ export declare const MAX_READ_BYTES: number;
|
|
|
25
25
|
* explicit slice, with guidance to stream a portion via bash (`sed -n` / `head -c`) instead, which
|
|
26
26
|
* never loads the whole file. */
|
|
27
27
|
export declare const SLICED_READ_MAX_BYTES: number;
|
|
28
|
-
/** The byte cap Edit refuses ABOVE
|
|
28
|
+
/** The byte cap Edit refuses ABOVE. CC stats the target before touching
|
|
29
29
|
* it and refuses with a formatted-size message when it exceeds this. Without the gate, Edit goes
|
|
30
30
|
* straight to a whole-file `readBinaryFile` (twice: the `old_string:""` full-overwrite branch and the
|
|
31
31
|
* normal find/replace branch), so a multi-GB target is an unguarded OOM lever an ordinary Edit call
|
|
32
32
|
* can pull. The shape is Read's: a pre-read `env.fileInfo` stat plus a post-read TOCTOU recheck
|
|
33
33
|
* ({@link SLICED_READ_MAX_BYTES} above). */
|
|
34
34
|
export declare const MAX_EDIT_BYTES: number;
|
|
35
|
-
/** `Edit`'s human-readable byte-count formatter (
|
|
35
|
+
/** `Edit`'s human-readable byte-count formatter (bytes below 1KB, else
|
|
36
36
|
* KB/MB/GB with one decimal, trailing ".0" stripped). */
|
|
37
37
|
export declare function formatByteSize(n: number): string;
|
|
38
38
|
/** Node's own string-length ceiling (`buffer.constants.MAX_STRING_LENGTH` — ~512MiB on V8/Node 24)
|
|
@@ -103,7 +103,7 @@ export interface RecordedEdit {
|
|
|
103
103
|
export declare function applyRecordedEdit(text: string, edit: RecordedEdit): string;
|
|
104
104
|
/** Render the read-before-edit refusal, appending the slice/bash escape hatch when the target is over
|
|
105
105
|
* the Read byte cap — a bare "read it first" is un-followable there (a default whole-file Read
|
|
106
|
-
* refuses such files). Best-effort: an un-stattable file keeps the bare
|
|
106
|
+
* refuses such files). Best-effort: an un-stattable file keeps the bare refusal.
|
|
107
107
|
*
|
|
108
108
|
* `fallbackHint` is a caller-supplied parenthetical for the case NO branch below diagnosed anything
|
|
109
109
|
* (all three writing tools pass {@link READ_REFUSED_ESCAPE_HINT} — the Read-refuses-this-file
|
|
@@ -332,7 +332,7 @@ export declare function createShellOverflowSpoolFence(env: ExecutionEnv): (path:
|
|
|
332
332
|
* executable. Full `bash` keeps the precise form.
|
|
333
333
|
*/
|
|
334
334
|
export declare function shellRecoveryHint(path: string, readOnly: boolean | undefined): string;
|
|
335
|
-
/**
|
|
335
|
+
/** Edit/Write success trailer — appended to every Edit/Write success message
|
|
336
336
|
* (NOT NotebookEdit — CC ships it without the trailer). */
|
|
337
337
|
export declare const FILE_STATE_TRAILER = " (file state is current in your context \u2014 no need to Read it back)";
|
|
338
338
|
export declare const CWD_SENTINEL = "__cc_cwd_9f2c1b__";
|
|
@@ -383,11 +383,11 @@ export declare function ipynbRedirect(toolName: string, path: string): string |
|
|
|
383
383
|
* ends in "\n". Behavior is identical for content WITHOUT a trailing newline. Shared by read_file's
|
|
384
384
|
* `total`, edit_file/write_file's "N lines" report, and the persisted ReadFileState.totalLines. */
|
|
385
385
|
export declare function countLines(s: string): number;
|
|
386
|
-
/**
|
|
386
|
+
/** The reminder served when a DEFAULT whole-file Read hits a startup-seeded,
|
|
387
387
|
* unchanged file. `filePath` is the CANONICAL key (CC passes the resolved full path, matching the
|
|
388
388
|
* `Contents of <path>` header its context seeding emits — deployments seeding files should title the
|
|
389
389
|
* injected block the same way so the back-reference lands). Locked verbatim by test: the BODY and
|
|
390
|
-
* close tag stay
|
|
390
|
+
* close tag stay fixed; the open tag alone is rendered by the mint home and carries the session
|
|
391
391
|
* mark when one is threaded (the recorded wire-form divergence). */
|
|
392
392
|
export declare function seededFileUnchangedReminder(filePath: string, mark?: string): string;
|
|
393
393
|
/**
|
|
@@ -404,7 +404,7 @@ export declare function seededFileUnchangedReminder(filePath: string, mark?: str
|
|
|
404
404
|
*/
|
|
405
405
|
export declare function isReadDedupStubResult(resultText: string): boolean;
|
|
406
406
|
/** Pre-seed the hands' read state for a file whose FULL, disk-verbatim text was injected into the
|
|
407
|
-
* model's context at startup (
|
|
407
|
+
* model's context at startup (`seededFromContext` seeding of the memory preload; sema:
|
|
408
408
|
* ProjectMemoryLoad.seededFiles → prepare-task).
|
|
409
409
|
* `content` MUST be the file's exact disk text at load time — the Read tool's seeded dedup treats a
|
|
410
410
|
* hash match as "unchanged"; a truncated/annotated variant must NOT be seeded (CC exempts those via
|
|
@@ -505,7 +505,7 @@ export type ReadFileStateShrink =
|
|
|
505
505
|
transmissions: ReadonlyArray<string>;
|
|
506
506
|
};
|
|
507
507
|
export declare function applyContextShrinkToReadFileState(state: ReadFileState, shrink: ReadFileStateShrink): void;
|
|
508
|
-
/**
|
|
508
|
+
/** The ENOENT error body for a
|
|
509
509
|
* missing Read/Edit target — `File does not exist. Note: your current working directory is <cwd>.`
|
|
510
510
|
* plus a `Did you mean <sibling>?` correction when the parent directory holds a near-name (case
|
|
511
511
|
* variant / same stem different extension — the high-frequency self-heal path). Best-effort: a
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* gh rate-limit hint
|
|
2
|
+
* gh rate-limit hint.
|
|
3
3
|
*
|
|
4
4
|
* CC appends a one-shot <system-reminder> to a FOREGROUND Bash result when a `gh` invocation hits the
|
|
5
5
|
* GitHub API rate limit, so the model sleeps/schedules instead of hammering retries. The command gate,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ImageContent } from "../../internal/llm.js";
|
|
2
2
|
/**
|
|
3
|
-
* The Read tool's Jupyter-notebook projection: `.ipynb` is rendered as cells with outputs (
|
|
3
|
+
* The Read tool's Jupyter-notebook projection: `.ipynb` is rendered as cells with outputs (reference
|
|
4
4
|
* parity), never as raw JSON text. Raw-JSON rendering lets a notebook's base64 outputs overflow the
|
|
5
5
|
* Read token cap, auto-paginate into an `isPartialView` entry, and thereby lock NotebookEdit out via
|
|
6
6
|
* the requireRead gate — with the marker's own offset/limit hint pointing at a range that itself
|
|
@@ -80,7 +80,7 @@ export interface NotebookRender {
|
|
|
80
80
|
imageChars: number;
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
83
|
+
* Render projected cells to content blocks. Tag shape is the reference's, including
|
|
84
84
|
* the deliberately malformed closing tag `</cell id="X">`; `<cell_type>` only when not code,
|
|
85
85
|
* `<language>` only for code cells whose language !== "python". Output text rides with a leading "\n"
|
|
86
86
|
* and adjacent text blocks merge with "\n", so an all-text notebook collapses to a single text block.
|
|
@@ -115,7 +115,7 @@ export declare function ruleHeadParts(rows: readonly Pick<PathRuleDenyRow, "head
|
|
|
115
115
|
* below that part. Every part, not the head alone: a link inside the rule's literal prefix that is re-pointed after the
|
|
116
116
|
* rows were placed still meets the row through the parts above it. One rule for every row form and every judge (the
|
|
117
117
|
* gate's lanes and the deny tables): the reference compiles the same "physical twin" of every deny / ask rule's literal
|
|
118
|
-
* prefix
|
|
118
|
+
* prefix. `leads` is the leg's resolution of each part (absent or
|
|
119
119
|
* `undefined` = no twin there); a part that only extends its parent's resolution adds no row. A twin is the row's own
|
|
120
120
|
* kind (it keeps every member but the head), so a judgment reports the rule the twin stands for.
|
|
121
121
|
*/
|
|
@@ -416,12 +416,32 @@ export declare function activeReadDenyBuiltinTiers(config?: ReadDenyBuiltinConfi
|
|
|
416
416
|
* renders "what COULD be switched on".
|
|
417
417
|
*/
|
|
418
418
|
export declare const READ_FACE_DEFAULT_DENY_ENTRIES: readonly ReadDenyEntry[];
|
|
419
|
+
/**
|
|
420
|
+
* The fold the "unicode" mode applies — the one a RegExp `i` flag without `u` applies, one UTF-16 code unit at a time: the
|
|
421
|
+
* upper-case mapping when it is a single unit and does not step from a non-ASCII unit down into ASCII (`ı` and `ſ` stay
|
|
422
|
+
* themselves, `ß` stays `ß`). Both sides of a comparison go through it.
|
|
423
|
+
*/
|
|
424
|
+
export declare function ignoreCaseFold(s: string): string;
|
|
425
|
+
/** How a compiled pattern compares: `none` byte for byte; `ascii` and `unicode` through the fold of that name, both sides —
|
|
426
|
+
* the pattern's side at compile, the segments' side by whoever tests (once per path: {@link segmentReadingsOf}). */
|
|
427
|
+
export type SegmentFold = "none" | "ascii" | "unicode";
|
|
428
|
+
/** The function that folds a string as each fold folds — the one place that says which function that is (the pattern at compile,
|
|
429
|
+
* a path's segments in the readings, an anchor's segments all read it, at the time they fold). */
|
|
430
|
+
export declare const SEGMENT_FOLDS: Record<SegmentFold, (s: string) => string>;
|
|
431
|
+
/** One compiled segment of a pattern: `*` stands for any run of characters but a separator, every other character for itself. */
|
|
432
|
+
export interface SegmentMatcher {
|
|
433
|
+
/** Does the whole of `segment` match? The segment is folded as the pattern's fold folds ({@link CompiledSegmentPattern.fold}) —
|
|
434
|
+
* by the caller; a segment that holds a separator never matches. */
|
|
435
|
+
test(segment: string): boolean;
|
|
436
|
+
/** The pattern is stars only: it matches every one segment. */
|
|
437
|
+
readonly anything: boolean;
|
|
438
|
+
}
|
|
419
439
|
/** A compiled segment-run pattern (shared engine — the write guard delegates here too). */
|
|
420
440
|
export interface CompiledSegmentPattern {
|
|
421
441
|
raw: string;
|
|
422
|
-
segments:
|
|
423
|
-
/** Fold BOTH sides
|
|
424
|
-
|
|
442
|
+
segments: SegmentMatcher[];
|
|
443
|
+
/** Fold BOTH sides before testing: compile folded the pattern side; the segments tested are folded the same way. */
|
|
444
|
+
fold: SegmentFold;
|
|
425
445
|
/** The segment lists of the directories the run is ANCHORED at (folded as the pattern folds): the run must start
|
|
426
446
|
* right after one of them. Absent = the run matches anywhere. */
|
|
427
447
|
anchors?: readonly (readonly string[])[];
|
|
@@ -437,12 +457,14 @@ export interface CompiledSegmentPattern {
|
|
|
437
457
|
* Compile one segment-glob pattern (shared engine). `fold`:
|
|
438
458
|
* · "none" — byte-exact segments;
|
|
439
459
|
* · "ascii" — ASCII-case-insensitive (deny-set contract);
|
|
440
|
-
* · "unicode" — RegExp `i` flag (the write guard's historical host-keyed
|
|
441
|
-
*
|
|
460
|
+
* · "unicode" — the fold a RegExp `i` flag applies, {@link ignoreCaseFold} (the write guard's historical host-keyed
|
|
461
|
+
* behavior — kept for it answer for answer; NOT used by the deny set).
|
|
462
|
+
* The pattern is folded here, once; the segments a row is tested on are folded by whoever tests, once per path
|
|
463
|
+
* ({@link segmentReadingsOf}) — never once per row per test.
|
|
442
464
|
* Returns null when the pattern reduces to zero segments — the CALLER owns its loud path (the two
|
|
443
465
|
* consumers refuse with their own surface-specific texts).
|
|
444
466
|
*/
|
|
445
|
-
export declare function compileSegmentPattern(raw: string, fold:
|
|
467
|
+
export declare function compileSegmentPattern(raw: string, fold: SegmentFold): CompiledSegmentPattern | null;
|
|
446
468
|
/**
|
|
447
469
|
* Does the path contain a compiled pattern as a CONTIGUOUS run of full path segments? (Shared engine:
|
|
448
470
|
* `.git/hooks` matches `/repo/.git/hooks/pre-commit`; `.ssh` matches any `.ssh` segment.) An ANCHORED pattern
|