@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.
Files changed (139) hide show
  1. package/CHANGELOG.md +298 -1
  2. package/dist/agents/extra-tool-names.d.ts +65 -0
  3. package/dist/agents/extra-tool-names.js +124 -0
  4. package/dist/agents/subagent.d.ts +17 -5
  5. package/dist/agents/subagent.js +33 -25
  6. package/dist/agents/tool-filter.d.ts +17 -1
  7. package/dist/agents/tool-filter.js +7 -0
  8. package/dist/core/agent-config-dir.d.ts +20 -0
  9. package/dist/core/agent-config-dir.js +49 -0
  10. package/dist/core/allow-entry.d.ts +6 -4
  11. package/dist/core/allow-entry.js +6 -5
  12. package/dist/core/ask-origin.d.ts +35 -12
  13. package/dist/core/ask-origin.js +24 -7
  14. package/dist/core/checkpoint-store.d.ts +39 -2
  15. package/dist/core/effective-path-target.d.ts +136 -4
  16. package/dist/core/effective-path-target.js +110 -2
  17. package/dist/core/engine-notice.d.ts +12 -4
  18. package/dist/core/gate-fold.js +5 -2
  19. package/dist/core/gate-lanes.js +11 -4
  20. package/dist/core/gate-outcome.d.ts +4 -2
  21. package/dist/core/gate-outcome.js +2 -2
  22. package/dist/core/governance-codes.d.ts +3 -1
  23. package/dist/core/governance-codes.js +3 -0
  24. package/dist/core/hooks.d.ts +3 -0
  25. package/dist/core/path-rule-binding.d.ts +65 -0
  26. package/dist/core/path-rule-binding.js +99 -0
  27. package/dist/core/permission-rule-model.d.ts +59 -24
  28. package/dist/core/permission-rule-model.js +48 -44
  29. package/dist/core/permission-rule-provider.d.ts +7 -0
  30. package/dist/core/permission-rule-provider.js +10 -3
  31. package/dist/core/permission-rule-store.d.ts +8 -0
  32. package/dist/core/permission-rule-store.js +6 -2
  33. package/dist/core/permission-rule-sync.js +2 -2
  34. package/dist/core/permission-rules.d.ts +26 -45
  35. package/dist/core/permission-rules.js +77 -57
  36. package/dist/core/runner/child-tree.d.ts +97 -0
  37. package/dist/core/runner/child-tree.js +104 -0
  38. package/dist/core/runner/construction-doors.d.ts +5 -0
  39. package/dist/core/runner/construction-doors.js +6 -0
  40. package/dist/core/runner/contracts.d.ts +46 -0
  41. package/dist/core/runner/gate-exit.d.ts +4 -1
  42. package/dist/core/runner/gate-exit.js +5 -1
  43. package/dist/core/runner/permission-rule-lanes.d.ts +34 -25
  44. package/dist/core/runner/permission-rule-lanes.js +18 -12
  45. package/dist/core/runner/persisted-path-rows.d.ts +31 -7
  46. package/dist/core/runner/persisted-path-rows.js +31 -12
  47. package/dist/core/runner/prepare-ask-lane.d.ts +4 -0
  48. package/dist/core/runner/prepare-ask-lane.js +4 -2
  49. package/dist/core/runner/prepare-execution-env.d.ts +5 -2
  50. package/dist/core/runner/prepare-execution-env.js +10 -3
  51. package/dist/core/runner/prepare-gate-stations.d.ts +3 -0
  52. package/dist/core/runner/prepare-gate-stations.js +2 -1
  53. package/dist/core/runner/prepare-hands-readface.d.ts +8 -4
  54. package/dist/core/runner/prepare-hands-readface.js +11 -11
  55. package/dist/core/runner/prepare-inherited-gate.d.ts +8 -1
  56. package/dist/core/runner/prepare-inherited-gate.js +8 -2
  57. package/dist/core/runner/prepare-park-ask.d.ts +3 -0
  58. package/dist/core/runner/prepare-park-ask.js +5 -3
  59. package/dist/core/runner/prepare-policy-chain.d.ts +14 -2
  60. package/dist/core/runner/prepare-policy-chain.js +13 -5
  61. package/dist/core/runner/prepare-suspend-saga.d.ts +10 -0
  62. package/dist/core/runner/prepare-suspend-saga.js +7 -1
  63. package/dist/core/runner/prepare-task.js +37 -18
  64. package/dist/core/runner/prepare-turn-wiring.d.ts +2 -0
  65. package/dist/core/runner/prepare-turn-wiring.js +2 -1
  66. package/dist/core/runner/prepare-workspace-restore.d.ts +3 -0
  67. package/dist/core/runner/prepare-workspace-restore.js +1 -0
  68. package/dist/core/runner/resume-apply.js +17 -3
  69. package/dist/core/runner/resume-checkpoint-screen.js +13 -0
  70. package/dist/core/runner/run-leg.js +5 -1
  71. package/dist/core/runner/runtask.js +2 -2
  72. package/dist/core/runner/sub-agent-deny-lists.d.ts +1 -1
  73. package/dist/core/runner/write-protection-station.d.ts +3 -2
  74. package/dist/core/runner/write-protection-station.js +1 -0
  75. package/dist/core/runner-deps.d.ts +14 -0
  76. package/dist/core/sensitive-path-policy.d.ts +8 -0
  77. package/dist/core/sensitive-path-policy.js +18 -2
  78. package/dist/core/shell-wrapper-projection.d.ts +11 -0
  79. package/dist/core/shell-wrapper-projection.js +56 -0
  80. package/dist/core/shell-wrapper-table.d.ts +144 -34
  81. package/dist/core/shell-wrapper-table.js +40 -20
  82. package/dist/core/synthetic-read-verdict.d.ts +3 -0
  83. package/dist/core/synthetic-read-verdict.js +3 -1
  84. package/dist/core/tool-catalog-entries.d.ts +21 -0
  85. package/dist/core/tool-catalog-entries.js +12 -2
  86. package/dist/core/tool-face.d.ts +10 -1
  87. package/dist/core/tool-name-readings.d.ts +8 -0
  88. package/dist/core/tool-name-readings.js +2 -0
  89. package/dist/core/tool-policy.d.ts +40 -17
  90. package/dist/core/tool-policy.js +11 -9
  91. package/dist/core/tool-registry.d.ts +9 -0
  92. package/dist/core/tool-registry.js +10 -0
  93. package/dist/core/tool-spec.d.ts +3 -2
  94. package/dist/core/write-protect.d.ts +14 -3
  95. package/dist/core/write-protect.js +41 -10
  96. package/dist/index.d.ts +6 -4
  97. package/dist/index.js +5 -3
  98. package/dist/orchestration/run-spec.js +8 -7
  99. package/dist/orchestration/workflow.js +1 -1
  100. package/dist/shell/lex.d.ts +22 -0
  101. package/dist/shell/lex.js +75 -13
  102. package/dist/tools/fs/bash-program-position.d.ts +14 -90
  103. package/dist/tools/fs/bash-program-position.js +41 -74
  104. package/dist/tools/fs/bash-readonly-classifier.d.ts +17 -444
  105. package/dist/tools/fs/bash-readonly-classifier.js +169 -1225
  106. package/dist/tools/fs/index.d.ts +3 -2
  107. package/dist/tools/fs/program-read-model.d.ts +711 -0
  108. package/dist/tools/fs/program-read-model.js +1259 -0
  109. package/dist/tools/fs/program-read-model.rows.d.ts +18 -0
  110. package/dist/tools/fs/program-read-model.rows.js +624 -0
  111. package/dist/tools/fs/read-deny-home.d.ts +19 -1
  112. package/dist/tools/fs/read-deny-home.js +62 -24
  113. package/dist/tools/fs/read-deny.d.ts +54 -14
  114. package/dist/tools/fs/read-deny.js +104 -50
  115. package/dist/tools/fs/removal-targets.d.ts +7 -6
  116. package/dist/tools/fs/removal-targets.js +34 -24
  117. package/dist/tools/fs/safety.d.ts +3 -0
  118. package/dist/tools/fs/safety.js +10 -3
  119. package/dist/tools/fs/shell-read-argv.d.ts +86 -0
  120. package/dist/tools/fs/shell-read-argv.js +388 -0
  121. package/dist/tools/fs/shell-read-bindings.d.ts +300 -0
  122. package/dist/tools/fs/shell-read-bindings.js +755 -0
  123. package/dist/tools/fs/shell-read-check.js +23 -15
  124. package/dist/tools/fs/shell-read-establish.js +82 -8
  125. package/dist/tools/fs/shell-read-judge.d.ts +11 -1
  126. package/dist/tools/fs/shell-read-judge.js +9 -1
  127. package/dist/tools/fs/shell-read-plan.d.ts +33 -8
  128. package/dist/tools/fs/shell-read-plan.js +309 -407
  129. package/dist/tools/fs/shell-read-word.d.ts +60 -26
  130. package/dist/tools/fs/shell-read-word.js +47 -37
  131. package/dist/tools/fs/shell-read-write-targets.d.ts +15 -64
  132. package/dist/tools/fs/shell-read-write-targets.js +85 -137
  133. package/dist/tools/fs/shell-reentry-text.d.ts +136 -6
  134. package/dist/tools/fs/shell-reentry-text.js +203 -53
  135. package/dist/tools/monitor.d.ts +3 -3
  136. package/package.json +1 -1
  137. package/test/export-surface.snapshot.json +25 -5
  138. package/wire-changes/core@7.46.0.json +1522 -0
  139. package/wire-changes/core@7.47.0.json +412 -0
