@molecule/api-ai-tools 1.13.1 → 1.14.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/README.md +112 -2
- package/dist/command-position.d.ts +26 -0
- package/dist/command-position.d.ts.map +1 -1
- package/dist/command-position.js +314 -59
- package/dist/suite-overlap.d.ts +3 -1
- package/dist/suite-overlap.d.ts.map +1 -1
- package/dist/suite-overlap.js +130 -7
- package/dist/tools.d.ts +15 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +20 -1
- package/dist/utilities.d.ts +36 -0
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js +86 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
|
3
3
|
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
4
|
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
5
|
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
-
Generated: 2026-10-
|
|
6
|
+
Generated: 2026-10-23T00:59:47.543Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/api-ai-tools
|
|
@@ -140,6 +140,13 @@ still names the deployed host (xr-molecule-flash-m103 +28:08).
|
|
|
140
140
|
|
|
141
141
|
```typescript
|
|
142
142
|
interface LocatedCommandSegment {
|
|
143
|
+
/**
|
|
144
|
+
* Directory-scope ancestry supplied by the existing shell parse, outermost first.
|
|
145
|
+
* Parenthesized groups and nested `sh -c` strings have their own shell directory;
|
|
146
|
+
* braces share their parent's. Identities are opaque and local to this invocation.
|
|
147
|
+
* Absent for ordinary statements in the outer shell, preserving their existing shape.
|
|
148
|
+
*/
|
|
149
|
+
shellScope?: readonly string[]
|
|
143
150
|
/**
|
|
144
151
|
* What the statement runs, or null when it only sets variables (`BASE=http://…` on its own):
|
|
145
152
|
* that shape persists in the shell, so a caller following assignments across `;`/`&&` has to
|
|
@@ -148,6 +155,13 @@ interface LocatedCommandSegment {
|
|
|
148
155
|
segment: CommandSegment | null
|
|
149
156
|
/** The statement's own leading `NAME=value` words, as written (`TEST_MODE=fullstack`). */
|
|
150
157
|
assignments: readonly string[]
|
|
158
|
+
/**
|
|
159
|
+
* Assignments whose values expand at this source statement, when different from
|
|
160
|
+
* inherited environment bindings. A nested `sh -c` carries outer bindings into
|
|
161
|
+
* every entry, but expands its caller's assignment values only before its first
|
|
162
|
+
* command. Absent when the ordinary `assignments` list is also the source list.
|
|
163
|
+
*/
|
|
164
|
+
sourceAssignments?: readonly string[]
|
|
151
165
|
/**
|
|
152
166
|
* The offset in the command of the statement's first word, or null for a segment inside a
|
|
153
167
|
* nested `sh -c '<command>'` string — its positions are offsets in THAT string, not in this
|
|
@@ -1491,6 +1505,19 @@ interface SuiteRunPipelinePlacement {
|
|
|
1491
1505
|
}
|
|
1492
1506
|
```
|
|
1493
1507
|
|
|
1508
|
+
#### `RunningLogRead`
|
|
1509
|
+
|
|
1510
|
+
A bounded, contiguous read of a running task's own log.
|
|
1511
|
+
|
|
1512
|
+
```typescript
|
|
1513
|
+
interface RunningLogRead {
|
|
1514
|
+
/** The log's last {@link RUNNING_LOG_READ_BYTES} bytes, contiguous, as one string. */
|
|
1515
|
+
text: string
|
|
1516
|
+
/** How many bytes the WHOLE log holds, or null when the read did not answer its size. */
|
|
1517
|
+
bytes: number | null
|
|
1518
|
+
}
|
|
1519
|
+
```
|
|
1520
|
+
|
|
1494
1521
|
#### `FailedTest`
|
|
1495
1522
|
|
|
1496
1523
|
One failed test, as a running suite's log names it.
|
|
@@ -1845,6 +1872,23 @@ function commandSegments(command: string): CommandSegment[]
|
|
|
1845
1872
|
|
|
1846
1873
|
**Returns:** One entry per statement or pipeline stage that runs something, in order.
|
|
1847
1874
|
|
|
1875
|
+
#### `commandSubstitutions(command)`
|
|
1876
|
+
|
|
1877
|
+
The direct executable command-substitution bodies in shell text, in source order.
|
|
1878
|
+
|
|
1879
|
+
Uses the same quote, comment and heredoc boundaries as {@link executedCommands}.
|
|
1880
|
+
Single-quoted and escaped text is inert. Nested substitutions stay inside their
|
|
1881
|
+
parent's body so a caller can recurse with a separate working-directory scope
|
|
1882
|
+
for each body; a `cd` inside one must not affect its sibling or the outer shell.
|
|
1883
|
+
|
|
1884
|
+
```typescript
|
|
1885
|
+
function commandSubstitutions(command: string): string[]
|
|
1886
|
+
```
|
|
1887
|
+
|
|
1888
|
+
- `command` — The shell text to read, including any leading assignments.
|
|
1889
|
+
|
|
1890
|
+
**Returns:** Each direct `$(…)` or backtick body, without its delimiters.
|
|
1891
|
+
|
|
1848
1892
|
#### `executedCommands(command)`
|
|
1849
1893
|
|
|
1850
1894
|
Every command a shell command actually executes, at any depth — the statements themselves, the
|
|
@@ -2691,7 +2735,9 @@ positional selection the run carried (a spec file, a suite directory or a regex
|
|
|
2691
2735
|
The re-run keeps the run's `> <file>` redirect only in the sense of keeping its OUTPUT there:
|
|
2692
2736
|
the target is rewritten to a fresh sibling ({@link redirectRunnerOutputsToFreshFiles}), so a
|
|
2693
2737
|
re-run never overwrites the log the run itself is the evidence for (xr-molecule-flash-m173) —
|
|
2694
|
-
and the setup around the run keeps its own file writes untouched (xr-molecule-flash-m429).
|
|
2738
|
+
and the setup around the run keeps its own file writes untouched (xr-molecule-flash-m429). A
|
|
2739
|
+
`tail`/`head`/`cat`/`grep` chained after the run that reads that exact log is shown the fresh
|
|
2740
|
+
sibling instead, so the re-run displays the run it performed (xr-molecule-flash-o03).
|
|
2695
2741
|
|
|
2696
2742
|
`config` is the config the run was measured under ({@link withSuiteConfig}): the narrowed re-run
|
|
2697
2743
|
carries it whenever the command itself does not, so a run that dropped `--config` cannot be
|
|
@@ -2890,6 +2936,26 @@ function moleculeDistReadNote(path: string): string | null
|
|
|
2890
2936
|
|
|
2891
2937
|
**Returns:** The note, or null when the path is not inside a package's `dist`.
|
|
2892
2938
|
|
|
2939
|
+
#### `registeredTaskLogCommand(taskId)`
|
|
2940
|
+
|
|
2941
|
+
The command that reads a REGISTERED background task's own log as one bounded contiguous window
|
|
2942
|
+
({@link runningLogReadCommand}), with the file its launch redirects to when the launch recorded
|
|
2943
|
+
one.
|
|
2944
|
+
|
|
2945
|
+
The task id is the ownership: it is the handle `wait_for_task` returned, `/tmp/${taskId}.log` is
|
|
2946
|
+
the log this platform's launcher writes for it, and the redirect target is the file this
|
|
2947
|
+
process's own launch registered for that id — never a path parsed out of a command by the
|
|
2948
|
+
caller. A diagnosis that reads a running walk must not build a `/tmp` path of its own
|
|
2949
|
+
(xr-molecule-flash-l07: the wait's DISPLAY was diagnosed as if it were the log).
|
|
2950
|
+
|
|
2951
|
+
```typescript
|
|
2952
|
+
function registeredTaskLogCommand(taskId: string): string | null
|
|
2953
|
+
```
|
|
2954
|
+
|
|
2955
|
+
- `taskId` — The `mol-bg-…` handle the wait returned.
|
|
2956
|
+
|
|
2957
|
+
**Returns:** The read command, or null when the handle is not a task id this platform minted.
|
|
2958
|
+
|
|
2893
2959
|
#### `shellInstalledPackageProbe(run)`
|
|
2894
2960
|
|
|
2895
2961
|
Build an {@link InstalledPackageProbe} from a shell runner (a backend's
|
|
@@ -4213,6 +4279,42 @@ function runningCauseCommand(log: string, own?: string): string
|
|
|
4213
4279
|
|
|
4214
4280
|
**Returns:** The shell command, safe to hand to the execution backend as-is.
|
|
4215
4281
|
|
|
4282
|
+
#### `runningLogReadCommand(log, own)`
|
|
4283
|
+
|
|
4284
|
+
The shell command whose stdout is a bounded CONTIGUOUS read of a running task's own log: the
|
|
4285
|
+
log's byte size, then its last {@link RUNNING_LOG_READ_BYTES} bytes.
|
|
4286
|
+
|
|
4287
|
+
{@link runningOutputSliceCommand} is the wrong read for a diagnosis, and l07 is the finding: it
|
|
4288
|
+
stitches the first 40 grep-selected failure lines to the last 1 000 bytes with a blank line
|
|
4289
|
+
between, so the tail is DISJOINT from the headers above it. Read as one log, the last numbered
|
|
4290
|
+
header absorbs whatever the tail starts with — a clipped skipped-test title became the cause of
|
|
4291
|
+
a genuine failure (xr-molecule-flash-l07). A contiguous window can only ever hold real
|
|
4292
|
+
neighbouring lines of one log.
|
|
4293
|
+
|
|
4294
|
+
The size rides along so a caller can say when the window is only the log's end
|
|
4295
|
+
({@link parseRunningLogRead}); without it a tail reads as the whole run.
|
|
4296
|
+
|
|
4297
|
+
```typescript
|
|
4298
|
+
function runningLogReadCommand(log: string, own?: string): string
|
|
4299
|
+
```
|
|
4300
|
+
|
|
4301
|
+
- `log` — The task log path.
|
|
4302
|
+
- `own` — A file the command redirects its own output to, if any.
|
|
4303
|
+
|
|
4304
|
+
**Returns:** The shell command, safe to hand to the execution backend as-is.
|
|
4305
|
+
|
|
4306
|
+
#### `parseRunningLogRead(stdout)`
|
|
4307
|
+
|
|
4308
|
+
The two parts of {@link runningLogReadCommand}'s answer.
|
|
4309
|
+
|
|
4310
|
+
```typescript
|
|
4311
|
+
function parseRunningLogRead(stdout: string): RunningLogRead | null
|
|
4312
|
+
```
|
|
4313
|
+
|
|
4314
|
+
- `stdout` — The command's stdout.
|
|
4315
|
+
|
|
4316
|
+
**Returns:** The window and the whole log's byte size, or null when the size line is absent (the read did not run, so nothing may be said about the log).
|
|
4317
|
+
|
|
4216
4318
|
#### `repeatingFailure(log)`
|
|
4217
4319
|
|
|
4218
4320
|
The cause repeating among a running suite's failures, or null.
|
|
@@ -5185,6 +5287,14 @@ Bytes of a running log a repeating-cause look reads back.
|
|
|
5185
5287
|
const REPEATING_CAUSE_TAIL_BYTES: 40000
|
|
5186
5288
|
```
|
|
5187
5289
|
|
|
5290
|
+
#### `RUNNING_LOG_READ_BYTES`
|
|
5291
|
+
|
|
5292
|
+
Bytes of a running log a diagnostic note reads back: one {@link REPEATING_CAUSE_TAIL_BYTES} window.
|
|
5293
|
+
|
|
5294
|
+
```typescript
|
|
5295
|
+
const RUNNING_LOG_READ_BYTES: 40000
|
|
5296
|
+
```
|
|
5297
|
+
|
|
5188
5298
|
#### `REPEATING_FAILURE_MIN`
|
|
5189
5299
|
|
|
5190
5300
|
DISTINCT tests that must share one signature before a running suite's repeating cause is named.
|
|
@@ -90,6 +90,18 @@ export interface ExecutedCommand {
|
|
|
90
90
|
/** The program and its arguments as one line, what a pattern anchored at the program matches. */
|
|
91
91
|
text: string;
|
|
92
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* The direct executable command-substitution bodies in shell text, in source order.
|
|
95
|
+
*
|
|
96
|
+
* Uses the same quote, comment and heredoc boundaries as {@link executedCommands}.
|
|
97
|
+
* Single-quoted and escaped text is inert. Nested substitutions stay inside their
|
|
98
|
+
* parent's body so a caller can recurse with a separate working-directory scope
|
|
99
|
+
* for each body; a `cd` inside one must not affect its sibling or the outer shell.
|
|
100
|
+
*
|
|
101
|
+
* @param command - The shell text to read, including any leading assignments.
|
|
102
|
+
* @returns Each direct `$(…)` or backtick body, without its delimiters.
|
|
103
|
+
*/
|
|
104
|
+
export declare function commandSubstitutions(command: string): string[];
|
|
93
105
|
/**
|
|
94
106
|
* Every command a shell command actually executes, at any depth — the statements themselves, the
|
|
95
107
|
* body of a `sh -c '<command>'`, and the body of every command substitution (`$(…)`, backticks).
|
|
@@ -122,6 +134,13 @@ export declare function executedCommands(command: string): ExecutedCommand[];
|
|
|
122
134
|
* still names the deployed host (xr-molecule-flash-m103 +28:08).
|
|
123
135
|
*/
|
|
124
136
|
export interface LocatedCommandSegment {
|
|
137
|
+
/**
|
|
138
|
+
* Directory-scope ancestry supplied by the existing shell parse, outermost first.
|
|
139
|
+
* Parenthesized groups and nested `sh -c` strings have their own shell directory;
|
|
140
|
+
* braces share their parent's. Identities are opaque and local to this invocation.
|
|
141
|
+
* Absent for ordinary statements in the outer shell, preserving their existing shape.
|
|
142
|
+
*/
|
|
143
|
+
shellScope?: readonly string[];
|
|
125
144
|
/**
|
|
126
145
|
* What the statement runs, or null when it only sets variables (`BASE=http://…` on its own):
|
|
127
146
|
* that shape persists in the shell, so a caller following assignments across `;`/`&&` has to
|
|
@@ -130,6 +149,13 @@ export interface LocatedCommandSegment {
|
|
|
130
149
|
segment: CommandSegment | null;
|
|
131
150
|
/** The statement's own leading `NAME=value` words, as written (`TEST_MODE=fullstack`). */
|
|
132
151
|
assignments: readonly string[];
|
|
152
|
+
/**
|
|
153
|
+
* Assignments whose values expand at this source statement, when different from
|
|
154
|
+
* inherited environment bindings. A nested `sh -c` carries outer bindings into
|
|
155
|
+
* every entry, but expands its caller's assignment values only before its first
|
|
156
|
+
* command. Absent when the ordinary `assignments` list is also the source list.
|
|
157
|
+
*/
|
|
158
|
+
sourceAssignments?: readonly string[];
|
|
133
159
|
/**
|
|
134
160
|
* The offset in the command of the statement's first word, or null for a segment inside a
|
|
135
161
|
* nested `sh -c '<command>'` string — its positions are offsets in THAT string, not in this
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-position.d.ts","sourceRoot":"","sources":["../src/command-position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,uFAAuF;AACvF,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,qFAAqF;IACrF,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,4FAA4F;IAC5F,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B;
|
|
1
|
+
{"version":3,"file":"command-position.d.ts","sourceRoot":"","sources":["../src/command-position.ts"],"names":[],"mappings":"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"}
|
package/dist/command-position.js
CHANGED
|
@@ -32,10 +32,246 @@
|
|
|
32
32
|
*
|
|
33
33
|
* @module
|
|
34
34
|
*/
|
|
35
|
-
/** A command's words, quotes kept whole — the same reading a printed-source check uses. */
|
|
36
|
-
const WORD = /"(?:\\.|[^"\\])*"|'[^']*'|\S+/g;
|
|
37
35
|
/** Shell words that stand alone: grouping, never an argument. */
|
|
38
36
|
const GROUPING = new Set(['(', ')', '{', '}']);
|
|
37
|
+
/** The index just past a single-quoted string that starts at `at` (its opening quote). */
|
|
38
|
+
function singleQuotedEnd(text, at) {
|
|
39
|
+
const close = text.indexOf("'", at + 1);
|
|
40
|
+
return close === -1 ? text.length : close + 1;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The index just past a double-quoted string that starts at `at`. A command substitution or a
|
|
44
|
+
* backtick inside it is skipped as a unit, because a `"` inside one belongs to the nested command,
|
|
45
|
+
* not to this string (`DIR="$(cd "$(dirname "$0")" && pwd)"`).
|
|
46
|
+
*/
|
|
47
|
+
function doubleQuotedEnd(text, at) {
|
|
48
|
+
let i = at + 1;
|
|
49
|
+
while (i < text.length) {
|
|
50
|
+
const char = text[i] ?? '';
|
|
51
|
+
if (char === '\\') {
|
|
52
|
+
i += 2;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (char === '"')
|
|
56
|
+
return i + 1;
|
|
57
|
+
if (char === '`') {
|
|
58
|
+
i = backtickEnd(text, i);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (char === '$' && text[i + 1] === '(') {
|
|
62
|
+
i = substitutionEnd(text, i + 2);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (char === '$' && text[i + 1] === '{') {
|
|
66
|
+
i = parameterEnd(text, i + 2);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
i += 1;
|
|
70
|
+
}
|
|
71
|
+
return text.length;
|
|
72
|
+
}
|
|
73
|
+
/** The index just past a backtick substitution that starts at `at` (`\`` is literal, not a close). */
|
|
74
|
+
function backtickEnd(text, at) {
|
|
75
|
+
let i = at + 1;
|
|
76
|
+
while (i < text.length) {
|
|
77
|
+
if (text[i] === '\\') {
|
|
78
|
+
i += 2;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (text[i] === '`')
|
|
82
|
+
return i + 1;
|
|
83
|
+
i += 1;
|
|
84
|
+
}
|
|
85
|
+
return text.length;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The index just past a `$( … )` command substitution whose body starts at `at`. The body is NOT
|
|
89
|
+
* evaluated and its whitespace splits nothing: only its closing `)` is looked for, through quotes,
|
|
90
|
+
* escapes and nested substitutions. An unclosed substitution runs to the end of the text.
|
|
91
|
+
*/
|
|
92
|
+
function substitutionEnd(text, at) {
|
|
93
|
+
let depth = 1;
|
|
94
|
+
let i = at;
|
|
95
|
+
while (i < text.length) {
|
|
96
|
+
const char = text[i] ?? '';
|
|
97
|
+
// A `#` in the nested command starts a comment, so a `$(` or `)` inside it is data — the same
|
|
98
|
+
// reading `splitCommand` makes (`$(printf x # $(` opens nothing).
|
|
99
|
+
if (char === '#' && commentStartsAt(text, i)) {
|
|
100
|
+
const newline = text.indexOf('\n', i);
|
|
101
|
+
i = newline === -1 ? text.length : newline;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (char === '\\') {
|
|
105
|
+
i += 2;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (char === "'") {
|
|
109
|
+
i = singleQuotedEnd(text, i);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (char === '"') {
|
|
113
|
+
i = doubleQuotedEnd(text, i);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (char === '`') {
|
|
117
|
+
i = backtickEnd(text, i);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (char === '$' && text[i + 1] === '(') {
|
|
121
|
+
i = substitutionEnd(text, i + 2);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (char === '$' && text[i + 1] === '{') {
|
|
125
|
+
i = parameterEnd(text, i + 2);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (char === '(')
|
|
129
|
+
depth += 1;
|
|
130
|
+
else if (char === ')') {
|
|
131
|
+
depth -= 1;
|
|
132
|
+
if (depth === 0)
|
|
133
|
+
return i + 1;
|
|
134
|
+
}
|
|
135
|
+
i += 1;
|
|
136
|
+
}
|
|
137
|
+
return text.length;
|
|
138
|
+
}
|
|
139
|
+
/** The index just past a `${ … }` parameter expansion whose body starts at `at`. */
|
|
140
|
+
function parameterEnd(text, at) {
|
|
141
|
+
let depth = 1;
|
|
142
|
+
let i = at;
|
|
143
|
+
while (i < text.length) {
|
|
144
|
+
const char = text[i] ?? '';
|
|
145
|
+
if (char === '\\') {
|
|
146
|
+
i += 2;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (char === "'") {
|
|
150
|
+
i = singleQuotedEnd(text, i);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (char === '"') {
|
|
154
|
+
i = doubleQuotedEnd(text, i);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (char === '`') {
|
|
158
|
+
i = backtickEnd(text, i);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (char === '$' && text[i + 1] === '(') {
|
|
162
|
+
i = substitutionEnd(text, i + 2);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (char === '$' && text[i + 1] === '{') {
|
|
166
|
+
depth += 1;
|
|
167
|
+
i += 2;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (char === '}') {
|
|
171
|
+
depth -= 1;
|
|
172
|
+
if (depth === 0)
|
|
173
|
+
return i + 1;
|
|
174
|
+
}
|
|
175
|
+
i += 1;
|
|
176
|
+
}
|
|
177
|
+
return text.length;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* The index just past the shell word that starts at `at` (a non-whitespace character): a word ends
|
|
181
|
+
* at unquoted whitespace, and every quoted part, command substitution (`$( … )`, backticks),
|
|
182
|
+
* parameter expansion (`${ … }`) and process substitution (`<( … )`) inside it is skipped as a
|
|
183
|
+
* unit — so the spaces in `UID_VAL=h$(date +%s)` belong to that one word.
|
|
184
|
+
*
|
|
185
|
+
* Nothing is evaluated or expanded: this finds word BOUNDARIES only, and returns the text as
|
|
186
|
+
* written. A backslash-newline is a line continuation, so it ends the word and is skipped.
|
|
187
|
+
*/
|
|
188
|
+
function shellWordEnd(text, at) {
|
|
189
|
+
let i = at;
|
|
190
|
+
while (i < text.length) {
|
|
191
|
+
const char = text[i] ?? '';
|
|
192
|
+
if (/\s/.test(char))
|
|
193
|
+
break;
|
|
194
|
+
// Grouping punctuation is a shell operator, never part of the word beside it (`tail -25)`,
|
|
195
|
+
// `(npx …`), so a caller can step over the closer the way it always has.
|
|
196
|
+
if (GROUPING.has(char))
|
|
197
|
+
break;
|
|
198
|
+
if (char === '\\') {
|
|
199
|
+
if (text[i + 1] === '\n')
|
|
200
|
+
break;
|
|
201
|
+
i += 2;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (char === "'") {
|
|
205
|
+
i = singleQuotedEnd(text, i);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (char === '"') {
|
|
209
|
+
i = doubleQuotedEnd(text, i);
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
if (char === '`') {
|
|
213
|
+
i = backtickEnd(text, i);
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (char === '$' && text[i + 1] === '(') {
|
|
217
|
+
i = substitutionEnd(text, i + 2);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (char === '$' && text[i + 1] === '{') {
|
|
221
|
+
i = parameterEnd(text, i + 2);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if ((char === '<' || char === '>') && text[i + 1] === '(') {
|
|
225
|
+
i = substitutionEnd(text, i + 2);
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
i += 1;
|
|
229
|
+
}
|
|
230
|
+
return i;
|
|
231
|
+
}
|
|
232
|
+
/** One text's shell words, quotes kept, grouping punctuation still its own word. */
|
|
233
|
+
function shellWordSpans(text) {
|
|
234
|
+
const words = [];
|
|
235
|
+
let i = 0;
|
|
236
|
+
while (i < text.length) {
|
|
237
|
+
const char = text[i] ?? '';
|
|
238
|
+
if (char === '\\' && text[i + 1] === '\n') {
|
|
239
|
+
i += 2;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (/\s/.test(char)) {
|
|
243
|
+
i += 1;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (GROUPING.has(char)) {
|
|
247
|
+
words.push({ text: char, start: i });
|
|
248
|
+
i += 1;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const end = shellWordEnd(text, i);
|
|
252
|
+
words.push({ text: text.slice(i, end), start: i });
|
|
253
|
+
i = end;
|
|
254
|
+
}
|
|
255
|
+
return words;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* The words {@link segmentWords} keeps, with the offset each was written at: quotes kept whole,
|
|
259
|
+
* grouping words dropped, and a leading `(`/`{` taken off the first word. One walk answers both
|
|
260
|
+
* readings, so a caller splicing text at a word's offset and a caller matching that word can
|
|
261
|
+
* never disagree.
|
|
262
|
+
*/
|
|
263
|
+
function segmentWordSpans(text) {
|
|
264
|
+
const words = shellWordSpans(text).filter((word) => !GROUPING.has(word.text));
|
|
265
|
+
const first = words[0];
|
|
266
|
+
if (first !== undefined) {
|
|
267
|
+
const bare = first.text.replace(/^[({]+/, '');
|
|
268
|
+
if (bare === '')
|
|
269
|
+
words.shift();
|
|
270
|
+
else if (bare !== first.text)
|
|
271
|
+
words[0] = { text: bare, start: first.start + (first.text.length - bare.length) };
|
|
272
|
+
}
|
|
273
|
+
return words;
|
|
274
|
+
}
|
|
39
275
|
/**
|
|
40
276
|
* A redirection written as ONE word, its target attached: `2>&1`, `>out.log`, `&>/dev/null`,
|
|
41
277
|
* `<<'EOF'`. Matched against a word of the statement, so a redirect's target written as its own
|
|
@@ -707,6 +943,8 @@ function splitCommand(command) {
|
|
|
707
943
|
const source = blankHeredocBodies(command);
|
|
708
944
|
const parts = [];
|
|
709
945
|
const substitutions = [];
|
|
946
|
+
const subshells = [];
|
|
947
|
+
const subshellOpens = [];
|
|
710
948
|
/** Where each open `$(` body starts; -1 for a bare `(` opened inside one. */
|
|
711
949
|
const subOpens = [];
|
|
712
950
|
/** Where each open backtick body starts. */
|
|
@@ -855,11 +1093,18 @@ function splitCommand(command) {
|
|
|
855
1093
|
// `{ … }` writes through that group, so the depth travels with every character a caller
|
|
856
1094
|
// reading a redirect may ask about.
|
|
857
1095
|
if (char === '(' || char === '{') {
|
|
1096
|
+
if (char === '(')
|
|
1097
|
+
subshellOpens.push(i + 1);
|
|
858
1098
|
put(char);
|
|
859
1099
|
groupDepth += 1;
|
|
860
1100
|
continue;
|
|
861
1101
|
}
|
|
862
1102
|
if (char === ')' || char === '}') {
|
|
1103
|
+
if (char === ')') {
|
|
1104
|
+
const start = subshellOpens.pop();
|
|
1105
|
+
if (start !== undefined)
|
|
1106
|
+
subshells.push({ start, end: i });
|
|
1107
|
+
}
|
|
863
1108
|
groupDepth = Math.max(0, groupDepth - 1);
|
|
864
1109
|
put(char);
|
|
865
1110
|
continue;
|
|
@@ -903,7 +1148,9 @@ function splitCommand(command) {
|
|
|
903
1148
|
});
|
|
904
1149
|
lastAfter = part.after;
|
|
905
1150
|
}
|
|
906
|
-
|
|
1151
|
+
for (const start of subshellOpens)
|
|
1152
|
+
subshells.push({ start, end: source.length });
|
|
1153
|
+
return { parts: out, substitutions, subshells };
|
|
907
1154
|
}
|
|
908
1155
|
/**
|
|
909
1156
|
* A command's statements and pipeline stages — {@link splitCommand}'s parts on their own.
|
|
@@ -980,20 +1227,8 @@ function redirectTargetOf(text, depths, program, args) {
|
|
|
980
1227
|
* @returns The words.
|
|
981
1228
|
*/
|
|
982
1229
|
function segmentWords(text) {
|
|
983
|
-
|
|
984
|
-
const cleaned = words.filter((word) => !GROUPING.has(word));
|
|
985
|
-
const first = cleaned[0];
|
|
986
|
-
if (first !== undefined) {
|
|
987
|
-
const bare = first.replace(/^[({]+/, '');
|
|
988
|
-
if (bare === '')
|
|
989
|
-
cleaned.shift();
|
|
990
|
-
else
|
|
991
|
-
cleaned[0] = bare;
|
|
992
|
-
}
|
|
993
|
-
return cleaned;
|
|
1230
|
+
return segmentWordSpans(text).map((word) => word.text);
|
|
994
1231
|
}
|
|
995
|
-
/** {@link WORD} anchored at an offset, for walking a statement's raw words. */
|
|
996
|
-
const WORD_AT = new RegExp(WORD.source, 'y');
|
|
997
1232
|
/**
|
|
998
1233
|
* A statement's own leading `NAME=value` words, and where they end.
|
|
999
1234
|
*
|
|
@@ -1008,19 +1243,25 @@ function leadingAssignments(text) {
|
|
|
1008
1243
|
const words = [];
|
|
1009
1244
|
let at = 0;
|
|
1010
1245
|
for (let guard = 0; guard < MAX_WRAPPERS; guard++) {
|
|
1011
|
-
while (at < text.length
|
|
1246
|
+
while (at < text.length) {
|
|
1247
|
+
if (text[at] === '\\' && text[at + 1] === '\n') {
|
|
1248
|
+
at += 2;
|
|
1249
|
+
continue;
|
|
1250
|
+
}
|
|
1251
|
+
if (!/\s/.test(text[at] ?? ''))
|
|
1252
|
+
break;
|
|
1012
1253
|
at += 1;
|
|
1254
|
+
}
|
|
1013
1255
|
// Grouping in front of the statement (`(npx …)`, `{ …`): not a word the shell assigns with.
|
|
1014
1256
|
if (text[at] === '(' || text[at] === '{') {
|
|
1015
1257
|
at += 1;
|
|
1016
1258
|
continue;
|
|
1017
1259
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
if (!match || !ENV_ASSIGNMENT.test(match[0]))
|
|
1260
|
+
const word = text.slice(at, shellWordEnd(text, at));
|
|
1261
|
+
if (!ENV_ASSIGNMENT.test(word))
|
|
1021
1262
|
return { words, end: at };
|
|
1022
|
-
words.push(
|
|
1023
|
-
at +=
|
|
1263
|
+
words.push(word);
|
|
1264
|
+
at += word.length;
|
|
1024
1265
|
}
|
|
1025
1266
|
return { words, end: at };
|
|
1026
1267
|
}
|
|
@@ -1117,6 +1358,31 @@ function executedCommandsOf(command, depth) {
|
|
|
1117
1358
|
}
|
|
1118
1359
|
return out;
|
|
1119
1360
|
}
|
|
1361
|
+
/**
|
|
1362
|
+
* The direct executable command-substitution bodies in shell text, in source order.
|
|
1363
|
+
*
|
|
1364
|
+
* Uses the same quote, comment and heredoc boundaries as {@link executedCommands}.
|
|
1365
|
+
* Single-quoted and escaped text is inert. Nested substitutions stay inside their
|
|
1366
|
+
* parent's body so a caller can recurse with a separate working-directory scope
|
|
1367
|
+
* for each body; a `cd` inside one must not affect its sibling or the outer shell.
|
|
1368
|
+
*
|
|
1369
|
+
* @param command - The shell text to read, including any leading assignments.
|
|
1370
|
+
* @returns Each direct `$(…)` or backtick body, without its delimiters.
|
|
1371
|
+
*/
|
|
1372
|
+
export function commandSubstitutions(command) {
|
|
1373
|
+
if (typeof command !== 'string' || !command.trim())
|
|
1374
|
+
return [];
|
|
1375
|
+
const { substitutions } = splitCommand(command);
|
|
1376
|
+
const bodies = [];
|
|
1377
|
+
let parentEnd = -1;
|
|
1378
|
+
for (const { start, end } of substitutions.sort((a, b) => a.start - b.start || b.end - a.end)) {
|
|
1379
|
+
if (start < parentEnd)
|
|
1380
|
+
continue;
|
|
1381
|
+
bodies.push(command.slice(start, end));
|
|
1382
|
+
parentEnd = end;
|
|
1383
|
+
}
|
|
1384
|
+
return bodies;
|
|
1385
|
+
}
|
|
1120
1386
|
/**
|
|
1121
1387
|
* Every command a shell command actually executes, at any depth — the statements themselves, the
|
|
1122
1388
|
* body of a `sh -c '<command>'`, and the body of every command substitution (`$(…)`, backticks).
|
|
@@ -1154,29 +1420,7 @@ export function executedCommands(command) {
|
|
|
1154
1420
|
* @returns The word's offset in `text`, or null when there is no such word.
|
|
1155
1421
|
*/
|
|
1156
1422
|
function wordOffset(text, index) {
|
|
1157
|
-
|
|
1158
|
-
let kept = 0;
|
|
1159
|
-
let first = true;
|
|
1160
|
-
for (let match = placement.exec(text); match !== null; match = placement.exec(text)) {
|
|
1161
|
-
if (GROUPING.has(match[0]))
|
|
1162
|
-
continue;
|
|
1163
|
-
if (first) {
|
|
1164
|
-
first = false;
|
|
1165
|
-
const bare = match[0].replace(/^[({]+/, '');
|
|
1166
|
-
// `segmentWords` shifts a first word that was nothing but grouping away, so the NEXT word
|
|
1167
|
-
// is not stripped and is counted from zero.
|
|
1168
|
-
if (bare === '')
|
|
1169
|
-
continue;
|
|
1170
|
-
if (kept === index)
|
|
1171
|
-
return match.index + (match[0].length - bare.length);
|
|
1172
|
-
kept += 1;
|
|
1173
|
-
continue;
|
|
1174
|
-
}
|
|
1175
|
-
if (kept === index)
|
|
1176
|
-
return match.index;
|
|
1177
|
-
kept += 1;
|
|
1178
|
-
}
|
|
1179
|
-
return null;
|
|
1423
|
+
return segmentWordSpans(text)[index]?.start ?? null;
|
|
1180
1424
|
}
|
|
1181
1425
|
/**
|
|
1182
1426
|
* Every statement of a command, with its own assignments and where it sits — assignment-only
|
|
@@ -1289,9 +1533,9 @@ export function statementArgumentEnd(command, start, end) {
|
|
|
1289
1533
|
}
|
|
1290
1534
|
at = cursor - 1;
|
|
1291
1535
|
}
|
|
1292
|
-
const words =
|
|
1293
|
-
text:
|
|
1294
|
-
index: start +
|
|
1536
|
+
const words = shellWordSpans(command.slice(start, at)).map((word) => ({
|
|
1537
|
+
text: word.text,
|
|
1538
|
+
index: start + word.start,
|
|
1295
1539
|
}));
|
|
1296
1540
|
// A trailing redirection belongs to the statement but is not an argument of its program. An
|
|
1297
1541
|
// option written after it would still parse, but the option belongs with the program's own
|
|
@@ -1404,7 +1648,8 @@ function locatedSegmentsOf(command, depth) {
|
|
|
1404
1648
|
if (typeof command !== 'string' || depth > MAX_NESTING)
|
|
1405
1649
|
return [];
|
|
1406
1650
|
const out = [];
|
|
1407
|
-
|
|
1651
|
+
const { parts, subshells } = splitCommand(command);
|
|
1652
|
+
for (const part of parts) {
|
|
1408
1653
|
const words = segmentWords(part.text);
|
|
1409
1654
|
const start = commandStart(words);
|
|
1410
1655
|
const leading = leadingAssignments(part.text);
|
|
@@ -1428,6 +1673,12 @@ function locatedSegmentsOf(command, depth) {
|
|
|
1428
1673
|
: part.start + (wordOffset(part.text, start.envInsert) ?? leading.end),
|
|
1429
1674
|
programOffset: words[start.at] === undefined ? null : part.start + (wordOffset(part.text, start.at) ?? 0),
|
|
1430
1675
|
};
|
|
1676
|
+
const scopeAt = placed.programOffset ?? part.start + (wordOffset(part.text, 0) ?? 0);
|
|
1677
|
+
const shellScope = subshells
|
|
1678
|
+
.filter(({ start, end }) => start <= scopeAt && scopeAt < end)
|
|
1679
|
+
.sort((a, b) => a.start - b.start)
|
|
1680
|
+
.map(({ start }) => `group:${start}`);
|
|
1681
|
+
const scoped = shellScope.length === 0 ? {} : { shellScope };
|
|
1431
1682
|
// The runner the word RUNS names, when that is not the word's own name (`node <path>/playwright`
|
|
1432
1683
|
// is a `playwright` invocation, xr-molecule-flash-m179).
|
|
1433
1684
|
const program = words[start.at] === undefined ? '' : (start.program ?? programName(words[start.at] ?? ''));
|
|
@@ -1441,9 +1692,14 @@ function locatedSegmentsOf(command, depth) {
|
|
|
1441
1692
|
continue;
|
|
1442
1693
|
out.push({
|
|
1443
1694
|
...entry,
|
|
1695
|
+
shellScope: [...shellScope, `shell:${part.start}`, ...(entry.shellScope ?? [])],
|
|
1444
1696
|
// The variables this statement bound before the shell reached it are the nested
|
|
1445
1697
|
// command's too: `env BASE_URL=… sh -c '… npx playwright test …'` passes them down.
|
|
1446
1698
|
assignments: [...new Set([...assignments, ...entry.assignments])],
|
|
1699
|
+
sourceAssignments: [
|
|
1700
|
+
...(i === 0 ? assignments : []),
|
|
1701
|
+
...(entry.sourceAssignments ?? entry.assignments),
|
|
1702
|
+
],
|
|
1447
1703
|
// A nested statement's positions are positions in the nested string, not in this
|
|
1448
1704
|
// command. The FIRST one keeps this statement's own separator: the shell reads the
|
|
1449
1705
|
// nested string where this statement stands.
|
|
@@ -1469,6 +1725,7 @@ function locatedSegmentsOf(command, depth) {
|
|
|
1469
1725
|
if (assignments.length > 0)
|
|
1470
1726
|
out.push({
|
|
1471
1727
|
segment: null,
|
|
1728
|
+
...scoped,
|
|
1472
1729
|
assignments,
|
|
1473
1730
|
...placed,
|
|
1474
1731
|
programOffset: null,
|
|
@@ -1479,6 +1736,7 @@ function locatedSegmentsOf(command, depth) {
|
|
|
1479
1736
|
continue;
|
|
1480
1737
|
}
|
|
1481
1738
|
out.push({
|
|
1739
|
+
...scoped,
|
|
1482
1740
|
segment: {
|
|
1483
1741
|
program,
|
|
1484
1742
|
args,
|
|
@@ -1554,16 +1812,13 @@ export function withoutTimeoutWrapper(command, which) {
|
|
|
1554
1812
|
continue;
|
|
1555
1813
|
// Every word in front of the program: the assignments and the wrappers. The duration belongs
|
|
1556
1814
|
// to the wrapper, so the walk has to see the words, not just the parse's total bound.
|
|
1557
|
-
const
|
|
1558
|
-
const
|
|
1559
|
-
const
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
end: located.start + match.index + match[0].length,
|
|
1565
|
-
});
|
|
1566
|
-
}
|
|
1815
|
+
const start = located.start;
|
|
1816
|
+
const prefix = command.slice(start, located.programOffset);
|
|
1817
|
+
const words = shellWordSpans(prefix).map((word) => ({
|
|
1818
|
+
text: word.text,
|
|
1819
|
+
start: start + word.start,
|
|
1820
|
+
end: start + word.start + word.text.length,
|
|
1821
|
+
}));
|
|
1567
1822
|
for (let i = 0; i < words.length; i += 1) {
|
|
1568
1823
|
const word = words[i];
|
|
1569
1824
|
if (word === undefined || programName(word.text) !== 'timeout')
|
package/dist/suite-overlap.d.ts
CHANGED
|
@@ -87,7 +87,9 @@ export declare function withSuiteConfig(command: string, config: string | null |
|
|
|
87
87
|
* The re-run keeps the run's `> <file>` redirect only in the sense of keeping its OUTPUT there:
|
|
88
88
|
* the target is rewritten to a fresh sibling ({@link redirectRunnerOutputsToFreshFiles}), so a
|
|
89
89
|
* re-run never overwrites the log the run itself is the evidence for (xr-molecule-flash-m173) —
|
|
90
|
-
* and the setup around the run keeps its own file writes untouched (xr-molecule-flash-m429).
|
|
90
|
+
* and the setup around the run keeps its own file writes untouched (xr-molecule-flash-m429). A
|
|
91
|
+
* `tail`/`head`/`cat`/`grep` chained after the run that reads that exact log is shown the fresh
|
|
92
|
+
* sibling instead, so the re-run displays the run it performed (xr-molecule-flash-o03).
|
|
91
93
|
*
|
|
92
94
|
* `config` is the config the run was measured under ({@link withSuiteConfig}): the narrowed re-run
|
|
93
95
|
* carries it whenever the command itself does not, so a run that dropped `--config` cannot be
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suite-overlap.d.ts","sourceRoot":"","sources":["../src/suite-overlap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAaH;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoB1D;AAKD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAS1F;
|
|
1
|
+
{"version":3,"file":"suite-overlap.d.ts","sourceRoot":"","sources":["../src/suite-overlap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAaH;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoB1D;AAKD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAS1F;AA4VD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,QAAQ,GAAE,SAAS,MAAM,EAAO,EAChC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,EACtB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,EACnB,GAAG,GAAE,SAAS,aAAa,EAAO,GACjC,MAAM,CAgDR;AAED,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAmCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,SAAS,aAAa,EAAO,GAAG,MAAM,CAe3F;AAwOD;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+FAA+F;IAC/F,SAAS,EAAE,OAAO,CAAA;IAClB,oFAAoF;IACpF,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,gBAAgB,EACzD,SAAS,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EAC7B,QAAQ,EAAE,SAAS,CAAC,EAAE,GACrB,CAAC,GAAG,IAAI,CAMV;AA2FD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACvC;AAmCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAYtF"}
|
package/dist/suite-overlap.js
CHANGED
|
@@ -180,9 +180,10 @@ function applyTextEdits(command, edits) {
|
|
|
180
180
|
* @param statement - The statement's text.
|
|
181
181
|
* @param offset - The statement's offset in the command.
|
|
182
182
|
* @param words - The command's word spans.
|
|
183
|
+
* @param fresh - The exact old file → fresh file mapping the edits make, filled in here.
|
|
183
184
|
* @returns The edits, in statement order.
|
|
184
185
|
*/
|
|
185
|
-
function freshRedirectEdits(statement, offset, words) {
|
|
186
|
+
function freshRedirectEdits(statement, offset, words, fresh) {
|
|
186
187
|
const edits = [];
|
|
187
188
|
for (const match of statement.matchAll(FILE_REDIRECT)) {
|
|
188
189
|
const before = match[1] ?? '';
|
|
@@ -203,7 +204,9 @@ function freshRedirectEdits(statement, offset, words) {
|
|
|
203
204
|
continue;
|
|
204
205
|
const quote = single !== undefined || double !== undefined ? 1 : 0;
|
|
205
206
|
const start = offset + (match.index ?? 0) + before.length + op.length + space.length + quote;
|
|
206
|
-
|
|
207
|
+
const rewritten = `${target}.rerun.log`;
|
|
208
|
+
fresh.set(target, rewritten);
|
|
209
|
+
edits.push({ start, end: start + target.length, text: rewritten });
|
|
207
210
|
}
|
|
208
211
|
return edits;
|
|
209
212
|
}
|
|
@@ -217,9 +220,10 @@ function freshRedirectEdits(statement, offset, words) {
|
|
|
217
220
|
*
|
|
218
221
|
* @param statement - The stage's text.
|
|
219
222
|
* @param offset - The stage's offset in the command.
|
|
223
|
+
* @param fresh - The exact old file → fresh file mapping the edits make, filled in here.
|
|
220
224
|
* @returns The edits, in stage order.
|
|
221
225
|
*/
|
|
222
|
-
function freshTeeEdits(statement, offset) {
|
|
226
|
+
function freshTeeEdits(statement, offset, fresh) {
|
|
223
227
|
const words = [...statement.matchAll(ARGUMENT_WORD)].map((match) => ({
|
|
224
228
|
text: match[0],
|
|
225
229
|
start: offset + (match.index ?? 0),
|
|
@@ -233,10 +237,12 @@ function freshTeeEdits(statement, offset) {
|
|
|
233
237
|
if (!bare || bare.startsWith('-') || DEVICE_TARGET.test(bare))
|
|
234
238
|
continue;
|
|
235
239
|
const quote = /^['"]/.test(word.text) ? 1 : 0;
|
|
240
|
+
const rewritten = `${bare}.rerun.log`;
|
|
241
|
+
fresh.set(bare, rewritten);
|
|
236
242
|
edits.push({
|
|
237
243
|
start: word.start + quote,
|
|
238
244
|
end: word.start + word.text.length - quote,
|
|
239
|
-
text:
|
|
245
|
+
text: rewritten,
|
|
240
246
|
});
|
|
241
247
|
}
|
|
242
248
|
return edits;
|
|
@@ -283,6 +289,113 @@ function runnerOutputStatements(command) {
|
|
|
283
289
|
}
|
|
284
290
|
return statements;
|
|
285
291
|
}
|
|
292
|
+
/**
|
|
293
|
+
* Readers whose non-flag operands are ALL files: a display of the run's own report. Every one of
|
|
294
|
+
* them is read-only, so moving its operand with the file it reads cannot change what it does.
|
|
295
|
+
*/
|
|
296
|
+
const FILE_READERS = new Set(['cat', 'head', 'tail']);
|
|
297
|
+
/**
|
|
298
|
+
* grep-family readers: their first non-flag operand is the pattern, and the words after it are the
|
|
299
|
+
* files they display — unless a `-e`/`-f` flag named the pattern already.
|
|
300
|
+
*/
|
|
301
|
+
const GREP_READERS = new Set(['egrep', 'fgrep', 'grep']);
|
|
302
|
+
/** grep's pattern flags: the word after one is a pattern (or a pattern file), never a file. */
|
|
303
|
+
const GREP_PATTERN_FLAGS = new Set(['-e', '--regexp', '-f', '--file']);
|
|
304
|
+
/**
|
|
305
|
+
* The postlude statements that DISPLAY the run's own report, with the exact file that run wrote
|
|
306
|
+
* pointed at the fresh sibling the re-run writes instead.
|
|
307
|
+
*
|
|
308
|
+
* xr-molecule-flash-o03 (2026-10-22; the stale-READ arm m248 filed at +25:55): the recipe the
|
|
309
|
+
* platform handed the executor ended `> /tmp/e2e-local.log.rerun.log 2>&1; echo EXIT=$?; tail -80
|
|
310
|
+
* /tmp/e2e-local.log`. The writer moved to the fresh sibling and the trailing tail did not, so the
|
|
311
|
+
* narrowed re-run displayed the walk it was narrowed FROM — the builder followed that recipe at
|
|
312
|
+
* +19:16 and read the previous walk's failures as the result of the run it had just done.
|
|
313
|
+
*
|
|
314
|
+
* Only the EXACT file a runner statement (or its `tee`) wrote moves, and only in a statement AFTER
|
|
315
|
+
* the run: the setup in front of it keeps every byte (m429), and a read of any other file is left
|
|
316
|
+
* alone. The value is compared whole — `/tmp/full.log` never matches `/tmp/full.log.bak` — and
|
|
317
|
+
* inside shell quotes the operand's own quoting survives (`"/tmp/my walk.log"` stays quoted).
|
|
318
|
+
*
|
|
319
|
+
* The bound is deliberate: a display this reader set does not recognise (a `wc`, a path held in a
|
|
320
|
+
* variable, a path the command builds) is left exactly as written rather than guessed at. Those
|
|
321
|
+
* shapes are not the ones the platform emits, and rewriting a word by resemblance is how m429's
|
|
322
|
+
* setup redirect was corrupted.
|
|
323
|
+
*
|
|
324
|
+
* @param command - The composed command.
|
|
325
|
+
* @param statements - The statements carrying the run's own output.
|
|
326
|
+
* @param fresh - The exact old file → fresh file mapping the redirect edits made.
|
|
327
|
+
* @returns The edits, in statement order.
|
|
328
|
+
*/
|
|
329
|
+
function freshReportReadEdits(command, statements, fresh) {
|
|
330
|
+
if (fresh.size === 0)
|
|
331
|
+
return [];
|
|
332
|
+
const after = Math.max(...statements.map((statement) => statement.end));
|
|
333
|
+
const edits = [];
|
|
334
|
+
for (const entry of locatedCommandSegments(command)) {
|
|
335
|
+
const segment = entry.segment;
|
|
336
|
+
const start = entry.start;
|
|
337
|
+
const end = entry.end;
|
|
338
|
+
const programOffset = entry.programOffset;
|
|
339
|
+
// Only a statement the parse placed and that runs AFTER the walk can display its report.
|
|
340
|
+
if (segment === null || start === null || end === null)
|
|
341
|
+
continue;
|
|
342
|
+
if (start < after || programOffset === null)
|
|
343
|
+
continue;
|
|
344
|
+
const allFiles = FILE_READERS.has(segment.program);
|
|
345
|
+
const grep = GREP_READERS.has(segment.program);
|
|
346
|
+
if (!allFiles && !grep)
|
|
347
|
+
continue;
|
|
348
|
+
const text = command.slice(start, end);
|
|
349
|
+
const words = [...text.matchAll(ARGUMENT_WORD)].map((match) => ({
|
|
350
|
+
text: match[0],
|
|
351
|
+
start: start + (match.index ?? 0),
|
|
352
|
+
}));
|
|
353
|
+
// The program word's own span, so the walk starts exactly where the parse says it does.
|
|
354
|
+
const program = words.findIndex((word) => word.start === programOffset);
|
|
355
|
+
if (program < 0)
|
|
356
|
+
continue;
|
|
357
|
+
/** grep still owes its pattern: the first bare operand is that pattern, not a file. */
|
|
358
|
+
let patternPending = grep;
|
|
359
|
+
for (let i = program + 1; i < words.length; i += 1) {
|
|
360
|
+
const word = words[i];
|
|
361
|
+
if (word === undefined)
|
|
362
|
+
break;
|
|
363
|
+
if (ARGUMENT_REDIRECT_OPERATOR.test(word.text)) {
|
|
364
|
+
// The operator's target is where the display WRITES, not a file it reads.
|
|
365
|
+
i += 1;
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (ARGUMENT_REDIRECT.test(word.text))
|
|
369
|
+
continue;
|
|
370
|
+
const flag = unquoted(word.text);
|
|
371
|
+
if (flag.startsWith('-') && flag !== '-') {
|
|
372
|
+
if (grep) {
|
|
373
|
+
if (GREP_PATTERN_FLAGS.has(flag)) {
|
|
374
|
+
patternPending = false;
|
|
375
|
+
i += 1;
|
|
376
|
+
}
|
|
377
|
+
else if (/^(?:--(?:regexp|file)=|-[ef].)/.test(flag))
|
|
378
|
+
patternPending = false;
|
|
379
|
+
}
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
if (patternPending) {
|
|
383
|
+
patternPending = false;
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
const to = fresh.get(unquoted(word.text));
|
|
387
|
+
if (to === undefined)
|
|
388
|
+
continue;
|
|
389
|
+
const quote = /^['"]/.test(word.text) ? 1 : 0;
|
|
390
|
+
edits.push({
|
|
391
|
+
start: word.start + quote,
|
|
392
|
+
end: word.start + word.text.length - quote,
|
|
393
|
+
text: to,
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return edits;
|
|
398
|
+
}
|
|
286
399
|
/**
|
|
287
400
|
* The command with the SUITE RUN's own log files pointed at fresh siblings, and nothing else
|
|
288
401
|
* changed.
|
|
@@ -302,6 +415,12 @@ function runnerOutputStatements(command) {
|
|
|
302
415
|
* source asset it lays down are the same shape: their targets stay byte-for-byte, and so does
|
|
303
416
|
* every statement chained after the run (`; echo EXIT $? > /tmp/done`).
|
|
304
417
|
*
|
|
418
|
+
* Every statement chained after the run (`; echo EXIT $? > /tmp/done`) is postlude and keeps its
|
|
419
|
+
* own writes, but the DISPLAY of the run's report is part of the same run: a `tail`, `head`, `cat`
|
|
420
|
+
* or `grep` after the run that reads the exact file it wrote is pointed at the fresh sibling too
|
|
421
|
+
* ({@link freshReportReadEdits}), so a re-run shows its own output instead of the walk's
|
|
422
|
+
* (xr-molecule-flash-o03).
|
|
423
|
+
*
|
|
305
424
|
* @param command - The composed command.
|
|
306
425
|
* @returns The command whose suite-run redirects write to a fresh target.
|
|
307
426
|
*/
|
|
@@ -311,12 +430,14 @@ function redirectRunnerOutputsToFreshFiles(command) {
|
|
|
311
430
|
return command;
|
|
312
431
|
const words = wordSpans(command);
|
|
313
432
|
const edits = [];
|
|
433
|
+
const fresh = new Map();
|
|
314
434
|
for (const statement of statements) {
|
|
315
435
|
const text = command.slice(statement.start, statement.end);
|
|
316
|
-
edits.push(...freshRedirectEdits(text, statement.start, words));
|
|
436
|
+
edits.push(...freshRedirectEdits(text, statement.start, words, fresh));
|
|
317
437
|
if (statement.tee)
|
|
318
|
-
edits.push(...freshTeeEdits(text, statement.start));
|
|
438
|
+
edits.push(...freshTeeEdits(text, statement.start, fresh));
|
|
319
439
|
}
|
|
440
|
+
edits.push(...freshReportReadEdits(command, statements, fresh));
|
|
320
441
|
return applyTextEdits(command, edits);
|
|
321
442
|
}
|
|
322
443
|
/**
|
|
@@ -329,7 +450,9 @@ function redirectRunnerOutputsToFreshFiles(command) {
|
|
|
329
450
|
* The re-run keeps the run's `> <file>` redirect only in the sense of keeping its OUTPUT there:
|
|
330
451
|
* the target is rewritten to a fresh sibling ({@link redirectRunnerOutputsToFreshFiles}), so a
|
|
331
452
|
* re-run never overwrites the log the run itself is the evidence for (xr-molecule-flash-m173) —
|
|
332
|
-
* and the setup around the run keeps its own file writes untouched (xr-molecule-flash-m429).
|
|
453
|
+
* and the setup around the run keeps its own file writes untouched (xr-molecule-flash-m429). A
|
|
454
|
+
* `tail`/`head`/`cat`/`grep` chained after the run that reads that exact log is shown the fresh
|
|
455
|
+
* sibling instead, so the re-run displays the run it performed (xr-molecule-flash-o03).
|
|
333
456
|
*
|
|
334
457
|
* `config` is the config the run was measured under ({@link withSuiteConfig}): the narrowed re-run
|
|
335
458
|
* carries it whenever the command itself does not, so a run that dropped `--config` cannot be
|
package/dist/tools.d.ts
CHANGED
|
@@ -59,6 +59,21 @@ export declare const SUITE_OVER_BUDGET_ADVICE: string;
|
|
|
59
59
|
* @returns The note, or null when the path is not inside a package's `dist`.
|
|
60
60
|
*/
|
|
61
61
|
export declare function moleculeDistReadNote(path: string): string | null;
|
|
62
|
+
/**
|
|
63
|
+
* The command that reads a REGISTERED background task's own log as one bounded contiguous window
|
|
64
|
+
* ({@link runningLogReadCommand}), with the file its launch redirects to when the launch recorded
|
|
65
|
+
* one.
|
|
66
|
+
*
|
|
67
|
+
* The task id is the ownership: it is the handle `wait_for_task` returned, `/tmp/${taskId}.log` is
|
|
68
|
+
* the log this platform's launcher writes for it, and the redirect target is the file this
|
|
69
|
+
* process's own launch registered for that id — never a path parsed out of a command by the
|
|
70
|
+
* caller. A diagnosis that reads a running walk must not build a `/tmp` path of its own
|
|
71
|
+
* (xr-molecule-flash-l07: the wait's DISPLAY was diagnosed as if it were the log).
|
|
72
|
+
*
|
|
73
|
+
* @param taskId - The `mol-bg-…` handle the wait returned.
|
|
74
|
+
* @returns The read command, or null when the handle is not a task id this platform minted.
|
|
75
|
+
*/
|
|
76
|
+
export declare function registeredTaskLogCommand(taskId: string): string | null;
|
|
62
77
|
/**
|
|
63
78
|
* What the filesystem says about a write target under `node_modules` — the half
|
|
64
79
|
* of the decision a path's spelling cannot make.
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAgS9C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAahG;AAudD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAgS9C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAahG;AAudD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAiInE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAEA,CAAA;AAE9B;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,QAI6C,CAAA;AA2DlF;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUhE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGtE;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;AAoBpF;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAAC,GACxE,qBAAqB,CAkBvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,qBAAqB,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiCxB;AA2GD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CAq/FxF"}
|
package/dist/tools.js
CHANGED
|
@@ -703,7 +703,7 @@ async function backgroundTaskState(backend, command, seconds, ceilingMs) {
|
|
|
703
703
|
}
|
|
704
704
|
import { suiteCommandTarget } from './suite-overlap.js';
|
|
705
705
|
import { diagnosisTraceCommand } from './trace-artifacts.js';
|
|
706
|
-
import { addedRedactionMask, BRACE_GLOB_HINT, checkBlockedCommand, declaredBudgetSeconds, DEFAULT_SEARCH_EXCLUDED_DIRS, directoryReadHint, earlyReturnCause, emptyCallError, expandBraceGlob, failureCausesNote, findPathArgs, findPatternArgs, fusedLine, htmlOutline, isCommandTimeout, isEnvFilePath, isOutsideRoot, isPlaywrightRunCommand, isReadOnlyInspection, isSuiteRunCommand, linesWithinSerialized, literalDirPrefix, logShowsInlineFailureBodies, MAX_BATCH_READ_FILES, MAX_FIND_RESULTS, MAX_HTML_INLINE_CHARS, MAX_OUTPUT_SIZE, MAX_READ_CALL_CHARS, MAX_READ_RETURN_CHARS, MAX_READ_SIZE, MAX_SEARCH_CONTEXT_LINES, MAX_SEARCH_RESULTS, MAX_WRITE_SIZE, outputIsWithheldUntilExit, outputRedirectTarget, parseCheckCommand, parseCheckProblem, pathArgError, READ_RESULT_ENVELOPE_CHARS, redactSecrets, redactSecretsInCode, repeatedSuiteRunError, repeatingFailure, repeatingFailureNote, resolvePath, RUNNING_FAILURE_LINES, runningCauseCommand, runningOutputSliceCommand, searchTimeoutError, serializedChars, shellQuote, sliceLines, SMALL_FILE_WHOLE_CHARS, streamingBackgroundCommand, stripControlChars, suiteRunBudgetCommand, suiteRunConfigCommand, suiteRunPipelinePlacement, suiteRunPriorityLaunch, TOOL_RESULT_CHARS, truncateMiddle, universalCause, whitespaceTolerantReplace, withoutSuiteTimeout, withPlaywrightRunReport, } from './utilities.js';
|
|
706
|
+
import { addedRedactionMask, BRACE_GLOB_HINT, checkBlockedCommand, declaredBudgetSeconds, DEFAULT_SEARCH_EXCLUDED_DIRS, directoryReadHint, earlyReturnCause, emptyCallError, expandBraceGlob, failureCausesNote, findPathArgs, findPatternArgs, fusedLine, htmlOutline, isCommandTimeout, isEnvFilePath, isOutsideRoot, isPlaywrightRunCommand, isReadOnlyInspection, isSuiteRunCommand, linesWithinSerialized, literalDirPrefix, logShowsInlineFailureBodies, MAX_BATCH_READ_FILES, MAX_FIND_RESULTS, MAX_HTML_INLINE_CHARS, MAX_OUTPUT_SIZE, MAX_READ_CALL_CHARS, MAX_READ_RETURN_CHARS, MAX_READ_SIZE, MAX_SEARCH_CONTEXT_LINES, MAX_SEARCH_RESULTS, MAX_WRITE_SIZE, outputIsWithheldUntilExit, outputRedirectTarget, parseCheckCommand, parseCheckProblem, pathArgError, READ_RESULT_ENVELOPE_CHARS, redactSecrets, redactSecretsInCode, repeatedSuiteRunError, repeatingFailure, repeatingFailureNote, resolvePath, RUNNING_FAILURE_LINES, runningCauseCommand, runningLogReadCommand, runningOutputSliceCommand, searchTimeoutError, serializedChars, shellQuote, sliceLines, SMALL_FILE_WHOLE_CHARS, streamingBackgroundCommand, stripControlChars, suiteRunBudgetCommand, suiteRunConfigCommand, suiteRunPipelinePlacement, suiteRunPriorityLaunch, TOOL_RESULT_CHARS, truncateMiddle, universalCause, whitespaceTolerantReplace, withoutSuiteTimeout, withPlaywrightRunReport, } from './utilities.js';
|
|
707
707
|
/**
|
|
708
708
|
* How long exec_command waits for a command it backgrounded only because the
|
|
709
709
|
* command asked for more than the tool's ceiling, before handing back a task id.
|
|
@@ -840,6 +840,25 @@ export function moleculeDistReadNote(path) {
|
|
|
840
840
|
? ' The declarations above are generated from it.'
|
|
841
841
|
: ' For one signature, read the matching .d.ts file.'));
|
|
842
842
|
}
|
|
843
|
+
/**
|
|
844
|
+
* The command that reads a REGISTERED background task's own log as one bounded contiguous window
|
|
845
|
+
* ({@link runningLogReadCommand}), with the file its launch redirects to when the launch recorded
|
|
846
|
+
* one.
|
|
847
|
+
*
|
|
848
|
+
* The task id is the ownership: it is the handle `wait_for_task` returned, `/tmp/${taskId}.log` is
|
|
849
|
+
* the log this platform's launcher writes for it, and the redirect target is the file this
|
|
850
|
+
* process's own launch registered for that id — never a path parsed out of a command by the
|
|
851
|
+
* caller. A diagnosis that reads a running walk must not build a `/tmp` path of its own
|
|
852
|
+
* (xr-molecule-flash-l07: the wait's DISPLAY was diagnosed as if it were the log).
|
|
853
|
+
*
|
|
854
|
+
* @param taskId - The `mol-bg-…` handle the wait returned.
|
|
855
|
+
* @returns The read command, or null when the handle is not a task id this platform minted.
|
|
856
|
+
*/
|
|
857
|
+
export function registeredTaskLogCommand(taskId) {
|
|
858
|
+
if (!TASK_ID.test(taskId))
|
|
859
|
+
return null;
|
|
860
|
+
return runningLogReadCommand(`/tmp/${taskId}.log`, outputFileByTask.get(taskId));
|
|
861
|
+
}
|
|
843
862
|
/**
|
|
844
863
|
* The `node_modules` entry a path goes through, and the package name after it
|
|
845
864
|
* (`null` when the path IS the entry).
|
package/dist/utilities.d.ts
CHANGED
|
@@ -964,6 +964,42 @@ export declare const REPEATING_CAUSE_TAIL_BYTES = 40000;
|
|
|
964
964
|
* @returns The shell command, safe to hand to the execution backend as-is.
|
|
965
965
|
*/
|
|
966
966
|
export declare function runningCauseCommand(log: string, own?: string): string;
|
|
967
|
+
/** Bytes of a running log a diagnostic note reads back: one {@link REPEATING_CAUSE_TAIL_BYTES} window. */
|
|
968
|
+
export declare const RUNNING_LOG_READ_BYTES = 40000;
|
|
969
|
+
/** A bounded, contiguous read of a running task's own log. */
|
|
970
|
+
export interface RunningLogRead {
|
|
971
|
+
/** The log's last {@link RUNNING_LOG_READ_BYTES} bytes, contiguous, as one string. */
|
|
972
|
+
text: string;
|
|
973
|
+
/** How many bytes the WHOLE log holds, or null when the read did not answer its size. */
|
|
974
|
+
bytes: number | null;
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* The shell command whose stdout is a bounded CONTIGUOUS read of a running task's own log: the
|
|
978
|
+
* log's byte size, then its last {@link RUNNING_LOG_READ_BYTES} bytes.
|
|
979
|
+
*
|
|
980
|
+
* {@link runningOutputSliceCommand} is the wrong read for a diagnosis, and l07 is the finding: it
|
|
981
|
+
* stitches the first 40 grep-selected failure lines to the last 1 000 bytes with a blank line
|
|
982
|
+
* between, so the tail is DISJOINT from the headers above it. Read as one log, the last numbered
|
|
983
|
+
* header absorbs whatever the tail starts with — a clipped skipped-test title became the cause of
|
|
984
|
+
* a genuine failure (xr-molecule-flash-l07). A contiguous window can only ever hold real
|
|
985
|
+
* neighbouring lines of one log.
|
|
986
|
+
*
|
|
987
|
+
* The size rides along so a caller can say when the window is only the log's end
|
|
988
|
+
* ({@link parseRunningLogRead}); without it a tail reads as the whole run.
|
|
989
|
+
*
|
|
990
|
+
* @param log - The task log path.
|
|
991
|
+
* @param own - A file the command redirects its own output to, if any.
|
|
992
|
+
* @returns The shell command, safe to hand to the execution backend as-is.
|
|
993
|
+
*/
|
|
994
|
+
export declare function runningLogReadCommand(log: string, own?: string): string;
|
|
995
|
+
/**
|
|
996
|
+
* The two parts of {@link runningLogReadCommand}'s answer.
|
|
997
|
+
*
|
|
998
|
+
* @param stdout - The command's stdout.
|
|
999
|
+
* @returns The window and the whole log's byte size, or null when the size line is absent (the
|
|
1000
|
+
* read did not run, so nothing may be said about the log).
|
|
1001
|
+
*/
|
|
1002
|
+
export declare function parseRunningLogRead(stdout: string): RunningLogRead | null;
|
|
967
1003
|
/**
|
|
968
1004
|
* DISTINCT tests that must share one signature before a running suite's repeating cause is named.
|
|
969
1005
|
* A test the log prints twice, or a test that failed twice, is still one test.
|
package/dist/utilities.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"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"}
|
package/dist/utilities.js
CHANGED
|
@@ -536,9 +536,25 @@ const PRINTING_REPORTERS = new Set(['list', 'line', 'dot', 'basic', 'spec']);
|
|
|
536
536
|
* edited `app/src` while the run was still walking — which voids the run.
|
|
537
537
|
*/
|
|
538
538
|
export const PLAYWRIGHT_FAILURES_INLINE_ENV = 'PLAYWRIGHT_LIST_PRINT_FAILURES_INLINE';
|
|
539
|
+
/**
|
|
540
|
+
* A step that stores the status of the step before it in a variable: `__proof_slow=$?`.
|
|
541
|
+
*
|
|
542
|
+
* The variable name is the shell's own (`[A-Za-z_][A-Za-z0-9_]*`) and the value is EXACTLY the
|
|
543
|
+
* special parameter, bare or double-quoted, so nothing else can be running here. A capture whose
|
|
544
|
+
* value is anything else — `x=$(rebuild)`, `x=$?; rm -rf …` (a separate statement anyway) — is a
|
|
545
|
+
* program, not a status, and is not one of these.
|
|
546
|
+
*/
|
|
547
|
+
const STATUS_CAPTURE_STEP = /^[A-Za-z_][A-Za-z0-9_]*=(?:\$\?|"\$\?"|\$\{\?\})$/;
|
|
548
|
+
/**
|
|
549
|
+
* The arithmetic body `exit $((…))` may carry and still run nothing: variable names, numbers and
|
|
550
|
+
* arithmetic operators only. No `$`, backtick, `;` or comma is allowed, so no command substitution
|
|
551
|
+
* and no expansion of a variable into something that runs can hide in it.
|
|
552
|
+
*/
|
|
553
|
+
const STATUS_EXIT_ARITHMETIC = /^[A-Za-z0-9_|&+\-*/%^<>=!~() \t]*$/;
|
|
539
554
|
/**
|
|
540
555
|
* Whether a command step only reports or discards the status of the steps before it: `echo EXIT
|
|
541
|
-
* $?`, `echo $?`, `printf …`, `true`, `exit 0
|
|
556
|
+
* $?`, `echo $?`, `printf …`, `true`, `exit 0`, a status capture (`__proof_slow=$?`), or an
|
|
557
|
+
* `exit $((a | b))` over statuses already captured.
|
|
542
558
|
*
|
|
543
559
|
* The shape models and the platform's own re-run notes send routinely ends on one of these —
|
|
544
560
|
* `npx playwright test … > /tmp/pw.log 2>&1; echo EXIT $?` — and reading the split's last part as
|
|
@@ -548,12 +564,33 @@ export const PLAYWRIGHT_FAILURES_INLINE_ENV = 'PLAYWRIGHT_LIST_PRINT_FAILURES_IN
|
|
|
548
564
|
* punctuation are not part of the step; {@link streamingBackgroundCommand} strips those before
|
|
549
565
|
* asking, and strips them here too for the split it is given.
|
|
550
566
|
*
|
|
567
|
+
* A status CAPTURE is the same kind of step, and the platform's own chained proof walks end on a
|
|
568
|
+
* run of them: `… <browser run>; __proof_slow=$?; echo __PROOF_EXIT__ …; exit $((__proof_fast |
|
|
569
|
+
* __proof_slow))` (`chainedProofCommand`, molecule-dev `post-deploy-proof-run.ts`). Reading the
|
|
570
|
+
* browser half as a status step is what lets the run keep its reporter, its machine report and the
|
|
571
|
+
* inline-failure switch — without it, every platform proof ran its browser suite on the request's
|
|
572
|
+
* own `line` reporter, which writes no ✓/✘ mark and no per-failure error into the log the wait
|
|
573
|
+
* reads (xr-molecule-flash-x03 +27:44).
|
|
574
|
+
*
|
|
575
|
+
* Only the two shapes whose whole value is the shell's own status are read this way; anything that
|
|
576
|
+
* could run — a command substitution, a backticked word, a suffix after the status — stays a step.
|
|
577
|
+
*
|
|
551
578
|
* @param step - One statement of the command, as the `&&`/`||`/`;` split left it.
|
|
552
579
|
* @returns True when the step runs nothing but a status report.
|
|
553
580
|
*/
|
|
554
581
|
function isStatusOnlyStep(step) {
|
|
555
|
-
const text = step.
|
|
556
|
-
|
|
582
|
+
const text = step.trim();
|
|
583
|
+
// An enclosing group's closer is punctuation, not part of the step — but the `))` that closes an
|
|
584
|
+
// arithmetic expansion is part of the statement, so that shape is read off the text as written.
|
|
585
|
+
const withoutCloser = text.replace(/[\s)}]+$/, '');
|
|
586
|
+
if (/^(?:echo|printf)\b/.test(withoutCloser) || /^true$/.test(withoutCloser))
|
|
587
|
+
return true;
|
|
588
|
+
if (/^exit(?:\s+\S+)?$/.test(withoutCloser))
|
|
589
|
+
return true;
|
|
590
|
+
if (STATUS_CAPTURE_STEP.test(withoutCloser))
|
|
591
|
+
return true;
|
|
592
|
+
const arithmetic = /^exit\s+\$\(\((.*)\)\)$/.exec(text);
|
|
593
|
+
return arithmetic !== null && STATUS_EXIT_ARITHMETIC.test(arithmetic[1] ?? '');
|
|
557
594
|
}
|
|
558
595
|
/**
|
|
559
596
|
* Rewrite a command about to run in the background so its log grows while it
|
|
@@ -2423,6 +2460,43 @@ export function runningCauseCommand(log, own) {
|
|
|
2423
2460
|
const read = `cat ${log}${own ? ` ${shellQuote(own)}` : ''} 2>/dev/null`;
|
|
2424
2461
|
return `${read} | tail -c ${REPEATING_CAUSE_TAIL_BYTES}`;
|
|
2425
2462
|
}
|
|
2463
|
+
/** Bytes of a running log a diagnostic note reads back: one {@link REPEATING_CAUSE_TAIL_BYTES} window. */
|
|
2464
|
+
export const RUNNING_LOG_READ_BYTES = REPEATING_CAUSE_TAIL_BYTES;
|
|
2465
|
+
/**
|
|
2466
|
+
* The shell command whose stdout is a bounded CONTIGUOUS read of a running task's own log: the
|
|
2467
|
+
* log's byte size, then its last {@link RUNNING_LOG_READ_BYTES} bytes.
|
|
2468
|
+
*
|
|
2469
|
+
* {@link runningOutputSliceCommand} is the wrong read for a diagnosis, and l07 is the finding: it
|
|
2470
|
+
* stitches the first 40 grep-selected failure lines to the last 1 000 bytes with a blank line
|
|
2471
|
+
* between, so the tail is DISJOINT from the headers above it. Read as one log, the last numbered
|
|
2472
|
+
* header absorbs whatever the tail starts with — a clipped skipped-test title became the cause of
|
|
2473
|
+
* a genuine failure (xr-molecule-flash-l07). A contiguous window can only ever hold real
|
|
2474
|
+
* neighbouring lines of one log.
|
|
2475
|
+
*
|
|
2476
|
+
* The size rides along so a caller can say when the window is only the log's end
|
|
2477
|
+
* ({@link parseRunningLogRead}); without it a tail reads as the whole run.
|
|
2478
|
+
*
|
|
2479
|
+
* @param log - The task log path.
|
|
2480
|
+
* @param own - A file the command redirects its own output to, if any.
|
|
2481
|
+
* @returns The shell command, safe to hand to the execution backend as-is.
|
|
2482
|
+
*/
|
|
2483
|
+
export function runningLogReadCommand(log, own) {
|
|
2484
|
+
const read = `cat ${log}${own ? ` ${shellQuote(own)}` : ''} 2>/dev/null`;
|
|
2485
|
+
return `{ ${read} | wc -c; ${read} | tail -c ${RUNNING_LOG_READ_BYTES}; }`;
|
|
2486
|
+
}
|
|
2487
|
+
/**
|
|
2488
|
+
* The two parts of {@link runningLogReadCommand}'s answer.
|
|
2489
|
+
*
|
|
2490
|
+
* @param stdout - The command's stdout.
|
|
2491
|
+
* @returns The window and the whole log's byte size, or null when the size line is absent (the
|
|
2492
|
+
* read did not run, so nothing may be said about the log).
|
|
2493
|
+
*/
|
|
2494
|
+
export function parseRunningLogRead(stdout) {
|
|
2495
|
+
const sized = /^\s*(\d+)\s*\n/.exec(stdout);
|
|
2496
|
+
if (sized === null)
|
|
2497
|
+
return null;
|
|
2498
|
+
return { text: stdout.slice(sized[0].length), bytes: Number(sized[1]) };
|
|
2499
|
+
}
|
|
2426
2500
|
/**
|
|
2427
2501
|
* DISTINCT tests that must share one signature before a running suite's repeating cause is named.
|
|
2428
2502
|
* A test the log prints twice, or a test that failed twice, is still one test.
|
|
@@ -2513,6 +2587,12 @@ function failureBody(block) {
|
|
|
2513
2587
|
.map((l) => l.replace(ANSI_SGR, '').trim())
|
|
2514
2588
|
.filter((l) => l &&
|
|
2515
2589
|
!LIST_RESULT_LINE.test(l) &&
|
|
2590
|
+
// A SKIPPED test's own row (` - 41 [chromium] › user-fetch-errors.spec.ts:88:3 › …`) is
|
|
2591
|
+
// a progress line, never a failure's body: a block with no body of its own is followed by
|
|
2592
|
+
// whatever the reporter printed next, and that row became the failure's "cause" when the
|
|
2593
|
+
// wait's stitched display was read as one log (xr-molecule-flash-l07). A `- waiting for`
|
|
2594
|
+
// call-log line stays — it names the locator, and the dash carries no index.
|
|
2595
|
+
!/^\s*-\s+\d+\s+/.test(l) &&
|
|
2516
2596
|
!/^(?:at\s|\d+ \||>\s*\d+ \||\|)/.test(l) &&
|
|
2517
2597
|
!/^Error Context:/.test(l));
|
|
2518
2598
|
}
|
|
@@ -3870,14 +3950,14 @@ regressedSpecs = []) {
|
|
|
3870
3950
|
'handler shape, a header or CORS.');
|
|
3871
3951
|
}
|
|
3872
3952
|
// A text that is the TAIL of a longer log says so in its first line (`…(N earlier characters
|
|
3873
|
-
// omitted)`,
|
|
3953
|
+
// omitted)`, or bytes for a byte-bounded read): what it holds is not
|
|
3874
3954
|
// the run's list of failures, only the part that survived the cut. Saying "N failures in this
|
|
3875
3955
|
// run" over it reads as complete, and did: xr-molecule-flash-m123's collected 42 KB diagnosis
|
|
3876
3956
|
// log was clipped to its last 8 KB, and this note grouped 2 of the run's 14 failures under
|
|
3877
3957
|
// "fix every cause below" while the 11 that shared the run's one real cause were gone
|
|
3878
3958
|
// (2026-10-17). The root fix is to hand this function the whole log; this says so when a
|
|
3879
3959
|
// caller cannot.
|
|
3880
|
-
const clipped = /^…\((\d+) earlier characters omitted\)/.exec(log);
|
|
3960
|
+
const clipped = /^…\((\d+) earlier (characters|bytes) omitted\)/.exec(log);
|
|
3881
3961
|
// The missing-header reading leads the list: four unrelated locators failing while every
|
|
3882
3962
|
// snapshot shows the page painted and un-navigated is ONE fact about the route, and the list
|
|
3883
3963
|
// below would otherwise read as four separate defects (xr-molecule-flash-m193 rewrote the
|
|
@@ -3887,7 +3967,7 @@ regressedSpecs = []) {
|
|
|
3887
3967
|
const header = (missingHeader === null ? '' : `${missingHeader}\n`) +
|
|
3888
3968
|
(clipped !== null
|
|
3889
3969
|
? `${total} failure${total === 1 ? '' : 's'} in the LAST part of this run’s log — its ` +
|
|
3890
|
-
`first ${clipped[1]}
|
|
3970
|
+
`first ${clipped[1]} ${clipped[2]} were clipped, so a cause that failed earlier is ` +
|
|
3891
3971
|
`missing here. Fix every cause below${connections.length > 0 ? ' the app’s code can produce, and re-send the connection error once as it is' : ''}, ` +
|
|
3892
3972
|
`and read the whole run log before concluding:\n`
|
|
3893
3973
|
: `${total} failure${total === 1 ? '' : 's'} in this run, grouped by cause — fix every cause ` +
|