@molecule/api-ai-tools 1.5.4 → 1.5.6
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 +30 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +51 -4
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utilities.d.ts +20 -0
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js +38 -0
- 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-15T21:29:34.478Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/api-ai-tools
|
|
@@ -282,6 +282,13 @@ interface ToolBuildConfig {
|
|
|
282
282
|
*/
|
|
283
283
|
commandBudgetMs?: number
|
|
284
284
|
|
|
285
|
+
/**
|
|
286
|
+
* How long (ms) exec_command waits for a command it backgrounded only because the
|
|
287
|
+
* command asked for more than {@link commandBudgetMs}, before handing back a task
|
|
288
|
+
* id; one that finishes inside it returns like a foreground run. Default 45000.
|
|
289
|
+
*/
|
|
290
|
+
overCeilingGraceMs?: number
|
|
291
|
+
|
|
285
292
|
/**
|
|
286
293
|
* Directory names `search_files` and `find_files` skip (VS Code
|
|
287
294
|
* `search.exclude` semantics). Defaults to `DEFAULT_SEARCH_EXCLUDED_DIRS`
|
|
@@ -750,6 +757,28 @@ function sliceLines(
|
|
|
750
757
|
|
|
751
758
|
**Returns:** The window plus its position, or null when neither was given.
|
|
752
759
|
|
|
760
|
+
#### `streamingBackgroundCommand(command)`
|
|
761
|
+
|
|
762
|
+
Rewrite a command about to run in the background so its log grows while it
|
|
763
|
+
runs. Two shapes left the log empty until exit, and an empty log is what
|
|
764
|
+
`wait_for_task` reads as "stuck", so working suites were reported stuck and
|
|
765
|
+
killed (X1 run flash-m15 lost 20 of its 60 minutes this way, 2026-10-15):
|
|
766
|
+
|
|
767
|
+
- a trailing `| tail -N`, which holds everything back until the command ends.
|
|
768
|
+
It is dropped: `wait_for_task` already returns the end of the log.
|
|
769
|
+
- `playwright test` with no `--reporter`, which runs the config's reporter —
|
|
770
|
+
often `html`, which prints nothing per test. `--reporter=line` is added
|
|
771
|
+
when the playwright run is the command's last step and nothing is piped or
|
|
772
|
+
redirected from it ( aside); the results are the same, printed as they happen.
|
|
773
|
+
|
|
774
|
+
```typescript
|
|
775
|
+
function streamingBackgroundCommand(command: string): { command: string; changes: string[] }
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
- `command` — The command as the executor sent it.
|
|
779
|
+
|
|
780
|
+
**Returns:** The command to run and one sentence per change made (empty when none).
|
|
781
|
+
|
|
753
782
|
#### `stripControlChars(s)`
|
|
754
783
|
|
|
755
784
|
Strip C0 control chars (except tab, newline, CR) that break PostgreSQL JSONB
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AA2B9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AA2B9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAuCnE;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CA+8CxF"}
|
package/dist/tools.js
CHANGED
|
@@ -23,7 +23,12 @@ const waitedByTask = new Map();
|
|
|
23
23
|
* m21, 2026-10-15).
|
|
24
24
|
*/
|
|
25
25
|
const logBytesByTask = new Map();
|
|
26
|
-
import { checkBlockedCommand, declaredBudgetSeconds, DEFAULT_SEARCH_EXCLUDED_DIRS, directoryReadHint, 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, parseCheckCommand, parseCheckProblem, pathArgError, redactSecrets, redactSecretsInCode, resolvePath, shellQuote, sliceLines, stripControlChars, truncateMiddle, whitespaceTolerantReplace, } from './utilities.js';
|
|
26
|
+
import { checkBlockedCommand, declaredBudgetSeconds, DEFAULT_SEARCH_EXCLUDED_DIRS, directoryReadHint, 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, parseCheckCommand, parseCheckProblem, pathArgError, redactSecrets, redactSecretsInCode, resolvePath, shellQuote, sliceLines, streamingBackgroundCommand, stripControlChars, truncateMiddle, whitespaceTolerantReplace, } from './utilities.js';
|
|
27
|
+
/**
|
|
28
|
+
* How long exec_command waits for a command it backgrounded only because the
|
|
29
|
+
* command asked for more than the tool's ceiling, before handing back a task id.
|
|
30
|
+
*/
|
|
31
|
+
const OVER_CEILING_GRACE_MS = 45_000;
|
|
27
32
|
/**
|
|
28
33
|
* Build a complete set of AI agent tools bound to an execution backend.
|
|
29
34
|
*
|
|
@@ -32,7 +37,7 @@ import { checkBlockedCommand, declaredBudgetSeconds, DEFAULT_SEARCH_EXCLUDED_DIR
|
|
|
32
37
|
* @returns Array of AITool objects ready to pass to an AI provider
|
|
33
38
|
*/
|
|
34
39
|
export function buildTools(backend, config) {
|
|
35
|
-
const { include, exclude, pathGuards = true, symlinkGuards = false, redactSecrets: doRedact = true, blockDangerousCommands = false, blockCommand, execTimeoutMs = 120_000, commandBudgetMs, searchExcludedDirs, onAfterWrite, onFileDiff, onFileChange, } = config ?? {};
|
|
40
|
+
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 ?? {};
|
|
36
41
|
const root = backend.projectRoot;
|
|
37
42
|
// A host-filesystem backend with escape guards off is the combination the
|
|
38
43
|
// audit flagged: `pathGuards` off lets `..` paths out of the workspace,
|
|
@@ -1021,9 +1026,50 @@ export function buildTools(backend, config) {
|
|
|
1021
1026
|
// an executor's commands routinely carry quotes, heredocs and
|
|
1022
1027
|
// newlines, and re-quoting them into a detached `sh -c` is how a
|
|
1023
1028
|
// background runner corrupts the very thing it is running.
|
|
1024
|
-
|
|
1029
|
+
// Keep the log growing while it runs (see streamingBackgroundCommand):
|
|
1030
|
+
// an empty log is what wait_for_task reads as stuck.
|
|
1031
|
+
const streaming = streamingBackgroundCommand(command);
|
|
1032
|
+
await backend.writeFile(script, `${streaming.command}\n`);
|
|
1025
1033
|
await backend.run(`nohup sh -c ${shellQuote(`sh ${script} > ${log} 2>&1; echo $? > ${exitFile}`)} ` +
|
|
1026
1034
|
`> /dev/null 2>&1 & echo $! > /tmp/${id}.pid`, { cwd, timeout: 15_000 });
|
|
1035
|
+
// A command backgrounded only for the budget it ASKED for often ends in
|
|
1036
|
+
// seconds (a Hurl suite: 37 ms). Handing it back as a task cost a
|
|
1037
|
+
// wait_for_task round trip each time (X1 flash-m20, twice in ten
|
|
1038
|
+
// minutes), so wait a short grace first and return a finished command
|
|
1039
|
+
// exactly as a foreground run returns.
|
|
1040
|
+
if (overCeiling && input.run_in_background !== true) {
|
|
1041
|
+
const graceUntil = Date.now() + overCeilingGraceMs;
|
|
1042
|
+
while (Date.now() < graceUntil) {
|
|
1043
|
+
let code = null;
|
|
1044
|
+
try {
|
|
1045
|
+
const raw = await backend.readFile(exitFile);
|
|
1046
|
+
const parsed = Number.parseInt(raw.trim(), 10);
|
|
1047
|
+
code = Number.isFinite(parsed) ? parsed : 0;
|
|
1048
|
+
}
|
|
1049
|
+
catch (_error) {
|
|
1050
|
+
// No exit file yet: still running.
|
|
1051
|
+
code = null;
|
|
1052
|
+
}
|
|
1053
|
+
if (code !== null) {
|
|
1054
|
+
let output = '';
|
|
1055
|
+
try {
|
|
1056
|
+
output = await backend.readFile(log);
|
|
1057
|
+
}
|
|
1058
|
+
catch (_error) {
|
|
1059
|
+
// Finished without writing anything: an empty output is still a result.
|
|
1060
|
+
output = '';
|
|
1061
|
+
}
|
|
1062
|
+
return {
|
|
1063
|
+
stdout: sanitizeOutput(truncateMiddle(output, MAX_OUTPUT_SIZE)),
|
|
1064
|
+
stderr: '',
|
|
1065
|
+
exitCode: code,
|
|
1066
|
+
...(output.length > MAX_OUTPUT_SIZE ? { truncated: true, fullOutput: log } : {}),
|
|
1067
|
+
...(streaming.changes.length ? { note: streaming.changes.join(' ') } : {}),
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
1070
|
+
await new Promise((r) => setTimeout(r, 1_500));
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1027
1073
|
return {
|
|
1028
1074
|
taskId: id,
|
|
1029
1075
|
log,
|
|
@@ -1036,7 +1082,8 @@ export function buildTools(backend, config) {
|
|
|
1036
1082
|
`stdout of wait_for_task when the command finishes (read_file cannot reach /tmp — ` +
|
|
1037
1083
|
`to peek mid-run, exec_command: tail ${log}). If you have other work, do it and ` +
|
|
1038
1084
|
`check back. If you need this result before you can continue, call wait_for_task ` +
|
|
1039
|
-
`with this taskId — never sleep and read the log by hand
|
|
1085
|
+
`with this taskId — never sleep and read the log by hand.` +
|
|
1086
|
+
(streaming.changes.length ? ` ${streaming.changes.join(' ')}` : ''),
|
|
1040
1087
|
};
|
|
1041
1088
|
}
|
|
1042
1089
|
catch (e) {
|
package/dist/types.d.ts
CHANGED
|
@@ -99,6 +99,12 @@ export interface ToolBuildConfig {
|
|
|
99
99
|
* little under that outer timeout. Unset = no budget.
|
|
100
100
|
*/
|
|
101
101
|
commandBudgetMs?: number;
|
|
102
|
+
/**
|
|
103
|
+
* How long (ms) exec_command waits for a command it backgrounded only because the
|
|
104
|
+
* command asked for more than {@link commandBudgetMs}, before handing back a task
|
|
105
|
+
* id; one that finishes inside it returns like a foreground run. Default 45000.
|
|
106
|
+
*/
|
|
107
|
+
overCeilingGraceMs?: number;
|
|
102
108
|
/**
|
|
103
109
|
* Directory names `search_files` and `find_files` skip (VS Code
|
|
104
110
|
* `search.exclude` semantics). Defaults to `DEFAULT_SEARCH_EXCLUDED_DIRS`
|
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
|
@@ -89,6 +89,26 @@ export declare function declaredBudgetSeconds(command: string, timeoutParam: unk
|
|
|
89
89
|
* @returns True when a kill would return no useful output.
|
|
90
90
|
*/
|
|
91
91
|
export declare function outputIsWithheldUntilExit(command: string): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Rewrite a command about to run in the background so its log grows while it
|
|
94
|
+
* runs. Two shapes left the log empty until exit, and an empty log is what
|
|
95
|
+
* `wait_for_task` reads as "stuck", so working suites were reported stuck and
|
|
96
|
+
* killed (X1 run flash-m15 lost 20 of its 60 minutes this way, 2026-10-15):
|
|
97
|
+
*
|
|
98
|
+
* - a trailing `| tail -N`, which holds everything back until the command ends.
|
|
99
|
+
* It is dropped: `wait_for_task` already returns the end of the log.
|
|
100
|
+
* - `playwright test` with no `--reporter`, which runs the config's reporter —
|
|
101
|
+
* often `html`, which prints nothing per test. `--reporter=line` is added
|
|
102
|
+
* when the playwright run is the command's last step and nothing is piped or
|
|
103
|
+
* redirected from it ( aside); the results are the same, printed as they happen.
|
|
104
|
+
*
|
|
105
|
+
* @param command - The command as the executor sent it.
|
|
106
|
+
* @returns The command to run and one sentence per change made (empty when none).
|
|
107
|
+
*/
|
|
108
|
+
export declare function streamingBackgroundCommand(command: string): {
|
|
109
|
+
command: string;
|
|
110
|
+
changes: string[];
|
|
111
|
+
};
|
|
92
112
|
/**
|
|
93
113
|
* Check if a command is blocked for security reasons. Returns error message or null if allowed.
|
|
94
114
|
*
|
package/dist/utilities.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAS5C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,GAAG,MAAM,KAAG,MAEE,CAAA;AAyFhD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,MAAM,CAUpF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAElE;AAKD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG;IAC3D,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB,CAyBA;AA2BD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuBlE;AAID;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAQrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAOxE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQpD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIvE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI9E;AAID,yCAAyC;AACzC,eAAO,MAAM,aAAa,QAAkB,CAAA;AAC5C,8CAA8C;AAC9C,eAAO,MAAM,cAAc,QAAmB,CAAA;AAC9C,kDAAkD;AAClD,eAAO,MAAM,eAAe,QAAa,CAAA;AACzC;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAE1C;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA6BhG;AAED,0BAA0B;AAC1B;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAA;AAEtC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,QAAa,CAAA;AAE9C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,QAAY,CAAA;AAE9C,0BAA0B;AAC1B,eAAO,MAAM,kBAAkB,KAAK,CAAA;AACpC,wBAAwB;AACxB,eAAO,MAAM,gBAAgB,MAAM,CAAA;AAEnC;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,mHAW/B,CAAA;AAEV;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmBnE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAsCf;AAED,qEAAqE;AACrE,eAAO,MAAM,eAAe,QAA0C,CAAA;AAEtE;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB7D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,MAAM,GAAG,IAAI,CAKhB"}
|
package/dist/utilities.js
CHANGED
|
@@ -189,6 +189,44 @@ export function declaredBudgetSeconds(command, timeoutParam) {
|
|
|
189
189
|
export function outputIsWithheldUntilExit(command) {
|
|
190
190
|
return /\|\s*(?:tail|head|grep|egrep|fgrep|sort|uniq|wc|jq)\b/.test(command);
|
|
191
191
|
}
|
|
192
|
+
/** A trailing `| tail -N` / `| tail -n N` (stderr redirects before it stay). */
|
|
193
|
+
const TRAILING_TAIL = /\s*\|\s*tail(?:\s+-n)?\s+[-+]?\d+\s*$/;
|
|
194
|
+
/**
|
|
195
|
+
* Rewrite a command about to run in the background so its log grows while it
|
|
196
|
+
* runs. Two shapes left the log empty until exit, and an empty log is what
|
|
197
|
+
* `wait_for_task` reads as "stuck", so working suites were reported stuck and
|
|
198
|
+
* killed (X1 run flash-m15 lost 20 of its 60 minutes this way, 2026-10-15):
|
|
199
|
+
*
|
|
200
|
+
* - a trailing `| tail -N`, which holds everything back until the command ends.
|
|
201
|
+
* It is dropped: `wait_for_task` already returns the end of the log.
|
|
202
|
+
* - `playwright test` with no `--reporter`, which runs the config's reporter —
|
|
203
|
+
* often `html`, which prints nothing per test. `--reporter=line` is added
|
|
204
|
+
* when the playwright run is the command's last step and nothing is piped or
|
|
205
|
+
* redirected from it ( aside); the results are the same, printed as they happen.
|
|
206
|
+
*
|
|
207
|
+
* @param command - The command as the executor sent it.
|
|
208
|
+
* @returns The command to run and one sentence per change made (empty when none).
|
|
209
|
+
*/
|
|
210
|
+
export function streamingBackgroundCommand(command) {
|
|
211
|
+
const changes = [];
|
|
212
|
+
let out = command;
|
|
213
|
+
const tail = TRAILING_TAIL.exec(out);
|
|
214
|
+
if (tail) {
|
|
215
|
+
out = out.slice(0, tail.index);
|
|
216
|
+
changes.push(`Dropped the trailing \`${tail[0].trim()}\`: it holds all output back until the command ends, ` +
|
|
217
|
+
'and wait_for_task returns the end of the log anyway.');
|
|
218
|
+
}
|
|
219
|
+
const lastStep = out.split(/&&|\|\||;/).at(-1) ?? '';
|
|
220
|
+
if (/\bplaywright\s+test\b/.test(lastStep) &&
|
|
221
|
+
!/--reporter\b/.test(lastStep) &&
|
|
222
|
+
// `2>&1` only joins stderr to the log; any other pipe or redirect sends the output elsewhere.
|
|
223
|
+
!/[|>]/.test(lastStep.replace(/\d?>&\d/g, ''))) {
|
|
224
|
+
out = `${out.trimEnd()} --reporter=line`;
|
|
225
|
+
changes.push('Added `--reporter=line` so each test result is written to the log as it finishes ' +
|
|
226
|
+
'(the config reporter may print nothing until the end).');
|
|
227
|
+
}
|
|
228
|
+
return { command: out, changes };
|
|
229
|
+
}
|
|
192
230
|
// ── Command blocking ──────────────────────────────────────────────────────────
|
|
193
231
|
/**
|
|
194
232
|
* Commands that dump environment variables — blocked to prevent secret leakage.
|