@sema-agent/core 7.47.0 → 7.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +472 -0
- package/README.md +2 -2
- package/dist/agents/cascade.d.ts +2 -5
- package/dist/agents/child-failure.d.ts +20 -0
- package/dist/agents/child-failure.js +28 -0
- package/dist/agents/cross-session-ref.d.ts +11 -3
- package/dist/agents/cross-session-ref.js +6 -0
- package/dist/agents/cumulative-stats.d.ts +12 -15
- package/dist/agents/cumulative-stats.js +1 -1
- package/dist/agents/extra-tool-names.js +1 -1
- package/dist/agents/inherited-tool-pool.d.ts +17 -13
- package/dist/agents/inherited-tool-pool.js +4 -3
- package/dist/agents/peer-session-drain.d.ts +3 -2
- package/dist/agents/peer-session-drain.js +5 -4
- package/dist/agents/send-message-tool.js +2 -9
- package/dist/agents/subagent.d.ts +10 -29
- package/dist/agents/subagent.js +65 -53
- package/dist/agents/suspend-guard.d.ts +1 -1
- package/dist/agents/tool-filter.d.ts +76 -65
- package/dist/agents/tool-filter.js +122 -92
- package/dist/agents/verify.d.ts +4 -7
- package/dist/agents/verify.js +6 -7
- package/dist/bench/metrics.d.ts +1 -2
- package/dist/brain/anthropic.js +133 -79
- package/dist/brain/errors.d.ts +53 -6
- package/dist/brain/errors.js +22 -2
- package/dist/brain/input-too-long.d.ts +40 -19
- package/dist/brain/input-too-long.js +3 -16
- package/dist/brain/open-responses.js +19 -10
- package/dist/brain/openai.js +123 -32
- package/dist/brain/provider-dialect.d.ts +214 -0
- package/dist/brain/provider-dialect.js +186 -0
- package/dist/brain/request-params.d.ts +27 -8
- package/dist/brain/request-params.js +7 -12
- package/dist/brain/request-route.d.ts +84 -0
- package/dist/brain/request-route.js +41 -0
- package/dist/brain/retry.d.ts +8 -0
- package/dist/brain/retry.js +10 -4
- package/dist/brain/route-adjudicator.d.ts +7 -0
- package/dist/brain/route-adjudicator.js +5 -1
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +11 -0
- package/dist/brain/stream-engine.d.ts +52 -1
- package/dist/brain/stream-engine.js +81 -24
- package/dist/brain/stream-shared.d.ts +57 -11
- package/dist/brain/stream-shared.js +28 -2
- package/dist/core/a2a.d.ts +1 -0
- package/dist/core/agent-config-dir.js +3 -2
- package/dist/core/allow-entry.d.ts +21 -12
- package/dist/core/allow-entry.js +39 -32
- package/dist/core/arg-summary.d.ts +17 -24
- package/dist/core/arg-summary.js +169 -68
- package/dist/core/ask-origin.d.ts +42 -24
- package/dist/core/ask-origin.js +18 -13
- package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
- package/dist/core/auto-mode-prompt-assets.js +1 -1
- package/dist/core/auto-mode-prompt.d.ts +11 -1
- package/dist/core/auto-mode-prompt.js +13 -10
- package/dist/core/auto-mode-rebuild.d.ts +7 -0
- package/dist/core/auto-mode-rebuild.js +4 -1
- package/dist/core/canonical-json.d.ts +3 -0
- package/dist/core/canonical-json.js +2 -1
- package/dist/core/checkpoint-requirements.d.ts +892 -0
- package/dist/core/checkpoint-requirements.js +333 -0
- package/dist/core/checkpoint-store.d.ts +95 -66
- package/dist/core/checkpoint-store.js +14 -26
- package/dist/core/child-clamp-seats.d.ts +228 -69
- package/dist/core/child-clamp-seats.js +211 -17
- package/dist/core/classifier-unavailable-arm.d.ts +5 -1
- package/dist/core/classifier-unavailable-arm.js +3 -3
- package/dist/core/compliance.d.ts +3 -0
- package/dist/core/compliance.js +9 -4
- package/dist/core/credential-vocabulary.d.ts +140 -0
- package/dist/core/credential-vocabulary.js +131 -0
- package/dist/core/decision-receipt.js +1 -1
- package/dist/core/effective-path-target.d.ts +73 -16
- package/dist/core/effective-path-target.js +63 -33
- package/dist/core/engine-notice.d.ts +32 -7
- package/dist/core/file-history-store.js +2 -2
- package/dist/core/fs-write-gate-policy.d.ts +4 -0
- package/dist/core/fs-write-gate-policy.js +22 -5
- package/dist/core/gate-bounded-await.d.ts +28 -13
- package/dist/core/gate-bounded-await.js +41 -4
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +24 -25
- package/dist/core/gate-lanes.js +16 -15
- package/dist/core/gate-outcome.d.ts +20 -5
- package/dist/core/gate-outcome.js +5 -0
- package/dist/core/governance-codes.d.ts +11 -4
- package/dist/core/governance-codes.js +14 -3
- package/dist/core/hooks.d.ts +4 -0
- package/dist/core/locked-config.d.ts +8 -0
- package/dist/core/locked-config.js +14 -2
- package/dist/core/lsp.js +3 -5
- package/dist/core/mailbox-store.d.ts +3 -4
- package/dist/core/mcp-connection-pool.d.ts +75 -0
- package/dist/core/mcp-connection-pool.js +128 -0
- package/dist/core/mcp-failure.d.ts +2 -1
- package/dist/core/mcp-failure.js +13 -2
- package/dist/core/mcp-server-spec.d.ts +1 -1
- package/dist/core/mcp.d.ts +4 -0
- package/dist/core/mcp.js +70 -43
- package/dist/core/memory-engine/content-origin.js +2 -14
- package/dist/core/memory-engine/engine.d.ts +32 -22
- package/dist/core/memory-engine/engine.js +103 -55
- package/dist/core/memory-engine/file-backend.d.ts +13 -30
- package/dist/core/memory-engine/file-backend.js +37 -252
- package/dist/core/memory-engine/index.d.ts +1 -1
- package/dist/core/memory-engine/index.js +1 -1
- package/dist/core/memory-engine/layout.d.ts +139 -9
- package/dist/core/memory-engine/layout.js +350 -7
- package/dist/core/memory-engine/scope-contract.d.ts +10 -0
- package/dist/core/memory-engine/scope-contract.js +8 -0
- package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
- package/dist/core/memory-engine/session-incarnation.js +5 -2
- package/dist/core/memory-engine/types.d.ts +10 -1
- package/dist/core/memory.js +5 -17
- package/dist/core/model-seat.d.ts +4 -4
- package/dist/core/model-seat.js +1 -1
- package/dist/core/mounted-mcp.d.ts +57 -0
- package/dist/core/mounted-mcp.js +19 -0
- package/dist/core/namespaced-rule-name.d.ts +29 -0
- package/dist/core/namespaced-rule-name.js +52 -0
- package/dist/core/park-selfcheck.d.ts +1 -1
- package/dist/core/park-selfcheck.js +16 -6
- package/dist/core/path-guard-rows.d.ts +99 -0
- package/dist/core/path-guard-rows.js +45 -0
- package/dist/core/path-identity.d.ts +22 -16
- package/dist/core/path-identity.js +10 -10
- package/dist/core/path-rule-binding.d.ts +2 -1
- package/dist/core/path-rule-binding.js +3 -1
- package/dist/core/pause-registry.d.ts +16 -2
- package/dist/core/pause-registry.js +6 -0
- package/dist/core/permission-rule-consent.js +0 -7
- package/dist/core/permission-rule-model.d.ts +68 -24
- package/dist/core/permission-rule-model.js +105 -24
- package/dist/core/permission-rule-store.js +2 -2
- package/dist/core/permission-rules.d.ts +3 -30
- package/dist/core/permission-rules.js +4 -54
- package/dist/core/read-root-candidate.d.ts +1 -3
- package/dist/core/read-root-candidate.js +4 -15
- package/dist/core/real-approval.d.ts +4 -3
- package/dist/core/retired-keys.d.ts +13 -0
- package/dist/core/retired-keys.js +14 -0
- package/dist/core/roles.d.ts +2 -3
- package/dist/core/roles.js +15 -6
- package/dist/core/runner/assemble-result.d.ts +0 -7
- package/dist/core/runner/assemble-result.js +19 -31
- package/dist/core/runner/caller-roster.d.ts +78 -0
- package/dist/core/runner/caller-roster.js +219 -0
- package/dist/core/runner/checkpoint-scope.d.ts +16 -16
- package/dist/core/runner/checkpoint-scope.js +2 -2
- package/dist/core/runner/child-tree.js +2 -2
- package/dist/core/runner/contracts.d.ts +68 -35
- package/dist/core/runner/decide-continuation.d.ts +51 -3
- package/dist/core/runner/decide-continuation.js +76 -21
- package/dist/core/runner/denial-limit-arms.d.ts +17 -5
- package/dist/core/runner/denial-limit-arms.js +11 -9
- package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
- package/dist/core/runner/extra-body-dropped-seat.js +22 -0
- package/dist/core/runner/finish-reason-seat.d.ts +9 -0
- package/dist/core/runner/finish-reason-seat.js +40 -0
- package/dist/core/runner/gate-exit.d.ts +44 -32
- package/dist/core/runner/gate-exit.js +112 -25
- package/dist/core/runner/inherited-ask-grants.js +6 -4
- package/dist/core/runner/mcp-redial.d.ts +3 -3
- package/dist/core/runner/mcp-redial.js +3 -4
- package/dist/core/runner/park-commit.d.ts +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
- package/dist/core/runner/permission-rule-lanes.js +5 -4
- package/dist/core/runner/prepare-artifact.d.ts +4 -0
- package/dist/core/runner/prepare-artifact.js +2 -1
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
- package/dist/core/runner/prepare-ask-lane.js +12 -6
- package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
- package/dist/core/runner/prepare-boundary-parks.js +4 -7
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
- package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
- package/dist/core/runner/prepare-config-doors.d.ts +9 -9
- package/dist/core/runner/prepare-config-doors.js +10 -5
- package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
- package/dist/core/runner/prepare-defer-classify.js +5 -3
- package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
- package/dist/core/runner/prepare-delegation-surface.js +3 -3
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
- package/dist/core/runner/prepare-gate-stations.js +9 -7
- package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
- package/dist/core/runner/prepare-hands-readface.js +7 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
- package/dist/core/runner/prepare-inherited-gate.js +14 -15
- package/dist/core/runner/prepare-listings.d.ts +7 -24
- package/dist/core/runner/prepare-listings.js +4 -5
- package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
- package/dist/core/runner/prepare-memory-engine-session.js +4 -3
- package/dist/core/runner/prepare-memory.d.ts +6 -0
- package/dist/core/runner/prepare-memory.js +13 -13
- package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
- package/dist/core/runner/prepare-offload-wrappers.js +3 -3
- package/dist/core/runner/prepare-park-ask.d.ts +7 -8
- package/dist/core/runner/prepare-park-ask.js +17 -10
- package/dist/core/runner/prepare-policy-chain.js +24 -44
- package/dist/core/runner/prepare-project-context.d.ts +1 -1
- package/dist/core/runner/prepare-project-context.js +3 -4
- package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
- package/dist/core/runner/prepare-protocol-tools.js +3 -4
- package/dist/core/runner/prepare-run-refs.d.ts +3 -0
- package/dist/core/runner/prepare-run-refs.js +2 -1
- package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
- package/dist/core/runner/prepare-safety-scan.js +1 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
- package/dist/core/runner/prepare-suspend-saga.js +28 -12
- package/dist/core/runner/prepare-task.d.ts +1 -1
- package/dist/core/runner/prepare-task.js +67 -56
- package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
- package/dist/core/runner/prepare-wiring-manifest.js +5 -8
- package/dist/core/runner/resume-apply.js +7 -14
- package/dist/core/runner/resume-checkpoint-screen.js +11 -4
- package/dist/core/runner/resume-internals-and-config.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +5 -32
- package/dist/core/runner/resume-review-outcome.js +4 -1
- package/dist/core/runner/retired-runner-deps.d.ts +6 -0
- package/dist/core/runner/retired-runner-deps.js +10 -1
- package/dist/core/runner/run-brain-sinks.d.ts +4 -0
- package/dist/core/runner/run-brain-sinks.js +5 -2
- package/dist/core/runner/run-harness-handlers.js +27 -34
- package/dist/core/runner/run-leg.d.ts +0 -2
- package/dist/core/runner/run-leg.js +32 -33
- package/dist/core/runner/run-terminal-adoption.js +4 -3
- package/dist/core/runner/runtask.js +8 -8
- package/dist/core/runner/session-rule-policy.js +5 -5
- package/dist/core/runner/stream-settle-backstop.js +7 -4
- package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
- package/dist/core/runner/sub-agent-deny-lists.js +111 -80
- package/dist/core/runner/terminal-account.d.ts +48 -0
- package/dist/core/runner/terminal-account.js +186 -0
- package/dist/core/runner/tool-end-body.d.ts +54 -17
- package/dist/core/runner/tool-end-body.js +27 -2
- package/dist/core/runner/tool-face-overlay.d.ts +3 -1
- package/dist/core/runner/tool-face-overlay.js +6 -4
- package/dist/core/runner/tool-occurrence.d.ts +106 -0
- package/dist/core/runner/tool-occurrence.js +123 -0
- package/dist/core/runner/tool-progress-lane.d.ts +16 -8
- package/dist/core/runner/tool-progress-lane.js +25 -34
- package/dist/core/runner/turn-attachments.d.ts +1 -1
- package/dist/core/runner/write-protection-station.d.ts +21 -9
- package/dist/core/runner/write-protection-station.js +20 -17
- package/dist/core/runner-deps.d.ts +12 -22
- package/dist/core/safety-axis-vocab.d.ts +1 -1
- package/dist/core/safety-merge-corpus.d.ts +1 -1
- package/dist/core/secret-env.d.ts +16 -5
- package/dist/core/secret-env.js +23 -63
- package/dist/core/sensitive-path-policy.d.ts +19 -18
- package/dist/core/sensitive-path-policy.js +73 -49
- package/dist/core/session-policy-store.d.ts +6 -3
- package/dist/core/session-policy-store.js +28 -10
- package/dist/core/session-reconcile.d.ts +3 -0
- package/dist/core/session-reconcile.js +5 -4
- package/dist/core/session-store.d.ts +5 -0
- package/dist/core/session-store.js +12 -0
- package/dist/core/session.d.ts +13 -0
- package/dist/core/shared-memory/normalize.d.ts +17 -4
- package/dist/core/shared-memory/normalize.js +7 -7
- package/dist/core/shell-lexer.js +5 -4
- package/dist/core/shell-wrapper-table.d.ts +2 -2
- package/dist/core/shell-wrapper-table.js +1 -1
- package/dist/core/skill-grant.js +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/synthetic-read-verdict.js +2 -2
- package/dist/core/task-event.d.ts +59 -5
- package/dist/core/task-result.d.ts +1 -1
- package/dist/core/task-spec.d.ts +42 -9
- package/dist/core/terminal-cause.d.ts +94 -11
- package/dist/core/tighten-task-spec.d.ts +5 -4
- package/dist/core/tighten-task-spec.js +20 -25
- package/dist/core/tool-catalog-entries.d.ts +5 -7
- package/dist/core/tool-catalog-entries.js +14 -15
- package/dist/core/tool-face.d.ts +47 -0
- package/dist/core/tool-face.js +5 -0
- package/dist/core/tool-model-gate.d.ts +5 -5
- package/dist/core/tool-name-aliases.d.ts +35 -10
- package/dist/core/tool-name-aliases.js +15 -0
- package/dist/core/tool-name-list.d.ts +30 -0
- package/dist/core/tool-name-list.js +55 -0
- package/dist/core/tool-name-readings.d.ts +1 -9
- package/dist/core/tool-name-readings.js +1 -3
- package/dist/core/tool-policy.d.ts +195 -85
- package/dist/core/tool-policy.js +165 -381
- package/dist/core/tool-registry.d.ts +44 -1
- package/dist/core/tool-registry.js +26 -0
- package/dist/core/tool-roster.d.ts +19 -1
- package/dist/core/tool-roster.js +21 -2
- package/dist/core/tool-spec-members.d.ts +45 -0
- package/dist/core/tool-spec-members.js +169 -0
- package/dist/core/tool-spec.d.ts +46 -8
- package/dist/core/tools.d.ts +6 -2
- package/dist/core/tools.js +8 -4
- package/dist/core/untrusted-egress.js +29 -26
- package/dist/core/untrusted-text.d.ts +13 -10
- package/dist/core/untrusted-text.js +6 -44
- package/dist/core/workflow-journal-store.d.ts +4 -1
- package/dist/core/write-protect.d.ts +65 -29
- package/dist/core/write-protect.js +235 -177
- package/dist/engine/compaction/compaction.d.ts +2 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
- package/dist/engine/execution-env/node-execution-env.js +16 -38
- package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
- package/dist/engine/execution-env/symlink-chain.js +32 -0
- package/dist/engine/harness/types.d.ts +7 -0
- package/dist/engine/llm/tool-turns.d.ts +3 -0
- package/dist/engine/llm/tool-turns.js +1 -0
- package/dist/engine/llm/types.d.ts +59 -23
- package/dist/engine/loop/agent-loop.js +16 -2
- package/dist/engine/session/memory-repo.js +11 -3
- package/dist/engine/session/repo-utils.d.ts +8 -0
- package/dist/engine/session/repo-utils.js +13 -0
- package/dist/index.d.ts +20 -23
- package/dist/index.js +17 -20
- package/dist/internal/harness.d.ts +1 -1
- package/dist/internal/harness.js +1 -1
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/governance-baseline-validity.js +1 -1
- package/dist/orchestration/run-spec.js +3 -3
- package/dist/orchestration/run-workflow-tool.d.ts +16 -35
- package/dist/orchestration/run-workflow-tool.js +38 -78
- package/dist/orchestration/workflow-governance.d.ts +21 -25
- package/dist/orchestration/workflow-governance.js +38 -78
- package/dist/orchestration/workflow-primitives.d.ts +7 -22
- package/dist/orchestration/workflow-primitives.js +5 -12
- package/dist/orchestration/workflow-types.d.ts +1 -1
- package/dist/orchestration/workflow.d.ts +61 -11
- package/dist/orchestration/workflow.js +191 -119
- package/dist/prompt-assembly/types.d.ts +1 -1
- package/dist/scenarios/full-body.d.ts +1 -1
- package/dist/shell/lex.d.ts +0 -21
- package/dist/shell/lex.js +278 -70
- package/dist/shell/shell-words.d.ts +35 -0
- package/dist/shell/shell-words.js +65 -0
- package/dist/stores/file/checkpoint-store.d.ts +5 -5
- package/dist/stores/file/checkpoint-store.js +5 -2
- package/dist/stores/file/index.d.ts +0 -8
- package/dist/stores/file/index.js +0 -12
- package/dist/stores/file/session-store.d.ts +3 -0
- package/dist/stores/file/session-store.js +44 -19
- package/dist/tools/artifact/artifact-tool.js +2 -0
- package/dist/tools/fs/bash-program-position.d.ts +17 -3
- package/dist/tools/fs/bash-program-position.js +25 -10
- package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
- package/dist/tools/fs/bash-readonly-classifier.js +8 -7
- package/dist/tools/fs/containment-face.d.ts +4 -0
- package/dist/tools/fs/containment-face.js +3 -0
- package/dist/tools/fs/fs-shared.d.ts +10 -0
- package/dist/tools/fs/fs-shared.js +18 -0
- package/dist/tools/fs/fs-write.js +4 -2
- package/dist/tools/fs/index.d.ts +3 -2
- package/dist/tools/fs/index.js +2 -2
- package/dist/tools/fs/program-read-model.d.ts +99 -23
- package/dist/tools/fs/program-read-model.js +129 -55
- package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
- package/dist/tools/fs/program-read-model.rows.js +18 -10
- package/dist/tools/fs/read-deny-home.d.ts +35 -30
- package/dist/tools/fs/read-deny-home.js +45 -38
- package/dist/tools/fs/read-deny.d.ts +35 -27
- package/dist/tools/fs/read-deny.js +126 -92
- package/dist/tools/fs/removal-targets.d.ts +56 -23
- package/dist/tools/fs/removal-targets.js +74 -87
- package/dist/tools/fs/safety.d.ts +29 -22
- package/dist/tools/fs/safety.js +17 -11
- package/dist/tools/fs/search.js +10 -8
- package/dist/tools/fs/shell-read-argv.d.ts +4 -7
- package/dist/tools/fs/shell-read-argv.js +6 -8
- package/dist/tools/fs/shell-read-bindings.d.ts +203 -46
- package/dist/tools/fs/shell-read-bindings.js +488 -144
- package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
- package/dist/tools/fs/shell-read-builtins.js +43 -0
- package/dist/tools/fs/shell-read-check.d.ts +15 -1
- package/dist/tools/fs/shell-read-check.js +51 -42
- package/dist/tools/fs/shell-read-establish.js +9 -10
- package/dist/tools/fs/shell-read-functions.d.ts +22 -0
- package/dist/tools/fs/shell-read-functions.js +29 -0
- package/dist/tools/fs/shell-read-judge.d.ts +48 -18
- package/dist/tools/fs/shell-read-judge.js +33 -4
- package/dist/tools/fs/shell-read-plan.d.ts +13 -20
- package/dist/tools/fs/shell-read-plan.js +200 -194
- package/dist/tools/fs/shell-read-start.d.ts +80 -0
- package/dist/tools/fs/shell-read-start.js +99 -0
- package/dist/tools/fs/shell-read-word.d.ts +35 -6
- package/dist/tools/fs/shell-read-word.js +89 -9
- package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
- package/dist/tools/fs/shell-read-workdir.js +281 -0
- package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
- package/dist/tools/fs/shell-read-write-targets.js +14 -5
- package/dist/tools/fs/shell-reentry-text.d.ts +26 -26
- package/dist/tools/fs/shell-reentry-text.js +31 -34
- package/dist/tools/task-list.d.ts +1 -2
- package/dist/tools/web.js +1 -1
- package/package.json +4 -1
- package/test/export-surface.snapshot.json +107 -143
- package/wire-changes/core@7.48.0.json +252 -0
- package/wire-changes/core@7.49.0.json +4765 -0
- package/dist/agents/teacher.d.ts +0 -159
- package/dist/agents/teacher.js +0 -577
- package/dist/agents/team.d.ts +0 -226
- package/dist/agents/team.js +0 -257
- package/dist/core/strategy-store.d.ts +0 -238
- package/dist/core/strategy-store.js +0 -253
- package/dist/orchestration/builtin-workflows.d.ts +0 -133
- package/dist/orchestration/builtin-workflows.js +0 -159
- package/dist/scenarios/env.d.ts +0 -40
- package/dist/scenarios/env.js +0 -39
- package/dist/scenarios/scenario-registry.d.ts +0 -110
- package/dist/scenarios/scenario-registry.js +0 -140
- package/dist/scenarios/teacher-quickstart.d.ts +0 -40
- package/dist/scenarios/teacher-quickstart.js +0 -12
- package/dist/stores/cc/lockfile.d.ts +0 -10
- package/dist/stores/cc/lockfile.js +0 -98
- package/dist/stores/cc/mailbox-store.d.ts +0 -20
- package/dist/stores/cc/mailbox-store.js +0 -255
- package/dist/stores/cc/roster-adapter.d.ts +0 -12
- package/dist/stores/cc/roster-adapter.js +0 -117
- package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
- package/dist/stores/cc/sidecar-transcript.js +0 -264
- package/dist/stores/cc/task-list-store.d.ts +0 -2
- package/dist/stores/cc/task-list-store.js +0 -125
- package/dist/stores/file/strategy-store.d.ts +0 -97
- package/dist/stores/file/strategy-store.js +0 -341
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import { argvOf, lexShell, literalTildeSpelling, substitutionsInHeredocBody } from "../../shell/lex.js";
|
|
2
|
-
import {
|
|
2
|
+
import { shellWordsOf } from "../../shell/shell-words.js";
|
|
3
|
+
import { isShellSyntaxWord, LOOP_LIST_HEADS, readProgramPosition } from "./bash-program-position.js";
|
|
3
4
|
import { declaredAttributes, programRow, readArgRoles } from "./program-read-model.js";
|
|
4
5
|
import { codeBodies } from "./shell-reentry-text.js";
|
|
6
|
+
import { BUILTIN_ENABLED, BUILTINS_ALL, ENABLE_BUILTIN, builtinKey, chainAvailability, enableBindings, isBuiltinKey, isDisabledValue, speaksFor } from "./shell-read-builtins.js";
|
|
7
|
+
export function judgedSpellingOf(v) {
|
|
8
|
+
if (v.glob !== true)
|
|
9
|
+
return undefined;
|
|
10
|
+
const judged = literalTildeSpelling(v.parts.map((p) => (p.pattern ? p.judged : p.text)).join(""));
|
|
11
|
+
return judged === literalTildeSpelling(v.spelled) ? undefined : judged;
|
|
12
|
+
}
|
|
13
|
+
export function floorOf(v) {
|
|
14
|
+
const pattern = judgedSpellingOf(v);
|
|
15
|
+
return v.glob === true ? { spelled: v.spelled, glob: true, ...(pattern !== undefined ? { pattern } : {}) } : { spelled: v.spelled };
|
|
16
|
+
}
|
|
5
17
|
function sameValue(a, b) {
|
|
6
|
-
if (a.spelled !== b.spelled)
|
|
18
|
+
if (a.spelled !== b.spelled || a.fields?.length !== b.fields?.length)
|
|
7
19
|
return false;
|
|
8
20
|
if (a.glob !== true || b.glob !== true)
|
|
9
21
|
return a.glob === b.glob;
|
|
@@ -15,53 +27,62 @@ export const SHELL_INTEGER_VARIABLES = new Set([
|
|
|
15
27
|
"LISTMAX", "LOGCHECK", "PERIOD", "FUNCNEST", "UID", "EUID", "GID", "EGID", "REPORTTIME", "REPORTMEMORY", "DIRSTACKSIZE", "BAUD",
|
|
16
28
|
"ZLE_RPROMPT_INDENT", "MBEGIN", "MEND", "PPID", "ARGC", "ZSH_SUBSHELL", "TTYIDLE", "status",
|
|
17
29
|
]);
|
|
18
|
-
const SHELL_SET_VARIABLES = new Set(["
|
|
30
|
+
const SHELL_SET_VARIABLES = new Set(["REPLY", "OPTARG", "MAPFILE", "BASH_REMATCH", "PIPESTATUS", "FUNCNAME", "BASH_COMMAND", "BASH_SUBSHELL", "COPROC", "GROUPS", "SHELLOPTS", "BASHOPTS", "BASH_VERSINFO"]);
|
|
19
31
|
export function shellKeepsName(name) {
|
|
20
32
|
return SHELL_INTEGER_VARIABLES.has(name) || SHELL_SET_VARIABLES.has(name);
|
|
21
33
|
}
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
34
|
+
export const WORKING_DIRECTORY_NAMES = Object.freeze(["PWD", "OLDPWD"]);
|
|
35
|
+
const isWorkingDirectoryName = (name) => name === "PWD" || name === "OLDPWD";
|
|
36
|
+
const OPENING_WORDS = shellWordsOf("scope_open");
|
|
37
|
+
const CLOSING_WORDS = shellWordsOf("scope_close");
|
|
38
|
+
const SWITCHING_WORDS = shellWordsOf("scope_switch");
|
|
39
|
+
const GROUP_WORDS = shellWordsOf("group"), DEFINITION_WORDS = shellWordsOf("definition"), ITERATING_HEADS = shellWordsOf("loop_iterates"), BACKGROUND_WORDS = shellWordsOf("background");
|
|
40
|
+
export const SPECIAL_BUILTINS = new Set([":", ".", "break", "continue", "eval", "exec", "exit", "export", "readonly", "return", "set", "shift", "source", "times", "trap", "unset"]);
|
|
26
41
|
const IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
42
|
+
const LOCAL_DECLARATION = "local";
|
|
43
|
+
const FUNCTION_KEY_PREFIX = "()";
|
|
44
|
+
export const functionKey = (name) => FUNCTION_KEY_PREFIX + name;
|
|
45
|
+
const isFunctionKey = (name) => name.startsWith(FUNCTION_KEY_PREFIX);
|
|
46
|
+
const FUNCTION_DEFINED = [{ spelled: "defined" }];
|
|
47
|
+
const FUNCTION_ABSENT = [{ spelled: "absent" }];
|
|
48
|
+
const isDefinedValue = (v) => v.spelled === "defined";
|
|
27
49
|
const ATTRIBUTE_KINDS = { integer: "integer", transformed: "transformed", frozen: "frozen" };
|
|
28
50
|
const EVERY_ATTRIBUTE = Object.values(ATTRIBUTE_KINDS).map((kind) => ({ kind }));
|
|
29
51
|
export function projectSegment(segment) {
|
|
30
52
|
const tokens = [...segment.tokens];
|
|
31
53
|
let grouped = tokens.some((t) => t.kind === "group");
|
|
32
|
-
const
|
|
54
|
+
const defines = dropDefinitionHeads(tokens).flat();
|
|
33
55
|
dropCasePattern(tokens);
|
|
34
56
|
const words = tokens.filter((t) => {
|
|
35
57
|
if (t.kind !== "word")
|
|
36
58
|
return false;
|
|
37
|
-
if (t.raw === t.folded && (t.folded
|
|
59
|
+
if (t.raw === t.folded && GROUP_WORDS.has(t.folded)) {
|
|
38
60
|
grouped = true;
|
|
39
61
|
return false;
|
|
40
62
|
}
|
|
41
63
|
return true;
|
|
42
64
|
});
|
|
43
|
-
return { argv: words, redirects: tokens.filter((t) => t.kind === "redirect"), grouped,
|
|
65
|
+
return { argv: words, redirects: tokens.filter((t) => t.kind === "redirect"), grouped, defines };
|
|
44
66
|
}
|
|
45
67
|
function isDefinitionName(word) {
|
|
46
68
|
return IDENTIFIER.test(word.folded) || (word.atCommandPosition && word.expansions.length === 0 && !/[?*+@!]$/.test(word.raw));
|
|
47
69
|
}
|
|
48
70
|
export function dropDefinitionHeads(tokens) {
|
|
49
|
-
const heads =
|
|
50
|
-
const drop = (k, count) => {
|
|
71
|
+
const heads = Array.from({ length: tokens.length + 1 }, () => []);
|
|
72
|
+
const drop = (k, count, name) => {
|
|
51
73
|
tokens.splice(k, count);
|
|
52
74
|
heads.splice(k, count);
|
|
53
|
-
heads[k]
|
|
75
|
+
heads[k].push(name);
|
|
54
76
|
};
|
|
55
77
|
for (let k = 0; k + 1 < tokens.length; k++) {
|
|
56
78
|
const [a, b, c, d] = [tokens[k], tokens[k + 1], tokens[k + 2], tokens[k + 3]];
|
|
57
|
-
if (a.kind === "word" && a.raw
|
|
58
|
-
drop(k--, c?.kind === "group" && c.op === "(" && d?.kind === "group" && d.op === ")" ? 4 : 2);
|
|
59
|
-
}
|
|
79
|
+
if (a.kind === "word" && DEFINITION_WORDS.has(a.raw) && a.atCommandPosition && b.kind === "word")
|
|
80
|
+
drop(k--, c?.kind === "group" && c.op === "(" && d?.kind === "group" && d.op === ")" ? 4 : 2, b.folded);
|
|
60
81
|
}
|
|
61
82
|
for (let k = 0; k + 2 < tokens.length; k++) {
|
|
62
83
|
const [a, b, c] = [tokens[k], tokens[k + 1], tokens[k + 2]];
|
|
63
84
|
if (a.kind === "word" && b.kind === "group" && b.op === "(" && c.kind === "group" && c.op === ")" && isDefinitionName(a))
|
|
64
|
-
drop(k, 3);
|
|
85
|
+
drop(k, 3, a.folded);
|
|
65
86
|
}
|
|
66
87
|
return heads;
|
|
67
88
|
}
|
|
@@ -98,6 +119,8 @@ function extglobParen(tokens, at) {
|
|
|
98
119
|
function blockStructure(segments) {
|
|
99
120
|
let depth = 0;
|
|
100
121
|
let bodies = 0;
|
|
122
|
+
let subshellIds = 0;
|
|
123
|
+
const subshellStack = [];
|
|
101
124
|
const frames = [];
|
|
102
125
|
const deeper = () => {
|
|
103
126
|
depth++;
|
|
@@ -113,9 +136,13 @@ function blockStructure(segments) {
|
|
|
113
136
|
return segments.map((segment) => {
|
|
114
137
|
const tokens = [...segment.tokens];
|
|
115
138
|
const heads = dropDefinitionHeads(tokens);
|
|
139
|
+
const defs = [];
|
|
116
140
|
const startBodies = (k) => {
|
|
117
|
-
for (
|
|
141
|
+
for (const name of heads[k]) {
|
|
142
|
+
const enclosing = innermost();
|
|
143
|
+
defs.push({ name, standing: { ...(enclosing !== undefined ? { body: enclosing } : {}), subshells: [...subshellStack], depth } });
|
|
118
144
|
frames.push({ body: { id: bodies++, base: depth }, opened: false });
|
|
145
|
+
}
|
|
119
146
|
};
|
|
120
147
|
const arithmetic = isArithmeticCommand(segment);
|
|
121
148
|
const patternEnd = casePatternEnd(tokens);
|
|
@@ -123,6 +150,7 @@ function blockStructure(segments) {
|
|
|
123
150
|
const open = [];
|
|
124
151
|
let lowest = depth;
|
|
125
152
|
let words;
|
|
153
|
+
let subshells;
|
|
126
154
|
let body;
|
|
127
155
|
const switches = [];
|
|
128
156
|
const innermost = () => [...frames].reverse().find((f) => f.opened)?.body;
|
|
@@ -140,6 +168,7 @@ function blockStructure(segments) {
|
|
|
140
168
|
if (k <= patternEnd)
|
|
141
169
|
return;
|
|
142
170
|
deeper();
|
|
171
|
+
subshellStack.push(subshellIds++);
|
|
143
172
|
return;
|
|
144
173
|
}
|
|
145
174
|
const from = open.pop();
|
|
@@ -151,6 +180,7 @@ function blockStructure(segments) {
|
|
|
151
180
|
return;
|
|
152
181
|
}
|
|
153
182
|
shallower();
|
|
183
|
+
subshellStack.pop();
|
|
154
184
|
lowest = Math.min(lowest, depth);
|
|
155
185
|
return;
|
|
156
186
|
}
|
|
@@ -167,6 +197,7 @@ function blockStructure(segments) {
|
|
|
167
197
|
switches.push(depth);
|
|
168
198
|
else if (k > patternEnd) {
|
|
169
199
|
words ??= depth;
|
|
200
|
+
subshells ??= [...subshellStack];
|
|
170
201
|
body = innermost();
|
|
171
202
|
}
|
|
172
203
|
};
|
|
@@ -200,17 +231,54 @@ function blockStructure(segments) {
|
|
|
200
231
|
while (frames.length > 0 && frames[frames.length - 1].flat === true)
|
|
201
232
|
frames.pop();
|
|
202
233
|
startBodies(tokens.length);
|
|
203
|
-
return { words: words ?? depth, after: depth, lowest, switches, ...(body !== undefined ? { body } : {}) };
|
|
234
|
+
return { words: words ?? depth, after: depth, lowest, switches, subshells: subshells ?? [...subshellStack], defs, ...(body !== undefined ? { body } : {}) };
|
|
204
235
|
});
|
|
205
236
|
}
|
|
206
|
-
const
|
|
237
|
+
const READABLE_VALUE = /^[^\\~()]*$/;
|
|
207
238
|
const WORD_VALUES_MAX = 64;
|
|
208
|
-
|
|
209
|
-
|
|
239
|
+
const quotedRunsOf = (v) => v.glob === true ? v.parts.map((r) => (r.pattern ? { text: r.text, mode: "set", judged: r.judged } : { text: r.text, mode: "inactive" })) : [{ text: v.spelled, mode: "inactive" }];
|
|
240
|
+
function formedField(f) {
|
|
241
|
+
const runs = f.runs;
|
|
242
|
+
if (!runs.some((r) => r.mode === "active" && /[[\]*?]/.test(r.text))) {
|
|
243
|
+
if (!runs.some((r) => r.mode === "raw" || r.mode === "set"))
|
|
244
|
+
return { spelled: f.text };
|
|
245
|
+
return { spelled: f.text, glob: true, parts: joinRuns([], runs.map((r) => (r.mode === "raw" || r.mode === "set" ? { text: r.text, pattern: true, judged: r.judged } : { text: r.text, pattern: false }))) };
|
|
246
|
+
}
|
|
247
|
+
if (runs.some((r) => r.mode === "active" && /[ \t\n\\]/.test(r.text)) || (runs.some((r) => r.mode === "set") && runs.some((r) => r.mode === "active" && /[[\]]/.test(r.text))))
|
|
248
|
+
return undefined;
|
|
249
|
+
const escaped = runs.map((r) => (r.mode === "raw" || r.mode === "set" ? r.text : r.text.replace(r.mode === "active" ? /[^A-Za-z0-9_./*?[\]!^:=,+@%-]/g : /[^A-Za-z0-9_./]/g, (c) => `\\${c}`))).join("");
|
|
250
|
+
const lexed = lexShell(`: ${escaped}`);
|
|
251
|
+
const words = "parseFailure" in lexed || lexed.segments.length !== 1 ? undefined : argvOf(lexed.segments[0]);
|
|
252
|
+
if (words?.length !== 2)
|
|
210
253
|
return undefined;
|
|
211
|
-
|
|
254
|
+
let parts = [];
|
|
255
|
+
for (const p of words[1].pieces) {
|
|
256
|
+
if (p.expansion?.pattern !== undefined)
|
|
257
|
+
parts = joinRuns(parts, [{ text: p.expansion.pattern.written, pattern: true, judged: p.expansion.pattern.judged }]);
|
|
258
|
+
else if (p.expansion === undefined && p.literal !== undefined)
|
|
259
|
+
parts = joinRuns(parts, [{ text: p.literal, pattern: false }]);
|
|
260
|
+
else
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
return parts.some((r) => r.pattern) ? { spelled: f.text, glob: true, parts } : { spelled: f.text };
|
|
264
|
+
}
|
|
265
|
+
export function wordValues(word, table, quoted, overlay = new Map(), split = false) {
|
|
266
|
+
if (!word.pieces.some((p) => p.expansion?.kind === "parameter" || p.expansion?.kind === "tilde") && namesIn(word).length === 0)
|
|
267
|
+
return undefined;
|
|
268
|
+
return valueOf(word, table, quoted, overlay, split);
|
|
269
|
+
}
|
|
270
|
+
export function namesIn(word) {
|
|
271
|
+
return word.pieces.flatMap((p) => {
|
|
272
|
+
const e = p.expansion;
|
|
273
|
+
if (e?.kind === "parameter" && e.name !== undefined)
|
|
274
|
+
return e.body === undefined || e.body === e.name ? [e.name] : [];
|
|
275
|
+
return e?.kind === "glob" && e.pattern === undefined ? (bracketBodyOf(e.body) ?? []).flatMap((w) => namesIn(w)) : [];
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
function bracketBodyOf(body) {
|
|
279
|
+
const lexed = body === undefined ? undefined : lexShell(`""${body}`);
|
|
280
|
+
return lexed === undefined || "parseFailure" in lexed ? undefined : lexed.segments.flatMap((s) => argvOf(s));
|
|
212
281
|
}
|
|
213
|
-
const runsOf = (v) => (v.glob === true ? v.parts : [{ text: v.spelled, pattern: false }]);
|
|
214
282
|
function joinRuns(runs, more) {
|
|
215
283
|
const out = [...runs];
|
|
216
284
|
for (const r of more) {
|
|
@@ -224,51 +292,96 @@ function joinRuns(runs, more) {
|
|
|
224
292
|
}
|
|
225
293
|
return out;
|
|
226
294
|
}
|
|
227
|
-
export function valueOf(word, table, quoted, overlay = new Map()) {
|
|
295
|
+
export function valueOf(word, table, quoted, overlay = new Map(), split = false) {
|
|
228
296
|
const stateOf = (name) => (table === undefined ? "unknown" : overlay.get(name) ?? table.stateOf(name));
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
297
|
+
const EMPTY = { text: "", runs: [] };
|
|
298
|
+
let combos = [{ field: EMPTY, closed: [], started: false, split: false }];
|
|
299
|
+
const activeRun = (text) => ({ text, mode: "active" });
|
|
300
|
+
const splitInto = (c, value) => {
|
|
301
|
+
const words = value.split(/[ \t\n]+/).filter((w) => w !== "");
|
|
302
|
+
if (words.length === 0)
|
|
303
|
+
return value === "" ? { ...c, split: true } : { ...c, field: EMPTY, started: false, closed: c.started ? [...c.closed, c.field] : c.closed, split: true };
|
|
304
|
+
const closed = [...c.closed];
|
|
305
|
+
if (/^[ \t\n]/.test(value) && c.started)
|
|
306
|
+
closed.push(c.field);
|
|
307
|
+
let field = closed.length > c.closed.length ? { text: words[0], runs: [activeRun(words[0])] } : { text: c.field.text + words[0], runs: [...c.field.runs, activeRun(words[0])] };
|
|
308
|
+
for (let i = 1; i < words.length; i++) {
|
|
309
|
+
closed.push(field);
|
|
310
|
+
field = { text: words[i], runs: [activeRun(words[i])] };
|
|
237
311
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return "unknown";
|
|
246
|
-
const home = stateOf("HOME");
|
|
247
|
-
if (home === "unknown")
|
|
248
|
-
return "unknown";
|
|
249
|
-
options = home;
|
|
250
|
-
}
|
|
251
|
-
else if (e.kind === "parameter" && e.name !== undefined && (e.body === undefined || e.body === e.name)) {
|
|
252
|
-
const state = stateOf(e.name);
|
|
253
|
-
if (state === "unknown")
|
|
254
|
-
return "unknown";
|
|
255
|
-
if (p.quotedBy === undefined && !quoted && (table?.ifsTouched === true || state.some((v) => v.glob === true || !ONE_WORD.test(v.spelled))))
|
|
256
|
-
return "unknown";
|
|
257
|
-
options = state;
|
|
258
|
-
}
|
|
259
|
-
else
|
|
260
|
-
return "unknown";
|
|
261
|
-
const next = [];
|
|
262
|
-
for (const c of combos)
|
|
263
|
-
for (const o of options)
|
|
264
|
-
next.push({ text: c.text + o.spelled, glob: c.glob || o.glob === true, parts: joinRuns(c.parts, runsOf(o)) });
|
|
312
|
+
if (!/[ \t\n]$/.test(value))
|
|
313
|
+
return { ...c, field, started: true, closed, split: true };
|
|
314
|
+
closed.push(field);
|
|
315
|
+
return { ...c, field: EMPTY, started: false, closed, split: true };
|
|
316
|
+
};
|
|
317
|
+
const extend = (options) => {
|
|
318
|
+
const next = combos.flatMap((c) => options.map((o) => ({ ...c, field: { text: c.field.text + o.text, runs: [...c.field.runs, ...o.runs] }, started: true })));
|
|
265
319
|
if (next.length > WORD_VALUES_MAX)
|
|
266
|
-
return
|
|
320
|
+
return false;
|
|
267
321
|
combos = next;
|
|
268
|
-
|
|
322
|
+
return true;
|
|
323
|
+
};
|
|
324
|
+
const unquotedKind = (v) => v.glob === true || !READABLE_VALUE.test(v.spelled) ? undefined : !/[ \t\n]/.test(v.spelled) && v.spelled !== "" ? "run" : split ? "split" : undefined;
|
|
325
|
+
const walk = (pieces, unquoted) => {
|
|
326
|
+
for (const p of pieces) {
|
|
327
|
+
const e = p.expansion;
|
|
328
|
+
const bare = unquoted && p.quotedBy === undefined;
|
|
329
|
+
if (e === undefined) {
|
|
330
|
+
if (p.literal === undefined || !extend([{ text: p.literal, runs: [{ text: p.literal, mode: bare ? "active" : "inactive" }] }]))
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
else if (e.kind === "glob") {
|
|
334
|
+
const formed = e.pattern;
|
|
335
|
+
if (formed !== undefined) {
|
|
336
|
+
if (!extend([{ text: formed.folded, runs: [{ text: formed.written, mode: "raw", judged: formed.judged }] }]))
|
|
337
|
+
return false;
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
const words = bracketBodyOf(e.body);
|
|
341
|
+
if (words?.length !== 1 || !extend([{ text: "[", runs: [activeRun("[")] }]) || !walk(words[0].pieces, true) || !extend([{ text: "]", runs: [activeRun("]")] }]))
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
else if (e.kind === "tilde") {
|
|
345
|
+
const home = e.body === "~" ? stateOf("HOME") : "unknown";
|
|
346
|
+
if (home === "unknown" || !extend(home.map((v) => ({ text: v.spelled, runs: quotedRunsOf(v) }))))
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
else if (e.kind === "parameter" && e.name !== undefined && (e.body === undefined || e.body === e.name)) {
|
|
350
|
+
const state = stateOf(e.name);
|
|
351
|
+
if (state === "unknown")
|
|
352
|
+
return false;
|
|
353
|
+
if (!bare) {
|
|
354
|
+
if (!extend(state.map((v) => ({ text: v.spelled, runs: quotedRunsOf(v) }))))
|
|
355
|
+
return false;
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
const kinds = state.map(unquotedKind);
|
|
359
|
+
if (table?.ifsTouched === true || kinds.includes(undefined))
|
|
360
|
+
return false;
|
|
361
|
+
if (!kinds.includes("split")) {
|
|
362
|
+
if (!extend(state.map((v) => ({ text: v.spelled, runs: [activeRun(v.spelled)] }))))
|
|
363
|
+
return false;
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
const next = combos.flatMap((c) => state.map((v) => splitInto(c, v.spelled)));
|
|
367
|
+
if (next.length > WORD_VALUES_MAX)
|
|
368
|
+
return false;
|
|
369
|
+
combos = next;
|
|
370
|
+
}
|
|
371
|
+
else
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
return true;
|
|
375
|
+
};
|
|
376
|
+
if (!walk(word.pieces, !quoted))
|
|
377
|
+
return "unknown";
|
|
269
378
|
const out = [];
|
|
270
379
|
for (const c of combos) {
|
|
271
|
-
const
|
|
380
|
+
const fields = (c.split ? (c.started ? [...c.closed, c.field] : c.closed) : [c.field]).map(formedField);
|
|
381
|
+
const formed = fields.filter((f) => f !== undefined && !(c.split && f.glob === true));
|
|
382
|
+
if (formed.length !== fields.length)
|
|
383
|
+
return "unknown";
|
|
384
|
+
const v = !c.split ? formed[0] : formed.length !== 1 ? { spelled: formed.map((f) => f.spelled).join(" "), fields: formed.map((f) => f.spelled) } : { spelled: formed[0].spelled };
|
|
272
385
|
if (!out.some((x) => sameValue(x, v)))
|
|
273
386
|
out.push(v);
|
|
274
387
|
}
|
|
@@ -288,25 +401,32 @@ export function wordFloorValues(word, table) {
|
|
|
288
401
|
}
|
|
289
402
|
else if (e.kind === "parameter" && e.name !== undefined) {
|
|
290
403
|
const state = table.stateOf(e.name);
|
|
291
|
-
options = state !== "unknown" && (e.body === undefined || e.body === e.name) ? state : table.floorOf(e.name);
|
|
404
|
+
options = state !== "unknown" && (e.body === undefined || e.body === e.name) ? state.map(floorOf) : table.floorOf(e.name);
|
|
292
405
|
}
|
|
293
406
|
else
|
|
294
407
|
return [];
|
|
295
408
|
if (options.length === 0)
|
|
296
409
|
return [];
|
|
297
410
|
const next = [];
|
|
298
|
-
for (const c of combos)
|
|
299
|
-
for (const o of options)
|
|
300
|
-
|
|
411
|
+
for (const c of combos) {
|
|
412
|
+
for (const o of options) {
|
|
413
|
+
const pattern = c.pattern !== undefined || o.pattern !== undefined ? (c.pattern ?? c.spelled) + (o.pattern ?? o.spelled) : undefined;
|
|
414
|
+
next.push(c.glob === true || o.glob === true ? { spelled: c.spelled + o.spelled, glob: true, ...(pattern !== undefined ? { pattern } : {}) } : { spelled: c.spelled + o.spelled });
|
|
415
|
+
}
|
|
416
|
+
}
|
|
301
417
|
if (next.length > WORD_VALUES_MAX)
|
|
302
418
|
return [];
|
|
303
419
|
combos = next;
|
|
304
420
|
}
|
|
305
421
|
return combos;
|
|
306
422
|
}
|
|
307
|
-
export function
|
|
423
|
+
export function loopListHeadAt(argv) {
|
|
424
|
+
const at = isShellSyntaxWord(argv[0], LOOP_LIST_HEADS) ? 0 : readProgramPosition(argv).written;
|
|
425
|
+
return at !== undefined && isShellSyntaxWord(argv[at], LOOP_LIST_HEADS) ? at : undefined;
|
|
426
|
+
}
|
|
427
|
+
export function bindingEffectOf(segment, argv, shape, readValue, shadow, availability) {
|
|
308
428
|
const bindings = [];
|
|
309
|
-
let all = shape.
|
|
429
|
+
let all = shape.defines.length > 0 ? "reset" : undefined;
|
|
310
430
|
const unknownAll = () => void (all = "unknown");
|
|
311
431
|
const overlay = new Map();
|
|
312
432
|
let scope;
|
|
@@ -316,6 +436,8 @@ export function bindingEffectOf(segment, argv, shape, readValue) {
|
|
|
316
436
|
overlay.set(b.name, b.state);
|
|
317
437
|
};
|
|
318
438
|
const kill = (name) => bind({ name, state: "unknown" });
|
|
439
|
+
for (const name of shape.defines)
|
|
440
|
+
bind({ name: functionKey(name), state: FUNCTION_DEFINED });
|
|
319
441
|
const nameOf = (w) => {
|
|
320
442
|
if (w.pieces.some((p) => p.expansion !== undefined || p.literal === undefined))
|
|
321
443
|
return "computed";
|
|
@@ -353,21 +475,21 @@ export function bindingEffectOf(segment, argv, shape, readValue) {
|
|
|
353
475
|
kill(name);
|
|
354
476
|
return { bindings, all };
|
|
355
477
|
}
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
478
|
+
const loopAt = loopListHeadAt(argv);
|
|
479
|
+
if (loopAt !== undefined) {
|
|
480
|
+
const headWord = argv[loopAt].folded;
|
|
359
481
|
if (tokens.some((t) => t.kind === "group"))
|
|
360
482
|
unknownAll();
|
|
361
|
-
const name = argv[1] !== undefined ? nameOf(argv[1]) : undefined;
|
|
483
|
+
const name = argv[loopAt + 1] !== undefined ? nameOf(argv[loopAt + 1]) : undefined;
|
|
362
484
|
if (name === undefined || name === "computed") {
|
|
363
485
|
unknownAll();
|
|
364
486
|
return { bindings, all };
|
|
365
487
|
}
|
|
366
|
-
const inAt = argv.findIndex((w, i) => i >= 2 && w.raw === "in");
|
|
488
|
+
const inAt = argv.findIndex((w, i) => i >= loopAt + 2 && w.raw === "in");
|
|
367
489
|
let state = "unknown";
|
|
368
|
-
if (headWord
|
|
490
|
+
if (ITERATING_HEADS.has(headWord) && inAt === loopAt + 2 && argv.length > loopAt + 3) {
|
|
369
491
|
const values = [];
|
|
370
|
-
for (const w of argv.slice(3)) {
|
|
492
|
+
for (const w of argv.slice(loopAt + 3)) {
|
|
371
493
|
const v = readValue(w, false, overlay);
|
|
372
494
|
if (v === "unknown") {
|
|
373
495
|
values.length = 0;
|
|
@@ -381,7 +503,7 @@ export function bindingEffectOf(segment, argv, shape, readValue) {
|
|
|
381
503
|
bind({ name, state, loopVar: true });
|
|
382
504
|
return { bindings, all };
|
|
383
505
|
}
|
|
384
|
-
if (
|
|
506
|
+
if (argv[0] !== undefined && BACKGROUND_WORDS.has(argv[0].raw) && argv[1] !== undefined)
|
|
385
507
|
killNamed(nameOf(argv[1]));
|
|
386
508
|
const pos = readProgramPosition(argv);
|
|
387
509
|
const program = pos.program;
|
|
@@ -401,9 +523,20 @@ export function bindingEffectOf(segment, argv, shape, readValue) {
|
|
|
401
523
|
unknownAll();
|
|
402
524
|
return { bindings, all, attributes: EVERY_ATTRIBUTE, references: true };
|
|
403
525
|
}
|
|
404
|
-
if (program === undefined ||
|
|
526
|
+
if (program === undefined || shadow === "named")
|
|
527
|
+
return { bindings, all };
|
|
528
|
+
const settled = bindings.length;
|
|
529
|
+
const runsAsBuiltin = program.name === program.basename && pos.launchers.every((l, i) => (l.name === "builtin" || l.name === "command") && argv[l.index].folded === l.name && l.index + 1 === (pos.launchers[i + 1]?.index ?? program.index)) && !segment.tokens.some((t) => t.kind === "redirect" || t.kind === "heredoc");
|
|
530
|
+
const available = runsAsBuiltin ? chainAvailability([...pos.launchers.map((l) => l.name), program.basename], availability) : "enabled";
|
|
531
|
+
if (available === "disabled")
|
|
405
532
|
return { bindings, all };
|
|
533
|
+
const mayNotRun = shadow === "maybe" || available === "maybe" || (!runsAsBuiltin && (row?.builtin === "declaration" || program.basename === ENABLE_BUILTIN));
|
|
534
|
+
const finish = (e) => (mayNotRun ? { ...e, bindings: e.bindings.map((b, i) => (i < settled ? b : { ...b, prefix: true })) } : e);
|
|
406
535
|
const args = argv.slice(program.index + 1);
|
|
536
|
+
if (program.basename === ENABLE_BUILTIN)
|
|
537
|
+
return finish({ bindings: [...bindings, ...enableBindings(args)], all });
|
|
538
|
+
if (row === undefined)
|
|
539
|
+
return { bindings, all };
|
|
407
540
|
const folded = args.map((w) => w.folded);
|
|
408
541
|
if (row.reentry?.kind === "shell" && (row.reentry.text === "words" || row.reentry.text === "file-operand"))
|
|
409
542
|
unknownAll();
|
|
@@ -416,7 +549,7 @@ export function bindingEffectOf(segment, argv, shape, readValue) {
|
|
|
416
549
|
kill(name);
|
|
417
550
|
}
|
|
418
551
|
if (row.builtin === "declaration") {
|
|
419
|
-
scope = args.some((w) => w.folded.startsWith("-") || w.folded.startsWith("+")) ? "unread" : program.basename ===
|
|
552
|
+
scope = args.some((w) => w.folded.startsWith("-") || w.folded.startsWith("+")) ? "unread" : program.basename === LOCAL_DECLARATION ? "local" : undefined;
|
|
420
553
|
const assigns = declaredAttributes(row, folded);
|
|
421
554
|
const kinds = [...assigns].filter((k) => k !== "reference" && k !== "unsettled");
|
|
422
555
|
const storesText = [...assigns].every((k) => k === "frozen");
|
|
@@ -443,12 +576,19 @@ export function bindingEffectOf(segment, argv, shape, readValue) {
|
|
|
443
576
|
bind({ name, state: assignedState(a, readValue, expanded) });
|
|
444
577
|
attributes.push(...kinds.map((kind) => ({ name, kind })));
|
|
445
578
|
}
|
|
446
|
-
const inFunction = program.basename ===
|
|
579
|
+
const inFunction = program.basename === LOCAL_DECLARATION ? { inFunction: true } : {};
|
|
447
580
|
if (references) {
|
|
448
581
|
unknownAll();
|
|
449
|
-
return { bindings, all, attributes, references: true, ...inFunction };
|
|
582
|
+
return finish({ bindings, all, attributes, references: true, ...inFunction });
|
|
450
583
|
}
|
|
451
|
-
return { bindings, all, attributes, ...inFunction };
|
|
584
|
+
return finish({ bindings, all, attributes, ...inFunction });
|
|
585
|
+
}
|
|
586
|
+
if (program.basename === "unset") {
|
|
587
|
+
const { operands, variablesOnly } = unsetOperands(args);
|
|
588
|
+
if (!variablesOnly)
|
|
589
|
+
for (const w of operands)
|
|
590
|
+
if (w.pieces.every((p) => p.literal !== undefined && p.expansion === undefined))
|
|
591
|
+
bind({ name: functionKey(w.folded), state: FUNCTION_ABSENT, prefix: true });
|
|
452
592
|
}
|
|
453
593
|
for (const e of readArgRoles(row, folded)) {
|
|
454
594
|
const role = e.kind === "value" || e.kind === "operand" ? e.role : e.kind === "option" && typeof e.reading === "object" ? e.reading.role : undefined;
|
|
@@ -468,11 +608,32 @@ export function bindingEffectOf(segment, argv, shape, readValue) {
|
|
|
468
608
|
const nameLetters = new Set(row.grammars.flatMap((g) => Object.entries(g.short).flatMap(([letter, s]) => (s.value?.kind === "binds-name" ? [letter] : []))));
|
|
469
609
|
if (nameLetters.size > 0 && readArgRoles(row, folded).some((e) => e.kind === "option" && e.reading === "speculative" && [...folded[e.at].slice(1)].some((ch) => nameLetters.has(ch))))
|
|
470
610
|
unknownAll();
|
|
471
|
-
return { bindings, all };
|
|
611
|
+
return finish({ bindings, all });
|
|
472
612
|
}
|
|
473
613
|
function nameIn(text) {
|
|
474
614
|
return /^([A-Za-z_][A-Za-z0-9_]*)(?:\[.*\])?$/s.exec(text)?.[1];
|
|
475
615
|
}
|
|
616
|
+
function unsetOperands(args) {
|
|
617
|
+
let variables = false;
|
|
618
|
+
let otherwise = false;
|
|
619
|
+
let at = 0;
|
|
620
|
+
for (; at < args.length; at++) {
|
|
621
|
+
const w = args[at].folded;
|
|
622
|
+
if (w === "--") {
|
|
623
|
+
at++;
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
if (!/^-./.test(w))
|
|
627
|
+
break;
|
|
628
|
+
for (const letter of w.slice(1)) {
|
|
629
|
+
if (letter === "v" || letter === "n")
|
|
630
|
+
variables = true;
|
|
631
|
+
else
|
|
632
|
+
otherwise = true;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return { operands: args.slice(at), variablesOnly: variables && !otherwise };
|
|
636
|
+
}
|
|
476
637
|
function compoundElementWords(raw) {
|
|
477
638
|
const inner = /^\(([\s\S]*)\)$/.exec(raw)?.[1];
|
|
478
639
|
const l = inner === undefined ? undefined : lexShell(inner);
|
|
@@ -490,7 +651,7 @@ function compoundFloor(raw, readValue, overlay) {
|
|
|
490
651
|
return compoundElementWords(raw).flatMap((w) => {
|
|
491
652
|
const v = w.tail === true ? "unknown" : readValue(w, true, overlay);
|
|
492
653
|
if (v !== "unknown")
|
|
493
|
-
return
|
|
654
|
+
return v.map(floorOf);
|
|
494
655
|
const text = w.pieces.some((q) => q.expansion?.kind === "tilde") ? w.folded : literalTildeSpelling(w.folded);
|
|
495
656
|
return [w.pieces.some((q) => q.expansion?.kind === "glob") ? { spelled: text, glob: true } : { spelled: text }];
|
|
496
657
|
});
|
|
@@ -538,6 +699,11 @@ export function textBindsHome(text) {
|
|
|
538
699
|
return names === "all" || names.has("HOME");
|
|
539
700
|
}
|
|
540
701
|
const NOTHING_INHERITED = { attributes: [], references: false };
|
|
702
|
+
export function joinRebound(a, b) {
|
|
703
|
+
if (a === "all" || b === "all")
|
|
704
|
+
return "all";
|
|
705
|
+
return new Set([...(a ?? []), ...(b ?? [])]);
|
|
706
|
+
}
|
|
541
707
|
export class BindingThread {
|
|
542
708
|
segments;
|
|
543
709
|
named;
|
|
@@ -545,40 +711,186 @@ export class BindingThread {
|
|
|
545
711
|
boundAnywhere;
|
|
546
712
|
loops;
|
|
547
713
|
homeStartsTouched;
|
|
714
|
+
inheritedFunctions;
|
|
548
715
|
entries = [];
|
|
716
|
+
localDeclarations = [];
|
|
549
717
|
attributesAt;
|
|
550
718
|
unreadable;
|
|
551
719
|
blocks;
|
|
552
|
-
|
|
553
|
-
|
|
720
|
+
ownSubshell;
|
|
721
|
+
startFloors;
|
|
722
|
+
startRebound;
|
|
723
|
+
bodyRuns = { limit: -1, environment: [] };
|
|
724
|
+
constructor(segments, named, initial, boundAnywhere, loops, homeStartsTouched = false, inherited = NOTHING_INHERITED, inheritedFunctions) {
|
|
554
725
|
this.segments = segments;
|
|
555
726
|
this.named = named;
|
|
556
727
|
this.initial = initial;
|
|
557
728
|
this.boundAnywhere = boundAnywhere;
|
|
558
729
|
this.loops = loops;
|
|
559
730
|
this.homeStartsTouched = homeStartsTouched;
|
|
731
|
+
this.inheritedFunctions = inheritedFunctions;
|
|
732
|
+
this.startFloors = inherited.floors ?? new Map();
|
|
733
|
+
this.startRebound = inherited.rebound ?? new Set();
|
|
560
734
|
this.blocks = blockStructure(segments);
|
|
561
|
-
this.
|
|
735
|
+
this.ownSubshell = segments.map((_, i) => segments[i + 1]?.connector === "|" || segments[i + 1]?.connector === "&");
|
|
562
736
|
this.unreadable = [...(inherited.references ? [{ at: -1 }] : []), ...named.flatMap((effect, at) => this.unreadableBy(effect, at))];
|
|
563
737
|
this.attributesAt = [...inherited.attributes.map((a) => ({ ...a, at: -1 })), ...named.flatMap((effect, at) => (effect.attributes ?? []).map((a) => ({ ...a, at })))];
|
|
564
738
|
}
|
|
565
739
|
inheritedAt(j) {
|
|
566
740
|
const holds = (at) => j === undefined || this.mayRunBefore(at, j);
|
|
741
|
+
const reaches = (e) => j === undefined || (this.mayRunBefore(e.at, j) && this.visible(e, j));
|
|
742
|
+
const floors = new Map(this.startFloors);
|
|
743
|
+
for (const e of this.entries)
|
|
744
|
+
if (e.name !== undefined && e.floor !== undefined && (j === undefined || e.at < j))
|
|
745
|
+
floors.set(e.name, [...(floors.get(e.name) ?? []), ...e.floor]);
|
|
746
|
+
let rebound = this.startRebound;
|
|
747
|
+
for (const e of this.entries)
|
|
748
|
+
if (e.state !== "reset" && reaches(e))
|
|
749
|
+
rebound = joinRebound(rebound, e.name === undefined ? "all" : [e.name]);
|
|
750
|
+
for (const u of this.unreadable)
|
|
751
|
+
if (j === undefined || this.lostAt(u, j))
|
|
752
|
+
rebound = joinRebound(rebound, u.name === undefined ? "all" : [u.name]);
|
|
753
|
+
rebound = joinRebound(rebound, this.boundLater(j));
|
|
567
754
|
return {
|
|
568
755
|
attributes: this.attributesAt.filter((x) => holds(x.at)).map(({ name, kind }) => (name !== undefined ? { name, kind } : { kind })),
|
|
569
756
|
references: this.unreadable.some((u) => u.name === undefined && u.body === undefined && holds(u.at)),
|
|
757
|
+
...(floors.size > 0 ? { floors } : {}),
|
|
758
|
+
rebound,
|
|
570
759
|
};
|
|
571
760
|
}
|
|
761
|
+
startOf(name) {
|
|
762
|
+
return isFunctionKey(name) ? this.inheritedFunctions?.start(name) ?? FUNCTION_ABSENT : isBuiltinKey(name) ? this.inheritedFunctions?.start(name) ?? BUILTIN_ENABLED : this.initial(name);
|
|
763
|
+
}
|
|
764
|
+
bindsInText(name) {
|
|
765
|
+
return this.named.some((effect) => effect.all === "unknown" || effect.bindings.some((b) => speaksFor(b.name, name)));
|
|
766
|
+
}
|
|
767
|
+
heldAnywhere() {
|
|
768
|
+
const start = (key) => {
|
|
769
|
+
const own = this.startOf(key);
|
|
770
|
+
if (own === "unknown")
|
|
771
|
+
return own;
|
|
772
|
+
const values = [...own];
|
|
773
|
+
for (const effect of this.named) {
|
|
774
|
+
if (effect.all === "unknown")
|
|
775
|
+
return "unknown";
|
|
776
|
+
for (const b of effect.bindings) {
|
|
777
|
+
if (!speaksFor(b.name, key))
|
|
778
|
+
continue;
|
|
779
|
+
if (b.state === "unknown")
|
|
780
|
+
return "unknown";
|
|
781
|
+
for (const v of b.state)
|
|
782
|
+
if (!values.some((x) => sameValue(x, v)))
|
|
783
|
+
values.push(v);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return values;
|
|
787
|
+
};
|
|
788
|
+
return { start, bound: new Set() };
|
|
789
|
+
}
|
|
790
|
+
runsBodies(runs, atEnd, environment) {
|
|
791
|
+
let limit = atEnd ? this.named.length - 1 : -1;
|
|
792
|
+
runs.forEach((r, si) => {
|
|
793
|
+
if (!r)
|
|
794
|
+
return;
|
|
795
|
+
limit = Math.max(limit, si);
|
|
796
|
+
for (const [head, end] of this.loops)
|
|
797
|
+
if (head <= si && si < end)
|
|
798
|
+
limit = Math.max(limit, end);
|
|
799
|
+
});
|
|
800
|
+
this.bodyRuns = { limit, environment };
|
|
801
|
+
const calling = new Set(runs.flatMap((r, si) => (r && this.blocks[si].body !== undefined ? [this.blocks[si].body.id] : [])));
|
|
802
|
+
this.named.forEach((effect, at) => {
|
|
803
|
+
for (const b of effect.bindings) {
|
|
804
|
+
const body = this.standingOf(at, b.name).body;
|
|
805
|
+
if (body !== undefined && calling.has(body.id))
|
|
806
|
+
this.unreadable.push({ at, name: b.name, body });
|
|
807
|
+
}
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
boundLater(j) {
|
|
811
|
+
const out = new Set();
|
|
812
|
+
if (j !== undefined && this.blocks[j].body === undefined)
|
|
813
|
+
return out;
|
|
814
|
+
const limit = j === undefined ? this.named.length - 1 : this.bodyRuns.limit;
|
|
815
|
+
for (let s = j === undefined ? 0 : j + 1; s <= limit; s++) {
|
|
816
|
+
const effect = this.named[s];
|
|
817
|
+
if (effect.all === "unknown" || effect.references === true)
|
|
818
|
+
return "all";
|
|
819
|
+
for (const b of effect.bindings)
|
|
820
|
+
out.add(b.name);
|
|
821
|
+
const environment = this.bodyRuns.environment[s];
|
|
822
|
+
if (environment === "all")
|
|
823
|
+
return "all";
|
|
824
|
+
for (const name of environment ?? [])
|
|
825
|
+
out.add(name);
|
|
826
|
+
}
|
|
827
|
+
return out;
|
|
828
|
+
}
|
|
829
|
+
ownSubshellAt(at, standing) {
|
|
830
|
+
return this.ownSubshell[at] === true && standing.depth >= this.blocks[at].after;
|
|
831
|
+
}
|
|
832
|
+
detachedAt(at, standing) {
|
|
833
|
+
return this.segments[at].connector === "|" || this.ownSubshellAt(at, standing);
|
|
834
|
+
}
|
|
835
|
+
visible(e, j) {
|
|
836
|
+
const reader = j === undefined ? undefined : this.blocks[j];
|
|
837
|
+
if (e.standing.body !== undefined && reader?.body?.id !== e.standing.body.id)
|
|
838
|
+
return false;
|
|
839
|
+
if (j !== e.at && this.ownSubshellAt(e.at, e.standing))
|
|
840
|
+
return false;
|
|
841
|
+
const around = reader?.subshells ?? [];
|
|
842
|
+
return e.standing.subshells.every((id) => around.includes(id));
|
|
843
|
+
}
|
|
844
|
+
standingOf(at, name) {
|
|
845
|
+
const own = this.blocks[at];
|
|
846
|
+
const head = name !== undefined && isFunctionKey(name) ? own.defs.find((d) => functionKey(d.name) === name) : undefined;
|
|
847
|
+
return head?.standing ?? { ...(own.body !== undefined ? { body: own.body } : {}), subshells: own.subshells, depth: own.words };
|
|
848
|
+
}
|
|
849
|
+
functionBound() {
|
|
850
|
+
const out = new Set();
|
|
851
|
+
if (this.inheritedFunctions?.bound === "all")
|
|
852
|
+
return "all";
|
|
853
|
+
for (const name of this.inheritedFunctions?.bound ?? [])
|
|
854
|
+
out.add(name);
|
|
855
|
+
for (let at = 0; at < this.named.length; at++) {
|
|
856
|
+
const effect = this.named[at];
|
|
857
|
+
if (this.blocks[at].body !== undefined && (effect.all === "unknown" || effect.references === true))
|
|
858
|
+
return "all";
|
|
859
|
+
for (const b of effect.bindings) {
|
|
860
|
+
const own = this.bodyBinding(b, at);
|
|
861
|
+
if (own !== undefined && (b.scope === "unread" || !this.declaredLocal(b.name, at, own)))
|
|
862
|
+
out.add(b.name);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
return out;
|
|
866
|
+
}
|
|
867
|
+
bodyBinding(b, at) {
|
|
868
|
+
const own = this.standingOf(at, b.name).body;
|
|
869
|
+
return own !== undefined && b.scope !== "local" ? own : undefined;
|
|
870
|
+
}
|
|
871
|
+
inFunctionBody(at) {
|
|
872
|
+
return this.blocks[at].body !== undefined;
|
|
873
|
+
}
|
|
874
|
+
runsApart(at) {
|
|
875
|
+
return this.blocks[at].subshells.length > 0 || this.ownSubshell[at] === true || this.blocks[at].body !== undefined;
|
|
876
|
+
}
|
|
877
|
+
runsLater(at, names) {
|
|
878
|
+
if (names === "all")
|
|
879
|
+
this.unreadable.push({ at });
|
|
880
|
+
else
|
|
881
|
+
for (const name of names)
|
|
882
|
+
this.unreadable.push({ at, name });
|
|
883
|
+
}
|
|
572
884
|
unreadableBy(effect, at) {
|
|
573
885
|
const body = this.blocks[at].body;
|
|
574
886
|
const out = [];
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
if (effect.all === "unknown")
|
|
580
|
-
out.push({ at, body });
|
|
887
|
+
for (const b of effect.bindings) {
|
|
888
|
+
const own = this.bodyBinding(b, at);
|
|
889
|
+
if (own !== undefined)
|
|
890
|
+
out.push({ at, name: b.name, body: own });
|
|
581
891
|
}
|
|
892
|
+
if (body !== undefined && effect.all === "unknown")
|
|
893
|
+
out.push({ at, body });
|
|
582
894
|
if (effect.references === true)
|
|
583
895
|
out.push({ at });
|
|
584
896
|
return out;
|
|
@@ -589,107 +901,139 @@ export class BindingThread {
|
|
|
589
901
|
return this.blocks[e].body !== undefined || [...this.loops].some(([head, end]) => head <= e && x < end);
|
|
590
902
|
}
|
|
591
903
|
declaredLocal(name, at, body) {
|
|
592
|
-
|
|
593
|
-
const connector = this.segments[k].connector;
|
|
594
|
-
if (this.blocks[k].body?.id !== body.id || this.detached[k] === true || connector === "&&" || connector === "||")
|
|
595
|
-
continue;
|
|
596
|
-
if (this.named[k].bindings.some((b) => b.scope === "local" && b.name === name) && this.heldThrough(k, at))
|
|
597
|
-
return true;
|
|
598
|
-
}
|
|
599
|
-
return false;
|
|
904
|
+
return this.localDeclarations.some((d) => d.body === body.id && d.name === name && d.at < at && this.heldThrough(d, at));
|
|
600
905
|
}
|
|
601
|
-
heldThrough(
|
|
602
|
-
const depth =
|
|
603
|
-
if (this.blocks[at].after < depth)
|
|
906
|
+
heldThrough(e, j) {
|
|
907
|
+
const depth = e.standing.depth;
|
|
908
|
+
if (this.blocks[e.at].after < depth)
|
|
604
909
|
return false;
|
|
605
|
-
for (let k = at + 1; k <= j; k++)
|
|
910
|
+
for (let k = e.at + 1; k <= j; k++)
|
|
606
911
|
if (this.blocks[k].lowest < depth || this.blocks[k].switches.includes(depth))
|
|
607
912
|
return false;
|
|
608
913
|
return true;
|
|
609
914
|
}
|
|
610
915
|
apply(at, effect, andRun, loopEnd) {
|
|
611
|
-
const
|
|
612
|
-
const refused = effect.inFunction === true &&
|
|
916
|
+
const body = this.blocks[at].body;
|
|
917
|
+
const refused = effect.inFunction === true && body === undefined;
|
|
613
918
|
if (effect.all !== undefined)
|
|
614
|
-
this.entries.push({ at, state: effect.all === "reset" ? "reset" : "unknown", detached: false, andRun: false });
|
|
919
|
+
this.entries.push({ at, standing: this.standingOf(at), state: effect.all === "reset" ? "reset" : "unknown", detached: false, andRun: false });
|
|
615
920
|
for (const b of effect.bindings) {
|
|
921
|
+
const standing = this.standingOf(at, b.name);
|
|
922
|
+
const detached = this.detachedAt(at, standing) || b.prefix === true;
|
|
616
923
|
this.entries.push({
|
|
617
|
-
at, name: b.name, state: refused ? "unknown" : b.state, detached
|
|
924
|
+
at, standing, name: b.name, state: refused ? "unknown" : b.state, detached, andRun,
|
|
618
925
|
...(b.loopVar === true && loopEnd !== undefined ? { certainUntil: loopEnd } : {}),
|
|
619
926
|
...(b.floor !== undefined && b.floor.length > 0 ? { floor: b.floor } : {}),
|
|
620
927
|
});
|
|
928
|
+
if (b.scope === "local" && body !== undefined && !refused && !detached && !andRun)
|
|
929
|
+
this.localDeclarations.push({ at, name: b.name, body: body.id, standing });
|
|
621
930
|
}
|
|
622
931
|
}
|
|
623
|
-
|
|
624
|
-
if (
|
|
625
|
-
return
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
return true;
|
|
629
|
-
return false;
|
|
932
|
+
lostAt(u, j) {
|
|
933
|
+
if (u.body === undefined)
|
|
934
|
+
return this.mayRunBefore(u.at, j);
|
|
935
|
+
const readerBody = this.blocks[j].body;
|
|
936
|
+
return readerBody !== undefined && readerBody.id !== u.body.id;
|
|
630
937
|
}
|
|
631
938
|
kill(at, names) {
|
|
939
|
+
const standing = this.standingOf(at);
|
|
632
940
|
if (names === "all") {
|
|
633
|
-
this.entries.push({ at, state: "unknown", detached: false, andRun: false });
|
|
941
|
+
this.entries.push({ at, standing, state: "unknown", detached: false, andRun: false });
|
|
634
942
|
return;
|
|
635
943
|
}
|
|
636
944
|
for (const name of names)
|
|
637
|
-
this.entries.push({ at, name, state: "unknown", detached: false, andRun: false });
|
|
945
|
+
this.entries.push({ at, standing, name, state: "unknown", detached: false, andRun: false });
|
|
638
946
|
}
|
|
639
|
-
tableAt(j, andRunStart) {
|
|
947
|
+
tableAt(j, andRunStart, where) {
|
|
640
948
|
const certain = (e) => {
|
|
641
949
|
if (e.certainUntil !== undefined && j < e.certainUntil)
|
|
642
950
|
return true;
|
|
643
|
-
if (e.detached || !this.heldThrough(e
|
|
951
|
+
if (e.detached || !this.heldThrough(e, j))
|
|
644
952
|
return false;
|
|
645
953
|
return !e.andRun || e.at >= andRunStart;
|
|
646
954
|
};
|
|
647
955
|
const readerBody = this.blocks[j].body;
|
|
648
|
-
const lost = (u) =>
|
|
649
|
-
|
|
650
|
-
return this.mayRunBefore(u.at, j);
|
|
651
|
-
if (readerBody !== undefined && readerBody.id !== u.body.id)
|
|
652
|
-
return true;
|
|
653
|
-
return u.at < j && this.leftBody(u.at, u.body, j);
|
|
654
|
-
};
|
|
655
|
-
const before = (e) => e.at < j || (e.at === j && e.state === "reset");
|
|
956
|
+
const lost = (u) => this.lostAt(u, j);
|
|
957
|
+
const before = (e) => (e.at < j || (e.at === j && e.state === "reset")) && this.visible(e, j);
|
|
656
958
|
const given = (name, at, integer) => this.attributesAt.some((x) => (x.name === undefined || x.name === name) && (integer !== true || x.kind === "integer") && x.at !== at && this.mayRunBefore(x.at, at));
|
|
657
|
-
const
|
|
658
|
-
if (shellKeepsName(name))
|
|
659
|
-
return "unknown";
|
|
660
|
-
if (this.unreadable.some((u) => (u.name === undefined || u.name === name) && lost(u)))
|
|
661
|
-
return "unknown";
|
|
959
|
+
const walk = (name, start) => {
|
|
662
960
|
const values = [];
|
|
663
961
|
const add = (vs) => { for (const v of vs)
|
|
664
962
|
if (!values.some((x) => sameValue(x, v)))
|
|
665
963
|
values.push(v); };
|
|
666
964
|
for (let i = this.entries.length - 1; i >= 0; i--) {
|
|
667
965
|
const e = this.entries[i];
|
|
668
|
-
if (!before(e) || (e.name !== undefined && e.name
|
|
966
|
+
if (!before(e) || (e.name !== undefined && !speaksFor(e.name, name)))
|
|
967
|
+
continue;
|
|
968
|
+
if (e.state === "reset" && isBuiltinKey(name))
|
|
669
969
|
continue;
|
|
670
|
-
const state = e.state === "reset" ? (name === "HOME" && this.boundAnywhere("HOME") ? "unknown" : this.initial(name)) : e.state;
|
|
970
|
+
const state = e.state === "reset" ? ((name === "HOME" && this.boundAnywhere("HOME")) || this.bindsInText(name) ? "unknown" : this.initial(name)) : e.state;
|
|
671
971
|
if (state === "unknown")
|
|
672
|
-
return "unknown";
|
|
972
|
+
return { state: "unknown" };
|
|
673
973
|
if (e.name !== undefined && given(e.name, e.at))
|
|
674
|
-
return "unknown";
|
|
974
|
+
return { state: "unknown" };
|
|
675
975
|
add(state);
|
|
676
976
|
if (certain(e))
|
|
677
|
-
return values;
|
|
977
|
+
return { state: values, decided: e };
|
|
678
978
|
}
|
|
679
|
-
const start = this.initial(name);
|
|
680
979
|
if (start === "unknown")
|
|
681
|
-
return "unknown";
|
|
980
|
+
return { state: "unknown" };
|
|
682
981
|
add(start);
|
|
683
|
-
return values;
|
|
982
|
+
return { state: values };
|
|
983
|
+
};
|
|
984
|
+
const later = this.boundLater(j);
|
|
985
|
+
const boundLater = (name) => later === "all" || later.has(name) || (isBuiltinKey(name) && later.has(BUILTINS_ALL));
|
|
986
|
+
const stateOf = (name) => {
|
|
987
|
+
if (shellKeepsName(name))
|
|
988
|
+
return "unknown";
|
|
989
|
+
if (this.unreadable.some((u) => speaksFor(u.name, name) && lost(u)))
|
|
990
|
+
return "unknown";
|
|
991
|
+
if (!isWorkingDirectoryName(name)) {
|
|
992
|
+
const walked = walk(name, this.startOf(name));
|
|
993
|
+
const own = walked.decided !== undefined && walked.decided.state !== "reset" && readerBody !== undefined && walked.decided.standing.body?.id === readerBody.id;
|
|
994
|
+
return boundLater(name) && !own ? "unknown" : walked.state;
|
|
995
|
+
}
|
|
996
|
+
if (boundLater(name))
|
|
997
|
+
return "unknown";
|
|
998
|
+
const assigned = walk(name, []);
|
|
999
|
+
if (assigned.decided !== undefined && where !== undefined && readerBody === undefined && assigned.decided.at > where.movedAt)
|
|
1000
|
+
return assigned.state;
|
|
1001
|
+
const thread = readerBody === undefined ? where?.[name] ?? "unknown" : "unknown";
|
|
1002
|
+
if (thread === "unknown" || assigned.state === "unknown")
|
|
1003
|
+
return "unknown";
|
|
1004
|
+
const held = assigned.state;
|
|
1005
|
+
return [...held, ...thread.filter((v) => !held.some((x) => sameValue(x, v)))];
|
|
684
1006
|
};
|
|
685
1007
|
const touched = (name) => this.entries.some((e) => before(e) && (e.name === undefined || e.name === name));
|
|
1008
|
+
let rebound = this.startRebound;
|
|
1009
|
+
for (const e of this.entries)
|
|
1010
|
+
if (e.state !== "reset" && (readerBody !== undefined ? e.at !== j : before(e)))
|
|
1011
|
+
rebound = joinRebound(rebound, e.name === undefined ? "all" : [e.name]);
|
|
1012
|
+
for (const u of this.unreadable)
|
|
1013
|
+
if (lost(u))
|
|
1014
|
+
rebound = joinRebound(rebound, u.name === undefined ? "all" : [u.name]);
|
|
1015
|
+
const settled = joinRebound(rebound, later);
|
|
686
1016
|
return {
|
|
687
1017
|
stateOf,
|
|
688
1018
|
isInteger: (name) => SHELL_INTEGER_VARIABLES.has(name) || given(name, j, true),
|
|
689
|
-
ifsTouched: touched("IFS"),
|
|
690
|
-
homeTouched: this.homeStartsTouched || touched("HOME"),
|
|
691
|
-
floorOf: (name) => this.entries.filter((e) => e.at < j && e.name === name).flatMap((e) => e.floor ?? []),
|
|
1019
|
+
ifsTouched: touched("IFS") || boundLater("IFS"),
|
|
1020
|
+
homeTouched: this.homeStartsTouched || touched("HOME") || boundLater("HOME"),
|
|
1021
|
+
floorOf: (name) => [...(this.startFloors.get(name) ?? []), ...this.entries.filter((e) => e.at < j && e.name === name).flatMap((e) => e.floor ?? [])],
|
|
692
1022
|
inherited: this.inheritedAt(j),
|
|
1023
|
+
rebound: settled,
|
|
1024
|
+
providedByShell: (name) => settled !== "all" && !settled.has(name),
|
|
1025
|
+
functionState: (name) => {
|
|
1026
|
+
const held = stateOf(functionKey(name));
|
|
1027
|
+
if (held === "unknown")
|
|
1028
|
+
return "maybe";
|
|
1029
|
+
return !held.some(isDefinedValue) ? "absent" : held.length > 1 ? "maybe" : "defined";
|
|
1030
|
+
},
|
|
1031
|
+
builtinState: (name) => {
|
|
1032
|
+
const held = stateOf(builtinKey(name));
|
|
1033
|
+
if (held === "unknown")
|
|
1034
|
+
return "maybe";
|
|
1035
|
+
return held.every(isDisabledValue) ? "disabled" : held.some(isDisabledValue) ? "maybe" : "enabled";
|
|
1036
|
+
},
|
|
693
1037
|
};
|
|
694
1038
|
}
|
|
695
1039
|
}
|