@molecule/api-ai-tools 1.16.3 → 1.16.4
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 +161 -136
- 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-11-
|
|
6
|
+
Generated: 2026-11-04T14:19:49.511Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/api-ai-tools
|
|
@@ -1266,165 +1266,76 @@ Allows consumers to customize security, callbacks, and tool selection.
|
|
|
1266
1266
|
|
|
1267
1267
|
```typescript
|
|
1268
1268
|
interface ToolBuildConfig {
|
|
1269
|
-
/** Which tools to include.
|
|
1269
|
+
/** Which tools to include. */
|
|
1270
1270
|
include?: string[]
|
|
1271
1271
|
|
|
1272
|
-
/** Which tools to exclude.
|
|
1272
|
+
/** Which tools to exclude. */
|
|
1273
1273
|
exclude?: string[]
|
|
1274
1274
|
|
|
1275
|
-
/** Whether to validate paths stay within projectRoot.
|
|
1275
|
+
/** Whether to validate paths stay within projectRoot. */
|
|
1276
1276
|
pathGuards?: boolean
|
|
1277
1277
|
|
|
1278
|
-
/** Whether to check symlinks resolve within projectRoot.
|
|
1278
|
+
/** Whether to check symlinks resolve within projectRoot. */
|
|
1279
1279
|
symlinkGuards?: boolean
|
|
1280
1280
|
|
|
1281
|
-
/** Whether to redact secrets in file reads and command output.
|
|
1281
|
+
/** Whether to redact secrets in file reads and command output. */
|
|
1282
1282
|
redactSecrets?: boolean
|
|
1283
1283
|
|
|
1284
|
-
/** Whether to block dangerous shell commands (env dumps, /proc access).
|
|
1284
|
+
/** Whether to block dangerous shell commands (env dumps, /proc access). */
|
|
1285
1285
|
blockDangerousCommands?: boolean
|
|
1286
1286
|
|
|
1287
|
-
/**
|
|
1288
|
-
* Consumer-specific command guard for `exec_command`, checked BEFORE execution (after
|
|
1289
|
-
* the built-in dangerous-command check). Return an error string to block the command —
|
|
1290
|
-
* it is returned to the model verbatim, so make it actionable (say what to do instead) —
|
|
1291
|
-
* or `null`/`undefined` to allow it. Keeps environment-specific rules (e.g. an IDE
|
|
1292
|
-
* sandbox forbidding installs that would break its preinstalled library) out of this
|
|
1293
|
-
* shared package.
|
|
1294
|
-
*
|
|
1295
|
-
* @param command - The shell command the model asked to run.
|
|
1296
|
-
* @param cwd - The resolved working directory it would run in.
|
|
1297
|
-
* @returns An error string to block, or null/undefined to allow.
|
|
1298
|
-
*/
|
|
1287
|
+
/** Consumer-specific command guard for `exec_command`, checked BEFORE execution (after the built-in dangerous-command check). */
|
|
1299
1288
|
blockCommand?: (command: string, cwd: string) => string | null | undefined
|
|
1300
1289
|
|
|
1301
|
-
/**
|
|
1302
|
-
* Timeout (ms) for a single `exec_command` run. `exec_command` legitimately
|
|
1303
|
-
* runs LONG — `npm install`, a production build, a test suite — so the default
|
|
1304
|
-
* is generous (2 min); the old 30 s hardcap killed those spuriously. A consumer
|
|
1305
|
-
* that wraps tool calls in its own outer timeout should set this to match (or
|
|
1306
|
-
* slightly exceed) that budget so its own timeout is the effective bound and
|
|
1307
|
-
* produces the nicer "tool timed out" message. Quick commands are unaffected —
|
|
1308
|
-
* this is only the ceiling before a wedged command is killed.
|
|
1309
|
-
*/
|
|
1290
|
+
/** Timeout (ms) for a single `exec_command` run. */
|
|
1310
1291
|
execTimeoutMs?: number
|
|
1311
1292
|
|
|
1312
|
-
/**
|
|
1313
|
-
* Budget (ms) for a single `exec_command`, passed to `backend.run` as
|
|
1314
|
-
* `budgetMs`: the backend runs the command under `timeout` in its own shell,
|
|
1315
|
-
* so when it overruns it is stopped there and the tool still returns
|
|
1316
|
-
* everything it printed until then (exit code 124 plus an `error` naming
|
|
1317
|
-
* the limit). Without this, an outer per-tool timeout races the run and
|
|
1318
|
-
* discards minutes of build or test output along with the result. Set it a
|
|
1319
|
-
* little under that outer timeout. Unset = no budget.
|
|
1320
|
-
*/
|
|
1293
|
+
/** Budget (ms) for a single `exec_command`, passed to `backend.run` as `budgetMs`: the backend runs the command under `timeout` in its own shell, so when it overr… */
|
|
1321
1294
|
commandBudgetMs?: number
|
|
1322
1295
|
|
|
1323
|
-
/**
|
|
1324
|
-
* Maximum time (ms) one `wait_for_task` call may wait, independently of the foreground
|
|
1325
|
-
* {@link commandBudgetMs}. The caller's requested `timeout` is honoured up to this budget.
|
|
1326
|
-
* Leave unset to keep the legacy ceiling: `commandBudgetMs` (or 290 s) less a 10 s result
|
|
1327
|
-
* margin. A host that raises this must also give the tool call a longer outer watchdog.
|
|
1328
|
-
*/
|
|
1296
|
+
/** Maximum time (ms) one `wait_for_task` call may wait, independently of the foreground {@link commandBudgetMs}. */
|
|
1329
1297
|
waitBudgetMs?: number
|
|
1330
1298
|
|
|
1331
|
-
/**
|
|
1332
|
-
* Opt in to one partial diagnostic return for a task driving this known deployed URL.
|
|
1333
|
-
* Return null when the task already returned a wait result or its history is unknown.
|
|
1334
|
-
* Only a real suite command with a complete inline failure report can yield; it remains
|
|
1335
|
-
* running, with no exit code or completed proof. Absent leaves ordinary waits unchanged.
|
|
1336
|
-
*/
|
|
1299
|
+
/** Opt in to one partial diagnostic return for a task driving this known deployed URL. */
|
|
1337
1300
|
yieldOnFirstFailureFor?: (taskId: string) => string | null
|
|
1338
1301
|
|
|
1339
|
-
/**
|
|
1340
|
-
* How long (ms) exec_command waits for a command it backgrounded only because the
|
|
1341
|
-
* command asked for more than {@link commandBudgetMs}, before handing back a task
|
|
1342
|
-
* id; one that finishes inside it returns like a foreground run. Default 45000.
|
|
1343
|
-
*/
|
|
1302
|
+
/** How long (ms) exec_command waits for a command it backgrounded only because the command asked for more than {@link commandBudgetMs}, before handing back a task… */
|
|
1344
1303
|
overCeilingGraceMs?: number
|
|
1345
1304
|
|
|
1346
|
-
/**
|
|
1347
|
-
* Directory names `search_files` and `find_files` skip (VS Code
|
|
1348
|
-
* `search.exclude` semantics). Defaults to `DEFAULT_SEARCH_EXCLUDED_DIRS`
|
|
1349
|
-
* (node_modules, VCS dirs, build output). Pass the consumer's per-project
|
|
1350
|
-
* setting so every search surface shares ONE synchronized set.
|
|
1351
|
-
*/
|
|
1305
|
+
/** Directory names `search_files` and `find_files` skip (VS Code `search.exclude` semantics). */
|
|
1352
1306
|
searchExcludedDirs?: string[]
|
|
1353
1307
|
|
|
1354
|
-
/**
|
|
1355
|
-
* Whether a LARGE HTML document should come back as its OUTLINE — the head's
|
|
1356
|
-
* tags and the tags that open each body section, one line each, plus a note
|
|
1357
|
-
* naming the offset/limit that returns the whole document — instead of its
|
|
1358
|
-
* whole text. Over {@link MAX_HTML_INLINE_CHARS}, and only when the read named
|
|
1359
|
-
* no line window.
|
|
1360
|
-
*
|
|
1361
|
-
* A getter, not a boolean, because the answer belongs to the TURN, not to the
|
|
1362
|
-
* tool set: a host that plans first and builds after wants an outline while the
|
|
1363
|
-
* executor is researching (where a read it cannot act on is pure context cost)
|
|
1364
|
-
* and the document itself while it is writing the page. Unset means every big
|
|
1365
|
-
* HTML read returns its text, which is what a host with no such phases wants.
|
|
1366
|
-
*
|
|
1367
|
-
* @returns True when a large HTML read should be outlined rather than returned.
|
|
1368
|
-
*/
|
|
1308
|
+
/** Whether a LARGE HTML document should come back as its OUTLINE — the head's tags and the tags that open each body section, one line each, plus a note naming the… */
|
|
1369
1309
|
outlineLargeHtml?: () => boolean
|
|
1370
1310
|
|
|
1371
|
-
/**
|
|
1372
|
-
* The test titles the person's request EXCLUDES by name (molecule-dev's `excludedTestTitles`),
|
|
1373
|
-
* asked when a finished suite run's cause note is built. Their failures are not causes to fix:
|
|
1374
|
-
* the note drops them, says so at the end, and inverts them out of the narrowed re-run it hands
|
|
1375
|
-
* over — a result must never name a test beside "it does not count" (an executor once spent a
|
|
1376
|
-
* turn and an edit on the excluded test).
|
|
1377
|
-
*
|
|
1378
|
-
* A getter, not an array, because the request is read per turn while the tool set is built
|
|
1379
|
-
* once. Unset means no test is excluded.
|
|
1380
|
-
*
|
|
1381
|
-
* @returns The quoted titles the request carves out.
|
|
1382
|
-
*/
|
|
1311
|
+
/** The test titles the person's request EXCLUDES by name (molecule-dev's `excludedTestTitles`), asked when a finished suite run's cause note is built. */
|
|
1383
1312
|
excludedTestTitles?: () => readonly string[]
|
|
1384
1313
|
|
|
1385
|
-
/**
|
|
1386
|
-
* The `NAME=value` settings the person's request REQUIRES of a suite run (molecule-dev's
|
|
1387
|
-
* `requiredRunSettings` — its mode, say), asked when the cause note composes a narrowed re-run
|
|
1388
|
-
* of a finished run's failures. A re-run composed from the executor's own command inherits what
|
|
1389
|
-
* that command set — and nothing it left out, so a run that measured the suite in `spa` handed
|
|
1390
|
-
* back a re-run that would measure `spa` again (the request names `TEST_MODE=fullstack`, and
|
|
1391
|
-
* both the run and its re-run omitted it).
|
|
1392
|
-
*
|
|
1393
|
-
* A getter, not an array: the request is read per turn while the tool set is built once, and
|
|
1394
|
-
* what the suite's own files read is the consumer's reading. Unset answers "nothing required".
|
|
1395
|
-
*
|
|
1396
|
-
* @param command - The command the finished run was started with.
|
|
1397
|
-
* @param cwd - The resolved working directory it ran in.
|
|
1398
|
-
* @returns The settings to put on a re-run of that command.
|
|
1399
|
-
*/
|
|
1314
|
+
/** The `NAME=value` settings the person's request REQUIRES of a suite run (molecule-dev's `requiredRunSettings` — its mode, say), asked when the cause note compos… */
|
|
1400
1315
|
requiredSuiteEnv?: (
|
|
1401
1316
|
command: string,
|
|
1402
1317
|
cwd: string,
|
|
1403
1318
|
) => Promise<readonly { name: string; value: string }[] | null | undefined>
|
|
1404
1319
|
|
|
1405
|
-
/**
|
|
1406
|
-
* The supplied suite's own budget, when the Playwright config a command would load sets
|
|
1407
|
-
* different settings, asked BEFORE the run executes. The consumer knows where the suite and its
|
|
1408
|
-
* base config live; this shared package does not, so the reading is the consumer's and the
|
|
1409
|
-
* mechanics — putting the flags on the runner's own arguments, before the pipeline and outside
|
|
1410
|
-
* any redirect or group closer, and pointing `--config` at the derived config that carries the
|
|
1411
|
-
* settings no flag can — are this tool's.
|
|
1412
|
-
*
|
|
1413
|
-
* Called for a Playwright suite command only, and only the LAST suite step is touched. A run
|
|
1414
|
-
* that already keeps the suite's settings, or a sandbox with no supplied suite, answers `null`.
|
|
1415
|
-
* Unset (or a hook that throws) changes nothing: the command runs as the model wrote it.
|
|
1416
|
-
*
|
|
1417
|
-
* @param command - The shell command, as the model sent it.
|
|
1418
|
-
* @param cwd - The resolved working directory it will run in.
|
|
1419
|
-
* @returns The flags, the derived config and the sentence, or null when nothing is put back.
|
|
1420
|
-
*/
|
|
1320
|
+
/** The supplied suite's own budget, when the Playwright config a command would load sets different settings, asked BEFORE the run executes. */
|
|
1421
1321
|
suiteBudget?: (command: string, cwd: string) => Promise<SuiteBudgetPin | null | undefined>
|
|
1422
1322
|
|
|
1423
|
-
/**
|
|
1424
|
-
|
|
1425
|
-
|
|
1323
|
+
/** A whole walk's duration in ms, as the consumer measured it. */
|
|
1324
|
+
suiteRunMs?: (command: string, cwd: string) => Promise<number | null | undefined>
|
|
1325
|
+
|
|
1326
|
+
/** Post-write hook (e.g. auto-format via Prettier/ESLint). */
|
|
1327
|
+
onAfterWrite?: (path: string) => Promise<void>
|
|
1328
|
+
|
|
1329
|
+
/** Diff tracking callback. */
|
|
1330
|
+
onFileDiff?: (event: FileDiffEvent) => void
|
|
1331
|
+
|
|
1332
|
+
/** Structural change callback. */
|
|
1333
|
+
onFileChange?: (event: FileChangeEvent) => void
|
|
1334
|
+
}
|
|
1426
1335
|
```
|
|
1427
1336
|
|
|
1337
|
+
_(Member comments are shortened to their first sentence to fit; the full declaration is in `node_modules/@molecule/api-ai-tools/dist/types.d.ts`.)_
|
|
1338
|
+
|
|
1428
1339
|
#### `FileDiffEvent`
|
|
1429
1340
|
|
|
1430
1341
|
Payload emitted when a tracked file changes contents.
|
|
@@ -2936,8 +2847,24 @@ deployed URL, where a network blip is likeliest and the retries it dropped are t
|
|
|
2936
2847
|
absorb it).
|
|
2937
2848
|
|
|
2938
2849
|
`--max-failures=0` is Playwright's own "no cap" ({@link boundsFailures}), so it is not a
|
|
2939
|
-
|
|
2940
|
-
|
|
2850
|
+
diagnosis. A command that starts no Playwright run is not one either (false): the question is
|
|
2851
|
+
about a run already read as a Playwright suite.
|
|
2852
|
+
|
|
2853
|
+
A `--grep-invert` is only a narrowing when it excludes MORE than the request already excludes.
|
|
2854
|
+
When the caller passes those approved titles ({@link DiagnosisRunContext}) and the inverted
|
|
2855
|
+
pattern names one of them — the request's own "except …" scope written as the flag, which
|
|
2856
|
+
molecule-dev's `invertDecision` reads the same way — the run still walks the whole proof scope,
|
|
2857
|
+
and it is not a diagnosis. The deployed proof carried exactly
|
|
2858
|
+
that exclusion, the rewriter added `--retries=0` to it, and the run lost the suite's retries on
|
|
2859
|
+
the one walk where a network blip is likeliest.
|
|
2860
|
+
|
|
2861
|
+
A command the PLATFORM composed and launched AS the graded proof keeps the suite's retries for
|
|
2862
|
+
the SELECTION it composed — the failures a redeploy re-runs, named as files and `file:line`
|
|
2863
|
+
({@link DiagnosisRunContext} `platformProof`). Only that selection is excused: a cap, a title
|
|
2864
|
+
filter, a last-failed set and a local targeted selection stay diagnoses, so the mark cannot turn a walk of
|
|
2865
|
+
part of the suite into the graded measurement. Which targets are local is
|
|
2866
|
+
{@link suiteCommandTarget}'s answer, and the launch rewrite asks it on the same reading
|
|
2867
|
+
({@link ./utilities.js} `streamingBackgroundCommand`).
|
|
2941
2868
|
|
|
2942
2869
|
```typescript
|
|
2943
2870
|
function isDiagnosisRun(command: string, context?: DiagnosisRunContext): boolean
|
|
@@ -3128,7 +3055,11 @@ A path INSIDE the link is still decided by what resolves there: a link into a
|
|
|
3128
3055
|
real tree is refused, because removing or writing through it reaches the
|
|
3129
3056
|
install.
|
|
3130
3057
|
|
|
3131
|
-
|
|
3058
|
+
The restore route is named because the model that has ALREADY clobbered a file
|
|
3059
|
+
(this refusal is too late for it) is the one who needs it, and because the
|
|
3060
|
+
obvious repair — `npm install <pkg>` — is itself refused in the pre-installed
|
|
3061
|
+
sandbox. `npm pack` + a `tar` extraction over the package directory is the
|
|
3062
|
+
repair both guards leave alone.
|
|
3132
3063
|
|
|
3133
3064
|
```typescript
|
|
3134
3065
|
function installedPackageWriteRefusal(
|
|
@@ -3176,8 +3107,15 @@ or still in flight when the test ended; it is kept too, but as what it is, not a
|
|
|
3176
3107
|
A trace.zip holds ONE trace member per browser context the test used (beside the runner's own
|
|
3177
3108
|
`test.trace`), and the archive's member order is not the test's chronology. Each member is read
|
|
3178
3109
|
as its own context: actions and requests keep their context id, requests and frame snapshots
|
|
3110
|
+
keep the pageId Playwright records, and the failing assertion's page — the page its own step id
|
|
3111
|
+
ran on — decides which actions, snapshots and requests become the test's row. What the test's
|
|
3112
|
+
other browser contexts recorded is reported apart, as `otherContexts`.
|
|
3179
3113
|
|
|
3180
|
-
|
|
3114
|
+
A request answered 4xx by the app's OWN API also keeps what the page SENT and the first of what
|
|
3115
|
+
came back: Playwright stores either inline (`text`) or in a resource entry (`_file`), and both
|
|
3116
|
+
are read. That is where a wrapped body shows: a helper passed
|
|
3117
|
+
`{ data: body }` as app-http's second argument, so every POST/PUT was `{"data":{…}}` and the API
|
|
3118
|
+
validated `{}`. Status alone said only "422".
|
|
3181
3119
|
|
|
3182
3120
|
```typescript
|
|
3183
3121
|
function traceArtifactsScript(): string
|
|
@@ -3362,6 +3300,38 @@ is `data`, the note names the call shape that produces it.
|
|
|
3362
3300
|
Every row opens with the test's LAST user action before the failing assertion and the requests
|
|
3363
3301
|
that action caused ({@link TraceArtifact.lastAction}) — started after it, before the assertion,
|
|
3364
3302
|
the app's own API calls first, each with its status and the first 200 characters of its response,
|
|
3303
|
+
then where the page went next. The trace's action clock and each request's `_monotonicTime` are
|
|
3304
|
+
the same clock, so "caused" is the trace's own fact rather than a guess from recording order.
|
|
3305
|
+
A run failed 13 then 12 tests on one unnamed cause while every row led with
|
|
3306
|
+
`GET /api/tags → 200` — the Home page's own fetch after the redirect — and filled its answered
|
|
3307
|
+
slots with the PWA's `/workbox-*.js` and its `/icons/*.svg`; the register `POST /api/users`
|
|
3308
|
+
(answered 201, the page still rendering signed-out) never appeared. With no action clock, the
|
|
3309
|
+
row falls back to {@link TraceArtifact.lead}: the page's last answered fetch/xhr.
|
|
3310
|
+
|
|
3311
|
+
The action, the URL and the requests are the FAILING ASSERTION'S PAGE's ({@link
|
|
3312
|
+
TraceArtifact.lastAction}), never the archive's last context: a test that creates its data in a
|
|
3313
|
+
second browser context writes that context's click and `/editor` snapshot into the same zip, and
|
|
3314
|
+
reading the concatenation made them the failing page. The other
|
|
3315
|
+
contexts' requests are named separately as set-up work. When the trace holds more than one used
|
|
3316
|
+
context and the assertion's page cannot be identified, the note lists the requests and makes NO
|
|
3317
|
+
causal claim — no "the test's last action", no "the page stayed at …" — instead of merging them.
|
|
3318
|
+
|
|
3319
|
+
A field the test filled and the page submitted EMPTY ({@link formResetOf}) leads the note: the
|
|
3320
|
+
trace holds both facts — the value typed into `textarea[name="bio"]` and the `PUT /api/user`
|
|
3321
|
+
whose body carried `"bio": ""` — so the form's state was reset between the typing and the
|
|
3322
|
+
submit. The note names the effect that re-seeds a form from data whose identity changed and the
|
|
3323
|
+
fix at the source (seed the form once). A deploy-and-walk cycle is lost to this on the
|
|
3324
|
+
deployed URL only, where the background session verification lands later than it does locally.
|
|
3325
|
+
|
|
3326
|
+
A write whose response said a boolean field is true and a LATER GET of the same resource that
|
|
3327
|
+
said it is false leads the note first ({@link readContradictionSentence}): the read route never
|
|
3328
|
+
saw the viewer, so the fix is on that route's middleware, not in the page. Rewriting the
|
|
3329
|
+
profile component over exactly that pair costs ~8 minutes — the write answered
|
|
3330
|
+
`{"following":true}` and the next profile GET answered `false`.
|
|
3331
|
+
|
|
3332
|
+
WHICH rows it spends is evidence, not artifact order: a row
|
|
3333
|
+
needs a recorded response, a real failure or a console line ({@link traceRowEvidence}), rows are
|
|
3334
|
+
deduplicated by the test's location, and they are ordered real failure → repeated from an
|
|
3365
3335
|
|
|
3366
3336
|
_(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/trace-artifacts.d.ts`.)_
|
|
3367
3337
|
|
|
@@ -3437,8 +3407,22 @@ between passing and timing out. This flag was added for exactly that failure: it
|
|
|
3437
3407
|
deployed proof run left only an `error-context.md` because the suite traces
|
|
3438
3408
|
`on-first-retry` and the run had no retries. That need is met without the flag — the graded
|
|
3439
3409
|
deployed run keeps the suite's own retries, so a failing test leaves its retry's trace — and
|
|
3410
|
+
the platform's re-run note carries `--trace=on` for a run that did leave none.
|
|
3440
3411
|
|
|
3441
|
-
|
|
3412
|
+
Which runs are proof-capable is {@link suiteCommandTarget}'s answer: a run against a deployed
|
|
3413
|
+
URL. A LOCAL run is never left to its config, because the launcher gives every local run
|
|
3414
|
+
`--retries=0` (`@molecule/api-ai-tools` `streamingBackgroundCommand`), so its retry trace would
|
|
3415
|
+
never happen. A run that pins `--retries=0` itself is in the same position, whatever its target.
|
|
3416
|
+
|
|
3417
|
+
A proof-capable run is left alone WHATEVER its config traces. `--trace` is a per-run override of
|
|
3418
|
+
the suite's own `use.trace` (Playwright merges the CLI's `use` into every project's), and a test
|
|
3419
|
+
record carries the project settings it ran under: a run with the flag is not the suite's own
|
|
3420
|
+
measurement, so it can never count as deployed proof. Added to a deployed walk, the flag made the
|
|
3421
|
+
walk unprovable, and the platform's own answer — "run the current selection" — was a command this
|
|
3422
|
+
same rewrite then flagged again: X1 P140–P173 had 22 deployed walks the executor started, and
|
|
3423
|
+
not one moved the native proof counts (xr-molecule-flash-l1255 walked 73/73 green twice, at
|
|
3424
|
+
+18.2 and +22.9, and neither counted). A failure in a suite that keeps no trace at all is still
|
|
3425
|
+
readable: the platform's re-run note carries `--trace=on` for a run that left none.
|
|
3442
3426
|
|
|
3443
3427
|
```typescript
|
|
3444
3428
|
function diagnosisTraceCommand(args: {
|
|
@@ -3684,8 +3668,38 @@ killed (one run lost 20 of its 60 minutes this way):
|
|
|
3684
3668
|
machine `json` report stays on the last invocation.
|
|
3685
3669
|
|
|
3686
3670
|
The run ends up with exactly ONE reporter that prints each failure — `list`. A run that names
|
|
3687
|
-
|
|
3688
|
-
|
|
3671
|
+
any other printing reporter has it REPLACED, never joined: two of them write every test result
|
|
3672
|
+
into the log twice, which made a `--reporter=list,line` run (its
|
|
3673
|
+
`line` added by this function one run earlier) report two distinct failures as "4 of this run's
|
|
3674
|
+
tests have already failed the same way", and the executor stopped a 139-test walk at test 21
|
|
3675
|
+
with a single cause in hand. `line` alone is no use either: it writes `[n/N] <title>` with no
|
|
3676
|
+
✓/✘ mark and no duration, so an 8.3-minute walk of one suite could never trip
|
|
3677
|
+
the fail-fast note. A reporter set that writes a machine format to a file (`json`, `html`,
|
|
3678
|
+
`junit`) is the
|
|
3679
|
+
executor's own and is left exactly as it is — so is any reporter this build does not know.
|
|
3680
|
+
|
|
3681
|
+
Every background command that is not a no-test invocation is also given
|
|
3682
|
+
{@link PLAYWRIGHT_FAILURES_INLINE_ENV} (inert except for Playwright's `list` reporter), so each
|
|
3683
|
+
failure's own error is in the log as that test fails rather than only at the end: a suite that is
|
|
3684
|
+
still walking is exactly when the executor reads the log, and without it a running log carries
|
|
3685
|
+
`✘` rows and nothing else (~90 s went to greps of one, then to fixing what was
|
|
3686
|
+
guessed; a wrapper-launched run lost 6.5 minutes to the same shape).
|
|
3687
|
+
|
|
3688
|
+
Only the step that runs the suite is touched, and only its reporter, and only when that step
|
|
3689
|
+
runs something: `npx playwright test --list` takes two seconds and writes nothing per test, so
|
|
3690
|
+
neither reporter nor `--retries=0` is added to it ({@link isPlaywrightRunCommand}). A trailing
|
|
3691
|
+
status step (`; echo EXIT $?`, `&& true`) is not the run and is skipped when the run step is
|
|
3692
|
+
found ({@link isStatusOnlyStep}); a run whose output is redirected to a file is still readable
|
|
3693
|
+
through that file, which the launch records as the task's own output.
|
|
3694
|
+
|
|
3695
|
+
A command that starts the suite MORE THAN ONCE is not launched at all: every run it carries is
|
|
3696
|
+
a whole walk of the same suite against the same app, and only the last step is rewritten, so the
|
|
3697
|
+
earlier walks run unmeasured for nothing. Two whole walks of one 138-test suite chained with
|
|
3698
|
+
`;` — 4.5 minutes each — measured nothing the first had not. The platform refuses a second CONCURRENT run against one app and database by the
|
|
3699
|
+
ONE rule ({@link suiteRunInTheWay}) — for every pair, whatever uid a run mints — and this is the
|
|
3700
|
+
same hazard inside one command ({@link suiteRunStatements}). `error` then carries the refusal,
|
|
3701
|
+
naming each suite step and the ONE command to send instead (the last suite step, rewritten as
|
|
3702
|
+
this function rewrites a run), and nothing is launched.
|
|
3689
3703
|
|
|
3690
3704
|
```typescript
|
|
3691
3705
|
function streamingBackgroundCommand(
|
|
@@ -4167,8 +4181,13 @@ is a directory rather than a directory name.
|
|
|
4167
4181
|
|
|
4168
4182
|
An npm SCOPE as the first segment, under a `node_modules` root, is the one
|
|
4169
4183
|
exception that parameter `root` enables: npm installs a scope only directly
|
|
4170
|
-
|
|
4171
|
-
|
|
4184
|
+
inside a `node_modules` directory, and the walk already prunes every nested
|
|
4185
|
+
`node_modules` (see `findPruneArgs`), so the whole-tree form can only ever
|
|
4186
|
+
match `<root>/@molecule/…` — the scope directory IS the directory the pattern
|
|
4187
|
+
names. Left un-narrowed, a scoped-package pattern walked the sandbox's entire
|
|
4188
|
+
dependency tree and hit the 10 s deadline with no result at all. A bare NAME stays a
|
|
4189
|
+
directory name at any depth:
|
|
4190
|
+
`helpers/*` is unchanged even under a `node_modules` root.
|
|
4172
4191
|
|
|
4173
4192
|
```typescript
|
|
4174
4193
|
function literalDirPrefix(pattern: string, root?: string): string | null
|
|
@@ -4507,8 +4526,7 @@ each was the test timeout and one missing `navigate('/')` was the cause of all o
|
|
|
4507
4526
|
The quorum is of DISTINCT tests — {@link REPEATING_FAILURE_MIN} of them — because a log that
|
|
4508
4527
|
prints each failure twice (a second reporter, a retry) has told a run that four of its
|
|
4509
4528
|
tests failed the same way when two had, so the executor stopped a 139-test walk at test 21
|
|
4510
|
-
|
|
4511
|
-
_(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/utilities.d.ts`.)_
|
|
4529
|
+
with one cause in hand.
|
|
4512
4530
|
|
|
4513
4531
|
```typescript
|
|
4514
4532
|
function repeatingFailure(log: string): RepeatingFailure | null
|
|
@@ -4641,7 +4659,11 @@ Both halves are load-bearing, each of them learned from a run that lost minutes
|
|
|
4641
4659
|
— read the early return as "stop waiting, edit now", and voided a run that was still walking;
|
|
4642
4660
|
the second cost a 224 s wait that ended with no result at all.
|
|
4643
4661
|
|
|
4644
|
-
|
|
4662
|
+
Neither half alone is enough, and {@link repeatingFailure} finding a signature is not either:
|
|
4663
|
+
that answers "is a cause repeating among this run's failures", which is worth telling the
|
|
4664
|
+
executor mid-run as a NOTE while the wait goes on. This answers the narrower question the wait
|
|
4665
|
+
needs — is the run over as a measuring instrument — and it is THE one predicate behind both
|
|
4666
|
+
that decision and the note's wording, so the two cannot come to different verdicts.
|
|
4645
4667
|
|
|
4646
4668
|
```typescript
|
|
4647
4669
|
function earlyReturnCause(
|
|
@@ -4854,9 +4876,12 @@ for — never as a verdict with a stop command in it.
|
|
|
4854
4876
|
The run is STILL WALKING while this note is written — both callers produce it mid-run — so a
|
|
4855
4877
|
re-run of one of its tests is a second run against the same app and database, and the platform
|
|
4856
4878
|
refuses that ({@link suiteRunInTheWay}, the same rule its overlap hold answers with):
|
|
4857
|
-
an executor read
|
|
4858
|
-
|
|
4859
|
-
_
|
|
4879
|
+
an executor read _"Start on them now, while the run keeps walking.
|
|
4880
|
+
`null-fields.spec.ts:53` alone reproduces the first one."_ and sent exactly that re-run 23 s
|
|
4881
|
+
later, where the hold answered _"A playwright suite is already running against this app and
|
|
4882
|
+
database … Wait for it."_ The note therefore hands over the read-and-fix to do NOW and the
|
|
4883
|
+
re-run for after the run ends — the exact command where the caller knows how the run was
|
|
4884
|
+
started ({@link rerunOfRunningSuite}), the timing alone where it does not.
|
|
4860
4885
|
|
|
4861
4886
|
```typescript
|
|
4862
4887
|
function repeatingFailureNote(
|