@molecule/api-ai-tools 1.16.6 → 1.16.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-11-05T22:20:21.693Z
6
+ Generated: 2026-11-06T02:27:22.476Z
7
7
  -->
8
8
 
9
9
  # @molecule/api-ai-tools
@@ -1188,6 +1188,30 @@ interface ExecutionBackend {
1188
1188
  /** Write content to a file. Creates parent directories as needed. */
1189
1189
  writeFile(path: string, content: string): Promise<void>
1190
1190
 
1191
+ /**
1192
+ * Optional single-call path check and bounded text read for write/edit tools.
1193
+ * `realPath` must be resolved before reading; never read outside `symlinkRoot`.
1194
+ * Null `content` means missing; omit it for a native read (large/unreadable text).
1195
+ * Returned text must match readFile's decoding and honor any host file-method wrappers.
1196
+ * Implementations must use this backend's `run` so host command wrappers still apply.
1197
+ */
1198
+ readFileForUpdate?(
1199
+ path: string,
1200
+ symlinkRoot?: string,
1201
+ ): Promise<{ realPath: string; content?: string | null }>
1202
+
1203
+ /**
1204
+ * Optional write followed by the supplied parse command in one transport call.
1205
+ * Null means unsupported BEFORE a successful write; the caller uses writeFile/run.
1206
+ * Never retry a transport error after a write may have landed. After-write and
1207
+ * file-change hooks use the ordinary path so their ordering before parsing stays intact.
1208
+ */
1209
+ writeFileAndCheck?(
1210
+ path: string,
1211
+ content: string,
1212
+ command: string,
1213
+ ): Promise<{ stdout: string; stderr: string; exitCode: number } | null>
1214
+
1191
1215
  /** Delete a file. */
1192
1216
  deleteFile(path: string): Promise<void>
1193
1217
 
@@ -1710,8 +1734,8 @@ function createLocalBackend(projectRoot: string): ExecutionBackend
1710
1734
 
1711
1735
  #### `createSandboxBackend(sandbox, projectRoot)`
1712
1736
 
1713
- Create an ExecutionBackend that delegates to a Docker sandbox instance.
1714
- The sandbox.exec method is inherently safe — it runs inside an isolated Docker container.
1737
+ Create an ExecutionBackend that delegates to an isolated sandbox instance.
1738
+ The sandbox.exec method runs inside the provider's isolated environment.
1715
1739
 
1716
1740
  ```typescript
1717
1741
  function createSandboxBackend(sandbox: SandboxLike, projectRoot?: string): ExecutionBackend
@@ -5723,6 +5747,11 @@ Peer dependencies:
5723
5747
  to the model, and execute `catalog.loader` like any other tool. Loading only
5724
5748
  exposes schemas, never grants permission or runs a tool. Persist its loaded
5725
5749
  names with `onLoad` to keep them available across turns and compaction.
5750
+ - **Sandbox writes batch transport work.** The optional backend operations
5751
+ `readFileForUpdate` and `writeFileAndCheck` combine path safety with the old-text
5752
+ read, then the write with its parse check. Diff tracking and redaction checks
5753
+ stay in the tools. Format and change hooks retain their ordering before parsing;
5754
+ large files and backends without these operations use the native file APIs.
5726
5755
  - **Scope the tool set per agent** with `include`/`exclude` — a read-only agent
5727
5756
  should not receive `write_file`/`exec_command`.
5728
5757
  - Outputs are size-capped (`MAX_READ_SIZE`, `MAX_OUTPUT_SIZE`, …) and searches
@@ -0,0 +1,11 @@
1
+ /** Bounded file/command batching for sandbox transports; native file APIs remain the fallback. */
2
+ import type { ExecutionBackend } from '../types.js';
3
+ /**
4
+ * Batch sandbox filesystem work through the backend's current command wrapper.
5
+ * Keeping `this.run` preserves a host's environment and module-resolution prelude.
6
+ *
7
+ * @param native - Original file delegates; host overrides must not be bypassed.
8
+ * @returns Optional backend operations that retain native fallbacks for large files.
9
+ */
10
+ export declare function sandboxFileOperations(native: Pick<ExecutionBackend, 'readFile' | 'writeFile'>): Pick<ExecutionBackend, 'readFileForUpdate' | 'writeFileAndCheck'>;
11
+ //# sourceMappingURL=sandbox-file-operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-file-operations.d.ts","sourceRoot":"","sources":["../../src/backends/sandbox-file-operations.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAElG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAenD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,WAAW,CAAC,GACvD,IAAI,CAAC,gBAAgB,EAAE,mBAAmB,GAAG,mBAAmB,CAAC,CA2FnE"}
@@ -0,0 +1,100 @@
1
+ /** Bounded file/command batching for sandbox transports; native file APIs remain the fallback. */
2
+ import { shellQuote } from '../utilities.js';
3
+ // envd may truncate command output; Docker also caps a shell argument at 128 KiB.
4
+ // Keep both envelopes small, and accept a read only after its complete JSON arrives.
5
+ const MAX_ENVELOPE = 24_000;
6
+ const WRITE_MARK = 'MOL_FILE_WRITTEN\n';
7
+ const NO_WRITE_MARK = 'MOL_FILE_NOT_WRITTEN\n';
8
+ // Native text APIs may strip an initial UTF-8 BOM (Response.text), whereas
9
+ // command envelopes preserve it. Keep that provider-specific decoding on the native path.
10
+ const READ_SCRIPT = `const fs=require('fs'),cp=require('child_process');const p=process.argv[1],root=process.argv[2];let realPath='';if(root){const r=cp.spawnSync('readlink',['-f',p],{encoding:'utf8'});realPath=(r.status===0?r.stdout:p).trim()}let out={realPath};if(!root||!realPath||realPath===root||realPath.startsWith(root==='/'?'/':root+'/')){try{if(fs.statSync(p).size<=24000){const content=fs.readFileSync(p,'utf8');if(content.charCodeAt(0)!==65279&&Buffer.byteLength(JSON.stringify({realPath,content}))<=24000)out={realPath,content}}}catch(e){if(e.code==='ENOENT'||e.code==='ENOTDIR')out.content=null;/* other errors use the native API */}}process.stdout.write(JSON.stringify(out))`;
11
+ const WRITE_SCRIPT = `const fs=require('fs'),cp=require('child_process'),path=require('path');const r=JSON.parse(Buffer.from(process.argv[1],'base64').toString('utf8'));try{fs.mkdirSync(path.dirname(r.path),{recursive:true});fs.writeFileSync(r.path,r.content,'utf8')}catch(e){process.stdout.write('MOL_FILE_NOT_WRITTEN\\n');process.exit(1)}process.stdout.write('MOL_FILE_WRITTEN\\n');const c=cp.spawnSync('sh',['-c',r.command],{cwd:path.dirname(r.path),encoding:'utf8',timeout:15000,maxBuffer:10*1024*1024});process.stdout.write(JSON.stringify({stdout:c.stdout||'',stderr:c.stderr||'',exitCode:c.status??1}))`;
12
+ /**
13
+ * Batch sandbox filesystem work through the backend's current command wrapper.
14
+ * Keeping `this.run` preserves a host's environment and module-resolution prelude.
15
+ *
16
+ * @param native - Original file delegates; host overrides must not be bypassed.
17
+ * @returns Optional backend operations that retain native fallbacks for large files.
18
+ */
19
+ export function sandboxFileOperations(native) {
20
+ let supported = false;
21
+ const { readFile, writeFile } = native;
22
+ return {
23
+ async readFileForUpdate(path, symlinkRoot) {
24
+ const q = shellQuote(path);
25
+ // The native API may resolve relative paths against a different base than exec.
26
+ if (!path.startsWith('/') || this.readFile !== readFile) {
27
+ if (!symlinkRoot)
28
+ return { realPath: '' };
29
+ const checked = await this.run(`readlink -f ${q} 2>/dev/null || echo ${q}`, {
30
+ timeout: 5000,
31
+ });
32
+ return { realPath: checked.stdout.trim() };
33
+ }
34
+ const result = await this.run(`node -e ${shellQuote(READ_SCRIPT)} ${q} ${shellQuote(symlinkRoot ?? '')}`, {
35
+ timeout: 5000,
36
+ });
37
+ try {
38
+ const body = JSON.parse(result.stdout);
39
+ if (body &&
40
+ typeof body === 'object' &&
41
+ 'realPath' in body &&
42
+ typeof body.realPath === 'string') {
43
+ supported = true;
44
+ if ('content' in body && (typeof body.content === 'string' || body.content === null))
45
+ return { realPath: body.realPath, content: body.content };
46
+ return { realPath: body.realPath };
47
+ }
48
+ }
49
+ catch (_error) {
50
+ // Missing Node or truncated/malformed stdout cannot supply file contents.
51
+ }
52
+ supported = false;
53
+ if (!symlinkRoot)
54
+ return { realPath: '' };
55
+ // Native path verification still decides safety when batching is unavailable.
56
+ const checked = await this.run(`readlink -f ${q} 2>/dev/null || echo ${q}`, { timeout: 5000 });
57
+ return { realPath: checked.stdout.trim() };
58
+ },
59
+ async writeFileAndCheck(path, content, command) {
60
+ if (!path.startsWith('/') || !supported || this.writeFile !== writeFile)
61
+ return null;
62
+ const request = Buffer.from(JSON.stringify({ path, content, command })).toString('base64');
63
+ if (request.length > MAX_ENVELOPE)
64
+ return null;
65
+ const result = await this.run(`node -e ${shellQuote(WRITE_SCRIPT)} ${shellQuote(request)}`, {
66
+ // The target's parent may be created by this very write. The child parse
67
+ // command enters it only after mkdir/write have succeeded.
68
+ cwd: this.projectRoot,
69
+ timeout: 20_000,
70
+ });
71
+ if (!result.stdout.startsWith(WRITE_MARK)) {
72
+ // No successful write acknowledged (e.g. no Node or a filesystem error).
73
+ // The native API retains its provider-specific error and directory behavior.
74
+ if (result.stdout.startsWith(NO_WRITE_MARK) ||
75
+ (result.exitCode === 127 && /node.*not found/.test(result.stderr)))
76
+ return null;
77
+ throw new Error('Sandbox file write returned no completion acknowledgement; not retrying an uncertain write');
78
+ }
79
+ try {
80
+ const check = JSON.parse(result.stdout.slice(WRITE_MARK.length));
81
+ if (typeof check.stdout === 'string' &&
82
+ typeof check.stderr === 'string' &&
83
+ typeof check.exitCode === 'number')
84
+ return check;
85
+ }
86
+ catch (_error) {
87
+ // The write succeeded, but its check output was truncated. Recheck only;
88
+ // never replay an acknowledged write or a failed transport.
89
+ }
90
+ return this.run(command, {
91
+ cwd: path.slice(0, path.lastIndexOf('/')) || '/',
92
+ timeout: 15_000,
93
+ }).catch((_error) => {
94
+ // Like the ordinary post-write check, an unavailable parser adds no syntax note.
95
+ // The write was acknowledged above, so only the best-effort check failed here.
96
+ return { stdout: '', stderr: '', exitCode: 0 };
97
+ });
98
+ },
99
+ };
100
+ }
@@ -14,12 +14,12 @@ interface SandboxLike {
14
14
  name: string;
15
15
  type: 'file' | 'directory';
16
16
  }>>;
17
- /** Sandbox command execution — already sandboxed within Docker. */
17
+ /** Sandbox command execution — already isolated by the provider. */
18
18
  [key: string]: any;
19
19
  }
20
20
  /**
21
- * Create an ExecutionBackend that delegates to a Docker sandbox instance.
22
- * The sandbox.exec method is inherently safe — it runs inside an isolated Docker container.
21
+ * Create an ExecutionBackend that delegates to an isolated sandbox instance.
22
+ * The sandbox.exec method runs inside the provider's isolated environment.
23
23
  *
24
24
  * @param sandbox - A running Sandbox instance from `@molecule/api-code-sandbox`
25
25
  * @param projectRoot - Root directory inside the sandbox (default: '/workspace')
@@ -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,CAmDlB"}
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;AAInD,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,oEAAoE;IAEpE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,WAAW,EACpB,WAAW,SAAe,GACzB,gBAAgB,CAuDlB"}
@@ -5,16 +5,17 @@
5
5
  * @module
6
6
  */
7
7
  import { shellQuote } from '../utilities.js';
8
+ import { sandboxFileOperations } from './sandbox-file-operations.js';
8
9
  /**
9
- * Create an ExecutionBackend that delegates to a Docker sandbox instance.
10
- * The sandbox.exec method is inherently safe — it runs inside an isolated Docker container.
10
+ * Create an ExecutionBackend that delegates to an isolated sandbox instance.
11
+ * The sandbox.exec method runs inside the provider's isolated environment.
11
12
  *
12
13
  * @param sandbox - A running Sandbox instance from `@molecule/api-code-sandbox`
13
14
  * @param projectRoot - Root directory inside the sandbox (default: '/workspace')
14
15
  * @returns A backend that proxies all filesystem calls into the sandbox.
15
16
  */
16
17
  export function createSandboxBackend(sandbox, projectRoot = '/workspace') {
17
- return {
18
+ const backend = {
18
19
  projectRoot,
19
20
  readFile(path) {
20
21
  return sandbox.readFile(path);
@@ -54,9 +55,10 @@ export function createSandboxBackend(sandbox, projectRoot = '/workspace') {
54
55
  const fullCommand = budgetSeconds
55
56
  ? `o=$(mktemp); e=$(mktemp); timeout -k 5 ${budgetSeconds} bash -c ${shellQuote(anchored)} > "$o" 2> "$e" < /dev/null; c=$?; cat "$o"; cat "$e" >&2; rm -f "$o" "$e"; exit $c`
56
57
  : anchored;
57
- // sandbox.exec is the Sandbox interface method — runs inside Docker, inherently sandboxed
58
+ // sandbox.exec is the Sandbox interface method — runs inside the provider's isolated environment
58
59
  const result = await sandbox.exec(fullCommand, { timeout: opts?.timeout });
59
60
  return { stdout: result.stdout, stderr: result.stderr, exitCode: result.exitCode };
60
61
  },
61
62
  };
63
+ return Object.assign(backend, typeof sandbox.exec === 'function' ? sandboxFileOperations(backend) : {});
62
64
  }
package/dist/index.d.ts CHANGED
@@ -81,6 +81,11 @@
81
81
  * to the model, and execute `catalog.loader` like any other tool. Loading only
82
82
  * exposes schemas, never grants permission or runs a tool. Persist its loaded
83
83
  * names with `onLoad` to keep them available across turns and compaction.
84
+ * - **Sandbox writes batch transport work.** The optional backend operations
85
+ * `readFileForUpdate` and `writeFileAndCheck` combine path safety with the old-text
86
+ * read, then the write with its parse check. Diff tracking and redaction checks
87
+ * stay in the tools. Format and change hooks retain their ordering before parsing;
88
+ * large files and backends without these operations use the native file APIs.
84
89
  * - **Scope the tool set per agent** with `include`/`exclude` — a read-only agent
85
90
  * should not receive `write_file`/`exec_command`.
86
91
  * - Outputs are size-capped (`MAX_READ_SIZE`, `MAX_OUTPUT_SIZE`, …) and searches
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6IG;AAEH,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,cAAc,CAAA;AAC5B,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,YAAY,CAAA;AAC1B,cAAc,sBAAsB,CAAA;AACpC,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkJG;AAEH,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,cAAc,CAAA;AAC5B,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,YAAY,CAAA;AAC1B,cAAc,sBAAsB,CAAA;AACpC,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA"}
package/dist/index.js CHANGED
@@ -81,6 +81,11 @@
81
81
  * to the model, and execute `catalog.loader` like any other tool. Loading only
82
82
  * exposes schemas, never grants permission or runs a tool. Persist its loaded
83
83
  * names with `onLoad` to keep them available across turns and compaction.
84
+ * - **Sandbox writes batch transport work.** The optional backend operations
85
+ * `readFileForUpdate` and `writeFileAndCheck` combine path safety with the old-text
86
+ * read, then the write with its parse check. Diff tracking and redaction checks
87
+ * stay in the tools. Format and change hooks retain their ordering before parsing;
88
+ * large files and backends without these operations use the native file APIs.
84
89
  * - **Scope the tool set per agent** with `include`/`exclude` — a read-only agent
85
90
  * should not receive `write_file`/`exec_command`.
86
91
  * - Outputs are size-capped (`MAX_READ_SIZE`, `MAX_OUTPUT_SIZE`, …) and searches
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AA2B9C,OAAO,EAIL,KAAK,mBAAmB,EAEzB,MAAM,wBAAwB,CAAA;AAsC/B;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,KAAK,CAAC,EACnD,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAmB9B;AAuLD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAahG;AAkeD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAkInE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAEA,CAAA;AAE9B;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,wBAAwB,QAI6C,CAAA;AA0DlF;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUhE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGtE;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;AAoBpF;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAAC,GACxE,qBAAqB,CAkBvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,qBAAqB,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiCxB;AA2GD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CA0pGxF"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AA2B9C,OAAO,EAIL,KAAK,mBAAmB,EAEzB,MAAM,wBAAwB,CAAA;AAsC/B;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,KAAK,CAAC,EACnD,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAmB9B;AAuLD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAahG;AAkeD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAkInE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAEA,CAAA;AAE9B;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,wBAAwB,QAI6C,CAAA;AA0DlF;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUhE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGtE;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;AAoBpF;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAAC,GACxE,qBAAqB,CAkBvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,qBAAqB,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiCxB;AA2GD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CA0sGxF"}
package/dist/tools.js CHANGED
@@ -1145,13 +1145,14 @@ export function buildTools(backend, config) {
1145
1145
  * is ~50 ms; the executor sees the exact line while the edit is still in
1146
1146
  * front of it.
1147
1147
  */
1148
- async function syntaxErrorAfterWrite(path) {
1148
+ async function syntaxErrorAfterWrite(path, checked) {
1149
1149
  const command = parseCheckCommand(path);
1150
1150
  if (!command)
1151
1151
  return {};
1152
- const result = await backend
1153
- .run(command, { cwd: path.slice(0, path.lastIndexOf('/')) || '/', timeout: 15_000 })
1154
- .catch(() => null);
1152
+ const result = checked ??
1153
+ (await backend
1154
+ .run(command, { cwd: path.slice(0, path.lastIndexOf('/')) || '/', timeout: 15_000 })
1155
+ .catch(() => null));
1155
1156
  const problem = result ? parseCheckProblem(result) : null;
1156
1157
  // JSX in a `.ts` file parses as a type assertion and fails on the first
1157
1158
  // attribute — `Expected ">" but found "className"` — which does not say the
@@ -1232,7 +1233,7 @@ export function buildTools(backend, config) {
1232
1233
  * @param path - Candidate filesystem path after `resolve()`.
1233
1234
  * @returns An error message when unsafe, otherwise `null`.
1234
1235
  */
1235
- async function checkSymlink(path) {
1236
+ async function checkSymlink(path, probe) {
1236
1237
  if (!symlinkGuards)
1237
1238
  return null;
1238
1239
  // The retry budget is failure-aware. A plain slow answer gets ONE quick retry
@@ -1249,7 +1250,9 @@ export function buildTools(backend, config) {
1249
1250
  attempts++;
1250
1251
  const started = Date.now();
1251
1252
  try {
1252
- const result = await backend.run(`readlink -f ${shellQuote(path)} 2>/dev/null || echo ${shellQuote(path)}`, { timeout: 5000 });
1253
+ const result = probe
1254
+ ? await probe()
1255
+ : await backend.run(`readlink -f ${shellQuote(path)} 2>/dev/null || echo ${shellQuote(path)}`, { timeout: 5000 });
1253
1256
  const realPath = result.stdout.trim();
1254
1257
  if (realPath &&
1255
1258
  realPath !== root &&
@@ -1286,6 +1289,37 @@ export function buildTools(backend, config) {
1286
1289
  return (`Unable to verify path safety: the sandbox's command channel failed (${err?.name ?? 'Error'}: ${String(err?.message ?? err).slice(0, 160)}), ` +
1287
1290
  'so the path was refused to stay safe. Retry the call; if every file tool fails this way, the sandbox needs a restart.');
