@sema-agent/core 7.55.0 → 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 +513 -0
- package/dist/agents/cascade.js +1 -1
- package/dist/agents/cc-peer-directory.js +1 -0
- package/dist/agents/child-model-seat.d.ts +0 -11
- package/dist/agents/child-model-seat.js +0 -3
- package/dist/agents/list-agents-tool.d.ts +3 -1
- package/dist/agents/list-agents-tool.js +7 -7
- package/dist/agents/peer-directory.d.ts +22 -4
- package/dist/agents/peer-directory.js +24 -2
- package/dist/agents/peer-session-drain.js +2 -2
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/send-message-tool.js +4 -4
- package/dist/agents/subagent.d.ts +6 -4
- package/dist/agents/subagent.js +64 -60
- package/dist/agents/tool-filter.d.ts +7 -5
- package/dist/agents/tool-filter.js +12 -9
- package/dist/agents/verify.d.ts +3 -2
- package/dist/agents/verify.js +3 -3
- package/dist/brain/anthropic.js +30 -73
- 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 +2 -8
- package/dist/brain/model-presets.js +1 -6
- package/dist/brain/open-responses.js +13 -26
- package/dist/brain/openai.js +14 -87
- package/dist/brain/reasoning-request.d.ts +96 -0
- package/dist/brain/reasoning-request.js +174 -0
- package/dist/brain/reasoning.d.ts +11 -11
- package/dist/brain/reasoning.js +4 -3
- package/dist/brain/request-params.d.ts +7 -4
- package/dist/brain/request-params.js +7 -4
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/core/a2a.d.ts +2 -1
- package/dist/core/a2a.js +19 -13
- package/dist/core/agent-definition.d.ts +10 -0
- package/dist/core/allow-entry.d.ts +20 -13
- package/dist/core/allow-entry.js +26 -22
- package/dist/core/allow-rule-shadow.d.ts +3 -3
- package/dist/core/ask-origin.d.ts +64 -18
- package/dist/core/ask-origin.js +63 -23
- package/dist/core/ask-question.d.ts +51 -8
- package/dist/core/ask-question.js +3 -4
- package/dist/core/ask-unresolvable-notice.d.ts +8 -3
- package/dist/core/ask-unresolvable-notice.js +16 -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 +13 -1
- package/dist/core/checkpoint-requirements.js +4 -0
- package/dist/core/checkpoint-store.d.ts +88 -24
- package/dist/core/checkpoint-store.js +24 -9
- package/dist/core/cross-boundary-taint.d.ts +6 -5
- package/dist/core/cross-boundary-taint.js +1 -3
- package/dist/core/decision-receipt.d.ts +37 -3
- package/dist/core/decision-receipt.js +17 -17
- package/dist/core/delegation-not-started.d.ts +6 -0
- package/dist/core/delegation-not-started.js +17 -0
- 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 +30 -11
- package/dist/core/file-history-store.d.ts +90 -14
- package/dist/core/file-history-store.js +23 -15
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +22 -10
- package/dist/core/gate-lanes.js +73 -64
- package/dist/core/gate-outcome.d.ts +26 -5
- package/dist/core/gate-outcome.js +26 -0
- package/dist/core/governance-codes.d.ts +5 -1
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/hooks.d.ts +17 -16
- 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 +38 -3
- package/dist/core/host-target.js +38 -5
- package/dist/core/mcp.d.ts +5 -1
- package/dist/core/mcp.js +67 -41
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- 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/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 +32 -38
- package/dist/core/namespaced-rule-name.js +29 -36
- package/dist/core/parent-spec-seat.d.ts +6 -1
- package/dist/core/parent-spec-seat.js +2 -0
- package/dist/core/park-selfcheck.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +19 -0
- package/dist/core/permission-rule-consent.js +116 -26
- package/dist/core/permission-rule-model.d.ts +14 -3
- package/dist/core/permission-rule-model.js +39 -24
- 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 +5 -2
- package/dist/core/permission-rule-provider.js +41 -11
- package/dist/core/permission-rule-store.d.ts +3 -2
- package/dist/core/permission-rule-store.js +11 -2
- package/dist/core/permission-rule-sync.js +3 -2
- 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 +4 -4
- package/dist/core/permission-rules.js +11 -20
- package/dist/core/persisted-rule-arms.d.ts +2 -2
- package/dist/core/persisted-rule-arms.js +10 -12
- 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/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 +28 -1
- package/dist/core/roles.js +31 -19
- package/dist/core/rule-lane-reads.d.ts +20 -15
- package/dist/core/rule-lane-reads.js +45 -17
- package/dist/core/rule-owner.d.ts +3 -3
- package/dist/core/rule-owner.js +3 -2
- package/dist/core/runner/announce-once-ledger.d.ts +14 -0
- package/dist/core/runner/announce-once-ledger.js +5 -0
- package/dist/core/runner/assemble-result.d.ts +1 -0
- 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 +16 -4
- package/dist/core/runner/caller-roster.js +33 -6
- 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 +7 -9
- package/dist/core/runner/classifier-ladder.js +3 -3
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +28 -25
- package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
- package/dist/core/runner/cross-boundary-lane.js +40 -27
- package/dist/core/runner/denial-limit-arms.d.ts +2 -2
- package/dist/core/runner/denial-limit-arms.js +1 -1
- 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 +3 -3
- package/dist/core/runner/gate-exit.js +4 -3
- package/dist/core/runner/image.d.ts +7 -17
- package/dist/core/runner/image.js +9 -60
- package/dist/core/runner/permission-rule-lanes.d.ts +4 -4
- package/dist/core/runner/permission-rule-lanes.js +26 -10
- package/dist/core/runner/person-path-rows.d.ts +12 -9
- package/dist/core/runner/person-path-rows.js +18 -7
- 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 +4 -3
- package/dist/core/runner/prepare-config-doors.d.ts +29 -38
- package/dist/core/runner/prepare-config-doors.js +42 -25
- 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-file-history.d.ts +48 -8
- package/dist/core/runner/prepare-file-history.js +7 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
- package/dist/core/runner/prepare-gate-stations.js +10 -1
- 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 +6 -3
- package/dist/core/runner/prepare-inherited-gate.js +5 -3
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.js +5 -5
- package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
- package/dist/core/runner/prepare-policy-chain.js +65 -72
- 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 +3 -5
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
- package/dist/core/runner/prepare-protocol-tools.js +3 -3
- package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
- package/dist/core/runner/prepare-safety-scan.js +0 -17
- 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 +29 -20
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +20 -16
- 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 +6 -2
- 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/retired-runner-deps.js +1 -0
- 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 -1
- 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-harness-handlers.js +12 -4
- package/dist/core/runner/run-leg.d.ts +1 -1
- package/dist/core/runner/run-leg.js +30 -18
- package/dist/core/runner/run-settle-and-teardown.js +2 -1
- package/dist/core/runner/run-turn-boundary.js +1 -10
- 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.js +4 -3
- 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/skills-seat.js +6 -2
- package/dist/core/runner/stream-settle-backstop.js +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -7
- package/dist/core/runner/synthetic-tools.d.ts +6 -0
- package/dist/core/runner/synthetic-tools.js +4 -1
- package/dist/core/runner/tool-disclosure.d.ts +10 -12
- package/dist/core/runner/tool-disclosure.js +1 -3
- 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-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/turn-attachments.d.ts +33 -15
- package/dist/core/runner/turn-attachments.js +62 -37
- package/dist/core/runner-deps.d.ts +5 -5
- 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 +11 -3
- 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/session-policy-store.d.ts +27 -15
- package/dist/core/session-policy-store.js +156 -36
- package/dist/core/session-store.d.ts +29 -10
- package/dist/core/session-store.js +51 -19
- package/dist/core/session.d.ts +82 -16
- package/dist/core/session.js +53 -0
- 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.js +10 -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 +140 -2
- package/dist/core/store-contracts/file-history-store-contract.js +31 -1
- 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-repo-contract.js +51 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
- package/dist/core/store-contracts/session-store-contract.js +150 -14
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/synthetic-read-verdict.js +3 -3
- package/dist/core/task-event.d.ts +32 -4
- package/dist/core/task-notification.d.ts +16 -12
- package/dist/core/task-registry.d.ts +9 -0
- package/dist/core/task-registry.js +11 -1
- package/dist/core/task-result.d.ts +18 -0
- package/dist/core/task-spec.d.ts +18 -13
- package/dist/core/tighten-task-spec.js +2 -1
- package/dist/core/tool-catalog-entries.d.ts +17 -0
- package/dist/core/tool-catalog-entries.js +13 -2
- package/dist/core/tool-check-reading.d.ts +11 -0
- package/dist/core/tool-check-reading.js +11 -6
- package/dist/core/tool-model-gate.d.ts +2 -2
- package/dist/core/tool-name-aliases.d.ts +16 -16
- package/dist/core/tool-name-aliases.js +13 -19
- package/dist/core/tool-name-readings.d.ts +5 -35
- package/dist/core/tool-name-readings.js +1 -9
- package/dist/core/tool-policy.d.ts +68 -198
- package/dist/core/tool-policy.js +149 -198
- package/dist/core/tool-result-store.js +3 -0
- package/dist/core/tool-roster.d.ts +14 -19
- package/dist/core/tool-roster.js +11 -44
- package/dist/core/tool-spec-members.js +7 -2
- package/dist/core/tool-spec.d.ts +19 -11
- package/dist/core/tools.js +49 -9
- package/dist/core/trace.d.ts +2 -2
- package/dist/core/types.d.ts +1 -1
- package/dist/core/user-attachment.d.ts +8 -1
- package/dist/core/user-attachment.js +64 -4
- package/dist/core/wiring-manifest.d.ts +9 -0
- package/dist/core/wiring-manifest.js +1 -0
- package/dist/core/workflow-journal-store.js +1 -1
- package/dist/engine/compaction/compaction.js +3 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
- package/dist/engine/execution-env/node-execution-env.js +11 -2
- package/dist/engine/harness/agent-harness.d.ts +25 -1
- package/dist/engine/harness/agent-harness.js +54 -7
- package/dist/engine/harness/types.d.ts +29 -2
- package/dist/engine/llm/types.d.ts +28 -11
- package/dist/engine/loop/agent-loop.d.ts +22 -0
- package/dist/engine/loop/agent-loop.js +16 -26
- package/dist/engine/loop/types.d.ts +16 -6
- package/dist/engine/session/memory-repo.d.ts +9 -2
- package/dist/engine/session/memory-repo.js +11 -1
- package/dist/engine/session/repo-utils.d.ts +6 -5
- package/dist/engine/session/repo-utils.js +14 -6
- package/dist/index.d.ts +22 -10
- package/dist/index.js +15 -7
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/llm.d.ts +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +6 -4
- package/dist/orchestration/run-workflow-tool.js +5 -3
- package/dist/orchestration/workflow.d.ts +3 -0
- package/dist/orchestration/workflow.js +36 -18
- 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 +1 -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 +37 -3
- package/dist/prompt-assembly/tool-catalog.js +114 -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/scenarios/full-body.d.ts +11 -11
- package/dist/scenarios/full-body.js +4 -3
- package/dist/shell/lex.js +10 -1
- package/dist/stores/file/adoption/adopt.js +4 -3
- package/dist/stores/file/adoption/marker.js +3 -2
- package/dist/stores/file/checkpoint-store.d.ts +21 -0
- package/dist/stores/file/checkpoint-store.js +38 -6
- package/dist/stores/file/file-history-store.js +6 -7
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/permission-rule-adopt.js +4 -3
- package/dist/stores/file/permission-rule-store.js +11 -5
- package/dist/stores/file/session-store.d.ts +29 -6
- package/dist/stores/file/session-store.js +42 -50
- package/dist/tools/artifact/artifact-tool.js +3 -2
- 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/fs-bash.js +5 -5
- 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/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/removal-targets.d.ts +17 -7
- package/dist/tools/fs/removal-targets.js +47 -20
- package/dist/tools/fs/search.d.ts +10 -0
- 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 +6 -19
- 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-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/todo.js +63 -63
- package/dist/tools/web.d.ts +19 -14
- package/dist/tools/web.js +38 -55
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +143 -5
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
|
@@ -9,7 +9,7 @@ const ARTIFACT_ACTION_LEGS = {
|
|
|
9
9
|
"local-stub": { publish: ["env"], list: [], read: [], list_files: [], read_file: [] },
|
|
10
10
|
};
|
|
11
11
|
import { ARTIFACT_TOOL_NAME, mountRuleFace, toolFace } from "../../core/tool-catalog-entries.js";
|
|
12
|
-
import { resolveAsk } from "../../core/tool-policy.js";
|
|
12
|
+
import { attest, 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";
|
|
15
15
|
import { errorResult } from "../../core/tools.js";
|
|
@@ -328,7 +328,8 @@ export function createArtifactTool(opts) {
|
|
|
328
328
|
if (sharedReadApproved.has(url))
|
|
329
329
|
return Promise.resolve({ ok: true });
|
|
330
330
|
if (permissionMode !== undefined) {
|
|
331
|
-
const
|
|
331
|
+
const call = { toolCallId: ctx.toolCallId, toolName: ARTIFACT_TOOL_NAME };
|
|
332
|
+
const verdict = arbitrateByMode(permissionMode(), classifyAsk(attest({ action: "ask", requiresRealApproval: true }, call, { guards: ["artifact_shared_read"] }), { call, contentQuestion: false, markedUnresolvable: false, org: undefined, tightened: undefined, mandateMarks: {} }));
|
|
332
333
|
if (verdict.kind === "released") {
|
|
333
334
|
if (!releaseAnnounced && onNotice !== undefined) {
|
|
334
335
|
releaseAnnounced = true;
|
|
@@ -39,14 +39,27 @@ export declare const LOOP_LIST_HEADS: ReadonlySet<string>;
|
|
|
39
39
|
* over control words and earlier assignments re-traces). One fact, two readers that must agree.
|
|
40
40
|
*/
|
|
41
41
|
export declare function isLeadingAssignmentWord(words: readonly LexedWord[], i: number): boolean;
|
|
42
|
-
export declare const PROGRAM_POSITION_REFUSAL_KINDS: readonly ["option_at_program_position", "control_syntax_at_program_position"];
|
|
42
|
+
export declare const PROGRAM_POSITION_REFUSAL_KINDS: readonly ["option_at_program_position", "control_syntax_at_program_position", "wildcard_program_word"];
|
|
43
43
|
export type ProgramPositionRefusalKind = (typeof PROGRAM_POSITION_REFUSAL_KINDS)[number];
|
|
44
44
|
/** Why the program could not be read — a closed set, each member minted into one sentence. `owner` is the word
|
|
45
45
|
* that took the offending token: the control word or the first launcher of the chain. */
|
|
46
|
-
export type ProgramPositionRefusal =
|
|
46
|
+
export type ProgramPositionRefusal =
|
|
47
|
+
/** `endedBy`: the launcher whose bare `--` ended its options before this word — the word is then no option of anyone's
|
|
48
|
+
* but a name spelled like one (`env -- -i ls` runs a program named `-i`), and the sentence says that, not "the option". */
|
|
49
|
+
{
|
|
47
50
|
readonly kind: "option_at_program_position";
|
|
48
51
|
readonly owner: string;
|
|
49
52
|
readonly option: string;
|
|
53
|
+
readonly endedBy?: string;
|
|
54
|
+
}
|
|
55
|
+
/** The program word carries an unquoted glob (`s[h]`, `s*h`, `./c?t`): the shell expands it against the filesystem,
|
|
56
|
+
* so which program runs — a shell among them — is not readable from the text (`touch sh; s[h] -c '…'`). `word` is the
|
|
57
|
+
* word as written, `at` its argv index (the words AFTER it are still handed over, so a deny operand still refuses).
|
|
58
|
+
* Both faces ask, the same as any unreadable program position. */
|
|
59
|
+
| {
|
|
60
|
+
readonly kind: "wildcard_program_word";
|
|
61
|
+
readonly word: string;
|
|
62
|
+
readonly at: number;
|
|
50
63
|
} | {
|
|
51
64
|
readonly kind: "control_syntax_at_program_position";
|
|
52
65
|
readonly owner: string;
|
|
@@ -130,3 +143,7 @@ export declare function programPositionRunsShell(pos: ProgramPosition, runsShell
|
|
|
130
143
|
export declare function shellScanDeclineOf(pos: ProgramPosition, acceptsStreamTarget: (basename: string) => boolean): ShellScanDecline | undefined;
|
|
131
144
|
/** ONE sentence per refusal kind, minted here and nowhere else. */
|
|
132
145
|
export declare function programPositionRefusalSentence(refusal: ProgramPositionRefusal): string;
|
|
146
|
+
/** The sentence a segment whose program the walk DECLINED carries, read off the segment's text — the program-position reader's own
|
|
147
|
+
* refusal, the stream fact, or that no program could be named: the read station's account of the segment and the removal guard's
|
|
148
|
+
* are this one sentence. */
|
|
149
|
+
export declare function declinedProgramSentence(text: string): string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SHELL_CONTROL_PREFIXES } from "../../shell/lex.js";
|
|
1
|
+
import { SHELL_CONTROL_PREFIXES, argvOf, lexShellText } from "../../shell/lex.js";
|
|
2
2
|
import { shellWordsOf } from "../../shell/shell-words.js";
|
|
3
3
|
import { BLOCK_WORD_NAMES, LAUNCHER_NAMES, feedsArgvFromStdin, launcherOptionMovesBase, launcherOptionQueries, launcherOptionStep, launcherRunsShell, programRow, selectedOptions, streamDefaultProgram } from "./program-read-model.js";
|
|
4
4
|
export const NOT_AUTO_ALLOWED = "— not auto-allowed";
|
|
@@ -31,7 +31,7 @@ function launcherRowOf(name) {
|
|
|
31
31
|
const row = programRow(name);
|
|
32
32
|
return row?.launcher !== undefined ? row : undefined;
|
|
33
33
|
}
|
|
34
|
-
function pastLauncherOptions(launcher, folded, i, moved, queried) {
|
|
34
|
+
function pastLauncherOptions(launcher, folded, i, moved, queried, ended) {
|
|
35
35
|
const row = launcherRowOf(launcher);
|
|
36
36
|
if (row === undefined)
|
|
37
37
|
return i;
|
|
@@ -53,14 +53,19 @@ function pastLauncherOptions(launcher, folded, i, moved, queried) {
|
|
|
53
53
|
if (launcherOptionQueries(row, tok))
|
|
54
54
|
queried?.();
|
|
55
55
|
i += step;
|
|
56
|
-
if (tok === "--")
|
|
56
|
+
if (tok === "--") {
|
|
57
|
+
ended?.();
|
|
57
58
|
return i;
|
|
59
|
+
}
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
|
-
export const PROGRAM_POSITION_REFUSAL_KINDS = Object.freeze(["option_at_program_position", "control_syntax_at_program_position"]);
|
|
62
|
+
export const PROGRAM_POSITION_REFUSAL_KINDS = Object.freeze(["option_at_program_position", "control_syntax_at_program_position", "wildcard_program_word"]);
|
|
61
63
|
export function readProgramPosition(words) {
|
|
62
64
|
const folded = words.map((w) => w.folded);
|
|
63
65
|
const controlWords = [];
|
|
66
|
+
const ended = { by: undefined };
|
|
67
|
+
const endsOptions = (name) => () => { ended.by = name; };
|
|
68
|
+
const optionShaped = (owner, option) => ({ kind: "option_at_program_position", owner, option, ...(ended.by !== undefined ? { endedBy: ended.by } : {}) });
|
|
64
69
|
let i = 0;
|
|
65
70
|
while (i < folded.length && isBareControlWord(words, i, SHELL_CONTROL_PREFIXES)) {
|
|
66
71
|
const controlWord = folded[i];
|
|
@@ -68,6 +73,23 @@ export function readProgramPosition(words) {
|
|
|
68
73
|
i = pastLauncherOptions(controlWord, folded, i + 1);
|
|
69
74
|
}
|
|
70
75
|
const none = (written, assignments, refusal) => ({ controlWords, written, assignments, launchers: [], argvFromStdin: false, runsDefaultProgram: false, program: undefined, refusal, launcherMovesBase: false });
|
|
76
|
+
const globProgramRefusal = (idx) => {
|
|
77
|
+
let glob = false;
|
|
78
|
+
for (const p of words[idx].pieces) {
|
|
79
|
+
const k = p.expansion?.kind;
|
|
80
|
+
if (k === "process" || k === "brace")
|
|
81
|
+
return undefined;
|
|
82
|
+
if (k === "glob")
|
|
83
|
+
glob = true;
|
|
84
|
+
if (p.literal !== undefined) {
|
|
85
|
+
if (p.quotedBy === undefined && /[{}$`]/.test(p.literal))
|
|
86
|
+
return undefined;
|
|
87
|
+
if (p.quotedBy === '"' && /[$`]/.test(p.literal))
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return glob ? { kind: "wildcard_program_word", word: folded[idx], at: idx } : undefined;
|
|
92
|
+
};
|
|
71
93
|
if (i >= folded.length)
|
|
72
94
|
return none(undefined, []);
|
|
73
95
|
const written = i;
|
|
@@ -82,9 +104,12 @@ export function readProgramPosition(words) {
|
|
|
82
104
|
const basename = programBasename(head);
|
|
83
105
|
if (basename.startsWith("-") && basename !== "-") {
|
|
84
106
|
const owner = controlWords.length > 0 ? folded[controlWords[controlWords.length - 1]] : head;
|
|
85
|
-
return none(written, assignments,
|
|
107
|
+
return none(written, assignments, optionShaped(owner, head));
|
|
86
108
|
}
|
|
87
109
|
if (!LAUNCHER_NAMES.has(basename)) {
|
|
110
|
+
const glob = globProgramRefusal(i);
|
|
111
|
+
if (glob !== undefined)
|
|
112
|
+
return none(written, assignments, glob);
|
|
88
113
|
return { controlWords, written, assignments, launchers: [], argvFromStdin: false, runsDefaultProgram: false, program: { index: i, name: head, basename }, refusal: undefined, launcherMovesBase: false };
|
|
89
114
|
}
|
|
90
115
|
const launchers = [{ index: i, name: basename }];
|
|
@@ -107,7 +132,7 @@ export function readProgramPosition(words) {
|
|
|
107
132
|
return { controlWords, written, assignments, launchers, argvFromStdin, runsDefaultProgram, ...(runsDefaultProgram && reentryDefault !== undefined ? { defaultProgram: reentryDefault } : {}), program, refusal, launcherMovesBase };
|
|
108
133
|
};
|
|
109
134
|
const selectsShell = (l, end) => selectedOptions(launcherRowOf(l.name), folded.slice(l.index + 1, end)).some((o) => o.mode === "interactive");
|
|
110
|
-
const first = pastLauncherOptions(basename, folded, i + 1, moved, queried);
|
|
135
|
+
const first = pastLauncherOptions(basename, folded, i + 1, moved, queried, endsOptions(basename));
|
|
111
136
|
if (looksUp)
|
|
112
137
|
return chain(undefined);
|
|
113
138
|
for (let j = first; j < folded.length; j++) {
|
|
@@ -127,6 +152,7 @@ export function readProgramPosition(words) {
|
|
|
127
152
|
reentryDefault = streamDefaultProgram(wordBasename);
|
|
128
153
|
lastRow = undefined;
|
|
129
154
|
owedOperands = 0;
|
|
155
|
+
ended.by = undefined;
|
|
130
156
|
continue;
|
|
131
157
|
}
|
|
132
158
|
if (LAUNCHER_NAMES.has(wordBasename)) {
|
|
@@ -135,16 +161,20 @@ export function readProgramPosition(words) {
|
|
|
135
161
|
if (launcherRunsShell(launcherRowOf(wordBasename), folded.slice(j + 1)))
|
|
136
162
|
return chain(undefined, shellRefusal(j, j + 1));
|
|
137
163
|
owedOperands = lastRow?.requiredOperands ?? 0;
|
|
138
|
-
|
|
164
|
+
ended.by = undefined;
|
|
165
|
+
j = pastLauncherOptions(wordBasename, folded, j + 1, moved, queried, endsOptions(wordBasename)) - 1;
|
|
139
166
|
if (looksUp)
|
|
140
167
|
return chain(undefined);
|
|
141
168
|
continue;
|
|
142
169
|
}
|
|
143
170
|
if (t.startsWith("-"))
|
|
144
|
-
return chain(undefined,
|
|
171
|
+
return chain(undefined, optionShaped(owner, t));
|
|
145
172
|
if (SHELL_CONTROL_PREFIXES.has(wordBasename) || BLOCK_WORD_NAMES.has(wordBasename)) {
|
|
146
173
|
return chain(undefined, { kind: "control_syntax_at_program_position", owner, word: wordBasename });
|
|
147
174
|
}
|
|
175
|
+
const glob = globProgramRefusal(j);
|
|
176
|
+
if (glob !== undefined)
|
|
177
|
+
return chain(undefined, glob);
|
|
148
178
|
return chain({ index: j, name: t, basename: wordBasename });
|
|
149
179
|
}
|
|
150
180
|
const last = launchers[launchers.length - 1];
|
|
@@ -173,12 +203,29 @@ export function shellScanDeclineOf(pos, acceptsStreamTarget) {
|
|
|
173
203
|
export function programPositionRefusalSentence(refusal) {
|
|
174
204
|
switch (refusal.kind) {
|
|
175
205
|
case "option_at_program_position":
|
|
176
|
-
return
|
|
206
|
+
return refusal.endedBy !== undefined
|
|
207
|
+
? `"${refusal.endedBy} --" ends the options, and "${refusal.option}" after it is a name spelled like an option where the program it runs would be — which program runs is not read from such a word ${NOT_AUTO_ALLOWED}`
|
|
208
|
+
: `"${refusal.owner}" is given the option "${refusal.option}" where the program it runs would be — which program runs is not readable without that word's option table ${NOT_AUTO_ALLOWED}`;
|
|
177
209
|
case "control_syntax_at_program_position":
|
|
178
210
|
return `"${refusal.owner}" is given shell control syntax ("${refusal.word}") where the program it runs would be ${NOT_AUTO_ALLOWED}`;
|
|
211
|
+
case "wildcard_program_word":
|
|
212
|
+
return `the program word "${refusal.word}" carries an unquoted filename pattern, so the shell expands it against the filesystem and which program runs is not readable from the text ${NOT_AUTO_ALLOWED}`;
|
|
179
213
|
default: {
|
|
180
214
|
const exhaustive = refusal;
|
|
181
215
|
return exhaustive;
|
|
182
216
|
}
|
|
183
217
|
}
|
|
184
218
|
}
|
|
219
|
+
export function declinedProgramSentence(text) {
|
|
220
|
+
const lexed = lexShellText(text);
|
|
221
|
+
if (!("reject" in lexed) && lexed.segments[0] !== undefined) {
|
|
222
|
+
const pos = readProgramPosition(argvOf(lexed.segments[0]));
|
|
223
|
+
if (pos.refusal !== undefined)
|
|
224
|
+
return programPositionRefusalSentence(pos.refusal);
|
|
225
|
+
if (pos.argvFromStdin) {
|
|
226
|
+
const runs = pos.program?.basename ?? "the program it runs";
|
|
227
|
+
return `"${text.trim()}" hands ${runs} its operands on its standard input, which this station does not read ${NOT_AUTO_ALLOWED}`;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return `"${text.trim()}" runs a program this station cannot name ${NOT_AUTO_ALLOWED}`;
|
|
231
|
+
}
|
package/dist/tools/fs/fs-bash.js
CHANGED
|
@@ -21,6 +21,7 @@ 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";
|
|
24
|
+
import { patternKillRefusal } from "./pattern-kill-guard.js";
|
|
24
25
|
function shellCommandOf(args) {
|
|
25
26
|
const command = args?.command;
|
|
26
27
|
return typeof command === "string" ? command : undefined;
|
|
@@ -38,11 +39,10 @@ export function bashReversibilityProbe(allow, boundary) {
|
|
|
38
39
|
return { reversible: false };
|
|
39
40
|
const home = typeof boundary === "function" ? boundary() : boundary;
|
|
40
41
|
const fold = home?.homeDir !== undefined ? { homeDir: home.homeDir } : undefined;
|
|
41
|
-
|
|
42
|
+
const reason = classifyCompoundReadonlyDetailed(command, allowSet, fold).reason;
|
|
43
|
+
if (reason === undefined)
|
|
42
44
|
return { reversible: true };
|
|
43
|
-
|
|
44
|
-
return { reversible: true };
|
|
45
|
-
return { reversible: false };
|
|
45
|
+
return classifyBoundedReadonlyPollLoopDetailed(command, allowSet, fold).reason === undefined ? { reversible: true } : { reversible: false, reason };
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
export { FULL_SHELL_CONTRACT_ID } from "../../core/tool-catalog-entries.js";
|
|
@@ -585,7 +585,7 @@ export function createBashTool(env, rootCanonical, coAuthor = false, cwdRef = {
|
|
|
585
585
|
const timeoutRefusal = bashTimeoutArgRefusal(timeout, timeoutCaps);
|
|
586
586
|
if (timeoutRefusal !== undefined)
|
|
587
587
|
return errorResult(timeoutRefusal, { type: "bash_invalid_timeout", code: "bash_invalid_timeout" });
|
|
588
|
-
const refused = await taskOpts.shellReadAdmission?.("Bash", ctx.toolCallId, command, ctx.signal);
|
|
588
|
+
const refused = (await taskOpts.shellReadAdmission?.("Bash", ctx.toolCallId, command, ctx.signal)) ?? (await patternKillRefusal(command, env, cwdRef.current, ctx.signal));
|
|
589
589
|
if (refused !== undefined)
|
|
590
590
|
return refused;
|
|
591
591
|
if (run_in_background) {
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The matcher of the filesystem glob dialect: a token list is compiled to a small program, and a path is matched by walking
|
|
3
|
+
* it once, left to right, holding the SET of instructions that are live at the current position. An instruction is in the set
|
|
4
|
+
* at most once, so the cost of one test is at most the program's length times the path's length plus one, however many stars
|
|
5
|
+
* the pattern holds and however they are arranged — no expression is built from the pattern's text, so nothing backtracks and
|
|
6
|
+
* no pattern needs a cap. That product is a limit a pattern can reach on an ordinary path, when it keeps every instruction live at
|
|
7
|
+
* every place (a ring of empty alternatives does). The scratch it needs is two sets of the program's length, kept between tests for a
|
|
8
|
+
* program of up to 65 536 instructions (a longer program's is made for each test that gets past the two checks below and dropped: a
|
|
9
|
+
* cost of the program's length, whatever the path); a test whose threads all die at the first character costs what it touched, not
|
|
10
|
+
* the product of the two lengths. Two cheap checks come before the walk and only ever say "cannot match": a value that lacks a
|
|
11
|
+
* literal every match holds, or does not end with the literal the pattern ends on, is refused at once; inside the walk, a program
|
|
12
|
+
* that opens on a literal starts a thread only where that literal stands.
|
|
13
|
+
*
|
|
14
|
+
* It answers a different question from {@link wildcardMatch} (the permission-rule name glob), which is why the two are two
|
|
15
|
+
* engines and not one with a switch. The grammars differ:
|
|
16
|
+
*
|
|
17
|
+
* | construct | rule glob (`wildcardMatch`) | filesystem glob (this module) |
|
|
18
|
+
* | ------------------ | ----------------------------- | ----------------------------------------------------- |
|
|
19
|
+
* | `*` | any run, `/` included | any run of characters but `/` (`star`) |
|
|
20
|
+
* | `**` | the same as `*` | any run, `/` included (`globstar`) |
|
|
21
|
+
* | `?` | a literal | one character but `/` (`one`) |
|
|
22
|
+
* | `[abc]`, `[!a-c]` | literals | one character of the class (`class`) |
|
|
23
|
+
* | `{a,b}` | literals | one alternative of several (`alt`) |
|
|
24
|
+
* | where it may start | the whole value | the whole path, or any path segment (`anchor`) |
|
|
25
|
+
*
|
|
26
|
+
* Each site that reads such a glob (the search tools' `pattern` / `glob` arguments and `.gitignore` lines, the shell read
|
|
27
|
+
* station's expansion of a command word) parses its own spelling into tokens — what a spelling MEANS stays with the site — and
|
|
28
|
+
* this module is the one place that matches them.
|
|
29
|
+
*
|
|
30
|
+
* Lengths are counted in UTF-16 code units, the unit a RegExp without the `u` flag counts in: `?` and a class stand for one unit.
|
|
31
|
+
*/
|
|
32
|
+
/** One bracket-expression's test of a single code unit, already validated: build it with {@link fsGlobClass}. */
|
|
33
|
+
export interface FsGlobClass {
|
|
34
|
+
/** Does this one code unit belong to the class? */
|
|
35
|
+
matches(unit: string): boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A class from its character-class source (`[a-z]`, `[^/ab]`), or `undefined` when the source is not a class JavaScript accepts
|
|
39
|
+
* (a reversed range, say). A class is one character wide: its expression holds no repetition, so it cannot backtrack and the
|
|
40
|
+
* repetition structure of a glob stays in the program.
|
|
41
|
+
*/
|
|
42
|
+
export declare function fsGlobClass(source: string): FsGlobClass | undefined;
|
|
43
|
+
/** A token that stands for a fixed or bounded part of the path. */
|
|
44
|
+
export type FsGlobUnit = {
|
|
45
|
+
readonly kind: "text";
|
|
46
|
+
readonly text: string;
|
|
47
|
+
} | {
|
|
48
|
+
readonly kind: "one";
|
|
49
|
+
} | {
|
|
50
|
+
readonly kind: "class";
|
|
51
|
+
readonly class: FsGlobClass;
|
|
52
|
+
} | {
|
|
53
|
+
readonly kind: "star";
|
|
54
|
+
};
|
|
55
|
+
export type FsGlobToken = FsGlobUnit | {
|
|
56
|
+
readonly kind: "globstar";
|
|
57
|
+
}
|
|
58
|
+
/** One of several alternatives, each a run of units (no nesting). */
|
|
59
|
+
| {
|
|
60
|
+
readonly kind: "alt";
|
|
61
|
+
readonly alternatives: readonly (readonly FsGlobUnit[])[];
|
|
62
|
+
};
|
|
63
|
+
/** Where a match may begin: `start` only at the first character of the value; `segment` at the first character or right after any `/`. */
|
|
64
|
+
export type FsGlobAnchor = "start" | "segment";
|
|
65
|
+
/** A compiled glob: the whole of a value must match. */
|
|
66
|
+
export interface FsGlob {
|
|
67
|
+
/** Does the whole of `value` match? */
|
|
68
|
+
test(value: string): boolean;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* What the matcher has done in this process so far, for a pin to state a bound as a count instead of timing a call. `visits`: the
|
|
72
|
+
* (instruction, position) pairs entered — a test of a program `size` long against a path of `length` enters at most
|
|
73
|
+
* `size * (length + 1)`. `scratchBytes`: the bytes of the sets allocated — it moves when a program larger than any before needs
|
|
74
|
+
* scratch, and per test only for a program past the retained size.
|
|
75
|
+
*/
|
|
76
|
+
export declare function fsGlobWorkTotals(): {
|
|
77
|
+
readonly visits: number;
|
|
78
|
+
readonly scratchBytes: number;
|
|
79
|
+
};
|
|
80
|
+
/** A compiled program (see the module header). */
|
|
81
|
+
export interface FsGlobProgram extends FsGlob {
|
|
82
|
+
/** The program's length in instructions: the factor of the visit bound that belongs to the pattern. */
|
|
83
|
+
readonly size: number;
|
|
84
|
+
}
|
|
85
|
+
/** Compile a token list. The match is always over the whole value; `anchor` says where it may begin. */
|
|
86
|
+
export declare function compileFsGlob(tokens: readonly FsGlobToken[], anchor: FsGlobAnchor): FsGlobProgram;
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
export function fsGlobClass(source) {
|
|
2
|
+
let re;
|
|
3
|
+
try {
|
|
4
|
+
re = new RegExp(source);
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
return { matches: (unit) => re.test(unit) };
|
|
10
|
+
}
|
|
11
|
+
const OP_TEXT = 0;
|
|
12
|
+
const OP_ONE = 1;
|
|
13
|
+
const OP_CLASS = 2;
|
|
14
|
+
const OP_ANY = 3;
|
|
15
|
+
const OP_SPLIT = 4;
|
|
16
|
+
const OP_JUMP = 5;
|
|
17
|
+
const OP_END = 6;
|
|
18
|
+
const SLASH = 47;
|
|
19
|
+
class LiveSet {
|
|
20
|
+
dense;
|
|
21
|
+
sparse;
|
|
22
|
+
count = 0;
|
|
23
|
+
constructor(capacity) {
|
|
24
|
+
this.dense = new Int32Array(capacity);
|
|
25
|
+
this.sparse = new Int32Array(capacity);
|
|
26
|
+
}
|
|
27
|
+
has(pc) {
|
|
28
|
+
const at = this.sparse[pc];
|
|
29
|
+
return at < this.count && this.dense[at] === pc;
|
|
30
|
+
}
|
|
31
|
+
add(pc) {
|
|
32
|
+
this.dense[this.count] = pc;
|
|
33
|
+
this.sparse[pc] = this.count++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const MAX_RETAINED_SIZE = 1 << 16;
|
|
37
|
+
let retained;
|
|
38
|
+
let retainedCapacity = 0;
|
|
39
|
+
const pending = [];
|
|
40
|
+
let visitsTotal = 0;
|
|
41
|
+
let scratchBytesTotal = 0;
|
|
42
|
+
function scratchFor(size) {
|
|
43
|
+
const made = (capacity) => {
|
|
44
|
+
scratchBytesTotal += 16 * capacity;
|
|
45
|
+
return [new LiveSet(capacity), new LiveSet(capacity)];
|
|
46
|
+
};
|
|
47
|
+
if (size > MAX_RETAINED_SIZE)
|
|
48
|
+
return made(size);
|
|
49
|
+
if (retained === undefined || size > retainedCapacity) {
|
|
50
|
+
retainedCapacity = Math.max(size, retainedCapacity * 2, 1 << 8);
|
|
51
|
+
retained = made(retainedCapacity);
|
|
52
|
+
}
|
|
53
|
+
retained[0].count = 0;
|
|
54
|
+
retained[1].count = 0;
|
|
55
|
+
return retained;
|
|
56
|
+
}
|
|
57
|
+
export function fsGlobWorkTotals() {
|
|
58
|
+
return { visits: visitsTotal, scratchBytes: scratchBytesTotal };
|
|
59
|
+
}
|
|
60
|
+
const isStarRun = (token) => token.kind === "star" || token.kind === "globstar";
|
|
61
|
+
export function compileFsGlob(tokens, anchor) {
|
|
62
|
+
const op = [];
|
|
63
|
+
const arg = [];
|
|
64
|
+
const arg2 = [];
|
|
65
|
+
const classes = [];
|
|
66
|
+
const emit = (o, a = 0, b = 0) => {
|
|
67
|
+
op.push(o);
|
|
68
|
+
arg.push(a);
|
|
69
|
+
arg2.push(b);
|
|
70
|
+
return op.length - 1;
|
|
71
|
+
};
|
|
72
|
+
const emitLoop = (unit) => {
|
|
73
|
+
const loop = emit(OP_SPLIT);
|
|
74
|
+
emit(unit);
|
|
75
|
+
emit(OP_JUMP, loop);
|
|
76
|
+
arg[loop] = loop + 1;
|
|
77
|
+
arg2[loop] = op.length;
|
|
78
|
+
};
|
|
79
|
+
const emitUnit = (unit) => {
|
|
80
|
+
if (unit.kind === "text")
|
|
81
|
+
for (let i = 0; i < unit.text.length; i++)
|
|
82
|
+
emit(OP_TEXT, unit.text.charCodeAt(i));
|
|
83
|
+
else if (unit.kind === "one")
|
|
84
|
+
emit(OP_ONE);
|
|
85
|
+
else if (unit.kind === "class")
|
|
86
|
+
emit(OP_CLASS, classes.push(unit.class) - 1);
|
|
87
|
+
else
|
|
88
|
+
emitLoop(OP_ONE);
|
|
89
|
+
};
|
|
90
|
+
const merged = [];
|
|
91
|
+
for (const token of tokens) {
|
|
92
|
+
const previous = merged[merged.length - 1];
|
|
93
|
+
if (previous !== undefined && isStarRun(previous) && isStarRun(token)) {
|
|
94
|
+
if (token.kind === "globstar")
|
|
95
|
+
merged[merged.length - 1] = token;
|
|
96
|
+
}
|
|
97
|
+
else
|
|
98
|
+
merged.push(token);
|
|
99
|
+
}
|
|
100
|
+
for (const token of merged) {
|
|
101
|
+
if (token.kind === "globstar")
|
|
102
|
+
emitLoop(OP_ANY);
|
|
103
|
+
else if (token.kind === "alt") {
|
|
104
|
+
const exits = [];
|
|
105
|
+
token.alternatives.forEach((alternative, k) => {
|
|
106
|
+
const last = k === token.alternatives.length - 1;
|
|
107
|
+
const choice = last ? -1 : emit(OP_SPLIT);
|
|
108
|
+
if (!last)
|
|
109
|
+
arg[choice] = choice + 1;
|
|
110
|
+
for (const unit of alternative)
|
|
111
|
+
emitUnit(unit);
|
|
112
|
+
if (!last) {
|
|
113
|
+
exits.push(emit(OP_JUMP));
|
|
114
|
+
arg2[choice] = op.length;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
for (const exit of exits)
|
|
118
|
+
arg[exit] = op.length;
|
|
119
|
+
}
|
|
120
|
+
else
|
|
121
|
+
emitUnit(token);
|
|
122
|
+
}
|
|
123
|
+
emit(OP_END);
|
|
124
|
+
let required = "";
|
|
125
|
+
let run = "";
|
|
126
|
+
for (const token of merged) {
|
|
127
|
+
run = token.kind === "text" ? run + token.text : "";
|
|
128
|
+
if (run.length > required.length)
|
|
129
|
+
required = run;
|
|
130
|
+
}
|
|
131
|
+
return new Program(Int32Array.from(op), Int32Array.from(arg), Int32Array.from(arg2), classes, anchor === "segment", required, run);
|
|
132
|
+
}
|
|
133
|
+
class Program {
|
|
134
|
+
op;
|
|
135
|
+
arg;
|
|
136
|
+
arg2;
|
|
137
|
+
classes;
|
|
138
|
+
segmentAnchored;
|
|
139
|
+
required;
|
|
140
|
+
tail;
|
|
141
|
+
constructor(op, arg, arg2, classes, segmentAnchored, required, tail) {
|
|
142
|
+
this.op = op;
|
|
143
|
+
this.arg = arg;
|
|
144
|
+
this.arg2 = arg2;
|
|
145
|
+
this.classes = classes;
|
|
146
|
+
this.segmentAnchored = segmentAnchored;
|
|
147
|
+
this.required = required;
|
|
148
|
+
this.tail = tail;
|
|
149
|
+
this.first = op[0] === OP_TEXT ? arg[0] : -1;
|
|
150
|
+
this.beginsAfter = this.first >= 0 ? `/${String.fromCharCode(this.first)}` : "/";
|
|
151
|
+
}
|
|
152
|
+
first;
|
|
153
|
+
beginsAfter;
|
|
154
|
+
get size() {
|
|
155
|
+
return this.op.length;
|
|
156
|
+
}
|
|
157
|
+
follow(set, from) {
|
|
158
|
+
const { op, arg, arg2 } = this;
|
|
159
|
+
let added = 0;
|
|
160
|
+
let pc = from;
|
|
161
|
+
for (;;) {
|
|
162
|
+
if (!set.has(pc)) {
|
|
163
|
+
set.add(pc);
|
|
164
|
+
added++;
|
|
165
|
+
const o = op[pc];
|
|
166
|
+
if (o === OP_SPLIT) {
|
|
167
|
+
pending.push(arg2[pc]);
|
|
168
|
+
pc = arg[pc];
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (o === OP_JUMP) {
|
|
172
|
+
pc = arg[pc];
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (pending.length === 0)
|
|
177
|
+
return added;
|
|
178
|
+
pc = pending.pop();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
test(value) {
|
|
182
|
+
if (this.tail !== "" && !value.endsWith(this.tail))
|
|
183
|
+
return false;
|
|
184
|
+
if (this.required !== "" && !value.includes(this.required))
|
|
185
|
+
return false;
|
|
186
|
+
const { op, arg, classes } = this;
|
|
187
|
+
const length = value.length;
|
|
188
|
+
const [first, second] = scratchFor(op.length);
|
|
189
|
+
let live = first;
|
|
190
|
+
let ahead = second;
|
|
191
|
+
let entered = 0;
|
|
192
|
+
let found = false;
|
|
193
|
+
for (let pos = 0;;) {
|
|
194
|
+
if ((pos === 0 || (this.segmentAnchored && value.charCodeAt(pos - 1) === SLASH)) && (this.first < 0 || value.charCodeAt(pos) === this.first))
|
|
195
|
+
entered += this.follow(live, 0);
|
|
196
|
+
if (pos === length) {
|
|
197
|
+
found = live.has(op.length - 1);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
if (live.count === 0) {
|
|
201
|
+
if (!this.segmentAnchored)
|
|
202
|
+
break;
|
|
203
|
+
const slash = value.indexOf(this.beginsAfter, pos);
|
|
204
|
+
if (slash < 0)
|
|
205
|
+
break;
|
|
206
|
+
pos = slash + 1;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
const unit = value.charCodeAt(pos);
|
|
210
|
+
ahead.count = 0;
|
|
211
|
+
for (let i = 0; i < live.count; i++) {
|
|
212
|
+
const pc = live.dense[i];
|
|
213
|
+
const o = op[pc];
|
|
214
|
+
const takes = o === OP_TEXT ? arg[pc] === unit : o === OP_ONE ? unit !== SLASH : o === OP_ANY ? true : o === OP_CLASS ? classes[arg[pc]].matches(value[pos]) : false;
|
|
215
|
+
if (takes)
|
|
216
|
+
entered += this.follow(ahead, pc + 1);
|
|
217
|
+
}
|
|
218
|
+
const spent = live;
|
|
219
|
+
live = ahead;
|
|
220
|
+
ahead = spent;
|
|
221
|
+
pos++;
|
|
222
|
+
}
|
|
223
|
+
visitsTotal += entered;
|
|
224
|
+
return found;
|
|
225
|
+
}
|
|
226
|
+
}
|
package/dist/tools/fs/fs-read.js
CHANGED
|
@@ -467,20 +467,20 @@ export function createReadFileTool(env, state, rootCanonical, cwdRef, additional
|
|
|
467
467
|
"- Other binaries (archives, executables) are refused. A whole-file read of a text file over 256 KB is refused — read it in slices with explicit offset/limit, or Grep it instead.\n" +
|
|
468
468
|
"- You must read a file before editing it.\n" +
|
|
469
469
|
"- Do NOT re-read a file you just edited to verify — Edit/Write would have errored if the change failed, and the harness tracks file state for you.",
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
470
|
+
descriptionVariants: [{ id: "classic", traits: { noneOf: ["lean_prompt"] }, text: "Reads a file from the local filesystem.\n" +
|
|
471
|
+
"\n" +
|
|
472
|
+
"Usage:\n" +
|
|
473
|
+
"- By default, it reads the whole file (from `offset`, 1-based); a very large file is served as a partial view with an explicit marker and the next-page call\n" +
|
|
474
|
+
"- You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters\n" +
|
|
475
|
+
"- Results are returned using cat -n format, with each line prefixed by its line number and a tab\n" +
|
|
476
|
+
"- This tool allows the model to read images (eg PNG, JPG, etc). When reading an image file the contents are presented visually.\n" +
|
|
477
|
+
"- This tool can only read files, not directories. To read a directory, use Glob/Grep or an ls command via the Bash tool.\n" +
|
|
478
|
+
"- You must read a file before editing it.\n" +
|
|
479
|
+
"- Reads PDFs (.pdf): the document is provided to the model directly (text layer included). Use the `pages` parameter (e.g., \"1-5\") to read a page range; a PDF whose detected page count exceeds 10 requires `pages`. Maximum 20 pages per request.\n" +
|
|
480
|
+
"- Reads Jupyter notebooks (.ipynb) as cells with outputs (offset/limit do not apply).\n" +
|
|
481
|
+
"- Other binaries (archives, executables) are refused. A whole-file read of a text file over 256 KB is refused — read it in slices with explicit offset/limit, or Grep it instead.\n" +
|
|
482
|
+
"- If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.\n" +
|
|
483
|
+
"- Do NOT re-read a file you just edited to verify — Edit/Write would have errored if the change failed, and the harness tracks file state for you." }],
|
|
484
484
|
parameters: Type.Object({
|
|
485
485
|
...FILE_PATH_PARAMS,
|
|
486
486
|
offset: Type.Optional(Type.Integer({ minimum: 0, description: "The line number to start reading from. Only provide if the file is too large to read at once (1-based; default 1)." })),
|
|
@@ -189,13 +189,13 @@ export function createGlobTool(env, rootCanonical, rootsSeat, denySeat, readFace
|
|
|
189
189
|
"\n" +
|
|
190
190
|
"- On environments that do not report modification times, results fall back to alphabetical order\n" +
|
|
191
191
|
"- Paths are RELATIVE to the root; ignored trees (node_modules/build/.gitignore) are skipped unless your pattern names them explicitly (e.g. `dist/**`)",
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
192
|
+
descriptionVariants: [{ id: "classic", traits: { noneOf: ["lean_prompt"] }, text: "- Fast file pattern matching tool that works with any codebase size\n" +
|
|
193
|
+
'- Supports glob patterns like "**/*.js" or "src/**/*.ts"\n' +
|
|
194
|
+
"- Returns matching file paths sorted by modification time\n" +
|
|
195
|
+
"- On environments that do not report modification times, results fall back to alphabetical order\n" +
|
|
196
|
+
"- Paths are RELATIVE to the root; ignored trees (node_modules/build/.gitignore) are skipped unless your pattern names them explicitly (e.g. `dist/**`)\n" +
|
|
197
|
+
"- Use this tool when you need to find files by name patterns; use `path` to scope to a sub-directory\n" +
|
|
198
|
+
"- When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead (if available)" }],
|
|
199
199
|
parameters: Type.Object({
|
|
200
200
|
pattern: Type.String({ description: "Glob pattern (`*`, `**`, `?`)." }),
|
|
201
201
|
path: Type.Optional(Type.String({
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ExecutionEnv } from "../../internal/harness.js";
|
|
2
|
+
/** One killer the command spells and the questions to put to `pgrep` for it, or why the question cannot be put. */
|
|
3
|
+
export interface PatternKillReading {
|
|
4
|
+
readonly text: string;
|
|
5
|
+
readonly probes: readonly (readonly string[])[];
|
|
6
|
+
/** Set when a word of the selector is decided only when the command runs. */
|
|
7
|
+
readonly computed?: string;
|
|
8
|
+
/** Set when the kill names every process the caller may signal — this agent's own among them — so there is nothing to ask. */
|
|
9
|
+
readonly everyProcess?: true;
|
|
10
|
+
}
|
|
11
|
+
/** The killers a command text spells, read off the plan the read station plans (nothing is read from disk or run). */
|
|
12
|
+
export declare function patternKillReadings(command: string, cwd: string): PatternKillReading[];
|
|
13
|
+
/**
|
|
14
|
+
* The refusal for a command whose pattern-kill would select this agent's own process or one above it — or undefined (run it).
|
|
15
|
+
* `cwd`: where the command stands, for the plan's read of its words (nothing is read from disk). Remote environments and
|
|
16
|
+
* Windows are not asked: their process table is not this one.
|
|
17
|
+
*/
|
|
18
|
+
export declare function patternKillRefusal(command: string, env: ExecutionEnv, cwd: string, signal?: AbortSignal): Promise<{
|
|
19
|
+
content: string;
|
|
20
|
+
isError: true;
|
|
21
|
+
details?: unknown;
|
|
22
|
+
} | undefined>;
|