@sema-agent/core 7.48.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 +418 -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 +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 +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 +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.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 +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/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/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 +10 -3
- package/dist/tools/fs/bash-program-position.js +21 -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 +39 -18
- package/dist/tools/fs/program-read-model.js +29 -19
- package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
- package/dist/tools/fs/program-read-model.rows.js +5 -5
- 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 +51 -42
- 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 +48 -18
- package/dist/tools/fs/shell-read-judge.js +33 -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,6 +1,7 @@
|
|
|
1
1
|
import { hasWin32AliasedComponent, normalizeAbsPathLexically, withinAnyRoot } from "./safety.js";
|
|
2
2
|
import { globInWord } from "./bash-readonly-classifier.js";
|
|
3
3
|
import { readOfText } from "./shell-read-word.js";
|
|
4
|
+
import { skipsRootsContainment } from "./containment-face.js";
|
|
4
5
|
export const SHELL_READ_FINDINGS = Object.freeze(["deny_hit", "outside_roots", "unestablishable", "declined", "identity_changed", "none"]);
|
|
5
6
|
export const SHELL_READ_SEATS = Object.freeze(["full_shell", "readonly", "rejudge"]);
|
|
6
7
|
export const SHELL_READ_FINDING_RANK = {
|
|
@@ -37,11 +38,11 @@ export function judgeRead(read, boundary) {
|
|
|
37
38
|
const folded = normalizeAbsPathLexically(view);
|
|
38
39
|
const pattern = writeTarget ? boundary.writeDenyMatch(folded) : boundary.denyMatch(folded, walked);
|
|
39
40
|
if (pattern !== null)
|
|
40
|
-
return { read, kind: "deny_hit", deny: { pattern, matchedView: folded, ...(writeTarget ? { face: "write" } : {}) }, containment: containmentOf(read, boundary) };
|
|
41
|
+
return { read, kind: "deny_hit", deny: { pattern, matchedView: folded, ...(writeTarget ? { face: "write" } : {}) }, containment: writeTarget ? writeContainmentOf(read, boundary) : containmentOf(read, boundary) };
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
if (writeTarget)
|
|
44
|
-
return
|
|
45
|
+
return judgeWrite(read, boundary);
|
|
45
46
|
const containment = containmentOf(read, boundary);
|
|
46
47
|
if (read.candidate.denyOnly === true)
|
|
47
48
|
return { read, kind: "none", containment };
|
|
@@ -72,19 +73,45 @@ function containmentOf(read, boundary) {
|
|
|
72
73
|
return "unknown";
|
|
73
74
|
return withinAnyRoot(boundary.roots, read.target) ? "inside" : "outside";
|
|
74
75
|
}
|
|
76
|
+
const NULL_DEVICE = "/dev/null";
|
|
77
|
+
function writeContainmentOf(read, boundary) {
|
|
78
|
+
const device = read.written?.seat === "landing" && read.candidate.expands === false && read.candidate.spelled === NULL_DEVICE;
|
|
79
|
+
if (read.written === undefined || read.candidate.denyOnly === true || device)
|
|
80
|
+
return "open";
|
|
81
|
+
const roots = boundary.writeRoots;
|
|
82
|
+
if (roots === undefined || read.target === undefined)
|
|
83
|
+
return "unknown";
|
|
84
|
+
return withinAnyRoot(roots, read.target) ? "inside" : "outside";
|
|
85
|
+
}
|
|
86
|
+
function judgeWrite(read, boundary) {
|
|
87
|
+
const containment = writeContainmentOf(read, boundary);
|
|
88
|
+
if (containment === "open")
|
|
89
|
+
return { read, kind: "none", containment };
|
|
90
|
+
if (read.established === "unestablishable" || boundary.writeRoots === undefined)
|
|
91
|
+
return { read, kind: "unestablishable", containment };
|
|
92
|
+
return { read, kind: containment === "outside" && !skipsRootsContainment(boundary.writeFace) ? "outside_roots" : "none", containment };
|
|
93
|
+
}
|
|
75
94
|
export function stationGuards(boundary) {
|
|
76
95
|
return boundary.face !== "open" || boundary.denyMatch !== undefined;
|
|
77
96
|
}
|
|
97
|
+
export function writeFaceGuards(boundary) {
|
|
98
|
+
return !skipsRootsContainment(boundary.writeFace) || boundary.writeDenyMatch !== undefined;
|
|
99
|
+
}
|
|
100
|
+
export function anyFaceGuards(boundary) {
|
|
101
|
+
return stationGuards(boundary) || writeFaceGuards(boundary);
|
|
102
|
+
}
|
|
78
103
|
export function foldShellReadFindings(judged) {
|
|
79
104
|
let best = { finding: "none" };
|
|
80
105
|
let unestablished = false;
|
|
81
106
|
const raise = (next) => {
|
|
82
107
|
if (next.finding === "unestablishable" || next.finding === "declined") {
|
|
83
|
-
|
|
108
|
+
const face = next.witness?.read.candidate.face;
|
|
109
|
+
if (!(next.witness === undefined ? judged.guards || judged.writeGuards : face === "write" ? judged.writeGuards : judged.guards))
|
|
84
110
|
return;
|
|
85
111
|
unestablished = true;
|
|
86
112
|
}
|
|
87
|
-
|
|
113
|
+
const rank = SHELL_READ_FINDING_RANK[next.finding] - SHELL_READ_FINDING_RANK[best.finding];
|
|
114
|
+
if (rank > 0 || (rank === 0 && next.witness?.read.candidate.face === "write" && best.witness?.read.candidate.face !== "write"))
|
|
88
115
|
best = next;
|
|
89
116
|
};
|
|
90
117
|
const walk = (j, denyOnly) => {
|
|
@@ -125,6 +152,7 @@ export function judgeEstablishedPlan(plan, established, boundary, nestedOf) {
|
|
|
125
152
|
nested: segment.nested.map(nestedOf),
|
|
126
153
|
})),
|
|
127
154
|
guards: stationGuards(boundary),
|
|
155
|
+
writeGuards: writeFaceGuards(boundary),
|
|
128
156
|
};
|
|
129
157
|
}
|
|
130
158
|
export function allFindings(judged) {
|
|
@@ -208,5 +236,6 @@ export function rejudge(judged, boundary) {
|
|
|
208
236
|
nested: s.nested.map((n) => rejudge(n, boundary)),
|
|
209
237
|
})),
|
|
210
238
|
guards: stationGuards(boundary),
|
|
239
|
+
writeGuards: writeFaceGuards(boundary),
|
|
211
240
|
};
|
|
212
241
|
}
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
* and here-strings are data (an UNQUOTED here-document body's substitutions are nested plans) — except to a shell
|
|
25
25
|
* whose argv names no script: what arrives on its standard input is its script, a nested plan where the text spells it;
|
|
26
26
|
* · `$(…)`, backticks and `<(…)` bodies are nested plans; a word carrying one cannot be resolved from the text;
|
|
27
|
-
* · `
|
|
28
|
-
* else does)
|
|
29
|
-
* otherwise loses the base for what follows.
|
|
27
|
+
* · the working-directory thread (`shell-read-workdir.ts`) moves the base the LATER segments resolve against, as a
|
|
28
|
+
* candidate SET (`&&` proves a move, nothing else does), and gives `PWD` / `OLDPWD` their values; a loop body with
|
|
29
|
+
* a base move is replayed per LITERAL beat and otherwise loses the base for what follows.
|
|
30
30
|
* Every ambiguity resolves toward MORE candidates, never fewer.
|
|
31
31
|
*/
|
|
32
32
|
import { type LenientConnector, type LexedRedirect, type LexedWord } from "../../shell/lex.js";
|
|
@@ -47,6 +47,9 @@ export interface ShellReadDeclarations {
|
|
|
47
47
|
readonly cwd: string;
|
|
48
48
|
readonly roots: readonly string[];
|
|
49
49
|
readonly face?: "open" | "roots";
|
|
50
|
+
/** The `CDPATH` the shell starts with (the environment's declared one, `ExecutionEnv.cdPath`; a bare relative `cd` is
|
|
51
|
+
* searched through it): absent ⇒ none declared, read as unset; `unknown` ⇒ the text cannot know it. */
|
|
52
|
+
readonly cdPath?: readonly string[] | "unknown";
|
|
50
53
|
}
|
|
51
54
|
export interface ReadCandidate {
|
|
52
55
|
/** The folded word (quotes removed, a literal leading tilde spelled `./~`) — a pattern's name where nothing matches. */
|
|
@@ -70,10 +73,10 @@ export interface ReadCandidate {
|
|
|
70
73
|
/** A home word the plan does not place (the text may rebind `HOME`, it sits in a value, or it is a literal tilde the
|
|
71
74
|
* program may expand itself): spelled with the DECLARED home. The judge reads it for deny rows ONLY. */
|
|
72
75
|
readonly floorSpelled?: string;
|
|
73
|
-
/**
|
|
76
|
+
/** Deny rows only (never containment): a `floorSpelled` shadow, or the read copy of a word the program only writes. */
|
|
74
77
|
readonly denyOnly?: true;
|
|
75
|
-
/** A WRITE target
|
|
76
|
-
*
|
|
78
|
+
/** A WRITE target (a `>`-family redirection, a `sed` `w` file, a file-writing command's operand): established like a
|
|
79
|
+
* read, judged on the WRITE face — the write deny rows, then the write roots where written — never as a read. */
|
|
77
80
|
readonly face?: "write";
|
|
78
81
|
/** A reading the station takes where no row says the program opens the word — a word of a program with no row, a
|
|
79
82
|
* role only another implementation reads — so the filesystem decides it: `containment` = the spelling always meets
|
|
@@ -129,6 +132,9 @@ export interface ShellReadSegment {
|
|
|
129
132
|
/** Substitution bodies, unquoted here-document substitutions, and re-entered shell text, each its own plan. */
|
|
130
133
|
readonly nested: readonly ShellReadPlan[];
|
|
131
134
|
readonly reach: SegmentReach;
|
|
135
|
+
/** The names a change that can reach this segment touched (`BindingTable.rebound`): any other name still holds what the
|
|
136
|
+
* shell provides here. `all`: any name may have changed. */
|
|
137
|
+
readonly rebound: ReadonlySet<string> | "all";
|
|
132
138
|
}
|
|
133
139
|
export interface ShellReadPlan {
|
|
134
140
|
readonly segments: readonly ShellReadSegment[];
|
|
@@ -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
|
-
}
|