@namzu/sdk 1.3.0 → 2.0.0

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.
Files changed (171) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/dist/compaction/__tests__/verifier-empty-reply.test.d.ts +12 -0
  3. package/dist/compaction/__tests__/verifier-empty-reply.test.d.ts.map +1 -0
  4. package/dist/compaction/__tests__/verifier-empty-reply.test.js +73 -0
  5. package/dist/compaction/__tests__/verifier-empty-reply.test.js.map +1 -0
  6. package/dist/compaction/verifier.d.ts.map +1 -1
  7. package/dist/compaction/verifier.js +10 -1
  8. package/dist/compaction/verifier.js.map +1 -1
  9. package/dist/config/__tests__/compaction-budget-schema.test.d.ts +18 -0
  10. package/dist/config/__tests__/compaction-budget-schema.test.d.ts.map +1 -0
  11. package/dist/config/__tests__/compaction-budget-schema.test.js +96 -0
  12. package/dist/config/__tests__/compaction-budget-schema.test.js.map +1 -0
  13. package/dist/config/runtime.d.ts.map +1 -1
  14. package/dist/config/runtime.js +20 -11
  15. package/dist/config/runtime.js.map +1 -1
  16. package/dist/manager/run/persistence.d.ts +2 -1
  17. package/dist/manager/run/persistence.d.ts.map +1 -1
  18. package/dist/manager/run/persistence.js +3 -1
  19. package/dist/manager/run/persistence.js.map +1 -1
  20. package/dist/provider/__tests__/errors.test.d.ts +2 -0
  21. package/dist/provider/__tests__/errors.test.d.ts.map +1 -0
  22. package/dist/provider/__tests__/errors.test.js +61 -0
  23. package/dist/provider/__tests__/errors.test.js.map +1 -0
  24. package/dist/provider/errors.d.ts +108 -0
  25. package/dist/provider/errors.d.ts.map +1 -0
  26. package/dist/provider/errors.js +311 -0
  27. package/dist/provider/errors.js.map +1 -0
  28. package/dist/provider/index.d.ts +2 -0
  29. package/dist/provider/index.d.ts.map +1 -1
  30. package/dist/provider/index.js +1 -0
  31. package/dist/provider/index.js.map +1 -1
  32. package/dist/public-runtime.d.ts +11 -11
  33. package/dist/public-runtime.d.ts.map +1 -1
  34. package/dist/public-runtime.js +11 -11
  35. package/dist/public-runtime.js.map +1 -1
  36. package/dist/registry/tool/execute.d.ts.map +1 -1
  37. package/dist/registry/tool/execute.js +45 -12
  38. package/dist/registry/tool/execute.js.map +1 -1
  39. package/dist/registry/tool/execute.test.js +104 -7
  40. package/dist/registry/tool/execute.test.js.map +1 -1
  41. package/dist/registry/toolset/catalog.d.ts.map +1 -1
  42. package/dist/registry/toolset/catalog.js +17 -4
  43. package/dist/registry/toolset/catalog.js.map +1 -1
  44. package/dist/registry/toolset/catalog.test.js +101 -0
  45. package/dist/registry/toolset/catalog.test.js.map +1 -1
  46. package/dist/runtime/query/__tests__/capability-negotiation.test.js +79 -0
  47. package/dist/runtime/query/__tests__/capability-negotiation.test.js.map +1 -1
  48. package/dist/runtime/query/__tests__/deferred-tools.test.js +100 -0
  49. package/dist/runtime/query/__tests__/deferred-tools.test.js.map +1 -1
  50. package/dist/runtime/query/__tests__/long-document-flow.test.js +12 -12
  51. package/dist/runtime/query/__tests__/long-document-flow.test.js.map +1 -1
  52. package/dist/runtime/query/__tests__/stream-recovery.test.js +55 -2
  53. package/dist/runtime/query/__tests__/stream-recovery.test.js.map +1 -1
  54. package/dist/runtime/query/executor.js +2 -2
  55. package/dist/runtime/query/executor.js.map +1 -1
  56. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  57. package/dist/runtime/query/iteration/index.js +10 -0
  58. package/dist/runtime/query/iteration/index.js.map +1 -1
  59. package/dist/runtime/query/iteration/phases/compaction-safe-cut.test.d.ts +32 -0
  60. package/dist/runtime/query/iteration/phases/compaction-safe-cut.test.d.ts.map +1 -0
  61. package/dist/runtime/query/iteration/phases/compaction-safe-cut.test.js +152 -0
  62. package/dist/runtime/query/iteration/phases/compaction-safe-cut.test.js.map +1 -0
  63. package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
  64. package/dist/runtime/query/iteration/phases/compaction.js +52 -12
  65. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  66. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  67. package/dist/runtime/query/iteration/stream-turn.js +11 -5
  68. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  69. package/dist/runtime/query/result.d.ts.map +1 -1
  70. package/dist/runtime/query/result.js +11 -1
  71. package/dist/runtime/query/result.js.map +1 -1
  72. package/dist/tools/builtins/__tests__/edit.test.js +216 -10
  73. package/dist/tools/builtins/__tests__/edit.test.js.map +1 -1
  74. package/dist/tools/builtins/__tests__/payload-budget.test.js +30 -16
  75. package/dist/tools/builtins/__tests__/payload-budget.test.js.map +1 -1
  76. package/dist/tools/builtins/__tests__/write-file.test.js +37 -13
  77. package/dist/tools/builtins/__tests__/write-file.test.js.map +1 -1
  78. package/dist/tools/builtins/atomic-write-file.d.ts +13 -0
  79. package/dist/tools/builtins/atomic-write-file.d.ts.map +1 -0
  80. package/dist/tools/builtins/atomic-write-file.js +46 -0
  81. package/dist/tools/builtins/atomic-write-file.js.map +1 -0
  82. package/dist/tools/builtins/bash.js +2 -2
  83. package/dist/tools/builtins/bash.js.map +1 -1
  84. package/dist/tools/builtins/edit.d.ts +2 -5
  85. package/dist/tools/builtins/edit.d.ts.map +1 -1
  86. package/dist/tools/builtins/edit.js +105 -125
  87. package/dist/tools/builtins/edit.js.map +1 -1
  88. package/dist/tools/builtins/file-mutation-lock.d.ts +7 -0
  89. package/dist/tools/builtins/file-mutation-lock.d.ts.map +1 -0
  90. package/dist/tools/builtins/file-mutation-lock.js +25 -0
  91. package/dist/tools/builtins/file-mutation-lock.js.map +1 -0
  92. package/dist/tools/builtins/index.js +2 -2
  93. package/dist/tools/builtins/index.js.map +1 -1
  94. package/dist/tools/builtins/write-file.d.ts +1 -2
  95. package/dist/tools/builtins/write-file.d.ts.map +1 -1
  96. package/dist/tools/builtins/write-file.js +66 -40
  97. package/dist/tools/builtins/write-file.js.map +1 -1
  98. package/dist/tools/coordinator/__tests__/task-list.test.js +14 -0
  99. package/dist/tools/coordinator/__tests__/task-list.test.js.map +1 -1
  100. package/dist/tools/coordinator/agent.d.ts +6 -8
  101. package/dist/tools/coordinator/agent.d.ts.map +1 -1
  102. package/dist/tools/coordinator/agent.js.map +1 -1
  103. package/dist/tools/coordinator/index.d.ts.map +1 -1
  104. package/dist/tools/coordinator/index.js +11 -32
  105. package/dist/tools/coordinator/index.js.map +1 -1
  106. package/dist/tools/defineTool.d.ts +3 -0
  107. package/dist/tools/defineTool.d.ts.map +1 -1
  108. package/dist/tools/defineTool.js +3 -0
  109. package/dist/tools/defineTool.js.map +1 -1
  110. package/dist/types/provider/chat.d.ts +9 -0
  111. package/dist/types/provider/chat.d.ts.map +1 -1
  112. package/dist/types/provider/error.d.ts +22 -0
  113. package/dist/types/provider/error.d.ts.map +1 -0
  114. package/dist/types/provider/error.js +2 -0
  115. package/dist/types/provider/error.js.map +1 -0
  116. package/dist/types/provider/index.d.ts +1 -0
  117. package/dist/types/provider/index.d.ts.map +1 -1
  118. package/dist/types/run/entity.d.ts +2 -0
  119. package/dist/types/run/entity.d.ts.map +1 -1
  120. package/dist/types/run/events.d.ts +2 -0
  121. package/dist/types/run/events.d.ts.map +1 -1
  122. package/dist/types/run/events.js.map +1 -1
  123. package/dist/types/sandbox/index.d.ts +4 -0
  124. package/dist/types/sandbox/index.d.ts.map +1 -1
  125. package/dist/types/sandbox/index.js.map +1 -1
  126. package/dist/types/tool/index.d.ts +20 -0
  127. package/dist/types/tool/index.d.ts.map +1 -1
  128. package/package.json +2 -1
  129. package/src/compaction/__tests__/verifier-empty-reply.test.ts +96 -0
  130. package/src/compaction/verifier.ts +10 -1
  131. package/src/config/__tests__/compaction-budget-schema.test.ts +114 -0
  132. package/src/config/runtime.ts +20 -11
  133. package/src/manager/run/persistence.ts +3 -1
  134. package/src/provider/__tests__/errors.test.ts +85 -0
  135. package/src/provider/errors.ts +344 -0
  136. package/src/provider/index.ts +15 -0
  137. package/src/public-runtime.ts +53 -10
  138. package/src/registry/tool/execute.test.ts +121 -7
  139. package/src/registry/tool/execute.ts +50 -12
  140. package/src/registry/toolset/catalog.test.ts +118 -0
  141. package/src/registry/toolset/catalog.ts +26 -4
  142. package/src/runtime/query/__tests__/capability-negotiation.test.ts +88 -0
  143. package/src/runtime/query/__tests__/deferred-tools.test.ts +111 -0
  144. package/src/runtime/query/__tests__/long-document-flow.test.ts +12 -12
  145. package/src/runtime/query/__tests__/stream-recovery.test.ts +65 -2
  146. package/src/runtime/query/executor.ts +2 -2
  147. package/src/runtime/query/iteration/index.ts +15 -0
  148. package/src/runtime/query/iteration/phases/compaction-safe-cut.test.ts +186 -0
  149. package/src/runtime/query/iteration/phases/compaction.ts +54 -12
  150. package/src/runtime/query/iteration/stream-turn.ts +11 -6
  151. package/src/runtime/query/result.ts +11 -1
  152. package/src/tools/builtins/__tests__/edit.test.ts +270 -10
  153. package/src/tools/builtins/__tests__/payload-budget.test.ts +40 -20
  154. package/src/tools/builtins/__tests__/write-file.test.ts +52 -13
  155. package/src/tools/builtins/atomic-write-file.ts +58 -0
  156. package/src/tools/builtins/bash.ts +2 -2
  157. package/src/tools/builtins/edit.ts +116 -162
  158. package/src/tools/builtins/file-mutation-lock.ts +27 -0
  159. package/src/tools/builtins/index.ts +2 -2
  160. package/src/tools/builtins/write-file.ts +68 -44
  161. package/src/tools/coordinator/__tests__/task-list.test.ts +16 -0
  162. package/src/tools/coordinator/agent.ts +6 -8
  163. package/src/tools/coordinator/index.ts +11 -34
  164. package/src/tools/defineTool.ts +6 -0
  165. package/src/types/provider/chat.ts +14 -1
  166. package/src/types/provider/error.ts +29 -0
  167. package/src/types/provider/index.ts +5 -0
  168. package/src/types/run/entity.ts +2 -0
  169. package/src/types/run/events.ts +7 -1
  170. package/src/types/sandbox/index.ts +4 -0
  171. package/src/types/tool/index.ts +20 -0