1288
1291
  }
1292
+ /** Guard and old-text read share a transport when the backend offers it. */
1293
+ async function readBeforeWrite(path) {
1294
+ let content;
1295
+ if (!backend.readFileForUpdate)
1296
+ return { error: await checkSymlink(path) };
1297
+ const probe = async () => {
1298
+ const result = await backend.readFileForUpdate(path, symlinkGuards ? root : undefined);
1299
+ content = result.content;
1300
+ return { stdout: result.realPath };
1301
+ };
1302
+ if (symlinkGuards)
1303
+ return { error: await checkSymlink(path, probe), content };
1304
+ try {
1305
+ await probe();
1306
+ }
1307
+ catch (_error) {
1308
+ // No safety check was requested; a failed optimization leaves the native read in charge.
1309
+ }
1310
+ return { error: null, content };
1311
+ }
1312
+ /** A formatter needs its original write/hook/reread/check ordering. */
1313
+ async function writeAndCheck(path, content) {
1314
+ const command = parseCheckCommand(path);
1315
+ if (!onAfterWrite && !onFileChange && command && backend.writeFileAndCheck) {
1316
+ const result = await backend.writeFileAndCheck(path, content, command);
1317
+ if (result !== null)
1318
+ return result;
1319
+ }
1320
+ await backend.writeFile(path, content);
1321
+ return null;
1322
+ }
1289
1323
  /**
1290
1324
  * Strip control characters and optionally redact secrets from tool output.
1291
1325
  *
@@ -1968,13 +2002,13 @@ export function buildTools(backend, config) {
1968
2002
  return {
1969
2003
  error: `Content too large (${Math.round(content.length / 1024)}KB). Maximum is ${MAX_WRITE_SIZE / 1024 / 1024}MB.`,
1970
2004
  };
1971
- const symlinkErr = await checkSymlink(path);
1972
- if (symlinkErr)
1973
- return { error: symlinkErr };
2005
+ const before = await readBeforeWrite(path);
2006
+ if (before.error)
2007
+ return { error: before.error };
1974
2008
  try {
1975
2009
  let oldContent = null;
1976
2010
  try {
1977
- oldContent = await backend.readFile(path);
2011
+ oldContent = before.content !== undefined ? before.content : await backend.readFile(path);
1978
2012
  }
1979
2013
  catch (_error) {
1980
2014
  /* file doesn't exist yet — oldContent stays null */
