pm-ops 2026.8.31 → 2026.9.2

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.
@@ -0,0 +1,438 @@
1
+ /**
2
+ * Tokenises shell text into the commands it would actually run.
3
+ *
4
+ * A guard that decides "does any publish here omit `--provenance`" is only as
5
+ * good as its idea of what a command is. The previous scan answered that
6
+ * question with a regular expression: it blanked every quoted span so an
7
+ * advisory `echo "npm publish"` could not read as an invocation, then split the
8
+ * remainder on `&&`, `||`, `;` and a space-surrounded `|`.
9
+ *
10
+ * Both halves of that shortcut are wrong in the same direction -- they make the
11
+ * gate report a pass it has not earned:
12
+ *
13
+ * - Blanking quoted spans deletes the argument being audited. `npm publish
14
+ * "--provenance"` runs with an attestation but scans as one without, and the
15
+ * reverse case is worse: `eval "npm publish"` and `bash -c 'npm publish'` are
16
+ * real unattested publishes that vanish entirely, leaving a conventional
17
+ * attested sibling elsewhere in the file to carry the audit to green.
18
+ * - Splitting on three operators misses a backgrounding `&`, a pipe written
19
+ * without surrounding spaces (`true|npm publish`), and command substitution.
20
+ *
21
+ * So the text is tokenised the way a shell does it -- quotes resolved rather
22
+ * than erased, operators recognised as operators, `$(...)`, backticks, `eval`
23
+ * and `sh -c` payloads recursed into -- and each command records whether its
24
+ * words were quoted. Nothing downstream has to guess.
25
+ *
26
+ * This is deliberately not a shell. It resolves only provably literal scalar
27
+ * and array bindings, preserves unknown expansions, and removes redirections
28
+ * when locating command words; it does not expand globs or arithmetic. It
29
+ * exists to enumerate candidate command invocations for auditing, where
30
+ * missing one is a security failure and inventing one is merely noise.
31
+ *
32
+ * @packageDocumentation
33
+ */
34
+ /** One word of a command, after quote resolution. */
35
+ export interface ShellToken {
36
+ /** The word's text with its quoting removed. */
37
+ value: string;
38
+ /** True when any part of the word came from inside quotes. */
39
+ quoted: boolean;
40
+ /**
41
+ * True when the word's FIRST character came from inside quotes.
42
+ *
43
+ * `quoted` alone cannot tell an assignment apart from a literal that merely
44
+ * looks like one. `NPM_CONFIG_REGISTRY="https://example"` is a real
45
+ * assignment whose value happens to be quoted, while `"FOO=bar"` is a single
46
+ * quoted word that the shell does not treat as an assignment at all. Both set
47
+ * `quoted`; only the second starts inside quotes.
48
+ */
49
+ startsQuoted: boolean;
50
+ }
51
+ /** One simple command: the words it would run, in order. */
52
+ export type ShellCommand = ShellToken[];
53
+ /**
54
+ * Split shell text into the simple commands it contains.
55
+ *
56
+ * Command substitutions are scanned as well as the command containing them,
57
+ * because `VERSION=$(npm publish)` runs a publish however unusual that is, and a
58
+ * gate that only looked at the outer assignment would miss it.
59
+ *
60
+ * `eval`, `bash -c` and their siblings receive the same treatment one level
61
+ * deeper: their string argument is re-tokenised, so a publish smuggled through
62
+ * an interpreter is enumerated alongside a plain one. Recursion is bounded --
63
+ * shell text that nests evaluators more than a handful of levels deep is not
64
+ * something this repository writes, and an unbounded walk over hostile input is
65
+ * a denial of service rather than a stronger audit.
66
+ *
67
+ * @param text - Shell text, typically one file or one manifest script body.
68
+ * @param depth - Current evaluator recursion depth; callers pass nothing.
69
+ * @returns Every simple command found, outermost first.
70
+ */
71
+ export declare function tokenizeCommands(text: string, depth?: number): ShellCommand[];
72
+ /**
73
+ * Name the program a command runs, or nothing when it runs none.
74
+ *
75
+ * Leading `NAME=value` assignments and wrapper words are skipped, and a path is
76
+ * reduced to its basename so `/usr/local/bin/npm publish` is recognised. The
77
+ * distinction this exists to draw is command *position*: `echo npm publish`
78
+ * prints three words and publishes nothing, while the previous scan searched
79
+ * the whole line for the word `npm` and counted it as an invocation.
80
+ *
81
+ * @param command - One simple command's tokens.
82
+ * @returns The program's basename, or undefined for an empty or assignment-only command.
83
+ */
84
+ export declare function commandName(input: ShellCommand): string | undefined;
85
+ /**
86
+ * Enumerate every reading of a command that could name a program.
87
+ *
88
+ * `commandName` answers "what does this command run" and answers it once. That
89
+ * is right for reporting and wrong for auditing, because a wrapper's options
90
+ * are not all known: `sudo -u root npm publish` stops at `root`, since `-u`
91
+ * takes a value and nothing here knows that. Enumerating the value-taking
92
+ * options of every wrapper would be a list that silently goes stale, and each
93
+ * omission is a publish that disappears from the audit.
94
+ *
95
+ * So once a wrapper has been consumed, every later word is also offered as a
96
+ * possible program, with the words after it as its arguments. An auditor asking
97
+ * "does any publish here lack an attestation" then cannot miss one behind a
98
+ * wrapper option it has never heard of.
99
+ *
100
+ * The cost is noise, never a miss: `sudo -u npm publish` -- a user actually
101
+ * named `npm` -- is offered as a publish that no shell would run. For a gate
102
+ * whose failure mode is an unattested release, a spurious finding an operator
103
+ * dismisses is the cheaper error.
104
+ *
105
+ * A command with no wrapper yields exactly one reading, so ordinary commands
106
+ * are unaffected.
107
+ *
108
+ * @param command - One simple command's tokens.
109
+ * @returns Each candidate reading, the command's own first.
110
+ */
111
+ export declare function commandCandidates(input: ShellCommand): ShellCommand[];
112
+ /**
113
+ * List a command's arguments -- everything after its program name.
114
+ *
115
+ * @param command - One simple command's tokens.
116
+ * @returns The argument tokens, in order.
117
+ */
118
+ export declare function commandArguments(input: ShellCommand): ShellToken[];
119
+ /** A tracked file's path and contents. */
120
+ export interface SourceFile {
121
+ /** Repository-relative path. */
122
+ file: string;
123
+ /** File contents. */
124
+ text: string;
125
+ }
126
+ /**
127
+ * Collapse shell and YAML line continuations so one logical command is one string.
128
+ *
129
+ * A backslash at end of line joins the next line; without this every multi-line
130
+ * invocation looks like a set of fragments, none of which carries both the
131
+ * version input and the date flag.
132
+ *
133
+ * @param text - Raw file contents.
134
+ * @returns The same text with continuations joined.
135
+ */
136
+ export declare function joinContinuations(text: string): string;
137
+ /**
138
+ * Strip the YAML block indentation from `run:` block scalars.
139
+ *
140
+ * GitHub Actions takes a `run:` block's text, removes the indentation YAML
141
+ * gave it, and hands the result to bash — so the shell never sees the leading
142
+ * whitespace the raw workflow file carries. The scanner reads the raw file,
143
+ * and exactly one of its rules is whitespace-sensitive: a heredoc terminator
144
+ * is recognised only at the start of the line the shell sees. A terminator
145
+ * compared against a YAML-indented line therefore never matches, the heredoc
146
+ * swallows the rest of the file, every later assignment is payload, and a
147
+ * `$NPM publish` after the heredoc is omitted from the audit while an
148
+ * attested sibling elsewhere satisfies the non-vacuity guard — the scan
149
+ * reports clean over an unattested publish.
150
+ *
151
+ * Dedenting the block content restores the text bash actually receives. Every
152
+ * other rule in the scanner already tolerates leading whitespace
153
+ * (`STANDALONE_ASSIGNMENT` opens with `^[ \t]*`, control closers and function
154
+ * openers are matched against trimmed syntax, a comment starts after any
155
+ * separator or whitespace, and `bashArrays` anchors on a word boundary), so
156
+ * this function changes nothing else about what the scanner sees.
157
+ *
158
+ * Only `run:` blocks are dedented, because `run` is the key GitHub Actions
159
+ * executes; a block scalar under any other key is data no shell runs, and
160
+ * stripping its indentation would be rewriting prose. The block's indentation
161
+ * is learned from its first non-blank line, as YAML itself learns it, a line
162
+ * keeps any indentation beyond the block's own, and the block ends at the
163
+ * first non-blank line indented less — which is where YAML ends it too. A
164
+ * `run:`-shaped line inside another block's content is content, not a header,
165
+ * because the scanner walks the file once, forward, consuming each block
166
+ * before looking for the next.
167
+ *
168
+ * @param text - A workflow file's raw contents.
169
+ * @returns The same text with each `run:` block's content dedented.
170
+ */
171
+ export declare function dedentRunBlocks(text: string): string;
172
+ /**
173
+ * Index bash array assignments so a shared options array can be expanded.
174
+ *
175
+ * The release workflows declare `common=( ... )` once and pass `"${common[@]}"`
176
+ * to each invocation, precisely so the invocations cannot drift. A scan that
177
+ * reads only the invocation line therefore sees none of the shared flags.
178
+ * Quoted or escaped closing parentheses are members, not array boundaries; an
179
+ * unsupported array shape is left unknown so verification fails closed.
180
+ *
181
+ * @param text - File contents with continuations already joined.
182
+ * @returns Array name mapped to the flag text it holds.
183
+ */
184
+ export declare function bashArrays(text: string): Map<string, string>;
185
+ /**
186
+ * Read persistent literal assignments from one control-operator-delimited segment.
187
+ *
188
+ * The line segmenter has already separated `;`, `&&`, and `||`. Shell keywords
189
+ * and grouping operators can still precede an assignment in the remaining text:
190
+ * `then NPM=npm`, `do FLAG=--provenance`, and `( NPM=npm` are all assignment-only
191
+ * commands. Tokenising finds command position without an anchored text pattern.
192
+ *
193
+ * The ordinary line-opening parser remains the more permissive path for quoted
194
+ * and escaped literal values. A compound-position assignment is accepted only
195
+ * when its token was wholly unquoted and substitution-free; uncertainty is left
196
+ * unresolved so the auditor can refuse rather than invent a binding.
197
+ *
198
+ * @param segment - One segment returned by {@link segmentShellLine}.
199
+ * @returns Literal scalar bindings made by assignment-only commands.
200
+ */
201
+ export declare function literalScalarAssignments(segment: string): Map<string, string>;
202
+ /**
203
+ * Report which lines of a file are heredoc *body* rather than shell source.
204
+ *
205
+ * A heredoc body is data on a command's stdin. It cannot bind a variable in the
206
+ * shell that reads it, so indexing `FLAG=--provenance` out of one invents a
207
+ * binding the shell never makes, and an unattested `npm publish $FLAG` then
208
+ * borrowed that flag and passed the attestation gate. Every heredoc spelling
209
+ * hid a binding the same way: the plain `<<EOF`, the space- and tab-separated
210
+ * `<< EOF`, the quoted `<<'EOF'` and `<<"EOF"`, the tab-stripping `<<-EOF`,
211
+ * and one written after another redirection (`cat > f <<EOF`).
212
+ *
213
+ * Only *binding* is suppressed here, never publish detection. A heredoc can
214
+ * carry a script that is written to a file and executed later, so an
215
+ * `npm publish` inside one remains a publish path this scan must report. Both
216
+ * halves of that split fail closed: an unindexed name leaves `$FLAG`
217
+ * unresolved, so the publish reads as unattested and the gate fails, and a
218
+ * publish written into a heredoc still has to carry the flag itself.
219
+ *
220
+ * Several heredocs may open on one line (`cat <<A <<B`); bash reads their
221
+ * bodies in the order the redirections appear, which is the order kept here. A
222
+ * body whose delimiter never arrives runs to the end of the file, exactly as
223
+ * the shell would read it.
224
+ *
225
+ * @param lines - The file's lines, with continuations already joined.
226
+ * @returns One flag per line, true where that line is heredoc body.
227
+ */
228
+ export declare function heredocBodyLines(lines: string[]): boolean[];
229
+ /**
230
+ * Report body-data lines on which Bash performs parameter expansion.
231
+ *
232
+ * Quote removal still applies to every delimiter, but quoting any part of that
233
+ * delimiter suppresses expansion in its body. Terminator lines never expand.
234
+ *
235
+ * @param lines - The file's lines, with continuations already joined.
236
+ * @returns One flag per line, true only for expandable heredoc body data.
237
+ */
238
+ export declare function heredocExpansionLines(lines: string[]): boolean[];
239
+ /**
240
+ * Parse the scalar names one command unsets, or nothing.
241
+ *
242
+ * `unset FLAG` after `FLAG=--provenance` leaves the shell passing no flag at
243
+ * all, so retaining the binding let an unattested publish borrow `--provenance`
244
+ * and pass the gate. Commands are read through the tokeniser rather than an
245
+ * anchored whole-line pattern, because `echo ready; unset FLAG` unsets exactly
246
+ * as effectively as a line holding nothing else.
247
+ *
248
+ * An unset the parent shell would not actually perform -- inside `$(...)`, or
249
+ * one the tokeniser surfaces from a nested body -- is honoured too, because the
250
+ * two directions of error are not symmetric. Dropping a binding can only make a
251
+ * later `$FLAG` unresolve, which reads as an unattested publish and *fails* the
252
+ * gate; keeping one the shell discarded is what lets an unattested publish
253
+ * pass. Erring toward the false alarm is the only direction that cannot ship an
254
+ * unattested artifact.
255
+ *
256
+ * Leading environment assignments and the `command unset` / `builtin unset`
257
+ * wrapper forms all reach the same builtin and therefore remove the same
258
+ * bindings.
259
+ *
260
+ * `-v` selects the variable namespace, which is what this map models. `-f`
261
+ * unsets a shell function and touches no variable, so such a command is left to
262
+ * bind nothing.
263
+ *
264
+ * @param command - One tokenised command.
265
+ * @returns The scalar names unset, empty when the command unsets none.
266
+ */
267
+ export declare function unsetNames(command: ShellCommand): string[];
268
+ /**
269
+ * Split one shell line into segments separated by control operators.
270
+ *
271
+ * Quoting and backslash escaping are respected so that operators inside quotes
272
+ * or after a backslash do not split. Comments (`#` at a word boundary) absorb
273
+ * the rest of the line into the preceding segment. The returned array
274
+ * interleaves text segments with operator segments (`;`, `&`, `&&`, `|`, `||`).
275
+ *
276
+ * @param line - One line of shell source (continuations already joined).
277
+ * @returns Segments where control operators are separate entries.
278
+ */
279
+ export declare function segmentShellLine(line: string): string[];
280
+ /**
281
+ * Net change in `case` nesting contributed by one line.
282
+ *
283
+ * Tracked separately from block depth because a `case` arm label ends in a bare
284
+ * `)` that is not a parenthesis close. Without knowing a `case` is open, that
285
+ * `)` decrements the depth counter and tags an assignment inside an untaken arm
286
+ * as file-scoped, which then attests a publish after `esac`.
287
+ *
288
+ * @param line - One already-continuation-joined source line.
289
+ * @returns +1 for each `case` opened, -1 for each `esac` closed.
290
+ */
291
+ export declare function caseDepthChange(line: string): number;
292
+ /**
293
+ * Report whether a segment's `case` arm label belongs to an ENCLOSING `case`.
294
+ *
295
+ * A segment can both close one arm and open a nested block, and the two cases
296
+ * need opposite treatment. In `b) case "$Y" in` the label precedes the opener,
297
+ * so it starts a sibling of the previous arm and that arm's bindings must be
298
+ * cleared. In `case "$Y" in c) npm publish` the opener precedes the label, so
299
+ * the label is the FIRST arm of the block this very segment opens - it has no
300
+ * earlier sibling, and clearing there would discard a binding the enclosing arm
301
+ * legitimately made, refusing a publish the shell does attest.
302
+ *
303
+ * Position is what separates them, which is why this compares indices rather
304
+ * than asking the two questions independently.
305
+ *
306
+ * @param line - One shell segment.
307
+ * @returns True when the segment opens an arm of a `case` it did not itself open.
308
+ */
309
+ export declare function startsEnclosingCaseArm(line: string): boolean;
310
+ /**
311
+ * Decide whether text starts a new `case` arm.
312
+ *
313
+ * An arm label ends at an unquoted `)` that does not close a parenthesis group.
314
+ * Treating an uncertain bare close as an arm boundary is deliberately
315
+ * conservative: it discards bindings from the preceding arm, which can only
316
+ * make later attestation fail closed.
317
+ *
318
+ * @param line - One already-continuation-joined source segment inside a case.
319
+ * @returns True when the segment contains a case-arm label terminator.
320
+ */
321
+ export declare function startsCaseArm(line: string): boolean;
322
+ /**
323
+ * Net change in block nesting contributed by one line.
324
+ *
325
+ * Counts shell keywords and brace/parenthesis groups outside quotes. This is a
326
+ * nesting count, not a parse: it exists to tell "this assignment is inside
327
+ * something conditional" from "this assignment is the file's own scope", which
328
+ * is the distinction attestation depends on.
329
+ *
330
+ * @param line - One already-continuation-joined source line.
331
+ * @param insideCase - Whether a `case` is open, so a bare `)` is an arm label
332
+ * rather than a group close.
333
+ * @returns Positive when the line opens more blocks than it closes.
334
+ */
335
+ export declare function blockDepthChange(line: string, insideCase?: boolean): number;
336
+ /**
337
+ * Index scalar assignments per line, so a command held in a variable can be
338
+ * audited against the bindings that stand where it actually runs.
339
+ *
340
+ * `CMD="npm publish"` followed by `$CMD` runs a publish that no scan of the
341
+ * invocation line can see, because the invocation line contains no publish. The
342
+ * assignment is where the command actually is. `NPM=npm` followed by
343
+ * `$NPM publish` hides one the same way, so unquoted values are indexed too.
344
+ *
345
+ * A name is taken only where a line OPENS with one assignment carrying a fully
346
+ * literal value and holds nothing else before its end or a `;`. `NPM=npm; cmd`
347
+ * therefore binds, because the semicolon ends the assignment and the shell keeps
348
+ * it afterwards, while `NPM=npm cmd` does not, because that binding lasts only
349
+ * for the command it precedes. Requiring the line to OPEN with the assignment is
350
+ * what keeps a `;` inside a comment from exposing one. That single rule keeps
351
+ * the scan from inventing
352
+ * bindings the shell never makes, each of which let an unattested publish
353
+ * borrow a flag and pass the gate:
354
+ *
355
+ * - `# FLAG=--provenance` is a comment, and a comment is not a line that is
356
+ * only an assignment.
357
+ * - `echo "config NPM=npm"` is a command with an argument, not an assignment.
358
+ * - `FLAG=--provenance some-command` binds only for that one command; the shell
359
+ * does not keep it afterwards, so neither does this map.
360
+ * - `$(FLAG=--provenance)` binds inside a subshell that the outer shell never
361
+ * sees.
362
+ * - `NPM=npm$SUFFIX` and `NPM=npm$(printf foo)` are not literal. The value must
363
+ * match to the end of the line, so a prefix is never mistaken for the whole
364
+ * value -- the mistake that let a scan analyse a different command from the
365
+ * one the shell runs.
366
+ *
367
+ * `export NPM=npm`, a trailing `# comment` and a CRLF line ending are all still
368
+ * assignments: refusing them left `$NPM` unresolved, and an attested publish
369
+ * elsewhere in the file then satisfied the non-vacuity guard, so being too
370
+ * strict here passes an unattested publish just as being too loose does.
371
+ *
372
+ * Escapes are honoured outside single quotes, so `NPM=npm\\ publish` is one word
373
+ * holding a command while `CMD='"'"'a\\b'"'"' keeps its backslash as the shell does.
374
+ * A value that still carries a substitution, backtick, quote or parenthesis
375
+ * after unescaping is refused: inlining `pkg_name="$(node -p …)"` injects an
376
+ * unbalanced parenthesis into an unrelated command, and the scan then reports
377
+ * invocations that are not there while losing the one that is -- a false
378
+ * verdict in both directions, which is worse than not resolving the variable.
379
+ * Shell metacharacters (`;`, `&`, `|`, `<`, `>`, `{`, `}`) are also refused
380
+ * after unescaping: an escaped `\;` would become `;`, and the tokeniser would
381
+ * split on it, so `FLAG=--provenance\;` would let an unattested publish borrow
382
+ * a flag the shell passes as a literal `--provenance;` argument.
383
+ *
384
+ * Two things the shell does that a line-at-a-time reading missed both let an
385
+ * unattested publish pass. A heredoc body is stdin data and binds nothing, yet
386
+ * `FLAG=--provenance` inside one was indexed as an assignment; see
387
+ * {@link heredocBodyLines}. And `unset FLAG` discards a binding, yet the map
388
+ * kept it, so a later `npm publish $FLAG` borrowed a flag the shell no longer
389
+ * passed; see the deletion below.
390
+ *
391
+ * Because `unset` makes a binding's lifetime positional, the result is one map
392
+ * per line rather than one per file. Reading every invocation against the
393
+ * file's end state would report an unattested publish for a flag that was
394
+ * genuinely set where the publish runs and unset only afterwards.
395
+ *
396
+ * @param text - File contents with continuations already joined.
397
+ * @returns One map per line: the bindings in effect once that line has run.
398
+ */
399
+ export declare function shellScalarsByLine(text: string): Array<Map<string, string>>;
400
+ /**
401
+ * The scalar bindings standing at the end of a file.
402
+ *
403
+ * @param text - File contents with continuations already joined.
404
+ * @returns Variable name mapped to the literal text it holds.
405
+ */
406
+ export declare function shellScalars(text: string): Map<string, string>;
407
+ /**
408
+ * Expand unescaped, non-single-quoted scalar references against known bindings.
409
+ *
410
+ * An unknown name is left in place for the same reason an unknown array is:
411
+ * erasing it would turn "not understood" into "carries no flags", which reads
412
+ * as a pass.
413
+ *
414
+ * @param line - One logical command.
415
+ * @param scalars - Scalar assignments from the same file.
416
+ * @returns The command with expandable known scalar references inlined.
417
+ */
418
+ export declare function expandScalars(line: string, scalars: Map<string, string>): string;
419
+ /**
420
+ * Expand `"${name[@]}"` references against the file's array declarations.
421
+ *
422
+ * An unknown name is left untouched rather than erased: silently dropping it
423
+ * would turn "this scan does not understand the command" into "this command has
424
+ * no flags", which reads as a pass.
425
+ *
426
+ * @param line - One logical command.
427
+ * @param arrays - Array declarations from the same file.
428
+ * @returns The command with referenced array contents inlined.
429
+ */
430
+ export declare function expandArrays(line: string, arrays: Map<string, string>): string;
431
+ /** The outcome of one verifier run. */
432
+ export interface VerifierResult {
433
+ /** Reasons the run failed; empty means it passed. */
434
+ failures: string[];
435
+ /** Lines describing what was checked, for the operator. */
436
+ notes: string[];
437
+ }
438
+ //# sourceMappingURL=shell-scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-scan.d.ts","sourceRoot":"","sources":["../shell-scan.ts"],"names":[],"mappings":"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"}