@molecule/api-ai-tools 1.8.2 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +413 -31
- package/dist/command-position.d.ts +26 -2
- package/dist/command-position.d.ts.map +1 -1
- package/dist/command-position.js +221 -24
- package/dist/failure-kind.d.ts +66 -0
- package/dist/failure-kind.d.ts.map +1 -0
- package/dist/failure-kind.js +134 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/sleep-peek.d.ts +51 -0
- package/dist/sleep-peek.d.ts.map +1 -0
- package/dist/sleep-peek.js +76 -0
- package/dist/suite-overlap.d.ts +35 -1
- package/dist/suite-overlap.d.ts.map +1 -1
- package/dist/suite-overlap.js +57 -2
- package/dist/tools.d.ts +56 -3
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +285 -48
- package/dist/trace-artifacts.d.ts +77 -7
- package/dist/trace-artifacts.d.ts.map +1 -1
- package/dist/trace-artifacts.js +344 -47
- package/dist/utilities.d.ts +63 -13
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js +277 -64
- 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-17T07:58:25.504Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/api-ai-tools
|
|
@@ -115,6 +115,24 @@ interface LocatedCommandSegment {
|
|
|
115
115
|
* inside a nested `sh -c` string, for the same reason as {@link start}.
|
|
116
116
|
*/
|
|
117
117
|
assignmentOffset: number | null
|
|
118
|
+
/**
|
|
119
|
+
* The offset in the command one past the statement's last word — where an option of this
|
|
120
|
+
* statement's program belongs, before whatever closes it. Null inside a nested `sh -c` string.
|
|
121
|
+
*/
|
|
122
|
+
end: number | null
|
|
123
|
+
/**
|
|
124
|
+
* The offset in the command of the word in command position — the program, once every wrapper
|
|
125
|
+
* in front of it is taken away (`npx --prefix /app <here>playwright test`). Null inside a
|
|
126
|
+
* nested `sh -c` string, and for a statement that only sets variables.
|
|
127
|
+
*/
|
|
128
|
+
programOffset: number | null
|
|
129
|
+
/**
|
|
130
|
+
* The separator the shell split at immediately before this statement — `|`, `||`, `&&`, `;`,
|
|
131
|
+
* a newline or `&` — or '' when it is the first statement of the command. It is the parse's own
|
|
132
|
+
* answer, so it is known even where the offsets are not, and a caller deciding whether two
|
|
133
|
+
* statements are one pipeline (`|`, never `;`) asks it instead of reading the text between them.
|
|
134
|
+
*/
|
|
135
|
+
separator: string
|
|
118
136
|
}
|
|
119
137
|
```
|
|
120
138
|
|
|
@@ -179,6 +197,23 @@ interface CutRun {
|
|
|
179
197
|
}
|
|
180
198
|
```
|
|
181
199
|
|
|
200
|
+
#### `RunFailureClass`
|
|
201
|
+
|
|
202
|
+
One failure a runner printed, classified by the layer that failed.
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
interface RunFailureClass {
|
|
206
|
+
/** The layer that failed. */
|
|
207
|
+
kind: RunFailureKind
|
|
208
|
+
/** For a `connection` failure, what the transport did. */
|
|
209
|
+
connection?: ConnectionFailureKind
|
|
210
|
+
/** How long the request waited before the transport gave up, in seconds, when printed. */
|
|
211
|
+
seconds?: number
|
|
212
|
+
/** The `file:line` the runner printed for the failure, when it printed one. */
|
|
213
|
+
at?: string
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
182
217
|
#### `NormalizableSchema`
|
|
183
218
|
|
|
184
219
|
The JSON-Schema-ish shape every tool in this package declares.
|
|
@@ -235,6 +270,19 @@ interface ToolSchema {
|
|
|
235
270
|
}
|
|
236
271
|
```
|
|
237
272
|
|
|
273
|
+
#### `LeadingSleep`
|
|
274
|
+
|
|
275
|
+
The leading `sleep` a command opens with, and the command that follows it.
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
interface LeadingSleep {
|
|
279
|
+
/** How many seconds the statement would have slept (GNU sleep sums its operands). */
|
|
280
|
+
seconds: number
|
|
281
|
+
/** What follows the leading statement, trimmed — '' when the sleep was the whole command. */
|
|
282
|
+
rest: string
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
238
286
|
#### `SuiteRunInFlight`
|
|
239
287
|
|
|
240
288
|
One suite run, as the rule that decides whether a second may start beside it reads it.
|
|
@@ -258,6 +306,20 @@ interface SuiteRunInFlight {
|
|
|
258
306
|
}
|
|
259
307
|
```
|
|
260
308
|
|
|
309
|
+
#### `InstalledPackageFacts`
|
|
310
|
+
|
|
311
|
+
What the filesystem says about a write target under `node_modules` — the half
|
|
312
|
+
of the decision a path's spelling cannot make.
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
interface InstalledPackageFacts {
|
|
316
|
+
/** Whether the `node_modules` entry the path goes through is a symbolic link. */
|
|
317
|
+
readonly symlink: boolean
|
|
318
|
+
/** Whether a package is really installed there: a `package.json` resolves under the entry. */
|
|
319
|
+
readonly installed: boolean
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
261
323
|
#### `TraceRequest`
|
|
262
324
|
|
|
263
325
|
One request a traced page made, as `*.network` records it.
|
|
@@ -268,8 +330,43 @@ interface TraceRequest {
|
|
|
268
330
|
method: string
|
|
269
331
|
/** The request's path (`/api/articles/x/favorite`), or the whole URL when it is cross-origin. */
|
|
270
332
|
path: string
|
|
271
|
-
/**
|
|
333
|
+
/**
|
|
334
|
+
* The response status as the trace recorded it. Playwright writes `-1` when a request was never
|
|
335
|
+
* answered (its HAR entry starts at `-1` and only a response event overwrites it); `0` is the
|
|
336
|
+
* same absence when the snapshot carried no response at all. Neither is a server failure.
|
|
337
|
+
*/
|
|
272
338
|
status: number
|
|
339
|
+
/**
|
|
340
|
+
* Playwright's own error text for a request that failed WITHOUT a response
|
|
341
|
+
* (`net::ERR_CONNECTION_REFUSED`) — a real failure. A request that got no response and recorded
|
|
342
|
+
* no text was aborted or still in flight when the test ended (the page closed under it), so it
|
|
343
|
+
* says nothing about the server (xr-molecule-flash-m112 +30:45).
|
|
344
|
+
*/
|
|
345
|
+
failure?: string
|
|
346
|
+
/**
|
|
347
|
+
* What the page SENT, for a 4xx answered by the app's own API — bounded (see
|
|
348
|
+
* {@link MAX_TRACED_BODY_CHARS}). A body wrapped as `{"data":{…}}` is visible here in one line:
|
|
349
|
+
* app-http's verbs take the body as their second argument, so a helper that passes
|
|
350
|
+
* `{ data: body }` there ships the wrapper (xr-molecule-flash-m111 +11:36).
|
|
351
|
+
*/
|
|
352
|
+
sent?: string
|
|
353
|
+
/** What came back for that 4xx, bounded the same way — the API's own error body. */
|
|
354
|
+
got?: string
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
#### `TraceAction`
|
|
359
|
+
|
|
360
|
+
One action the traced page performed, with the trace's own timing for it.
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
interface TraceAction {
|
|
364
|
+
/** The Playwright API the entry names: `Frame.goto`, `Locator.fill`, `Locator.click`. */
|
|
365
|
+
api: string
|
|
366
|
+
/** When the action started, on the trace's own monotonic clock (ms). */
|
|
367
|
+
start: number
|
|
368
|
+
/** When it finished, or null when the run ended before it did. */
|
|
369
|
+
end: number | null
|
|
273
370
|
}
|
|
274
371
|
```
|
|
275
372
|
|
|
@@ -287,6 +384,12 @@ interface TraceArtifact {
|
|
|
287
384
|
requests: TraceRequest[]
|
|
288
385
|
/** The console errors and page errors the page raised. */
|
|
289
386
|
console: string[]
|
|
387
|
+
/**
|
|
388
|
+
* The page's own actions in the order the trace recorded them, bounded — what a test that ran
|
|
389
|
+
* out of a per-test budget spends its time on. A test that repeats one action prints it once per
|
|
390
|
+
* repeat, so the gap between two starts is one repeat's measured cost.
|
|
391
|
+
*/
|
|
392
|
+
actions: TraceAction[]
|
|
290
393
|
}
|
|
291
394
|
```
|
|
292
395
|
|
|
@@ -553,6 +656,27 @@ interface SuiteFilterStrip {
|
|
|
553
656
|
}
|
|
554
657
|
```
|
|
555
658
|
|
|
659
|
+
#### `SuiteRunPipelinePlacement`
|
|
660
|
+
|
|
661
|
+
Whether a finished run's exit code belongs to a stage after the suite runner.
|
|
662
|
+
|
|
663
|
+
```typescript
|
|
664
|
+
interface SuiteRunPipelinePlacement {
|
|
665
|
+
/**
|
|
666
|
+
* True when a pipe this tool must not drop still follows the suite runner: the code in the
|
|
667
|
+
* result is that stage's, not the run's.
|
|
668
|
+
*/
|
|
669
|
+
piped: boolean
|
|
670
|
+
/**
|
|
671
|
+
* True when the suite (or a stage of its pipeline) sits inside a nested `sh -c '<command>'`
|
|
672
|
+
* string, so the parse cannot place it in the command's own text. The caller then says so
|
|
673
|
+
* plainly instead of implying a stage it can point at — and keeps the command's own code when
|
|
674
|
+
* no pipe follows the runner, because on that command the pipeline's last stage IS the run.
|
|
675
|
+
*/
|
|
676
|
+
unplaced: boolean
|
|
677
|
+
}
|
|
678
|
+
```
|
|
679
|
+
|
|
556
680
|
#### `FailedTest`
|
|
557
681
|
|
|
558
682
|
One failed test, as a running suite's log names it.
|
|
@@ -619,6 +743,20 @@ interface FailureCause {
|
|
|
619
743
|
* for a duration group, whose blocks carried no bodies.
|
|
620
744
|
*/
|
|
621
745
|
evidence: string[]
|
|
746
|
+
/**
|
|
747
|
+
* The suite's own per-test budget in ms, when the cause is the test-budget kill
|
|
748
|
+
* (`Test timeout of 15000ms exceeded`). The signature normalizes the number away
|
|
749
|
+
* ({@link normalizedSignature}) so equal causes group, and that number is the one fact that
|
|
750
|
+
* predicts a test spending its budget on a repeated action (xr-molecule-flash-m110 +20:44).
|
|
751
|
+
*/
|
|
752
|
+
budgetMs?: number
|
|
753
|
+
/**
|
|
754
|
+
* The layer the failure came from ({@link classifyRunFailure}). A `connection` cause never
|
|
755
|
+
* reached the app, so it is NOT a cause the app's code can fix: the note says to re-run it
|
|
756
|
+
* once and read the app's log on a repeat, instead of sending a fix at a handler
|
|
757
|
+
* (xr-molecule-flash-m110 +18:42 rewrote a CORS middleware for a 20 s connection timeout).
|
|
758
|
+
*/
|
|
759
|
+
kind: RunFailureKind
|
|
622
760
|
}
|
|
623
761
|
```
|
|
624
762
|
|
|
@@ -650,6 +788,23 @@ type CutBy =
|
|
|
650
788
|
| 'process-stop'
|
|
651
789
|
```
|
|
652
790
|
|
|
791
|
+
#### `RunFailureKind`
|
|
792
|
+
|
|
793
|
+
The layer a failure came from: the transport (no answer at all), the response's status, or an
|
|
794
|
+
assertion over a response that arrived.
|
|
795
|
+
|
|
796
|
+
```typescript
|
|
797
|
+
type RunFailureKind = 'connection' | 'status' | 'assertion'
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
#### `ConnectionFailureKind`
|
|
801
|
+
|
|
802
|
+
What the transport did when a request never got an answer.
|
|
803
|
+
|
|
804
|
+
```typescript
|
|
805
|
+
type ConnectionFailureKind = 'timeout' | 'refused' | 'reset' | 'dns' | 'tls' | 'empty'
|
|
806
|
+
```
|
|
807
|
+
|
|
653
808
|
#### `DiscoveredSkill` _(deprecated)_
|
|
654
809
|
|
|
655
810
|
Re-export SkillEntry as DiscoveredSkill for backwards compatibility.
|
|
@@ -658,6 +813,19 @@ Re-export SkillEntry as DiscoveredSkill for backwards compatibility.
|
|
|
658
813
|
type DiscoveredSkill = SkillEntry
|
|
659
814
|
```
|
|
660
815
|
|
|
816
|
+
#### `InstalledPackageProbe`
|
|
817
|
+
|
|
818
|
+
Looks at the filesystem for {@link InstalledPackageFacts}.
|
|
819
|
+
|
|
820
|
+
The guard cannot `stat` the path itself: the tools act through a backend (a
|
|
821
|
+
sandbox over the network for the fleet), so the caller — which holds that
|
|
822
|
+
backend — supplies the look. {@link shellInstalledPackageProbe} builds one
|
|
823
|
+
from any shell runner.
|
|
824
|
+
|
|
825
|
+
```typescript
|
|
826
|
+
type InstalledPackageProbe = (path: string) => Promise<InstalledPackageFacts>
|
|
827
|
+
```
|
|
828
|
+
|
|
661
829
|
### Classes
|
|
662
830
|
|
|
663
831
|
#### `ToolInputError`
|
|
@@ -922,6 +1090,36 @@ function cutRunSentence(run: CutRun): string
|
|
|
922
1090
|
|
|
923
1091
|
**Returns:** The sentence.
|
|
924
1092
|
|
|
1093
|
+
#### `classifyRunFailure(text)`
|
|
1094
|
+
|
|
1095
|
+
Classify ONE failure's text — a Hurl `error:` block, or a Playwright failure message/body.
|
|
1096
|
+
|
|
1097
|
+
The transport is read first: a block that carries a connection error AND an assertion is a
|
|
1098
|
+
request whose assertion never ran, so it is a connection failure. Only a block that carries no
|
|
1099
|
+
failure signature at all answers null — unknown is never a connection failure, because a
|
|
1100
|
+
misread transport hides a real app failure behind "just re-run it".
|
|
1101
|
+
|
|
1102
|
+
```typescript
|
|
1103
|
+
function classifyRunFailure(text: string): RunFailureClass | null
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
- `text` — One failure's text, as the runner printed it.
|
|
1107
|
+
|
|
1108
|
+
**Returns:** The classification, or null when the text carries no failure this reads.
|
|
1109
|
+
|
|
1110
|
+
#### `allConnectionFailures(failures)`
|
|
1111
|
+
|
|
1112
|
+
Whether every one of the classified failures is a connection failure — the only shape in which
|
|
1113
|
+
no response the app produced was measured.
|
|
1114
|
+
|
|
1115
|
+
```typescript
|
|
1116
|
+
function allConnectionFailures(failures: readonly (RunFailureClass | null)[]): boolean
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
- `failures` — The run's classifications, in printed order.
|
|
1120
|
+
|
|
1121
|
+
**Returns:** True when there is at least one and none of them is the app's.
|
|
1122
|
+
|
|
925
1123
|
#### `normalizeToolInput(schema, raw)`
|
|
926
1124
|
|
|
927
1125
|
Move known aliases onto the declared parameter names and report what is still
|
|
@@ -1029,6 +1227,26 @@ function commandRunsNoTests(command: string): boolean
|
|
|
1029
1227
|
|
|
1030
1228
|
**Returns:** True when the command invokes a runner only to print.
|
|
1031
1229
|
|
|
1230
|
+
#### `leadingSleepPeek(command)`
|
|
1231
|
+
|
|
1232
|
+
The leading `sleep` of a command, when the first statement is one and it asks for at least
|
|
1233
|
+
{@link MIN_PEEK_SLEEP_SECONDS}.
|
|
1234
|
+
|
|
1235
|
+
The statement is read by {@link locatedCommandSegments} — the same parse every other command
|
|
1236
|
+
classifier uses — so only a `sleep` in command position of the FIRST statement counts. The end
|
|
1237
|
+
of that statement is then found by walking forward from its own start: the statement is
|
|
1238
|
+
`sleep <duration>`, whose words carry no quotes and open no substitution, so the first unquoted
|
|
1239
|
+
`;`, newline or `&` ends it. A `|` is refused: dropping the left side of a pipeline would hand
|
|
1240
|
+
the right side its stdin instead, and a `||` fallback would run on a success that never did.
|
|
1241
|
+
|
|
1242
|
+
```typescript
|
|
1243
|
+
function leadingSleepPeek(command: string): LeadingSleep | null
|
|
1244
|
+
```
|
|
1245
|
+
|
|
1246
|
+
- `command` — The shell command the executor sent.
|
|
1247
|
+
|
|
1248
|
+
**Returns:** The seconds and the remaining command, or null when the command does not open with a long `sleep`.
|
|
1249
|
+
|
|
1032
1250
|
#### `withoutHeredocs(command)`
|
|
1033
1251
|
|
|
1034
1252
|
A command with its heredoc bodies removed: the runs, kills and hosts it names in a file it
|
|
@@ -1061,24 +1279,68 @@ function suiteCommandTarget(command: string): string
|
|
|
1061
1279
|
|
|
1062
1280
|
**Returns:** The target key.
|
|
1063
1281
|
|
|
1064
|
-
#### `
|
|
1282
|
+
#### `namesSuiteConfig(command)`
|
|
1283
|
+
|
|
1284
|
+
Whether a Playwright statement names its own config — the reading {@link withSuiteConfig} and
|
|
1285
|
+
{@link scopedRerunCommand} share, so neither adds a second `--config` to a command that has one.
|
|
1286
|
+
|
|
1287
|
+
```typescript
|
|
1288
|
+
function namesSuiteConfig(command: string): boolean
|
|
1289
|
+
```
|
|
1290
|
+
|
|
1291
|
+
- `command` — A command, or the Playwright statement inside it.
|
|
1292
|
+
|
|
1293
|
+
**Returns:** True when the statement loads a config of its own.
|
|
1294
|
+
|
|
1295
|
+
#### `withSuiteConfig(command, config)`
|
|
1296
|
+
|
|
1297
|
+
The command with a `--config` added to the Playwright invocation it starts — or unchanged when
|
|
1298
|
+
it already names one, or starts no Playwright run.
|
|
1299
|
+
|
|
1300
|
+
The flag rides the same statement the runner does: a `cd`, an env prefix and a `timeout` before
|
|
1301
|
+
it are left exactly as they were, and so is everything chained after the run (`| tail -50`).
|
|
1302
|
+
|
|
1303
|
+
xr-molecule-flash-m113 (+19:09): the model's fix-round re-run dropped the
|
|
1304
|
+
`--config playwright.conduit.config.ts` both earlier runs had carried, so Playwright started with
|
|
1305
|
+
NO base URL and all 10 failures were `page.goto: Cannot navigate to invalid URL` — a failure list
|
|
1306
|
+
that says nothing about the app. The platform composes commands back to the executor too (the
|
|
1307
|
+
narrowed re-run of a finished run's failures), and a command it hands back has to carry the
|
|
1308
|
+
config the run was measured under, never the shape that caused that finding.
|
|
1309
|
+
|
|
1310
|
+
```typescript
|
|
1311
|
+
function withSuiteConfig(command: string, config: string | null | undefined): string
|
|
1312
|
+
```
|
|
1313
|
+
|
|
1314
|
+
- `command` — The command as the executor sent it.
|
|
1315
|
+
- `config` — The config the run loads, when the caller knows it.
|
|
1316
|
+
|
|
1317
|
+
**Returns:** The command with the flag, or the command unchanged.
|
|
1318
|
+
|
|
1319
|
+
#### `scopedRerunCommand(command, locations, excluded, config)`
|
|
1065
1320
|
|
|
1066
1321
|
The whole-suite command made scoped to the tests it should re-run instead: the same
|
|
1067
1322
|
invocation — same directory, same settings — with the named `file:line`s in place of the whole
|
|
1068
1323
|
suite, `--last-failed` dropped (it re-runs the tests that never ran too, X1 flash-m60) and
|
|
1069
1324
|
`--retries=0` set (a re-run of a known failure does not need to pay for retries).
|
|
1070
1325
|
|
|
1326
|
+
`config` is the config the run was measured under ({@link withSuiteConfig}): the narrowed re-run
|
|
1327
|
+
carries it whenever the command itself does not, so a run that dropped `--config` cannot be
|
|
1328
|
+
handed back a command with the same defect (xr-molecule-flash-m113: every failing test was
|
|
1329
|
+
`Cannot navigate to invalid URL` because the re-run loaded no base URL).
|
|
1330
|
+
|
|
1071
1331
|
```typescript
|
|
1072
1332
|
function scopedRerunCommand(
|
|
1073
1333
|
command: string,
|
|
1074
1334
|
locations: readonly string[],
|
|
1075
1335
|
excluded?: readonly string[],
|
|
1336
|
+
config?: string | null,
|
|
1076
1337
|
): string
|
|
1077
1338
|
```
|
|
1078
1339
|
|
|
1079
1340
|
- `command` — The whole-suite run's command.
|
|
1080
1341
|
- `locations` — The failing `file:line`s to re-run, as the run's own log printed them — or, for a run that started outside the suite, the absolute form Playwright matches each file argument against.
|
|
1081
1342
|
- `excluded` — The test titles the request carves out. They are inverted out (`--grep-invert`) so a re-run of the failing locations cannot report one of them again — xr-molecule-flash-m101 re-ran the whole 139-test suite and spent ~4 minutes to be told about a test the request had already said does not count.
|
|
1343
|
+
- `config` — The config the run loaded, when the caller knows it; added when the command does not name one.
|
|
1082
1344
|
|
|
1083
1345
|
**Returns:** The scoped command, or the command unchanged when it runs no Playwright suite.
|
|
1084
1346
|
|
|
@@ -1213,10 +1475,26 @@ function moleculeDistReadNote(path: string): string | null
|
|
|
1213
1475
|
|
|
1214
1476
|
**Returns:** The note, or null when the path is not inside a package's `dist`.
|
|
1215
1477
|
|
|
1216
|
-
#### `
|
|
1478
|
+
#### `shellInstalledPackageProbe(run)`
|
|
1479
|
+
|
|
1480
|
+
Build an {@link InstalledPackageProbe} from a shell runner (a backend's
|
|
1481
|
+
`run`, or a sandbox's `exec`): one command reports whether the entry is a
|
|
1482
|
+
link and whether a `package.json` resolves under it.
|
|
1483
|
+
|
|
1484
|
+
```typescript
|
|
1485
|
+
function shellInstalledPackageProbe(
|
|
1486
|
+
run: (command: string) => Promise<{ stdout?: string } | null | undefined>,
|
|
1487
|
+
): InstalledPackageProbe
|
|
1488
|
+
```
|
|
1489
|
+
|
|
1490
|
+
- `run` — Runs a command where the path lives.
|
|
1491
|
+
|
|
1492
|
+
**Returns:** The probe.
|
|
1217
1493
|
|
|
1218
|
-
|
|
1219
|
-
|
|
1494
|
+
#### `installedPackageWriteRefusal(path, probe)`
|
|
1495
|
+
|
|
1496
|
+
The refusal for a write whose target is inside an INSTALLED package, or null
|
|
1497
|
+
when the path is not under `node_modules` or nothing is installed there.
|
|
1220
1498
|
|
|
1221
1499
|
`node_modules` is not the project's code: nothing written there survives the
|
|
1222
1500
|
next install, no deploy carries it, and a sandbox whose dependency tree is
|
|
@@ -1229,17 +1507,29 @@ answered `ok: true`, and 18 s went to noticing, `npm pack`-ing the package and
|
|
|
1229
1507
|
putting the file back. Reading these files stays allowed (that is how the
|
|
1230
1508
|
declarations above are read at all).
|
|
1231
1509
|
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1510
|
+
What is protected is the INSTALL, not the spelling: the decision comes from
|
|
1511
|
+
{@link InstalledPackageFacts}, never from the path alone (m106 above). Three
|
|
1512
|
+
things are the run's own to remove or replace —
|
|
1513
|
+
|
|
1514
|
+
- a `node_modules` that is a SYMLINK: `rm`/`unlink` removes the link, never the
|
|
1515
|
+
tree it points at, so a link the run made cannot clobber anything;
|
|
1516
|
+
- anything under the run's own `.mol-scratch/` directory;
|
|
1517
|
+
- a `node_modules` with no `package.json` under it (nothing was ever installed).
|
|
1518
|
+
|
|
1519
|
+
A path INSIDE the link is still decided by what resolves there: a link into a
|
|
1520
|
+
real tree is refused, because removing or writing through it reaches the
|
|
1521
|
+
|
|
1522
|
+
_(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/tools.d.ts`.)_
|
|
1237
1523
|
|
|
1238
1524
|
```typescript
|
|
1239
|
-
function installedPackageWriteRefusal(
|
|
1525
|
+
function installedPackageWriteRefusal(
|
|
1526
|
+
path: string,
|
|
1527
|
+
probe?: InstalledPackageProbe,
|
|
1528
|
+
): Promise<string | null>
|
|
1240
1529
|
```
|
|
1241
1530
|
|
|
1242
1531
|
- `path` — An absolute path a tool is about to write.
|
|
1532
|
+
- `probe` — Looks at the filesystem where the path lives.
|
|
1243
1533
|
|
|
1244
1534
|
**Returns:** The one-line refusal naming the package, or null when nothing is installed there.
|
|
1245
1535
|
|
|
@@ -1268,10 +1558,17 @@ on `unzip` would make the read fail on every sandbox that has none. The zip is r
|
|
|
1268
1558
|
central directory and `zlib.inflateRawSync` — about forty lines, and the only thing that has to
|
|
1269
1559
|
be true of a `trace.zip` is that it IS one.
|
|
1270
1560
|
|
|
1271
|
-
A request is kept over a static asset when it failed
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1561
|
+
A request is kept over a static asset when it failed — a `status >= 400`, or no response at all
|
|
1562
|
+
together with Playwright's own error text (`-1` plus `_failureText`, a refused connection) — and
|
|
1563
|
+
over anything else when it is the page talking to the app (`fetch`/`xhr`/`document`): a failing
|
|
1564
|
+
test's trace holds the whole page load. A request with no response and NO error text was aborted
|
|
1565
|
+
or still in flight when the test ended; it is kept too, but as what it is, not as a failure.
|
|
1566
|
+
|
|
1567
|
+
A request answered 4xx by the app's OWN API also keeps what the page SENT and the first of what
|
|
1568
|
+
came back: Playwright stores either inline (`text`) or in a resource entry (`_file`), and both
|
|
1569
|
+
are read. That is where a wrapped body shows: xr-molecule-flash-m111's helper passed
|
|
1570
|
+
|
|
1571
|
+
_(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/trace-artifacts.d.ts`.)_
|
|
1275
1572
|
|
|
1276
1573
|
```typescript
|
|
1277
1574
|
function traceArtifactsScript(): string
|
|
@@ -1294,7 +1591,7 @@ function parseTraceArtifacts(stdout: string): TraceArtifact[]
|
|
|
1294
1591
|
|
|
1295
1592
|
**Returns:** One entry per trace it printed.
|
|
1296
1593
|
|
|
1297
|
-
#### `failureTraceNote(items, target)`
|
|
1594
|
+
#### `failureTraceNote(items, target, earlierFailures)`
|
|
1298
1595
|
|
|
1299
1596
|
The note a failed suite run's result carries: what each failing test's page actually sent, and
|
|
1300
1597
|
what came back.
|
|
@@ -1305,14 +1602,34 @@ with them: read the handler the route reaches, not the selector. It is BOUNDED t
|
|
|
1305
1602
|
{@link MAX_TRACE_NOTE_TESTS} tests with {@link MAX_TRACE_NOTE_REQUESTS} requests each, because it
|
|
1306
1603
|
rides in a result the model pays for.
|
|
1307
1604
|
|
|
1605
|
+
The three kinds are kept apart, because they mean different things. A FAILED request (4xx/5xx, or
|
|
1606
|
+
a network error with Playwright's own text) is a cause. A request with NO RESPONSE RECORDED —
|
|
1607
|
+
Playwright's `-1`, no error text — was still in flight when the test ended (the page closed under
|
|
1608
|
+
it); listing it as a failure sent a run hunting an API that never answered anything wrong
|
|
1609
|
+
(xr-molecule-flash-m112 +30:45). The rest are the page's last answered requests.
|
|
1610
|
+
|
|
1611
|
+
A 4xx request carries what the page SENT beside its status, so a wrapped body is visible in one
|
|
1612
|
+
line rather than inferred from the status; when one of those bodies is an object whose only key
|
|
1613
|
+
is `data`, the note names the call shape that produces it (xr-molecule-flash-m111 +11:36).
|
|
1614
|
+
|
|
1615
|
+
WHICH rows it spends is evidence, not artifact order (xr-molecule-flash-m112 +53:46): a row
|
|
1616
|
+
needs a recorded response, a real failure or a console error ({@link traceRowEvidence}), rows are
|
|
1617
|
+
|
|
1618
|
+
_(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/trace-artifacts.d.ts`.)_
|
|
1619
|
+
|
|
1308
1620
|
```typescript
|
|
1309
|
-
function failureTraceNote(
|
|
1621
|
+
function failureTraceNote(
|
|
1622
|
+
items: readonly TraceArtifact[],
|
|
1623
|
+
target: string,
|
|
1624
|
+
earlierFailures?: readonly string[],
|
|
1625
|
+
): string | null
|
|
1310
1626
|
```
|
|
1311
1627
|
|
|
1312
1628
|
- `items` — The traces {@link parseTraceArtifacts} read.
|
|
1313
1629
|
- `target` — Where the run went — the deployed host, as the note names it.
|
|
1630
|
+
- `earlierFailures` — The failing `file:line`s earlier walks of this suite left, so a repeat is ranked above a one-off. Empty when the caller knows of no earlier walk.
|
|
1314
1631
|
|
|
1315
|
-
**Returns:** The note, or null when no trace held a
|
|
1632
|
+
**Returns:** The note, or null when no trace held a recorded response, a real failure or a console error.
|
|
1316
1633
|
|
|
1317
1634
|
#### `suiteRecordsTraces(configText)`
|
|
1318
1635
|
|
|
@@ -1602,23 +1919,40 @@ function stripTrailingSuiteFilters(command: string): SuiteFilterStrip
|
|
|
1602
1919
|
|
|
1603
1920
|
**Returns:** The rewritten command and the stages dropped.
|
|
1604
1921
|
|
|
1922
|
+
#### `suiteRunPipelinePlacement(command)`
|
|
1923
|
+
|
|
1924
|
+
Where the suite runner's exit code comes from: the runner itself, or a stage piped after it.
|
|
1925
|
+
|
|
1926
|
+
{@link suiteRunPipedAfterRunner}'s one question, with the honest third answer kept apart. The
|
|
1927
|
+
code a finished run reports is its LAST pipeline stage's, so a stage after the runner makes the
|
|
1928
|
+
code the stage's — but only when such a stage EXISTS. The platform used to report "piped" for
|
|
1929
|
+
any run whose statements it could not place in the text, which one heredoc body was enough to
|
|
1930
|
+
cause: on X1 xr-molecule-flash-m105 (+08:12) a config written in the same `exec_command` made
|
|
1931
|
+
the run come back with no exit code at all, and the note under it claimed a stage after the
|
|
1932
|
+
runner that was not there. The parse now places every statement (`locatedCommandSegments`), so
|
|
1933
|
+
"unplaced" is the rare, named case rather than a guess dressed as an answer.
|
|
1934
|
+
|
|
1935
|
+
```typescript
|
|
1936
|
+
function suiteRunPipelinePlacement(command: string): SuiteRunPipelinePlacement
|
|
1937
|
+
```
|
|
1938
|
+
|
|
1939
|
+
- `command` — The shell command, after the streaming rewrite when one was applied.
|
|
1940
|
+
|
|
1941
|
+
**Returns:** Whether a stage follows the runner, and whether the run could be placed at all.
|
|
1942
|
+
|
|
1605
1943
|
#### `suiteRunPipedAfterRunner(command)`
|
|
1606
1944
|
|
|
1607
1945
|
Whether the command's last step runs a suite whose output still passes through a stage after
|
|
1608
1946
|
the runner — one {@link stripTrailingSuiteFilters} could not prove is output-only (`| tee log`,
|
|
1609
1947
|
`| xargs …`). The pipeline's exit status is that stage's, not the run's.
|
|
1610
1948
|
|
|
1611
|
-
A command whose stages cannot be placed in the text (irregular whitespace inside the run) is
|
|
1612
|
-
reported as piped too: whether a pipe follows the runner is then UNKNOWN, and an unknown exit
|
|
1613
|
-
code that gets trusted is a failing run read as a pass — the failure this rule exists to stop.
|
|
1614
|
-
|
|
1615
1949
|
```typescript
|
|
1616
1950
|
function suiteRunPipedAfterRunner(command: string): boolean
|
|
1617
1951
|
```
|
|
1618
1952
|
|
|
1619
1953
|
- `command` — The shell command, after the streaming rewrite when one was applied.
|
|
1620
1954
|
|
|
1621
|
-
**Returns:** True when a pipe this tool must not drop still follows the suite runner
|
|
1955
|
+
**Returns:** True when a pipe this tool must not drop still follows the suite runner.
|
|
1622
1956
|
|
|
1623
1957
|
#### `suiteRunPriorityLaunch(command, launch)`
|
|
1624
1958
|
|
|
@@ -2231,21 +2565,28 @@ executor reads, so one round of fixes covers all of them rather than the one cau
|
|
|
2231
2565
|
stopped early happened to reach.
|
|
2232
2566
|
|
|
2233
2567
|
A test the request excludes is not one of the causes — it is dropped and named once, at the
|
|
2234
|
-
end, so a result never asks to fix a test it also says to ignore.
|
|
2235
|
-
|
|
2236
|
-
|
|
2568
|
+
end, so a result never asks to fix a test it also says to ignore. A test the runner itself
|
|
2569
|
+
declared `flaky` (it failed once and passed on its config retry) is not a cause either: it is
|
|
2570
|
+
named apart from them, once, as what the tally called it ({@link flakyTestsDeclared}). Where
|
|
2571
|
+
the caller knows how the run was started, the note also hands over the narrowed re-run of
|
|
2572
|
+
exactly those tests ({@link rerunOfRunningSuite}) instead of leaving the executor to re-run the
|
|
2573
|
+
whole suite.
|
|
2574
|
+
|
|
2575
|
+
A run whose failures are ALL {@link NO_BASE_URL_ERROR} is not a set of causes at all: it is one
|
|
2576
|
+
configuration failure, said in one line ({@link noBaseUrlConfigNote}) rather than a list that
|
|
2577
|
+
reads as ten defects in the app.
|
|
2237
2578
|
|
|
2238
2579
|
```typescript
|
|
2239
2580
|
function failureCausesNote(
|
|
2240
2581
|
log: string,
|
|
2241
2582
|
excluded?: readonly string[],
|
|
2242
|
-
run?: { command: string; cwd?: string; log?: string },
|
|
2583
|
+
run?: { command: string; cwd?: string; log?: string; config?: string | null },
|
|
2243
2584
|
): string | null
|
|
2244
2585
|
```
|
|
2245
2586
|
|
|
2246
2587
|
- `log` — The finished run's output.
|
|
2247
2588
|
- `excluded` — The test titles the request carves out, if the caller knows them.
|
|
2248
|
-
- `run` — How the run was started, when the caller knows it: the narrowed re-run is built from `command`/`cwd`, and `log` (the path the output was written to) is what the "left out" sentence greps when more causes exist than the result has room for.
|
|
2589
|
+
- `run` — How the run was started, when the caller knows it: the narrowed re-run is built from `command`/`cwd`/`config`, and `log` (the path the output was written to) is what the "left out" sentence greps when more causes exist than the result has room for.
|
|
2249
2590
|
|
|
2250
2591
|
**Returns:** The note, or null.
|
|
2251
2592
|
|
|
@@ -2264,13 +2605,13 @@ the same app and database, and that is exactly what is refused while the run wal
|
|
|
2264
2605
|
|
|
2265
2606
|
```typescript
|
|
2266
2607
|
function rerunOfRunningSuite(
|
|
2267
|
-
run: { command: string; cwd?: string },
|
|
2608
|
+
run: { command: string; cwd?: string; config?: string | null },
|
|
2268
2609
|
locations: readonly string[],
|
|
2269
2610
|
excluded?: readonly string[],
|
|
2270
2611
|
): string | null
|
|
2271
2612
|
```
|
|
2272
2613
|
|
|
2273
|
-
- `run` — The run in flight: the command it was started with, as it was run,
|
|
2614
|
+
- `run` — The run in flight: the command it was started with, as it was run, the directory that command ran in, and the config it loaded when the caller knows it.
|
|
2274
2615
|
- `locations` — The failing `file:line`s to re-run, as the run's log printed them.
|
|
2275
2616
|
- `excluded` — The test titles the request carves out: the re-run inverts them out (`--grep-invert`) so it cannot report them again.
|
|
2276
2617
|
|
|
@@ -2414,6 +2755,15 @@ Canonical tool schemas shared by the agent runtime and documentation.
|
|
|
2414
2755
|
const TOOL_SCHEMAS: Record<string, ToolSchema>
|
|
2415
2756
|
```
|
|
2416
2757
|
|
|
2758
|
+
#### `MIN_PEEK_SLEEP_SECONDS`
|
|
2759
|
+
|
|
2760
|
+
The shortest leading sleep the platform drops: below it the wall clock it costs is noise, and a
|
|
2761
|
+
short settle (`sleep 2; curl …`) is a legitimate thing to run.
|
|
2762
|
+
|
|
2763
|
+
```typescript
|
|
2764
|
+
const MIN_PEEK_SLEEP_SECONDS: 5
|
|
2765
|
+
```
|
|
2766
|
+
|
|
2417
2767
|
#### `SPLIT_WORK_ADVICE`
|
|
2418
2768
|
|
|
2419
2769
|
The closing advice on an over-budget message for a command that is not a test
|
|
@@ -2466,6 +2816,22 @@ How many console errors one test's trace contributes.
|
|
|
2466
2816
|
const MAX_TRACED_CONSOLE: 4
|
|
2467
2817
|
```
|
|
2468
2818
|
|
|
2819
|
+
#### `MAX_TRACED_ACTIONS`
|
|
2820
|
+
|
|
2821
|
+
How many of the page's own actions one test's trace contributes, the LAST ones.
|
|
2822
|
+
|
|
2823
|
+
```typescript
|
|
2824
|
+
const MAX_TRACED_ACTIONS: 40
|
|
2825
|
+
```
|
|
2826
|
+
|
|
2827
|
+
#### `MAX_TRACED_BODY_CHARS`
|
|
2828
|
+
|
|
2829
|
+
How much of a 4xx request's sent body (or its response body) the trace read keeps.
|
|
2830
|
+
|
|
2831
|
+
```typescript
|
|
2832
|
+
const MAX_TRACED_BODY_CHARS: 300
|
|
2833
|
+
```
|
|
2834
|
+
|
|
2469
2835
|
#### `MAX_TRACE_NOTE_TESTS`
|
|
2470
2836
|
|
|
2471
2837
|
How many tests the note in a run's result names.
|
|
@@ -2490,6 +2856,22 @@ How long a URL the note prints, before the middle is cut.
|
|
|
2490
2856
|
const TRACE_NOTE_URL_CHARS: 96
|
|
2491
2857
|
```
|
|
2492
2858
|
|
|
2859
|
+
#### `TRACE_NOTE_SENT_CHARS`
|
|
2860
|
+
|
|
2861
|
+
How much of the sent body the note prints — enough to see a `{"data":…}` wrapper.
|
|
2862
|
+
|
|
2863
|
+
```typescript
|
|
2864
|
+
const TRACE_NOTE_SENT_CHARS: 160
|
|
2865
|
+
```
|
|
2866
|
+
|
|
2867
|
+
#### `TRACE_NOTE_GOT_CHARS`
|
|
2868
|
+
|
|
2869
|
+
How much of the response body the note prints — the API's first error line.
|
|
2870
|
+
|
|
2871
|
+
```typescript
|
|
2872
|
+
const TRACE_NOTE_GOT_CHARS: 120
|
|
2873
|
+
```
|
|
2874
|
+
|
|
2493
2875
|
#### `DIAGNOSIS_TRACE_FLAG`
|
|
2494
2876
|
|
|
2495
2877
|
The `--trace` flag this platform adds, and the only value it adds it with.
|