@sema-agent/core 7.47.0 → 7.49.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 +472 -0
- package/README.md +2 -2
- package/dist/agents/cascade.d.ts +2 -5
- package/dist/agents/child-failure.d.ts +20 -0
- package/dist/agents/child-failure.js +28 -0
- package/dist/agents/cross-session-ref.d.ts +11 -3
- package/dist/agents/cross-session-ref.js +6 -0
- package/dist/agents/cumulative-stats.d.ts +12 -15
- package/dist/agents/cumulative-stats.js +1 -1
- package/dist/agents/extra-tool-names.js +1 -1
- package/dist/agents/inherited-tool-pool.d.ts +17 -13
- package/dist/agents/inherited-tool-pool.js +4 -3
- package/dist/agents/peer-session-drain.d.ts +3 -2
- package/dist/agents/peer-session-drain.js +5 -4
- package/dist/agents/send-message-tool.js +2 -9
- package/dist/agents/subagent.d.ts +10 -29
- package/dist/agents/subagent.js +65 -53
- package/dist/agents/suspend-guard.d.ts +1 -1
- package/dist/agents/tool-filter.d.ts +76 -65
- package/dist/agents/tool-filter.js +122 -92
- package/dist/agents/verify.d.ts +4 -7
- package/dist/agents/verify.js +6 -7
- package/dist/bench/metrics.d.ts +1 -2
- package/dist/brain/anthropic.js +133 -79
- package/dist/brain/errors.d.ts +53 -6
- package/dist/brain/errors.js +22 -2
- package/dist/brain/input-too-long.d.ts +40 -19
- package/dist/brain/input-too-long.js +3 -16
- package/dist/brain/open-responses.js +19 -10
- package/dist/brain/openai.js +123 -32
- package/dist/brain/provider-dialect.d.ts +214 -0
- package/dist/brain/provider-dialect.js +186 -0
- package/dist/brain/request-params.d.ts +27 -8
- package/dist/brain/request-params.js +7 -12
- package/dist/brain/request-route.d.ts +84 -0
- package/dist/brain/request-route.js +41 -0
- package/dist/brain/retry.d.ts +8 -0
- package/dist/brain/retry.js +10 -4
- package/dist/brain/route-adjudicator.d.ts +7 -0
- package/dist/brain/route-adjudicator.js +5 -1
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +11 -0
- package/dist/brain/stream-engine.d.ts +52 -1
- package/dist/brain/stream-engine.js +81 -24
- package/dist/brain/stream-shared.d.ts +57 -11
- package/dist/brain/stream-shared.js +28 -2
- package/dist/core/a2a.d.ts +1 -0
- package/dist/core/agent-config-dir.js +3 -2
- package/dist/core/allow-entry.d.ts +21 -12
- package/dist/core/allow-entry.js +39 -32
- package/dist/core/arg-summary.d.ts +17 -24
- package/dist/core/arg-summary.js +169 -68
- package/dist/core/ask-origin.d.ts +42 -24
- package/dist/core/ask-origin.js +18 -13
- package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
- package/dist/core/auto-mode-prompt-assets.js +1 -1
- package/dist/core/auto-mode-prompt.d.ts +11 -1
- package/dist/core/auto-mode-prompt.js +13 -10
- package/dist/core/auto-mode-rebuild.d.ts +7 -0
- package/dist/core/auto-mode-rebuild.js +4 -1
- package/dist/core/canonical-json.d.ts +3 -0
- package/dist/core/canonical-json.js +2 -1
- package/dist/core/checkpoint-requirements.d.ts +892 -0
- package/dist/core/checkpoint-requirements.js +333 -0
- package/dist/core/checkpoint-store.d.ts +95 -66
- package/dist/core/checkpoint-store.js +14 -26
- package/dist/core/child-clamp-seats.d.ts +228 -69
- package/dist/core/child-clamp-seats.js +211 -17
- package/dist/core/classifier-unavailable-arm.d.ts +5 -1
- package/dist/core/classifier-unavailable-arm.js +3 -3
- package/dist/core/compliance.d.ts +3 -0
- package/dist/core/compliance.js +9 -4
- package/dist/core/credential-vocabulary.d.ts +140 -0
- package/dist/core/credential-vocabulary.js +131 -0
- package/dist/core/decision-receipt.js +1 -1
- package/dist/core/effective-path-target.d.ts +73 -16
- package/dist/core/effective-path-target.js +63 -33
- package/dist/core/engine-notice.d.ts +32 -7
- package/dist/core/file-history-store.js +2 -2
- package/dist/core/fs-write-gate-policy.d.ts +4 -0
- package/dist/core/fs-write-gate-policy.js +22 -5
- package/dist/core/gate-bounded-await.d.ts +28 -13
- package/dist/core/gate-bounded-await.js +41 -4
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +24 -25
- package/dist/core/gate-lanes.js +16 -15
- package/dist/core/gate-outcome.d.ts +20 -5
- package/dist/core/gate-outcome.js +5 -0
- package/dist/core/governance-codes.d.ts +11 -4
- package/dist/core/governance-codes.js +14 -3
- package/dist/core/hooks.d.ts +4 -0
- package/dist/core/locked-config.d.ts +8 -0
- package/dist/core/locked-config.js +14 -2
- package/dist/core/lsp.js +3 -5
- package/dist/core/mailbox-store.d.ts +3 -4
- package/dist/core/mcp-connection-pool.d.ts +75 -0
- package/dist/core/mcp-connection-pool.js +128 -0
- package/dist/core/mcp-failure.d.ts +2 -1
- package/dist/core/mcp-failure.js +13 -2
- package/dist/core/mcp-server-spec.d.ts +1 -1
- package/dist/core/mcp.d.ts +4 -0
- package/dist/core/mcp.js +70 -43
- package/dist/core/memory-engine/content-origin.js +2 -14
- package/dist/core/memory-engine/engine.d.ts +32 -22
- package/dist/core/memory-engine/engine.js +103 -55
- package/dist/core/memory-engine/file-backend.d.ts +13 -30
- package/dist/core/memory-engine/file-backend.js +37 -252
- package/dist/core/memory-engine/index.d.ts +1 -1
- package/dist/core/memory-engine/index.js +1 -1
- package/dist/core/memory-engine/layout.d.ts +139 -9
- package/dist/core/memory-engine/layout.js +350 -7
- package/dist/core/memory-engine/scope-contract.d.ts +10 -0
- package/dist/core/memory-engine/scope-contract.js +8 -0
- package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
- package/dist/core/memory-engine/session-incarnation.js +5 -2
- package/dist/core/memory-engine/types.d.ts +10 -1
- package/dist/core/memory.js +5 -17
- package/dist/core/model-seat.d.ts +4 -4
- package/dist/core/model-seat.js +1 -1
- package/dist/core/mounted-mcp.d.ts +57 -0
- package/dist/core/mounted-mcp.js +19 -0
- package/dist/core/namespaced-rule-name.d.ts +29 -0
- package/dist/core/namespaced-rule-name.js +52 -0
- package/dist/core/park-selfcheck.d.ts +1 -1
- package/dist/core/park-selfcheck.js +16 -6
- package/dist/core/path-guard-rows.d.ts +99 -0
- package/dist/core/path-guard-rows.js +45 -0
- package/dist/core/path-identity.d.ts +22 -16
- package/dist/core/path-identity.js +10 -10
- package/dist/core/path-rule-binding.d.ts +2 -1
- package/dist/core/path-rule-binding.js +3 -1
- package/dist/core/pause-registry.d.ts +16 -2
- package/dist/core/pause-registry.js +6 -0
- package/dist/core/permission-rule-consent.js +0 -7
- package/dist/core/permission-rule-model.d.ts +68 -24
- package/dist/core/permission-rule-model.js +105 -24
- package/dist/core/permission-rule-store.js +2 -2
- package/dist/core/permission-rules.d.ts +3 -30
- package/dist/core/permission-rules.js +4 -54
- package/dist/core/read-root-candidate.d.ts +1 -3
- package/dist/core/read-root-candidate.js +4 -15
- package/dist/core/real-approval.d.ts +4 -3
- package/dist/core/retired-keys.d.ts +13 -0
- package/dist/core/retired-keys.js +14 -0
- package/dist/core/roles.d.ts +2 -3
- package/dist/core/roles.js +15 -6
- package/dist/core/runner/assemble-result.d.ts +0 -7
- package/dist/core/runner/assemble-result.js +19 -31
- package/dist/core/runner/caller-roster.d.ts +78 -0
- package/dist/core/runner/caller-roster.js +219 -0
- package/dist/core/runner/checkpoint-scope.d.ts +16 -16
- package/dist/core/runner/checkpoint-scope.js +2 -2
- package/dist/core/runner/child-tree.js +2 -2
- package/dist/core/runner/contracts.d.ts +68 -35
- package/dist/core/runner/decide-continuation.d.ts +51 -3
- package/dist/core/runner/decide-continuation.js +76 -21
- package/dist/core/runner/denial-limit-arms.d.ts +17 -5
- package/dist/core/runner/denial-limit-arms.js +11 -9
- package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
- package/dist/core/runner/extra-body-dropped-seat.js +22 -0
- package/dist/core/runner/finish-reason-seat.d.ts +9 -0
- package/dist/core/runner/finish-reason-seat.js +40 -0
- package/dist/core/runner/gate-exit.d.ts +44 -32
- package/dist/core/runner/gate-exit.js +112 -25
- package/dist/core/runner/inherited-ask-grants.js +6 -4
- package/dist/core/runner/mcp-redial.d.ts +3 -3
- package/dist/core/runner/mcp-redial.js +3 -4
- package/dist/core/runner/park-commit.d.ts +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
- package/dist/core/runner/permission-rule-lanes.js +5 -4
- package/dist/core/runner/prepare-artifact.d.ts +4 -0
- package/dist/core/runner/prepare-artifact.js +2 -1
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
- package/dist/core/runner/prepare-ask-lane.js +12 -6
- package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
- package/dist/core/runner/prepare-boundary-parks.js +4 -7
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
- package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
- package/dist/core/runner/prepare-config-doors.d.ts +9 -9
- package/dist/core/runner/prepare-config-doors.js +10 -5
- package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
- package/dist/core/runner/prepare-defer-classify.js +5 -3
- package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
- package/dist/core/runner/prepare-delegation-surface.js +3 -3
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
- package/dist/core/runner/prepare-gate-stations.js +9 -7
- package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
- package/dist/core/runner/prepare-hands-readface.js +7 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
- package/dist/core/runner/prepare-inherited-gate.js +14 -15
- package/dist/core/runner/prepare-listings.d.ts +7 -24
- package/dist/core/runner/prepare-listings.js +4 -5
- package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
- package/dist/core/runner/prepare-memory-engine-session.js +4 -3
- package/dist/core/runner/prepare-memory.d.ts +6 -0
- package/dist/core/runner/prepare-memory.js +13 -13
- package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
- package/dist/core/runner/prepare-offload-wrappers.js +3 -3
- package/dist/core/runner/prepare-park-ask.d.ts +7 -8
- package/dist/core/runner/prepare-park-ask.js +17 -10
- package/dist/core/runner/prepare-policy-chain.js +24 -44
- package/dist/core/runner/prepare-project-context.d.ts +1 -1
- package/dist/core/runner/prepare-project-context.js +3 -4
- package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
- package/dist/core/runner/prepare-protocol-tools.js +3 -4
- package/dist/core/runner/prepare-run-refs.d.ts +3 -0
- package/dist/core/runner/prepare-run-refs.js +2 -1
- package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
- package/dist/core/runner/prepare-safety-scan.js +1 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
- package/dist/core/runner/prepare-suspend-saga.js +28 -12
- package/dist/core/runner/prepare-task.d.ts +1 -1
- package/dist/core/runner/prepare-task.js +67 -56
- package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
- package/dist/core/runner/prepare-wiring-manifest.js +5 -8
- package/dist/core/runner/resume-apply.js +7 -14
- package/dist/core/runner/resume-checkpoint-screen.js +11 -4
- package/dist/core/runner/resume-internals-and-config.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +5 -32
- package/dist/core/runner/resume-review-outcome.js +4 -1
- package/dist/core/runner/retired-runner-deps.d.ts +6 -0
- package/dist/core/runner/retired-runner-deps.js +10 -1
- package/dist/core/runner/run-brain-sinks.d.ts +4 -0
- package/dist/core/runner/run-brain-sinks.js +5 -2
- package/dist/core/runner/run-harness-handlers.js +27 -34
- package/dist/core/runner/run-leg.d.ts +0 -2
- package/dist/core/runner/run-leg.js +32 -33
- package/dist/core/runner/run-terminal-adoption.js +4 -3
- package/dist/core/runner/runtask.js +8 -8
- package/dist/core/runner/session-rule-policy.js +5 -5
- package/dist/core/runner/stream-settle-backstop.js +7 -4
- package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
- package/dist/core/runner/sub-agent-deny-lists.js +111 -80
- package/dist/core/runner/terminal-account.d.ts +48 -0
- package/dist/core/runner/terminal-account.js +186 -0
- package/dist/core/runner/tool-end-body.d.ts +54 -17
- package/dist/core/runner/tool-end-body.js +27 -2
- package/dist/core/runner/tool-face-overlay.d.ts +3 -1
- package/dist/core/runner/tool-face-overlay.js +6 -4
- package/dist/core/runner/tool-occurrence.d.ts +106 -0
- package/dist/core/runner/tool-occurrence.js +123 -0
- package/dist/core/runner/tool-progress-lane.d.ts +16 -8
- package/dist/core/runner/tool-progress-lane.js +25 -34
- package/dist/core/runner/turn-attachments.d.ts +1 -1
- package/dist/core/runner/write-protection-station.d.ts +21 -9
- package/dist/core/runner/write-protection-station.js +20 -17
- package/dist/core/runner-deps.d.ts +12 -22
- package/dist/core/safety-axis-vocab.d.ts +1 -1
- package/dist/core/safety-merge-corpus.d.ts +1 -1
- package/dist/core/secret-env.d.ts +16 -5
- package/dist/core/secret-env.js +23 -63
- package/dist/core/sensitive-path-policy.d.ts +19 -18
- package/dist/core/sensitive-path-policy.js +73 -49
- package/dist/core/session-policy-store.d.ts +6 -3
- package/dist/core/session-policy-store.js +28 -10
- package/dist/core/session-reconcile.d.ts +3 -0
- package/dist/core/session-reconcile.js +5 -4
- package/dist/core/session-store.d.ts +5 -0
- package/dist/core/session-store.js +12 -0
- package/dist/core/session.d.ts +13 -0
- package/dist/core/shared-memory/normalize.d.ts +17 -4
- package/dist/core/shared-memory/normalize.js +7 -7
- package/dist/core/shell-lexer.js +5 -4
- package/dist/core/shell-wrapper-table.d.ts +2 -2
- package/dist/core/shell-wrapper-table.js +1 -1
- package/dist/core/skill-grant.js +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/synthetic-read-verdict.js +2 -2
- package/dist/core/task-event.d.ts +59 -5
- package/dist/core/task-result.d.ts +1 -1
- package/dist/core/task-spec.d.ts +42 -9
- package/dist/core/terminal-cause.d.ts +94 -11
- package/dist/core/tighten-task-spec.d.ts +5 -4
- package/dist/core/tighten-task-spec.js +20 -25
- package/dist/core/tool-catalog-entries.d.ts +5 -7
- package/dist/core/tool-catalog-entries.js +14 -15
- package/dist/core/tool-face.d.ts +47 -0
- package/dist/core/tool-face.js +5 -0
- package/dist/core/tool-model-gate.d.ts +5 -5
- package/dist/core/tool-name-aliases.d.ts +35 -10
- package/dist/core/tool-name-aliases.js +15 -0
- package/dist/core/tool-name-list.d.ts +30 -0
- package/dist/core/tool-name-list.js +55 -0
- package/dist/core/tool-name-readings.d.ts +1 -9
- package/dist/core/tool-name-readings.js +1 -3
- package/dist/core/tool-policy.d.ts +195 -85
- package/dist/core/tool-policy.js +165 -381
- package/dist/core/tool-registry.d.ts +44 -1
- package/dist/core/tool-registry.js +26 -0
- package/dist/core/tool-roster.d.ts +19 -1
- package/dist/core/tool-roster.js +21 -2
- package/dist/core/tool-spec-members.d.ts +45 -0
- package/dist/core/tool-spec-members.js +169 -0
- package/dist/core/tool-spec.d.ts +46 -8
- package/dist/core/tools.d.ts +6 -2
- package/dist/core/tools.js +8 -4
- package/dist/core/untrusted-egress.js +29 -26
- package/dist/core/untrusted-text.d.ts +13 -10
- package/dist/core/untrusted-text.js +6 -44
- package/dist/core/workflow-journal-store.d.ts +4 -1
- package/dist/core/write-protect.d.ts +65 -29
- package/dist/core/write-protect.js +235 -177
- package/dist/engine/compaction/compaction.d.ts +2 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
- package/dist/engine/execution-env/node-execution-env.js +16 -38
- package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
- package/dist/engine/execution-env/symlink-chain.js +32 -0
- package/dist/engine/harness/types.d.ts +7 -0
- package/dist/engine/llm/tool-turns.d.ts +3 -0
- package/dist/engine/llm/tool-turns.js +1 -0
- package/dist/engine/llm/types.d.ts +59 -23
- package/dist/engine/loop/agent-loop.js +16 -2
- package/dist/engine/session/memory-repo.js +11 -3
- package/dist/engine/session/repo-utils.d.ts +8 -0
- package/dist/engine/session/repo-utils.js +13 -0
- package/dist/index.d.ts +20 -23
- package/dist/index.js +17 -20
- package/dist/internal/harness.d.ts +1 -1
- package/dist/internal/harness.js +1 -1
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/governance-baseline-validity.js +1 -1
- package/dist/orchestration/run-spec.js +3 -3
- package/dist/orchestration/run-workflow-tool.d.ts +16 -35
- package/dist/orchestration/run-workflow-tool.js +38 -78
- package/dist/orchestration/workflow-governance.d.ts +21 -25
- package/dist/orchestration/workflow-governance.js +38 -78
- package/dist/orchestration/workflow-primitives.d.ts +7 -22
- package/dist/orchestration/workflow-primitives.js +5 -12
- package/dist/orchestration/workflow-types.d.ts +1 -1
- package/dist/orchestration/workflow.d.ts +61 -11
- package/dist/orchestration/workflow.js +191 -119
- package/dist/prompt-assembly/types.d.ts +1 -1
- package/dist/scenarios/full-body.d.ts +1 -1
- package/dist/shell/lex.d.ts +0 -21
- package/dist/shell/lex.js +278 -70
- package/dist/shell/shell-words.d.ts +35 -0
- package/dist/shell/shell-words.js +65 -0
- package/dist/stores/file/checkpoint-store.d.ts +5 -5
- package/dist/stores/file/checkpoint-store.js +5 -2
- package/dist/stores/file/index.d.ts +0 -8
- package/dist/stores/file/index.js +0 -12
- package/dist/stores/file/session-store.d.ts +3 -0
- package/dist/stores/file/session-store.js +44 -19
- package/dist/tools/artifact/artifact-tool.js +2 -0
- package/dist/tools/fs/bash-program-position.d.ts +17 -3
- package/dist/tools/fs/bash-program-position.js +25 -10
- package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
- package/dist/tools/fs/bash-readonly-classifier.js +8 -7
- package/dist/tools/fs/containment-face.d.ts +4 -0
- package/dist/tools/fs/containment-face.js +3 -0
- package/dist/tools/fs/fs-shared.d.ts +10 -0
- package/dist/tools/fs/fs-shared.js +18 -0
- package/dist/tools/fs/fs-write.js +4 -2
- package/dist/tools/fs/index.d.ts +3 -2
- package/dist/tools/fs/index.js +2 -2
- package/dist/tools/fs/program-read-model.d.ts +99 -23
- package/dist/tools/fs/program-read-model.js +129 -55
- package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
- package/dist/tools/fs/program-read-model.rows.js +18 -10
- package/dist/tools/fs/read-deny-home.d.ts +35 -30
- package/dist/tools/fs/read-deny-home.js +45 -38
- package/dist/tools/fs/read-deny.d.ts +35 -27
- package/dist/tools/fs/read-deny.js +126 -92
- package/dist/tools/fs/removal-targets.d.ts +56 -23
- package/dist/tools/fs/removal-targets.js +74 -87
- package/dist/tools/fs/safety.d.ts +29 -22
- package/dist/tools/fs/safety.js +17 -11
- package/dist/tools/fs/search.js +10 -8
- package/dist/tools/fs/shell-read-argv.d.ts +4 -7
- package/dist/tools/fs/shell-read-argv.js +6 -8
- package/dist/tools/fs/shell-read-bindings.d.ts +203 -46
- package/dist/tools/fs/shell-read-bindings.js +488 -144
- package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
- package/dist/tools/fs/shell-read-builtins.js +43 -0
- package/dist/tools/fs/shell-read-check.d.ts +15 -1
- package/dist/tools/fs/shell-read-check.js +51 -42
- package/dist/tools/fs/shell-read-establish.js +9 -10
- package/dist/tools/fs/shell-read-functions.d.ts +22 -0
- package/dist/tools/fs/shell-read-functions.js +29 -0
- package/dist/tools/fs/shell-read-judge.d.ts +48 -18
- package/dist/tools/fs/shell-read-judge.js +33 -4
- package/dist/tools/fs/shell-read-plan.d.ts +13 -20
- package/dist/tools/fs/shell-read-plan.js +200 -194
- package/dist/tools/fs/shell-read-start.d.ts +80 -0
- package/dist/tools/fs/shell-read-start.js +99 -0
- package/dist/tools/fs/shell-read-word.d.ts +35 -6
- package/dist/tools/fs/shell-read-word.js +89 -9
- package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
- package/dist/tools/fs/shell-read-workdir.js +281 -0
- package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
- package/dist/tools/fs/shell-read-write-targets.js +14 -5
- package/dist/tools/fs/shell-reentry-text.d.ts +26 -26
- package/dist/tools/fs/shell-reentry-text.js +31 -34
- package/dist/tools/task-list.d.ts +1 -2
- package/dist/tools/web.js +1 -1
- package/package.json +4 -1
- package/test/export-surface.snapshot.json +107 -143
- package/wire-changes/core@7.48.0.json +252 -0
- package/wire-changes/core@7.49.0.json +4765 -0
- package/dist/agents/teacher.d.ts +0 -159
- package/dist/agents/teacher.js +0 -577
- package/dist/agents/team.d.ts +0 -226
- package/dist/agents/team.js +0 -257
- package/dist/core/strategy-store.d.ts +0 -238
- package/dist/core/strategy-store.js +0 -253
- package/dist/orchestration/builtin-workflows.d.ts +0 -133
- package/dist/orchestration/builtin-workflows.js +0 -159
- package/dist/scenarios/env.d.ts +0 -40
- package/dist/scenarios/env.js +0 -39
- package/dist/scenarios/scenario-registry.d.ts +0 -110
- package/dist/scenarios/scenario-registry.js +0 -140
- package/dist/scenarios/teacher-quickstart.d.ts +0 -40
- package/dist/scenarios/teacher-quickstart.js +0 -12
- package/dist/stores/cc/lockfile.d.ts +0 -10
- package/dist/stores/cc/lockfile.js +0 -98
- package/dist/stores/cc/mailbox-store.d.ts +0 -20
- package/dist/stores/cc/mailbox-store.js +0 -255
- package/dist/stores/cc/roster-adapter.d.ts +0 -12
- package/dist/stores/cc/roster-adapter.js +0 -117
- package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
- package/dist/stores/cc/sidecar-transcript.js +0 -264
- package/dist/stores/cc/task-list-store.d.ts +0 -2
- package/dist/stores/cc/task-list-store.js +0 -125
- package/dist/stores/file/strategy-store.d.ts +0 -97
- package/dist/stores/file/strategy-store.js +0 -341
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { argvOf, lexShell } from "../../shell/lex.js";
|
|
2
|
+
import { shellWordsOf } from "../../shell/shell-words.js";
|
|
3
|
+
import { resolveOperandLexically } from "./bash-readonly-classifier.js";
|
|
4
|
+
import { readProgramPosition } from "./bash-program-position.js";
|
|
5
|
+
import { valueOf } from "./shell-read-bindings.js";
|
|
6
|
+
import { evalDefinedFunctions, functionCallOf } from "./shell-read-functions.js";
|
|
7
|
+
import { codeBodies } from "./shell-reentry-text.js";
|
|
8
|
+
import { isAbsoluteForFamily } from "./safety.js";
|
|
9
|
+
const TEXT_RUNNING_PROGRAMS = new Set(["eval", "source", "."]);
|
|
10
|
+
const BASE_CANDIDATE_MAX = 256;
|
|
11
|
+
const tableSays = (name, at, ctx) => ctx.textBinds(name) || at.table.commandSets.has(name);
|
|
12
|
+
export class WorkdirThread {
|
|
13
|
+
readable;
|
|
14
|
+
candidates;
|
|
15
|
+
lostAt = false;
|
|
16
|
+
floors;
|
|
17
|
+
physical;
|
|
18
|
+
movedAt = -1;
|
|
19
|
+
constructor(start, readable, startsPhysical = false) {
|
|
20
|
+
this.readable = readable;
|
|
21
|
+
this.physical = startsPhysical;
|
|
22
|
+
this.lostAt = start === "unmodelled";
|
|
23
|
+
this.candidates = start === "unmodelled" ? [] : start.map((c) => (typeof c === "string" ? { base: c, skippedCd: -1, ...(readable && isAbsoluteForFamily("own", c) ? { pwd: c } : {}), dirStack: [] } : { ...c, skippedCd: -1 }));
|
|
24
|
+
}
|
|
25
|
+
get lost() {
|
|
26
|
+
return this.lostAt;
|
|
27
|
+
}
|
|
28
|
+
get floorBases() {
|
|
29
|
+
return this.floors;
|
|
30
|
+
}
|
|
31
|
+
reachable(andRunStart) {
|
|
32
|
+
return this.candidates.filter((c) => c.skippedCd < andRunStart);
|
|
33
|
+
}
|
|
34
|
+
end() {
|
|
35
|
+
return this.lostAt ? "unmodelled" : this.candidates;
|
|
36
|
+
}
|
|
37
|
+
where(andRunStart) {
|
|
38
|
+
if (this.lostAt || !this.readable)
|
|
39
|
+
return { PWD: "unknown", OLDPWD: "unknown", movedAt: this.movedAt };
|
|
40
|
+
const reachable = this.reachable(andRunStart);
|
|
41
|
+
const values = (pick) => {
|
|
42
|
+
const out = new Set();
|
|
43
|
+
for (const c of reachable) {
|
|
44
|
+
const v = pick(c);
|
|
45
|
+
if (v === undefined)
|
|
46
|
+
return "unknown";
|
|
47
|
+
out.add(v);
|
|
48
|
+
}
|
|
49
|
+
return [...out].map((spelled) => ({ spelled }));
|
|
50
|
+
};
|
|
51
|
+
return { PWD: values((c) => c.pwd), OLDPWD: values((c) => c.old), movedAt: this.movedAt };
|
|
52
|
+
}
|
|
53
|
+
setPhysical() {
|
|
54
|
+
this.physical = true;
|
|
55
|
+
}
|
|
56
|
+
get mayBePhysical() {
|
|
57
|
+
return this.physical;
|
|
58
|
+
}
|
|
59
|
+
lose(at, reachable, floorTargets = []) {
|
|
60
|
+
this.movedAt = Math.max(this.movedAt, at);
|
|
61
|
+
this.lostAt = true;
|
|
62
|
+
this.floors ??= [...new Set([...reachable.map((c) => c.base), ...floorTargets])];
|
|
63
|
+
}
|
|
64
|
+
shift(si, at, ctx) {
|
|
65
|
+
if (this.lostAt) {
|
|
66
|
+
if (this.floors !== undefined && this.floors.length > 0)
|
|
67
|
+
this.floors = [...new Set([...this.floors, ...floorOf(at.shift, this.reachable(at.andRunStart), ctx)])];
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.movedAt = si;
|
|
71
|
+
const reachable = this.reachable(at.andRunStart);
|
|
72
|
+
const s = at.shift;
|
|
73
|
+
if (s.kind === "lost")
|
|
74
|
+
return this.lose(si, reachable);
|
|
75
|
+
if (s.kind === "stack") {
|
|
76
|
+
this.candidates = this.candidates.map(({ dirStack: _, ...c }) => c);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const branched = [];
|
|
80
|
+
for (const c of this.candidates) {
|
|
81
|
+
if (c.skippedCd < at.andRunStart) {
|
|
82
|
+
const moved = this.movedFrom(c, at, ctx);
|
|
83
|
+
if (moved === "lost")
|
|
84
|
+
return this.lose(si, reachable, floorOf(s, reachable, ctx));
|
|
85
|
+
for (const m of moved)
|
|
86
|
+
branched.push({ ...m, skippedCd: c.skippedCd });
|
|
87
|
+
}
|
|
88
|
+
branched.push({ ...c, skippedCd: at.provable ? si : c.skippedCd });
|
|
89
|
+
}
|
|
90
|
+
const byKey = new Map();
|
|
91
|
+
for (const c of branched) {
|
|
92
|
+
const key = JSON.stringify([c.base, c.pwd, c.old, c.dirStack]);
|
|
93
|
+
const prior = byKey.get(key);
|
|
94
|
+
if (prior === undefined || c.skippedCd < prior.skippedCd)
|
|
95
|
+
byKey.set(key, c);
|
|
96
|
+
}
|
|
97
|
+
const next = [...byKey.values()];
|
|
98
|
+
if (next.length > BASE_CANDIDATE_MAX)
|
|
99
|
+
this.lose(si, reachable);
|
|
100
|
+
else
|
|
101
|
+
this.candidates = next;
|
|
102
|
+
}
|
|
103
|
+
movedFrom(c, at, ctx) {
|
|
104
|
+
const s = at.shift;
|
|
105
|
+
if (s.kind === "eval") {
|
|
106
|
+
const ran = ctx.evalEnd(s.text, c, at.table);
|
|
107
|
+
if (ran.physical)
|
|
108
|
+
this.physical = true;
|
|
109
|
+
return ran.end === "unmodelled" ? "lost" : ran.end.map((e) => (this.physical ? withoutPwd(e) : e));
|
|
110
|
+
}
|
|
111
|
+
const old = tableSays("PWD", at, ctx) ? {} : c.pwd !== undefined ? { old: c.pwd } : {};
|
|
112
|
+
const land = (base, physical, stack) => ({ base, skippedCd: c.skippedCd, ...(physical || this.physical || !this.readable ? {} : { pwd: base }), ...old, ...(stack !== undefined ? { dirStack: stack } : {}) });
|
|
113
|
+
if (s.kind === "swap" || s.kind === "pop") {
|
|
114
|
+
const top = c.dirStack?.[0];
|
|
115
|
+
if (top === undefined)
|
|
116
|
+
return "lost";
|
|
117
|
+
return [land(top, false, s.kind === "swap" ? [c.base, ...c.dirStack.slice(1)] : c.dirStack.slice(1))];
|
|
118
|
+
}
|
|
119
|
+
if (s.kind !== "cd")
|
|
120
|
+
return "lost";
|
|
121
|
+
const stack = s.push === true ? (c.dirStack === undefined ? undefined : [c.base, ...c.dirStack]) : c.dirStack;
|
|
122
|
+
const targets = targetsOf(s.target, c, at, ctx);
|
|
123
|
+
if (targets === "lost")
|
|
124
|
+
return "lost";
|
|
125
|
+
const out = [];
|
|
126
|
+
for (const t of targets) {
|
|
127
|
+
if ((s.physical || this.physical || c.pwd === undefined) && t.split("/").includes(".."))
|
|
128
|
+
return "lost";
|
|
129
|
+
const moved = resolveOperandLexically(c.base, t, ctx.homeDir);
|
|
130
|
+
if (moved === undefined)
|
|
131
|
+
return "lost";
|
|
132
|
+
out.push(land(moved, s.physical, stack));
|
|
133
|
+
}
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const withoutPwd = ({ pwd: _, ...c }) => c;
|
|
138
|
+
function floorOf(s, reachable, ctx) {
|
|
139
|
+
if (s.kind !== "cd")
|
|
140
|
+
return [];
|
|
141
|
+
if (s.target === "home")
|
|
142
|
+
return ctx.homeDir !== undefined ? [ctx.homeDir] : [];
|
|
143
|
+
if (typeof s.target === "string")
|
|
144
|
+
return [];
|
|
145
|
+
const target = s.target;
|
|
146
|
+
return [...(target.floorSpelled !== undefined ? [target.floorSpelled] : []), ...(target.expands === false ? reachable.flatMap((c) => resolveOperandLexically(c.base, target.spelled, ctx.homeDir) ?? []) : [])];
|
|
147
|
+
}
|
|
148
|
+
function targetsOf(target, c, at, ctx) {
|
|
149
|
+
if (target === "home")
|
|
150
|
+
return settledValues(at.table.stateOf("HOME"));
|
|
151
|
+
if (target === "previous")
|
|
152
|
+
return tableSays("OLDPWD", at, ctx) ? settledValues(at.table.stateOf("OLDPWD")) : c.old === undefined ? "lost" : [c.old];
|
|
153
|
+
if (target.expands !== false)
|
|
154
|
+
return "lost";
|
|
155
|
+
const dir = target.spelled;
|
|
156
|
+
if (!searchesCdPath(dir))
|
|
157
|
+
return [dir];
|
|
158
|
+
if (at.cdable && /^[A-Za-z_][A-Za-z0-9_]*$/.test(dir))
|
|
159
|
+
return "lost";
|
|
160
|
+
const cdPath = settledValues(at.table.stateOf("CDPATH"));
|
|
161
|
+
if (cdPath === "lost")
|
|
162
|
+
return "lost";
|
|
163
|
+
const entries = cdPath.flatMap((v) => (v === "" ? [] : v.split(":")));
|
|
164
|
+
return [...new Set([...entries.map((e) => (e === "" ? dir : `${e.replace(/\/+$/, "")}/${dir}`)), dir])];
|
|
165
|
+
}
|
|
166
|
+
export function searchesCdPath(dir) {
|
|
167
|
+
return dir !== "" && !isAbsoluteForFamily("own", dir) && !/^\.\.?(?:\/|$)/.test(dir) && !dir.startsWith("~");
|
|
168
|
+
}
|
|
169
|
+
function settledValues(state) {
|
|
170
|
+
if (state === "unknown" || state.some((v) => v.glob === true))
|
|
171
|
+
return "lost";
|
|
172
|
+
return state.map((v) => v.spelled);
|
|
173
|
+
}
|
|
174
|
+
export function baseShiftOf(program, args, targetOf) {
|
|
175
|
+
if (program === "cd") {
|
|
176
|
+
let physical = false;
|
|
177
|
+
let at = 0;
|
|
178
|
+
for (; at < args.length; at++) {
|
|
179
|
+
const w = args[at].folded;
|
|
180
|
+
if (w === "--") {
|
|
181
|
+
at++;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
if (!w.startsWith("-") || w === "-")
|
|
185
|
+
break;
|
|
186
|
+
for (const letter of w.slice(1)) {
|
|
187
|
+
if (letter === "P")
|
|
188
|
+
physical = true;
|
|
189
|
+
else if (letter === "L")
|
|
190
|
+
physical = false;
|
|
191
|
+
else if (letter !== "e" && letter !== "@")
|
|
192
|
+
return { shift: { kind: "lost" }, reported: "unmodelled" };
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (at >= args.length)
|
|
196
|
+
return { shift: { kind: "cd", target: "home", physical }, reported: "home" };
|
|
197
|
+
if (args[at].folded === "-")
|
|
198
|
+
return { shift: { kind: "cd", target: "previous", physical }, reported: "previous" };
|
|
199
|
+
const target = targetOf(args[at]);
|
|
200
|
+
return { shift: { kind: "cd", target, physical }, reported: target };
|
|
201
|
+
}
|
|
202
|
+
if (shellWordsOf("stack_mover").has(program)) {
|
|
203
|
+
const words = args.map((a) => a.folded);
|
|
204
|
+
if (words.some((w) => w === "-n"))
|
|
205
|
+
return { shift: { kind: "stack" }, reported: "unmodelled" };
|
|
206
|
+
if (words.some((w) => /^[+-]\d+$/.test(w)) || words.some((w) => w.startsWith("-") && w !== "--"))
|
|
207
|
+
return { shift: { kind: "lost" }, reported: "unmodelled" };
|
|
208
|
+
const operand = args.find((a) => a.folded !== "--");
|
|
209
|
+
if (program === "popd")
|
|
210
|
+
return { shift: operand === undefined ? { kind: "pop" } : { kind: "lost" }, reported: "unmodelled" };
|
|
211
|
+
if (operand === undefined)
|
|
212
|
+
return { shift: { kind: "swap" }, reported: "unmodelled" };
|
|
213
|
+
return { shift: { kind: "cd", target: targetOf(operand), physical: false, push: true }, reported: targetOf(operand) };
|
|
214
|
+
}
|
|
215
|
+
if (shellWordsOf("stack_editor").has(program) && args.some((a) => a.folded.startsWith("-") || a.folded.startsWith("+")))
|
|
216
|
+
return { shift: { kind: "stack" } };
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
export function textMayMove(text, functions) {
|
|
220
|
+
const lexed = lexShell(text);
|
|
221
|
+
if ("parseFailure" in lexed)
|
|
222
|
+
return true;
|
|
223
|
+
return lexed.segments.some((s) => segmentMayMove(argvOf(s), functions));
|
|
224
|
+
}
|
|
225
|
+
const programOf = (argv) => {
|
|
226
|
+
const pos = readProgramPosition(argv);
|
|
227
|
+
return pos.program === undefined ? undefined : { name: pos.program.basename, args: argv.slice(pos.program.index + 1).map((w) => w.folded) };
|
|
228
|
+
};
|
|
229
|
+
const setsPhysical = (p) => p?.name === "set" && p.args.some((a, k) => /^-[A-Za-z]*P/.test(a) || (a === "-o" && p.args[k + 1] === "physical"));
|
|
230
|
+
export function textSetsPhysical(text) {
|
|
231
|
+
const lexed = lexShell(text);
|
|
232
|
+
return !("parseFailure" in lexed) && lexed.segments.some((s) => setsPhysical(programOf(argvOf(s))));
|
|
233
|
+
}
|
|
234
|
+
export function withCommandEnvironment(table, argv) {
|
|
235
|
+
const overlay = new Map();
|
|
236
|
+
const overlaid = () => ({ ...table, stateOf: (name) => overlay.get(name) ?? table.stateOf(name) });
|
|
237
|
+
for (const k of readProgramPosition(argv).assignments) {
|
|
238
|
+
const a = argv[k].assignment;
|
|
239
|
+
if (a === undefined)
|
|
240
|
+
continue;
|
|
241
|
+
if (a.op !== "=" || a.subscript !== undefined || a.form !== "scalar" || a.value.unresolved !== undefined) {
|
|
242
|
+
overlay.set(a.name, "unknown");
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
const before = valueOf({ pieces: a.value.pieces }, table, true);
|
|
246
|
+
const ordered = valueOf({ pieces: a.value.pieces }, overlaid(), true);
|
|
247
|
+
overlay.set(a.name, before === "unknown" || ordered === "unknown" ? "unknown" : [...before, ...ordered.filter((v) => !before.some((b) => b.spelled === v.spelled))]);
|
|
248
|
+
}
|
|
249
|
+
return { ...overlaid(), commandSets: new Set(overlay.keys()) };
|
|
250
|
+
}
|
|
251
|
+
export function textCalls(text, functions) {
|
|
252
|
+
const lexed = lexShell(text);
|
|
253
|
+
if ("parseFailure" in lexed)
|
|
254
|
+
return true;
|
|
255
|
+
return lexed.segments.some((s) => functionCallOf(argvOf(s), functions) !== undefined);
|
|
256
|
+
}
|
|
257
|
+
export function segmentMayMove(argv, functions) {
|
|
258
|
+
const pos = readProgramPosition(argv);
|
|
259
|
+
if (pos.program === undefined)
|
|
260
|
+
return false;
|
|
261
|
+
const word = argv[pos.program.index];
|
|
262
|
+
return shellWordsOf("base_mover").has(pos.program.basename) || TEXT_RUNNING_PROGRAMS.has(pos.program.basename) || functionCallOf(argv, functions) !== undefined || word.pieces.some((p) => p.expansion !== undefined || p.literal === undefined);
|
|
263
|
+
}
|
|
264
|
+
export function textMovesOf(defined, argvs, inFunctionBody, inherited) {
|
|
265
|
+
const unread = new Set([...evalDefinedFunctions(argvs), ...(inherited?.unread ?? [])]);
|
|
266
|
+
const functions = new Set([...defined, ...unread, ...(inherited?.functions ?? [])]);
|
|
267
|
+
const programs = argvs.map(programOf);
|
|
268
|
+
const mayMove = argvs.map((argv) => segmentMayMove(argv, functions));
|
|
269
|
+
const bodyMoves = mayMove.some((m, si) => m && inFunctionBody(si));
|
|
270
|
+
const bodiesAt = programs.map((p) => (p === undefined ? [] : codeBodies(p.name, p.args)));
|
|
271
|
+
const mayCallAt = argvs.map((argv) => functionCallOf(argv, functions) !== undefined);
|
|
272
|
+
const runsTextAt = argvs.map((argv) => { const pos = readProgramPosition(argv); const word = pos.program === undefined ? undefined : argv[pos.program.index]; return word !== undefined && (["eval", "source", "."].includes(pos.program.basename) || word.pieces.some((p) => p.expansion !== undefined || p.literal === undefined)); });
|
|
273
|
+
const callAt = (si, table) => functionCallOf(argvs[si], functions, (name) => table.functionState(name));
|
|
274
|
+
const callsUnread = (si, table) => functionCallOf(argvs[si], unread, (name) => table.functionState(name)) !== undefined;
|
|
275
|
+
return {
|
|
276
|
+
functions, unread, mayMove, mayCallAt, runsBodyAt: mayCallAt.map((c, si) => c || runsTextAt[si] || bodiesAt[si].length > 0), bodiesAt, bodyMoves, callAt, callsUnread,
|
|
277
|
+
physicalAt: programs.map(setsPhysical),
|
|
278
|
+
cdableFrom: programs.findIndex((p) => p?.name === "shopt" && p.args.includes("-s") && p.args.includes("cdable_vars")),
|
|
279
|
+
losesBaseAt: (si, table) => (callAt(si, table) !== undefined && bodyMoves) || callsUnread(si, table) || bodiesAt[si].some((b) => bodyMoves || textMayMove(b, functions)),
|
|
280
|
+
};
|
|
281
|
+
}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* writes, the operands an option made edited in place, a copy's destination and its children, an in-place edit's
|
|
6
6
|
* backups), at the seats the role and the selected options name ({@link WriteSeat}: the directory entry, or where the
|
|
7
7
|
* path lands). The establisher (`shell-read-establish.ts`) places what this module names; the judge reads the result
|
|
8
|
-
* on the deny
|
|
8
|
+
* on the write face (the write deny rows, then the write roots). No table of programs or options lives here: what a
|
|
9
|
+
* program writes is its row's.
|
|
9
10
|
*/
|
|
10
11
|
import type { ReadCandidate, ShellReadSegment } from "./shell-read-plan.js";
|
|
11
12
|
import { type WriteSeat } from "./program-read-model.js";
|
|
@@ -47,5 +48,7 @@ export interface JudgedCandidate {
|
|
|
47
48
|
}
|
|
48
49
|
/** Every candidate a segment hands the judge: its reads minus the write targets, plus its `cd` target (the plan already
|
|
49
50
|
* lists it among the reads), plus its WRITE targets for the write face ({@link writeTargetsOf}), plus the deny-floor
|
|
50
|
-
* shadow of every unplaced home word ({@link denyFloorShadowsOf}) on both faces.
|
|
51
|
+
* shadow of every unplaced home word ({@link denyFloorShadowsOf}) on both faces. A word the program only writes keeps
|
|
52
|
+
* its read copy for the read deny rows alone (`denyOnly`): whether it lands inside the write roots — or cannot be placed
|
|
53
|
+
* at all — is the write face's question, never a read's. */
|
|
51
54
|
export declare function judgedCandidatesOf(segment: ShellReadSegment): readonly JudgedCandidate[];
|
|
@@ -29,6 +29,7 @@ function writeOwnersOf(segment) {
|
|
|
29
29
|
}
|
|
30
30
|
function writeTargetsOf(segment) {
|
|
31
31
|
const out = [];
|
|
32
|
+
const writeOnly = new Set();
|
|
32
33
|
const write = (c, seats, written, child, onlyIfExists) => void out.push({ candidate: { ...c, face: "write" }, ...(seats !== undefined ? { seats } : {}), ...(written !== undefined ? { written } : {}), ...(child === true ? { child } : {}), ...(onlyIfExists !== undefined ? { onlyIfExists } : {}) });
|
|
33
34
|
for (const r of segment.redirects)
|
|
34
35
|
if (r.direction === "out" && r.target !== undefined)
|
|
@@ -48,9 +49,12 @@ function writeTargetsOf(segment) {
|
|
|
48
49
|
continue;
|
|
49
50
|
const placed = owners.filter((o) => o.words.some((w) => w.raw === c.raw));
|
|
50
51
|
const fallback = placed.length === 0 ? owners.filter((o) => o.program) : [];
|
|
52
|
+
let only = placed.length > 0;
|
|
51
53
|
for (const o of [...placed, ...fallback]) {
|
|
52
|
-
if (o.readings.length === 0)
|
|
54
|
+
if (o.readings.length === 0) {
|
|
55
|
+
only = false;
|
|
53
56
|
continue;
|
|
57
|
+
}
|
|
54
58
|
const at = new Set(o.words.flatMap((w, i) => (w.raw === c.raw ? [i] : [])));
|
|
55
59
|
const roles = [];
|
|
56
60
|
let readings = 0;
|
|
@@ -64,8 +68,11 @@ function writeTargetsOf(segment) {
|
|
|
64
68
|
readings += 1;
|
|
65
69
|
unexplained ||= unplaced;
|
|
66
70
|
}
|
|
67
|
-
if (roles.length === 0)
|
|
71
|
+
if (roles.length === 0) {
|
|
72
|
+
only = false;
|
|
68
73
|
continue;
|
|
74
|
+
}
|
|
75
|
+
only &&= !unexplained && readings === o.all.length && roles.every((role) => role.effect !== "edit-in-place" && role.writtenAt === undefined);
|
|
69
76
|
const stated = roles.some((role) => (o.override ?? role.seats) !== undefined);
|
|
70
77
|
const seats = stated ? [...new Set(roles.flatMap((role) => o.override ?? role.seats ?? ["landing"]))] : undefined;
|
|
71
78
|
const written = unexplained || roles.some((role) => role.writtenAt === undefined) ? undefined : [...new Set(roles.flatMap((role) => role.writtenAt ?? []))];
|
|
@@ -74,13 +81,15 @@ function writeTargetsOf(segment) {
|
|
|
74
81
|
if (roles.some((role) => role.effect === "edit-in-place") && c.expands === false)
|
|
75
82
|
edited.set(o, [...(edited.get(o) ?? []), { candidate: c, ...(speculative !== undefined ? { onlyIfExists: speculative } : {}) }]);
|
|
76
83
|
}
|
|
84
|
+
if (only)
|
|
85
|
+
writeOnly.add(c);
|
|
77
86
|
}
|
|
78
87
|
for (const o of owners) {
|
|
79
88
|
for (const c of copyDestinationChildren(segment, o.words, o.readings))
|
|
80
89
|
write(c, ["landing", "entry"], undefined, true);
|
|
81
90
|
out.push(...backupTargetsOf(edited.get(o) ?? [], o.readings, o.override));
|
|
82
91
|
}
|
|
83
|
-
return out;
|
|
92
|
+
return { targets: out, writeOnly };
|
|
84
93
|
}
|
|
85
94
|
function backupTargetsOf(edited, readings, override) {
|
|
86
95
|
const suffixes = [...new Set(readings.flatMap((r) => r.suffixes))];
|
|
@@ -114,8 +123,8 @@ function copyDestinationChildren(segment, words, readings) {
|
|
|
114
123
|
return [...children.values()];
|
|
115
124
|
}
|
|
116
125
|
export function judgedCandidatesOf(segment) {
|
|
117
|
-
const
|
|
118
|
-
const
|
|
126
|
+
const { targets: writes, writeOnly } = writeTargetsOf(segment);
|
|
127
|
+
const reads = segment.reads.flatMap((c) => (c.provenance === "write_redirect_target" ? [] : [writeOnly.has(c) ? { ...c, denyOnly: true } : c]));
|
|
119
128
|
const plain = (cs) => cs.map((candidate) => ({ candidate }));
|
|
120
129
|
return [...plain(reads), ...plain(denyFloorShadowsOf(reads)), ...writes, ...plain(denyFloorShadowsOf(writes.map((w) => w.candidate)))];
|
|
121
130
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { type LexedSegment, type LexedWord } from "../../shell/lex.js";
|
|
8
8
|
import { type ProgramPosition } from "./bash-program-position.js";
|
|
9
|
+
import { type TargetUser } from "./program-read-model.js";
|
|
9
10
|
import type { BoundValue } from "./shell-read-bindings.js";
|
|
10
11
|
/**
|
|
11
12
|
* The code bodies a builtin keeps among its operands, one per body; empty for every other program. The program read
|
|
@@ -52,6 +53,8 @@ export interface LaunchedCommand {
|
|
|
52
53
|
readonly spelled: string;
|
|
53
54
|
};
|
|
54
55
|
readonly args: readonly LaunchedArg[];
|
|
56
|
+
/** The user the launcher runs it as, where its row says it runs another ({@link targetUserOf}). */
|
|
57
|
+
readonly as?: TargetUser;
|
|
55
58
|
}
|
|
56
59
|
/**
|
|
57
60
|
* What a launcher that runs a program named by no word of its own runs ({@link readProgramPosition}'s `runsShell`: the
|
|
@@ -79,11 +82,11 @@ export declare function launchedReadings(argv: readonly LexedWord[], command: La
|
|
|
79
82
|
readonly shell?: string;
|
|
80
83
|
readonly line?: string;
|
|
81
84
|
};
|
|
82
|
-
/** What a launcher runs ({@link launchedCommands}, {@link launchedReadings}), as a reader of the command line reads it
|
|
83
|
-
* each shell's argv in two spellings — `texts` (a word's literal value, else `spell.text`) and
|
|
84
|
-
* with the argv index each position stands for (`words`),
|
|
85
|
-
*
|
|
86
|
-
* line a program that is no shell runs (`lines`, once each). */
|
|
85
|
+
/** What a launcher runs ({@link launchedCommands}, {@link launchedReadings}), as a reader of the command line reads it in
|
|
86
|
+
* one reading of its names: each shell's argv in two spellings — `texts` (a word's literal value, else `spell.text`) and
|
|
87
|
+
* `args` (`spell.folded`) — with the argv index each position stands for (`words`), its words' fields read off
|
|
88
|
+
* `spell.values` ({@link spellLaunched}) and the user it runs as (`as`); the word naming a shell (`su -s /bin/bash`,
|
|
89
|
+
* `programWords`); and each command line a program that is no shell runs (`lines`, once each). */
|
|
87
90
|
export declare function launchedInput(argv: readonly LexedWord[], pos: ProgramPosition, spell: {
|
|
88
91
|
readonly text: (k: number) => string;
|
|
89
92
|
readonly folded: (k: number) => string;
|
|
@@ -94,6 +97,7 @@ export declare function launchedInput(argv: readonly LexedWord[], pos: ProgramPo
|
|
|
94
97
|
readonly texts: readonly string[];
|
|
95
98
|
readonly args: readonly string[];
|
|
96
99
|
readonly words: readonly (number | undefined)[];
|
|
100
|
+
readonly as?: TargetUser;
|
|
97
101
|
}[];
|
|
98
102
|
readonly programWords: readonly number[];
|
|
99
103
|
readonly lines: readonly string[];
|
|
@@ -107,34 +111,30 @@ export interface LaunchedSpelling {
|
|
|
107
111
|
readonly values?: (at: number) => readonly BoundValue[] | undefined;
|
|
108
112
|
}
|
|
109
113
|
/**
|
|
110
|
-
* The argv a launched shell is handed ({@link launchedCommands}), spelled as `spell` spells the command line's words
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* combinations reading `i` hands each word its `i`-th value (its last where it holds fewer) — every value of every word is
|
|
121
|
-
* still read, the same word spelled twice takes one value per reading as the shell expands it, and the readings stay as
|
|
122
|
-
* many as one word's values: their cost is linear in the command, whatever its length.
|
|
114
|
+
* The argv a launched shell is handed ({@link launchedCommands}), spelled as `spell` spells the command line's words in ONE
|
|
115
|
+
* reading of their names (the plan reads a segment once per combination of its names' values, `segmentReadingsOf` in
|
|
116
|
+
* shell-read-word.ts — a word's value here is its value in that reading). A word an escaping launcher joins (`sudo -s
|
|
117
|
+
* CMD…`) is handed as the launcher hands it: the FIELD the command line's shell gives the launcher, escaped
|
|
118
|
+
* ({@link sudoEscaped}) — the field a literal word spells, or the field the shell established for a word it rewrites first
|
|
119
|
+
* (`X='#'; sudo -s rm -r "$X" d` hands `rm -r \# d`: the value is an operand, never a comment), a pattern's literal
|
|
120
|
+
* characters escaped and its pattern characters bare ({@link launchedSpellingOf}). A word whose field the reader does not
|
|
121
|
+
* know is handed AS WRITTEN: the launched shell re-reads the expansion with the command line's quoting, so the word stays
|
|
122
|
+
* one argument (an unknown there) and its neighbours stay theirs (`"#$Y" d` is never `#$Y d`). Any other launcher hands a
|
|
123
|
+
* word's text as `spell.word` spells it.
|
|
123
124
|
*/
|
|
124
|
-
export declare function spellLaunched(argv: readonly LexedWord[], args: readonly LaunchedArg[], spell: LaunchedSpelling): string[]
|
|
125
|
+
export declare function spellLaunched(argv: readonly LexedWord[], args: readonly LaunchedArg[], spell: LaunchedSpelling): string[];
|
|
125
126
|
/** The argv index of the SCRIPT FILE a shell runs where its argv carries no text ({@link scriptSourceOf}). */
|
|
126
127
|
export declare function scriptFileAt(basename: string, args: readonly string[]): number | undefined;
|
|
127
128
|
/** One text that may arrive on a segment's standard input: `from` = its source as written (a here-document's body,
|
|
128
|
-
* `<<<WORD`, `<FILE`, `<&N`, the segment the pipe comes from); `literal` = the text, where the command spells it
|
|
129
|
+
* `<<<WORD`, `<FILE`, `<&N`, the segment the pipe comes from); `literal` = the text, where the command spells it — a
|
|
130
|
+
* here-document or here-string written in the command; never a pipe's text, which a program PRODUCES. */
|
|
129
131
|
export interface StdinText {
|
|
130
132
|
readonly from: string;
|
|
131
133
|
readonly literal?: string;
|
|
132
134
|
}
|
|
133
135
|
/** What may arrive on a segment's standard input: each here-document (its descriptor is not read: every one counts) —
|
|
134
136
|
* its body, literal when quoted or when nothing in it expands — each here-string (literal when its word is), `<` file
|
|
135
|
-
* or `<&` descriptor written to no other descriptor, and the pipe it is reached through
|
|
136
|
-
*
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
* program word and every argument are literal, else only the segment as written. */
|
|
140
|
-
export declare function pipedTextOf(segment: LexedSegment, argv: readonly LexedWord[]): StdinText;
|
|
137
|
+
* or `<&` descriptor written to no other descriptor, and what it inherits (`fed`: the pipe it is reached through, the
|
|
138
|
+
* pipe or the input of the group it stands in, the input of the shell running its text) unless one of those three
|
|
139
|
+
* replaces it. */
|
|
140
|
+
export declare function stdinTextsOf(segment: LexedSegment, fed: readonly StdinText[]): StdinText[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { literalHeredocBody, literalTextOf } from "../../shell/lex.js";
|
|
2
2
|
import { programBasename, readProgramPosition } from "./bash-program-position.js";
|
|
3
|
-
import {
|
|
3
|
+
import { implementationRejects, implementationsOf, programRow, readArgRoles, selectedOptions, targetUserOf } from "./program-read-model.js";
|
|
4
4
|
import { namesStandardInput } from "./safety.js";
|
|
5
5
|
export function codeBodies(basename, args) {
|
|
6
6
|
const row = programRow(basename);
|
|
@@ -77,17 +77,27 @@ export function launchedCommands(argv, pos = readProgramPosition(argv)) {
|
|
|
77
77
|
const row = programRow(programBasename(argv[runs.launcher].folded));
|
|
78
78
|
const words = argv.slice(runs.from).map((w) => w.folded);
|
|
79
79
|
const at = (k) => runs.from + k;
|
|
80
|
-
if (
|
|
81
|
-
return [{ args: [] }];
|
|
82
|
-
if (row.launcher.shellText === "user")
|
|
80
|
+
if (row?.launcher?.shellText === "user")
|
|
83
81
|
return userCommands(row, words, at);
|
|
82
|
+
const user = row === undefined ? undefined : targetUserOf(row, argv.slice(runs.launcher + 1, runs.from).map((w) => w.folded));
|
|
83
|
+
const as = user !== undefined ? { as: user } : {};
|
|
84
|
+
if (words.length === 0 || row?.launcher === undefined)
|
|
85
|
+
return [{ args: [], ...as }];
|
|
84
86
|
if (row.launcher.shellText === "joined") {
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
const texts = new Map();
|
|
88
|
+
for (const view of implementationsOf(row)) {
|
|
89
|
+
const events = readArgRoles(view, words);
|
|
90
|
+
const first = events.find((e) => e.kind === "operand" || e.kind === "dash-word-operand")?.at ?? words.length;
|
|
91
|
+
if (implementationRejects(row, view, words.slice(0, first)))
|
|
92
|
+
continue;
|
|
93
|
+
const joined = words.slice(first).map((_, k) => at(first + k));
|
|
94
|
+
const values = events.flatMap((e) => (e.kind === "option" || (e.kind === "value" && e.at < first) ? roleValue(e, "shell-text", words, at) ?? [] : []));
|
|
95
|
+
for (const t of [...(joined.length === 0 ? [] : [{ joined }]), ...values])
|
|
96
|
+
texts.set(JSON.stringify(t), t);
|
|
97
|
+
}
|
|
98
|
+
return texts.size === 0 ? [{ args: [], ...as }] : [...texts.values()].map((t) => ({ args: [{ fixed: "-c" }, t], ...as }));
|
|
89
99
|
}
|
|
90
|
-
return [{ args: [{ fixed: "-c" }, { joined: words.map((_, k) => at(k)), escaped: true }] }];
|
|
100
|
+
return [{ args: [{ fixed: "-c" }, { joined: words.map((_, k) => at(k)), escaped: true }], ...as }];
|
|
91
101
|
}
|
|
92
102
|
function roleValue(e, kind, words, at) {
|
|
93
103
|
if (e.kind === "value" && e.role?.kind === kind)
|
|
@@ -109,16 +119,18 @@ function userCommands(row, words, at) {
|
|
|
109
119
|
const named = own.flatMap((e) => valued(e, "command") ?? []).at(-1);
|
|
110
120
|
const fromEnvironment = selectedOptions(view, stops ? words.slice(0, end) : words, "one-implementation").some((o) => o.mode === "names-program");
|
|
111
121
|
const program = named !== undefined ? { program: named } : fromEnvironment ? { program: { spelled: "\"$SHELL\"" } } : {};
|
|
122
|
+
const target = targetUserOf(view, stops ? words.slice(0, end) : words.filter((_, k) => k !== user), { name: user === undefined ? "root" : words[user], dash: operands[0]?.dash !== undefined });
|
|
123
|
+
const runs = { ...program, ...(target !== undefined ? { as: target } : {}) };
|
|
112
124
|
if (stops) {
|
|
113
|
-
out.push({ ...
|
|
125
|
+
out.push({ ...runs, args: user === undefined ? [] : words.slice(user + 1).map((_, k) => ({ at: at(user + 1 + k) })) });
|
|
114
126
|
continue;
|
|
115
127
|
}
|
|
116
128
|
const rest = operands.filter((e) => user !== undefined && e.at > user).map((e) => ({ at: at(e.at) }));
|
|
117
129
|
const texts = own.flatMap((e) => valued(e, "shell-text") ?? []);
|
|
118
130
|
if (texts.length === 0)
|
|
119
|
-
out.push({ ...
|
|
131
|
+
out.push({ ...runs, args: rest });
|
|
120
132
|
for (const text of texts)
|
|
121
|
-
out.push({ ...
|
|
133
|
+
out.push({ ...runs, args: [{ fixed: "-c" }, text, ...rest] });
|
|
122
134
|
}
|
|
123
135
|
return out;
|
|
124
136
|
}
|
|
@@ -155,12 +167,10 @@ export function launchedInput(argv, pos, spell) {
|
|
|
155
167
|
if (line === undefined && c.program !== undefined && "at" in c.program && c.program.from === undefined)
|
|
156
168
|
programWords.push(c.program.at);
|
|
157
169
|
const words = c.args.map((x) => ("at" in x && x.from === undefined ? x.at : undefined));
|
|
158
|
-
|
|
159
|
-
return asTexts(c.args).map((texts, i) => ({ shell, texts, args: args[i], words }));
|
|
170
|
+
return [{ shell, texts: asTexts(c.args), args: asArgs(c.args), words, ...(c.as !== undefined ? { as: c.as } : {}) }];
|
|
160
171
|
});
|
|
161
172
|
return { shells, programWords, lines: [...lines] };
|
|
162
173
|
}
|
|
163
|
-
const LAUNCHED_READINGS_MAX = 64;
|
|
164
174
|
function sudoEscaped(field) {
|
|
165
175
|
return field.replace(/[^A-Za-z0-9_$-]/gu, (c) => `\\${c}`);
|
|
166
176
|
}
|
|
@@ -168,20 +178,14 @@ function launchedSpellingOf(v) {
|
|
|
168
178
|
return v.glob === true ? v.parts.map((p) => (p.pattern ? p.text : sudoEscaped(p.text))).join("") : sudoEscaped(v.spelled);
|
|
169
179
|
}
|
|
170
180
|
export function spellLaunched(argv, args, spell) {
|
|
171
|
-
const
|
|
181
|
+
const field = (k) => {
|
|
172
182
|
const literal = literalTextOf(argv[k].pieces);
|
|
173
183
|
if (literal !== undefined)
|
|
174
|
-
return
|
|
184
|
+
return sudoEscaped(literal);
|
|
175
185
|
const values = spell.values?.(k);
|
|
176
|
-
return values ===
|
|
186
|
+
return values?.length === 1 ? launchedSpellingOf(values[0]) : argv[k].raw;
|
|
177
187
|
};
|
|
178
|
-
|
|
179
|
-
const distinct = new Map([...choices].map(([k, c]) => [argv[k].raw, c]));
|
|
180
|
-
const combinations = [...distinct.values()].reduce((n, c) => n * c.length, 1);
|
|
181
|
-
const readings = combinations <= LAUNCHED_READINGS_MAX
|
|
182
|
-
? [...distinct].reduce((acc, [w, c]) => acc.flatMap((r) => c.map((x) => new Map(r).set(w, x))), [new Map()]).map((r) => new Map([...choices.keys()].map((k) => [k, r.get(argv[k].raw)])))
|
|
183
|
-
: Array.from({ length: [...choices.values()].reduce((n, c) => Math.max(n, c.length), 1) }, (_, i) => new Map([...choices].map(([k, c]) => [k, c[Math.min(i, c.length - 1)]])));
|
|
184
|
-
return readings.map((reading) => args.map((a) => ("fixed" in a ? a.fixed : "at" in a ? spell.word(a.at, a.from ?? 0) : a.joined.map((k) => (a.escaped === true ? reading.get(k) : spell.word(k, 0))).join(" "))));
|
|
188
|
+
return args.map((a) => ("fixed" in a ? a.fixed : "at" in a ? spell.word(a.at, a.from ?? 0) : a.joined.map((k) => (a.escaped === true ? field(k) : spell.word(k, 0))).join(" ")));
|
|
185
189
|
}
|
|
186
190
|
export function scriptFileAt(basename, args) {
|
|
187
191
|
const row = programRow(basename);
|
|
@@ -198,7 +202,7 @@ function scriptSourceOf(row, args) {
|
|
|
198
202
|
return { stdin: true };
|
|
199
203
|
return { file: first.at, stdin: options.some((e) => e.kind === "option" && e.reading === "speculative") };
|
|
200
204
|
}
|
|
201
|
-
export function stdinTextsOf(segment,
|
|
205
|
+
export function stdinTextsOf(segment, fed) {
|
|
202
206
|
const out = [];
|
|
203
207
|
let replacesPipe = false;
|
|
204
208
|
for (const t of segment.tokens) {
|
|
@@ -212,12 +216,5 @@ export function stdinTextsOf(segment, piped) {
|
|
|
212
216
|
replacesPipe = true;
|
|
213
217
|
}
|
|
214
218
|
}
|
|
215
|
-
return
|
|
216
|
-
}
|
|
217
|
-
export function pipedTextOf(segment, argv) {
|
|
218
|
-
const from = `${segment.text.trim()} |`;
|
|
219
|
-
const pos = readProgramPosition(argv);
|
|
220
|
-
const program = pos.program;
|
|
221
|
-
const literal = program === undefined || pos.refusal !== undefined || literalTextOf(argv[program.index].pieces) === undefined ? undefined : printedText(programRow(program.basename), argv.slice(program.index + 1).map((w) => literalTextOf(w.pieces)));
|
|
222
|
-
return literal === undefined ? { from } : { from, literal };
|
|
219
|
+
return replacesPipe ? out : [...fed, ...out];
|
|
223
220
|
}
|
|
@@ -96,8 +96,7 @@ export interface TaskListStore {
|
|
|
96
96
|
export declare function normalizeTaskShape<T>(item: T): T;
|
|
97
97
|
export declare function assertJsonMetadata(value: unknown, path?: string): void;
|
|
98
98
|
/**
|
|
99
|
-
* RB-274 — the contract's `list` order
|
|
100
|
-
* (`stores/cc/task-list-store.ts`): numeric ids ascending (CC's own task order), any non-numeric id
|
|
99
|
+
* RB-274 — the contract's `list` order: numeric ids ascending (CC's own task order), any non-numeric id
|
|
101
100
|
* after them, lexicographically. Ties broken lexicographically so the comparator is total (and the
|
|
102
101
|
* order therefore stable across repeated calls, which the contract also requires).
|
|
103
102
|
*/
|
package/dist/tools/web.js
CHANGED
|
@@ -67,7 +67,7 @@ function assessGrounding(text, bytes) {
|
|
|
67
67
|
return { level: low ? "low" : "ok", textChars, bytes, textRatio: Math.round(textRatio * 1000) / 1000 };
|
|
68
68
|
}
|
|
69
69
|
function recoveryToolRuledOut(ctx, toolName) {
|
|
70
|
-
if (ctx.
|
|
70
|
+
if (ctx.toolSelector !== undefined && !ctx.toolSelector.admits({ name: toolName }))
|
|
71
71
|
return true;
|
|
72
72
|
const deferred = ctx.deferTools?.includes(toolName) ?? false;
|
|
73
73
|
const pinnedInline = ctx.alwaysLoadTools?.includes(toolName) ?? false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/core",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.49.0",
|
|
4
4
|
"description": "Stateless, task-oriented AI agent core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BUSL-1.1",
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"handoff:diff": "node scripts/dist-handoff-diff.mjs",
|
|
73
73
|
"post-ship": "node scripts/post-ship.mjs",
|
|
74
74
|
"gate:debts:rc": "node scripts/verify-debts.mjs --rc-gate",
|
|
75
|
+
"gate:rulings": "node scripts/rulings-gate.mjs --require-comms",
|
|
75
76
|
"gate:error-surface": "node scripts/verify-error-surface.mjs",
|
|
76
77
|
"gate:criteria": "node scripts/criteria-lint.mjs",
|
|
77
78
|
"gate:reminder-literal": "node scripts/verify-reminder-literal.mjs",
|
|
@@ -89,7 +90,9 @@
|
|
|
89
90
|
"gate:child-clamp-seats": "node scripts/verify-child-clamp-seats.mjs",
|
|
90
91
|
"gate:spawn-sites": "node scripts/verify-spawn-sites.mjs",
|
|
91
92
|
"gate:point-free-callbacks": "node scripts/verify-point-free-callbacks.mjs",
|
|
93
|
+
"gate:weak-identity": "node scripts/gate-weak-identity.mjs",
|
|
92
94
|
"gate:docs-tool-names": "node scripts/verify-docs-tool-names.mjs",
|
|
95
|
+
"gate:credential-vocabulary": "node scripts/verify-credential-vocabulary.mjs",
|
|
93
96
|
"gate:comment-ratio": "vitest run test/comment-ratio-ratchet.test.ts",
|
|
94
97
|
"gate:negative-controls": "vitest run test/gate-negative-controls.test.ts",
|
|
95
98
|
"gate:memory-ga": "node scripts/gate-memory-distillation-ga.mjs",
|