@molecule/api-ai-tools 1.5.4 → 1.5.5

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 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-15T00:28:10.570Z
6
+ Generated: 2026-10-15T20:27:42.092Z
7
7
  -->
8
8
 
9
9
  # @molecule/api-ai-tools
@@ -750,6 +750,28 @@ function sliceLines(
750
750
 
751
751
  **Returns:** The window plus its position, or null when neither was given.
752
752
 
753
+ #### `streamingBackgroundCommand(command)`
754
+
755
+ Rewrite a command about to run in the background so its log grows while it
756
+ runs. Two shapes left the log empty until exit, and an empty log is what
757
+ `wait_for_task` reads as "stuck", so working suites were reported stuck and
758
+ killed (X1 run flash-m15 lost 20 of its 60 minutes this way, 2026-10-15):
759
+
760
+ - a trailing `| tail -N`, which holds everything back until the command ends.
761
+ It is dropped: `wait_for_task` already returns the end of the log.
762
+ - `playwright test` with no `--reporter`, which runs the config's reporter —
763
+ often `html`, which prints nothing per test. `--reporter=line` is added
764
+ when the playwright run is the command's last step and nothing is piped or
765
+ redirected from it ( aside); the results are the same, printed as they happen.
766
+
767
+ ```typescript
768
+ function streamingBackgroundCommand(command: string): { command: string; changes: string[] }
769
+ ```
770
+
771
+ - `command` — The command as the executor sent it.
772
+
773
+ **Returns:** The command to run and one sentence per change made (empty when none).
774
+
753
775
  #### `stripControlChars(s)`
754
776
 
755
777
  Strip C0 control chars (except tab, newline, CR) that break PostgreSQL JSONB
@@ -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;AAgCnE;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CAs6CxF"}
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;AAiCnE;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CA06CxF"}
package/dist/tools.js CHANGED
@@ -23,7 +23,7 @@ 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
27
  /**
28
28
  * Build a complete set of AI agent tools bound to an execution backend.
29
29
  *
@@ -1021,7 +1021,10 @@ export function buildTools(backend, config) {
1021
1021
  // an executor's commands routinely carry quotes, heredocs and
1022
1022
  // newlines, and re-quoting them into a detached `sh -c` is how a
1023
1023
  // background runner corrupts the very thing it is running.
1024
- await backend.writeFile(script, `${command}\n`);
1024
+ // Keep the log growing while it runs (see streamingBackgroundCommand):
1025
+ // an empty log is what wait_for_task reads as stuck.
1026
+ const streaming = streamingBackgroundCommand(command);
1027
+ await backend.writeFile(script, `${streaming.command}\n`);
1025
1028
  await backend.run(`nohup sh -c ${shellQuote(`sh ${script} > ${log} 2>&1; echo $? > ${exitFile}`)} ` +
1026
1029
  `> /dev/null 2>&1 & echo $! > /tmp/${id}.pid`, { cwd, timeout: 15_000 });
1027
1030
  return {
@@ -1036,7 +1039,8 @@ export function buildTools(backend, config) {
1036
1039
  `stdout of wait_for_task when the command finishes (read_file cannot reach /tmp — ` +
1037
1040
  `to peek mid-run, exec_command: tail ${log}). If you have other work, do it and ` +
1038
1041
  `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.`,
1042
+ `with this taskId — never sleep and read the log by hand.` +
1043
+ (streaming.changes.length ? ` ${streaming.changes.join(' ')}` : ''),
1040
1044
  };
1041
1045
  }
1042
1046
  catch (e) {
@@ -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
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"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"}
package/dist/utilities.js CHANGED
@@ -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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@molecule/api-ai-tools",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "description": "Shared AI agent tools with backend abstraction for sandbox and local execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",