@@ -1988,7 +2022,7 @@ export function buildTools(backend, config) {
1988
2022
  }
1989
2023
  if (onFileDiff)
1990
2024
  onFileDiff({ path, oldContent, newContent: content });
1991
- await backend.writeFile(path, content);
2025
+ const checked = await writeAndCheck(path, content);
1992
2026
  if (onAfterWrite)
1993
2027
  await onAfterWrite(path).catch(() => { });
1994
2028
  // The text on disk is the text just written unless an after-write hook (a formatter)
@@ -2011,7 +2045,7 @@ export function buildTools(backend, config) {
2011
2045
  diff,
2012
2046
  totalLines: countLines(finalContent),
2013
2047
  ...(echo !== null ? { excerpt: sanitizeFileContent(echo, path) } : {}),
2014
- ...(await syntaxErrorAfterWrite(path)),
2048
+ ...(await syntaxErrorAfterWrite(path, checked)),
2015
2049
  };
2016
2050
  }
2017
2051
  catch (e) {
@@ -2067,11 +2101,11 @@ export function buildTools(backend, config) {
2067
2101
  return {
2068
2102
  error: 'No replacements provided. Use { replacements: [{ old_string, new_string }] } or { old_string, new_string }.',
2069
2103
  };
2070
- const symlinkErr = await checkSymlink(path);
2071
- if (symlinkErr)
2072
- return { error: symlinkErr };
2104
+ const before = await readBeforeWrite(path);
2105
+ if (before.error)
2106
+ return { error: before.error };
2073
2107
  try {
2074
- let content = await backend.readFile(path);
2108
+ let content = before.content ?? (await backend.readFile(path));
2075
2109
  // A transiently-empty read here made every old_string "not found", which
2076
2110
  // steers the model to re-read and then rewrite a file it never saw. Same
2077
2111
  // verification as read_file: empty is only believed once it is confirmed.
@@ -2450,7 +2484,7 @@ export function buildTools(backend, config) {
2450
2484
  }
2451
2485
  if (onFileDiff)
2452
2486
  onFileDiff({ path, oldContent, newContent: content });
2453
- await backend.writeFile(path, content);
2487
+ const checked = await writeAndCheck(path, content);
2454
2488
  if (onAfterWrite)
2455
2489
  await onAfterWrite(path).catch(() => { });
2456
2490
  if (onFileChange)
@@ -2483,7 +2517,7 @@ export function buildTools(backend, config) {
2483
2517
  r.old_string.endsWith('\n') &&
2484
2518
  r.new_string !== '' &&
2485
2519
  !r.new_string.endsWith('\n'));
2486
- const syntax = await syntaxErrorAfterWrite(path);
2520
+ const syntax = await syntaxErrorAfterWrite(path, checked);
2487
2521
  // A parse error and a dropped line break are two OBSERVATIONS, not one
2488
2522
  // accident. A join only sometimes breaks the syntax (same-line JSX siblings
2489
2523
  // parse), and the diagnostic usually comes from something else in the same
package/dist/types.d.ts CHANGED
@@ -22,6 +22,28 @@ export interface ExecutionBackend {
22
22
  readFile(path: string): Promise<string>;
23
23
  /** Write content to a file. Creates parent directories as needed. */
24
24
  writeFile(path: string, content: string): Promise<void>;
25
+ /**
26
+ * Optional single-call path check and bounded text read for write/edit tools.
27
+ * `realPath` must be resolved before reading; never read outside `symlinkRoot`.
28
+ * Null `content` means missing; omit it for a native read (large/unreadable text).
29
+ * Returned text must match readFile's decoding and honor any host file-method wrappers.
30
+ * Implementations must use this backend's `run` so host command wrappers still apply.
31
+ */
32
+ readFileForUpdate?(path: string, symlinkRoot?: string): Promise<{
33
+ realPath: string;
34
+ content?: string | null;
35
+ }>;
36
+ /**
37
+ * Optional write followed by the supplied parse command in one transport call.
38
+ * Null means unsupported BEFORE a successful write; the caller uses writeFile/run.
39
+ * Never retry a transport error after a write may have landed. After-write and
40
+ * file-change hooks use the ordinary path so their ordering before parsing stays intact.
41
+ */
42
+ writeFileAndCheck?(path: string, content: string, command: string): Promise<{
43
+ stdout: string;
44
+ stderr: string;
45
+ exitCode: number;
46
+ } | null>;
25
47
  /** Delete a file. */
26
48
  deleteFile(path: string): Promise<void>;
27
49
  /** List entries in a directory. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yFAAyF;IACzF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAE5B;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;IAEzB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAEvC,qEAAqE;IACrE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEvD,qBAAqB;IACrB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEvC,mCAAmC;IACnC,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;IAEnF;;;OAGG;IACH,GAAG,CACD,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;QACL,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB;;;;;WAKG;QACH,QAAQ,CAAC,EAAE,MAAM,CAAA;KAClB,GACA,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACjE;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACxD;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAElB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAElB,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAA;IAEpB,2FAA2F;IAC3F,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB,iFAAiF;IACjF,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB,2FAA2F;IAC3F,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAEhC;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAE1E;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;IAE1D;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAE3B;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAE7B;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAA;IAEhC;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,EAAE,MAAM,SAAS,MAAM,EAAE,CAAA;IAE5C;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,EAAE,CACjB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,KACR,OAAO,CAAC,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IAE3E;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IAE1F;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IAEjF,uGAAuG;IACvG,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAE9C,yEAAyE;IACzE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAE3C,wFAAwF;IACxF,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAA;IACxC,IAAI,EAAE,MAAM,CAAA;CACb;AAED,+DAA+D;AAC/D,MAAM,WAAW,UAAU;IACzB,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAA;IAEjB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAA;IAEnB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,EAAE,CAAA;IAEf,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IAEjB,kFAAkF;IAClF,gBAAgB,CAAC,EAAE,UAAU,EAAE,CAAA;IAE/B,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;CAC1B"}
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.16.6",
3
+ "version": "1.16.7",
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",