@sema-agent/core 7.45.0 → 7.47.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 +298 -1
- package/dist/agents/extra-tool-names.d.ts +65 -0
- package/dist/agents/extra-tool-names.js +124 -0
- package/dist/agents/subagent.d.ts +17 -5
- package/dist/agents/subagent.js +33 -25
- package/dist/agents/tool-filter.d.ts +17 -1
- package/dist/agents/tool-filter.js +7 -0
- package/dist/core/agent-config-dir.d.ts +20 -0
- package/dist/core/agent-config-dir.js +49 -0
- package/dist/core/allow-entry.d.ts +6 -4
- package/dist/core/allow-entry.js +6 -5
- package/dist/core/ask-origin.d.ts +35 -12
- package/dist/core/ask-origin.js +24 -7
- package/dist/core/checkpoint-store.d.ts +39 -2
- package/dist/core/effective-path-target.d.ts +136 -4
- package/dist/core/effective-path-target.js +110 -2
- package/dist/core/engine-notice.d.ts +12 -4
- package/dist/core/gate-fold.js +5 -2
- package/dist/core/gate-lanes.js +11 -4
- package/dist/core/gate-outcome.d.ts +4 -2
- package/dist/core/gate-outcome.js +2 -2
- package/dist/core/governance-codes.d.ts +3 -1
- package/dist/core/governance-codes.js +3 -0
- package/dist/core/hooks.d.ts +3 -0
- package/dist/core/path-rule-binding.d.ts +65 -0
- package/dist/core/path-rule-binding.js +99 -0
- package/dist/core/permission-rule-model.d.ts +59 -24
- package/dist/core/permission-rule-model.js +48 -44
- package/dist/core/permission-rule-provider.d.ts +7 -0
- package/dist/core/permission-rule-provider.js +10 -3
- package/dist/core/permission-rule-store.d.ts +8 -0
- package/dist/core/permission-rule-store.js +6 -2
- package/dist/core/permission-rule-sync.js +2 -2
- package/dist/core/permission-rules.d.ts +26 -45
- package/dist/core/permission-rules.js +77 -57
- package/dist/core/runner/child-tree.d.ts +97 -0
- package/dist/core/runner/child-tree.js +104 -0
- package/dist/core/runner/construction-doors.d.ts +5 -0
- package/dist/core/runner/construction-doors.js +6 -0
- package/dist/core/runner/contracts.d.ts +46 -0
- package/dist/core/runner/gate-exit.d.ts +4 -1
- package/dist/core/runner/gate-exit.js +5 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +34 -25
- package/dist/core/runner/permission-rule-lanes.js +18 -12
- package/dist/core/runner/persisted-path-rows.d.ts +31 -7
- package/dist/core/runner/persisted-path-rows.js +31 -12
- package/dist/core/runner/prepare-ask-lane.d.ts +4 -0
- package/dist/core/runner/prepare-ask-lane.js +4 -2
- package/dist/core/runner/prepare-execution-env.d.ts +5 -2
- package/dist/core/runner/prepare-execution-env.js +10 -3
- package/dist/core/runner/prepare-gate-stations.d.ts +3 -0
- package/dist/core/runner/prepare-gate-stations.js +2 -1
- package/dist/core/runner/prepare-hands-readface.d.ts +8 -4
- package/dist/core/runner/prepare-hands-readface.js +11 -11
- package/dist/core/runner/prepare-inherited-gate.d.ts +8 -1
- package/dist/core/runner/prepare-inherited-gate.js +8 -2
- package/dist/core/runner/prepare-park-ask.d.ts +3 -0
- package/dist/core/runner/prepare-park-ask.js +5 -3
- package/dist/core/runner/prepare-policy-chain.d.ts +14 -2
- package/dist/core/runner/prepare-policy-chain.js +13 -5
- package/dist/core/runner/prepare-suspend-saga.d.ts +10 -0
- package/dist/core/runner/prepare-suspend-saga.js +7 -1
- package/dist/core/runner/prepare-task.js +37 -18
- package/dist/core/runner/prepare-turn-wiring.d.ts +2 -0
- package/dist/core/runner/prepare-turn-wiring.js +2 -1
- package/dist/core/runner/prepare-workspace-restore.d.ts +3 -0
- package/dist/core/runner/prepare-workspace-restore.js +1 -0
- package/dist/core/runner/resume-apply.js +17 -3
- package/dist/core/runner/resume-checkpoint-screen.js +13 -0
- package/dist/core/runner/run-leg.js +5 -1
- package/dist/core/runner/runtask.js +2 -2
- package/dist/core/runner/sub-agent-deny-lists.d.ts +1 -1
- package/dist/core/runner/write-protection-station.d.ts +3 -2
- package/dist/core/runner/write-protection-station.js +1 -0
- package/dist/core/runner-deps.d.ts +14 -0
- package/dist/core/sensitive-path-policy.d.ts +8 -0
- package/dist/core/sensitive-path-policy.js +18 -2
- package/dist/core/shell-wrapper-projection.d.ts +11 -0
- package/dist/core/shell-wrapper-projection.js +56 -0
- package/dist/core/shell-wrapper-table.d.ts +144 -34
- package/dist/core/shell-wrapper-table.js +40 -20
- package/dist/core/synthetic-read-verdict.d.ts +3 -0
- package/dist/core/synthetic-read-verdict.js +3 -1
- package/dist/core/tool-catalog-entries.d.ts +21 -0
- package/dist/core/tool-catalog-entries.js +12 -2
- package/dist/core/tool-face.d.ts +10 -1
- package/dist/core/tool-name-readings.d.ts +8 -0
- package/dist/core/tool-name-readings.js +2 -0
- package/dist/core/tool-policy.d.ts +40 -17
- package/dist/core/tool-policy.js +11 -9
- package/dist/core/tool-registry.d.ts +9 -0
- package/dist/core/tool-registry.js +10 -0
- package/dist/core/tool-spec.d.ts +3 -2
- package/dist/core/write-protect.d.ts +14 -3
- package/dist/core/write-protect.js +41 -10
- package/dist/index.d.ts +6 -4
- package/dist/index.js +5 -3
- package/dist/orchestration/run-spec.js +8 -7
- package/dist/orchestration/workflow.js +1 -1
- package/dist/shell/lex.d.ts +22 -0
- package/dist/shell/lex.js +75 -13
- package/dist/tools/fs/bash-program-position.d.ts +14 -90
- package/dist/tools/fs/bash-program-position.js +41 -74
- package/dist/tools/fs/bash-readonly-classifier.d.ts +17 -444
- package/dist/tools/fs/bash-readonly-classifier.js +169 -1225
- package/dist/tools/fs/index.d.ts +3 -2
- package/dist/tools/fs/program-read-model.d.ts +711 -0
- package/dist/tools/fs/program-read-model.js +1259 -0
- package/dist/tools/fs/program-read-model.rows.d.ts +18 -0
- package/dist/tools/fs/program-read-model.rows.js +624 -0
- package/dist/tools/fs/read-deny-home.d.ts +19 -1
- package/dist/tools/fs/read-deny-home.js +62 -24
- package/dist/tools/fs/read-deny.d.ts +54 -14
- package/dist/tools/fs/read-deny.js +104 -50
- package/dist/tools/fs/removal-targets.d.ts +7 -6
- package/dist/tools/fs/removal-targets.js +34 -24
- package/dist/tools/fs/safety.d.ts +3 -0
- package/dist/tools/fs/safety.js +10 -3
- package/dist/tools/fs/shell-read-argv.d.ts +86 -0
- package/dist/tools/fs/shell-read-argv.js +388 -0
- package/dist/tools/fs/shell-read-bindings.d.ts +300 -0
- package/dist/tools/fs/shell-read-bindings.js +755 -0
- package/dist/tools/fs/shell-read-check.js +23 -15
- package/dist/tools/fs/shell-read-establish.js +82 -8
- package/dist/tools/fs/shell-read-judge.d.ts +11 -1
- package/dist/tools/fs/shell-read-judge.js +9 -1
- package/dist/tools/fs/shell-read-plan.d.ts +33 -8
- package/dist/tools/fs/shell-read-plan.js +309 -407
- package/dist/tools/fs/shell-read-word.d.ts +60 -26
- package/dist/tools/fs/shell-read-word.js +47 -37
- package/dist/tools/fs/shell-read-write-targets.d.ts +15 -64
- package/dist/tools/fs/shell-read-write-targets.js +85 -137
- package/dist/tools/fs/shell-reentry-text.d.ts +136 -6
- package/dist/tools/fs/shell-reentry-text.js +203 -53
- package/dist/tools/monitor.d.ts +3 -3
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +25 -5
- package/wire-changes/core@7.46.0.json +1522 -0
- package/wire-changes/core@7.47.0.json +412 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type LexedCommand, type LexedSegment, type LexedWord, type ShellLex, type ShellSegmentConnector, type WordPiece } from "../../shell/lex.js";
|
|
2
|
+
import { type ProgramRow } from "./program-read-model.js";
|
|
2
3
|
/**
|
|
3
4
|
* Bare command names `bash_readonly` permits out of the box, ALSO the default reversible set for the
|
|
4
5
|
* The {@link import("./fs-bash.js").bashReversibilityProbe} classifier. **Coarse first filter, NOT a security
|
|
@@ -22,8 +23,8 @@ import { type LexedCommand, type LexedSegment, type LexedWord, type ShellLex, ty
|
|
|
22
23
|
* no change on this face) that satisfy THIS list's curation bar (no write/mutation mode under any args)
|
|
23
24
|
* without new stdin-floor/option-value modeling: pure status/computation printers (`cal`…`sleep` — none
|
|
24
25
|
* reads stdin when bare, none takes a path it READS except realpath/readlink, which stay boundary-judged)
|
|
25
|
-
* plus the floor-2 content comparers `diff`/`cmp`/`comm` (
|
|
26
|
-
* recursive form was already
|
|
26
|
+
* plus the floor-2 content comparers `diff`/`cmp`/`comm` (their rows state the floor of 2 operands; diff's
|
|
27
|
+
* recursive form was already a traversal row of the program read model). Still deliberately excluded, each for a
|
|
27
28
|
* stated reason: `env` (an executor: `env FOO=1 cmd` runs cmd — CC excludes it too), `sort` (`-o` writes),
|
|
28
29
|
* `uniq` (second positional is an OUTPUT file; CC allows a flags-only regex form this filter cannot
|
|
29
30
|
* express), `printf` (builtin `-v var` assigns), `find` (CC allows only a regex excluding
|
|
@@ -156,7 +157,7 @@ export interface StrictResidualOptions {
|
|
|
156
157
|
/** Only the two data-free spellings pass ({@link isDataFreeRedirection}); every other redirection refuses. */
|
|
157
158
|
readonly dataFreeRedirections?: boolean;
|
|
158
159
|
/** The declared home: a word that spells it ({@link homeExpansionOf}) is not an expansion to refuse — unless the
|
|
159
|
-
* command may rebind `HOME` ({@link
|
|
160
|
+
* command may rebind `HOME` ({@link textBindsHome}), which makes the declared home a guess. */
|
|
160
161
|
readonly homeDir?: string;
|
|
161
162
|
}
|
|
162
163
|
/**
|
|
@@ -294,8 +295,8 @@ export interface BashReadonlyRootBoundary {
|
|
|
294
295
|
* only, no ancestor intersection: the judge sees the operand's own resolved spelling, never its subtree.
|
|
295
296
|
* The RECURSIVE-reach half of ① is narrowed — a listed recursive verb's path operand under this wired
|
|
296
297
|
* seat rides {@link CompoundReadonlyVerdict.recursiveReadPaths} (⊂ undecidedPaths), so `grep -r x ~/` no
|
|
297
|
-
* longer auto-allows; what REMAINS is the
|
|
298
|
-
*
|
|
298
|
+
* longer auto-allows; what REMAINS is the traversal rows' stated open set (the KNOWN OPEN SET note at
|
|
299
|
+
* the program read model's traversal rows: a traversal verb absent there that a deployment allowlists classifies by
|
|
299
300
|
* its ordinary form and can auto-run a traversal unjudged). ② LEXICAL only HERE — an in-root symlink
|
|
300
301
|
* whose target is guarded reads as its innocent spelling at this seat, as it does for the containment
|
|
301
302
|
* half, because the classify auto-allow lane has no I/O seat by contract; the CANONICAL view is judged by
|
|
@@ -346,31 +347,6 @@ export interface CompoundReadonlyVerdict {
|
|
|
346
347
|
* uses the host's native separator.
|
|
347
348
|
*/
|
|
348
349
|
export declare function formatOutOfRootReadApprovalOption(directory: string): string;
|
|
349
|
-
/** Programs whose operands are NEVER filesystem paths, so no operand of theirs is checked:
|
|
350
|
-
* `echo`'s words are literal text, `which`'s are PATH lookups, `tr`'s are character sets, and
|
|
351
|
-
* `basename`/`dirname` do pure string surgery on a path without ever opening it. Everything else —
|
|
352
|
-
* including a deployment-widened name this file does not know — goes through the path-shaped
|
|
353
|
-
* operand scan below, which is safe for an unknown command because a bare word can only ever name
|
|
354
|
-
* something under the working directory. */
|
|
355
|
-
export declare const NO_PATH_OPERAND_COMMANDS: ReadonlySet<string>;
|
|
356
|
-
/** The no-path-operand programs that EVALUATE a word (`test -v 'a[$(…)]'` runs the substitution in the subscript): a word
|
|
357
|
-
* the shell or that evaluation rewrites is handed over as any program's is; only their settled words name nothing. */
|
|
358
|
-
export declare const NO_PATH_OPERAND_EVALUATORS: ReadonlySet<string>;
|
|
359
|
-
/** The builtins whose `NAME=value` arguments are assignments bash performs (and exports, for `export`), never paths. */
|
|
360
|
-
export declare const DECLARATION_BUILTINS: ReadonlySet<string>;
|
|
361
|
-
/** The shell BUILTINS that open no file, start no program and evaluate nothing: an external program's loader reads its
|
|
362
|
-
* environment (`LD_PRELOAD` for `sleep`), `printf` reads `TZ` for `%(…)T` and assigns through `-v`, `test -v` and an
|
|
363
|
-
* array subscript evaluate arithmetic (which runs a `$(…)` inside it). A declaration builtin counts only bare — no option
|
|
364
|
-
* word (`-i` evaluates the value) — and every inert segment's words carry no `[` `]` `$` or backquote. */
|
|
365
|
-
export declare const INERT_BUILTINS: ReadonlySet<string>;
|
|
366
|
-
/** The indices of the SETTLED words a {@link MESSAGE_SLOTS} row reads as message text under the subcommand's grammar:
|
|
367
|
-
* the value of `-m` (attached, or the next word) or of `--message` (`=`, or the next word; an unambiguous prefix of it
|
|
368
|
-
* counts). A word the shell rewrites is never claimed, and neither is any word another option consumes — those words
|
|
369
|
-
* stay the verb-blind walk's. */
|
|
370
|
-
export declare function messageSlotWords(program: string, words: readonly {
|
|
371
|
-
readonly folded: string;
|
|
372
|
-
readonly expands: unknown;
|
|
373
|
-
}[], programIndex: number): Set<number>;
|
|
374
350
|
/** True for a token that can denote a filesystem location OUTSIDE the working directory. A bare word
|
|
375
351
|
* (`foo`, `a.txt`, a grep pattern, an awk program) cannot: with no separator and no `..` it always
|
|
376
352
|
* resolves under the cwd, which the caller's cwd governance already covers.
|
|
@@ -427,13 +403,6 @@ export interface OperandSpellings {
|
|
|
427
403
|
/** Resolve one operand into {@link OperandSpellings}, or `undefined` on the same unresolvable operands
|
|
428
404
|
* {@link resolveOperandLexically} reports (it is this function's folded half). */
|
|
429
405
|
export declare function resolveOperandSpellings(base: string | undefined, operand: string, homeDir: string | undefined): OperandSpellings | undefined;
|
|
430
|
-
/** Programs that run their argument AS SHELL TEXT (the sh family, `eval`, `source`, `.`): what they read is decided
|
|
431
|
-
* by text nobody here parsed. Spelled as a pattern, not a name list — these are program names, never tool names.
|
|
432
|
-
* The prefix alternation is the SPELLINGS of the shell, not a curated subset of them: the Almquist shell and
|
|
433
|
-
* its descendants (`ash`, `mksh`, `yash`, `pdksh`) and the C shell family (`csh`, `tcsh`) all run `-c` text
|
|
434
|
-
* exactly as `sh` does, and a deployment that meets one of them meets the whole member. GNU `parallel` is a member
|
|
435
|
-
* for the reason it is not a launcher: it hands a BUILT command line to a shell. */
|
|
436
|
-
export declare const SHELL_REENTRY_PROGRAM_RE: RegExp;
|
|
437
406
|
/**
|
|
438
407
|
* Does the shell REWRITE this word before the program sees it — a brace list, a parameter, command, process or
|
|
439
408
|
* arithmetic expansion, or a `$` / backtick / brace character where bash reads it (unquoted; `$` and a backtick
|
|
@@ -444,7 +413,8 @@ export declare const SHELL_REENTRY_PROGRAM_RE: RegExp;
|
|
|
444
413
|
* has no filesystem), such a word is declared unresolvable — the direction the whole file errs in.
|
|
445
414
|
*
|
|
446
415
|
* Deliberately NOT here: the GLOB characters ({@link globInWord}) — a glob only ever names entries of a
|
|
447
|
-
* directory that is already on the command line — and a tilde, which the resolver reads.
|
|
416
|
+
* directory that is already on the command line — and a tilde, which the resolver reads. A bracket expression whose
|
|
417
|
+
* body carries an expansion (`[$x]`, `[$(…)]`: bash expands the members before it matches) IS here.
|
|
448
418
|
*/
|
|
449
419
|
export declare function expansionInWord(w: {
|
|
450
420
|
readonly pieces: readonly WordPiece[];
|
|
@@ -458,250 +428,6 @@ export declare function expansionInWord(w: {
|
|
|
458
428
|
export declare function globInWord(w: {
|
|
459
429
|
readonly pieces: readonly WordPiece[];
|
|
460
430
|
}): boolean;
|
|
461
|
-
/**
|
|
462
|
-
* Does this token supply the verb's FIRST-OPERAND slot, so that the first operand is a FILE rather than the
|
|
463
|
-
* slot ({@link VerbOptionSlots.firstOperand})? One reader, every verb with such a row.
|
|
464
|
-
*
|
|
465
|
-
* Read over the whole leading letter RUN, not a prefix: GNU clusters short options (`-if` is `-i -f`) and a
|
|
466
|
-
* prefix reading left the slot to swallow — and therefore skip — a real file operand. Digits belong to the run
|
|
467
|
-
* (grep's obsolete numeric context spec: `-2ebeta` is `-C2 -e beta`), and a long option is matched as an
|
|
468
|
-
* ABBREVIATION of the declared name (`grep --reg=X <outside>` is `--regexp`). Over-triggering is harmless in
|
|
469
|
-
* the direction that matters: a token wrongly counted here makes the first operand a CHECKED path candidate.
|
|
470
|
-
*/
|
|
471
|
-
export declare function suppliesFirstOperandSlot(slot: NonNullable<VerbOptionSlots["firstOperand"]>, tok: string): boolean;
|
|
472
|
-
/**
|
|
473
|
-
* WHAT ONE OPTION'S VALUE IS, per verb — the one declaration every reader of an option token shares.
|
|
474
|
-
*
|
|
475
|
-
* The question asked of a value is always "can this name a file?", and the answer is a property of the
|
|
476
|
-
* OPTION and its own grammar, never of the value's shape: `sed -e 's/a/b/'` and `sed -f s.sed` differ in
|
|
477
|
-
* nothing a shape test can see. The kinds spell that answer out per slot so a row is auditable letter by
|
|
478
|
-
* letter, and {@link slotValueCandidates} is where every consumer gets it — a kind that cannot name a
|
|
479
|
-
* file yields nothing there, which is the same answer as "this value named none".
|
|
480
|
-
*/
|
|
481
|
-
export type OptionValueKind = "path" | "indirect" | "pattern" | "script" | "count" | "delimiter" | "name-pattern" | "form" | "header" | "url" | "label";
|
|
482
|
-
/**
|
|
483
|
-
* One verb's option grammar: which short letters and long names take a VALUE, and what that value is.
|
|
484
|
-
*
|
|
485
|
-
* FAIL-SAFE BY CONSTRUCTION, which is what makes a PARTIAL row sound: the reader must account for every
|
|
486
|
-
* option character it walks, so the first character a row does not declare ends the reading as
|
|
487
|
-
* `unexplained` and hands the token back to the verb-blind payload scan ({@link attachedOptionPayloads})
|
|
488
|
-
* — today's over-approximation, unchanged. A row therefore only ever makes an answer MORE precise where
|
|
489
|
-
* it recognizes the option; omitting one costs precision, never a judgement.
|
|
490
|
-
*
|
|
491
|
-
* THREE ARITIES, because `getopt_long` has three. An option that takes no value, one that requires a
|
|
492
|
-
* value (attached or the next token), and one whose value is OPTIONAL — and the third is not the second
|
|
493
|
-
* with a caveat: `getopt_long` gives an optional value NO separated spelling, so `diff --unified a b`
|
|
494
|
-
* hands diff two FILES while `diff --unified=3 a b` hands it a width. A row that files an optional-value
|
|
495
|
-
* option under {@link VerbOptionSlots.longValue} therefore eats `a`, and the file operand it swallowed
|
|
496
|
-
* is judged by nobody — the one direction this table may never move. They go in
|
|
497
|
-
* {@link VerbOptionSlots.longOptionalValue}, which reads the attached spelling and consumes nothing in
|
|
498
|
-
* the separated one. A short letter whose value is optional (`sed -i[SUFFIX]`) is left out of BOTH short
|
|
499
|
-
* maps for the same reason: an optional value can only ever be attached, and the blind scan is the safe
|
|
500
|
-
* reading of a token this row will not explain.
|
|
501
|
-
*
|
|
502
|
-
* WHAT A ROW MAY NOT GET WRONG, stated as the rule for adding one: declaring a FILE-valued option
|
|
503
|
-
* as something else hides a read, and so does declaring an OPTIONAL-value option as a required one —
|
|
504
|
-
* the value it eats in the separated spelling is a file operand. Declaring a value-taking option as
|
|
505
|
-
* plain is safe (the reading ends unexplained at its value), and declaring the non-file slots is what
|
|
506
|
-
* removes the phantom candidates a blind split invents — admitting one more option character moves the
|
|
507
|
-
* split right, and a split that lands on a `/` manufactures an absolute path the command never names.
|
|
508
|
-
*
|
|
509
|
-
* AND A ROW IS ABOUT A NAME, WHICH TWO IMPLEMENTATIONS MAY NOT SPELL ALIKE. `sed -l` takes a required
|
|
510
|
-
* line length in one widely deployed sed and NO value in another; `grep --context` is optional in one
|
|
511
|
-
* and required in another; and the engine runs whichever the host ships. A disputed arity is resolved
|
|
512
|
-
* towards the reading that CONSUMES NOTHING, because only consuming can swallow a file operand: a
|
|
513
|
-
* disputed LONG name is filed as optional-value (right under one reading, merely imprecise under the
|
|
514
|
-
* other), and a disputed SHORT letter is left out of both short maps, since the short maps have no way
|
|
515
|
-
* to say "attached only". Where implementations disagree about a value's KIND rather than its arity,
|
|
516
|
-
* the file-naming reading is the one to declare — over-approximating a value costs an ask and
|
|
517
|
-
* under-approximating one costs the read. Every row here is checked against the binaries this
|
|
518
|
-
* repository's own tools run on; a row added from a manual page alone is a guess.
|
|
519
|
-
*
|
|
520
|
-
* AND A ROW APPLIES WHILE THE COMMAND IS STILL IN ITS OPTION SECTION. POSIX ends option parsing at the
|
|
521
|
-
* first operand, GNU permutes, and a transfer program parses its own options anywhere — so once the
|
|
522
|
-
* operands have begun, whether a dash-leading token is an option at all is implementation-dependent and
|
|
523
|
-
* BOTH readings are taken: the token is not consumed (it is judged as the operand it may be) and the
|
|
524
|
-
* slot's candidates are judged too (it may name a file). Adding a candidate is always safe; consuming
|
|
525
|
-
* is what hides one.
|
|
526
|
-
*
|
|
527
|
-
* @contract shell.read_boundary.option_value_slots — where this table declares a verb's option, the
|
|
528
|
-
* read boundary reads that option's value from the DECLARED slot and nowhere else: a slot that can name
|
|
529
|
-
* a file yields exactly its value as a path candidate (an `indirect` slot also yields what the value
|
|
530
|
-
* names past its `@`, a `header` slot only for a whole-value `@<file>`, and a `url` slot the local path
|
|
531
|
-
* a `file:` URL names), and a slot that cannot yields none — the attached and separated spellings of one
|
|
532
|
-
* option read the same row and can never disagree, except where the row declares the value OPTIONAL,
|
|
533
|
-
* which has no separated spelling at all. Past the command's first operand the separated spelling
|
|
534
|
-
* consumes nothing and its value is judged BOTH as that value and as an operand, because which of the
|
|
535
|
-
* two it is, is implementation-dependent. Where it declares nothing — no row for the verb, an
|
|
536
|
-
* option character the row does not account for, a long-option prefix whose reachable names leave this
|
|
537
|
-
* spelling's value unsettled —
|
|
538
|
-
* the verb-blind payload scan judges the token exactly as it did before, so an absent or partial row
|
|
539
|
-
* costs precision and never a judgement. A row is DATA about a PROGRAM and not about the read-only
|
|
540
|
-
* allowlist: it says what that program does with its own argument, never that the program may be read
|
|
541
|
-
* from, and it grants no per-verb arm to a program a deployment has not listed.
|
|
542
|
-
*/
|
|
543
|
-
export interface VerbOptionSlots {
|
|
544
|
-
/** Short letters whose value is the rest of the token, or the NEXT token when the letter ends it. */
|
|
545
|
-
readonly shortValue: Readonly<Record<string, OptionValueKind>>;
|
|
546
|
-
/** Short letters taking no value. */
|
|
547
|
-
readonly shortPlain: string;
|
|
548
|
-
/** Long option FULL names whose value is `=<value>` or the next token. */
|
|
549
|
-
readonly longValue: Readonly<Record<string, OptionValueKind>>;
|
|
550
|
-
/** Long option FULL names whose value exists ONLY as `=<value>`: `getopt_long`'s `optional_argument`,
|
|
551
|
-
* which never reaches for the next token. Reading one of these as {@link longValue} would consume the
|
|
552
|
-
* operand that follows the bare spelling, so the operand goes unjudged — see the THREE ARITIES note. */
|
|
553
|
-
readonly longOptionalValue: Readonly<Record<string, OptionValueKind>>;
|
|
554
|
-
/** Long option FULL names taking no value — declared so that an abbreviation reaching one is seen to be
|
|
555
|
-
* ambiguous rather than read as its value-taking neighbour. */
|
|
556
|
-
readonly longPlain: readonly string[];
|
|
557
|
-
/** SINGLE-dash WORD options — a grammar getopt does not have and a cluster walk cannot read: `-name` is not
|
|
558
|
-
* `-n -a -m -e`, and splitting it that way manufactures a path candidate per suffix. Asked before the cluster
|
|
559
|
-
* walk, only for a dash plus MORE THAN ONE character; a name in neither map falls to the verb-blind scan. */
|
|
560
|
-
readonly dashWordValue?: Readonly<Record<string, OptionValueKind>>;
|
|
561
|
-
/** The value-less half of {@link dashWordValue}. */
|
|
562
|
-
readonly dashWordPlain?: readonly string[];
|
|
563
|
-
/** The FIRST positional operand, where this verb's grammar gives it a meaning that is NOT a file: grep's
|
|
564
|
-
* PATTERN, sed's SCRIPT. Read with the same {@link OptionValueKind} vocabulary the option slots use, so
|
|
565
|
-
* {@link slotValueCandidates} answers "can this word name a file" once for both spellings — `sed -e '/x/p' f`
|
|
566
|
-
* and `sed '/x/p' f` are one invocation and were two readings. `suppliedBy*` name the options that deliver
|
|
567
|
-
* the slot instead, leaving the first operand a file after all. No row ⇒ an ordinary first operand. */
|
|
568
|
-
readonly firstOperand?: {
|
|
569
|
-
readonly kind: OptionValueKind;
|
|
570
|
-
/** Short letters, matched inside a cluster and with digits allowed in front (grep's obsolete numeric
|
|
571
|
-
* context spec: `-2ebeta` is `-C2 -e beta`). */
|
|
572
|
-
readonly suppliedByLetters: string;
|
|
573
|
-
/** Long option FULL names; an abbreviation reaching one counts ({@link isLongOptionAbbrevOf}). */
|
|
574
|
-
readonly suppliedByLongNames: readonly string[];
|
|
575
|
-
};
|
|
576
|
-
/** This program parses its options WHEREVER they appear, so the permute ambiguity the both-readings rule
|
|
577
|
-
* below answers (POSIX/GNU/BSD disagree whether a dash-token past the first operand is still an option) does
|
|
578
|
-
* not exist for it. Declared only where the program's manual states the grammar, and never to rescue a
|
|
579
|
-
* spelling into auto-allow: a token the row does not explain still goes to the verb-blind scan. */
|
|
580
|
-
readonly optionsArePositionIndependent?: true;
|
|
581
|
-
}
|
|
582
|
-
/** What one row makes of ONE option token. `unexplained` = the row cannot account for the token, and the
|
|
583
|
-
* caller reads it the verb-blind way it always did. */
|
|
584
|
-
export type VerbOptionSlotReading = {
|
|
585
|
-
readonly form: "unexplained";
|
|
586
|
-
} | {
|
|
587
|
-
readonly form: "no-value";
|
|
588
|
-
} | {
|
|
589
|
-
readonly form: "attached";
|
|
590
|
-
readonly value: string;
|
|
591
|
-
readonly kind: OptionValueKind;
|
|
592
|
-
} | {
|
|
593
|
-
readonly form: "separated";
|
|
594
|
-
readonly kind: OptionValueKind;
|
|
595
|
-
};
|
|
596
|
-
/**
|
|
597
|
-
* Read one option token of `name` through its row. `undefined` ⇒ this verb has no row.
|
|
598
|
-
*
|
|
599
|
-
* Short form is getopt: scanning the cluster left to right, the FIRST value-taking letter owns the
|
|
600
|
-
* remainder of the token, or the next token when it ends there. Long form is `getopt_long`'s
|
|
601
|
-
* unambiguous-prefix rule with an EXACT name resolved first; a prefix reaching several names is settled
|
|
602
|
-
* only where they agree about what THIS spelling does with its value, which is one question for an
|
|
603
|
-
* attached `=value` (can it name a file?) and two for a separated one (does the option take the next
|
|
604
|
-
* token at all?) — see the branch below.
|
|
605
|
-
*
|
|
606
|
-
* An unsettled prefix falls back rather than guessing, because skipping a value that is really a FILE
|
|
607
|
-
* hides a read: the verb-blind scan that judges every suffix is the safe answer to "this row does not
|
|
608
|
-
* know". That direction is why this reading is NOT the stdin floor's ({@link SEPARATED_VALUE_OPTIONS}),
|
|
609
|
-
* which asks a different question — does this value fill one of the SLOTS the floor counts — and answers
|
|
610
|
-
* it in the other direction. Measured rather than argued: reading the floor off this table moved twelve
|
|
611
|
-
* of its verdicts, eight of them wrongly (`grep -e pat file` blocks on nothing, and its pattern value is
|
|
612
|
-
* exactly what makes grep's floor of two `<pattern> <file>`).
|
|
613
|
-
*/
|
|
614
|
-
export declare function readVerbOptionSlot(name: string, tok: string): VerbOptionSlotReading | undefined;
|
|
615
|
-
/** Does this verb's row declare that its options are parsed WHEREVER they appear — i.e. that the permute
|
|
616
|
-
* ambiguity the both-readings rule answers does not exist for it? See
|
|
617
|
-
* {@link VerbOptionSlots.optionsArePositionIndependent}. */
|
|
618
|
-
export declare function verbOptionsArePositionIndependent(name: string): boolean;
|
|
619
|
-
/** The verb's first-operand slot row, for a reader outside this module that walks operands with the same tables. */
|
|
620
|
-
export declare function verbFirstOperandSlot(name: string): VerbOptionSlots["firstOperand"];
|
|
621
|
-
/**
|
|
622
|
-
* The path candidates one DECLARED value offers, which is also the answer to "did this value name a
|
|
623
|
-
* file?" — an empty list IS the no.
|
|
624
|
-
*
|
|
625
|
-
* Three readings, one per grammar the declared slots have: a value that always names a file offers
|
|
626
|
-
* itself; an `indirect` one may name a file either way, so it offers itself AND what it names past an
|
|
627
|
-
* `@`; and a `header` names a file ONLY as a whole-value `@<file>` — `curl -H 'X: /etc/x'` sends that
|
|
628
|
-
* text and opens nothing, while `curl -H @<file>` adds a header per line of the file (measured against
|
|
629
|
-
* the binary, both directions). Reading `header` the `indirect` way would refuse a header whose text
|
|
630
|
-
* merely looks like a path; reading it as a non-file kind hides the `@` spelling, which is the direction
|
|
631
|
-
* that may not be taken.
|
|
632
|
-
*/
|
|
633
|
-
export declare function slotValueCandidates(value: string, kind: OptionValueKind): string[];
|
|
634
|
-
/**
|
|
635
|
-
* The per-command model of RECURSIVE/EXPANDING read forms: invocations that read the
|
|
636
|
-
* SUBTREE of a path operand, not the operand itself. Consumed by {@link collectSegmentBoundaryFindings}
|
|
637
|
-
* only when a {@link BashReadonlyRootBoundary.denyMatch} seat is wired and has entries to apply (see
|
|
638
|
-
* {@link CompoundReadonlyVerdict.recursiveReadPaths} for the contract and why the deny seat is the
|
|
639
|
-
* trigger), and then only for the rows whose {@link RecursiveReadFormModel.discloses} column reads
|
|
640
|
-
* "contents". The reference implementation draws the same line as a verb set: its recursive-reach breaker
|
|
641
|
-
* fires for `grep`/`egrep`/`fgrep`/`rg`/`diff` (plus two copy verbs a WRITE face answers for here) and for no
|
|
642
|
-
* name that merely lists a tree; `tar` is a contents row here and absent there, because that implementation
|
|
643
|
-
* ships no built-in deny table and this one does.
|
|
644
|
-
*
|
|
645
|
-
* Membership covers every {@link BASH_READONLY_DEFAULT_ALLOW} verb with a recursive form, PLUS the
|
|
646
|
-
* common tree-reading verbs a deployment plausibly widens its allowlist with (`find`, `rg`, …): the
|
|
647
|
-
* allow set is a caller parameter, and a table pinned to the default list would silently go blind the
|
|
648
|
-
* day a deployment adds `rg` — whose recursion needs no flag at all. A widened verb this table does
|
|
649
|
-
* not know stays name-only classified (recorded residual: the deployment owns that widening, same
|
|
650
|
-
* posture as the allowlist's own header note).
|
|
651
|
-
*
|
|
652
|
-
* DIRECTION. Detection over-approximates deliberately: a flag mis-read as recursive costs one ask on
|
|
653
|
-
* a command that is usually a real-getopt error anyway (`grep -dr …` — ambiguous enum value), while an
|
|
654
|
-
* under-read auto-allows a traversal the deny judge never saw — the leaking direction. The cluster
|
|
655
|
-
* walk therefore honours getopt value-owner semantics ONLY where skipping prevents a false fire on a
|
|
656
|
-
* value AND the ownership holds on every supported implementation (`grep -eRfoo` is a pattern under
|
|
657
|
-
* GNU and BSD alike), never to rescue a spelling into auto-allow — a letter whose ownership DIVERGES
|
|
658
|
-
* across implementations is not modeled at all (see the `ls` row), because a scan stopped on the
|
|
659
|
-
* wrong platform's table is an auto-allowed real traversal.
|
|
660
|
-
*/
|
|
661
|
-
export interface RecursiveReadFormModel {
|
|
662
|
-
/** What the traversal puts in front of the CALLER: the file CONTENTS it walked over, or only their
|
|
663
|
-
* NAMES and sizes. The demotion arm reads "contents" rows only — the deny judge cannot pre-check a
|
|
664
|
-
* subtree, and handing back the bytes it guards is the hazard; handing back names is a different
|
|
665
|
-
* disclosure with a different answer. WHERE THE BYTES GO is part of the question and not always a
|
|
666
|
-
* property of the verb (`tar -cf -` writes the archive to stdout), and reading that per invocation is a
|
|
667
|
-
* per-program option model this zero-IO pass does not carry — so an ambiguous row resolves demote-ward,
|
|
668
|
-
* as every ambiguity here does. A "names" row's other fields have no behavioural consumer today; the
|
|
669
|
-
* row stays because it is a DECISION, and a verb deleted from this table reads as one nobody made. */
|
|
670
|
-
readonly discloses: "contents" | "names";
|
|
671
|
-
/** The verb's ordinary operation IS a tree walk — every invocation with a path operand recurses,
|
|
672
|
-
* no flag required (`du`, `find`, `rg`, `tree`, `ag`, `ack`). */
|
|
673
|
-
readonly always?: true;
|
|
674
|
-
/** Short option letters selecting recursion, judged over the getopt option-letter run. */
|
|
675
|
-
readonly shortLetters?: string;
|
|
676
|
-
/** Value-taking short letters: the FIRST one hit owns the token remainder (or, when it ends the
|
|
677
|
-
* token, the next token) — letters inside that value are not options and must not fire. List a
|
|
678
|
-
* letter ONLY when it takes a value on EVERY supported implementation (GNU and BSD): stopping the
|
|
679
|
-
* scan on one platform's table is an under-read on the other, the leaking direction. */
|
|
680
|
-
readonly valueOwners?: string;
|
|
681
|
-
/** Long option names selecting recursion, abbreviation-aware ({@link isLongOptionAbbrevOf} — an
|
|
682
|
-
* abbreviation real getopt_long would call ambiguous over-fires into an ask, the safe side). */
|
|
683
|
-
readonly longNames?: readonly string[];
|
|
684
|
-
/** Enum-valued options where one VALUE selects recursion (grep's `-d recurse` /
|
|
685
|
-
* `--directories=recurse`). The value is matched as a CASE-FOLDED unambiguous-prefix
|
|
686
|
-
* over-approximation: GNU argmatch accepts prefixes, and BSD grep accepts the value
|
|
687
|
-
* case-insensitively (`-d RECURSE` recurses — verified on the real binary), so
|
|
688
|
-
* both laxities fold in. A spelling only one implementation accepts over-fires on the other
|
|
689
|
-
* into an ask on an erroring command — the required side. */
|
|
690
|
-
readonly enumOptions?: readonly {
|
|
691
|
-
shortLetter?: string;
|
|
692
|
-
longName?: string;
|
|
693
|
-
recursiveValue: string;
|
|
694
|
-
}[];
|
|
695
|
-
/** tar's traditional dash-less FIRST-operand key word (`tar cf out.tar dir`, the "old option
|
|
696
|
-
* style" in tar's own manual): mode letters found there select recursion exactly as their dashed
|
|
697
|
-
* spellings do. */
|
|
698
|
-
readonly bundledModeLetters?: string;
|
|
699
|
-
/** `true` when a bare `-` operand denotes STDIN for this command (content readers: grep's file
|
|
700
|
-
* slot, diff, tar's `-f -`). Absent ⇒ `-` is an ordinary filename (ls/du/find/tree have no stdin
|
|
701
|
-
* sense) and stays a positional operand for the recursion demotion. */
|
|
702
|
-
readonly dashIsStdin?: boolean;
|
|
703
|
-
}
|
|
704
|
-
export declare const RECURSIVE_READ_FORMS: Readonly<Record<string, RecursiveReadFormModel>>;
|
|
705
431
|
/**
|
|
706
432
|
* Read ONE sed script and answer whether it can name a file or run a command.
|
|
707
433
|
*
|
|
@@ -723,133 +449,11 @@ export interface SedScriptNames {
|
|
|
723
449
|
* in the command (one reading), or no reading could parse it to its end. Absent when every name is listed. */
|
|
724
450
|
readonly unread?: string;
|
|
725
451
|
}
|
|
726
|
-
/**
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
730
|
-
|
|
731
|
-
* refuses; a script no reading could SEE refuses, because file-supplied program text may carry anything;
|
|
732
|
-
* and a script no reading could finish refuses. A reading that lands on a clean script is what clears the
|
|
733
|
-
* invocation — which is what keeps the everyday spellings, whose other reading lands on a plain file name,
|
|
734
|
-
* at their old verdict.
|
|
735
|
-
*/
|
|
736
|
-
/** Every file and command line a sed invocation's script slot names, under BOTH option dialects (the union,
|
|
737
|
-
* deduplicated): what a candidate extraction hands the read judge (`reads`), the write face (`writes`) and a
|
|
738
|
-
* nested plan (`commands`). A reading that saw no text names nothing here — that fact rides the verdict face. */
|
|
739
|
-
export declare function sedScriptSlotFiles(args: readonly string[]): SedScriptNames;
|
|
740
|
-
/**
|
|
741
|
-
* How an INTERPRETER receives the program it runs, declared per interpreter rather than guessed.
|
|
742
|
-
*
|
|
743
|
-
* The member that completes the ARGUMENT-AS-PROGRAM family. An interpreter's program can arrive three
|
|
744
|
-
* ways: as an OPTION's value (`perl -e '...'`, `python3 -c '...'`, `node --eval '...'`), as the first
|
|
745
|
-
* OPERAND (the awk family, whose program is mandatory and is not a file unless `-f` named one), or on
|
|
746
|
-
* STANDARD INPUT when the command line names none at all. Only the third and the first are this arm's
|
|
747
|
-
* business together with the second; a program named as a FILE operand (`perl x.pl`, `python3 app.py`)
|
|
748
|
-
* is a path the ordinary operand walk already judges, and stays exactly where it was.
|
|
749
|
-
*
|
|
750
|
-
* WHAT IS JUDGED IS THE PRESENCE OF PROGRAM TEXT, NEVER ITS CONTENT. A quoted program is ONE word to
|
|
751
|
-
* this file's lexer and its contents are never parsed — so the answer cannot be "does this program read
|
|
752
|
-
* a file", only "is there a program this walk did not read". That is why the everyday harmless
|
|
753
|
-
* spellings (`node -e 'console.log(1)'`) refuse along with the rest: telling them apart needs a parser
|
|
754
|
-
* per language, which is exactly the thing a lexical floor must not grow.
|
|
755
|
-
*
|
|
756
|
-
* A row is DATA, so a further interpreter is a row rather than a branch, and a versioned spelling
|
|
757
|
-
* (`python3.11`, `perl5.36`, `tclsh8.6`) is the same row via {@link interpreterKey}.
|
|
758
|
-
*/
|
|
759
|
-
export interface InlineProgramModel {
|
|
760
|
-
/** Options whose value is program TEXT, separated (`--eval prog`) or fused (`--eval=prog`). Matched on
|
|
761
|
-
* the whole token, so a single-dash long option (`-cmd`) is one of these rather than a letter bundle. */
|
|
762
|
-
readonly longText: ReadonlySet<string>;
|
|
763
|
-
/** Options whose value NAMES the program (a script file, or a module the interpreter resolves). */
|
|
764
|
-
readonly longFile: ReadonlySet<string>;
|
|
765
|
-
/** Options that NAME the program while taking NO value of their own — a mode that selects what runs
|
|
766
|
-
* (`node --test` runs the test files it discovers, and reads no program from its input). */
|
|
767
|
-
readonly longNamesProgram: ReadonlySet<string>;
|
|
768
|
-
/** Options whose value is a file the interpreter reads BESIDE the program it is given — an
|
|
769
|
-
* initialization script, a library to preload. Their value is consumed so it is not counted as an
|
|
770
|
-
* operand, and they do NOT name the program: what follows still has to. */
|
|
771
|
-
readonly longSupplemental: ReadonlySet<string>;
|
|
772
|
-
/** Options whose value is the NEXT token and means none of the above. */
|
|
773
|
-
readonly longValue: ReadonlySet<string>;
|
|
774
|
-
/** Long options this row declares to take NO value. Declaring them is what keeps an invocation
|
|
775
|
-
* EXPLAINED past them, so a later script operand still ends the interpreter's own option scanning. */
|
|
776
|
-
readonly longPlain: ReadonlySet<string>;
|
|
777
|
-
/** Whether an option that NAMES the program also ends this interpreter's option processing, because
|
|
778
|
-
* what follows is the named program's own argument list (`python3 -m <module> -c` passes `-c` to the
|
|
779
|
-
* module). False where a named source is PRELIMINARY and further sources still follow (`dc -f <file>
|
|
780
|
-
* -e '<program>'` runs both). */
|
|
781
|
-
readonly fileOptionEndsOptions: boolean;
|
|
782
|
-
/** Short-option letters that introduce program text — alone (`-e prog`), fused (`-eprog`) or inside a
|
|
783
|
-
* bundle (`-pe`, `-lne`, `-uc`, `-0777e`). */
|
|
784
|
-
readonly textLetters: string;
|
|
785
|
-
/** Short-option letters whose value names the program (`-f prog.awk`, `-fprog.awk`, `-m <module>`). */
|
|
786
|
-
readonly fileLetters: string;
|
|
787
|
-
/** Short-option letters whose value is the rest of the token, or the NEXT token when the token ends on
|
|
788
|
-
* them (`perl -I lib`). The bundle scan stops there — what follows in the token is that value. */
|
|
789
|
-
readonly separatedValueLetters: string;
|
|
790
|
-
/** Short-option letters whose value can only be ATTACHED (`perl -i.bak`, `-C<flags>`): the bundle scan
|
|
791
|
-
* stops there too, but a bare spelling takes NOTHING from the next token — reading `perl -C -e '…'`
|
|
792
|
-
* as "-C whose value is -e" swallowed the option that carries the program. */
|
|
793
|
-
readonly attachedValueLetters: string;
|
|
794
|
-
/** Short-option letters that take no value at all. Declaring them is what makes an invocation EXPLAINED
|
|
795
|
-
* (see `explained` in the recognizer); they change nothing else. */
|
|
796
|
-
readonly plainLetters: string;
|
|
797
|
-
/** Short-option letters that make this interpreter PRINT AND EXIT. Per interpreter, because the same
|
|
798
|
-
* letter is a banner in one and something else entirely in another (`-v` is the version in ruby and
|
|
799
|
-
* VERBOSE EXECUTION in python; `-h` is the version banner in lua and the HOST in psql). */
|
|
800
|
-
readonly bannerLetters: string;
|
|
801
|
-
/** Short-option letters that make the interpreter read commands INTERACTIVELY after whatever else it
|
|
802
|
-
* was given — a banner or a named script does not end the session, so the program still arrives on
|
|
803
|
-
* standard input (`lua -v -i`, `lua -i script.lua`). */
|
|
804
|
-
readonly interactiveLetters: string;
|
|
805
|
-
/** Which OPERAND names the program, when any does, and whether it is program TEXT (the awk family, a
|
|
806
|
-
* jq filter, the SQL after a database) or a program FILE (every script interpreter). Absent when no
|
|
807
|
-
* operand ever names the program — psql's are connection arguments, and an interactive compiler's are
|
|
808
|
-
* modules it loads before reading commands from its input. */
|
|
809
|
-
readonly programOperand?: {
|
|
810
|
-
readonly at: number;
|
|
811
|
-
readonly isText: boolean;
|
|
812
|
-
};
|
|
813
|
-
/** Whether an invocation that names no program anywhere reads one from its standard input. */
|
|
814
|
-
readonly stdinWhenUnnamed: boolean;
|
|
815
|
-
}
|
|
816
|
-
/** The interpreters this file has a row for, keyed by the basename bash resolves, with the trailing
|
|
817
|
-
* version dropped ({@link interpreterKey} — which is also why the key for `sqlite3` is `sqlite`). */
|
|
818
|
-
export declare const INTERPRETER_INLINE_PROGRAMS: ReadonlyMap<string, InlineProgramModel>;
|
|
819
|
-
/** The row a versioned spelling belongs to: `python3`, `python3.11` and `python` are one program with
|
|
820
|
-
* one program-delivery grammar, so the trailing version is dropped before the lookup. */
|
|
821
|
-
export declare function interpreterKey(name: string): string;
|
|
822
|
-
/**
|
|
823
|
-
* How this invocation receives its program, or `undefined` when it NAMES one (a script file, a module,
|
|
824
|
-
* a program file option) or names none at all on an interpreter that then reads none.
|
|
825
|
-
*
|
|
826
|
-
* Read over the folded arguments with the program word excluded. Three sources in one pass — an option
|
|
827
|
-
* whose value is program text, the operand a row declares as the program, and standard input — and one
|
|
828
|
-
* rule for every doubt: an option this file has no row for never ENDS the search for program text. The
|
|
829
|
-
* word that names the program stops the scan (past a script, `-p` belongs to the SCRIPT), but only while
|
|
830
|
-
* every option so far was one the row EXPLAINS: after an option of unknown arity the following word may
|
|
831
|
-
* be that option's value rather than the script, so the search has to run to the end.
|
|
832
|
-
*/
|
|
833
|
-
export declare function inlineProgramClause(model: InlineProgramModel, args: readonly string[]): string | undefined;
|
|
834
|
-
/** Does this already-vetted segment (FOLDED tokens — quoting does not change what getopt sees) invoke
|
|
835
|
-
* a {@link RECURSIVE_READ_FORMS} verb in a recursive form that DISCLOSES CONTENTS? `args` excludes the
|
|
836
|
-
* command name. Names-only traversals (`find`, `ls -R`, `du`, `tree`, an archive write) are in the table
|
|
837
|
-
* and answer `false` here — see {@link RecursiveReadFormModel.discloses}. */
|
|
838
|
-
export declare function segmentSelectsRecursiveRead(name: string, args: readonly string[]): boolean;
|
|
839
|
-
/** WHICH programs are DECLARED not to open the value of a `NAME=value` ARGUMENT — an allow-list, because
|
|
840
|
-
* the other polarity was measured false. `make PREFIX=/usr/local`, `cmake -D…`, `docker run -e HOME=/root`
|
|
841
|
-
* name a build prefix and an environment value their program never opens, and judging those was the one
|
|
842
|
-
* shape of the verb-blind rule that MANDATED the everyday build line. The exemption is theirs alone.
|
|
843
|
-
*
|
|
844
|
-
* The polarity is the whole point. Listing the programs that DO open such a value means anything the walk
|
|
845
|
-
* fails to recognise is exempt — and what it fails to recognise is WHICH PROGRAM RUNS: an undeclared
|
|
846
|
-
* wrapper is read as the program (`caffeinate dd if=<path>`), and a launcher can carry the program inside
|
|
847
|
-
* an option payload with no word equal to it (`env -Sdd if=<path>`). Both were verified to execute the
|
|
848
|
-
* read. Inverted, none of those is on this list, so none is exempt — nor is a fifth spelling of the same
|
|
849
|
-
* trick. A further program is a member, not a branch, and adding one is a claim about it alone.
|
|
850
|
-
*
|
|
851
|
-
* NOT its business: the LEADING environment assignments and an OPTION word's payload, each with its own arm. */
|
|
852
|
-
export declare const ASSIGNMENT_VALUE_NOT_PATHS: ReadonlySet<string>;
|
|
452
|
+
/** Every file and command line the program text of a read-language row names, under EVERY implementation's grammar
|
|
453
|
+
* (the union, deduplicated): what a candidate extraction hands the read judge (`reads`), the write face (`writes`) and
|
|
454
|
+
* a nested plan (`commands`). `undefined` for a row whose program text the station does not read. A reading that saw
|
|
455
|
+
* no text names nothing here — that fact rides the verdict face. */
|
|
456
|
+
export declare function programTextSlotFiles(row: ProgramRow, args: readonly string[]): SedScriptNames | undefined;
|
|
853
457
|
/** The program the shell will RUN here and where its OWN argv begins — the two seats
|
|
854
458
|
* {@link HeadedSegment.argvProgram} / {@link HeadedSegment.argvFrom} carry, from one reader so they cannot
|
|
855
459
|
* disagree. The LEADING assignments (both spellings) are the program-position reader's own step, so this
|
|
@@ -869,35 +473,14 @@ export declare function attachedOptionPayloads(tok: string): string[];
|
|
|
869
473
|
* (`x$HOME`, `$HOME.bak`, `$HOMES`) is a substitution the classify faces refuse and the read station cannot
|
|
870
474
|
* place, and an unquoted spelling of a home bash would split or glob ({@link HOME_EXPANDS_TO_ONE_WORD}) is not
|
|
871
475
|
* one word. The caller reads it only against a declared home (with none declared the child's `$HOME` may differ
|
|
872
|
-
* from what `~` falls back to) and only when the command cannot rebind `HOME` ({@link
|
|
476
|
+
* from what `~` falls back to) and only when the command cannot rebind `HOME` ({@link textBindsHome}).
|
|
873
477
|
*/
|
|
874
478
|
export declare function homeExpansionOf(w: LexedWord, home: string): {
|
|
875
479
|
readonly spelled: string;
|
|
876
480
|
} | undefined;
|
|
877
|
-
/**
|
|
878
|
-
*
|
|
879
|
-
* continuations
|
|
880
|
-
* `"HO"ME`, `HO\ME`, `HO$'ME'` and an `eval` string spell it the same as a bare word. That covers an assignment at ANY nesting depth (a `{ … }` group, a
|
|
881
|
-
* function body, a `case` arm, a loop), a declaration builtin's operand, a `for` / `select` variable, a `read` /
|
|
882
|
-
* `printf -v` / `mapfile` / `getopts` / `unset` target, a nameref value, an arithmetic or `${HOME:=…}` assignment,
|
|
883
|
-
* without naming any of them. A reader that substitutes the declared home for `$HOME` / `${HOME}` / a leading `~`
|
|
884
|
-
* asks this first; a text it answers yes for leaves those words unplaced (the fail-closed side).
|
|
885
|
-
* WHY not a grammar reading: every "where does the name stand" reading of this question (the leading assignment
|
|
886
|
-
* words, a declaration builtin's operands) has had a nesting level or a builtin it did not see.
|
|
887
|
-
* ACCEPTED COST: a text that merely spells the name while reading through the home — `echo HOME; cat ~/x`, a longer
|
|
888
|
-
* name ending in it (`MY_HOME=…`), a comment — asks instead of running.
|
|
889
|
-
* A name the shell COMPUTES spells no `HOME` to find, so four more readings count as a rebinding: an unquoted GLOB
|
|
890
|
-
* word whose pattern can match the name `HOME` or an array element `HOME[…]` of it ({@link globMayMatchHome} —
|
|
891
|
-
* `read H?ME`, `unset [H]OME`, `read H?ME[0]`, `unset *` glob against the working directory when an entry named
|
|
892
|
-
* `HOME` sits there); an unquoted EXTGLOB opener ({@link hasUnquotedExtglobOpener} — `read !(x)` matches nearly
|
|
893
|
-
* every name); an unquoted BRACE list ({@link wordHasBraceList} — `read H{O,X}ME` expands to a list whose first
|
|
894
|
-
* word is the name); an option word that carries a glob ({@link optionWordCarriesGlob} — `read -aH?ME`, where a
|
|
895
|
-
* matched entry named `-aHOME` hands the builtin `-a HOME`); and a `printf -v` name that is not a literal
|
|
896
|
-
* identifier ({@link printfNamesComputed} — `printf` opens no path, so its words are no candidate of their own).
|
|
897
|
-
* Elsewhere a computed word is its own unresolvable candidate, and an escape the lexer does not decode is
|
|
898
|
-
* unresolved on its own (asked). */
|
|
899
|
-
export declare function homeMayBeRebound(text: string): boolean;
|
|
900
|
-
/** {@link hasUnquotedExtglobOpener} over an already-lexed text. A here-document delimiter counts too: the lexer ends
|
|
481
|
+
/** An `?(` `*(` `+(` `@(` `!(` extended-glob opener spelled UNQUOTED, over an already-lexed text: a word whose last piece
|
|
482
|
+
* stands unquoted and whose written text ends in one of `? * + @ !`, with the source `(` right after it (across `\<newline>`
|
|
483
|
+
* continuations only). A here-document delimiter counts too: the lexer ends
|
|
901
484
|
* it at the `(` (`<<@(x)` reads as the delimiter `@` and a group), where bash with `extglob` on reads the one word
|
|
902
485
|
* `@(x)` — a different delimiter, so the body the lexer read as data is not the body bash reads. The token keeps no
|
|
903
486
|
* per-character quoting, so a delimiter quoted anywhere (`<<'E'@(X)`) counts as well: a quoted opener is bash's
|
|
@@ -915,16 +498,6 @@ export declare function classifyCompoundReadonlyDetailed(command: string, allow:
|
|
|
915
498
|
boundary?: {
|
|
916
499
|
readonly homeDir?: string;
|
|
917
500
|
}): CompoundReadonlyVerdict;
|
|
918
|
-
/** Working-directory moves {@link evaluateReadBoundary} does NOT model. `cd` is deliberately absent —
|
|
919
|
-
* it IS modelled (the walk threads the base through it), which is the whole difference: a move the
|
|
920
|
-
* walk follows keeps the verdict decidable, and one it cannot follow does not. */
|
|
921
|
-
export declare const UNMODELLED_BASE_MOVERS: ReadonlySet<string>;
|
|
922
|
-
/** Test seam for the lockstep pin that the launcher table (the ONE launcher truth, in the program-position
|
|
923
|
-
* reader's module) stays a SUBSET of the rule lane's curated `BARE_INTERPRETER_NAMES`. Exported for that one
|
|
924
|
-
* assertion — production code reads the table directly. The containment face ({@link classifyOutOfRootReadGate})
|
|
925
|
-
* does NOT look through a launcher: there every segment whose program is not a listed reader is judged whole,
|
|
926
|
-
* launcher or not, so looking through one would only narrow what it reads. */
|
|
927
|
-
export declare const COMMAND_LAUNCHERS_FOR_TEST: ReadonlySet<string>;
|
|
928
501
|
/**
|
|
929
502
|
* Compound read-only classification, reason-only face. Returns the demotion reason, or
|
|
930
503
|
* undefined when the command classifies read-only. ⚠️ `undefined` is NOT "safe to auto-execute":
|