@sema-agent/core 7.55.0 → 7.57.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 +1054 -0
- package/LICENSE +1 -1
- 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/org-delivery-gate.js +3 -4
- package/dist/agents/peer-directory.d.ts +22 -4
- package/dist/agents/peer-directory.js +24 -2
- package/dist/agents/peer-held-queue.d.ts +69 -49
- package/dist/agents/peer-held-queue.js +255 -106
- package/dist/agents/peer-session-drain.js +65 -45
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/send-message-tool.js +7 -6
- package/dist/agents/subagent.d.ts +6 -4
- package/dist/agents/subagent.js +72 -68
- 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 +45 -80
- 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 +23 -34
- package/dist/brain/openai.js +25 -96
- package/dist/brain/provider-dialect.d.ts +3 -2
- package/dist/brain/provider-dialect.js +2 -2
- 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 +13 -4
- package/dist/brain/request-params.js +21 -5
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/brain/stream-engine.d.ts +9 -0
- package/dist/brain/stream-engine.js +24 -10
- package/dist/brain/stream-shared.d.ts +5 -4
- package/dist/brain/stream-shared.js +4 -4
- 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 +23 -23
- package/dist/core/allow-entry.js +42 -46
- package/dist/core/allow-rule-shadow.d.ts +3 -3
- package/dist/core/approval-object.d.ts +21 -5
- package/dist/core/approval-object.js +44 -17
- package/dist/core/ask-origin.d.ts +66 -20
- 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/auto-compaction.d.ts +71 -6
- package/dist/core/auto-compaction.js +42 -26
- package/dist/core/background-agent-store.d.ts +6 -2
- package/dist/core/background-agent-store.js +1 -1
- package/dist/core/checkpoint-generation.d.ts +53 -0
- package/dist/core/checkpoint-generation.js +35 -0
- package/dist/core/checkpoint-queries.d.ts +180 -0
- package/dist/core/checkpoint-queries.js +272 -0
- package/dist/core/checkpoint-requirements.d.ts +19 -1
- package/dist/core/checkpoint-requirements.js +6 -0
- package/dist/core/checkpoint-store.d.ts +105 -53
- package/dist/core/checkpoint-store.js +43 -20
- package/dist/core/cross-boundary-taint.d.ts +6 -5
- package/dist/core/cross-boundary-taint.js +5 -5
- 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 +32 -12
- package/dist/core/engine-notice.js +6 -0
- package/dist/core/file-history-store.d.ts +104 -22
- package/dist/core/file-history-store.js +37 -19
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +22 -10
- package/dist/core/gate-lanes.js +73 -65
- 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 +19 -18
- 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/mailbox-store.d.ts +62 -1
- package/dist/core/mailbox-store.js +59 -0
- package/dist/core/mcp-name-judge.d.ts +46 -0
- package/dist/core/mcp-name-judge.js +61 -0
- package/dist/core/mcp-probe.d.ts +1 -1
- package/dist/core/mcp-probe.js +2 -5
- package/dist/core/mcp.d.ts +5 -1
- package/dist/core/mcp.js +70 -64
- package/dist/core/memory-engine/consolidation-driver.js +4 -3
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- package/dist/core/memory-engine/distiller.js +26 -17
- 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 +70 -8
- 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 +3 -0
- package/dist/core/permission-rule-consent.d.ts +24 -3
- package/dist/core/permission-rule-consent.js +136 -41
- package/dist/core/permission-rule-model.d.ts +57 -5
- package/dist/core/permission-rule-model.js +90 -31
- package/dist/core/permission-rule-org.d.ts +6 -2
- package/dist/core/permission-rule-org.js +8 -4
- 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 +40 -5
- package/dist/core/protocol-http-auth.js +168 -4
- package/dist/core/protocol-naming.d.ts +20 -0
- package/dist/core/protocol-naming.js +20 -3
- package/dist/core/read-only-shell.d.ts +20 -5
- package/dist/core/read-only-shell.js +29 -14
- package/dist/core/remote-env.d.ts +37 -1
- package/dist/core/remote-env.js +11 -0
- package/dist/core/resume-startup-cause.d.ts +24 -2
- package/dist/core/resume-startup-cause.js +20 -1
- package/dist/core/retired-keys.d.ts +16 -0
- package/dist/core/retired-keys.js +16 -4
- package/dist/core/rewrite-rejudge.d.ts +60 -0
- package/dist/core/rewrite-rejudge.js +36 -0
- package/dist/core/roles.d.ts +28 -1
- package/dist/core/roles.js +81 -26
- 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/compact-session.d.ts +10 -0
- package/dist/core/runner/compact-session.js +202 -0
- package/dist/core/runner/compaction-call-options.d.ts +2 -2
- package/dist/core/runner/compaction-seams.d.ts +21 -1
- package/dist/core/runner/compaction-seams.js +11 -8
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +50 -40
- 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/derived-route-fallback.d.ts +13 -0
- package/dist/core/runner/derived-route-fallback.js +6 -0
- package/dist/core/runner/env-capability-census.d.ts +3 -2
- package/dist/core/runner/env-capability-census.js +9 -3
- 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 +11 -11
- package/dist/core/runner/permission-rule-lanes.js +39 -17
- 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-acquire-reconcile.d.ts +3 -0
- package/dist/core/runner/prepare-acquire-reconcile.js +2 -1
- 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 +35 -38
- package/dist/core/runner/prepare-config-doors.js +46 -28
- 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 +5 -9
- package/dist/core/runner/prepare-hands-readface.js +17 -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.d.ts +2 -0
- package/dist/core/runner/prepare-park-ask.js +7 -7
- package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
- package/dist/core/runner/prepare-policy-chain.js +67 -76
- 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 +5 -2
- package/dist/core/runner/prepare-task.js +48 -43
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +20 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +33 -23
- 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 +12 -0
- package/dist/core/runner/rewind-files.js +90 -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 +40 -39
- package/dist/core/runner/run-notification-lane.d.ts +2 -0
- package/dist/core/runner/run-notification-lane.js +2 -2
- package/dist/core/runner/run-recovery-lanes.js +3 -4
- package/dist/core/runner/run-settle-and-teardown.js +7 -12
- package/dist/core/runner/run-terminal-adoption.js +3 -4
- package/dist/core/runner/run-turn-boundary.js +4 -15
- package/dist/core/runner/runtask.d.ts +10 -0
- package/dist/core/runner/runtask.js +35 -42
- package/dist/core/runner/send-message-continuation.js +1 -1
- 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/session-verb-doors.d.ts +28 -0
- package/dist/core/runner/session-verb-doors.js +48 -0
- package/dist/core/runner/session-write-ledger.d.ts +30 -0
- package/dist/core/runner/session-write-ledger.js +101 -0
- 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 +12 -15
- package/dist/core/runner/sub-agent-deny-lists.d.ts +25 -3
- package/dist/core/runner/sub-agent-deny-lists.js +25 -17
- package/dist/core/runner/synthetic-tools.d.ts +6 -0
- package/dist/core/runner/synthetic-tools.js +4 -1
- package/dist/core/runner/teardown-bounded.d.ts +1 -0
- package/dist/core/runner/teardown-bounded.js +1 -0
- 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 +7 -7
- 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 +30 -3
- package/dist/core/secret-env.js +47 -8
- package/dist/core/select-model.js +3 -3
- package/dist/core/session-policy-store.d.ts +32 -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.d.ts +1 -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/background-agent-store-contract.js +1 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +141 -2
- package/dist/core/store-contracts/file-history-store-contract.js +40 -1
- package/dist/core/store-contracts/mailbox-store-contract.js +49 -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-agent.d.ts +8 -4
- package/dist/core/task-registry-agent.js +14 -8
- package/dist/core/task-registry-shared.d.ts +35 -6
- package/dist/core/task-registry-shared.js +11 -0
- package/dist/core/task-registry.d.ts +10 -1
- package/dist/core/task-registry.js +12 -2
- 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 +23 -0
- package/dist/core/tool-catalog-entries.js +14 -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 +48 -18
- package/dist/core/tool-name-aliases.js +36 -19
- package/dist/core/tool-name-readings.d.ts +6 -32
- package/dist/core/tool-name-readings.js +2 -9
- package/dist/core/tool-policy.d.ts +78 -204
- package/dist/core/tool-policy.js +152 -204
- 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 +6 -3
- package/dist/core/trace.js +2 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/untrusted-egress.d.ts +20 -0
- package/dist/core/untrusted-egress.js +77 -3
- 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 +32 -6
- package/dist/engine/harness/agent-harness.js +65 -9
- 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 +23 -4
- package/dist/engine/loop/agent-loop.js +42 -30
- 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 +34 -17
- package/dist/index.js +22 -11
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +2 -1
- package/dist/internal/harness.js +1 -0
- 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/primitives/credential-ref.d.ts +89 -0
- package/dist/primitives/credential-ref.js +125 -0
- package/dist/primitives/index.d.ts +2 -0
- package/dist/primitives/index.js +1 -0
- 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 -4
- package/dist/stores/file/checkpoint-store.js +38 -7
- package/dist/stores/file/file-history-store.js +18 -11
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/mailbox-store.d.ts +2 -1
- package/dist/stores/file/mailbox-store.js +26 -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/bash-readonly-classifier.d.ts +15 -19
- package/dist/tools/fs/bash-readonly-classifier.js +5 -10
- package/dist/tools/fs/fs-bash.js +15 -8
- 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 +23 -0
- package/dist/tools/fs/pattern-kill-guard.js +429 -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.d.ts +10 -0
- package/dist/tools/fs/shell-read-check.js +13 -20
- package/dist/tools/fs/shell-read-environment.d.ts +5 -1
- package/dist/tools/fs/shell-read-environment.js +3 -2
- package/dist/tools/fs/shell-read-establish.d.ts +15 -0
- package/dist/tools/fs/shell-read-establish.js +19 -20
- package/dist/tools/fs/shell-read-identity.d.ts +12 -9
- package/dist/tools/fs/shell-read-identity.js +9 -4
- 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 +46 -61
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +221 -7
- package/wire-changes/core-stores-sql@7.57.0.json +29 -0
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/core@7.57.0.json +1487 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
- package/wire-changes/mods-kernel@7.57.0.json +29 -0
- package/wire-changes/primitives@7.57.0.json +245 -0
|
@@ -2,18 +2,19 @@ import { existsSync, renameSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { writerOf } from "../../core/permission-rule-store.js";
|
|
4
4
|
import { readRuleOwner, ruleOwnerText, sameRuleOwner } from "../../core/rule-owner.js";
|
|
5
|
+
import { principalNameOf } from "../../core/principal-name.js";
|
|
5
6
|
import { createPermissionRuleStoreProvider } from "../../core/permission-rule-provider.js";
|
|
6
7
|
import { syncPermissionRules } from "../../core/permission-rule-sync.js";
|
|
7
8
|
import { thrownText } from "../../core/thrown-value.js";
|
|
8
9
|
import { FileStoreLockError } from "./fs-atomic.js";
|
|
9
10
|
import { FileDurableRulePartitionProvider, LOCAL_OWNER_FILE, principalRuleFileName, readRuleAdoptionFile, writeRuleAdoptionFile, } from "./permission-rule-store.js";
|
|
10
11
|
export async function adoptFilePermissionRuleStore(opts) {
|
|
11
|
-
if (
|
|
12
|
-
throw new Error("adoptFilePermissionRuleStore requires the adopting principal — adoption is the act of giving this bucket an identity");
|
|
12
|
+
if (principalNameOf(opts.toPrincipal) === undefined) {
|
|
13
|
+
throw new Error("adoptFilePermissionRuleStore requires the adopting principal, a principal name — adoption is the act of giving this bucket an identity");
|
|
13
14
|
}
|
|
14
15
|
const from = readRuleOwner(opts.from);
|
|
15
16
|
if (from === undefined) {
|
|
16
|
-
throw new Error("adoptFilePermissionRuleStore requires a source owner — a principal
|
|
17
|
+
throw new Error("adoptFilePermissionRuleStore requires a source owner — a principal owner whose principal is a principal name, or the local owner");
|
|
17
18
|
}
|
|
18
19
|
if (from.kind === "principal" && from.principal === opts.toPrincipal) {
|
|
19
20
|
throw new Error(`the bucket already belongs to "${opts.toPrincipal}" — there is nothing to adopt`);
|
|
@@ -4,6 +4,7 @@ import { createHash, randomBytes } from "node:crypto";
|
|
|
4
4
|
import { isRuleBehavior } from "../../core/permission-rule-model.js";
|
|
5
5
|
import { posixModeBitsMeaningful } from "../../core/posix-mode-face.js";
|
|
6
6
|
import { readRuleOwner } from "../../core/rule-owner.js";
|
|
7
|
+
import { principalNameOf, readPrincipal } from "../../core/principal-name.js";
|
|
7
8
|
import { PERMISSION_RULES_LATER_GRAMMAR_CODE, PERMISSION_RULE_WRITER, applySyncJoin, applyTombstones, assertDeleteDeltaCarriesNoAdd, assertRedemptionNotQuarantined, assertWriteDeltaScopeDurable, foldDelta, unknownRuleWriteDeltaError, } from "../../core/permission-rule-store.js";
|
|
8
9
|
import { sameOrgPolicyContent } from "../../core/permission-rule-org.js";
|
|
9
10
|
import { SESSION_RULES_GRAMMAR, readRuleGrammarStamp } from "../../core/session-policy-store.js";
|
|
@@ -66,7 +67,7 @@ function isRuleAdoptionFileShape(v) {
|
|
|
66
67
|
const rec = (hasMarker ? v.marker : v.adopted);
|
|
67
68
|
if (rec === null || typeof rec !== "object")
|
|
68
69
|
return false;
|
|
69
|
-
if (readRuleOwner(rec.from) === undefined ||
|
|
70
|
+
if (readRuleOwner(rec.from) === undefined || principalNameOf(rec.toPrincipal) === undefined)
|
|
70
71
|
return false;
|
|
71
72
|
return hasMarker ? rec.phase === 2 || rec.phase === 3 || rec.phase === 4 || rec.phase === 5 : typeof rec.atMs === "number" && Number.isFinite(rec.atMs);
|
|
72
73
|
}
|
|
@@ -452,17 +453,22 @@ export class FileDurableRulePartitionProvider {
|
|
|
452
453
|
this.lock = lock;
|
|
453
454
|
};
|
|
454
455
|
forPrincipal(principal) {
|
|
455
|
-
|
|
456
|
+
const reading = readPrincipal(principal);
|
|
457
|
+
if (reading.kind === "invalid") {
|
|
458
|
+
throw new Error(`the principal given is not a principal name (got ${reading.fault}) — refusing to resolve a bucket for it; a provided value that names nobody is not "no principal"`);
|
|
459
|
+
}
|
|
460
|
+
if (reading.kind === "absent") {
|
|
456
461
|
return { list: async () => ({ ...EMPTY_READ }), durability: "process-local" };
|
|
457
462
|
}
|
|
463
|
+
const name = reading.name;
|
|
458
464
|
const adoption = this.adoptionMarker();
|
|
459
465
|
if (adoption !== undefined) {
|
|
460
466
|
const rec = "adopted" in adoption ? adoption.adopted : adoption.marker;
|
|
461
|
-
if (rec.from.kind === "principal" && rec.from.principal ===
|
|
462
|
-
return this.readOnlySourceView(principalRuleFileName(
|
|
467
|
+
if (rec.from.kind === "principal" && rec.from.principal === name) {
|
|
468
|
+
return this.readOnlySourceView(principalRuleFileName(name), principalRuleFileName(rec.toPrincipal), "adopted" in adoption || adoption.marker.phase >= 4);
|
|
463
469
|
}
|
|
464
470
|
}
|
|
465
|
-
return new FileDurableRulePartition(this.dir, join(this.dir, principalRuleFileName(
|
|
471
|
+
return new FileDurableRulePartition(this.dir, join(this.dir, principalRuleFileName(name)), this.acquireWriteLock, this.onError, this.vetting);
|
|
466
472
|
}
|
|
467
473
|
readOnlySourceView(sourceName, targetName, flipped) {
|
|
468
474
|
const pick = flipped ? targetName : existsSync(join(this.dir, sourceName)) ? sourceName : targetName;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Session, SessionCreateOptions, SessionForkOptions, SessionHead, SessionMetadata, SessionPlacementRecord, SessionRepo, SessionTreeEntry } from "../../internal/harness.js";
|
|
1
|
+
import type { Session, SessionCreateOptions, SessionForkOptions, SessionHead, SessionMetadata, SessionPlacementRecord, SessionRepo, SessionRow, SessionTreeEntry } from "../../internal/harness.js";
|
|
2
2
|
import type { PlacedSessionRow } from "../../core/session.js";
|
|
3
3
|
import { type CorruptReadInfo } from "./corrupt-read-sink.js";
|
|
4
4
|
export interface FileSessionRepoOptions {
|
|
@@ -8,8 +8,9 @@ export interface FileSessionRepoOptions {
|
|
|
8
8
|
* "corrupt read as missing" are one failure grammar, so they get one seat name.
|
|
9
9
|
*
|
|
10
10
|
* Fires for: an unreadable sessions DIRECTORY (the listing degrades to "no sessions"), a session log
|
|
11
|
-
*
|
|
12
|
-
* record dropped on replay plus that replay's
|
|
11
|
+
* whose header could not be read during a listing (skipped from the result — a listing reads headers,
|
|
12
|
+
* it never replays a log), and each corrupt interior JSONL record dropped on replay plus that replay's
|
|
13
|
+
* tally (turns missing from an otherwise healthy session).
|
|
13
14
|
*
|
|
14
15
|
* Never fires on plain ENOENT / `not_found` — that is honest absence, and the torn TAIL stays silent
|
|
15
16
|
* too (dying mid-write is the append log's documented crash-recovery shape, not corruption).
|
|
@@ -59,6 +60,15 @@ export declare class FileSessionRepo implements SessionRepo {
|
|
|
59
60
|
* head does not see. A leaf entry naming an id the log does not hold is not checked here (a replay refuses that log on open).
|
|
60
61
|
*/
|
|
61
62
|
headOf(sessionId: string): Promise<SessionHead | undefined>;
|
|
63
|
+
/**
|
|
64
|
+
* The row's {@link SessionRow} — its header cells and the newest write it holds, the log's modification time (every write to a row
|
|
65
|
+
* is an append to its log; the placed listing's age reads the same time) — in one read of the header, never a replay of the log.
|
|
66
|
+
* `undefined` = no row; a row whose header cannot be read rejects (`corrupt_session`).
|
|
67
|
+
*/
|
|
68
|
+
private rowOf;
|
|
69
|
+
/** The one descriptor a by-id read of the row takes: its size and modification time and its header, from one inode (a file replaced
|
|
70
|
+
* or removed while this reads is still the inode this descriptor opened); `undefined` = no file. */
|
|
71
|
+
private atRow;
|
|
62
72
|
private storage;
|
|
63
73
|
/**
|
|
64
74
|
* RB-437 — release every shared authority this repo joined (LAST holder ⇒ evict + close the append fd).
|
|
@@ -75,12 +85,25 @@ export declare class FileSessionRepo implements SessionRepo {
|
|
|
75
85
|
dispose(): Promise<void>;
|
|
76
86
|
create(options?: SessionCreateOptions): Promise<Session>;
|
|
77
87
|
open(metadata: SessionMetadata): Promise<Session>;
|
|
78
|
-
|
|
88
|
+
/** Record activity on the row now: its log's modification time — the one time a listing reads, which every append moves too — is
|
|
89
|
+
* set to now, the log's bytes untouched. A missing file is nothing to record; any other fault rejects. */
|
|
90
|
+
touch(sessionId: string): Promise<void>;
|
|
91
|
+
/** Every ordinary row with the newest write its log holds ({@link rowOf}): one header read per session file, no replay — what a
|
|
92
|
+
* listing costs grows with the number of sessions, never with their history. Placed rows are the placed listing's. */
|
|
93
|
+
list(): Promise<SessionRow[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Every row of the sessions directory, each read by {@link rowOf}. The listing degrades to "no sessions" so a
|
|
96
|
+
* browse face never throws — but "I could not read the directory" and "there are none" are different facts, and only the sink can
|
|
97
|
+
* tell them apart (ENOENT is honest absence: the constructor creates the directory, so it was removed underneath us). A session
|
|
98
|
+
* whose header cannot be read is skipped and disclosed — it exists and is missing from the listing — while a file that vanished
|
|
99
|
+
* between the directory read and its own is honest absence.
|
|
100
|
+
*/
|
|
101
|
+
private rows;
|
|
79
102
|
/**
|
|
80
103
|
* Subagent transcript persistence — the PLACED partition's own enumeration (the joint reap's
|
|
81
104
|
* partition-leg input; `TtlSessionStore` re-exposes it verbatim). Age (`olderThanMs`) is judged on
|
|
82
|
-
* the session FILE's mtime — the transcript's last append
|
|
83
|
-
*
|
|
105
|
+
* the session FILE's mtime — the transcript's last append, the time the host listing reads too
|
|
106
|
+
* (mtime is also the CC orphan-adoption window's basis, so the age reads agree).
|
|
84
107
|
* Rows missing either `(scope, handle)` join half return the honest `tupleIncomplete` variant
|
|
85
108
|
* (consumers fail closed on it — never age-reaped, see the SessionStore contract).
|
|
86
109
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { closeSync, existsSync, fstatSync, openSync, readdirSync, rmSync,
|
|
1
|
+
import { closeSync, existsSync, fstatSync, openSync, readdirSync, rmSync, utimesSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { BaseSessionStorage, StoredSession, SessionError, assertForkTarget, compareOccupants, forkRowCells, frozenRow, getEntriesToFork, importRowCells, incarnationCell, leafIdAfterEntry, ownerCell, readIncarnationCell, readOwnerCell, uuidv7, validateEntriesForImport, } from "../../internal/harness.js";
|
|
4
4
|
import { canonicalStoreKey, AppendLog, atomicWriteFile, ensureDir, firstJsonlRecord, lastJsonlRecord, readJsonlRecords, sanitizePathComponent, writeThenLink } from "./fs-atomic.js";
|
|
@@ -125,6 +125,15 @@ export class FileSessionRepo {
|
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
127
|
async headOf(sessionId) {
|
|
128
|
+
return this.atRow(sessionId, (fd, size, meta) => {
|
|
129
|
+
const last = lastJsonlRecord(fd, size, (r) => r.kind === "entry", SESSION_LINE_JUDGE);
|
|
130
|
+
return { owner: meta.owner ?? null, incarnation: meta.incarnation, leafId: last === undefined ? null : leafIdAfterEntry(last.entry) };
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
rowOf(sessionId) {
|
|
134
|
+
return this.atRow(sessionId, (_fd, _size, meta, mtimeMs) => ({ ...meta, lastActiveAt: Math.trunc(mtimeMs) }));
|
|
135
|
+
}
|
|
136
|
+
atRow(sessionId, read) {
|
|
128
137
|
const path = this.pathFor(sessionId);
|
|
129
138
|
let fd;
|
|
130
139
|
try {
|
|
@@ -136,10 +145,8 @@ export class FileSessionRepo {
|
|
|
136
145
|
throw err;
|
|
137
146
|
}
|
|
138
147
|
try {
|
|
139
|
-
const size = fstatSync(fd)
|
|
140
|
-
|
|
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) };
|
|
148
|
+
const { size, mtimeMs } = fstatSync(fd);
|
|
149
|
+
return read(fd, size, this.headerOf(sessionId, path, firstJsonlRecord(fd, size, SESSION_LINE_JUDGE)), mtimeMs);
|
|
143
150
|
}
|
|
144
151
|
finally {
|
|
145
152
|
closeSync(fd);
|
|
@@ -201,80 +208,65 @@ export class FileSessionRepo {
|
|
|
201
208
|
const { meta, entries } = this.read(metadata.id);
|
|
202
209
|
return new StoredSession(this.storage(meta, entries));
|
|
203
210
|
}
|
|
204
|
-
async
|
|
205
|
-
|
|
211
|
+
async touch(sessionId) {
|
|
212
|
+
const now = new Date();
|
|
206
213
|
try {
|
|
207
|
-
|
|
214
|
+
utimesSync(this.pathFor(sessionId), now, now);
|
|
208
215
|
}
|
|
209
216
|
catch (err) {
|
|
210
|
-
if (err.code
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
return [];
|
|
214
|
-
}
|
|
215
|
-
const out = [];
|
|
216
|
-
for (const name of names) {
|
|
217
|
-
if (!name.endsWith(SUFFIX))
|
|
218
|
-
continue;
|
|
219
|
-
const id = name.slice(0, -SUFFIX.length);
|
|
220
|
-
try {
|
|
221
|
-
const { createdAt, forkedFrom, placement } = this.read(id).meta;
|
|
222
|
-
if (placement !== undefined)
|
|
223
|
-
continue;
|
|
224
|
-
out.push({ id, createdAt, ...(forkedFrom !== undefined ? { forkedFrom } : {}) });
|
|
225
|
-
}
|
|
226
|
-
catch (err) {
|
|
227
|
-
if (!(err instanceof SessionError && err.code === "not_found")) {
|
|
228
|
-
this.disclose(this.pathFor(id), `session log unreadable (${thrownText(err)}) — skipped from the listing`, id);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
217
|
+
if (err.code === "ENOENT")
|
|
218
|
+
return;
|
|
219
|
+
throw new SessionError("storage", `session ${sessionId}'s activity could not be recorded: ${thrownText(err)}`, err instanceof Error ? err : undefined);
|
|
231
220
|
}
|
|
232
|
-
return out.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
233
221
|
}
|
|
234
|
-
async
|
|
222
|
+
async list() {
|
|
223
|
+
return this.rows("the listing")
|
|
224
|
+
.filter((row) => row.placement === undefined)
|
|
225
|
+
.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
226
|
+
}
|
|
227
|
+
rows(listing) {
|
|
235
228
|
let names;
|
|
236
229
|
try {
|
|
237
230
|
names = readdirSync(this.dir);
|
|
238
231
|
}
|
|
239
232
|
catch (err) {
|
|
240
233
|
if (err.code !== "ENOENT") {
|
|
241
|
-
this.disclose(this.dir, `session directory unreadable (${err.code ?? "unknown"}) —
|
|
234
|
+
this.disclose(this.dir, `session directory unreadable (${err.code ?? "unknown"}) — ${listing} degraded to empty`);
|
|
242
235
|
}
|
|
243
236
|
return [];
|
|
244
237
|
}
|
|
245
|
-
const now = Date.now();
|
|
246
238
|
const out = [];
|
|
247
239
|
for (const name of names) {
|
|
248
240
|
if (!name.endsWith(SUFFIX))
|
|
249
241
|
continue;
|
|
250
242
|
const id = name.slice(0, -SUFFIX.length);
|
|
251
|
-
let
|
|
243
|
+
let row;
|
|
252
244
|
try {
|
|
253
|
-
|
|
245
|
+
row = this.rowOf(id);
|
|
254
246
|
}
|
|
255
247
|
catch (err) {
|
|
256
|
-
|
|
257
|
-
this.disclose(this.pathFor(id), `session log unreadable (${thrownText(err)}) — skipped from the placed listing`, id);
|
|
258
|
-
}
|
|
248
|
+
this.disclose(this.pathFor(id), `session log unreadable (${thrownText(err)}) — skipped from ${listing}`, id);
|
|
259
249
|
continue;
|
|
260
250
|
}
|
|
251
|
+
if (row !== undefined)
|
|
252
|
+
out.push(row);
|
|
253
|
+
}
|
|
254
|
+
return out;
|
|
255
|
+
}
|
|
256
|
+
async listPlaced(kind, opts) {
|
|
257
|
+
const now = Date.now();
|
|
258
|
+
const out = [];
|
|
259
|
+
for (const row of this.rows("the placed listing")) {
|
|
260
|
+
const placement = row.placement;
|
|
261
261
|
if (placement === undefined || placement.kind !== kind)
|
|
262
262
|
continue;
|
|
263
263
|
if (opts?.scope !== undefined && placement.scope !== opts.scope)
|
|
264
264
|
continue;
|
|
265
|
-
if (opts?.olderThanMs !== undefined)
|
|
266
|
-
|
|
267
|
-
try {
|
|
268
|
-
ageAnchor = statSync(this.pathFor(id)).mtimeMs;
|
|
269
|
-
}
|
|
270
|
-
catch {
|
|
271
|
-
}
|
|
272
|
-
if (now - ageAnchor <= opts.olderThanMs)
|
|
273
|
-
continue;
|
|
274
|
-
}
|
|
265
|
+
if (opts?.olderThanMs !== undefined && now - row.lastActiveAt <= opts.olderThanMs)
|
|
266
|
+
continue;
|
|
275
267
|
out.push(placement.scope !== undefined && placement.handle !== undefined
|
|
276
|
-
? { sessionId: id, placedAt: placement.placedAt, scope: placement.scope, handle: placement.handle }
|
|
277
|
-
: { sessionId: id, placedAt: placement.placedAt, tupleIncomplete: true });
|
|
268
|
+
? { sessionId: row.id, placedAt: placement.placedAt, scope: placement.scope, handle: placement.handle }
|
|
269
|
+
: { sessionId: row.id, placedAt: placement.placedAt, tupleIncomplete: true });
|
|
278
270
|
}
|
|
279
271
|
return out;
|
|
280
272
|
}
|
|
@@ -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
|
+
}
|
|
@@ -2,15 +2,15 @@ import { type LexedCommand, type LexedSegment, type LexedWord, type ShellLex, ty
|
|
|
2
2
|
import { type ProgramRow } from "./program-read-model.js";
|
|
3
3
|
/**
|
|
4
4
|
* Bare command names `bash_readonly` permits out of the box, ALSO the default reversible set for the
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
5
|
+
* {@link import("./fs-bash.js").bashReversibilityProbe} classifier. On the read-only face and in the transcript gate the
|
|
6
|
+
* list only NARROWS the read-only reader ({@link import("../../core/read-only-shell.js").readOnlyShellVerdict}'s
|
|
7
|
+
* `readers`): a listed program runs there only in a call the reader reads as read-only, so a deployment that widens the
|
|
8
|
+
* list with `sort` still has `sort -o out f` refused. The reversibility classifier reads the list as its allowlist: a
|
|
9
|
+
* listed program with a program-model row has its writing options refused by the row; one without a row is admitted
|
|
10
|
+
* by its name. The default is curated to commands with NO write/mutation mode under ANY args, so the `effect:"read"`
|
|
11
|
+
* declaration (relied on by wake/resume reconcile + the verifier read-only boundary) AND the classifier's
|
|
12
|
+
* "reversible" promise both stay truthful. The deployment's tool-policy gate is the authoritative control;
|
|
13
|
+
* anything that can mutate state or run arbitrary code belongs on the full `bash` (effect:write, gated), not here.
|
|
14
14
|
*
|
|
15
15
|
* Deliberately ABSENT: `date` (`-s`/`--set` → CLOCK_SETTIME), `hostname` (`<name>` → kernel
|
|
16
16
|
* hostname), and `file` (`-C -m` → compiles/writes a magic file) were REMOVED — each is read-only by NAME
|
|
@@ -112,7 +112,7 @@ export interface LeadingCommandNameOptions {
|
|
|
112
112
|
pathPrefixedNameIsText?: boolean;
|
|
113
113
|
}
|
|
114
114
|
/**
|
|
115
|
-
* The SINGLE fail-closed simple-command parser shared by `bash_readonly`
|
|
115
|
+
* The SINGLE fail-closed simple-command parser shared by `bash_readonly`'s single-command admission, the
|
|
116
116
|
* `bash` reversibility classifier ({@link import("./fs-bash.js").bashReversibilityProbe}), and the coarse command-name policy
|
|
117
117
|
* ({@link import("../../core/tool-policy.js").createCoarseCommandNamePolicy}). It extracts the leading
|
|
118
118
|
* `argv[0]` command NAME of a SINGLE simple command, rejecting anything that could chain past or escape an
|
|
@@ -131,13 +131,9 @@ export declare function parseLeadingCommandName(command: string, options?: Leadi
|
|
|
131
131
|
} | {
|
|
132
132
|
reject: string;
|
|
133
133
|
};
|
|
134
|
-
/**
|
|
135
|
-
*
|
|
136
|
-
|
|
137
|
-
* the policy gate are what make `effect:"read"` truthful. Returns a reason when rejected, else undefined.
|
|
138
|
-
* This `effect:"read"` DECLARATION face deliberately stays strict-single-command; only the
|
|
139
|
-
* classify face ({@link classifyCompoundReadonly} via {@link import("./fs-bash.js").bashReversibilityProbe}) segments compounds. */
|
|
140
|
-
export declare function coarseReadonlyCheck(command: string, allow: ReadonlySet<string>, options?: LeadingCommandNameOptions): string | undefined;
|
|
134
|
+
/** The one sentence for a program a face's list of programs does not name — the compound classifier's list check and
|
|
135
|
+
* the read-only reader's `readers` narrowing both mint it here. */
|
|
136
|
+
export declare function unlistedReaderSentence(program: string): string;
|
|
141
137
|
/**
|
|
142
138
|
* Does this text carry a bare redirection operator — the ONE metacharacter family
|
|
143
139
|
* {@link splitShellCompoundSegments} can be asked to tolerate at its whole-string gate
|
|
@@ -226,7 +222,7 @@ export declare function splitShellCompoundSegments(source: string, options?: {
|
|
|
226
222
|
/**
|
|
227
223
|
* Compound read-only classification for the `bash` full-shell face (the shape tier).
|
|
228
224
|
* Splits a command on the connector set `;` `&&` `||` `|` and passes every segment through
|
|
229
|
-
*
|
|
225
|
+
* the single {@link parseLeadingCommandName} parser and the bare-name allowlist.
|
|
230
226
|
* All segments green ⇒ read-only. Returns a reason when rejected, else undefined.
|
|
231
227
|
*
|
|
232
228
|
* G2 — the split CARRIES QUOTE STATE (the one lexer): a connector character inside a quoted region is
|
|
@@ -548,7 +544,7 @@ export declare const POLL_LOOP_MAX_SLEEP_SECONDS = 600;
|
|
|
548
544
|
* -f`, unbounded devices all reject), and `sleep` must be a literal ≤
|
|
549
545
|
* {@link POLL_LOOP_MAX_SLEEP_SECONDS}. Bounded beats × terminating body ⇒ the loop halts.
|
|
550
546
|
* G2 NO WRITE OR EGRESS CHANNEL. Every non-`sleep` body segment must pass the SAME
|
|
551
|
-
* {@link
|
|
547
|
+
* {@link parseLeadingCommandName} parser + allowlist the compound classifier reads (one parser, no drift);
|
|
552
548
|
* `sleep` touches neither filesystem nor network. No redirection (`>` `<`), no `$`/backtick
|
|
553
549
|
* substitution, no subshell exists anywhere: the body bans them wholesale
|
|
554
550
|
* ({@link POLL_BODY_HARD_REJECT}), and the head's single `$(seq <int> <int>)` exemption is an
|
|
@@ -71,13 +71,8 @@ export function parseLeadingCommandName(command, options) {
|
|
|
71
71
|
return { reject: "the command name must be a bare token (no quotes, braces, globs, or ~)" };
|
|
72
72
|
return { name: first };
|
|
73
73
|
}
|
|
74
|
-
export function
|
|
75
|
-
|
|
76
|
-
if ("reject" in parsed)
|
|
77
|
-
return parsed.reject;
|
|
78
|
-
if (!allow.has(parsed.name))
|
|
79
|
-
return `command "${parsed.name}" is not in the read-only allowlist`;
|
|
80
|
-
return undefined;
|
|
74
|
+
export function unlistedReaderSentence(program) {
|
|
75
|
+
return `command "${program}" is not in the read-only allowlist`;
|
|
81
76
|
}
|
|
82
77
|
const SHELL_SEGMENT_QUOTE_BLIND_REJECT = /[<>()`\n\r\\]/;
|
|
83
78
|
const SHELL_EXPANSION_CHARS = /[$]/;
|
|
@@ -761,7 +756,7 @@ export function classifyCompoundReadonlyDetailed(command, allow, boundary) {
|
|
|
761
756
|
return { reason: "`coproc` backgrounds a command — a backgrounded process outlives the command" };
|
|
762
757
|
if (isBareControlWord(words, from, BLOCK_WORD_NAMES)) {
|
|
763
758
|
unlistedSegments.add(si);
|
|
764
|
-
nameRefusal ??=
|
|
759
|
+
nameRefusal ??= unlistedReaderSentence(written);
|
|
765
760
|
continue;
|
|
766
761
|
}
|
|
767
762
|
const program = pos.program;
|
|
@@ -783,10 +778,10 @@ export function classifyCompoundReadonlyDetailed(command, allow, boundary) {
|
|
|
783
778
|
if (pathPrefixed || from > 0)
|
|
784
779
|
reheaded.set(si, { from, head: name });
|
|
785
780
|
if (from > 0)
|
|
786
|
-
nameRefusal ??=
|
|
781
|
+
nameRefusal ??= unlistedReaderSentence(folded[0]);
|
|
787
782
|
continue;
|
|
788
783
|
}
|
|
789
|
-
nameRefusal ??=
|
|
784
|
+
nameRefusal ??= unlistedReaderSentence(parsed.name);
|
|
790
785
|
if (runsShellText(name))
|
|
791
786
|
return { reason: unjudgedProgramTextRefusal(parsed.name, "runs its argument as shell text") };
|
|
792
787
|
if (pos.launchers.length > 0) {
|