@@ -0,0 +1,711 @@
1
+ /** What a datum names: never a file. */
2
+ export declare const DATUM_FORMS: readonly ["count", "pattern", "name-pattern", "label", "message", "delimiter"];
3
+ export type DatumForm = (typeof DATUM_FORMS)[number];
4
+ /** How a path-valued word carries its path, when it is not the plain word: `indirect` = the word, or what it names
5
+ * past a leading `@`; `form` = a field spec whose files sit after `@` / `<`; `header` = only a whole-word `@<file>`;
6
+ * `url` = the local path a `file:` URL names. */
7
+ export declare const PATH_VALUE_FORMS: readonly ["indirect", "form", "header", "url"];
8
+ export type PathValueForm = (typeof PATH_VALUE_FORMS)[number];
9
+ /** What selecting an option does to how the program runs ({@link OptionSpec.mode}) — a CLOSED set (`docs/CLOSED-SETS.md`,
10
+ * `OptionMode`). */
11
+ export declare const OPTION_MODES: readonly ["banner", "interactive", "names-program", "follows", "repeats", "quiet", "forced"];
12
+ export type OptionMode = (typeof OPTION_MODES)[number];
13
+ /**
14
+ * What one word is in this program's hands — a CLOSED set (`docs/CLOSED-SETS.md`, `ArgRoleKind`), the eleven members the
15
+ * read-station design names.
16
+ */
17
+ export declare const ARG_ROLE_KINDS: readonly ["path", "mount-source", "object-path", "program-text", "program-file", "shell-text", "command", "assignment", "binds-name", "entry-probe", "datum"];
18
+ export type ArgRoleKind = (typeof ARG_ROLE_KINDS)[number];
19
+ /**
20
+ * WHERE a write reaches a path it names. `landing` — the path followed through every link to where it lands: the
21
+ * program opens the path and writes through it. `entry` — the directory entry itself, the canonical parent joined with
22
+ * the last name: the program renames over the entry, unlinks it or replaces it, and a link there is not followed.
23
+ */
24
+ export type WriteSeat = "landing" | "entry";
25
+ /** What a path role does with the path: opens it for reading, only NAMES it (examines its entry, matches it, changes
26
+ * into it), writes it (an existing file or a new one, or removes it), creates it, or edits it IN PLACE (an existing
27
+ * file is rewritten — a program edits nothing that is not there). */
28
+ export declare const PATH_EFFECTS: readonly ["read", "names", "write", "create", "edit-in-place"];
29
+ export type PathEffect = (typeof PATH_EFFECTS)[number];
30
+ /** The effects that write the path: the write face's targets. */
31
+ export declare const WRITING_EFFECTS: ReadonlySet<PathEffect>;
32
+ export type ArgRole =
33
+ /** A path, by what the program does with it ({@link PathEffect}). Every effect is a path the command names. */
34
+ {
35
+ readonly kind: "path";
36
+ readonly effect: PathEffect;
37
+ readonly valueForm?: PathValueForm;
38
+ /** The program expands `{a,b}` sets and `[a-z]` / `[1-9]` ranges in the value itself before it opens anything
39
+ * (curl's URL glob), unless the invocation carries an option marked {@link OptionSpec.literalValues}. */
40
+ readonly programGlob?: true;
41
+ /** A writing effect: the seats the program writes the path at (absent: where it lands). */
42
+ readonly seats?: readonly WriteSeat[];
43
+ /** A writing effect the program does NOT itself perform at every seat: the seats it does write (`[]`: none — a
44
+ * copy READS its sources; the write face still judges them, as the reference implementation does). Absent: every
45
+ * seat in {@link seats}. */
46
+ readonly writtenAt?: readonly WriteSeat[];
47
+ /** The program RUNS in this directory (`env -C <dir>`), or with it as its root (`sudo -R <dir>`): the paths it is
48
+ * handed resolve against it, not against the working directory the command line stands in. Or the program word is
49
+ * LOOKED UP in these directories (`env -P <dirs>`): which program runs is not the one the word names on the PATH. */
50
+ readonly base?: "working-directory" | "root" | "program-search";
51
+ }
52
+ /** A HOST path a container runtime's daemon opens and mounts: `src[:dst[:opts]]` (`form: "volume"`, the source before the
53
+ * first `:`) or `key=value,…` with a `source=` / `src=` key (`form: "mount"`). A source that is no path (a volume name:
54
+ * no `/`, not led by `.` or `~`) names nothing on the host. */
55
+ | {
56
+ readonly kind: "mount-source";
57
+ readonly form: "volume" | "mount";
58
+ }
59
+ /** A repository object named `<rev>:<path>`: the object store opens it, not the working tree, so `<path>` is a
60
+ * spelling of a path the repository holds — relative to its top, which the text does not name. */
61
+ | {
62
+ readonly kind: "object-path";
63
+ }
64
+ /** Program text in `language`, run rather than opened. */
65
+ | {
66
+ readonly kind: "program-text";
67
+ readonly language: string;
68
+ }
69
+ /** A file holding program text in `language` — the file itself is opened. */
70
+ | {
71
+ readonly kind: "program-file";
72
+ readonly language: string;
73
+ }
74
+ /** Text the shell runs (now or later) as a command line. */
75
+ | {
76
+ readonly kind: "shell-text";
77
+ }
78
+ /** The program a launcher or a builtin runs by name: a function (`compgen -F`), the program a launcher runs in place of
79
+ * a shell (`su -s PROGRAM`). */
80
+ | {
81
+ readonly kind: "command";
82
+ }
83
+ /** A `NAME=value` the program (or the shell) consumes as an assignment. */
84
+ | {
85
+ readonly kind: "assignment";
86
+ }
87
+ /** A variable NAME the builtin reads or binds (`read NAME`, `printf -v NAME`, `unset NAME`, `declare NAME=…`, `test -v
88
+ * NAME`): an array element's subscript in it is evaluated as arithmetic — unless the builtin takes the name as
89
+ * WRITTEN (`asWritten`: `export` / `readonly` evaluate no subscript and refuse an element as no identifier). */
90
+ | {
91
+ readonly kind: "binds-name";
92
+ readonly asWritten?: true;
93
+ }
94
+ /** A path whose directory ENTRY is examined (type, mode, size) — nothing is opened. */
95
+ | {
96
+ readonly kind: "entry-probe";
97
+ } | {
98
+ readonly kind: "datum";
99
+ readonly form: DatumForm;
100
+ };
101
+ export type Arity =
102
+ /** A switch. */
103
+ 0
104
+ /** A value: the rest of the token, the next word, or `=value` for a long name. */
105
+ | 1
106
+ /** A value that exists only attached (`getopt_long`'s optional argument): the bare spelling takes nothing. */
107
+ | "attached"
108
+ /** A backup suffix: the rest of the token, or the NEXT word whatever it is spelled — the implementation's own reading
109
+ * (the role walk, the write reading, the binary gate). The read extraction (the candidate view and the program-text
110
+ * slot) takes the next word only when it is spelled like a suffix (empty, or `.`-led): taking any word there reads the
111
+ * everyday other-implementation spelling `-i '<script>' <file>` with its FILE as the script. */
112
+ | "suffix";
113
+ /**
114
+ * One option of a program row.
115
+ *
116
+ * @contract shell.read_boundary.option_value_slots — where a program row declares an option, the read boundary reads
117
+ * that option's value from the DECLARED role and nowhere else: a role that can name a file yields exactly the value
118
+ * as a path candidate (an `indirect` value also yields what it names past its `@`, a `header` value only a
119
+ * whole-value `@<file>`, a `form` value the files after its `@` / `<`, a `url` value the local path a `file:` URL
120
+ * names — each after the program's own glob where the role says the program expands one), and a role that cannot
121
+ * yields none; the attached and separated spellings of one option read the same row, except a value that exists
122
+ * only attached, which has no separated spelling. Past the command's first operand the separated spelling consumes
123
+ * nothing and its value is judged BOTH as that value and as an operand (which of the two it is, is
124
+ * implementation-dependent), unless the row's options stand anywhere in every implementation. A spelling one
125
+ * implementation rejects is read by the others alone, and an arity they dispute is read the way that consumes
126
+ * nothing. Where the row declares nothing — no row for the program, an option character it does not account for, a
127
+ * value declared without a role, a long-option prefix whose reachable names leave the value unsettled — the token
128
+ * is read the speculative way (its payloads are candidates), so an absent or partial row costs precision and never
129
+ * a judgement. A row is DATA about a PROGRAM and not about the read-only allowlist: it says what that program does
130
+ * with its own arguments, never that the program may be read from, and it grants no per-program arm to a program a
131
+ * deployment has not listed.
132
+ */
133
+ export interface OptionSpec {
134
+ readonly arity: Arity;
135
+ /** The value's role. Absent = this row does not model the value; a reader that needs it reads the option the
136
+ * speculative way (every spelling it could name is a candidate). */
137
+ readonly value?: ArgRole;
138
+ /** Selecting this option makes the operands roots of a tree walk (`traversal`), or makes the ordinary operands files
139
+ * the program rewrites in place (`edit-in-place`: they take {@link OperandSpec.editedInPlace}; the option's value, when
140
+ * it is given one, is the BACKUP suffix). */
141
+ readonly selects?: "traversal" | "edit-in-place";
142
+ /** Selecting this switch makes the program write every path it writes at these seats instead (`touch -h` writes the
143
+ * entry too; an in-place `sed --follow-symlinks` writes where the operand lands, and names its backups after that). */
144
+ readonly writesAt?: readonly WriteSeat[];
145
+ /** What selecting this option does beyond its value's role: `writes` a file or the system's state (`find -delete`,
146
+ * `date -s`), `executes` a command (`find -exec`), or `none` — neither, which the binary gate witnesses for every
147
+ * option that states it (the read-only form of a program admits only such options). Absent: not stated. */
148
+ readonly effect?: "writes" | "executes" | "none";
149
+ /** The option's value names a FILE the program reads its OPERANDS from (`find -files0-from`, `tar -T`): what it walks
150
+ * or opens is not in the command line. */
151
+ readonly delivers?: "operands";
152
+ /** The option's value bounds the program's output, in bytes or in lines (`head -c` / `head -n`). */
153
+ readonly bounds?: "bytes" | "lines";
154
+ /** The option's value is what the row's LAST operand would otherwise be (`cp -t <dir>`), so every operand is an
155
+ * ordinary one after it. */
156
+ readonly fillsLast?: true;
157
+ /** An enum option: selecting the value (case-folded, any unambiguous prefix of it) makes the operands roots of a
158
+ * tree walk (`grep -d recurse`). */
159
+ readonly selectsWhenValue?: string;
160
+ /** This option delivers what the row's first positional would otherwise be (grep's `-e`, sed's `-f`, an
161
+ * interpreter's `-c`), so the first operand is an ordinary operand after it. */
162
+ readonly fillsSlot?: true;
163
+ /** What follows this option (after its value) is the named program's own argv (`python -m <module> …`). */
164
+ readonly endsOptions?: true;
165
+ /** `banner`: prints and exits; `interactive`: reads commands from its standard input (after its program, `python -i`;
166
+ * instead of a script file, `sh -s`; a launcher's shell, run where no program follows, `sudo -s`); `names-program`: selects
167
+ * the program to run without a value (`node --test`; a launcher's, from the caller's environment: `su -m`); `follows`:
168
+ * follows its files as they grow, until killed (`tail -f`); `repeats`: repeats on an interval until killed (`free -s`);
169
+ * `quiet`: prints only what the program's own text tells it to (`sed -n`); `forced`: removes without asking, and passes
170
+ * over an operand that is not there (`rm -f`). */
171
+ readonly mode?: OptionMode;
172
+ /** This switch turns the program's own value glob off (`curl -g`): every {@link ArgRole} `programGlob` value of the
173
+ * invocation is read literally. */
174
+ readonly literalValues?: true;
175
+ /** What selecting this switch makes a declaration builtin do to the names it binds (`declare -i`): evaluate an assigned
176
+ * value as ARITHMETIC (`integer` — a substitution in a subscript of it runs; the value bound is not the text), make
177
+ * the name a REFERENCE to another (`reference` — an assignment through it binds the name it holds), bind something
178
+ * other than the text (`transformed` — a case change, an array), make the name READ-ONLY (`frozen` — the shell
179
+ * refuses every later assignment to it and keeps the value, or exits; the builtin's own `NAME=value` still binds), or
180
+ * leave what a `NAME=value` operand binds UNSETTLED (`unsettled` — the builtin may assign none of them: it displays
181
+ * the names, `declare -p`; names functions, `-f`; or a bash it runs on refuses the switch, bash 3.2's `declare -g`). */
182
+ readonly assigns?: DeclaredAttribute;
183
+ }
184
+ /** What a declaration builtin does to the names it binds ({@link OptionSpec.assigns}). */
185
+ export type DeclaredAttribute = "integer" | "reference" | "transformed" | "frozen" | "unsettled";
186
+ /** One implementation's option grammar. `any` = every implementation the row was measured on reads it this way. */
187
+ export type Dialect = "any" | "gnu" | "bsd";
188
+ export interface Grammar {
189
+ readonly dialect: Dialect;
190
+ /** Short option letters. */
191
+ readonly short: Readonly<Record<string, OptionSpec>>;
192
+ /** Long option names, without the leading `--`. */
193
+ readonly long: Readonly<Record<string, OptionSpec>>;
194
+ /** Single-dash WORD options (`find -name`, `sqlite3 -cmd`), without the dash. */
195
+ readonly dashWords?: Readonly<Record<string, OptionSpec>>;
196
+ /** What a dash-led word past the first operand is: still an `options` word (permuting, or a grammar whose options
197
+ * stand anywhere), an `operands` word (the implementation stops at the first operand), or `either` (the row is
198
+ * read for implementations that disagree). */
199
+ readonly afterFirstOperand: "options" | "operands" | "either";
200
+ /** A `+` word is an option word too, read as its `-` spelling (a POSIX shell's `+x` turns `-x` off; `+o NAME` takes its
201
+ * name as `-o` does). */
202
+ readonly plusOptions?: true;
203
+ /** The `+` spellings of a declaration builtin's switches (`declare +x` turns an attribute off), measured apart from the
204
+ * `-` ones: a `+` word with a letter this table does not carry (`++`, `+Z`) is one the builtin refuses. Absent, a
205
+ * `+` word is no switch of the builtin (`export ++` is an operand). */
206
+ readonly plusShort?: Readonly<Record<string, OptionSpec>>;
207
+ /** A launcher whose walk steps over a bare `--` (the `time` reserved word's TIMEIGN, the program's end-of-options). */
208
+ readonly stepsDashDash?: true;
209
+ /** With no operand, this implementation walks the working directory (`grep -r pat`); absent, it walks nothing (it
210
+ * reads its standard input, or refuses to run). */
211
+ readonly walksCwdWithoutOperand?: true;
212
+ /** The traditional FIRST-argument form `<sign><number><letters>` (`tail +0f`, `tail -1f`): the signs this
213
+ * implementation reads it with, and the option each letter names. */
214
+ readonly obsoleteFirst?: {
215
+ readonly signs: string;
216
+ readonly letters: Readonly<Record<string, OptionSpec>>;
217
+ };
218
+ }
219
+ export interface OperandSpec {
220
+ /** Roles of the positional operands by position (`undefined` = an ordinary operand). */
221
+ readonly positional?: readonly (ArgRole | undefined)[];
222
+ /** The role of every operand past `positional` (absent = an ordinary operand: a path the program may read). */
223
+ readonly rest?: ArgRole;
224
+ /** A bare `-` operand is a FILE name (absent: it is standard input). */
225
+ readonly dash?: "file";
226
+ /** The program evaluates its words (an array subscript in one runs a substitution): a word the shell or that
227
+ * evaluation rewrites is still handed over, whatever the operand role says. */
228
+ readonly evaluates?: true;
229
+ /** A `NAME=value` argument's value names no path to this program. */
230
+ readonly assignmentArguments?: "not-paths";
231
+ /** The role of the LAST operand, unless an option delivered it ({@link OptionSpec.fillsLast}): a copy's destination. */
232
+ readonly last?: ArgRole;
233
+ /** What an ordinary operand becomes when an option selects editing in place ({@link OptionSpec.selects}). */
234
+ readonly editedInPlace?: ArgRole;
235
+ /** With fewer operands than this (the first-operand slot counted), the program reads its standard input; `always`:
236
+ * it reads nothing else. Absent: the row does not say. */
237
+ readonly stdinBelow?: number | "always";
238
+ }
239
+ export interface TraversalSpec {
240
+ /** What the walk hands back: the CONTENTS it walked over, or only NAMES (and sizes). */
241
+ readonly discloses: "contents" | "names";
242
+ /** Every invocation walks (`find`, `du`, `rg`): no option selects it. */
243
+ readonly always?: true;
244
+ /** Mode letters of a traditional dash-less first-operand key word (`tar cf …`) that select the walk. */
245
+ readonly keyWordLetters?: string;
246
+ }
247
+ export interface LauncherSpec {
248
+ /** Positional operands the launcher takes BEFORE the program (`timeout DURATION COMMAND`). */
249
+ readonly requiredOperands?: number;
250
+ /** The launcher reads `NAME=VALUE` operands with its own name grammar (`env 1=x …`). */
251
+ readonly assignmentOperands?: true;
252
+ /** A bare negative integer in its option section is its own argument (`nice -5 <cmd>`). */
253
+ readonly negativeIntegerIsOwnArgument?: true;
254
+ /** It runs a SHELL in place of a program word, and how the words after it become that shell's argv: `joined` — its
255
+ * non-option words, joined by a space, are the shell's `-c` text (`watch "cat /x"`); `user` — its first operand (past
256
+ * a lone `-`) names the user it runs as, and the words after the user are the shell's own argv, behind a `-c TEXT` its
257
+ * own shell-text option gives (`su [-] [USER [ARG…]]`: an implementation that reads its options anywhere takes them
258
+ * past the user too, one that stops at the user hands them on); the program is its option of role `command` where
259
+ * one is given (`su -s PROGRAM`), or a `names-program` switch's (`su -m`: the caller's `$SHELL`). */
260
+ readonly shellText?: "joined" | "user";
261
+ /** Option spellings that make a {@link shellText} launcher run the program its operands name instead
262
+ * (`runuser -u USER CMD…`). */
263
+ readonly programWith?: readonly string[];
264
+ /** With no program word it runs a shell. */
265
+ readonly whenNoProgram?: "shell";
266
+ /** Where a switch selecting its shell (mode `interactive`: `sudo -s`) has words after it, they are that shell's `-c`
267
+ * text: `escaped` — joined by a space, every character of each but a letter, a digit, `_`, `-` and `$` escaped with a
268
+ * backslash. Absent, the launcher takes no such words (`doas -s CMD` is refused) and they are read as the program. */
269
+ readonly shellCommand?: "escaped";
270
+ /** The spelling a required operand must have (a word spelled otherwise is not one the launcher accepts). Absent: any
271
+ * word that is not option-shaped. */
272
+ readonly requiredOperandSpelling?: RegExp;
273
+ /** A lone `-` in its option section is its own switch (`env -`, the obsolete spelling of `env -i`). */
274
+ readonly bareDash?: true;
275
+ }
276
+ /** How a program receives the PROGRAM it runs (an interpreter): an option value, an operand (`operands.positional`),
277
+ * or standard input when it names none. */
278
+ export interface DeliverySpec {
279
+ readonly stdinWhenUnnamed: boolean;
280
+ }
281
+ /** The shell text a re-entry program runs: `-c`'s value, its words joined (`eval`), its non-option words (`parallel`),
282
+ * or none (`source FILE` reads a file operand). `stdin: "script"`: where its argv names no text and no script file, it
283
+ * runs its STANDARD INPUT (`bash <<EOF`, `… | sh`, `parallel < commands`). */
284
+ export type ShellReentry = {
285
+ readonly kind: "shell";
286
+ readonly text: "c-option" | "words" | "non-option-words" | "file-operand";
287
+ readonly stdin?: "script";
288
+ }
289
+ /** Its operands arrive on a stream and it execs `defaultProgram` when the chain names none (`xargs`). */
290
+ | {
291
+ readonly kind: "argv";
292
+ readonly defaultProgram: string;
293
+ };
294
+ /** Where a builtin keeps shell text it runs later: its first operand after the options (`trap`), the values of its
295
+ * `NAME=VALUE` operands (`alias`), or the values of its shell-text options (`mapfile -C`). */
296
+ export type CodeBody = "first-operand" | "assignment-values" | "option-values";
297
+ /** How a row is checked against the program: the gate runs the binary, or the row says why it cannot. */
298
+ export type Witness = "binary" | {
299
+ readonly declared: string;
300
+ };
301
+ /** One subcommand of a row: its own grammar, and — where its words name paths in their own way — its operands and its
302
+ * traversal. Read as a row of its own ({@link subcommandOf}); witnessed with its program's row. */
303
+ export interface Subcommand {
304
+ readonly grammar: Grammar;
305
+ readonly operands?: OperandSpec;
306
+ readonly traversal?: TraversalSpec;
307
+ }
308
+ export interface ProgramRow {
309
+ readonly key: string;
310
+ /** A versioned spelling (`python3`, `python3.11`) is this row. */
311
+ readonly versioned?: true;
312
+ readonly grammars: readonly Grammar[];
313
+ readonly operands?: OperandSpec;
314
+ readonly traversal?: TraversalSpec;
315
+ readonly delivery?: DeliverySpec;
316
+ readonly launcher?: LauncherSpec;
317
+ readonly reentry?: ShellReentry;
318
+ readonly body?: CodeBody;
319
+ /** `declaration`: performs its `NAME=value` operands as shell assignments (`export`); `inert`: opens no file, starts
320
+ * no program and evaluates nothing (`echo`). A declaration builtin is inert only bare. */
321
+ readonly builtin?: "declaration" | "inert";
322
+ /** What a declaration builtin does to every name it binds with no switch selected ({@link OptionSpec.assigns}):
323
+ * `readonly` makes them read-only, as `declare -r` does. */
324
+ readonly assigns?: DeclaredAttribute;
325
+ /** It moves the working directory in a way the station does not follow (`pushd`). */
326
+ readonly movesBase?: "unfollowed";
327
+ /** What it writes to its standard output, read off its operands ({@link printedText}): `words` = its operands joined
328
+ * by a space (`echo`), `format` = its one operand as a format (`printf`). */
329
+ readonly prints?: "words" | "format";
330
+ /** A shell block word at the program position: it names no command of its own. */
331
+ readonly syntax?: "block";
332
+ /** Git-style subcommands: the word after the program's own options names one, and the words after it are read by
333
+ * ITS grammar, operands and traversal ({@link subcommandOf}). */
334
+ readonly subcommands?: Readonly<Record<string, Subcommand>>;
335
+ /** Modules the interpreter runs by name (`python -m <module>`) whose own argv tail is not argv: the role of every word
336
+ * after the module name (`timeit` compiles and runs it as program text). */
337
+ readonly modules?: Readonly<Record<string, ArgRole>>;
338
+ readonly witness: Witness;
339
+ }
340
+ /** The row bash runs for this basename: the exact key, or — for a row that declares versioned spellings — the name
341
+ * with its trailing version dropped (`python3.11` is `python`). */
342
+ export declare function programRow(name: string): ProgramRow | undefined;
343
+ /** Every row, in table order. */
344
+ export declare function programRows(): readonly ProgramRow[];
345
+ /** The launcher names — derived from the rows. */
346
+ export declare const LAUNCHER_NAMES: ReadonlySet<string>;
347
+ /** The block words — derived from the rows. */
348
+ export declare const BLOCK_WORD_NAMES: ReadonlySet<string>;
349
+ /** Does this program run its argument as SHELL text (`sh -c`, `eval`, `source`, `parallel`)? */
350
+ export declare function runsShellText(name: string): boolean;
351
+ /** Does this program take its operands from a stream and exec a program with them (`xargs`)? */
352
+ export declare function feedsArgvFromStdin(name: string): boolean;
353
+ /** The program a stream-fed launcher runs when the chain names none. */
354
+ export declare function streamDefaultProgram(name: string): string | undefined;
355
+ /** Does this program open none of its operands (they are text, numbers, names, or entries it only examines)? */
356
+ export declare function opensNoOperand(name: string): boolean;
357
+ /** Does this no-path program evaluate its words (so a rewritten one is still handed over)? */
358
+ export declare function evaluatesOperands(name: string): boolean;
359
+ /** Is a `NAME=value` argument of this program a value it never opens? */
360
+ export declare function assignmentArgumentsAreNotPaths(name: string): boolean;
361
+ export declare function isDeclarationBuiltin(name: string): boolean;
362
+ /** What one invocation of a declaration builtin does to the names it binds: the row's own attribute and every selected
363
+ * switch's ({@link OptionSpec.assigns}). A `-` word reads the grammar's letters, a `+` word its `+` spellings
364
+ * ({@link Grammar.plusShort}; a `+` word turns an attribute off — it gives none); a switch word a bash it runs on
365
+ * refuses — a letter the table of its sign does not carry — leaves the operands `unsettled`. */
366
+ export declare function declaredAttributes(row: ProgramRow | undefined, args: readonly string[]): ReadonlySet<DeclaredAttribute>;
367
+ /** Opens no file, starts no program and evaluates nothing (a declaration builtin: only bare — its caller checks). */
368
+ export declare function isInertBuiltin(name: string): boolean;
369
+ export declare function movesBaseUnfollowed(name: string): boolean;
370
+ /** The LONG-OPTION name carried by a token (`--file=p` → `file`, `--reg` → `reg`); `undefined` for anything that is
371
+ * not a long option with a non-empty name (`--`, `--=x`, a short option). */
372
+ export declare function longOptionNameOf(tok: string): string | undefined;
373
+ /** Is `name` a spelling (possibly ABBREVIATED) of the long option `full`? Every prefix counts — `getopt_long`'s
374
+ * ambiguity is not modelled, and each caller makes that over-approximation land on its own safe side. */
375
+ export declare function isLongOptionAbbrevOf(name: string, full: string): boolean;
376
+ /** The languages whose program text the read station parses (the rest is program text it does not read). */
377
+ export declare const READ_LANGUAGES: ReadonlySet<string>;
378
+ /**
379
+ * What program text in a language can do to the reads of the command running it (its `opensVia` reading):
380
+ * · `any` — the language opens files (and runs programs) from its text by any spelling: its text is never a path, but
381
+ * where it may open what it opens is not readable from it;
382
+ * · a token list — the language opens a file only through these words or characters (jq's `import` / `include`; awk's
383
+ * `getline`, `system`, `ARGV` / `ARGC` (it can replace the input files), the `(` of a call — an indirect `@f(…)` call
384
+ * reaches `system` too — and `|` pipes): text carrying one of them may open a file; text carrying none opens nothing;
385
+ * · `never` — the language opens nothing from its text;
386
+ * · `parsed` — the station reads the text itself (`sed`: the script's `r` / `w` / `e` commands, `READ_LANGUAGES`);
387
+ * · `arithmetic` — the shell's arithmetic evaluator: it opens nothing, but a substitution in an array subscript it
388
+ * evaluates runs (the station reads those substitutions itself).
389
+ * A language the table does not name is read as `any`.
390
+ */
391
+ type ProgramTextOpens = "any" | "never" | "parsed" | "arithmetic" | readonly string[];
392
+ /** How program text in `language` opens files ({@link PROGRAM_TEXT_OPENS}; `any` for a language it does not name). */
393
+ export declare function programTextOpensOf(language: string): ProgramTextOpens;
394
+ /** Does this program text in `language` carry what may make it open a file (`any`, or a token of its list)? `parsed`,
395
+ * `arithmetic` and `never` texts answer no: what they open is read elsewhere, or nothing. */
396
+ export declare function programTextMayOpen(language: string, text: string): boolean;
397
+ /** What a row makes of ONE option token. `unexplained` = the row cannot account for it, and the caller reads it the
398
+ * speculative way. `R` is the role a value carries: always known in the candidate view, possibly unmodelled in the
399
+ * role view. */
400
+ type Reading<R> = {
401
+ readonly form: "unexplained";
402
+ } | {
403
+ readonly form: "no-value";
404
+ } | {
405
+ readonly form: "attached";
406
+ readonly value: string;
407
+ readonly role: R;
408
+ readonly spec?: OptionSpec;
409
+ } | {
410
+ readonly form: "separated";
411
+ readonly role: R;
412
+ readonly spec?: OptionSpec;
413
+ };
414
+ export type OptionSlotReading = Reading<ArgRole>;
415
+ export type OptionRoleReading = Reading<ArgRole | undefined>;
416
+ /** Which options a reader may rely on. `candidates`: switches and values of a role the candidate extraction reads
417
+ * (a value of any other role, an attached-only SHORT letter and a short letter whose arity the
418
+ * implementations dispute are not in it — the extraction reads those the speculative way). `roles`: every declared
419
+ * option, its value's role when the row models it — what the binary gate checks the row against. */
420
+ type View = "candidates" | "roles";
421
+ /** The candidate extraction's reading of one option token: a value whose role it does not read is read the speculative
422
+ * way. */
423
+ export declare function readOptionSlot(row: ProgramRow, tok: string): OptionSlotReading;
424
+ /** The role reading of one option token: every declared option, its value's role where the row models it. */
425
+ export declare function readOptionRole(row: ProgramRow, tok: string, next?: string): OptionRoleReading;
426
+ /** The row's FIRST positional as a slot a reader reads by its role (grep's pattern, sed's script) — with the options
427
+ * that deliver it instead, which leave the first operand an ordinary operand after all. The candidate view has the
428
+ * slot only where the extraction reads its role. */
429
+ export interface FirstOperandSlot {
430
+ readonly role: ArgRole;
431
+ readonly suppliedByLetters: string;
432
+ readonly suppliedByLongNames: readonly string[];
433
+ /** The other letters that take a value in every implementation: in a cluster, the rest of the token is theirs. */
434
+ readonly valueLetters: string;
435
+ }
436
+ export declare function firstOperandSlot(row: ProgramRow | undefined, view?: View): FirstOperandSlot | undefined;
437
+ /** Does this token supply the first-operand slot? A short cluster is read as getopt reads it: scanning left to right,
438
+ * a letter that delivers the slot supplies it, and the first OTHER letter that takes a value owns the rest of the
439
+ * token (`grep -Dread x f`: `read` is `-D`'s value, its `e` delivers nothing); a letter the row does not declare is
440
+ * stepped over (it may be a switch), as digits are (grep's obsolete numeric context spec: `-2ebeta`). A long option
441
+ * supplies it by abbreviation. Over-triggering makes the first operand a CHECKED path candidate, the safe side. */
442
+ export declare function suppliesFirstOperandSlot(slot: FirstOperandSlot, tok: string): boolean;
443
+ /** The row's options stand anywhere in its argv in every implementation (`find`'s predicates past its paths), so the
444
+ * "is a dash-word past the first operand still an option" ambiguity does not exist for it. */
445
+ export declare function optionsStandAnywhere(row: ProgramRow | undefined): boolean;
446
+ /** The most values a program glob is listed out to; past it the value names files the reader does not list. */
447
+ export declare const PROGRAM_GLOB_MAX = 256;
448
+ /**
449
+ * The values a program glob expands to (curl's URL glob): `{a,b}` sets (no nesting, a `\` escaping the next character),
450
+ * `[a-z]` / `[1-9]` / `[01-10:2]` ranges, `\{ \[ \} \]` literal. `undefined` = the reader does not list what the value
451
+ * names: more than {@link PROGRAM_GLOB_MAX} values, or a form it does not read (an unmatched or nested bracket, a range
452
+ * it cannot parse) — never "names nothing", since a form misread as refused would hide a read.
453
+ */
454
+ export declare function programGlobExpansions(value: string): readonly string[] | undefined;
455
+ /**
456
+ * The path candidates one value offers, which is also the answer to "did this value name a file?" — an empty list IS
457
+ * the no. A plain path offers itself; an `indirect` one itself and what it names past an `@`; a `header` only a
458
+ * whole-word `@<file>`; a `form` field spec the files after its `@` / `<`; a `url` the local path of a `file:` URL. A
459
+ * `programGlob` value offers what each of its expansions offers (`globs: "literal"` = the invocation turned the glob
460
+ * off); `undefined` = it expands past {@link PROGRAM_GLOB_MAX}: it names files the reader does not list.
461
+ */
462
+ export declare function slotValueCandidates(value: string, role: ArgRole, globs?: "expanded" | "literal"): string[] | undefined;
463
+ /** The paths an object name `<rev>:<path>` ({@link ArgRole} `object-path`) may spell: the text after each `:` (a stage
464
+ * number, `:1:x`, and a revision spelled with a colon both leave more than one reading — every one is offered). None
465
+ * for a word with no `:`, a URL-like `scheme://…`, or an empty path. */
466
+ export declare function objectPathsOf(value: string): string[];
467
+ /** One word of the argv a candidate reader hands the walk: `skip` = the reader already handed it over (it is stepped
468
+ * past, though an option before it may still take it as its value). */
469
+ export interface ArgWord {
470
+ readonly folded: string;
471
+ readonly skip?: boolean;
472
+ }
473
+ /** What the walk read at one index, in the order a reader must hand the candidates over. `R` as in {@link Reading}. */
474
+ type Event<R> =
475
+ /** The `--` that ends the options. */
476
+ {
477
+ readonly kind: "end-of-options";
478
+ readonly at: number;
479
+ }
480
+ /** A dash-word past the first operand on a grammar that may have stopped reading options: it is ALSO an operand. */
481
+ | {
482
+ readonly kind: "dash-word-operand";
483
+ readonly at: number;
484
+ }
485
+ /** An option word: `no-value`, `attached` (its value inside the word), or `speculative` (the row does not explain
486
+ * it, or its separated value is read without being consumed). */
487
+ | {
488
+ readonly kind: "option";
489
+ readonly at: number;
490
+ readonly reading: "no-value" | "speculative" | {
491
+ readonly attached: string;
492
+ readonly role: R;
493
+ readonly spec?: OptionSpec;
494
+ };
495
+ }
496
+ /** The value of the separated option at `of`: `consumed` = the walk steps past it; otherwise it is read as that value
497
+ * AND later as whatever it is on its own. */
498
+ | {
499
+ readonly kind: "value";
500
+ readonly at: number;
501
+ readonly of: number;
502
+ readonly role: R;
503
+ readonly consumed: boolean;
504
+ readonly spec?: OptionSpec;
505
+ }
506
+ /** An operand, the `ordinal`-th. `slot` = the first-operand slot's role when the slot applies; `role` = the role the
507
+ * row declares for an operand at this position past the slot (a URL, a name it only examines); `dash` = the word is
508
+ * a lone `-`, read as standard input (`stdin`) or as a file name. */
509
+ | {
510
+ readonly kind: "operand";
511
+ readonly at: number;
512
+ readonly ordinal: number;
513
+ readonly slot?: ArgRole;
514
+ readonly role?: ArgRole;
515
+ readonly dash?: "stdin" | "file";
516
+ };
517
+ export type ArgEvent = Event<ArgRole>;
518
+ export type ArgRoleEvent = Event<ArgRole | undefined>;
519
+ /** The candidate extraction's walk (the program word excluded). `firstOperandSlot: false` reads every operand as an
520
+ * ordinary one. */
521
+ export declare function readArgs(row: ProgramRow | undefined, words: readonly ArgWord[], opts: {
522
+ readonly firstOperandSlot: boolean | "program-text";
523
+ }): ArgEvent[];
524
+ /** The role walk: the SAME walk, every declared option read by its declared arity and role. What the binary gate
525
+ * predicts a binary opens is read off these events. */
526
+ export declare function readArgRoles(row: ProgramRow, args: readonly string[]): ArgRoleEvent[];
527
+ /**
528
+ * Does this invocation walk its operands' subtrees AND hand back their CONTENTS? Detection over-approximates: a flag
529
+ * misread as recursive costs one ask, an under-read hides a traversal. A value-taking letter owns its value only where
530
+ * every implementation reads it so; a `--` right after a long option that may take a value is that option's value
531
+ * (`grep --label -- -r . .` recurses).
532
+ */
533
+ export declare function selectsContentsTraversal(row: ProgramRow | undefined, args: readonly string[]): boolean;
534
+ /** With no operand, does some implementation walk the working directory? A contents walk then has `.` as its root. */
535
+ export declare function walksCwdWithoutOperand(row: ProgramRow | undefined): boolean;
536
+ /**
537
+ * Does this invocation turn the program's own value glob off (`curl -g`, `--globoff`)? Read with the role walk, so a
538
+ * spelling that is another option's value does not count; a cluster counts the switch only up to its first letter that
539
+ * is not an unambiguous switch, a long name only when it abbreviates nothing else, a switch behind an option the row
540
+ * does not explain is not trusted (it may be that option's value), and a `--no-` spelling of the switch anywhere turns
541
+ * the glob back on — every doubt reads the glob ON (more candidates, never fewer).
542
+ */
543
+ export declare function valuesAreLiteral(row: ProgramRow | undefined, args: readonly string[]): boolean;
544
+ /** A lone `-` operand is standard input to this program (absent row: it is). */
545
+ export declare function dashOperandIsStdin(row: ProgramRow | undefined): boolean;
546
+ /** Does the row declare an option (in any implementation, short, long or dash word) the predicate holds for? */
547
+ export declare function declaresOption(row: ProgramRow, pred: (spec: OptionSpec) => boolean): boolean;
548
+ /**
549
+ * Does this option token take the NEXT word as a value that never names a file (a count, a label, a pattern, a
550
+ * delimiter)? Read for a count of the operands a program is handed, in the direction that lowers it: an arity the
551
+ * implementations dispute counts as taking the value (some implementation does), and a long spelling counts when any
552
+ * name it can abbreviate takes one. A value that may name a file — or that delivers the first positional (`grep -e`,
553
+ * whose value the count states as one of its operands) — is not stepped over: a `-` there is a standard-input read the
554
+ * count must still see. getopt's cluster rule: the FIRST value-taking letter owns the rest of the token.
555
+ */
556
+ export declare function takesSeparatedDatum(row: ProgramRow | undefined, tok: string): boolean;
557
+ /**
558
+ * Does this option word carry, ATTACHED, the value `-` for an option whose value is a file the program opens or names
559
+ * (`grep -f-`, `diff --from-file=-`, `diff -X-`) — or for a spelling the row does not account for? Such a word makes the
560
+ * program read its standard input, out of sight of any operand count.
561
+ */
562
+ export declare function attachedStdinFile(row: ProgramRow | undefined, tok: string): boolean;
563
+ /** The row read under each implementation's grammar alone (one view per grammar), or the row itself when it declares
564
+ * at most one. A reader that needs to know what ONE implementation does with an argv reads these views. */
565
+ export declare function implementationsOf(row: ProgramRow): readonly ProgramRow[];
566
+ /**
567
+ * Every option spec an argv selects. A short cluster is read as getopt reads it, scanning left to right: a declared
568
+ * letter is selected; a value-taking letter owns the rest of the token (and the next word, when it ends the token); a
569
+ * letter the row does not declare is read as a switch and the scan goes on. A long option is every name its spelling
570
+ * can abbreviate (the exact name alone where there is one); a dash word its exact name. Two readings:
571
+ * · over ONE implementation's view ({@link implementationsOf}): what that program selects — a separated value is
572
+ * stepped over, `--` ends the options, and so does the first operand where the grammar stops there;
573
+ * · over the row (every implementation merged): every word is read as the option it SPELLS — a value spelled like an
574
+ * option, and a word past `--`, included. The reading a check that only ever refuses takes: it errs to more options.
575
+ */
576
+ export declare function selectedOptions(row: ProgramRow | undefined, args: readonly string[], under?: "one-implementation"): OptionSpec[];
577
+ /** A path role whose effect writes. */
578
+ export type WritingRole = Extract<ArgRole, {
579
+ kind: "path";
580
+ }>;
581
+ /** Does this role write its path ({@link WRITING_EFFECTS})? */
582
+ export declare function writesPath(role: ArgRole | undefined): role is WritingRole;
583
+ /** One word an implementation's reading writes: its argv index, the value inside it when an option carries it
584
+ * attached, and the role it is written by. */
585
+ export interface WrittenWord {
586
+ readonly at: number;
587
+ readonly value?: string;
588
+ readonly role: WritingRole;
589
+ }
590
+ /** What ONE implementation's reading of an argv writes. */
591
+ export interface WriteReading {
592
+ /** The words the reading writes, by the role each is read in. */
593
+ readonly written: readonly WrittenWord[];
594
+ /** The role the row's ordinary operands write with in this reading (an in-place edit's operands, a removal's, a
595
+ * copy's sources), or `undefined` when they write nothing here. */
596
+ readonly operandRole?: WritingRole;
597
+ /** The reading cannot account for some option word (one this implementation does not declare, whose value may be any
598
+ * word that follows): every word the command hands the program may be written, by {@link operandRole}. */
599
+ readonly unexplained: boolean;
600
+ /** The backup suffixes an option selecting edit-in-place was given (empty values dropped: no backup). */
601
+ readonly suffixes: readonly string[];
602
+ /** A copy's destination (argv index, and its value when an option carries it attached) and its sources. */
603
+ readonly copy?: {
604
+ readonly destination: {
605
+ readonly at: number;
606
+ readonly value?: string;
607
+ };
608
+ readonly sources: readonly number[];
609
+ };
610
+ }
611
+ /**
612
+ * Every implementation's reading of what an argv (the program word excluded) WRITES: the words read in a writing role
613
+ * — an option value, an operand by its position, the ordinary operands an option made edited in place, a copy's last
614
+ * operand as its destination — and the facts a write face needs beside them. Read with the role walk
615
+ * ({@link readArgRoles}) under each implementation alone ({@link implementationsOf}): no reader of writes carries a
616
+ * grammar of its own.
617
+ */
618
+ export declare function writeReadings(row: ProgramRow, args: readonly string[]): WriteReading[];
619
+ /** How this invocation receives its program: `text` (an option value or the program operand is program text), `stdin`
620
+ * (it reads the program from its standard input), or `undefined` (it names one — a script file, a module — or names
621
+ * none on an interpreter that then reads none). `undefined` too for a row that is no interpreter. */
622
+ export type ProgramDelivery = "text" | "stdin";
623
+ /**
624
+ * Read over the argv with the program word excluded. One rule for every doubt: an option the row does not explain never
625
+ * ENDS the search for program text. The word that names the program stops the scan, but only while every option so far
626
+ * was one the row EXPLAINS: after an option of unknown arity the next word may be its value rather than the program.
627
+ */
628
+ export declare function programDelivery(row: ProgramRow | undefined, args: readonly string[]): ProgramDelivery | undefined;
629
+ /** The language of the program an interpreter row runs: the language of its program operand, or of the first option that
630
+ * delivers program text or a program file. `undefined` for a row that runs no program text. */
631
+ export declare function programLanguageOf(row: ProgramRow | undefined): string | undefined;
632
+ /**
633
+ * The text a printer row ({@link ProgramRow.prints}) writes to its standard output, read off its argv (the program word
634
+ * excluded; `undefined` = a word whose value the command does not spell). `undefined` wherever the words do not spell the
635
+ * text: such a word, an option the row does not explain, an escape the program may interpret (a backslash: `echo -e`, an
636
+ * `echo` that reads escapes by default, every `printf` format), a format with a directive (`%`) or values to fill it, or a
637
+ * row that prints nothing it is handed.
638
+ */
639
+ export declare function printedText(row: ProgramRow | undefined, args: readonly (string | undefined)[]): string | undefined;
640
+ /**
641
+ * The argv indices some implementation of the row reads as a path it OPENS (an ordinary operand, a value or operand of a
642
+ * reading path role, a program file) while another reads them as something else (program text, a backup suffix, a
643
+ * datum) — a reading the filesystem decides. Empty where the row has one implementation, or where
644
+ * any implementation cannot account for an option of the argv (its reading is then no evidence either way).
645
+ */
646
+ export declare function wordsReadBySomeImplementations(row: ProgramRow | undefined, args: readonly string[]): ReadonlySet<number>;
647
+ /** The words an interpreter hands a module it runs by name (`python -m timeit …`) when the row says what that module does
648
+ * with them ({@link ProgramRow.modules}): the index of the first such word and their role; `undefined` when the
649
+ * invocation names no such module. Read with the role walk: the module name is the value of an option that names the
650
+ * program. */
651
+ export declare function moduleTailOf(row: ProgramRow | undefined, args: readonly string[]): {
652
+ readonly from: number;
653
+ readonly role: ArgRole;
654
+ } | undefined;
655
+ /** The arity of a launcher option spelled EXACTLY (`-u`, `--unset`, a stepped `--`): 0 for a switch or an option whose
656
+ * value exists only attached (spelled bare, it takes nothing), 1 for one that takes the next word; `undefined` for any
657
+ * other spelling and for an option the walk does not step over. */
658
+ export declare function launcherOptionArity(row: ProgramRow, tok: string): 0 | 1 | undefined;
659
+ /** The PATH role of the value a launcher option spelled EXACTLY takes (`xargs -a FILE`, `strace -o FILE`), or `undefined`
660
+ * when its value names no path. Such a value is a word the launcher opens or writes, not an operand of its own. */
661
+ export declare function launcherOptionPathRole(row: ProgramRow, tok: string): Extract<ArgRole, {
662
+ kind: "path";
663
+ }> | undefined;
664
+ /** How many tokens one launcher option occupies, or `undefined` where the row does not explain it: an arity-1 option
665
+ * separated (2), a value fused to its long name or short letter (1); a switch, an attached-only option, or a cluster of
666
+ * switches (1); a lone `-` where the launcher reads it as its own switch (1). */
667
+ export declare function launcherOptionStep(row: ProgramRow, tok: string): 1 | 2 | undefined;
668
+ /** Does a launcher that runs a shell ({@link LauncherSpec.shellText}) run one over these words — the words after it —
669
+ * rather than the program they name? Not where an implementation selects one of its {@link LauncherSpec.programWith}
670
+ * options (as that implementation reads them: past `--` a word is an operand). */
671
+ export declare function launcherRunsShell(row: ProgramRow, args: readonly string[]): boolean;
672
+ /** The spellings of a launcher's command-line options (`env -S` / `--split-string`): the value is a command line the
673
+ * launcher splits and runs. */
674
+ export declare function commandLineOptionSpellings(row: ProgramRow | undefined): readonly string[];
675
+ /** One implementation's reading of where the program text is: the text (every text option's value joined by newlines,
676
+ * or the first operand), `from-file` (an option names a FILE holding it), `unparsed` (an option the grammar does not
677
+ * declare, or a text option with nothing left to take), or `none` (no program text at all). */
678
+ export type ProgramTextReading = {
679
+ readonly text: string;
680
+ } | "from-file" | "unparsed" | "none";
681
+ /** The language of the row's program text when the read station parses it (its first positional is program text in a
682
+ * read language), else `undefined`. */
683
+ export declare function readProgramTextLanguage(row: ProgramRow | undefined): string | undefined;
684
+ /** The program text of an invocation of a row whose first positional is program text, under EACH implementation's
685
+ * grammar (no text says which one runs, so a reader combines the readings). */
686
+ export declare function programTextReadings(row: ProgramRow, args: readonly string[]): ProgramTextReading[];
687
+ /**
688
+ * The subcommand an argv (the program word excluded) names, and the row it is read by: the first word past the
689
+ * program's own options, which are read EXACTLY by the row's grammar — an option the row does not declare may take the
690
+ * next word, so no subcommand is claimed past it. `at` = the subcommand word's index; `relocated` = an option before it
691
+ * moves where the program works (a value whose role is a path with a base — `git -C <dir>`), so the subcommand's paths
692
+ * are not relative to the command's working directory. The subcommand's row carries its own grammar, operands and
693
+ * traversal, and its program's witness.
694
+ */
695
+ export declare function subcommandOf(row: ProgramRow | undefined, words: readonly string[]): {
696
+ readonly name: string;
697
+ readonly at: number;
698
+ readonly row: ProgramRow;
699
+ readonly relocated: boolean;
700
+ } | undefined;
701
+ /**
702
+ * The indices of the SETTLED words a row's subcommand reads as message text: the value of its message option attached
703
+ * or as the next word, by its own grammar. The global options are read exactly ({@link subcommandOf}); in the subcommand
704
+ * an unknown long option takes no value, an unknown short letter or an unsettled word takes the next word (which is
705
+ * then never a message).
706
+ */
707
+ export declare function messageWords(program: string, words: readonly {
708
+ readonly folded: string;
709
+ readonly expands: unknown;
710
+ }[], programIndex: number): Set<number>;
711
+ export {};