@molecule/api-ai-tools 1.5.18 → 1.5.20
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 +320 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/no-test-run.d.ts +45 -0
- package/dist/no-test-run.d.ts.map +1 -0
- package/dist/no-test-run.js +125 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +5 -3
- package/dist/system-prompt.js +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +155 -7
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utilities.d.ts +207 -1
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js +513 -15
- package/package.json +2 -2
package/dist/tools.js
CHANGED
|
@@ -32,6 +32,58 @@ const outputFileByTask = new Map();
|
|
|
32
32
|
* would re-read the task's script on every single wait.
|
|
33
33
|
*/
|
|
34
34
|
const outputFileProbed = new Set();
|
|
35
|
+
/**
|
|
36
|
+
* How often a wait looks at a running task's log for a cause repeating among its failures.
|
|
37
|
+
* Env-tunable so a test can exercise it.
|
|
38
|
+
*/
|
|
39
|
+
const repeatingCauseLookMs = () => Number(process.env.MOL_AI_BG_CAUSE_LOOK_MS) || 10_000;
|
|
40
|
+
/**
|
|
41
|
+
* Task ids a wait has already named a repeating cause for. The note is news once; a second wait
|
|
42
|
+
* on the same run has nothing to add to it, and re-sending it would spend the executor's turns
|
|
43
|
+
* telling it what it has already been told.
|
|
44
|
+
*/
|
|
45
|
+
const repeatingCauseNoted = new Set();
|
|
46
|
+
/**
|
|
47
|
+
* The shell command that stops a background task by pid: the pid the platform wrote when it
|
|
48
|
+
* detached the run, plus every process under it.
|
|
49
|
+
*
|
|
50
|
+
* Both halves matter and neither is a pattern. Killing only the pid file's entry can leave the
|
|
51
|
+
* runner (`sh -c` wraps the command here) orphaned and still driving the app, and a
|
|
52
|
+
* `pkill -f <something>` is the shape that matches the shell running the kill itself — the
|
|
53
|
+
* platform holds that command once with the processes it would hit named
|
|
54
|
+
* (`molecule-dev/api/src/ai/pattern-kill-guard.ts`). `pgrep -P` walks to a real pid list, which
|
|
55
|
+
* is what the guard's own note sends the executor to.
|
|
56
|
+
*
|
|
57
|
+
* @param taskId - The task's `mol-bg-…` handle (format already checked by the caller).
|
|
58
|
+
* @returns The pids, space-separated, or '' when the pid file is gone.
|
|
59
|
+
*/
|
|
60
|
+
const taskPidsCommand = (taskId) => `R=$(cat /tmp/${taskId}.pid 2>/dev/null); ` +
|
|
61
|
+
'all() { echo "$1"; for c in $(pgrep -P "$1" 2>/dev/null); do all "$c"; done; }; ' +
|
|
62
|
+
'all "$R" | tr "\\n" " "';
|
|
63
|
+
/**
|
|
64
|
+
* The command that stops a running background task, read from the sandbox's own pid files.
|
|
65
|
+
*
|
|
66
|
+
* @param backend - The execution backend.
|
|
67
|
+
* @param taskId - The task's `mol-bg-…` handle.
|
|
68
|
+
* @returns The command to hand the executor — `kill <pids>` — falling back to the task's own pid
|
|
69
|
+
* file when the walk comes back empty (a sandbox without `pgrep`, or a pid file already gone,
|
|
70
|
+
* in which case the pid-file form is still the one the platform's guard names).
|
|
71
|
+
*/
|
|
72
|
+
async function taskStopCommand(backend, taskId) {
|
|
73
|
+
const fallback = `kill $(cat /tmp/${taskId}.pid)`;
|
|
74
|
+
try {
|
|
75
|
+
const r = await backend.run(taskPidsCommand(taskId), { timeout: 10_000 });
|
|
76
|
+
const pids = String(r.stdout ?? '')
|
|
77
|
+
.split(/\s+/)
|
|
78
|
+
.filter((p) => /^\d+$/.test(p));
|
|
79
|
+
return pids.length ? `kill ${pids.join(' ')}` : fallback;
|
|
80
|
+
}
|
|
81
|
+
catch (_error) {
|
|
82
|
+
// The sandbox would not answer the pid walk. The pid-file form below is what the platform
|
|
83
|
+
// tells the executor to use anyway, so there is nothing to report and nothing to lose.
|
|
84
|
+
return fallback;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
35
87
|
/** A millisecond span the way a model reads it: seconds under 90, else minutes. */
|
|
36
88
|
function durationText(ms) {
|
|
37
89
|
const s = Math.max(0, Math.round(ms / 1000));
|
|
@@ -109,7 +161,7 @@ function waitProgressNote(o) {
|
|
|
109
161
|
const sentence = parts.join('; ');
|
|
110
162
|
return ` ${sentence[0].toUpperCase()}${sentence.slice(1)}.`;
|
|
111
163
|
}
|
|
112
|
-
import { checkBlockedCommand, declaredBudgetSeconds, DEFAULT_SEARCH_EXCLUDED_DIRS, directoryReadHint, fusedLine, isEnvFilePath, isOutsideRoot, isValidGlob, MAX_BATCH_READ_BYTES, MAX_BATCH_READ_FILES, MAX_FIND_RESULTS, MAX_OUTPUT_SIZE, MAX_READ_RETURN_CHARS, MAX_READ_SIZE, MAX_SEARCH_CONTEXT_LINES, MAX_SEARCH_RESULTS, MAX_WRITE_SIZE, outputIsWithheldUntilExit, outputRedirectTarget, parseCheckCommand, parseCheckProblem, pathArgError, printsOnlySource, redactSecrets, redactSecretsInCode, resolvePath, RUNNING_FAILURE_LINES, runningOutputSliceCommand, shellQuote, sliceLines, SMALL_FILE_WHOLE_CHARS, streamingBackgroundCommand, stripControlChars, truncateMiddle, whitespaceTolerantReplace, } from './utilities.js';
|
|
164
|
+
import { checkBlockedCommand, declaredBudgetSeconds, DEFAULT_SEARCH_EXCLUDED_DIRS, directoryReadHint, findPatternArgs, fusedLine, htmlOutline, isEnvFilePath, isOutsideRoot, isPlaywrightRunCommand, isValidGlob, MAX_BATCH_READ_BYTES, MAX_BATCH_READ_FILES, MAX_FIND_RESULTS, MAX_HTML_INLINE_CHARS, MAX_OUTPUT_SIZE, MAX_READ_RETURN_CHARS, MAX_READ_SIZE, MAX_SEARCH_CONTEXT_LINES, MAX_SEARCH_RESULTS, MAX_WRITE_SIZE, outputIsWithheldUntilExit, outputRedirectTarget, parseCheckCommand, parseCheckProblem, pathArgError, printsOnlySource, redactSecrets, redactSecretsInCode, repeatingFailure, repeatingFailureNote, resolvePath, RUNNING_FAILURE_LINES, runningCauseCommand, runningOutputSliceCommand, shellQuote, sliceLines, SMALL_FILE_WHOLE_CHARS, streamingBackgroundCommand, stripControlChars, suiteRunPriorityLaunch, truncateMiddle, whitespaceTolerantReplace, } from './utilities.js';
|
|
113
165
|
/**
|
|
114
166
|
* How long exec_command waits for a command it backgrounded only because the
|
|
115
167
|
* command asked for more than the tool's ceiling, before handing back a task id.
|
|
@@ -145,7 +197,7 @@ export function moleculeDistReadNote(path) {
|
|
|
145
197
|
* @returns Array of AITool objects ready to pass to an AI provider
|
|
146
198
|
*/
|
|
147
199
|
export function buildTools(backend, config) {
|
|
148
|
-
const { include, exclude, pathGuards = true, symlinkGuards = false, redactSecrets: doRedact = true, blockDangerousCommands = false, blockCommand, execTimeoutMs = 120_000, commandBudgetMs, overCeilingGraceMs = OVER_CEILING_GRACE_MS, searchExcludedDirs, onAfterWrite, onFileDiff, onFileChange, } = config ?? {};
|
|
200
|
+
const { include, exclude, pathGuards = true, symlinkGuards = false, redactSecrets: doRedact = true, blockDangerousCommands = false, blockCommand, execTimeoutMs = 120_000, commandBudgetMs, overCeilingGraceMs = OVER_CEILING_GRACE_MS, searchExcludedDirs, outlineLargeHtml, onAfterWrite, onFileDiff, onFileChange, } = config ?? {};
|
|
149
201
|
const root = backend.projectRoot;
|
|
150
202
|
// A host-filesystem backend with escape guards off is the combination the
|
|
151
203
|
// audit flagged: `pathGuards` off lets `..` paths out of the workspace,
|
|
@@ -499,6 +551,41 @@ export function buildTools(backend, config) {
|
|
|
499
551
|
return {
|
|
500
552
|
error: `File too large (${Math.round(content.length / 1024)}KB). Maximum is ${MAX_READ_SIZE / 1024 / 1024}MB.`,
|
|
501
553
|
};
|
|
554
|
+
// A LARGE HTML document comes back as its OUTLINE, not its text, when the
|
|
555
|
+
// host asks for that (a plan-mode turn: see `outlineLargeHtml`). X0
|
|
556
|
+
// flash-m77 paid 63,735 chars for one `read_file` of `app/index.html` —
|
|
557
|
+
// ~60 KB of it the IDE's own preview bridges — and that read alone took the
|
|
558
|
+
// transcript past its context cap, so the e2e specs it had just read were
|
|
559
|
+
// trimmed to summaries and it read the whole suite again, twice (+01:23,
|
|
560
|
+
// +02:56). An outline is not a truncation: the note names the exact
|
|
561
|
+
// offset/limit that returns the whole document, and any line range works.
|
|
562
|
+
if (!sliceLines(content, window) &&
|
|
563
|
+
content.length > MAX_HTML_INLINE_CHARS &&
|
|
564
|
+
outlineLargeHtml?.()) {
|
|
565
|
+
const outline = htmlOutline(content, path);
|
|
566
|
+
if (outline) {
|
|
567
|
+
const totalLines = content.split('\n').length;
|
|
568
|
+
return noted({
|
|
569
|
+
path,
|
|
570
|
+
// Same redaction every other read goes through: an outline is made of
|
|
571
|
+
// the document's own lines, and a meta tag can carry a key.
|
|
572
|
+
content: sanitizeFileContent(outline, path),
|
|
573
|
+
outline: true,
|
|
574
|
+
bytes: content.length,
|
|
575
|
+
totalLines,
|
|
576
|
+
note: `Outlined, not returned whole: a ${Math.round(content.length / 1024)} KB HTML document is ` +
|
|
577
|
+
`its tags plus a lot of plumbing, and the tags are what matter. ` +
|
|
578
|
+
`The whole file is ONE call — read_file {path, offset: 1, limit: ${totalLines}} — ` +
|
|
579
|
+
`and any line range works the same way.` +
|
|
580
|
+
// The IDE's own preview scripts are in this document but are not the
|
|
581
|
+
// app's behaviour, and an executor that reads them pays 60 KB for
|
|
582
|
+
// something it must never edit (flash-m77). Named only when present.
|
|
583
|
+
(/<!--\s*mol:[a-z0-9-]+-(?:bridge|shim)/.test(content)
|
|
584
|
+
? ' The `mol:*-bridge` scripts the IDE injects belong to the platform, not to the app: leave them as they are.'
|
|
585
|
+
: ''),
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
502
589
|
// No window asked for and the file is bigger than one call should hand
|
|
503
590
|
// back: return its first window, sized to the ceiling, and say so. The
|
|
504
591
|
// model can read on with offset/limit; it cannot un-send 300k tokens.
|
|
@@ -1162,9 +1249,18 @@ export function buildTools(backend, config) {
|
|
|
1162
1249
|
if (symlinkErr)
|
|
1163
1250
|
return { error: symlinkErr };
|
|
1164
1251
|
try {
|
|
1165
|
-
|
|
1252
|
+
// `findPatternArgs`, not `-name`: a pattern with a `/` in it
|
|
1253
|
+
// (`helpers/*`, `e2e/*.spec.ts`) matched nothing at all, because `-name`
|
|
1254
|
+
// compares it against the basename (xr-molecule-flash-m77).
|
|
1255
|
+
const result = await backend.run(`find ${shellQuote(path)} ${findPruneArgs(path)} ${findPatternArgs(pattern)} -print 2>/dev/null | head -${MAX_FIND_RESULTS}`, { timeout: 10000 });
|
|
1166
1256
|
const files = result.stdout.trim().split('\n').filter(Boolean);
|
|
1167
|
-
|
|
1257
|
+
// A slash changes what the pattern means — the whole path, not the file
|
|
1258
|
+
// name — and an empty result does not say so, so the model reads it as
|
|
1259
|
+
// "no such file" and goes looking elsewhere. Name the rule on the miss.
|
|
1260
|
+
const note = files.length === 0 && pattern.includes('/')
|
|
1261
|
+
? `"${pattern}" contains a "/", so it was matched against each file's PATH below ${path} (a leading "*/" is implicit), not against the file name — no path matched it. list_files shows the real entries.`
|
|
1262
|
+
: undefined;
|
|
1263
|
+
return { pattern, path, files, ...(note ? { note } : {}) };
|
|
1168
1264
|
}
|
|
1169
1265
|
catch (e) {
|
|
1170
1266
|
return { error: `Find failed: ${e.message}` };
|
|
@@ -1275,12 +1371,15 @@ export function buildTools(backend, config) {
|
|
|
1275
1371
|
// declaring a budget too: a suite routinely outlasts the ceiling, and killed there
|
|
1276
1372
|
// behind `| tail` it returns nothing (X1 flash-m29 lost a 290 s run that way).
|
|
1277
1373
|
// A short one still comes back as a foreground result, through the grace below.
|
|
1374
|
+
// A Playwright command that runs no test is not one of these either: `playwright test
|
|
1375
|
+
// --list` piped through `tail` takes two seconds, and backgrounding it costs the round
|
|
1376
|
+
// trip `wait_for_task` owes the executor (flash-m79's config check).
|
|
1278
1377
|
const overCeiling = commandBudgetMs !== undefined &&
|
|
1279
1378
|
((outputIsWithheldUntilExit(command) &&
|
|
1280
|
-
(declaredSeconds > ceilingSeconds ||
|
|
1379
|
+
(declaredSeconds > ceilingSeconds || isPlaywrightRunCommand(command))) ||
|
|
1281
1380
|
// A redirected Playwright run shows nothing either (`> out.txt`), and was killed at
|
|
1282
1381
|
// the ceiling with 38 tests unrun (X1 flash-m36).
|
|
1283
|
-
(
|
|
1382
|
+
(isPlaywrightRunCommand(command) && outputRedirectTarget(command) !== null));
|
|
1284
1383
|
if (input.run_in_background === true || overCeiling) {
|
|
1285
1384
|
const id = `mol-bg-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1286
1385
|
const log = `/tmp/${id}.log`;
|
|
@@ -1294,6 +1393,11 @@ export function buildTools(backend, config) {
|
|
|
1294
1393
|
// Keep the log growing while it runs (see streamingBackgroundCommand):
|
|
1295
1394
|
// an empty log is what wait_for_task reads as stuck.
|
|
1296
1395
|
const streaming = streamingBackgroundCommand(command);
|
|
1396
|
+
// A whole-suite run starves the sandbox it shares with the app and with
|
|
1397
|
+
// every command the executor sends next, so it starts at lower CPU and
|
|
1398
|
+
// IO priority (see suiteRunPriorityLaunch). Foreground runs are never
|
|
1399
|
+
// touched, and a sandbox without the tools runs it unchanged.
|
|
1400
|
+
const prioritized = suiteRunPriorityLaunch(streaming.command, `sh ${script} > ${log} 2>&1; echo $? > ${exitFile}`);
|
|
1297
1401
|
const ownTarget = outputRedirectTarget(streaming.command);
|
|
1298
1402
|
const ownFile = ownTarget
|
|
1299
1403
|
? ownTarget.startsWith('/')
|
|
@@ -1303,7 +1407,7 @@ export function buildTools(backend, config) {
|
|
|
1303
1407
|
if (ownFile)
|
|
1304
1408
|
outputFileByTask.set(id, ownFile);
|
|
1305
1409
|
await backend.writeFile(script, `${streaming.command}\n`);
|
|
1306
|
-
await backend.run(`nohup sh -c ${shellQuote(
|
|
1410
|
+
await backend.run(`nohup sh -c ${shellQuote(prioritized.launch)} ` +
|
|
1307
1411
|
`> /dev/null 2>&1 & echo $! > /tmp/${id}.pid`, { cwd, timeout: 15_000 });
|
|
1308
1412
|
// A command backgrounded only for the budget it ASKED for often ends in
|
|
1309
1413
|
// seconds (a Hurl suite: 37 ms). Handing it back as a task cost a
|
|
@@ -1360,6 +1464,7 @@ export function buildTools(backend, config) {
|
|
|
1360
1464
|
`check back. If you need this result before you can continue, call wait_for_task ` +
|
|
1361
1465
|
`with this taskId — never sleep and read the log by hand.` +
|
|
1362
1466
|
(streaming.changes.length ? ` ${streaming.changes.join(' ')}` : '') +
|
|
1467
|
+
(prioritized.note ? ` ${prioritized.note}` : '') +
|
|
1363
1468
|
(ownFile
|
|
1364
1469
|
? ` This command writes its own output to ${ownFile}, so the task log stays empty: peek with exec_command: tail ${ownFile}.`
|
|
1365
1470
|
: ''),
|
|
@@ -1588,10 +1693,53 @@ export function buildTools(backend, config) {
|
|
|
1588
1693
|
return null;
|
|
1589
1694
|
}
|
|
1590
1695
|
};
|
|
1696
|
+
// A running SUITE whose failures repeat one cause is named at the third of them. The run
|
|
1697
|
+
// would otherwise spend its whole clock proving that cause, and the executor only learns it
|
|
1698
|
+
// from the finished log: X1 flash-m76 waited out 4.0 minutes of 15 tests where every
|
|
1699
|
+
// failure was the same `TimeoutError: page.waitForURL` from one missing `navigate('/')`,
|
|
1700
|
+
// and then fixed it in 51 s. The task is NOT stopped — the executor is handed the cause and
|
|
1701
|
+
// its own pid command and decides.
|
|
1702
|
+
let lastCauseLookAt = startedAt - repeatingCauseLookMs();
|
|
1591
1703
|
let exitCode = await readExit();
|
|
1592
1704
|
while (exitCode === null && Date.now() - startedAt < budgetMs) {
|
|
1593
1705
|
await new Promise((r) => setTimeout(r, Math.min(2_000, budgetMs - (Date.now() - startedAt))));
|
|
1594
1706
|
exitCode = await readExit();
|
|
1707
|
+
// The exit file is read first, so a run that finishes between two looks still returns
|
|
1708
|
+
// its real result instead of a note about it.
|
|
1709
|
+
if (exitCode !== null)
|
|
1710
|
+
break;
|
|
1711
|
+
if (repeatingCauseNoted.has(taskId))
|
|
1712
|
+
continue;
|
|
1713
|
+
if (Date.now() - lastCauseLookAt < repeatingCauseLookMs())
|
|
1714
|
+
continue;
|
|
1715
|
+
lastCauseLookAt = Date.now();
|
|
1716
|
+
let causeLog;
|
|
1717
|
+
try {
|
|
1718
|
+
const r = await backend.run(runningCauseCommand(log, outputFileByTask.get(taskId)), {
|
|
1719
|
+
timeout: 10_000,
|
|
1720
|
+
});
|
|
1721
|
+
causeLog = r.stdout ?? '';
|
|
1722
|
+
}
|
|
1723
|
+
catch (_error) {
|
|
1724
|
+
// No look at the log this tick; the next one asks again.
|
|
1725
|
+
continue;
|
|
1726
|
+
}
|
|
1727
|
+
const found = repeatingFailure(causeLog);
|
|
1728
|
+
if (!found)
|
|
1729
|
+
continue;
|
|
1730
|
+
repeatingCauseNoted.add(taskId);
|
|
1731
|
+
const earlyMs = Date.now() - startedAt;
|
|
1732
|
+
waitedByTask.set(taskId, waitedBefore + earlyMs);
|
|
1733
|
+
return {
|
|
1734
|
+
taskId,
|
|
1735
|
+
status: 'repeating_failure',
|
|
1736
|
+
waitedMs: earlyMs,
|
|
1737
|
+
note: repeatingFailureNote(found, {
|
|
1738
|
+
taskId,
|
|
1739
|
+
log,
|
|
1740
|
+
stop: await taskStopCommand(backend, taskId),
|
|
1741
|
+
}),
|
|
1742
|
+
};
|
|
1595
1743
|
}
|
|
1596
1744
|
const waitedMs = Date.now() - startedAt;
|
|
1597
1745
|
waitedByTask.set(taskId, waitedBefore + waitedMs);
|
package/dist/types.d.ts
CHANGED
|
@@ -112,6 +112,22 @@ export interface ToolBuildConfig {
|
|
|
112
112
|
* setting so every search surface shares ONE synchronized set.
|
|
113
113
|
*/
|
|
114
114
|
searchExcludedDirs?: string[];
|
|
115
|
+
/**
|
|
116
|
+
* Whether a LARGE HTML document should come back as its OUTLINE — the head's
|
|
117
|
+
* tags and the tags that open each body section, one line each, plus a note
|
|
118
|
+
* naming the offset/limit that returns the whole document — instead of its
|
|
119
|
+
* whole text. Over {@link MAX_HTML_INLINE_CHARS}, and only when the read named
|
|
120
|
+
* no line window.
|
|
121
|
+
*
|
|
122
|
+
* A getter, not a boolean, because the answer belongs to the TURN, not to the
|
|
123
|
+
* tool set: a host that plans first and builds after wants an outline while the
|
|
124
|
+
* executor is researching (where a read it cannot act on is pure context cost)
|
|
125
|
+
* and the document itself while it is writing the page. Unset means every big
|
|
126
|
+
* HTML read returns its text, which is what a host with no such phases wants.
|
|
127
|
+
*
|
|
128
|
+
* @returns True when a large HTML read should be outlined rather than returned.
|
|
129
|
+
*/
|
|
130
|
+
outlineLargeHtml?: () => boolean;
|
|
115
131
|
/** Post-write hook (e.g. auto-format via Prettier/ESLint). Called after every write_file/edit_file. */
|
|
116
132
|
onAfterWrite?: (path: string) => Promise<void>;
|
|
117
133
|
/** Diff tracking callback. Called before writes with old/new content. */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/utilities.d.ts
CHANGED
|
@@ -128,7 +128,17 @@ export declare function outputRedirectTarget(command: string): string | null;
|
|
|
128
128
|
* `[n/N] <title>` with no ✓/✘ mark and no duration, so on X1 flash-m62 an
|
|
129
129
|
* 8.3-minute walk of one suite could never trip the fail-fast note.
|
|
130
130
|
*
|
|
131
|
-
*
|
|
131
|
+
* A run being ITERATED on (capped, narrowed, or by file) gets `list,line` instead
|
|
132
|
+
* of `list` alone. `list` holds every failure's error for the summary at the end,
|
|
133
|
+
* so mid-run its log says only how long each failure took; `line` writes the body
|
|
134
|
+
* as the failure happens, and a look at a running suite (`wait_for_task`'s
|
|
135
|
+
* repeating-cause note, `suite-fail-fast.ts`) can then name the repeating cause by
|
|
136
|
+
* its error message. X1 flash-m76 walked 15 tests for 4.0 minutes, every one a
|
|
137
|
+
* `TimeoutError: page.waitForURL` from one missing `navigate('/')`.
|
|
138
|
+
*
|
|
139
|
+
* Only the command's last step is touched, and only its reporter, and only when that step runs
|
|
140
|
+
* something: `npx playwright test --list` takes two seconds and writes nothing per test, so
|
|
141
|
+
* neither reporter nor `--retries=0` is added to it ({@link isPlaywrightRunCommand}).
|
|
132
142
|
*
|
|
133
143
|
* @param command - The command as the executor sent it.
|
|
134
144
|
* @returns The command to run and one sentence per change made (empty when none).
|
|
@@ -137,6 +147,61 @@ export declare function streamingBackgroundCommand(command: string): {
|
|
|
137
147
|
command: string;
|
|
138
148
|
changes: string[];
|
|
139
149
|
};
|
|
150
|
+
/**
|
|
151
|
+
* Whether a command runs a whole test suite — a Playwright, Vitest or Hurl run
|
|
152
|
+
* — rather than a build, an install or a one-off script.
|
|
153
|
+
*
|
|
154
|
+
* A command that invokes a runner only to print is not one of these
|
|
155
|
+
* ({@link commandRunsNoTests}): `npx playwright test --list` prints the tests it would run and
|
|
156
|
+
* exits, and `npx playwright install`, `vitest list` and `hurl --help` start no test either.
|
|
157
|
+
*
|
|
158
|
+
* @param command - The shell command.
|
|
159
|
+
* @returns True when the command starts one of those runners.
|
|
160
|
+
*/
|
|
161
|
+
export declare function isSuiteRunCommand(command: string): boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Whether a command starts a Playwright run — `playwright test` in a form that runs something.
|
|
164
|
+
*
|
|
165
|
+
* `npx playwright test --list` matched every `\bplaywright\s+test\b` test in the platform and was
|
|
166
|
+
* then treated as a run: held (flash-m79's config check), backgrounded for a run that outlasts
|
|
167
|
+
* the tool's ceiling, and rewritten with `--reporter`. A list takes two seconds, prints its lines
|
|
168
|
+
* and exits, so it is none of those; {@link commandRunsNoTests} is what decides.
|
|
169
|
+
*
|
|
170
|
+
* @param command - The shell command.
|
|
171
|
+
* @returns True when the command starts a Playwright run.
|
|
172
|
+
*/
|
|
173
|
+
export declare function isPlaywrightRunCommand(command: string): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Start a background suite run at lower CPU and IO priority, so the sandbox it
|
|
176
|
+
* shares with everything else stays responsive to what the executor does next.
|
|
177
|
+
*
|
|
178
|
+
* A whole-suite Playwright run saturates the one container the app's Vite
|
|
179
|
+
* server, its API process and every other command also live in: on X1 flash-m75
|
|
180
|
+
* the model backgrounded a 139-test run at +36:23 and the two-word shell
|
|
181
|
+
* command it sent next — tick its plan file — returned nothing for 2 min 40 s,
|
|
182
|
+
* measured on the chat payload and on the live-stream follower independently.
|
|
183
|
+
* The backgrounding note is right that the executor should go do other work;
|
|
184
|
+
* what it cannot promise is that the sandbox will let it.
|
|
185
|
+
*
|
|
186
|
+
* `nice -n 10` lowers the run's CPU share and `ionice -c3` its IO class. Both
|
|
187
|
+
* are PROBED in the sandbox by RUNNING them, not with `command -v`: a syscall a
|
|
188
|
+
* container's seccomp policy refuses leaves `-v` passing while the real run
|
|
189
|
+
* fails. Each is applied only if its probe passed, so a sandbox with neither,
|
|
190
|
+
* or with only one, runs the suite exactly as it did before. Playwright's own
|
|
191
|
+
* workers are children of this shell and inherit both (niceness and IO class
|
|
192
|
+
* are inherited across fork/exec).
|
|
193
|
+
*
|
|
194
|
+
* Only a command the caller has already detached reaches this: foreground
|
|
195
|
+
* commands are never touched.
|
|
196
|
+
*
|
|
197
|
+
* @param command - The command as the executor sent it; the suite detection reads this.
|
|
198
|
+
* @param launch - The shell line that would start it, with no prefix of its own.
|
|
199
|
+
* @returns The line to run, and one sentence for the tool note ('' when unchanged).
|
|
200
|
+
*/
|
|
201
|
+
export declare function suiteRunPriorityLaunch(command: string, launch: string): {
|
|
202
|
+
launch: string;
|
|
203
|
+
note: string;
|
|
204
|
+
};
|
|
140
205
|
/**
|
|
141
206
|
* Check if a command is blocked for security reasons. Returns error message or null if allowed.
|
|
142
207
|
*
|
|
@@ -184,6 +249,28 @@ export declare function isOutsideRoot(path: string, projectRoot: string): boolea
|
|
|
184
249
|
* @returns `true` when the pattern contains only allowed characters.
|
|
185
250
|
*/
|
|
186
251
|
export declare function isValidGlob(pattern: string): boolean;
|
|
252
|
+
/**
|
|
253
|
+
* The `find` predicate for a `find_files` pattern.
|
|
254
|
+
*
|
|
255
|
+
* `find -name` compares a pattern against a file's BASENAME, so a pattern
|
|
256
|
+
* containing a slash (`helpers/*`, `e2e/*.spec.ts`, `src` + `**` + `/App.tsx`)
|
|
257
|
+
* can never match and the tool answers `[]` (xr-molecule-flash-m77, on two
|
|
258
|
+
* calls in one run). Such a pattern is matched with `-path` instead: an fnmatch
|
|
259
|
+
* glob over the whole printed path, whose `*` crosses `/` — the rule
|
|
260
|
+
* `.gitignore` uses, and the reason a bare `helpers/*` means "a `helpers/`
|
|
261
|
+
* directory anywhere below the root". The pattern is anchored with a leading
|
|
262
|
+
* `*` then `/` ("any parent") so the search root — an absolute
|
|
263
|
+
* `/workspace/<app>` in a sandbox — need not be spelled out.
|
|
264
|
+
*
|
|
265
|
+
* A doubled-star directory segment keeps its usual meaning of ZERO or more
|
|
266
|
+
* directories; `-path` alone would demand at least one, so the pattern is also
|
|
267
|
+
* emitted with each such segment removed.
|
|
268
|
+
*
|
|
269
|
+
* @param pattern - A pattern already accepted by {@link isValidGlob}.
|
|
270
|
+
* @returns A `find` predicate: `-name '…'` for a bare name, else one or more
|
|
271
|
+
* `-path '…'` alternatives, ORed inside parens when there is more than one.
|
|
272
|
+
*/
|
|
273
|
+
export declare function findPatternArgs(pattern: string): string;
|
|
187
274
|
/**
|
|
188
275
|
* Validate a file tool's `path` argument is a non-empty string. A weak model
|
|
189
276
|
* sometimes omits it or passes a non-string, which would otherwise crash
|
|
@@ -273,6 +360,47 @@ export declare const MAX_READ_RETURN_CHARS: number;
|
|
|
273
360
|
* file under it "fits in ONE call", and a smaller bound here broke that promise (X1 flash-m67).
|
|
274
361
|
*/
|
|
275
362
|
export declare const SMALL_FILE_WHOLE_CHARS: number;
|
|
363
|
+
/**
|
|
364
|
+
* How large an HTML document must be before a whole-file read is replaced by its
|
|
365
|
+
* outLINE — much smaller than {@link MAX_READ_RETURN_CHARS}, because the cost of
|
|
366
|
+
* an HTML read is almost never worth it.
|
|
367
|
+
*
|
|
368
|
+
* An entry document is boilerplate the reader rarely needs in full: meta tags,
|
|
369
|
+
* stylesheet and preload links, a `<style>` block, and a handful of `<script>`
|
|
370
|
+
* tags. The parts an executor acts on — the body's structure, where a script is
|
|
371
|
+
* loaded — are all visible in an outline of one line per tag. X0 flash-m77 paid
|
|
372
|
+
* 63,735 chars for one such read: ~60 KB of it was the IDE's own preview bridges,
|
|
373
|
+
* and the read pushed the transcript past its context cap, so the e2e specs the
|
|
374
|
+
* executor had just read were trimmed to summaries and it read the whole suite
|
|
375
|
+
* again — twice (findings, +01:23 and +02:56). The scaffold now keeps those
|
|
376
|
+
* bridges in separate files, but a template's own head is still ~5-12 KB, and a
|
|
377
|
+
* static-site or SSR entry can be far more.
|
|
378
|
+
*
|
|
379
|
+
* The outline is not a truncation: the note beside it names the exact
|
|
380
|
+
* offset/limit that returns the whole document in one call.
|
|
381
|
+
*/
|
|
382
|
+
export declare const MAX_HTML_INLINE_CHARS: number;
|
|
383
|
+
/** Most lines an HTML outline prints before it stops and says so. */
|
|
384
|
+
export declare const MAX_HTML_OUTLINE_LINES = 200;
|
|
385
|
+
/** Whether `text` is an HTML document (a doctype or an `<html` root tag). */
|
|
386
|
+
export declare function looksLikeHtml(text: string): boolean;
|
|
387
|
+
/**
|
|
388
|
+
* An OUTLINE of an HTML document: its head's tags and the tags that open each
|
|
389
|
+
* body section, one per line, with line numbers.
|
|
390
|
+
*
|
|
391
|
+
* Line-based on purpose — a parser would be a dependency and an attack surface
|
|
392
|
+
* for a read that only has to be *navigable*. A line is shown when it starts with
|
|
393
|
+
* `<` after trimming, which is what keeps the inside of a `<style>` block, a
|
|
394
|
+
* `<script>` body or a prerendered text section out of the outline while keeping
|
|
395
|
+
* every tag the document is built from. Long lines (a minified tag, a data URI)
|
|
396
|
+
* are cut, and the whole outline is capped, so a pathological document cannot
|
|
397
|
+
* turn one read into another wall of text.
|
|
398
|
+
*
|
|
399
|
+
* @param text - The document's full text.
|
|
400
|
+
* @param label - What to call the document in the outline's header (its path).
|
|
401
|
+
* @returns The outline — or null when `text` is not an HTML document.
|
|
402
|
+
*/
|
|
403
|
+
export declare function htmlOutline(text: string, label?: string): string | null;
|
|
276
404
|
/** Max search results. */
|
|
277
405
|
export declare const MAX_SEARCH_RESULTS = 50;
|
|
278
406
|
/** Max find results. */
|
|
@@ -341,6 +469,84 @@ export declare const RUNNING_FAILURE_LINE_RE = "^[[:space:]]*(\u2718|\u2717|\u00
|
|
|
341
469
|
* @returns The shell command, safe to hand to the execution backend as-is.
|
|
342
470
|
*/
|
|
343
471
|
export declare function runningOutputSliceCommand(log: string, own?: string): string;
|
|
472
|
+
/** Bytes of a running log a repeating-cause look reads back. */
|
|
473
|
+
export declare const REPEATING_CAUSE_TAIL_BYTES = 40000;
|
|
474
|
+
/**
|
|
475
|
+
* The shell command whose stdout is enough of a running log to tell whether one cause is
|
|
476
|
+
* repeating: its tail, {@link REPEATING_CAUSE_TAIL_BYTES} of it.
|
|
477
|
+
*
|
|
478
|
+
* {@link runningOutputSliceCommand} is the wrong read for this: it keeps only the FIRST 40
|
|
479
|
+
* failure lines plus 1 000 bytes, so on a run whose failures print a body each — which is what
|
|
480
|
+
* a `line` reporter does, and the only form that names the cause as an error message rather than
|
|
481
|
+
* a duration — three bodies do not fit, and the repeat is invisible. This read is not shown to
|
|
482
|
+
* anyone; it is parsed.
|
|
483
|
+
*
|
|
484
|
+
* @param log - The task log path.
|
|
485
|
+
* @param own - A file the command redirects its own output to, if any.
|
|
486
|
+
* @returns The shell command, safe to hand to the execution backend as-is.
|
|
487
|
+
*/
|
|
488
|
+
export declare function runningCauseCommand(log: string, own?: string): string;
|
|
489
|
+
/** Failures that must share one signature before a running suite's repeating cause is named. */
|
|
490
|
+
export declare const REPEATING_FAILURE_MIN = 3;
|
|
491
|
+
/** One failed test, as a running suite's log names it. */
|
|
492
|
+
export interface FailedTest {
|
|
493
|
+
/** The location the log writes (`specs/e2e/articles.spec.ts:32`), or '' when it writes none. */
|
|
494
|
+
where: string;
|
|
495
|
+
/** The test's own title — the last segment of its title path. */
|
|
496
|
+
title: string;
|
|
497
|
+
/** How long it ran before failing, in seconds, or null when the log does not say. */
|
|
498
|
+
seconds: number | null;
|
|
499
|
+
}
|
|
500
|
+
/** A cause repeating among a running suite's failures. */
|
|
501
|
+
export interface RepeatingFailure {
|
|
502
|
+
/** How many failures share the signature. */
|
|
503
|
+
count: number;
|
|
504
|
+
/** The shared error line, when the log carries the failures' bodies (`line` reporter). */
|
|
505
|
+
message: string | null;
|
|
506
|
+
/** The shared duration in seconds, when the failures line up by how long they ran. */
|
|
507
|
+
seconds: number | null;
|
|
508
|
+
/** The failures that share it, in log order. */
|
|
509
|
+
tests: FailedTest[];
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* The cause repeating among a running suite's failures, or null.
|
|
513
|
+
*
|
|
514
|
+
* Playwright's `list` reporter prints one line per test as it finishes — its mark, its title
|
|
515
|
+
* path and how long it ran — and defers each failure's error to the summary at the end, so
|
|
516
|
+
* mid-run the only signature those lines carry is the duration. A `line` reporter prints the
|
|
517
|
+
* failure bodies as they happen, and there the repeated error message itself is the signature,
|
|
518
|
+
* which is stronger (it needs no assumption about how long a failure should take), so the
|
|
519
|
+
* message is looked for first.
|
|
520
|
+
*
|
|
521
|
+
* Either way the point is the same: a suite whose failures repeat one cause spends its whole
|
|
522
|
+
* runtime proving that one cause, and the executor watching it can be told so at the third
|
|
523
|
+
* failure instead of at the last. X1 flash-m76 walked 15 tests in 4.0 minutes where 15.6 s
|
|
524
|
+
* each was the test timeout and one missing `navigate('/')` was the cause of all of them.
|
|
525
|
+
*
|
|
526
|
+
* @param log - The log so far.
|
|
527
|
+
* @returns The repeating cause, or null when no signature has {@link REPEATING_FAILURE_MIN}
|
|
528
|
+
* failures behind it.
|
|
529
|
+
*/
|
|
530
|
+
export declare function repeatingFailure(log: string): RepeatingFailure | null;
|
|
531
|
+
/** How many of a repeating cause's failures the note lists before it says "and N more". */
|
|
532
|
+
export declare const REPEATING_FAILURE_LISTED = 5;
|
|
533
|
+
/**
|
|
534
|
+
* The sentence that names a cause repeating among a running suite's failures, and the command
|
|
535
|
+
* that stops the run so the cause can be fixed first.
|
|
536
|
+
*
|
|
537
|
+
* Kept here, beside {@link repeatingFailure}, so the two stay in step: every word below is about
|
|
538
|
+
* what that function could actually see in the log.
|
|
539
|
+
*
|
|
540
|
+
* @param found - What {@link repeatingFailure} found.
|
|
541
|
+
* @param o - The run's facts: its `taskId`, its `log` path, and `stop` — the shell command that
|
|
542
|
+
* stops it (the pids the platform's own pid file leads to).
|
|
543
|
+
* @returns The note.
|
|
544
|
+
*/
|
|
545
|
+
export declare function repeatingFailureNote(found: RepeatingFailure, o: {
|
|
546
|
+
taskId: string;
|
|
547
|
+
log: string;
|
|
548
|
+
stop: string;
|
|
549
|
+
}): string;
|
|
344
550
|
/**
|
|
345
551
|
* Attempt a whitespace-tolerant replacement when an exact `old_string` match
|
|
346
552
|
* failed. Finds a contiguous run of lines in `content` whose per-line
|
package/dist/utilities.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"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"}
|