@molecule/api-ai-tools 1.10.6 → 1.10.7

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-19T13:08:52.848Z
6
+ Generated: 2026-10-19T22:30:20.727Z
7
7
  -->
8
8
 
9
9
  # @molecule/api-ai-tools
@@ -58,6 +58,28 @@ npm install @molecule/api-ai-tools @molecule/api-ai
58
58
 
59
59
  ### Interfaces
60
60
 
61
+ #### `BrowserProbeLeak`
62
+
63
+ A browser launch bound to a variable, proven to have no cleanup path.
64
+
65
+ ```typescript
66
+ interface BrowserProbeLeak {
67
+ /** The variable the launched browser is bound to (`browser` in the m257 probe). */
68
+ readonly variable: string
69
+ }
70
+ ```
71
+
72
+ #### `ForegroundBrowserProbe`
73
+
74
+ A foreground command that directly executes such a script.
75
+
76
+ ```typescript
77
+ interface ForegroundBrowserProbe extends BrowserProbeLeak {
78
+ /** The script file as the command named it. */
79
+ readonly script: string
80
+ }
81
+ ```
82
+
61
83
  #### `CommandSegment`
62
84
 
63
85
  One statement or pipeline stage of a shell command: what it runs, and with what.
@@ -222,6 +244,13 @@ interface CutRun {
222
244
  * is slow, so the sentence must not send it to the background (xr-molecule-flash-m200 +03:45).
223
245
  */
224
246
  inlineScript?: string | null
247
+ /**
248
+ * The variable a leaked standalone browser launch is bound to, when the command ran such a probe
249
+ * and the cut reader could only classify it after the run (xr-molecule-flash-m257). A leaked
250
+ * handle is not a slow workload: the background is the one place it must not be sent, so the
251
+ * sentence names the close instead.
252
+ */
253
+ browserProbe?: string | null
225
254
  }
