@sema-agent/core 7.48.0 → 7.49.1
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 +457 -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 +38 -31
- package/dist/core/arg-summary.d.ts +21 -28
- package/dist/core/arg-summary.js +235 -88
- 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 +94 -65
- 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 +43 -11
- 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 +21 -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.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/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 +29 -36
- 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/tool-turn-repair-seat.d.ts +28 -4
- package/dist/core/runner/tool-turn-repair-seat.js +36 -13
- 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/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-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-projection.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 +26 -2
- package/dist/core/tool-name-aliases.js +13 -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 -380
- 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 +189 -117
- package/dist/scenarios/full-body.d.ts +1 -1
- package/dist/shell/lex.d.ts +0 -21
- package/dist/shell/lex.js +250 -68
- 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 +12 -4
- package/dist/tools/fs/bash-program-position.js +32 -9
- 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 +1 -1
- package/dist/tools/fs/program-read-model.d.ts +46 -20
- package/dist/tools/fs/program-read-model.js +50 -20
- package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
- package/dist/tools/fs/program-read-model.rows.js +16 -15
- package/dist/tools/fs/read-deny-home.d.ts +33 -47
- package/dist/tools/fs/read-deny-home.js +35 -49
- package/dist/tools/fs/read-deny.d.ts +23 -22
- package/dist/tools/fs/read-deny.js +114 -89
- package/dist/tools/fs/removal-targets.d.ts +56 -23
- package/dist/tools/fs/removal-targets.js +65 -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.js +1 -1
- package/dist/tools/fs/shell-read-bindings.d.ts +169 -37
- package/dist/tools/fs/shell-read-bindings.js +324 -86
- 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 +67 -43
- package/dist/tools/fs/shell-read-establish.js +6 -6
- 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 +51 -18
- package/dist/tools/fs/shell-read-judge.js +40 -4
- package/dist/tools/fs/shell-read-plan.d.ts +12 -6
- package/dist/tools/fs/shell-read-plan.js +118 -113
- package/dist/tools/fs/shell-read-start.d.ts +29 -6
- package/dist/tools/fs/shell-read-start.js +16 -9
- package/dist/tools/fs/shell-read-word.js +4 -0
- 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 +4 -6
- package/dist/tools/fs/shell-reentry-text.js +3 -11
- 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.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
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { lexShell, PARSE_FAILURE_SENTENCE, substitutionsInHeredocBody, literalTextOf, literalTildeSpelling, } from "../../shell/lex.js";
|
|
2
2
|
import { programTextOf, readOfText, readsOf, rewritten, segmentReadingsOf, settledFieldsOf, spelledWithHome, isArithmeticBody, unreadableSentenceOf } from "./shell-read-word.js";
|
|
3
3
|
import { assignmentArithmetic, bare, listedVerbCandidates, pathSubcommandOf, programTextSentence, pushAssignment, roleReads, subscriptOnly, unlistedWords } from "./shell-read-argv.js";
|
|
4
|
-
import { ARITHMETIC_TEST_OPERATORS, BindingThread, arithmeticSubstitutions, isArithmeticCommand, bindingEffectOf, loopListHeadAt, parameterBodySubstitutions, projectSegment, valueOf, } from "./shell-read-bindings.js";
|
|
5
|
-
import { isShellSyntaxWord, programBasename, programPositionRunsShell, readProgramPosition, shellScanDeclineOf, } from "./bash-program-position.js";
|
|
4
|
+
import { ARITHMETIC_TEST_OPERATORS, BindingThread, arithmeticSubstitutions, isArithmeticCommand, bindingEffectOf, joinRebound, loopListHeadAt, namesBoundIn, parameterBodySubstitutions, projectSegment, valueOf, } from "./shell-read-bindings.js";
|
|
5
|
+
import { commandEnvironmentNames, isShellSyntaxWord, programBasename, programPositionRunsShell, readProgramPosition, shellScanDeclineOf, } from "./bash-program-position.js";
|
|
6
|
+
import { WorkdirThread, baseShiftOf, textCalls, textMayMove, textMovesOf, textSetsPhysical, withCommandEnvironment } from "./shell-read-workdir.js";
|
|
6
7
|
import { POLL_LOOP_MAX_BEATS, attachedOptionPayloads, resolveOperandLexically, isPathShapedToken, programTextSlotFiles, } from "./bash-readonly-classifier.js";
|
|
7
|
-
import { BLOCK_WORD_NAMES, commandLineOf, commandLineOptionSpellings, declaredAttributes, isDeclarationBuiltin, isInertBuiltin, launcherOptionPathRole, launcherOptionStep, readOptionRole, programLanguageOf, programTextOpensOf, selectedOptions,
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { BLOCK_WORD_NAMES, commandLineOf, commandLineOptionSpellings, declaredAttributes, isDeclarationBuiltin, isInertBuiltin, launcherOptionPathRole, launcherOptionStep, readOptionRole, programLanguageOf, programTextOpensOf, selectedOptions, movesBaseByStack, opensNoOperand, programDelivery, programRow, readArgRoles, runsShellText, } from "./program-read-model.js";
|
|
9
|
+
import { shellWordsOf } from "../../shell/shell-words.js";
|
|
10
|
+
import { isAbsoluteForFamily } from "./safety.js";
|
|
11
|
+
import { codeBodies, launchedInput, reentryText, scriptFileAt, stdinTextsOf } from "./shell-reentry-text.js";
|
|
12
|
+
import { heldAt, plannedOnce, rebasePlan, startedAt, stdinFeeds } from "./shell-read-start.js";
|
|
11
13
|
export const READ_CANDIDATE_PROVENANCES = Object.freeze([
|
|
12
14
|
"operand",
|
|
13
15
|
"option_value",
|
|
@@ -23,22 +25,26 @@ export const READ_CANDIDATE_PROVENANCES = Object.freeze([
|
|
|
23
25
|
"object_path",
|
|
24
26
|
]);
|
|
25
27
|
const NESTING_MAX = 4;
|
|
26
|
-
const LOOP_END =
|
|
27
|
-
const BASE_CANDIDATE_MAX = 256;
|
|
28
|
+
const LOOP_END = shellWordsOf("loop_end"), LOOP_CONDITION = shellWordsOf("loop_condition"), COPROC = shellWordsOf("background"), RESERVED = shellWordsOf("rule_reserved");
|
|
28
29
|
export function planShellReads(command, decl, depth = 0, start) {
|
|
30
|
+
return planText(command, decl, depth, start).plan;
|
|
31
|
+
}
|
|
32
|
+
function planText(command, decl, depth, start, from) {
|
|
29
33
|
const shape = { grouped: false, backgrounded: false, strayRedirection: false };
|
|
30
34
|
if (depth > NESTING_MAX)
|
|
31
|
-
return { segments: [], unreadable: `command text nested more than ${NESTING_MAX} levels deep`, shape };
|
|
35
|
+
return { plan: { segments: [], unreadable: `command text nested more than ${NESTING_MAX} levels deep`, shape }, end: "unmodelled", physical: false };
|
|
32
36
|
const lexed = lexShell(command);
|
|
33
37
|
if ("parseFailure" in lexed)
|
|
34
|
-
return { segments: [], unreadable: PARSE_FAILURE_SENTENCE[lexed.parseFailure.reason], shape };
|
|
38
|
+
return { plan: { segments: [], unreadable: PARSE_FAILURE_SENTENCE[lexed.parseFailure.reason], shape }, end: "unmodelled", physical: false };
|
|
35
39
|
const unreadable = unreadableSentenceOf(lexed, command);
|
|
36
40
|
const projected = lexed.segments.map((segment) => projectSegment(segment));
|
|
37
41
|
const named = projected.map((p, si) => bindingEffectOf(lexed.segments[si], p.argv, p, () => "unknown"));
|
|
38
42
|
const boundHere = (name) => named.some((e) => e.all === "unknown" || e.bindings.some((b) => b.name === name));
|
|
39
43
|
const boundAnywhere = (name) => boundHere(name) || start?.boundAnywhere(name) === true;
|
|
40
44
|
const declaredHome = decl.homeDir !== undefined ? [{ spelled: decl.homeDir }] : "unknown";
|
|
41
|
-
const
|
|
45
|
+
const declaredCdPath = decl.cdPath === "unknown" ? "unknown" : [{ spelled: (decl.cdPath ?? []).join(":") }];
|
|
46
|
+
const declared = (name, rebound) => (rebound ? "unknown" : name === "HOME" ? declaredHome : name === "CDPATH" ? declaredCdPath : "unknown");
|
|
47
|
+
const initial = start?.initial ?? ((name) => declared(name, false));
|
|
42
48
|
const loopShapes = projected.map((p) => loopShapeOf(p));
|
|
43
49
|
const loopEndOf = new Map();
|
|
44
50
|
{
|
|
@@ -53,26 +59,35 @@ export function planShellReads(command, decl, depth = 0, start) {
|
|
|
53
59
|
}
|
|
54
60
|
});
|
|
55
61
|
}
|
|
56
|
-
const names = new BindingThread(lexed.segments, named, initial, boundAnywhere, loopEndOf, start?.homeTouched === true, start?.inherited);
|
|
57
|
-
const laterStart = { initial: (name) => (name
|
|
58
|
-
const nestedPlanner = (table) => (text, kind, at) => planShellReads(text, decl, depth + 1, kind === "substitution" ? { initial: (name) => table.stateOf(name), boundAnywhere, homeTouched: table.homeTouched, inherited: table.inherited } : startedAt(laterStart, at));
|
|
62
|
+
const names = new BindingThread(lexed.segments, named, initial, boundAnywhere, loopEndOf, start?.homeTouched === true, start?.inherited, start?.names);
|
|
63
|
+
const laterStart = { initial: (name) => declared(name, boundAnywhere(name)), boundAnywhere, homeTouched: boundAnywhere("HOME"), inherited: names.inheritedAt() };
|
|
64
|
+
const nestedPlanner = (table, si) => (text, kind, at) => planShellReads(text, decl, depth + 1, kind === "substitution" ? { initial: (name) => table.stateOf(name), boundAnywhere, homeTouched: table.homeTouched, inherited: table.inherited, thread: heldThread(moves.functions), names: heldAt(table) } : startedAt(kind === "now" ? { ...laterStart, inherited: { ...laterStart.inherited, rebound: joinRebound(table.inherited.rebound, commandEnvironmentNames(projected[si].argv)) }, ...(readProgramPosition(projected[si].argv).program?.basename === "eval" ? { thread: heldThread(moves.unread), names: heldAt(table, names.functionBound()) } : {}) } : { ...laterStart, thread: heldThread(moves.functions, workdir.mayBePhysical || moves.physicalAt.some(Boolean)), names: names.heldAnywhere() }, at));
|
|
59
65
|
const empty = lexed.segments.map((segment, si) => segmentIsEmpty(segment, projected[si]));
|
|
60
66
|
const facts = projected.map(() => undefined);
|
|
61
67
|
const tables = projected.map(() => undefined);
|
|
62
|
-
const fedAt = stdinFeeds(lexed.segments, start?.stdin ?? [], (si) =>
|
|
68
|
+
const fedAt = stdinFeeds(lexed.segments, start?.stdin ?? [], (si) => [{ from: `${lexed.segments[si - 1].text.trim()} |` }]);
|
|
63
69
|
const factsAt = (si, table) => {
|
|
64
70
|
tables[si] ??= table;
|
|
65
|
-
return (facts[si] ??= segmentFacts(lexed.segments[si], projected[si], decl, table, nestedPlanner(table), fedAt(si)));
|
|
71
|
+
return (facts[si] ??= segmentFacts(lexed.segments[si], projected[si], decl, table, nestedPlanner(table, si), fedAt(si)));
|
|
66
72
|
};
|
|
67
73
|
const basesOf = projected.map(() => new Set());
|
|
68
74
|
const unmodelled = projected.map(() => false);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
const moves = textMovesOf(new Set(projected.flatMap((p) => p.defines)), projected.map((p) => p.argv), (si) => names.inFunctionBody(si), start?.thread);
|
|
76
|
+
names.runsBodies(moves.runsBodyAt, moves.bodiesAt.some((b) => b.length > 0), moves.mayCallAt.map((c, si) => (c ? commandEnvironmentNames(projected[si].argv) : undefined)));
|
|
77
|
+
const workdir = new WorkdirThread(from ?? start?.bases ?? [decl.cwd], depth === 0 || start?.bases !== undefined || from !== undefined, start?.thread?.physical === true);
|
|
78
|
+
const workdirContext = {
|
|
79
|
+
...(decl.homeDir !== undefined ? { homeDir: decl.homeDir } : {}),
|
|
80
|
+
textBinds: boundAnywhere,
|
|
81
|
+
evalEnd: (text, c, table) => {
|
|
82
|
+
if (moves.bodyMoves && textCalls(text, moves.functions))
|
|
83
|
+
return { end: "unmodelled", physical: false };
|
|
84
|
+
if (!textMayMove(text, moves.functions) && !textSetsPhysical(text))
|
|
85
|
+
return { end: [c], physical: false };
|
|
86
|
+
const ran = planText(text, decl, depth + 1, { initial: (name) => table.stateOf(name), boundAnywhere, homeTouched: table.homeTouched, inherited: table.inherited, thread: heldThread(moves.unread), names: heldAt(table, names.functionBound()) }, [c]);
|
|
87
|
+
return { end: ran.end, physical: ran.physical };
|
|
88
|
+
},
|
|
75
89
|
};
|
|
90
|
+
const heldThread = (unread, physical = workdir.mayBePhysical) => ({ physical, functions: moves.functions, unread });
|
|
76
91
|
let andRunStart = 0;
|
|
77
92
|
let crossedAllAnd = true;
|
|
78
93
|
let crossedAnyOr = false;
|
|
@@ -89,55 +104,28 @@ export function planShellReads(command, decl, depth = 0, start) {
|
|
|
89
104
|
}
|
|
90
105
|
if (empty[si]) {
|
|
91
106
|
if (!replay)
|
|
92
|
-
factsAt(si, names.tableAt(si, andRunStart));
|
|
107
|
+
factsAt(si, names.tableAt(si, andRunStart, workdir.where(andRunStart)));
|
|
93
108
|
return;
|
|
94
109
|
}
|
|
95
110
|
if (previousEmitted >= 0 && !crossedAllAnd)
|
|
96
111
|
andRunStart = crossedAnyOr ? si + 1 : si;
|
|
97
|
-
const f = replay ? facts[si] : factsAt(si, names.tableAt(si, andRunStart));
|
|
98
|
-
const pipeFed = f.connector === "|" || lexed.segments[si + 1]?.connector === "|";
|
|
99
|
-
reaches[si] ??= { andJoined: previousEmitted >= 0 && crossedAllAnd, orBroken: !crossedAllAnd && crossedAnyOr, moveProvable: f.moveProvable && !replay && !pipeFed };
|
|
112
|
+
const f = replay ? facts[si] : factsAt(si, names.tableAt(si, andRunStart, workdir.where(andRunStart)));
|
|
113
|
+
const pipeFed = f.connector === "|" || lexed.segments[si + 1]?.connector === "|", call = moves.callAt(si, tables[si]);
|
|
114
|
+
reaches[si] ??= { andJoined: previousEmitted >= 0 && crossedAllAnd, orBroken: !crossedAllAnd && crossedAnyOr, moveProvable: f.moveProvable && !replay && !pipeFed && !names.runsApart(si) };
|
|
100
115
|
crossedAllAnd = true;
|
|
101
116
|
crossedAnyOr = false;
|
|
102
117
|
previousEmitted = si;
|
|
103
|
-
|
|
104
|
-
if (baseLost)
|
|
118
|
+
if (workdir.lost)
|
|
105
119
|
unmodelled[si] = true;
|
|
106
120
|
else
|
|
107
|
-
for (const c of reachable)
|
|
121
|
+
for (const c of workdir.reachable(andRunStart))
|
|
108
122
|
basesOf[si].add(c.base);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
const target = move.target.spelled;
|
|
117
|
-
const provable = reaches[si].moveProvable;
|
|
118
|
-
const branched = [];
|
|
119
|
-
for (const c of candidates) {
|
|
120
|
-
if (c.skippedCd < andRunStart) {
|
|
121
|
-
const moved = joinBase(c.base, target, decl.homeDir);
|
|
122
|
-
if (moved === undefined) {
|
|
123
|
-
loseBase(reachable);
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
branched.push({ base: moved, skippedCd: c.skippedCd });
|
|
127
|
-
}
|
|
128
|
-
branched.push({ base: c.base, skippedCd: provable ? si : c.skippedCd });
|
|
129
|
-
}
|
|
130
|
-
const byBase = new Map();
|
|
131
|
-
for (const c of branched) {
|
|
132
|
-
const prior = byBase.get(c.base);
|
|
133
|
-
if (prior === undefined || c.skippedCd < prior.skippedCd)
|
|
134
|
-
byBase.set(c.base, c);
|
|
135
|
-
}
|
|
136
|
-
const next = [...byBase.values()];
|
|
137
|
-
if (next.length > BASE_CANDIDATE_MAX)
|
|
138
|
-
loseBase(reachable);
|
|
139
|
-
else
|
|
140
|
-
candidates = next;
|
|
123
|
+
if (moves.physicalAt[si])
|
|
124
|
+
workdir.setPhysical();
|
|
125
|
+
if (f.shift !== undefined && call !== "named")
|
|
126
|
+
workdir.shift(si, { shift: f.shift, provable: reaches[si].moveProvable && call === undefined, andRunStart, table: withCommandEnvironment(tables[si], projected[si].argv), cdable: moves.cdableFrom >= 0 && si > moves.cdableFrom }, workdirContext);
|
|
127
|
+
if (moves.losesBaseAt(si, tables[si]))
|
|
128
|
+
workdir.lose(si, workdir.reachable(andRunStart));
|
|
141
129
|
};
|
|
142
130
|
const bind = (si) => {
|
|
143
131
|
const table = tables[si];
|
|
@@ -146,12 +134,16 @@ export function planShellReads(command, decl, depth = 0, start) {
|
|
|
146
134
|
const end = loopEndOf.get(si);
|
|
147
135
|
if (end !== undefined) {
|
|
148
136
|
const body = named.slice(si + 1, end);
|
|
149
|
-
names.kill(si, body.some((e) => e.all === "unknown") ? "all" : body.flatMap((e) => e.bindings.map((b) => b.name)));
|
|
137
|
+
names.kill(si, body.some((e) => e.all === "unknown") ? "all" : [...body.flatMap((e) => e.bindings.map((b) => b.name)), ...(moves.mayMove.slice(si + 1, end).some(Boolean) ? ["PWD", "OLDPWD"] : [])]);
|
|
150
138
|
}
|
|
151
139
|
const segment = lexed.segments[si];
|
|
152
|
-
const effect = bindingEffectOf(segment, projected[si].argv, projected[si], (w, quoted, overlay) => valueOf(w, table, quoted, overlay));
|
|
140
|
+
const effect = bindingEffectOf(segment, projected[si].argv, projected[si], (w, quoted, overlay) => valueOf(w, table, quoted, overlay), moves.callAt(si, table), (builtin) => table.builtinState(builtin));
|
|
153
141
|
const { all, ...rest } = effect;
|
|
154
142
|
names.apply(si, all === "reset" ? rest : effect, segment.connector === "&&" || segment.connector === "||", end);
|
|
143
|
+
if (moves.callAt(si, table) !== undefined)
|
|
144
|
+
names.kill(si, moves.callsUnread(si, table) ? "all" : names.functionBound());
|
|
145
|
+
if (moves.bodiesAt[si].length > 0)
|
|
146
|
+
names.runsLater(si, moves.bodiesAt[si].reduce((held, b) => joinRebound(held, namesBoundIn(b)), names.functionBound()));
|
|
155
147
|
};
|
|
156
148
|
for (let si = 0; si < projected.length; si++) {
|
|
157
149
|
const shapeOfLoop = loopShapes[si];
|
|
@@ -168,17 +160,15 @@ export function planShellReads(command, decl, depth = 0, start) {
|
|
|
168
160
|
const frame = loops.pop();
|
|
169
161
|
if (frame === undefined)
|
|
170
162
|
continue;
|
|
171
|
-
|
|
172
|
-
const moves = body.some((b) => b?.baseMove !== undefined);
|
|
173
|
-
if (!moves)
|
|
163
|
+
if (!facts.slice(frame.bodyStart, si).some((b, k) => b?.shift !== undefined || (tables[frame.bodyStart + k] !== undefined && moves.losesBaseAt(frame.bodyStart + k, tables[frame.bodyStart + k]))))
|
|
174
164
|
continue;
|
|
175
165
|
if (frame.beats === undefined) {
|
|
176
166
|
for (let k = frame.bodyStart; k < si; k++)
|
|
177
167
|
unmodelled[k] = true;
|
|
178
|
-
|
|
168
|
+
workdir.lose(si, workdir.reachable(andRunStart));
|
|
179
169
|
continue;
|
|
180
170
|
}
|
|
181
|
-
for (let beat = 1; beat < frame.beats && !
|
|
171
|
+
for (let beat = 1; beat < frame.beats && !workdir.lost; beat++) {
|
|
182
172
|
for (let k = frame.bodyStart; k < si; k++)
|
|
183
173
|
thread(k, true);
|
|
184
174
|
}
|
|
@@ -195,14 +185,19 @@ export function planShellReads(command, decl, depth = 0, start) {
|
|
|
195
185
|
if (threaded.empty)
|
|
196
186
|
continue;
|
|
197
187
|
const bases = unmodelled[si] ? "unmodelled" : [...basesOf[si]];
|
|
188
|
+
const floorBases = workdir.floorBases;
|
|
198
189
|
const floor = unmodelled[si] && floorBases !== undefined && floorBases.length > 0 ? floorBases : undefined;
|
|
199
|
-
const
|
|
190
|
+
const placedAt = (at, atFloor) => (c) => {
|
|
200
191
|
const relative = relativeSpelling(c.spelled);
|
|
201
|
-
const here = c.provenance === "object_path" &&
|
|
202
|
-
return { ...c, bases: relative ? here : [], ...(relative &&
|
|
192
|
+
const here = c.provenance === "object_path" && at !== "unmodelled" ? [...new Set(at.flatMap(ancestorsOf))] : at;
|
|
193
|
+
return { ...c, bases: relative ? here : [], ...(relative && atFloor !== undefined ? { floorBases: atFloor } : {}) };
|
|
203
194
|
};
|
|
195
|
+
const withBases = placedAt(bases, floor);
|
|
204
196
|
const move = threaded.baseMove;
|
|
205
197
|
for (const f of threaded.readings ?? [threaded]) {
|
|
198
|
+
const moved = readProgramPosition(f.argv).launcherMovesBase;
|
|
199
|
+
const programPlaced = moved ? placedAt("unmodelled", bases !== "unmodelled" ? bases : floor) : withBases;
|
|
200
|
+
const programRead = (c) => (c.provenance === "stdin_redirect" ? withBases(c) : programPlaced(c));
|
|
206
201
|
segments.push({
|
|
207
202
|
text: f.text,
|
|
208
203
|
connector: f.connector,
|
|
@@ -213,16 +208,17 @@ export function planShellReads(command, decl, depth = 0, start) {
|
|
|
213
208
|
...(f.unreadProgramText !== undefined ? { unreadProgramText: f.unreadProgramText } : {}),
|
|
214
209
|
...(f.stdin !== undefined ? { stdin: f.stdin } : {}),
|
|
215
210
|
declines: f.declines,
|
|
216
|
-
reads: dedupe(f.reads).map(
|
|
211
|
+
reads: dedupe(f.reads).map(programRead),
|
|
217
212
|
redirects: f.redirects.map((r) => (r.target === undefined ? { op: r.op, direction: r.direction } : { op: r.op, direction: r.direction, target: withBases(r.target) })),
|
|
218
213
|
...(move !== undefined ? { baseMove: { target: typeof move.target === "string" ? move.target : withBases(move.target) } } : {}),
|
|
219
214
|
bases,
|
|
220
|
-
nested: f.nested.map((n) => (f.elsewhere?.has(n) === true ? n : rebasePlan(n, decl.cwd, bases))),
|
|
215
|
+
nested: f.nested.map((n) => (f.elsewhere?.has(n) === true ? n : rebasePlan(n, decl.cwd, moved && f.shellSide?.has(n) !== true ? "unmodelled" : bases, bases === "unmodelled" ? floor : bases))),
|
|
221
216
|
reach: reaches[si] ?? { andJoined: false, orBroken: false, moveProvable: false },
|
|
217
|
+
rebound: tables[si]?.rebound ?? "all",
|
|
222
218
|
});
|
|
223
219
|
}
|
|
224
220
|
}
|
|
225
|
-
return { segments, shape, ...(unreadable !== undefined ? { unreadable } : {}) };
|
|
221
|
+
return { plan: { segments, shape, ...(unreadable !== undefined ? { unreadable } : {}) }, end: workdir.end(), physical: workdir.mayBePhysical };
|
|
226
222
|
}
|
|
227
223
|
function ancestorsOf(dir) {
|
|
228
224
|
const out = [dir];
|
|
@@ -234,15 +230,14 @@ function parentOf(dir) {
|
|
|
234
230
|
return resolveOperandLexically(dir, "..", undefined) ?? dir;
|
|
235
231
|
}
|
|
236
232
|
function loopShapeOf(p) {
|
|
237
|
-
|
|
238
|
-
if (head === undefined)
|
|
233
|
+
if (p.argv[0] === undefined)
|
|
239
234
|
return undefined;
|
|
240
235
|
if (loopListHeadAt(p.argv) !== undefined)
|
|
241
236
|
return "head";
|
|
242
|
-
if (isShellSyntaxWord(
|
|
237
|
+
if (isShellSyntaxWord(p.argv[0], LOOP_END))
|
|
243
238
|
return "end";
|
|
244
239
|
const pos = readProgramPosition(p.argv);
|
|
245
|
-
return pos.controlWords.some((i) =>
|
|
240
|
+
return pos.controlWords.some((i) => LOOP_CONDITION.has(p.argv[i].folded)) ? "head" : undefined;
|
|
246
241
|
}
|
|
247
242
|
function segmentIsEmpty(segment, p) {
|
|
248
243
|
if (p.argv.length > 0 || p.redirects.length > 0 || segment.substitutions.length > 0)
|
|
@@ -263,19 +258,22 @@ function segmentFacts(segment, p, decl, table, nestedPlan, fed) {
|
|
|
263
258
|
if (readings.length === 1)
|
|
264
259
|
return readingFacts(segment, { ...p, argv: readings[0].argv }, decl, readings[0], nestedPlan, fed);
|
|
265
260
|
const once = plannedOnce(nestedPlan);
|
|
266
|
-
|
|
261
|
+
return readInSeveral(readings.map((reading) => readingFacts(segment, { ...p, argv: reading.argv }, decl, reading, once, fed)));
|
|
262
|
+
}
|
|
263
|
+
function readInSeveral(each) {
|
|
267
264
|
const first = each[0];
|
|
268
265
|
const move = each.find((f) => f.baseMove !== undefined)?.baseMove;
|
|
269
266
|
return {
|
|
270
267
|
...first,
|
|
271
268
|
moveProvable: false,
|
|
272
269
|
...(move !== undefined ? { baseMove: { target: typeof move.target === "string" ? move.target : { ...move.target, expands: "unresolvable" } } } : {}),
|
|
273
|
-
|
|
270
|
+
...(each.some((f) => f.shift !== undefined) ? { shift: { kind: "lost" } } : {}),
|
|
271
|
+
readings: each.flatMap((f) => f.readings ?? [f]),
|
|
274
272
|
};
|
|
275
273
|
}
|
|
276
274
|
function readingFacts(segment, p, decl, reading, nestedPlan, fed) {
|
|
277
275
|
const table = reading.table;
|
|
278
|
-
const planner = (text, kind, at) => nestedPlan(text, kind, kind
|
|
276
|
+
const planner = (text, kind, at) => nestedPlan(text, kind, kind !== "substitution" ? { ...at, floors: reading.floors } : at);
|
|
279
277
|
const facts = segmentFactsRead(segment, p, decl, table, planner, fed, reading.reads);
|
|
280
278
|
const unresolvedRaw = new Set();
|
|
281
279
|
for (const t of segment.tokens) {
|
|
@@ -297,11 +295,13 @@ function readingFacts(segment, p, decl, reading, nestedPlan, fed) {
|
|
|
297
295
|
return [unsettle(one), ...shadows];
|
|
298
296
|
};
|
|
299
297
|
const move = facts.baseMove;
|
|
298
|
+
const shift = facts.shift;
|
|
300
299
|
return {
|
|
301
300
|
...facts,
|
|
302
301
|
reads: facts.reads.flatMap(each),
|
|
303
302
|
redirects: facts.redirects.map((r) => (r.target === undefined ? r : { ...r, target: unsettle(r.target) })),
|
|
304
303
|
...(move !== undefined && typeof move.target !== "string" ? { baseMove: { target: unsettle(move.target) } } : {}),
|
|
304
|
+
...(shift?.kind === "cd" && typeof shift.target !== "string" ? { shift: { ...shift, target: unsettle(shift.target) } } : {}),
|
|
305
305
|
};
|
|
306
306
|
}
|
|
307
307
|
function segmentFactsRead(segment, p, decl, table, nestedPlan, fed, toks) {
|
|
@@ -343,6 +343,7 @@ function segmentFactsRead(segment, p, decl, table, nestedPlan, fed, toks) {
|
|
|
343
343
|
}
|
|
344
344
|
if (unreadableHeredoc)
|
|
345
345
|
nested.push({ segments: [], unreadable: "a here-document body carries a substitution this lexer cannot delimit", shape: { grouped: false, backgrounded: false, strayRedirection: false } });
|
|
346
|
+
const shellSide = new Set(nested);
|
|
346
347
|
if (isArithmeticCommand(segment))
|
|
347
348
|
ctx.reentered.push(...arithmeticSubstitutions(p.argv.map((w) => w.folded).join(" "), table));
|
|
348
349
|
for (const t of segment.tokens) {
|
|
@@ -365,26 +366,31 @@ function segmentFactsRead(segment, p, decl, table, nestedPlan, fed, toks) {
|
|
|
365
366
|
};
|
|
366
367
|
const done = (f) => {
|
|
367
368
|
const reentered = [...new Set(ctx.reentered)];
|
|
368
|
-
for (const body of reentered)
|
|
369
|
-
|
|
369
|
+
for (const body of reentered) {
|
|
370
|
+
const plan = nestedPlan(body, "later");
|
|
371
|
+
nested.push(plan);
|
|
372
|
+
shellSide.add(plan);
|
|
373
|
+
}
|
|
370
374
|
return {
|
|
371
375
|
...base,
|
|
372
376
|
...f,
|
|
373
377
|
...(reentered.length > 0 ? { reentry: "shell" } : {}),
|
|
374
378
|
...(f.unreadProgramText === undefined && ctx.programText !== undefined ? { unreadProgramText: ctx.programText } : {}),
|
|
375
379
|
...(elsewhere.size > 0 ? { elsewhere } : {}),
|
|
380
|
+
...(shellSide.size > 0 ? { shellSide } : {}),
|
|
376
381
|
};
|
|
377
382
|
};
|
|
378
383
|
const head = toks[0]?.folded;
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
384
|
+
const pos = readProgramPosition(p.argv);
|
|
385
|
+
const coproc = pos.written !== undefined && isShellSyntaxWord(p.argv[pos.written], COPROC) ? pos.written : undefined;
|
|
386
|
+
if (coproc !== undefined && toks.length > coproc + 1) {
|
|
387
|
+
const once = plannedOnce(nestedPlan);
|
|
388
|
+
const tail = (from) => ({ ...p, argv: p.argv.slice(coproc + from) });
|
|
389
|
+
const background = (f) => ({ ...f, backgrounds: true, ...(f.readings !== undefined ? { readings: f.readings.map((g) => ({ ...g, backgrounds: true })) } : {}) });
|
|
390
|
+
const first = segmentFacts(segment, tail(1), decl, table, once, fed);
|
|
391
|
+
if (toks.length < coproc + 3 || isShellSyntaxWord(p.argv[coproc + 1], RESERVED) || readProgramPosition(tail(2).argv.slice(0, 1)).refusal !== undefined)
|
|
392
|
+
return background(first);
|
|
393
|
+
return background(readInSeveral([first, segmentFacts(segment, tail(2), decl, table, once, fed)]));
|
|
388
394
|
}
|
|
389
395
|
const loop = loopShapeOf(p);
|
|
390
396
|
if (loopListHeadAt(p.argv) !== undefined)
|
|
@@ -398,7 +404,6 @@ function segmentFactsRead(segment, p, decl, table, nestedPlan, fed, toks) {
|
|
|
398
404
|
}
|
|
399
405
|
return done({ empty: false, launcherChain: [], declines: [], reads, moveProvable: false });
|
|
400
406
|
}
|
|
401
|
-
const pos = readProgramPosition(p.argv);
|
|
402
407
|
const written = pos.written;
|
|
403
408
|
if (written === undefined)
|
|
404
409
|
return done({ empty: segmentIsEmpty(segment, p), launcherChain: [], declines: [], reads, moveProvable: false });
|
|
@@ -482,6 +487,7 @@ function segmentFactsRead(segment, p, decl, table, nestedPlan, fed, toks) {
|
|
|
482
487
|
}
|
|
483
488
|
}
|
|
484
489
|
let reentry;
|
|
490
|
+
let shift;
|
|
485
491
|
if (pos.argvFromStdin)
|
|
486
492
|
reentry = "argv";
|
|
487
493
|
const reenterShell = (verb, argvs) => {
|
|
@@ -500,7 +506,7 @@ function segmentFactsRead(segment, p, decl, table, nestedPlan, fed, toks) {
|
|
|
500
506
|
script(reentryText(shell, t, s.literal), user);
|
|
501
507
|
}
|
|
502
508
|
for (const { text, ...at } of scripts.values()) {
|
|
503
|
-
const plan = nestedPlan(text, "
|
|
509
|
+
const plan = nestedPlan(text, "now", at);
|
|
504
510
|
nested.push(plan);
|
|
505
511
|
if (at.as?.login === true)
|
|
506
512
|
elsewhere.add(plan);
|
|
@@ -511,14 +517,14 @@ function segmentFactsRead(segment, p, decl, table, nestedPlan, fed, toks) {
|
|
|
511
517
|
if (file !== undefined)
|
|
512
518
|
reads.push(bare(file, "operand"));
|
|
513
519
|
}
|
|
514
|
-
return done({ empty: false, launcherChain, verb, reentry: "shell", declines, reads, moveProvable: false, ...(loopHead !== undefined ? { loopHead } : {}), ...(stdin.length > 0 ? { stdin } : {}) });
|
|
520
|
+
return done({ empty: false, launcherChain, verb, reentry: "shell", declines, reads, moveProvable: false, ...(loopHead !== undefined ? { loopHead } : {}), ...(stdin.length > 0 ? { stdin } : {}), ...(shift !== undefined ? { shift } : {}) });
|
|
515
521
|
};
|
|
516
522
|
if (pos.refusal !== undefined) {
|
|
517
523
|
const owner = programRow(programBasename(pos.refusal.owner));
|
|
518
524
|
if (pos.refusal.kind === "option_at_program_position" && owner !== undefined && commandLineOptionSpellings(owner).length > 0) {
|
|
519
525
|
const text = commandStringValue(owner, toks, pos.refusal.option);
|
|
520
526
|
if (text !== undefined) {
|
|
521
|
-
nested.push(nestedPlan(text.value, "
|
|
527
|
+
nested.push(nestedPlan(text.value, "now"));
|
|
522
528
|
reentry = "shell";
|
|
523
529
|
unlistedWords(reads, toks, text.next, launcherIndices, "unlisted_word", ctx);
|
|
524
530
|
return done({ empty: false, launcherChain, ...(verb !== undefined ? { verb } : {}), reentry, declines, reads, moveProvable: false, ...(loopHead !== undefined ? { loopHead } : {}) });
|
|
@@ -551,6 +557,12 @@ function segmentFactsRead(segment, p, decl, table, nestedPlan, fed, toks) {
|
|
|
551
557
|
const programRead = toks[program.index];
|
|
552
558
|
if (rewritten(programRead) || isPathShapedToken(programRead.folded))
|
|
553
559
|
reads.push(bare(programRead, "program_path"));
|
|
560
|
+
if (rewritten(programRead) && !programRead.word.pieces.some((p) => p.literal?.includes("/") === true))
|
|
561
|
+
shift = { kind: "lost" };
|
|
562
|
+
if (basename === "eval")
|
|
563
|
+
shift = argReads.every((r) => literalTextOf(r.word.pieces) !== undefined) && reentryText("eval", texts) !== undefined ? { kind: "eval", text: reentryText("eval", texts) } : { kind: "lost" };
|
|
564
|
+
if (basename === "source" || basename === ".")
|
|
565
|
+
shift = { kind: "lost" };
|
|
554
566
|
if (runsShellText(basename))
|
|
555
567
|
return reenterShell(verb, [{ shell: basename, texts, args, words: argReads }]);
|
|
556
568
|
const row = programRow(basename);
|
|
@@ -559,11 +571,16 @@ function segmentFactsRead(segment, p, decl, table, nestedPlan, fed, toks) {
|
|
|
559
571
|
reentry = "interpreter";
|
|
560
572
|
const moveProvable = pos.controlWords.length === 0 && pos.launchers.length === 0 && pos.assignments.length === 0 && program.name === basename;
|
|
561
573
|
let baseMove;
|
|
574
|
+
const moving = baseShiftOf(basename, argReads, (r) => bare(r, "cd_target"));
|
|
575
|
+
if (moving !== undefined)
|
|
576
|
+
shift = moving.shift;
|
|
577
|
+
if (moving?.reported !== undefined)
|
|
578
|
+
baseMove = { target: moving.reported };
|
|
562
579
|
if (basename === "cd") {
|
|
563
|
-
baseMove
|
|
580
|
+
if (typeof baseMove?.target === "object")
|
|
581
|
+
reads.push(baseMove.target);
|
|
564
582
|
}
|
|
565
|
-
else if (
|
|
566
|
-
baseMove = { target: "unmodelled" };
|
|
583
|
+
else if (movesBaseByStack(basename)) {
|
|
567
584
|
unlistedWords(reads, toks, program.index, launcherIndices, "unlisted_word", ctx, program);
|
|
568
585
|
}
|
|
569
586
|
else if (listed) {
|
|
@@ -631,6 +648,7 @@ function segmentFactsRead(segment, p, decl, table, nestedPlan, fed, toks) {
|
|
|
631
648
|
declines,
|
|
632
649
|
reads,
|
|
633
650
|
...(baseMove !== undefined ? { baseMove } : {}),
|
|
651
|
+
...(shift !== undefined ? { shift } : {}),
|
|
634
652
|
moveProvable,
|
|
635
653
|
...(loopHead !== undefined ? { loopHead } : {}),
|
|
636
654
|
});
|
|
@@ -648,10 +666,7 @@ function dedupe(reads) {
|
|
|
648
666
|
return out;
|
|
649
667
|
}
|
|
650
668
|
function relativeSpelling(spelled) {
|
|
651
|
-
return !(
|
|
652
|
-
}
|
|
653
|
-
function joinBase(base, target, homeDir) {
|
|
654
|
-
return resolveOperandLexically(base, target, homeDir);
|
|
669
|
+
return !(isAbsoluteForFamily("own", spelled) || spelled.startsWith("~"));
|
|
655
670
|
}
|
|
656
671
|
function redirectFact(r, table, homeDir) {
|
|
657
672
|
if (r.target === undefined)
|
|
@@ -692,13 +707,3 @@ function literalBeats(toks) {
|
|
|
692
707
|
return undefined;
|
|
693
708
|
return words.length <= POLL_LOOP_MAX_BEATS ? words.length : undefined;
|
|
694
709
|
}
|
|
695
|
-
function cdMove(args, reads) {
|
|
696
|
-
const target = args.find((t) => !t.folded.startsWith("-") || t.folded === "-");
|
|
697
|
-
if (target === undefined)
|
|
698
|
-
return { target: "home" };
|
|
699
|
-
if (target.folded === "-")
|
|
700
|
-
return { target: "previous" };
|
|
701
|
-
const c = bare(target, "cd_target");
|
|
702
|
-
reads.push(c);
|
|
703
|
-
return { target: c };
|
|
704
|
-
}
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
* the segment it sits in ({@link rebasePlan}), unless it starts in a working directory of its own.
|
|
6
6
|
*/
|
|
7
7
|
import type { LexedSegment } from "../../shell/lex.js";
|
|
8
|
-
import type { BindingTable, FloorValue, NameReader } from "./shell-read-bindings.js";
|
|
8
|
+
import type { BindingTable, FloorValue, InheritedFunctions, NameReader } from "./shell-read-bindings.js";
|
|
9
9
|
import type { TargetUser } from "./program-read-model.js";
|
|
10
10
|
import type { StdinText } from "./shell-reentry-text.js";
|
|
11
11
|
import type { ReadCandidate, ShellReadPlan } from "./shell-read-plan.js";
|
|
12
12
|
/** Where a nested text starts its names: a substitution body inherits the table of the segment it sits in (a subshell
|
|
13
|
-
* holds every variable); a text the shell runs later or elsewhere (a code body, `eval`'s
|
|
14
|
-
* starts from the text's own start — every name unknown, `HOME` the declared home unless
|
|
15
|
-
* anywhere. `boundAnywhere` answers for the enclosing texts. */
|
|
13
|
+
* holds every variable of the shell that forks it); a text the shell runs later or elsewhere (a code body, `eval`'s
|
|
14
|
+
* text, a child shell's `-c`) starts from the text's own start — every name unknown, `HOME` the declared home unless
|
|
15
|
+
* the enclosing text binds it anywhere. `boundAnywhere` answers for the enclosing texts. */
|
|
16
16
|
export interface PlanStart {
|
|
17
17
|
readonly initial: NameReader;
|
|
18
18
|
readonly boundAnywhere: (name: string) => boolean;
|
|
@@ -23,9 +23,30 @@ export interface PlanStart {
|
|
|
23
23
|
/** The working directories it starts in, where they are not the enclosing segment's (a login shell starts in its user's
|
|
24
24
|
* home; `"unmodelled"` — a home the text does not settle). */
|
|
25
25
|
readonly bases?: readonly string[] | "unmodelled";
|
|
26
|
+
/** The thread of the shell that runs the text, where the text runs in that shell or a fork of it ({@link HeldThread}). */
|
|
27
|
+
readonly thread?: HeldThread;
|
|
28
|
+
/** What the shell around the text holds where the text runs in that shell or a fork of it — a literal `eval` text, a
|
|
29
|
+
* substitution body, a text run later (a `trap` action): each function and builtin key as it stands there
|
|
30
|
+
* ({@link InheritedFunctions}). A text a new process runs (a child shell's `-c`) holds none: every builtin enabled, no function. */
|
|
31
|
+
readonly names?: InheritedFunctions;
|
|
26
32
|
/** What arrives on its own standard input (the input of the shell running it). */
|
|
27
33
|
readonly stdin?: readonly StdinText[];
|
|
28
34
|
}
|
|
35
|
+
/** The thread of the shell that runs a text, at the segment that hands it on: a literal `eval` text is not a new plan but the next
|
|
36
|
+
* segment of the same thread, so it starts in all of it and hands the working directory and the physical mode back; a substitution
|
|
37
|
+
* body (a fork) and a text run later start in what the shell holds and hand nothing back. `functions`: the names a call may mean
|
|
38
|
+
* (the shell's definition heads and the ones an `eval` text defines), `unread` those whose bodies the nested plan has not read — an
|
|
39
|
+
* `eval` text reads the shell's bodies through the names they bind, every other text has none of them in front of it. */
|
|
40
|
+
export interface HeldThread {
|
|
41
|
+
readonly physical: boolean;
|
|
42
|
+
readonly functions: ReadonlySet<string>;
|
|
43
|
+
readonly unread: ReadonlySet<string>;
|
|
44
|
+
}
|
|
45
|
+
/** What a shell holds at a segment, for a text that runs in it or in a fork of it ({@link PlanStart.names}): each function and builtin key
|
|
46
|
+
* as it stands there, and the names a call to one of its functions may change — the ones the text reads a call of: an `eval` text names
|
|
47
|
+
* the shell's functions (`bound`: what a call to one of them changes); a substitution body and a text run later read none of their bodies
|
|
48
|
+
* (the shell's functions are {@link HeldThread.unread} there: a call to one makes every name unknown), so they name none. */
|
|
49
|
+
export declare function heldAt(table: BindingTable, bound?: InheritedFunctions["bound"]): InheritedFunctions;
|
|
29
50
|
/** What a segment says of the start of a text it hands a shell to run later: the deny floors of the words it holds as
|
|
30
51
|
* written, the user the shell runs as ({@link TargetUser}), and the shell's standard input. */
|
|
31
52
|
export interface NestedStart {
|
|
@@ -52,6 +73,8 @@ export declare function stdinFeeds(segments: readonly LexedSegment[], start: rea
|
|
|
52
73
|
* $(cat secret)`), so its relative candidates are re-based onto the ENCLOSING segment's bases — every base the
|
|
53
74
|
* nested text derived from the start is carried over by prefix, an unsettled enclosing base leaves every
|
|
54
75
|
* relative candidate unplaced, and absolute candidates are untouched. Recursive: a nested plan's own nested plans
|
|
55
|
-
* derive from the same start.
|
|
76
|
+
* derive from the same start. A candidate left unplaced is judged where the text stood when it lost track (its floor,
|
|
77
|
+
* {@link ReadCandidate.floorBases}): the places the nested text was in move with it like its bases, and an enclosing segment that
|
|
78
|
+
* lost its base itself hands on its own floor (`floor`).
|
|
56
79
|
*/
|
|
57
|
-
export declare function rebasePlan(plan: ShellReadPlan, from: string, to: ReadCandidate["bases"]): ShellReadPlan;
|
|
80
|
+
export declare function rebasePlan(plan: ShellReadPlan, from: string, to: ReadCandidate["bases"], floor?: readonly string[]): ShellReadPlan;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
const NO_NAMES = new Set();
|
|
2
|
+
export function heldAt(table, bound = NO_NAMES) {
|
|
3
|
+
return { start: (key) => table.stateOf(key), bound };
|
|
4
|
+
}
|
|
1
5
|
const ROOT_HOMES = ["/root", "/var/root"];
|
|
2
6
|
export function startedAt(later, at) {
|
|
3
7
|
if (at === undefined)
|
|
@@ -58,24 +62,27 @@ export function stdinFeeds(segments, start, piped) {
|
|
|
58
62
|
};
|
|
59
63
|
return fedAt;
|
|
60
64
|
}
|
|
61
|
-
export function rebasePlan(plan, from, to) {
|
|
65
|
+
export function rebasePlan(plan, from, to, floor) {
|
|
62
66
|
if (to !== "unmodelled" && to.length === 1 && to[0] === from)
|
|
63
67
|
return plan;
|
|
64
68
|
const fromSep = from.endsWith("/") || from.endsWith("\\") ? from : `${from}/`;
|
|
65
|
-
const
|
|
66
|
-
if (to === "unmodelled")
|
|
67
|
-
return [];
|
|
69
|
+
const moveInto = (into, b) => {
|
|
68
70
|
if (b === from)
|
|
69
|
-
return [...
|
|
71
|
+
return [...into];
|
|
70
72
|
if (b.startsWith(fromSep))
|
|
71
|
-
return
|
|
73
|
+
return into.map((t) => `${t.endsWith("/") || t.endsWith("\\") ? t : `${t}/`}${b.slice(fromSep.length)}`);
|
|
72
74
|
return [b];
|
|
73
75
|
};
|
|
76
|
+
const moveBase = (b) => (to === "unmodelled" ? [] : moveInto(to, b));
|
|
77
|
+
const floorAt = to === "unmodelled" ? floor : to;
|
|
78
|
+
const moveFloor = (bases, into) => [...new Set(bases.flatMap((b) => moveInto(into, b)))];
|
|
74
79
|
const moveCandidate = (c) => {
|
|
75
|
-
if (c.bases === "unmodelled"
|
|
80
|
+
if (c.bases === "unmodelled")
|
|
81
|
+
return c.floorBases === undefined || floorAt === undefined ? c : { ...c, floorBases: moveFloor(c.floorBases, floorAt) };
|
|
82
|
+
if (c.bases.length === 0)
|
|
76
83
|
return c;
|
|
77
84
|
if (to === "unmodelled")
|
|
78
|
-
return { ...c, bases: "unmodelled" };
|
|
85
|
+
return floor === undefined ? { ...c, bases: "unmodelled" } : { ...c, bases: "unmodelled", floorBases: moveFloor(c.bases, floor) };
|
|
79
86
|
return { ...c, bases: [...new Set(c.bases.flatMap(moveBase))] };
|
|
80
87
|
};
|
|
81
88
|
return {
|
|
@@ -86,7 +93,7 @@ export function rebasePlan(plan, from, to) {
|
|
|
86
93
|
redirects: s.redirects.map((r) => (r.target === undefined ? r : { ...r, target: moveCandidate(r.target) })),
|
|
87
94
|
...(s.baseMove !== undefined ? { baseMove: { target: typeof s.baseMove.target === "string" ? s.baseMove.target : moveCandidate(s.baseMove.target) } } : {}),
|
|
88
95
|
bases: s.bases === "unmodelled" || to === "unmodelled" ? "unmodelled" : [...new Set(s.bases.flatMap(moveBase))],
|
|
89
|
-
nested: s.nested.map((n) => rebasePlan(n, from, to)),
|
|
96
|
+
nested: s.nested.map((n) => rebasePlan(n, from, to, floor)),
|
|
90
97
|
})),
|
|
91
98
|
};
|
|
92
99
|
}
|
|
@@ -85,6 +85,10 @@ function overlaidTable(table, overlay) {
|
|
|
85
85
|
isInteger: (name) => table.isInteger(name),
|
|
86
86
|
ifsTouched: table.ifsTouched,
|
|
87
87
|
homeTouched: table.homeTouched,
|
|
88
|
+
rebound: table.rebound,
|
|
89
|
+
providedByShell: (name) => table.providedByShell(name),
|
|
90
|
+
functionState: (name) => table.functionState(name),
|
|
91
|
+
builtinState: (name) => table.builtinState(name),
|
|
88
92
|
floorOf: (name) => {
|
|
89
93
|
const held = table.stateOf(name);
|
|
90
94
|
return overlay.get(name) !== "unknown" || held === "unknown" ? table.floorOf(name) : [...table.floorOf(name), ...held.map(floorOf)];
|