@@ -16,7 +16,7 @@ const inputSchema = z.object({
16
16
  command: z
17
17
  .string()
18
18
  .min(1)
19
- .describe('The bash command to execute. Required, non-empty. Single command per call (use `&&` / `;` chaining for compound commands). Avoid heredocs that span more than a few hundred bytes — large content should be created with `write`, then extended with `edit` insertLine: "end", not piped into bash.'),
19
+ .describe('The bash command to execute. Required, non-empty. Single command per call (use `&&` / `;` chaining for compound commands). Avoid heredocs that span more than a few hundred bytes — create large content with bounded write plus exact marker-advancing edit calls instead.'),
20
20
  timeout: z
21
21
  .preprocess((v) => (typeof v === 'string' ? Number(v) : v), z.number().default(DEFAULT_BASH_TIMEOUT_MS))
22
22
  .describe(`Command timeout in milliseconds. Default: ${DEFAULT_BASH_TIMEOUT_MS}`),
@@ -26,7 +26,7 @@ function isDangerousCommand(command) {
26
26
  }
27
27
  export const BashTool = defineTool({
28
28
  name: 'bash',
29
- description: 'Executes a bash command and returns stdout/stderr output. Command timeout is configurable. The `command` parameter is required — never call this tool with empty arguments. For very long content (e.g. building a large file), prefer `write` for the opening and `edit` with insertLine: "end" for follow-up chunks over a heredoc to avoid hitting the output token limit mid-stream.',
29
+ description: 'Executes a bash command and returns stdout/stderr output. Command timeout is configurable. The `command` parameter is required — never call this tool with empty arguments. For very long content, prefer a bounded write with a deterministic marker followed by exact marker-advancing edit calls over a heredoc.',
30
30
  inputSchema,
31
31
  category: 'shell',
32
32
  permissions: ['shell_execute'],
@@ -1 +1 @@
1
- {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../src/tools/builtins/bash.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../src/tools/builtins/bash.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,7 @@
1
1
  export declare const EditTool: import("../../public-types.js").ToolDefinition<{
2
2
  path: string;
3
+ old_string: string;
4
+ new_string: string;
3
5
  replace_all: boolean;
4
- newStr?: string | undefined;
5
- old_string?: string | undefined;
6
- oldStr?: string | undefined;
7
- new_string?: string | undefined;
8
- insertLine?: string | number | undefined;
9
6
  }>;
10
7
  //# sourceMappingURL=edit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../src/tools/builtins/edit.ts"],"names":[],"mappings":"AAoEA,eAAO,MAAM,QAAQ;;;;;;;;EA4DnB,CAAA"}
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../src/tools/builtins/edit.ts"],"names":[],"mappings":"AAiEA,eAAO,MAAM,QAAQ;;;;;EAwEnB,CAAA"}
@@ -1,167 +1,165 @@
1
- import { readFile, writeFile } from 'node:fs/promises';
1
+ import { readFile } from 'node:fs/promises';
2
2
  import { resolve } from 'node:path';
3
3
  import { z } from 'zod';
4
4
  import { defineTool } from '../defineTool.js';
5
+ import { atomicWriteFile } from './atomic-write-file.js';
6
+ import { withFileMutationLock } from './file-mutation-lock.js';
5
7
  const inputSchema = z
6
8
  .object({
7
- path: z.string().describe('Path to the file to edit'),
8
- old_string: z
9
+ path: z
9
10
  .string()
10
- .optional()
11
- .describe('The exact string to find and replace. Must be unique in the file.'),
12
- oldStr: z
11
+ .refine((value) => value.trim().length > 0, 'Path must not be empty.')
12
+ .describe('Path to the file to edit. Must not be empty.'),
13
+ old_string: z
13
14
  .string()
14
- .optional()
15
- .describe('Alias for old_string. Used by hosts that expose text replacement as oldStr/newStr.'),
15
+ .min(1)
16
+ .describe('The exact unique text to replace, without read-tool line-number prefixes. Must not be empty.'),
16
17
  new_string: z
17
18
  .string()
18
- .optional()
19
- .describe('The replacement string. Self-budget this payload under 12000 characters before calling.'),
20
- newStr: z
21
- .string()
22
- .optional()
23
- .describe('Alias for new_string. Also used as inserted content when insertLine is provided. Self-budget this payload under 12000 characters before calling.'),
24
- insertLine: z
25
- .union([z.coerce.number().int().min(0), z.string().min(1)])
26
- .optional()
27
- .describe('Optional line insertion target. Inserts the replacement after this 1-indexed line; 0 inserts before the first line; "end" appends to the file.'),
19
+ .describe('The exact replacement text. May be empty to delete old_string. Keep this payload under 12000 characters.'),
28
20
  replace_all: z
29
21
  .boolean()
30
22
  .default(false)
31
- .describe('Replace all occurrences instead of just the first unique match'),
23
+ .describe('Replace every occurrence instead of requiring one unique match.'),
32
24
  })
33
- .refine((value) => typeof value.new_string === 'string' || typeof value.newStr === 'string', {
34
- message: 'Either new_string or newStr is required.',
35
- })
36
- .refine((value) => value.insertLine !== undefined ||
37
- typeof value.old_string === 'string' ||
38
- typeof value.oldStr === 'string', { message: 'Either old_string/oldStr or insertLine is required.' });
25
+ .strict();
26
+ const modelInputSchema = {
27
+ type: 'object',
28
+ properties: {
29
+ path: {
30
+ type: 'string',
31
+ description: 'Path to the file to edit. Must not be empty.',
32
+ },
33
+ old_string: {
34
+ type: 'string',
35
+ description: 'Exact unique text from the file, without read-tool line-number prefixes. Must not be empty.',
36
+ },
37
+ new_string: {
38
+ type: 'string',
39
+ description: 'Exact replacement text. May be empty to delete old_string. Keep under 12000 characters.',
40
+ },
41
+ replace_all: {
42
+ type: 'boolean',
43
+ description: 'Replace every occurrence instead of requiring one unique match.',
44
+ },
45
+ },
46
+ required: ['path', 'old_string', 'new_string'],
47
+ additionalProperties: false,
48
+ };
39
49
  export const EditTool = defineTool({
40
50
  name: 'edit',
41
- description: 'Makes targeted edits to a file using exact string find-and-replace or line insertion. THIS IS THE PREFERRED WAY TO MODIFY AN EXISTING FILE never reach for `write` to change a file that already exists, because `write` overwrites the whole body and discards earlier work on partial failure. `edit` keeps the rest of the file byte-for-byte intact and is recoverable: if a single edit fails (old_string/oldStr ambiguous, broader restructuring needed), follow up with another `edit` instead of re-emitting the entire file via `write`. The old_string/oldStr must be unique in the file unless replace_all is true. For insertions, pass insertLine plus new_string/newStr; use insertLine: "end" to extend a file at the end. Self-budget new_string/newStr under 12000 characters before emitting the tool call; use repeated bounded edits for long sections. Preserves file formatting and indentation.',
51
+ description: "Performs one targeted exact-string replacement in an existing file. Pass path + old_string + new_string; old_string must match exactly and be unique unless replace_all is true. Read the file immediately before editing, preserve whitespace and indentation, and never include the read tool's line-number prefix in old_string. To append or insert, replace a unique existing tail/marker with itself plus the new text; advance a deterministic marker such as {{CHUNK_001}} to {{CHUNK_002}} so replaying a completed edit cannot duplicate content. Prefer this tool over rewriting an existing file. Self-budget new_string under 12000 characters.",
42
52
  inputSchema,
53
+ modelInputSchema,
54
+ enforceModelInput: true,
55
+ validationErrorHint: 'Required shape: {"path":"file.md","old_string":"exact unique text","new_string":"replacement text"}. Optional: "replace_all": true.',
43
56
  category: 'filesystem',
44
57
  permissions: ['file_write'],
45
58
  readOnly: false,
46
59
  destructive: false,
47
60
  concurrencySafe: false,
48
61
  async execute(input, context) {
49
- const normalized = normalizeEditInput(input);
50
- if (!normalized.success) {
51
- return { success: false, output: '', error: normalized.error };
62
+ const parsed = inputSchema.safeParse(input);
63
+ if (!parsed.success) {
64
+ return {
65
+ success: false,
66
+ output: '',
67
+ error: `Invalid edit input: ${parsed.error.issues.map((issue) => issue.message).join('; ')}`,
68
+ };
52
69
  }
53
- if (normalized.operation.operation === 'replace' &&
54
- normalized.operation.oldString === normalized.operation.newString) {
70
+ const canonicalInput = parsed.data;
71
+ const replacement = {
72
+ oldString: canonicalInput.old_string,
73
+ newString: canonicalInput.new_string,
74
+ replaceAll: canonicalInput.replace_all,
75
+ };
76
+ if (replacement.oldString === replacement.newString) {
55
77
  return {
56
78
  success: false,
57
79
  output: '',
58
- error: 'old_string/oldStr and new_string/newStr are identical — no change needed',
80
+ error: 'old_string and new_string are identical — no change needed.',
59
81
  };
60
82
  }
61
- // Sandbox-aware: route through sandbox when available
62
- if (context.sandbox) {
63
- const buffer = await context.sandbox.readFile(input.path);
64
- const content = buffer.toString('utf-8');
65
- const result = applyEdit(content, normalized.operation);
66
- if (!result.success) {
67
- return { success: false, output: '', error: result.error };
83
+ const filePath = resolve(context.workingDirectory, canonicalInput.path);
84
+ const lockKey = `${context.sandbox ? 'sandbox' : 'local'}:${filePath}`;
85
+ return withFileMutationLock(lockKey, async () => {
86
+ if (context.sandbox) {
87
+ const buffer = await context.sandbox.readFile(canonicalInput.path);
88
+ const result = applyEdit(buffer.toString('utf-8'), replacement);
89
+ if (!result.success)
90
+ return { success: false, output: '', error: result.error };
91
+ await context.sandbox.writeFile(canonicalInput.path, result.content);
92
+ return {
93
+ success: true,
94
+ output: `Edited ${canonicalInput.path}: ${result.replacements} replacement(s) [sandboxed]`,
95
+ data: {
96
+ path: canonicalInput.path,
97
+ replacements: result.replacements,
98
+ sandboxed: true,
99
+ },
100
+ };
68
101
  }
69
- await context.sandbox.writeFile(input.path, result.content);
102
+ const content = await readFile(filePath, 'utf-8');
103
+ const result = applyEdit(content, replacement);
104
+ if (!result.success)
105
+ return { success: false, output: '', error: result.error };
106
+ await atomicWriteFile(filePath, result.content);
70
107
  return {
71
108
  success: true,
72
- output: `Edited ${input.path}: ${result.replacements} replacement(s) [sandboxed]`,
73
- data: { path: input.path, replacements: result.replacements, sandboxed: true },
109
+ output: `Edited ${filePath}: ${result.replacements} replacement(s)`,
110
+ data: { path: filePath, replacements: result.replacements },
74
111
  };
75
- }
76
- const filePath = resolve(context.workingDirectory, input.path);
77
- const content = await readFile(filePath, 'utf-8');
78
- const result = applyEdit(content, normalized.operation);
79
- if (!result.success) {
80
- return { success: false, output: '', error: result.error };
81
- }
82
- await writeFile(filePath, result.content, 'utf-8');
83
- return {
84
- success: true,
85
- output: `Edited ${filePath}: ${result.replacements} replacement(s)`,
86
- data: { path: filePath, replacements: result.replacements },
87
- };
112
+ });
88
113
  },
89
114
  });
90
- function normalizeEditInput(input) {
91
- const newString = input.new_string ?? input.newStr;
92
- if (typeof newString !== 'string') {
93
- return { success: false, error: 'Either new_string or newStr is required.' };
94
- }
95
- if (input.insertLine !== undefined) {
96
- const insertLine = normalizeInsertLine(input.insertLine);
97
- if (!insertLine.success)
98
- return insertLine;
115
+ function normalizeLineEndings(content, input) {
116
+ const withoutCrlf = content.replaceAll('\r\n', '');
117
+ const usesOnlyCrlf = content.includes('\r\n') && !withoutCrlf.includes('\n');
118
+ if (usesOnlyCrlf) {
99
119
  return {
100
- success: true,
101
- operation: {
102
- operation: 'insert',
103
- insertLine: insertLine.value,
104
- newString,
105
- replace_all: input.replace_all,
106
- },
120
+ ...input,
121
+ oldString: content.includes(input.oldString)
122
+ ? input.oldString
123
+ : input.oldString.replaceAll('\r\n', '\n').replaceAll('\n', '\r\n'),
124
+ newString: input.newString.replaceAll('\r\n', '\n').replaceAll('\n', '\r\n'),
107
125
  };
108
126
  }
109
- const oldString = input.old_string ?? input.oldStr;
110
- if (typeof oldString !== 'string') {
111
- return { success: false, error: 'Either old_string/oldStr or insertLine is required.' };
112
- }
113
- return {
114
- success: true,
115
- operation: {
116
- operation: 'replace',
117
- oldString,
118
- newString,
119
- replace_all: input.replace_all,
120
- },
121
- };
122
- }
123
- function normalizeInsertLine(value) {
124
- if (typeof value === 'string') {
125
- if (value.trim().toLowerCase() === 'end')
126
- return { success: true, value: 'end' };
127
- const parsed = Number(value);
128
- if (Number.isInteger(parsed) && parsed >= 0)
129
- return { success: true, value: parsed };
127
+ const usesOnlyLf = content.includes('\n') && !content.includes('\r\n');
128
+ if (usesOnlyLf) {
130
129
  return {
131
- success: false,
132
- error: 'insertLine must be a non-negative line number or "end".',
130
+ ...input,
131
+ oldString: content.includes(input.oldString)
132
+ ? input.oldString
133
+ : input.oldString.replaceAll('\r\n', '\n'),
134
+ newString: input.newString.replaceAll('\r\n', '\n'),
133
135
  };
134
136
  }
135
- return { success: true, value };
137
+ return input;
136
138
  }
137
- function applyEdit(content, input) {
138
- if (input.operation === 'insert') {
139
- return applyLineInsert(content, input);
140
- }
139
+ function applyEdit(content, rawInput) {
140
+ const input = normalizeLineEndings(content, rawInput);
141
141
  if (!content.includes(input.oldString)) {
142
142
  return {
143
143
  success: false,
144
- error: 'old_string/oldStr not found in file. Make sure the string matches exactly, including whitespace and indentation.',
144
+ error: 'old_string was not found. Read the file again and copy exact text without line-number prefixes.',
145
145
  };
146
146
  }
147
- if (input.replace_all) {
147
+ if (input.replaceAll) {
148
148
  const parts = content.split(input.oldString);
149
- const replacements = parts.length - 1;
150
149
  return {
151
150
  success: true,
152
151
  content: parts.join(input.newString),
153
- replacements,
152
+ replacements: parts.length - 1,
154
153
  };
155
154
  }
156
- // Uniqueness check: old_string/oldStr must appear exactly once
157
155
  const firstIndex = content.indexOf(input.oldString);
158
- const secondIndex = content.indexOf(input.oldString, firstIndex + 1);
156
+ const secondIndex = content.indexOf(input.oldString, firstIndex + input.oldString.length);
159
157
  if (secondIndex !== -1) {
160
- const lineNumber = content.slice(0, firstIndex).split('\n').length;
158
+ const firstLine = content.slice(0, firstIndex).split('\n').length;
161
159
  const secondLine = content.slice(0, secondIndex).split('\n').length;
162
160
  return {
163
161
  success: false,
164
- error: `old_string/oldStr is not unique — found at lines ${lineNumber} and ${secondLine}. Provide more surrounding context to make it unique, or use replace_all: true.`,
162
+ error: `old_string is not unique — found at lines ${firstLine} and ${secondLine}. Include more surrounding context, or use replace_all: true.`,
165
163
  };
166
164
  }
167
165
  return {
@@ -172,22 +170,4 @@ function applyEdit(content, input) {
172
170
  replacements: 1,
173
171
  };
174
172
  }
175
- function applyLineInsert(content, input) {
176
- const hasTrailingNewline = content.endsWith('\n');
177
- const lines = content.split('\n');
178
- if (hasTrailingNewline)
179
- lines.pop();
180
- const line = input.insertLine === 'end'
181
- ? lines.length
182
- : Math.min(Math.max(input.insertLine, 0), lines.length);
183
- const inserted = input.newString.endsWith('\n')
184
- ? input.newString.slice(0, -1).split('\n')
185
- : input.newString.split('\n');
186
- lines.splice(line, 0, ...inserted);
187
- return {
188
- success: true,
189
- content: `${lines.join('\n')}${hasTrailingNewline ? '\n' : ''}`,
190
- replacements: 1,
191
- };
192
- }
193
173
  //# sourceMappingURL=edit.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/tools/builtins/edit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/tools/builtins/edit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Serialize read-modify-write filesystem operations by resolved path within
3
+ * one SDK process. Distributed hosts must still assign one writer per file or
4
+ * provide a storage-level compare-and-swap primitive.
5
+ */
6
+ export declare function withFileMutationLock<T>(key: string, operation: () => Promise<T>): Promise<T>;
7
+ //# sourceMappingURL=file-mutation-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-mutation-lock.d.ts","sourceRoot":"","sources":["../../../src/tools/builtins/file-mutation-lock.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,EAC3C,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAgBZ"}
@@ -0,0 +1,25 @@
1
+ const mutationTails = new Map();
2
+ /**
3
+ * Serialize read-modify-write filesystem operations by resolved path within
4
+ * one SDK process. Distributed hosts must still assign one writer per file or
5
+ * provide a storage-level compare-and-swap primitive.
6
+ */
7
+ export async function withFileMutationLock(key, operation) {
8
+ const previous = mutationTails.get(key) ?? Promise.resolve();
9
+ let release = () => { };
10
+ const current = new Promise((resolve) => {
11
+ release = resolve;
12
+ });
13
+ const tail = previous.then(() => current);
14
+ mutationTails.set(key, tail);
15
+ await previous;
16
+ try {
17
+ return await operation();
18
+ }
19
+ finally {
20
+ release();
21
+ if (mutationTails.get(key) === tail)
22
+ mutationTails.delete(key);
23
+ }
24
+ }
25
+ //# sourceMappingURL=file-mutation-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-mutation-lock.js","sourceRoot":"","sources":["../../../src/tools/builtins/file-mutation-lock.ts"],"names":[],"mappings":"AAAA,MAAM,aAAa,GAAG,IAAI,GAAG,EAAyB,CAAA;AAEtD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACzC,GAAW,EACX,SAA2B;IAE3B,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;IAC5D,IAAI,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;IACtB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAC7C,OAAO,GAAG,OAAO,CAAA;IAClB,CAAC,CAAC,CAAA;IACF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAA;IACzC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAE5B,MAAM,QAAQ,CAAA;IACd,IAAI,CAAC;QACJ,OAAO,MAAM,SAAS,EAAE,CAAA;IACzB,CAAC;YAAS,CAAC;QACV,OAAO,EAAE,CAAA;QACT,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;YAAE,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAC/D,CAAC;AACF,CAAC"}
@@ -24,8 +24,8 @@ import { WriteFileTool } from './write-file.js';
24
24
  // `code.claude.com/docs/en/tools-reference`) does NOT include `LS` —
25
25
  // directory listing is canonical `Bash` + `Glob`. `search_tools` has no
26
26
  // Claude analogue at all. Including these in the defaults gives the model
27
- // tools that look right but degrade alignment. File extension is canonical
28
- // `edit` with `insertLine: "end"` the legacy `Append` tool is gone.
27
+ // tools that look right but degrade alignment. File extension uses canonical
28
+ // exact replacement against a unique tail or deterministic marker.
29
29
  // Hosts that genuinely want LS/search can still register them explicitly.
30
30
  export function getBuiltinTools() {
31
31
  return [BashTool, EditTool, GlobTool, GrepTool, ReadFileTool, VerifyOutputsTool, WriteFileTool];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/builtins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAGjF,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,wEAAwE;AACxE,sEAAsE;AACtE,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,qEAAqE;AACrE,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,sEAAsE;AACtE,0EAA0E;AAE1E,MAAM,UAAU,eAAe;IAC9B,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAA;AAChG,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/builtins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAGjF,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,wEAAwE;AACxE,sEAAsE;AACtE,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,qEAAqE;AACrE,wEAAwE;AACxE,0EAA0E;AAC1E,6EAA6E;AAC7E,mEAAmE;AACnE,0EAA0E;AAE1E,MAAM,UAAU,eAAe;IAC9B,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAA;AAChG,CAAC"}
@@ -1,6 +1,5 @@
1
1
  export declare const WriteFileTool: import("../../types/tool/index.js").ToolDefinition<{
2
2
  path: string;
3
- content?: string | undefined;
4
- newStr?: string | undefined;
3
+ content: string;
5
4
  }>;
6
5
  //# sourceMappingURL=write-file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"write-file.d.ts","sourceRoot":"","sources":["../../../src/tools/builtins/write-file.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,aAAa;;;;EA+CxB,CAAA"}
1
+ {"version":3,"file":"write-file.d.ts","sourceRoot":"","sources":["../../../src/tools/builtins/write-file.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,aAAa;;;EA8DxB,CAAA"}
@@ -1,67 +1,93 @@
1
- import { access, mkdir, writeFile } from 'node:fs/promises';
2
- import { dirname, resolve } from 'node:path';
1
+ import { access } from 'node:fs/promises';
2
+ import { resolve } from 'node:path';
3
3
  import { z } from 'zod';
4
4
  import { defineTool } from '../defineTool.js';
5
+ import { atomicWriteFile } from './atomic-write-file.js';
6
+ import { withFileMutationLock } from './file-mutation-lock.js';
5
7
  const inputSchema = z
6
8
  .object({
7
9
  path: z
8
10
  .string()
9
- .min(1)
10
- .describe('Relative path to the file to write (e.g. "outputs/report.md"). Required. Must be a non-empty string.'),
11
+ .refine((value) => value.trim().length > 0, 'Path must not be empty.')
12
+ .describe('Relative path to the file to write (e.g. "outputs/report.md"). Must not be empty.'),
11
13
  content: z
12
14
  .string()
13
- .optional()
14
- .describe('Full file body to write. Required (use "" only for an intentionally empty file). The file is fully overwritten — pass the COMPLETE intended content for this bounded chunk, not a diff. Self-budget content under 12000 characters before calling; if the intended body is longer, write a smaller opening section here, then use `edit` with insertLine: "end" to extend the file section by section. Do NOT try to chain multiple `write` calls, since each one overwrites the previous.'),
15
- newStr: z
16
- .string()
17
- .optional()
18
- .describe('Alias for content. Useful for hosts that expose create/write operations as newStr. Self-budget this payload under 12000 characters before calling.'),
15
+ .describe('Complete bounded file body. Use "" only for an intentionally empty file. Keep under 12000 characters. For longer documents, include a deterministic marker such as {{CHUNK_001}} and advance it with exact edit calls.'),
19
16
  })
20
- .refine((value) => typeof value.content === 'string' || typeof value.newStr === 'string', {
21
- message: 'Either content or newStr is required.',
22
- });
17
+ .strict();
18
+ const modelInputSchema = {
19
+ type: 'object',
20
+ properties: {
21
+ path: {
22
+ type: 'string',
23
+ description: 'Non-empty path to the file to write.',
24
+ },
25
+ content: {
26
+ type: 'string',
27
+ description: 'Complete bounded file body. May be empty only for an intentionally empty file.',
28
+ },
29
+ },
30
+ required: ['path', 'content'],
31
+ additionalProperties: false,
32
+ };
23
33
  export const WriteFileTool = defineTool({
24
34
  name: 'write',
25
- description: 'Writes a file to the local filesystem. Overwrites the existing file at the path if there is one.\n\n- If the file already exists, you must use the `read` tool on it first in this conversation, or this call will fail.\n- Prefer the `edit` tool for modifying existing files — it only sends the diff and preserves the rest of the file byte-for-byte.\n- Use `write` to create a new file or to perform a deliberate full rewrite of a file you have already read.\n- Self-budget content/newStr under 12000 characters before emitting the tool call. For long content, write a smaller opening section, then use `edit` with insertLine: "end" to extend the file section by section. Do not chain multiple `write` calls each one overwrites the previous.',
35
+ description: 'Writes a complete bounded file body. Pass exactly path + content. If the file exists, read it first; prefer edit for targeted changes. Self-budget content under 12000 characters. For longer documents, write an opening with a deterministic marker such as {{CHUNK_001}}, then use exact edit calls that advance the marker one chunk at a time. Do not chain write calls because each overwrites the file.',
26
36
  inputSchema,
37
+ modelInputSchema,
38
+ enforceModelInput: true,
39
+ validationErrorHint: 'Required shape: {"path":"file.md","content":"complete bounded file body"}.',
27
40
  category: 'filesystem',
28
41
  permissions: ['file_write'],
29
42
  readOnly: false,
30
43
  destructive: true,
31
44
  concurrencySafe: false,
32
45
  async execute(input, context) {
33
- const content = input.content ?? input.newStr ?? '';
34
- // Sandbox-aware: route through sandbox.writeFile() when available
35
- if (context.sandbox) {
36
- const sandboxExists = await sandboxFileExists(context, input.path);
37
- if (sandboxExists) {
38
- const guard = enforceReadBeforeOverwrite(context, input.path);
46
+ const parsed = inputSchema.safeParse(input);
47
+ if (!parsed.success) {
48
+ return {
49
+ success: false,
50
+ output: '',
51
+ error: `Invalid write input: ${parsed.error.issues.map((issue) => issue.message).join('; ')}`,
52
+ };
53
+ }
54
+ const canonicalInput = parsed.data;
55
+ const filePath = resolve(context.workingDirectory, canonicalInput.path);
56
+ const lockKey = `${context.sandbox ? 'sandbox' : 'local'}:${filePath}`;
57
+ return withFileMutationLock(lockKey, async () => {
58
+ if (context.sandbox) {
59
+ const sandboxExists = await sandboxFileExists(context, canonicalInput.path);
60
+ if (sandboxExists) {
61
+ const guard = enforceReadBeforeOverwrite(context, canonicalInput.path);
62
+ if (guard)
63
+ return guard;
64
+ }
65
+ await context.sandbox.writeFile(canonicalInput.path, canonicalInput.content);
66
+ context.fileReadTracker?.recordRead(canonicalInput.path);
67
+ return {
68
+ success: true,
69
+ output: `File written successfully: ${canonicalInput.path} (${canonicalInput.content.length} chars) [sandboxed]`,
70
+ data: {
71
+ path: canonicalInput.path,
72
+ size: canonicalInput.content.length,
73
+ sandboxed: true,
74
+ },
75
+ };
76
+ }
77
+ const localExists = await pathExists(filePath);
78
+ if (localExists) {
79
+ const guard = enforceReadBeforeOverwrite(context, filePath);
39
80
  if (guard)
40
81
  return guard;
41
82
  }
42
- await context.sandbox.writeFile(input.path, content);
43
- context.fileReadTracker?.recordRead(input.path);
83
+ await atomicWriteFile(filePath, canonicalInput.content);
84
+ context.fileReadTracker?.recordRead(filePath);
44
85
  return {
45
86
  success: true,
46
- output: `File written successfully: ${input.path} (${content.length} chars) [sandboxed]`,
47
- data: { path: input.path, size: content.length, sandboxed: true },
87
+ output: `File written successfully: ${filePath} (${canonicalInput.content.length} chars)`,
88
+ data: { path: filePath, size: canonicalInput.content.length },
48
89
  };
49
- }
50
- const filePath = resolve(context.workingDirectory, input.path);
51
- const localExists = await pathExists(filePath);
52
- if (localExists) {
53
- const guard = enforceReadBeforeOverwrite(context, filePath);
54
- if (guard)
55
- return guard;
56
- }
57
- await mkdir(dirname(filePath), { recursive: true });
58
- await writeFile(filePath, content, 'utf-8');
59
- context.fileReadTracker?.recordRead(filePath);
60
- return {
61
- success: true,
62
- output: `File written successfully: ${filePath} (${content.length} chars)`,
63
- data: { path: filePath, size: content.length },
64
- };
90
+ });
65
91
  },
66
92
  });
67
93
  function enforceReadBeforeOverwrite(context, key) {