226
255
  ```
227
256
 
@@ -1469,6 +1498,58 @@ function createSandboxBackend(sandbox: SandboxLike, projectRoot?: string): Execu
1469
1498
 
1470
1499
  **Returns:** A backend that proxies all filesystem calls into the sandbox.
1471
1500
 
1501
+ #### `standaloneBrowserLeak(source)`
1502
+
1503
+ The browser variable a standalone script launches and never closes, when that can be proven from
1504
+ the source alone.
1505
+
1506
+ The proof is a closed world: one plain TOP-LEVEL launch binding whose engine is genuinely
1507
+ Playwright's, every reference to it a known non-closing method call, and no cleanup, escape or
1508
+ persistent-process path anywhere in the source. A source with two launches is read one binding
1509
+ at a time — a proven leak in either one is enough, because that handle alone keeps Node alive.
1510
+
1511
+ ```typescript
1512
+ function standaloneBrowserLeak(source: string): BrowserProbeLeak | null
1513
+ ```
1514
+
1515
+ - `source` — The script's source, as read from disk.
1516
+
1517
+ **Returns:** The leaking binding, or null when the script is clean or ambiguous.
1518
+
1519
+ #### `browserProbeRefusal(probe, budgetSeconds, piped)`
1520
+
1521
+ The refusal for a foreground command that would run a leaking browser probe: it never returns,
1522
+ and the one move that makes it return is closing the browser (or letting the Playwright runner
1523
+ own it), never moving the leak to the background.
1524
+
1525
+ ```typescript
1526
+ function browserProbeRefusal(
1527
+ probe: ForegroundBrowserProbe,
1528
+ budgetSeconds: number,
1529
+ piped?: boolean,
1530
+ ): string
1531
+ ```
1532
+
1533
+ - `probe` — The leaked probe, from `foregroundBrowserProbe`.
1534
+ - `budgetSeconds` — The tool's budget, which the probe would consume whole.
1535
+ - `piped` — Whether the command pipes through `tail`/`head`, which withholds the probe's output.
1536
+
1537
+ **Returns:** The refusal sentence.
1538
+
1539
+ #### `browserProbeOverBudgetAdvice(probe)`
1540
+
1541
+ The over-budget advice for a leak discovered at cut time (the preflight could not read the script
1542
+ before the run — e.g. the same command wrote it). It names the lifecycle fix and says explicitly
1543
+ that the background is not one: a leaked handle hangs there too.
1544
+
1545
+ ```typescript
1546
+ function browserProbeOverBudgetAdvice(probe: ForegroundBrowserProbe): string
1547
+ ```
1548
+
1549
+ - `probe` — The leaked probe.
1550
+
1551
+ **Returns:** The sentence the cut result carries.
1552
+
1472
1553
  #### `durationSeconds(word)`
1473
1554
 
1474
1555
  The seconds a duration word stands for.
@@ -1790,7 +1871,12 @@ function allConnectionFailures(failures: readonly (RunFailureClass | null)[]): b
1790
1871
  The interpreter of an INLINE program that only reads and writes local files — the shape that gets
1791
1872
  {@link INLINE_SCRIPT_BUDGET_MS} instead of the tool's command budget.
1792
1873
 
1793
- An inline program with any external effect keeps the full budget: no network, install, test
1874
+ EVERY statement of the command must be proven local, not just one of them: each is either an
1875
+ inline interpreter program or a plain file utility ({@link LOCAL_UTILITY}). A statement that runs
1876
+ a script FILE (`node smoke.mjs`, `python3 x.py`, `bash x.sh`) or names a program this module does
1877
+ not know can do anything at all, so the command keeps the full budget.
1878
+
1879
+ An inline program with any external effect keeps the full budget too: no network, install, test
1794
1880
  runner, build or server verb may appear anywhere in the command ({@link EXTERNAL_EFFECT}), and
1795
1881
  the command must not be a suite run or a foreground server (the platform's own classifiers).
1796
1882
 
@@ -2033,6 +2119,29 @@ function foregroundServerCommand(
2033
2119
 
2034
2120
  **Returns:** The serving program, or null when the command starts no server in the foreground.
2035
2121
 
2122
+ #### `foregroundBrowserProbe(command, readScript)`
2123
+
2124
+ A FOREGROUND command that directly runs a standalone script which launches a browser and never
2125
+ closes it — the same never-returns lifecycle class as {@link foregroundServerCommand}, read from
2126
+ the script's SOURCE by {@link standaloneBrowserLeak}.
2127
+
2128
+ The boundaries are the server preflight's, so the two readers cannot disagree about what they are
2129
+ allowed to touch: a backgrounded launch, a test runner and a test file are left alone, and a
2130
+ script the backend will not answer for is a command this reading cannot classify, never a
2131
+ refusal. A Playwright suite is owned by its runner's browser fixture and is never read here.
2132
+
2133
+ ```typescript
2134
+ function foregroundBrowserProbe(
2135
+ command: string,
2136
+ readScript: (path: string) => Promise<string>,
2137
+ ): Promise<ForegroundBrowserProbe | null>
2138
+ ```
2139
+
2140
+ - `command` — The command as the executor sent it.
2141
+ - `readScript` — Reads a script file the command names (`backend.readFile`).
2142
+
2143
+ **Returns:** The leaked probe's variable and script path, or null when the command is not one.
2144
+
2036
2145
  #### `serverCommandRefusal(server, budgetSeconds)`
2037
2146
 
2038
2147
  The refusal for a foreground command that starts a server: why it would never return, and the
@@ -0,0 +1,82 @@
1
+ /**
2
+ * A standalone Playwright probe that launches a browser and never closes it — the
3
+ * resource-lifecycle hang `exec_command` did not yet classify.
4
+ *
5
+ * X1 xr-molecule-flash-m257 (+10:44 → +15:34) ran
6
+ * `cd /workspace/my-app/app && node /workspace/.mol-scratch/fav-probe.mjs 2>&1 | tail -5`. The
7
+ * 30-line script binds `const browser = await chromium.launch()`, walks a real page, reaches its
8
+ * last `console.log`, and ends without `browser.close()`, `disconnect()`, a disposal scope or
9
+ * `process.exit()`. Chromium is a live handle, so Node never exits: the tool waited its whole 290 s
10
+ * budget, returned `status: cut_at_budget` with empty stdout (the `| tail` held it), and then
11
+ * advised "run it in the background" — advice for a slow workload, not for a leaked handle.
12
+ *
13
+ * That is the same lifecycle class {@link foregroundServerCommand} already refuses: a foreground
14
+ * process that never returns. So the same preflight seam reads it, with a deliberately narrow
15
+ * closed-world proof:
16
+ *
17
+ * - the script is DIRECTLY executed (`node`/`tsx`/`bun`/`deno` naming a script file, never a
18
+ * test-runner invocation or a test/fixture file — those are the runner's business);
19
+ * - the source, with comments and string/template/regex literals blanked, binds a browser by a
20
+ * TOP-LEVEL (brace depth 0) `const|let|var <x> = await chromium|firefox|webkit.launch(`
21
+ * assignment, where the engine (or its namespace) is imported/required from `playwright`,
22
+ * `playwright-core` or `@playwright/test` — a locally bound stub is not Playwright;
23
+ * - every reference to `<x>` is a known browser method that does NOT close it (`newPage`,
24
+ * `newContext`, `on`, `version`, …), and the binding is never aliased, passed to a helper, or
25
+ * read as a property;
26
+ * - nothing in the source is a cleanup path (any `.close(`/`.disconnect(`/`.dispose(`, a `using`
27
+ * scope, a cleanup-named import), an escape (`process.exit`, `eval`, `new Function`, dynamic
28
+ * `import`), or a persistent-process intent (`launchServer`, `connect`, a server `.listen`, a
29
+ * timer or signal handler).
30
+ *
31
+ * Anything ambiguous is left alone. A wrong refusal costs a valid probe — the review that found
32
+ * the m257 leak also proved five harmless scripts a raw substring match would refuse (a local
33
+ * engine stub, the launch text in a string, in a comment, in a template literal, and inside a
34
+ * function that is never called) — and a missed leak costs the same budget the tool already had.
35
+ * This is a lifecycle diagnostic, never an egress or security gate.
36
+ *
37
+ * @module
38
+ */
39
+ /** A browser launch bound to a variable, proven to have no cleanup path. */
40
+ export interface BrowserProbeLeak {
41
+ /** The variable the launched browser is bound to (`browser` in the m257 probe). */
42
+ readonly variable: string;
43
+ }
44
+ /** A foreground command that directly executes such a script. */
45
+ export interface ForegroundBrowserProbe extends BrowserProbeLeak {
46
+ /** The script file as the command named it. */
47
+ readonly script: string;
48
+ }
49
+ /**
50
+ * The browser variable a standalone script launches and never closes, when that can be proven from
51
+ * the source alone.
52
+ *
53
+ * The proof is a closed world: one plain TOP-LEVEL launch binding whose engine is genuinely
54
+ * Playwright's, every reference to it a known non-closing method call, and no cleanup, escape or
55
+ * persistent-process path anywhere in the source. A source with two launches is read one binding
56
+ * at a time — a proven leak in either one is enough, because that handle alone keeps Node alive.
57
+ *
58
+ * @param source - The script's source, as read from disk.
59
+ * @returns The leaking binding, or null when the script is clean or ambiguous.
60
+ */
61
+ export declare function standaloneBrowserLeak(source: string): BrowserProbeLeak | null;
62
+ /**
63
+ * The refusal for a foreground command that would run a leaking browser probe: it never returns,
64
+ * and the one move that makes it return is closing the browser (or letting the Playwright runner
65
+ * own it), never moving the leak to the background.
66
+ *
67
+ * @param probe - The leaked probe, from `foregroundBrowserProbe`.
68
+ * @param budgetSeconds - The tool's budget, which the probe would consume whole.
69
+ * @param piped - Whether the command pipes through `tail`/`head`, which withholds the probe's output.
70
+ * @returns The refusal sentence.
71
+ */
72
+ export declare function browserProbeRefusal(probe: ForegroundBrowserProbe, budgetSeconds: number, piped?: boolean): string;
73
+ /**
74
+ * The over-budget advice for a leak discovered at cut time (the preflight could not read the script
75
+ * before the run — e.g. the same command wrote it). It names the lifecycle fix and says explicitly
76
+ * that the background is not one: a leaked handle hangs there too.
77
+ *
78
+ * @param probe - The leaked probe.
79
+ * @returns The sentence the cut result carries.
80
+ */
81
+ export declare function browserProbeOverBudgetAdvice(probe: ForegroundBrowserProbe): string;
82
+ //# sourceMappingURL=browser-probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-probe.d.ts","sourceRoot":"","sources":["../src/browser-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,iEAAiE;AACjE,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC9D,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AA6aD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAyB7E;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,sBAAsB,EAC7B,aAAa,EAAE,MAAM,EACrB,KAAK,UAAQ,GACZ,MAAM,CAaR;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CASlF"}