@sema-agent/core 7.53.0 → 7.54.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +291 -1
- package/LICENSE +3 -1
- package/dist/agents/peer-session-drain.d.ts +0 -1
- package/dist/agents/peer-session-drain.js +0 -2
- package/dist/agents/send-message-tool.js +3 -4
- package/dist/agents/subagent.d.ts +3 -5
- package/dist/agents/subagent.js +18 -11
- package/dist/agents/tool-filter.d.ts +7 -4
- package/dist/agents/tool-filter.js +7 -3
- package/dist/core/a2a.js +4 -2
- package/dist/core/allow-entry.d.ts +1 -0
- package/dist/core/allow-entry.js +1 -0
- package/dist/core/approval-object.d.ts +87 -0
- package/dist/core/approval-object.js +85 -0
- package/dist/core/arg-summary.d.ts +3 -2
- package/dist/core/arg-summary.js +17 -11
- package/dist/core/ask-origin.d.ts +43 -27
- package/dist/core/ask-origin.js +20 -11
- package/dist/core/ask-question.d.ts +0 -1
- package/dist/core/ask-question.js +4 -67
- package/dist/core/ask-unresolvable-notice.d.ts +3 -2
- package/dist/core/auto-compaction.d.ts +49 -50
- package/dist/core/auto-compaction.js +41 -51
- package/dist/core/auto-mode-prompt.d.ts +4 -2
- package/dist/core/auto-mode-prompt.js +4 -3
- package/dist/core/canonical-json.d.ts +69 -0
- package/dist/core/canonical-json.js +130 -8
- package/dist/core/checkpoint-requirements.d.ts +13 -7
- package/dist/core/checkpoint-requirements.js +4 -1
- package/dist/core/checkpoint-store.d.ts +33 -18
- package/dist/core/checkpoint-store.js +5 -4
- package/dist/core/child-clamp-seats.d.ts +45 -6
- package/dist/core/child-clamp-seats.js +56 -4
- package/dist/core/consolidate-scope.d.ts +1 -1
- package/dist/core/cross-boundary-taint.d.ts +213 -0
- package/dist/core/cross-boundary-taint.js +196 -0
- package/dist/core/decision-receipt.d.ts +44 -1
- package/dist/core/decision-receipt.js +16 -0
- package/dist/core/effective-path-target.d.ts +3 -0
- package/dist/core/effective-path-target.js +4 -0
- package/dist/core/engine-notice.d.ts +34 -2
- package/dist/core/engine-notice.js +17 -1
- package/dist/core/engine-storage-backend.d.ts +73 -0
- package/dist/core/engine-storage-backend.js +1 -0
- package/dist/core/file-history-store.d.ts +6 -2
- package/dist/core/file-history-store.js +1 -0
- package/dist/core/gate-fold.js +10 -2
- package/dist/core/gate-lanes.js +30 -21
- package/dist/core/gate-outcome.d.ts +7 -3
- package/dist/core/governance-codes.d.ts +7 -2
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/hooks.d.ts +14 -14
- package/dist/core/hooks.js +1 -2
- package/dist/core/locked-config.d.ts +28 -1
- package/dist/core/locked-config.js +30 -3
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/mcp-server-spec.d.ts +66 -9
- package/dist/core/mcp-server-spec.js +52 -19
- package/dist/core/mcp.js +5 -4
- package/dist/core/memory-engine/engine.js +2 -1
- package/dist/core/memory-engine/export-bundle.d.ts +1 -1
- package/dist/core/memory-engine/export-bundle.js +1 -1
- package/dist/core/memory-engine/file-backend.d.ts +2 -6
- package/dist/core/memory-engine/file-backend.js +1 -12
- package/dist/core/memory.d.ts +3 -3
- package/dist/core/mode-policy.d.ts +13 -8
- package/dist/core/mode-policy.js +3 -2
- package/dist/core/mods/kernel/receive.d.ts +2 -1
- package/dist/core/mods/kernel/receive.js +7 -2
- package/dist/core/parent-spec-seat.d.ts +10 -13
- package/dist/core/parent-spec-seat.js +14 -6
- package/dist/core/pause-registry.d.ts +35 -1
- package/dist/core/pause-registry.js +10 -0
- package/dist/core/permission-rule-consent.d.ts +18 -5
- package/dist/core/permission-rule-consent.js +13 -8
- package/dist/core/permission-rule-model.d.ts +29 -6
- package/dist/core/permission-rule-model.js +6 -1
- package/dist/core/permission-rule-org.d.ts +37 -0
- package/dist/core/permission-rule-org.js +34 -42
- package/dist/core/permission-rule-session.js +2 -2
- package/dist/core/permission-rule-store.d.ts +8 -0
- package/dist/core/permission-rule-store.js +1 -0
- package/dist/core/permission-rule-sync.js +3 -2
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/read-only-shell.js +30 -9
- package/dist/core/remote-env.d.ts +41 -1
- package/dist/core/remote-env.js +18 -0
- package/dist/core/resume-startup-cause.d.ts +18 -0
- package/dist/core/resume-startup-cause.js +12 -0
- package/dist/core/runner/approval-feedback.d.ts +46 -0
- package/dist/core/runner/approval-feedback.js +41 -0
- package/dist/core/runner/compaction-call-options.d.ts +3 -3
- package/dist/core/runner/compaction-call-options.js +2 -2
- package/dist/core/runner/contracts.d.ts +33 -41
- package/dist/core/runner/cross-boundary-lane.d.ts +87 -0
- package/dist/core/runner/cross-boundary-lane.js +190 -0
- package/dist/core/runner/decide-continuation.d.ts +4 -4
- package/dist/core/runner/decide-continuation.js +3 -1
- package/dist/core/runner/gate-exit.d.ts +32 -12
- package/dist/core/runner/gate-exit.js +75 -33
- package/dist/core/runner/inherited-ask-grants.js +2 -2
- package/dist/core/runner/person-path-rows.d.ts +2 -2
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +7 -9
- package/dist/core/runner/prepare-acquire-reconcile.js +8 -6
- package/dist/core/runner/prepare-ask-lane.js +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +6 -5
- package/dist/core/runner/prepare-caps-and-workflow.js +3 -3
- package/dist/core/runner/prepare-config-doors.d.ts +12 -15
- package/dist/core/runner/prepare-config-doors.js +8 -3
- package/dist/core/runner/prepare-context-lane.js +6 -3
- package/dist/core/runner/prepare-delegation-surface.d.ts +3 -2
- package/dist/core/runner/prepare-delegation-surface.js +2 -3
- package/dist/core/runner/prepare-execution-env.d.ts +1 -2
- package/dist/core/runner/prepare-execution-env.js +2 -1
- package/dist/core/runner/prepare-gate-stations.d.ts +2 -0
- package/dist/core/runner/prepare-gate-stations.js +4 -3
- package/dist/core/runner/prepare-hands-readface.d.ts +2 -2
- package/dist/core/runner/prepare-hands-readface.js +1 -1
- package/dist/core/runner/prepare-inherited-gate.d.ts +2 -0
- package/dist/core/runner/prepare-inherited-gate.js +1 -0
- package/dist/core/runner/prepare-park-ask.d.ts +1 -1
- package/dist/core/runner/prepare-park-ask.js +9 -3
- package/dist/core/runner/prepare-policy-chain.js +2 -7
- package/dist/core/runner/prepare-safety-scan.d.ts +7 -2
- package/dist/core/runner/prepare-safety-scan.js +34 -27
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -2
- package/dist/core/runner/prepare-suspend-saga.js +6 -2
- package/dist/core/runner/prepare-task.js +13 -10
- package/dist/core/runner/prepare-turn-wiring.d.ts +10 -5
- package/dist/core/runner/prepare-turn-wiring.js +14 -49
- package/dist/core/runner/prepare-wiring-manifest.d.ts +2 -2
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/prepare-workspace-restore.js +2 -2
- package/dist/core/runner/resume-admission.js +9 -9
- package/dist/core/runner/resume-apply.js +4 -4
- package/dist/core/runner/resume-policy-outcome.d.ts +2 -2
- package/dist/core/runner/resume-policy-outcome.js +18 -15
- package/dist/core/runner/resume-preflight.js +2 -2
- package/dist/core/runner/resume-review-outcome.js +3 -3
- package/dist/core/runner/run-leg.js +57 -33
- package/dist/core/runner/run-settle-and-teardown.js +2 -0
- package/dist/core/runner/run-terminal-adoption.js +15 -4
- package/dist/core/runner/session-file-state-replay.d.ts +5 -2
- package/dist/core/runner/session-file-state-replay.js +3 -2
- package/dist/core/runner/stream-steer-verb.js +2 -2
- package/dist/core/runner/tool-face-overlay.d.ts +24 -6
- package/dist/core/runner/tool-face-overlay.js +24 -15
- package/dist/core/runner-deps.d.ts +9 -9
- package/dist/core/session-store.d.ts +35 -16
- package/dist/core/session-store.js +20 -12
- package/dist/core/{shell-lexer.d.ts → shell-run-candidates.d.ts} +36 -12
- package/dist/core/{shell-lexer.js → shell-run-candidates.js} +145 -225
- package/dist/core/shell-wrapper-table.d.ts +5 -3
- package/dist/core/shell-wrapper-table.js +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +2 -2
- package/dist/core/store-contracts/session-store-contract.d.ts +49 -0
- package/dist/core/store-contracts/session-store-contract.js +683 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +12 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.js +5 -2
- package/dist/core/task-event.d.ts +6 -4
- package/dist/core/task-registry-agent.js +1 -0
- package/dist/core/task-registry-shared.d.ts +5 -0
- package/dist/core/task-registry.d.ts +7 -0
- package/dist/core/task-registry.js +17 -0
- package/dist/core/task-result.d.ts +1 -1
- package/dist/core/task-spec.d.ts +6 -6
- package/dist/core/tighten-task-spec.d.ts +6 -4
- package/dist/core/tighten-task-spec.js +2 -2
- package/dist/core/tool-catalog-entries.d.ts +1 -1
- package/dist/core/tool-catalog-entries.js +52 -52
- package/dist/core/tool-face-reader.d.ts +49 -0
- package/dist/core/tool-face-reader.js +94 -0
- package/dist/core/tool-face.d.ts +17 -8
- package/dist/core/tool-face.js +1 -0
- package/dist/core/tool-policy.d.ts +64 -23
- package/dist/core/tool-policy.js +62 -56
- package/dist/core/tool-roster.d.ts +46 -28
- package/dist/core/tool-roster.js +91 -14
- package/dist/core/tool-spec-members.js +2 -2
- package/dist/core/tool-spec.d.ts +20 -4
- package/dist/core/tools.js +2 -0
- package/dist/core/trace.d.ts +24 -2
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/untrusted-text.d.ts +7 -0
- package/dist/core/untrusted-text.js +3 -8
- package/dist/core/user-attachment.d.ts +43 -0
- package/dist/core/user-attachment.js +92 -15
- package/dist/engine/compaction/compaction.d.ts +2 -2
- package/dist/engine/compaction/utils.d.ts +2 -2
- package/dist/engine/harness/types.d.ts +7 -4
- package/dist/engine/llm/types.d.ts +7 -2
- package/dist/engine/llm/types.js +2 -1
- package/dist/engine/session/parent-chain-guard.d.ts +10 -0
- package/dist/engine/session/parent-chain-guard.js +10 -0
- package/dist/engine/session/repo-utils.d.ts +5 -0
- package/dist/engine/session/repo-utils.js +9 -0
- package/dist/engine/session/storage-base.js +5 -2
- package/dist/index.d.ts +23 -9
- package/dist/index.js +19 -8
- package/dist/internal/harness.d.ts +1 -0
- package/dist/internal/harness.js +1 -0
- package/dist/internal/llm.d.ts +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +3 -0
- package/dist/orchestration/run-workflow-tool.js +1 -0
- package/dist/orchestration/workflow-governance.d.ts +1 -1
- package/dist/orchestration/workflow.d.ts +3 -0
- package/dist/orchestration/workflow.js +2 -1
- package/dist/prompt-assembly/catalog/schema.d.ts +3 -0
- package/dist/prompt-assembly/catalog/schema.js +3 -0
- package/dist/prompt-assembly/overlay.js +2 -2
- package/dist/prompt-assembly/select.js +2 -2
- package/dist/prompts/default.d.ts +1 -1
- package/dist/shell/lex.d.ts +87 -8
- package/dist/shell/lex.js +283 -49
- package/dist/stores/file/index.d.ts +8 -6
- package/dist/tools/artifact/artifact-tool.js +10 -0
- package/dist/tools/fs/bash-program-position.d.ts +3 -15
- package/dist/tools/fs/bash-program-position.js +3 -10
- package/dist/tools/fs/bash-readonly-classifier.js +2 -0
- package/dist/tools/fs/fs-bash.d.ts +3 -3
- package/dist/tools/fs/fs-bash.js +72 -101
- package/dist/tools/fs/fs-read.d.ts +12 -0
- package/dist/tools/fs/fs-read.js +10 -9
- package/dist/tools/fs/fs-shared.d.ts +27 -31
- package/dist/tools/fs/fs-shared.js +12 -15
- package/dist/tools/fs/fs-write.js +1 -1
- package/dist/tools/fs/index.js +2 -2
- package/dist/tools/fs/read-deny-home.d.ts +1 -1
- package/dist/tools/fs/read-deny-home.js +5 -4
- package/dist/tools/fs/read-deny.d.ts +16 -3
- package/dist/tools/fs/read-deny.js +12 -9
- package/dist/tools/fs/safety.d.ts +7 -6
- package/dist/tools/fs/shell-read-bindings.d.ts +5 -3
- package/dist/tools/fs/shell-read-bindings.js +15 -16
- package/dist/tools/fs/shell-read-device.js +1 -1
- package/dist/tools/fs/shell-read-plan.js +36 -47
- package/dist/tools/fs/shell-read-word.d.ts +1 -6
- package/dist/tools/fs/shell-read-word.js +2 -20
- package/dist/tools/fs/shell-reentry-text.js +1 -1
- package/dist/tools/web.d.ts +2 -2
- package/package.json +4 -1
- package/test/export-surface.snapshot.json +5654 -5520
- package/wire-changes/core@7.53.0.json +30 -8
- package/wire-changes/core@7.54.0.json +2870 -0
- package/wire-changes/core@7.54.1.json +37 -0
- package/dist/core/shell-scan.d.ts +0 -60
- package/dist/core/shell-scan.js +0 -183
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"repo": "core",
|
|
3
|
+
"version": "7.54.1",
|
|
4
|
+
"from": "371ab636fb4dc957f79229a654ff6c2fe840c9a3",
|
|
5
|
+
"to": "v7.54.1",
|
|
6
|
+
"added": [],
|
|
7
|
+
"removed": [],
|
|
8
|
+
"changed": [],
|
|
9
|
+
"narrowed": [],
|
|
10
|
+
"closedSetMembers": [],
|
|
11
|
+
"closedSetsUnreadable": [],
|
|
12
|
+
"typeKeys": [],
|
|
13
|
+
"typeKeysUnreadableArms": [],
|
|
14
|
+
"typeKeysFlattenedCount": 237,
|
|
15
|
+
"signatures": [],
|
|
16
|
+
"declarationMoves": [],
|
|
17
|
+
"mintMoves": [],
|
|
18
|
+
"criteriaObserves": [
|
|
19
|
+
{
|
|
20
|
+
"kind": "typeMember",
|
|
21
|
+
"name": "SessionError.code",
|
|
22
|
+
"assertions": [
|
|
23
|
+
"G1.a",
|
|
24
|
+
"G1.b"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"consumersHint": {
|
|
29
|
+
"cli": [],
|
|
30
|
+
"server": [],
|
|
31
|
+
"sdk": [],
|
|
32
|
+
"note": "scanned cli@5028feb7 server@41b72695 sdk@e8794dc — a name listed is MENTIONED there today, which is evidence of consumption, not proof of it"
|
|
33
|
+
},
|
|
34
|
+
"breakingCount": 0,
|
|
35
|
+
"breakingItems": [],
|
|
36
|
+
"toResolvedAt": "854e82a40701de98758a3f8a41e62431cf67facd"
|
|
37
|
+
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The character-level scanners under the tightening reader's shell lexer (`shell-lexer.ts`): a double-
|
|
3
|
-
* quoted body, an expansion (`$…`, a backtick, a process substitution), a balanced `(…)` / `{…}` region,
|
|
4
|
-
* and the here-document bodies. Every scanner answers an INDEX (past what it read) or `undefined` for
|
|
5
|
-
* "never closes", and reports through `word.substitution` / the heredoc result whether it passed a
|
|
6
|
-
* COMMAND SUBSTITUTION — `$(…)`, a backtick, `<(…)`/`>(…)`, anywhere, including inside `${…}` and
|
|
7
|
-
* `$((…))` — because a substitution runs a program the lexer does not read: the lexer marks the segment
|
|
8
|
-
* and the reader answers `unreadable` for every rule the segment does not otherwise reach. Reading the
|
|
9
|
-
* commands INSIDE a substitution was tried and retired: every bash quirk of substitution boundaries
|
|
10
|
-
* (a `)` in a comment, a multi-line body in a heredoc, a `$"…"` string) became a way to hide a run, and
|
|
11
|
-
* the fail-closed word costs an approval prompt, never a bypass. Split from the lexer so the lexer's own
|
|
12
|
-
* ceiling holds the segment/peel logic and this one holds the byte walking.
|
|
13
|
-
*/
|
|
14
|
-
/** A word under construction; `braceOpen`/`braceExpands` track an unquoted `{a,b}` / `{1..3}` pattern, `bracketOpen` a `[…]` class;
|
|
15
|
-
* `substitution` is set when the word carries a command/process substitution anywhere. */
|
|
16
|
-
export interface Word {
|
|
17
|
-
text: string;
|
|
18
|
-
raw: string;
|
|
19
|
-
expands: false | "one" | "many";
|
|
20
|
-
started: boolean;
|
|
21
|
-
braceOpen: boolean;
|
|
22
|
-
braceExpands: boolean;
|
|
23
|
-
bracketOpen: boolean;
|
|
24
|
-
substitution: boolean;
|
|
25
|
-
}
|
|
26
|
-
export interface Heredoc {
|
|
27
|
-
delimiter: string;
|
|
28
|
-
quoted: boolean;
|
|
29
|
-
dash: boolean;
|
|
30
|
-
}
|
|
31
|
-
/** Is `expr`, the interior of an arithmetic expansion or command, provably free of a hidden run? Only digits,
|
|
32
|
-
* operators and spaces are: a NAME or a `$…` evaluates recursively (`a='arr[$(…)]'; $((a))`), and anything
|
|
33
|
-
* else (`;`, a quote, a bracket) is not arithmetic at all — bash then re-reads `((…))` as nested subshells. */
|
|
34
|
-
export declare const arithmeticHidesRun: (expr: string) => boolean;
|
|
35
|
-
/** Does an expansion interior, an extended-glob interior or a heredoc line carry a run this reader does not
|
|
36
|
-
* read — a substitution opener, or a subscript that evaluates indirectly? Backslash-newline is removed
|
|
37
|
-
* first, as bash removes it before it reads the opener (`$\<newline>(` is `$(`). */
|
|
38
|
-
export declare const carriesSubstitution: (text: string) => boolean;
|
|
39
|
-
export declare const freshWord: () => Word;
|
|
40
|
-
/** Read a `"…"` body into `word` from `i` (just past the opening quote); returns the index past the closing quote. */
|
|
41
|
-
export declare function readDoubleQuoted(s: string, i: number, word: Word): number | undefined;
|
|
42
|
-
/** The index past the expansion starting at `i` (`$…`, a backtick, or a `<(`/`>(` process substitution);
|
|
43
|
-
* `i + 1` when the `$` is literal; `undefined` when it never closes. Sets `word.substitution` when the
|
|
44
|
-
* region is, or contains, a command/process substitution. A `$"…"` string is NOT read here (the lexer
|
|
45
|
-
* reads it as a double-quoted string, which is what it is); inside double quotes `$'` is a literal `$`
|
|
46
|
-
* (ANSI-C quoting exists only outside them). */
|
|
47
|
-
export declare function readExpansion(s: string, i: number, word: Word, inDoubleQuotes?: boolean): number | undefined;
|
|
48
|
-
/** Past the matching `close` for the `open` at `i`, quote-aware (a `)` inside `$(echo ")")` is text).
|
|
49
|
-
* LINEAR: one pass with a small state stack (nesting depth × quote state), no re-entry. */
|
|
50
|
-
export declare function skipBalanced(s: string, i: number, open: string, close: string): number | undefined;
|
|
51
|
-
/** Skip the here-document bodies that begin at `i` (the start of a line), one per delimiter in order,
|
|
52
|
-
* answering the index past them and whether an UNQUOTED body carries a substitution (bash expands such a
|
|
53
|
-
* body: `$(…)` in it runs). An unquoted body joins a line ending in an ODD run of backslashes with the
|
|
54
|
-
* next before the delimiter is compared; `<<-` strips leading tabs. */
|
|
55
|
-
export declare function skipHeredocBodies(s: string, i: number, docs: readonly Heredoc[]): {
|
|
56
|
-
end: number;
|
|
57
|
-
substitution: boolean;
|
|
58
|
-
} | undefined;
|
|
59
|
-
/** The LONGEST operator of `ops` at `i` (`>&` before `>`, `&&` before `&`). */
|
|
60
|
-
export declare function matchOp(s: string, i: number, ops: readonly string[]): string | undefined;
|
package/dist/core/shell-scan.js
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
const SPECIAL_PARAMS = "?$!#@*-0123456789";
|
|
2
|
-
const SUBSTITUTION_RE = /\$\(|`|<\(|>\(|\$\[/;
|
|
3
|
-
export const arithmeticHidesRun = (expr) => /[^\s\d+\-*/%&|^~!<>=?:,()]/.test(expr);
|
|
4
|
-
const SUBSCRIPT_RE = /\$\{[!#]?[A-Za-z_][A-Za-z0-9_]*(?:\[[^\]]*[A-Za-z_$]|(?:\[[^\]]*\])?:(?![-=+?])[^}]*[A-Za-z_$])/;
|
|
5
|
-
export const carriesSubstitution = (text) => { const t = text.replace(/\\\n/g, ""); return SUBSTITUTION_RE.test(t) || SUBSCRIPT_RE.test(t); };
|
|
6
|
-
const PER_ELEMENT_RE = /^\$@$|^\$\{!?@|\[@\]|^\$\{![^}]*@\}$/;
|
|
7
|
-
export const freshWord = () => ({ text: "", raw: "", expands: false, started: false, braceOpen: false, braceExpands: false, bracketOpen: false, substitution: false });
|
|
8
|
-
export function readDoubleQuoted(s, i, word) {
|
|
9
|
-
word.started = true;
|
|
10
|
-
while (i < s.length) {
|
|
11
|
-
const ch = s[i];
|
|
12
|
-
if (ch === '"')
|
|
13
|
-
return i + 1;
|
|
14
|
-
if (ch === "\\") {
|
|
15
|
-
const next = s[i + 1];
|
|
16
|
-
if (next === undefined)
|
|
17
|
-
return undefined;
|
|
18
|
-
if (next === "\n") {
|
|
19
|
-
i += 2;
|
|
20
|
-
continue;
|
|
21
|
-
}
|
|
22
|
-
if ('$`"\\'.includes(next)) {
|
|
23
|
-
word.text += next;
|
|
24
|
-
i += 2;
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
word.text += ch;
|
|
28
|
-
i++;
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
if (ch === "$" || ch === "`") {
|
|
32
|
-
const end = readExpansion(s, i, word, true);
|
|
33
|
-
if (end === undefined)
|
|
34
|
-
return undefined;
|
|
35
|
-
if (end === i + 1) {
|
|
36
|
-
word.text += ch;
|
|
37
|
-
i = end;
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
if (PER_ELEMENT_RE.test(s.slice(i, end).replace(/\\\n/g, "")))
|
|
41
|
-
word.expands = "many";
|
|
42
|
-
else if (word.expands === false)
|
|
43
|
-
word.expands = "one";
|
|
44
|
-
i = end;
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
word.text += ch;
|
|
48
|
-
i++;
|
|
49
|
-
}
|
|
50
|
-
return undefined;
|
|
51
|
-
}
|
|
52
|
-
export function readExpansion(s, i, word, inDoubleQuotes = false) {
|
|
53
|
-
if (s[i] === "`") {
|
|
54
|
-
word.substitution = true;
|
|
55
|
-
for (let j = i + 1; j < s.length; j += s[j] === "\\" ? 2 : 1)
|
|
56
|
-
if (s[j] === "`")
|
|
57
|
-
return j + 1;
|
|
58
|
-
return undefined;
|
|
59
|
-
}
|
|
60
|
-
let o = i + 1;
|
|
61
|
-
while (s[o] === "\\" && s[o + 1] === "\n")
|
|
62
|
-
o += 2;
|
|
63
|
-
const next = s[o];
|
|
64
|
-
if (next === undefined)
|
|
65
|
-
return i + 1;
|
|
66
|
-
if (next === "(") {
|
|
67
|
-
const end = skipBalanced(s, o, "(", ")");
|
|
68
|
-
if (end === undefined)
|
|
69
|
-
return undefined;
|
|
70
|
-
if (s[i] !== "$" || s[o + 1] !== "(" || arithmeticHidesRun(s.slice(o + 2, end - 2)))
|
|
71
|
-
word.substitution = true;
|
|
72
|
-
return end;
|
|
73
|
-
}
|
|
74
|
-
if (next === "[") {
|
|
75
|
-
const end = s.indexOf("]", o);
|
|
76
|
-
word.substitution = true;
|
|
77
|
-
return end < 0 ? undefined : end + 1;
|
|
78
|
-
}
|
|
79
|
-
if (next === "{") {
|
|
80
|
-
const end = skipBalanced(s, o, "{", "}");
|
|
81
|
-
if (end !== undefined && carriesSubstitution(s.slice(i, end)))
|
|
82
|
-
word.substitution = true;
|
|
83
|
-
return end;
|
|
84
|
-
}
|
|
85
|
-
if (next === "'" && !inDoubleQuotes) {
|
|
86
|
-
let j = o + 1;
|
|
87
|
-
while (j < s.length && s[j] !== "'")
|
|
88
|
-
j += s[j] === "\\" ? 2 : 1;
|
|
89
|
-
return j < s.length ? j + 1 : undefined;
|
|
90
|
-
}
|
|
91
|
-
if (/[A-Za-z_]/.test(next)) {
|
|
92
|
-
let j = o + 1;
|
|
93
|
-
while (j < s.length && /[A-Za-z0-9_]/.test(s[j]))
|
|
94
|
-
j++;
|
|
95
|
-
return j;
|
|
96
|
-
}
|
|
97
|
-
return SPECIAL_PARAMS.includes(next) ? o + 1 : i + 1;
|
|
98
|
-
}
|
|
99
|
-
export function skipBalanced(s, i, open, close) {
|
|
100
|
-
const stack = [];
|
|
101
|
-
for (let j = i; j < s.length; j++) {
|
|
102
|
-
const ch = s[j];
|
|
103
|
-
const top = stack[stack.length - 1];
|
|
104
|
-
if (ch === "\\") {
|
|
105
|
-
j++;
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
if (top?.quote === true) {
|
|
109
|
-
if (ch === '"')
|
|
110
|
-
top.quote = false;
|
|
111
|
-
else if (ch === "$" && (s[j + 1] === "(" || s[j + 1] === "{")) {
|
|
112
|
-
stack.push({ closer: s[j + 1] === "(" ? ")" : "}", quote: false });
|
|
113
|
-
j++;
|
|
114
|
-
}
|
|
115
|
-
else if (ch === "`") {
|
|
116
|
-
const k = s.indexOf("`", j + 1);
|
|
117
|
-
if (k < 0)
|
|
118
|
-
return undefined;
|
|
119
|
-
j = k;
|
|
120
|
-
}
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
if (ch === "'") {
|
|
124
|
-
const k = s.indexOf("'", j + 1);
|
|
125
|
-
if (k < 0)
|
|
126
|
-
return undefined;
|
|
127
|
-
j = k;
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
if (ch === '"') {
|
|
131
|
-
if (top !== undefined)
|
|
132
|
-
top.quote = true;
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
if (ch === "`") {
|
|
136
|
-
const k = s.indexOf("`", j + 1);
|
|
137
|
-
if (k < 0)
|
|
138
|
-
return undefined;
|
|
139
|
-
j = k;
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
if (ch === open || ch === "(" || ch === "{") {
|
|
143
|
-
stack.push({ closer: ch === "(" ? ")" : "}", quote: false });
|
|
144
|
-
continue;
|
|
145
|
-
}
|
|
146
|
-
if (ch === close || ch === ")" || ch === "}") {
|
|
147
|
-
if (stack.pop()?.closer !== ch)
|
|
148
|
-
return undefined;
|
|
149
|
-
if (stack.length === 0)
|
|
150
|
-
return j + 1;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return undefined;
|
|
154
|
-
}
|
|
155
|
-
export function skipHeredocBodies(s, i, docs) {
|
|
156
|
-
let substitution = false;
|
|
157
|
-
for (const { delimiter, quoted, dash } of docs) {
|
|
158
|
-
for (;;) {
|
|
159
|
-
if (i >= s.length)
|
|
160
|
-
return undefined;
|
|
161
|
-
let eol = s.indexOf("\n", i);
|
|
162
|
-
let line = s.slice(i, eol < 0 ? s.length : eol);
|
|
163
|
-
while (!quoted && eol >= 0 && (/\\+$/.exec(line)?.[0].length ?? 0) % 2 === 1) {
|
|
164
|
-
const next = s.indexOf("\n", eol + 1);
|
|
165
|
-
line = line.slice(0, -1) + s.slice(eol + 1, next < 0 ? s.length : next);
|
|
166
|
-
eol = next;
|
|
167
|
-
}
|
|
168
|
-
i = eol < 0 ? s.length : eol + 1;
|
|
169
|
-
if ((dash ? line.replace(/^\t+/, "") : line) === delimiter)
|
|
170
|
-
break;
|
|
171
|
-
if (!quoted && carriesSubstitution(line))
|
|
172
|
-
substitution = true;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return { end: i, substitution };
|
|
176
|
-
}
|
|
177
|
-
export function matchOp(s, i, ops) {
|
|
178
|
-
let best;
|
|
179
|
-
for (const op of ops)
|
|
180
|
-
if (s.startsWith(op, i) && (best === undefined || op.length > best.length))
|
|
181
|
-
best = op;
|
|
182
|
-
return best;
|
|
183
|
-
}
|