@hyperspaceng/neural-coding-agent 0.63.0 → 0.63.2

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 (100) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +2 -2
  3. package/dist/core/agent-session.d.ts +9 -6
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +98 -54
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/auth-storage.d.ts +3 -1
  8. package/dist/core/auth-storage.d.ts.map +1 -1
  9. package/dist/core/auth-storage.js +5 -2
  10. package/dist/core/auth-storage.js.map +1 -1
  11. package/dist/core/compaction/branch-summarization.d.ts +2 -0
  12. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  13. package/dist/core/compaction/branch-summarization.js +2 -2
  14. package/dist/core/compaction/branch-summarization.js.map +1 -1
  15. package/dist/core/compaction/compaction.d.ts +3 -3
  16. package/dist/core/compaction/compaction.d.ts.map +1 -1
  17. package/dist/core/compaction/compaction.js +27 -26
  18. package/dist/core/compaction/compaction.js.map +1 -1
  19. package/dist/core/export-html/index.d.ts.map +1 -1
  20. package/dist/core/export-html/index.js +5 -4
  21. package/dist/core/export-html/index.js.map +1 -1
  22. package/dist/core/extensions/types.d.ts +7 -1
  23. package/dist/core/extensions/types.d.ts.map +1 -1
  24. package/dist/core/extensions/types.js.map +1 -1
  25. package/dist/core/model-registry.d.ts +18 -2
  26. package/dist/core/model-registry.d.ts.map +1 -1
  27. package/dist/core/model-registry.js +83 -69
  28. package/dist/core/model-registry.js.map +1 -1
  29. package/dist/core/model-resolver.d.ts.map +1 -1
  30. package/dist/core/model-resolver.js +4 -4
  31. package/dist/core/model-resolver.js.map +1 -1
  32. package/dist/core/package-manager.d.ts.map +1 -1
  33. package/dist/core/package-manager.js +88 -24
  34. package/dist/core/package-manager.js.map +1 -1
  35. package/dist/core/resolve-config-value.d.ts +6 -0
  36. package/dist/core/resolve-config-value.d.ts.map +1 -1
  37. package/dist/core/resolve-config-value.js +37 -5
  38. package/dist/core/resolve-config-value.js.map +1 -1
  39. package/dist/core/sdk.d.ts +1 -1
  40. package/dist/core/sdk.d.ts.map +1 -1
  41. package/dist/core/sdk.js +13 -22
  42. package/dist/core/sdk.js.map +1 -1
  43. package/dist/core/settings-manager.d.ts +2 -0
  44. package/dist/core/settings-manager.d.ts.map +1 -1
  45. package/dist/core/settings-manager.js +3 -0
  46. package/dist/core/settings-manager.js.map +1 -1
  47. package/dist/core/timings.d.ts +1 -0
  48. package/dist/core/timings.d.ts.map +1 -1
  49. package/dist/core/timings.js +6 -0
  50. package/dist/core/timings.js.map +1 -1
  51. package/dist/core/tools/edit-diff.d.ts +23 -1
  52. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  53. package/dist/core/tools/edit-diff.js +150 -57
  54. package/dist/core/tools/edit-diff.js.map +1 -1
  55. package/dist/core/tools/edit.d.ts +18 -6
  56. package/dist/core/tools/edit.d.ts.map +1 -1
  57. package/dist/core/tools/edit.js +108 -59
  58. package/dist/core/tools/edit.js.map +1 -1
  59. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  60. package/dist/core/tools/file-mutation-queue.js +4 -4
  61. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  62. package/dist/core/tools/index.d.ts +12 -4
  63. package/dist/core/tools/index.d.ts.map +1 -1
  64. package/dist/main.d.ts.map +1 -1
  65. package/dist/main.js +28 -10
  66. package/dist/main.js.map +1 -1
  67. package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
  68. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  69. package/dist/modes/interactive/components/bash-execution.js +18 -5
  70. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  71. package/dist/modes/interactive/components/tool-execution.d.ts +0 -1
  72. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  73. package/dist/modes/interactive/components/tool-execution.js +2 -7
  74. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  75. package/dist/modes/interactive/interactive-mode.d.ts +0 -1
  76. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  77. package/dist/modes/interactive/interactive-mode.js +28 -65
  78. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  79. package/dist/modes/print-mode.d.ts +1 -1
  80. package/dist/modes/print-mode.d.ts.map +1 -1
  81. package/dist/modes/print-mode.js +83 -71
  82. package/dist/modes/print-mode.js.map +1 -1
  83. package/docs/development.md +3 -1
  84. package/docs/extensions.md +13 -2
  85. package/docs/models.md +6 -0
  86. package/docs/rpc.md +11 -2
  87. package/docs/settings.md +12 -0
  88. package/docs/skills.md +3 -2
  89. package/examples/extensions/custom-compaction.ts +17 -4
  90. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  91. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  92. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  93. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  94. package/examples/extensions/handoff.ts +5 -2
  95. package/examples/extensions/qna.ts +5 -2
  96. package/examples/extensions/summarize.ts +15 -4
  97. package/examples/extensions/trigger-compact.ts +11 -1
  98. package/examples/extensions/with-deps/package-lock.json +2 -2
  99. package/examples/extensions/with-deps/package.json +1 -1
  100. package/package.json +5 -4
@@ -3,21 +3,88 @@ import { Type } from "@sinclair/typebox";
3
3
  import { constants } from "fs";
4
4
  import { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from "fs/promises";
5
5
  import { renderDiff } from "../../modes/interactive/components/diff.js";
6
- import { computeEditDiff, detectLineEnding, fuzzyFindText, generateDiffString, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
6
+ import { applyEditsToNormalizedContent, computeEditsDiff, detectLineEnding, generateDiffString, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
7
7
  import { withFileMutationQueue } from "./file-mutation-queue.js";
8
8
  import { resolveToCwd } from "./path-utils.js";
9
9
  import { invalidArgText, shortenPath, str } from "./render-utils.js";
10
10
  import { wrapToolDefinition } from "./tool-definition-wrapper.js";
11
+ const replaceEditSchema = Type.Object({
12
+ oldText: Type.String({
13
+ description: "Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call.",
14
+ }),
15
+ newText: Type.String({ description: "Replacement text for this targeted edit." }),
16
+ }, { additionalProperties: false });
11
17
  const editSchema = Type.Object({
12
18
  path: Type.String({ description: "Path to the file to edit (relative or absolute)" }),
13
- oldText: Type.String({ description: "Exact text to find and replace (must match exactly)" }),
14
- newText: Type.String({ description: "New text to replace the old text with" }),
15
- });
19
+ oldText: Type.Optional(Type.String({
20
+ description: "Exact text to replace for one contiguous change. Include only enough surrounding context to make the match unique. Do not use this to cover multiple distant changes in one large block.",
21
+ })),
22
+ newText: Type.Optional(Type.String({
23
+ description: "Replacement text for oldText in single-replacement mode.",
24
+ })),
25
+ edits: Type.Optional(Type.Array(replaceEditSchema, {
26
+ description: "Use this when changing multiple separate, disjoint regions in the same file. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead.",
27
+ })),
28
+ }, { additionalProperties: false });
16
29
  const defaultEditOperations = {
17
30
  readFile: (path) => fsReadFile(path),
18
31
  writeFile: (path, content) => fsWriteFile(path, content, "utf-8"),
19
32
  access: (path) => fsAccess(path, constants.R_OK | constants.W_OK),
20
33
  };
34
+ function getMultiReplaceModeInput(input) {
35
+ if (input.edits === undefined)
36
+ return null;
37
+ if (input.oldText !== undefined || input.newText !== undefined) {
38
+ throw new Error("Edit tool input is invalid. Use either edits or single replacement mode, not both.");
39
+ }
40
+ if (input.edits.length === 0) {
41
+ throw new Error("Edit tool input is invalid. edits must contain at least one replacement.");
42
+ }
43
+ return { path: input.path, edits: input.edits };
44
+ }
45
+ function getReplaceModeInput(input) {
46
+ const { oldText, newText } = input;
47
+ if (oldText === undefined && newText === undefined)
48
+ return null;
49
+ if (input.edits !== undefined) {
50
+ throw new Error("Edit tool input is invalid. Use either single replacement mode or edits mode, not both.");
51
+ }
52
+ if (oldText === undefined || newText === undefined) {
53
+ throw new Error("Edit tool input is invalid. Single replacement mode requires both oldText and newText.");
54
+ }
55
+ return { path: input.path, oldText, newText };
56
+ }
57
+ function normalizeEditInput(input) {
58
+ const multiReplaceModeInput = getMultiReplaceModeInput(input);
59
+ if (multiReplaceModeInput) {
60
+ return { path: multiReplaceModeInput.path, edits: multiReplaceModeInput.edits, mode: "multi" };
61
+ }
62
+ const replaceModeInput = getReplaceModeInput(input);
63
+ if (replaceModeInput) {
64
+ return {
65
+ path: replaceModeInput.path,
66
+ edits: [{ oldText: replaceModeInput.oldText, newText: replaceModeInput.newText }],
67
+ mode: "single",
68
+ };
69
+ }
70
+ throw new Error("Edit tool input is invalid. Provide either oldText and newText, or edits.");
71
+ }
72
+ function getRenderablePreviewInput(args) {
73
+ if (!args || typeof args.path !== "string") {
74
+ return null;
75
+ }
76
+ if (args.oldText === undefined &&
77
+ args.newText === undefined &&
78
+ Array.isArray(args.edits) &&
79
+ args.edits.length > 0 &&
80
+ args.edits.every((edit) => typeof edit?.oldText === "string" && typeof edit?.newText === "string")) {
81
+ return { path: args.path, edits: args.edits };
82
+ }
83
+ if (typeof args.oldText === "string" && typeof args.newText === "string" && args.edits === undefined) {
84
+ return { path: args.path, edits: [{ oldText: args.oldText, newText: args.newText }] };
85
+ }
86
+ return null;
87
+ }
21
88
  function formatEditCall(args, state, theme) {
22
89
  const invalidArg = invalidArgText(theme);
23
90
  const rawPath = str(args?.file_path ?? args?.path);
@@ -41,7 +108,14 @@ function formatEditResult(args, state, result, theme, isError) {
41
108
  .filter((c) => c.type === "text")
42
109
  .map((c) => c.text || "")
43
110
  .join("\n");
44
- return errorText ? `\n${theme.fg("error", errorText)}` : undefined;
111
+ let previewError;
112
+ if (state.preview && "error" in state.preview) {
113
+ previewError = state.preview.error;
114
+ }
115
+ if (!errorText || errorText === previewError) {
116
+ return undefined;
117
+ }
118
+ return `\n${theme.fg("error", errorText)}`;
45
119
  }
46
120
  const previewDiff = state.preview && !("error" in state.preview) ? state.preview.diff : undefined;
47
121
  const resultDiff = result.details?.diff;
@@ -55,11 +129,17 @@ export function createEditToolDefinition(cwd, options) {
55
129
  return {
56
130
  name: "edit",
57
131
  label: "edit",
58
- description: "Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.",
59
- promptSnippet: "Make surgical edits to files (find exact text and replace)",
60
- promptGuidelines: ["Use edit for precise changes (old text must match exactly)."],
132
+ description: "Edit a single file using exact text replacement. Use oldText/newText only for one contiguous replacement. Use edits when changing multiple separate, disjoint regions in the same file. In edits mode, every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes. Do not provide both modes at once.",
133
+ promptSnippet: "Make precise file edits with exact text replacement, including multiple disjoint edits in one call",
134
+ promptGuidelines: [
135
+ "Use edit for precise changes (old text must match exactly)",
136
+ "When changing multiple separate locations in one file, use one edit call with edits[] instead of multiple edit calls",
137
+ "Each edits[].oldText is matched against the original file, not after earlier edits are applied. Do not emit overlapping or nested edits. Merge nearby changes into one edit.",
138
+ "Keep oldText as small as possible while still being unique in the file. Do not pad with large unchanged regions.",
139
+ ],
61
140
  parameters: editSchema,
62
- async execute(_toolCallId, { path, oldText, newText }, signal, _onUpdate, _ctx) {
141
+ async execute(_toolCallId, input, signal, _onUpdate, _ctx) {
142
+ const { path, edits, mode } = normalizeEditInput(input);
63
143
  const absolutePath = resolveToCwd(path, cwd);
64
144
  return withFileMutationQueue(absolutePath, () => new Promise((resolve, reject) => {
65
145
  // Check if already aborted.
@@ -77,7 +157,7 @@ export function createEditToolDefinition(cwd, options) {
77
157
  signal.addEventListener("abort", onAbort, { once: true });
78
158
  }
79
159
  // Perform the edit operation.
80
- (async () => {
160
+ void (async () => {
81
161
  try {
82
162
  // Check if file exists.
83
163
  try {
@@ -105,46 +185,11 @@ export function createEditToolDefinition(cwd, options) {
105
185
  const { bom, text: content } = stripBom(rawContent);
106
186
  const originalEnding = detectLineEnding(content);
107
187
  const normalizedContent = normalizeToLF(content);
108
- const normalizedOldText = normalizeToLF(oldText);
109
- const normalizedNewText = normalizeToLF(newText);
110
- // Find the old text using fuzzy matching. This tries exact match first, then a normalized fallback.
111
- const matchResult = fuzzyFindText(normalizedContent, normalizedOldText);
112
- if (!matchResult.found) {
113
- if (signal) {
114
- signal.removeEventListener("abort", onAbort);
115
- }
116
- reject(new Error(`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`));
117
- return;
118
- }
119
- // Count occurrences using fuzzy-normalized content for consistency with the matcher.
120
- const fuzzyContent = normalizeForFuzzyMatch(normalizedContent);
121
- const fuzzyOldText = normalizeForFuzzyMatch(normalizedOldText);
122
- const occurrences = fuzzyContent.split(fuzzyOldText).length - 1;
123
- if (occurrences > 1) {
124
- if (signal) {
125
- signal.removeEventListener("abort", onAbort);
126
- }
127
- reject(new Error(`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`));
128
- return;
129
- }
188
+ const { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);
130
189
  // Check if aborted before writing.
131
190
  if (aborted) {
132
191
  return;
133
192
  }
134
- // Perform replacement using the matched text position.
135
- // When fuzzy matching was used, contentForReplacement is the normalized version.
136
- const baseContent = matchResult.contentForReplacement;
137
- const newContent = baseContent.substring(0, matchResult.index) +
138
- normalizedNewText +
139
- baseContent.substring(matchResult.index + matchResult.matchLength);
140
- // Verify the replacement actually changed something.
141
- if (baseContent === newContent) {
142
- if (signal) {
143
- signal.removeEventListener("abort", onAbort);
144
- }
145
- reject(new Error(`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`));
146
- return;
147
- }
148
193
  const finalContent = bom + restoreLineEndings(newContent, originalEnding);
149
194
  await ops.writeFile(absolutePath, finalContent);
150
195
  // Check if aborted after writing.
@@ -160,7 +205,9 @@ export function createEditToolDefinition(cwd, options) {
160
205
  content: [
161
206
  {
162
207
  type: "text",
163
- text: `Successfully replaced text in ${path}.`,
208
+ text: mode === "single"
209
+ ? `Successfully replaced text in ${path}.`
210
+ : `Successfully replaced ${edits.length} block(s) in ${path}.`,
164
211
  },
165
212
  ],
166
213
  details: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },
@@ -172,24 +219,26 @@ export function createEditToolDefinition(cwd, options) {
172
219
  signal.removeEventListener("abort", onAbort);
173
220
  }
174
221
  if (!aborted) {
175
- reject(error);
222
+ reject(error instanceof Error ? error : new Error(String(error)));
176
223
  }
177
224
  }
178
225
  })();
179
226
  }));
180
227
  },
181
228
  renderCall(args, theme, context) {
182
- const isSingleMode = typeof args?.path === "string" && typeof args?.oldText === "string" && typeof args?.newText === "string";
183
- if (context.argsComplete && isSingleMode) {
184
- const argsKey = JSON.stringify({ path: args.path, oldText: args.oldText, newText: args.newText });
185
- if (context.state.argsKey !== argsKey) {
186
- context.state.argsKey = argsKey;
187
- computeEditDiff(args.path, args.oldText, args.newText, context.cwd).then((preview) => {
188
- if (context.state.argsKey === argsKey) {
189
- context.state.preview = preview;
190
- context.invalidate();
191
- }
192
- });
229
+ if (context.argsComplete) {
230
+ const previewInput = getRenderablePreviewInput(args);
231
+ if (previewInput) {
232
+ const argsKey = JSON.stringify({ path: previewInput.path, edits: previewInput.edits });
233
+ if (context.state.argsKey !== argsKey) {
234
+ context.state.argsKey = argsKey;
235
+ computeEditsDiff(previewInput.path, previewInput.edits, context.cwd).then((preview) => {
236
+ if (context.state.argsKey === argsKey) {
237
+ context.state.preview = preview;
238
+ context.invalidate();
239
+ }
240
+ });
241
+ }
193
242
  }
194
243
  }
195
244
  const text = context.lastComponent ?? new Text("", 0, 0);
@@ -1 +1 @@
1
- {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@hyperspaceng/neural-agent-core\";\nimport { Container, Text } from \"@hyperspaceng/neural-tui\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { renderDiff } from \"../../modes/interactive/components/diff.js\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport {\n\tcomputeEditDiff,\n\tdetectLineEnding,\n\ttype EditDiffError,\n\ttype EditDiffResult,\n\tfuzzyFindText,\n\tgenerateDiffString,\n\tnormalizeForFuzzyMatch,\n\tnormalizeToLF,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.js\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\n\ntype EditRenderState = {\n\targsKey?: string;\n\tpreview?: EditDiffResult | EditDiffError;\n};\n\nconst editSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\toldText: Type.String({ description: \"Exact text to find and replace (must match exactly)\" }),\n\tnewText: Type.String({ description: \"New text to replace the old text with\" }),\n});\n\nexport type EditToolInput = Static<typeof editSchema>;\n\nexport interface EditToolDetails {\n\t/** Unified diff of the changes made */\n\tdiff: string;\n\t/** Line number of the first change in the new file (for editor navigation) */\n\tfirstChangedLine?: number;\n}\n\n/**\n * Pluggable operations for the edit tool.\n * Override these to delegate file editing to remote systems (for example SSH).\n */\nexport interface EditOperations {\n\t/** Read file contents as a Buffer */\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\t/** Write content to a file */\n\twriteFile: (absolutePath: string, content: string) => Promise<void>;\n\t/** Check if file is readable and writable (throw if not) */\n\taccess: (absolutePath: string) => Promise<void>;\n}\n\nconst defaultEditOperations: EditOperations = {\n\treadFile: (path) => fsReadFile(path),\n\twriteFile: (path, content) => fsWriteFile(path, content, \"utf-8\"),\n\taccess: (path) => fsAccess(path, constants.R_OK | constants.W_OK),\n};\n\nexport interface EditToolOptions {\n\t/** Custom operations for file editing. Default: local filesystem */\n\toperations?: EditOperations;\n}\n\nfunction formatEditCall(\n\targs: { path?: string; file_path?: string; oldText?: string; newText?: string } | undefined,\n\tstate: EditRenderState,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst invalidArg = invalidArgText(theme);\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath) : null;\n\tconst pathDisplay = path === null ? invalidArg : path ? theme.fg(\"accent\", path) : theme.fg(\"toolOutput\", \"...\");\n\tlet text = `${theme.fg(\"toolTitle\", theme.bold(\"edit\"))} ${pathDisplay}`;\n\n\tif (state.preview) {\n\t\tif (\"error\" in state.preview) {\n\t\t\ttext += `\\n\\n${theme.fg(\"error\", state.preview.error)}`;\n\t\t} else if (state.preview.diff) {\n\t\t\ttext += `\\n\\n${renderDiff(state.preview.diff, { filePath: rawPath ?? undefined })}`;\n\t\t}\n\t}\n\n\treturn text;\n}\n\nfunction formatEditResult(\n\targs: { path?: string; file_path?: string; oldText?: string; newText?: string } | undefined,\n\tstate: EditRenderState,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: EditToolDetails;\n\t},\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tisError: boolean,\n): string | undefined {\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tif (isError) {\n\t\tconst errorText = result.content\n\t\t\t.filter((c) => c.type === \"text\")\n\t\t\t.map((c) => c.text || \"\")\n\t\t\t.join(\"\\n\");\n\t\treturn errorText ? `\\n${theme.fg(\"error\", errorText)}` : undefined;\n\t}\n\n\tconst previewDiff = state.preview && !(\"error\" in state.preview) ? state.preview.diff : undefined;\n\tconst resultDiff = result.details?.diff;\n\tif (!resultDiff || resultDiff === previewDiff) {\n\t\treturn undefined;\n\t}\n\treturn `\\n${renderDiff(resultDiff, { filePath: rawPath ?? undefined })}`;\n}\n\nexport function createEditToolDefinition(\n\tcwd: string,\n\toptions?: EditToolOptions,\n): ToolDefinition<typeof editSchema, EditToolDetails | undefined, EditRenderState> {\n\tconst ops = options?.operations ?? defaultEditOperations;\n\treturn {\n\t\tname: \"edit\",\n\t\tlabel: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.\",\n\t\tpromptSnippet: \"Make surgical edits to files (find exact text and replace)\",\n\t\tpromptGuidelines: [\"Use edit for precise changes (old text must match exactly).\"],\n\t\tparameters: editSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ path, oldText, newText }: { path: string; oldText: string; newText: string },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\tconst absolutePath = resolveToCwd(path, cwd);\n\n\t\t\treturn withFileMutationQueue(\n\t\t\t\tabsolutePath,\n\t\t\t\t() =>\n\t\t\t\t\tnew Promise<{\n\t\t\t\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\t\t\t\tdetails: EditToolDetails | undefined;\n\t\t\t\t\t}>((resolve, reject) => {\n\t\t\t\t\t\t// Check if already aborted.\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet aborted = false;\n\n\t\t\t\t\t\t// Set up abort handler.\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Perform the edit operation.\n\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Check if file exists.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treject(new Error(`File not found: ${path}`));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Check if aborted before reading.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Read the file.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tconst rawContent = buffer.toString(\"utf-8\");\n\n\t\t\t\t\t\t\t\t// Check if aborted after reading.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Strip BOM before matching. The model will not include an invisible BOM in oldText.\n\t\t\t\t\t\t\t\tconst { bom, text: content } = stripBom(rawContent);\n\n\t\t\t\t\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\t\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\t\t\t\t\tconst normalizedOldText = normalizeToLF(oldText);\n\t\t\t\t\t\t\t\tconst normalizedNewText = normalizeToLF(newText);\n\n\t\t\t\t\t\t\t\t// Find the old text using fuzzy matching. This tries exact match first, then a normalized fallback.\n\t\t\t\t\t\t\t\tconst matchResult = fuzzyFindText(normalizedContent, normalizedOldText);\n\n\t\t\t\t\t\t\t\tif (!matchResult.found) {\n\t\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\t`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Count occurrences using fuzzy-normalized content for consistency with the matcher.\n\t\t\t\t\t\t\t\tconst fuzzyContent = normalizeForFuzzyMatch(normalizedContent);\n\t\t\t\t\t\t\t\tconst fuzzyOldText = normalizeForFuzzyMatch(normalizedOldText);\n\t\t\t\t\t\t\t\tconst occurrences = fuzzyContent.split(fuzzyOldText).length - 1;\n\n\t\t\t\t\t\t\t\tif (occurrences > 1) {\n\t\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\t`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Check if aborted before writing.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Perform replacement using the matched text position.\n\t\t\t\t\t\t\t\t// When fuzzy matching was used, contentForReplacement is the normalized version.\n\t\t\t\t\t\t\t\tconst baseContent = matchResult.contentForReplacement;\n\t\t\t\t\t\t\t\tconst newContent =\n\t\t\t\t\t\t\t\t\tbaseContent.substring(0, matchResult.index) +\n\t\t\t\t\t\t\t\t\tnormalizedNewText +\n\t\t\t\t\t\t\t\t\tbaseContent.substring(matchResult.index + matchResult.matchLength);\n\n\t\t\t\t\t\t\t\t// Verify the replacement actually changed something.\n\t\t\t\t\t\t\t\tif (baseContent === newContent) {\n\t\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\t`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`,\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\t\t\t\t\tawait ops.writeFile(absolutePath, finalContent);\n\n\t\t\t\t\t\t\t\t// Check if aborted after writing.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Clean up abort handler.\n\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\t\ttext: `Successfully replaced text in ${path}.`,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tdetails: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\t\t\t// Clean up abort handler.\n\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})();\n\t\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst isSingleMode =\n\t\t\t\ttypeof args?.path === \"string\" && typeof args?.oldText === \"string\" && typeof args?.newText === \"string\";\n\t\t\tif (context.argsComplete && isSingleMode) {\n\t\t\t\tconst argsKey = JSON.stringify({ path: args.path, oldText: args.oldText, newText: args.newText });\n\t\t\t\tif (context.state.argsKey !== argsKey) {\n\t\t\t\t\tcontext.state.argsKey = argsKey;\n\t\t\t\t\tcomputeEditDiff(args.path!, args.oldText!, args.newText!, context.cwd).then((preview) => {\n\t\t\t\t\t\tif (context.state.argsKey === argsKey) {\n\t\t\t\t\t\t\tcontext.state.preview = preview;\n\t\t\t\t\t\t\tcontext.invalidate();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatEditCall(args, context.state, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, _options, theme, context) {\n\t\t\tconst output = formatEditResult(context.args, context.state, result as any, theme, context.isError);\n\t\t\tif (!output) {\n\t\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\t\tcomponent.clear();\n\t\t\t\treturn component;\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(output);\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createEditTool(cwd: string, options?: EditToolOptions): AgentTool<typeof editSchema> {\n\treturn wrapToolDefinition(createEditToolDefinition(cwd, options));\n}\n\n/** Default edit tool using process.cwd() for backwards compatibility. */\nexport const editToolDefinition = createEditToolDefinition(process.cwd());\nexport const editTool = createEditTool(process.cwd());\n"]}
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@hyperspaceng/neural-agent-core\";\nimport { Container, Text } from \"@hyperspaceng/neural-tui\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { renderDiff } from \"../../modes/interactive/components/diff.js\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport {\n\tapplyEditsToNormalizedContent,\n\tcomputeEditsDiff,\n\tdetectLineEnding,\n\ttype EditDiffError,\n\ttype EditDiffResult,\n\tgenerateDiffString,\n\tnormalizeToLF,\n\ttype ReplaceEdit,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.js\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\n\ntype EditRenderState = {\n\targsKey?: string;\n\tpreview?: EditDiffResult | EditDiffError;\n};\n\nconst replaceEditSchema = Type.Object(\n\t{\n\t\toldText: Type.String({\n\t\t\tdescription:\n\t\t\t\t\"Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call.\",\n\t\t}),\n\t\tnewText: Type.String({ description: \"Replacement text for this targeted edit.\" }),\n\t},\n\t{ additionalProperties: false },\n);\n\nconst editSchema = Type.Object(\n\t{\n\t\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\t\toldText: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Exact text to replace for one contiguous change. Include only enough surrounding context to make the match unique. Do not use this to cover multiple distant changes in one large block.\",\n\t\t\t}),\n\t\t),\n\t\tnewText: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdescription: \"Replacement text for oldText in single-replacement mode.\",\n\t\t\t}),\n\t\t),\n\t\tedits: Type.Optional(\n\t\t\tType.Array(replaceEditSchema, {\n\t\t\t\tdescription:\n\t\t\t\t\t\"Use this when changing multiple separate, disjoint regions in the same file. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead.\",\n\t\t\t}),\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type EditToolInput = Static<typeof editSchema>;\n\ninterface ReplaceModeInput {\n\tpath: string;\n\toldText: string;\n\tnewText: string;\n}\n\ninterface MultiReplaceModeInput {\n\tpath: string;\n\tedits: ReplaceEdit[];\n}\n\ninterface NormalizedEditInput {\n\tpath: string;\n\tedits: ReplaceEdit[];\n\tmode: \"single\" | \"multi\";\n}\n\nexport interface EditToolDetails {\n\t/** Unified diff of the changes made */\n\tdiff: string;\n\t/** Line number of the first change in the new file (for editor navigation) */\n\tfirstChangedLine?: number;\n}\n\n/**\n * Pluggable operations for the edit tool.\n * Override these to delegate file editing to remote systems (for example SSH).\n */\nexport interface EditOperations {\n\t/** Read file contents as a Buffer */\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\t/** Write content to a file */\n\twriteFile: (absolutePath: string, content: string) => Promise<void>;\n\t/** Check if file is readable and writable (throw if not) */\n\taccess: (absolutePath: string) => Promise<void>;\n}\n\nconst defaultEditOperations: EditOperations = {\n\treadFile: (path) => fsReadFile(path),\n\twriteFile: (path, content) => fsWriteFile(path, content, \"utf-8\"),\n\taccess: (path) => fsAccess(path, constants.R_OK | constants.W_OK),\n};\n\nexport interface EditToolOptions {\n\t/** Custom operations for file editing. Default: local filesystem */\n\toperations?: EditOperations;\n}\n\nfunction getMultiReplaceModeInput(input: EditToolInput): MultiReplaceModeInput | null {\n\tif (input.edits === undefined) return null;\n\tif (input.oldText !== undefined || input.newText !== undefined) {\n\t\tthrow new Error(\"Edit tool input is invalid. Use either edits or single replacement mode, not both.\");\n\t}\n\tif (input.edits.length === 0) {\n\t\tthrow new Error(\"Edit tool input is invalid. edits must contain at least one replacement.\");\n\t}\n\treturn { path: input.path, edits: input.edits };\n}\n\nfunction getReplaceModeInput(input: EditToolInput): ReplaceModeInput | null {\n\tconst { oldText, newText } = input;\n\tif (oldText === undefined && newText === undefined) return null;\n\tif (input.edits !== undefined) {\n\t\tthrow new Error(\"Edit tool input is invalid. Use either single replacement mode or edits mode, not both.\");\n\t}\n\tif (oldText === undefined || newText === undefined) {\n\t\tthrow new Error(\"Edit tool input is invalid. Single replacement mode requires both oldText and newText.\");\n\t}\n\treturn { path: input.path, oldText, newText };\n}\n\nfunction normalizeEditInput(input: EditToolInput): NormalizedEditInput {\n\tconst multiReplaceModeInput = getMultiReplaceModeInput(input);\n\tif (multiReplaceModeInput) {\n\t\treturn { path: multiReplaceModeInput.path, edits: multiReplaceModeInput.edits, mode: \"multi\" };\n\t}\n\n\tconst replaceModeInput = getReplaceModeInput(input);\n\tif (replaceModeInput) {\n\t\treturn {\n\t\t\tpath: replaceModeInput.path,\n\t\t\tedits: [{ oldText: replaceModeInput.oldText, newText: replaceModeInput.newText }],\n\t\t\tmode: \"single\",\n\t\t};\n\t}\n\n\tthrow new Error(\"Edit tool input is invalid. Provide either oldText and newText, or edits.\");\n}\n\nfunction getRenderablePreviewInput(\n\targs: { path?: string; oldText?: string; newText?: string; edits?: ReplaceEdit[] } | undefined,\n): { path: string; edits: ReplaceEdit[] } | null {\n\tif (!args || typeof args.path !== \"string\") {\n\t\treturn null;\n\t}\n\n\tif (\n\t\targs.oldText === undefined &&\n\t\targs.newText === undefined &&\n\t\tArray.isArray(args.edits) &&\n\t\targs.edits.length > 0 &&\n\t\targs.edits.every((edit) => typeof edit?.oldText === \"string\" && typeof edit?.newText === \"string\")\n\t) {\n\t\treturn { path: args.path, edits: args.edits };\n\t}\n\n\tif (typeof args.oldText === \"string\" && typeof args.newText === \"string\" && args.edits === undefined) {\n\t\treturn { path: args.path, edits: [{ oldText: args.oldText, newText: args.newText }] };\n\t}\n\n\treturn null;\n}\n\nfunction formatEditCall(\n\targs: { path?: string; file_path?: string; oldText?: string; newText?: string; edits?: ReplaceEdit[] } | undefined,\n\tstate: EditRenderState,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst invalidArg = invalidArgText(theme);\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath) : null;\n\tconst pathDisplay = path === null ? invalidArg : path ? theme.fg(\"accent\", path) : theme.fg(\"toolOutput\", \"...\");\n\tlet text = `${theme.fg(\"toolTitle\", theme.bold(\"edit\"))} ${pathDisplay}`;\n\n\tif (state.preview) {\n\t\tif (\"error\" in state.preview) {\n\t\t\ttext += `\\n\\n${theme.fg(\"error\", state.preview.error)}`;\n\t\t} else if (state.preview.diff) {\n\t\t\ttext += `\\n\\n${renderDiff(state.preview.diff, { filePath: rawPath ?? undefined })}`;\n\t\t}\n\t}\n\n\treturn text;\n}\n\nfunction formatEditResult(\n\targs: { path?: string; file_path?: string; oldText?: string; newText?: string; edits?: ReplaceEdit[] } | undefined,\n\tstate: EditRenderState,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: EditToolDetails;\n\t},\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tisError: boolean,\n): string | undefined {\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tif (isError) {\n\t\tconst errorText = result.content\n\t\t\t.filter((c) => c.type === \"text\")\n\t\t\t.map((c) => c.text || \"\")\n\t\t\t.join(\"\\n\");\n\t\tlet previewError: string | undefined;\n\t\tif (state.preview && \"error\" in state.preview) {\n\t\t\tpreviewError = state.preview.error;\n\t\t}\n\t\tif (!errorText || errorText === previewError) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn `\\n${theme.fg(\"error\", errorText)}`;\n\t}\n\n\tconst previewDiff = state.preview && !(\"error\" in state.preview) ? state.preview.diff : undefined;\n\tconst resultDiff = result.details?.diff;\n\tif (!resultDiff || resultDiff === previewDiff) {\n\t\treturn undefined;\n\t}\n\treturn `\\n${renderDiff(resultDiff, { filePath: rawPath ?? undefined })}`;\n}\n\nexport function createEditToolDefinition(\n\tcwd: string,\n\toptions?: EditToolOptions,\n): ToolDefinition<typeof editSchema, EditToolDetails | undefined, EditRenderState> {\n\tconst ops = options?.operations ?? defaultEditOperations;\n\treturn {\n\t\tname: \"edit\",\n\t\tlabel: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a single file using exact text replacement. Use oldText/newText only for one contiguous replacement. Use edits when changing multiple separate, disjoint regions in the same file. In edits mode, every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes. Do not provide both modes at once.\",\n\t\tpromptSnippet:\n\t\t\t\"Make precise file edits with exact text replacement, including multiple disjoint edits in one call\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use edit for precise changes (old text must match exactly)\",\n\t\t\t\"When changing multiple separate locations in one file, use one edit call with edits[] instead of multiple edit calls\",\n\t\t\t\"Each edits[].oldText is matched against the original file, not after earlier edits are applied. Do not emit overlapping or nested edits. Merge nearby changes into one edit.\",\n\t\t\t\"Keep oldText as small as possible while still being unique in the file. Do not pad with large unchanged regions.\",\n\t\t],\n\t\tparameters: editSchema,\n\t\tasync execute(_toolCallId, input: EditToolInput, signal?: AbortSignal, _onUpdate?, _ctx?) {\n\t\t\tconst { path, edits, mode } = normalizeEditInput(input);\n\t\t\tconst absolutePath = resolveToCwd(path, cwd);\n\n\t\t\treturn withFileMutationQueue(\n\t\t\t\tabsolutePath,\n\t\t\t\t() =>\n\t\t\t\t\tnew Promise<{\n\t\t\t\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\t\t\t\tdetails: EditToolDetails | undefined;\n\t\t\t\t\t}>((resolve, reject) => {\n\t\t\t\t\t\t// Check if already aborted.\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet aborted = false;\n\n\t\t\t\t\t\t// Set up abort handler.\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Perform the edit operation.\n\t\t\t\t\t\tvoid (async () => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Check if file exists.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treject(new Error(`File not found: ${path}`));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Check if aborted before reading.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Read the file.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tconst rawContent = buffer.toString(\"utf-8\");\n\n\t\t\t\t\t\t\t\t// Check if aborted after reading.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Strip BOM before matching. The model will not include an invisible BOM in oldText.\n\t\t\t\t\t\t\t\tconst { bom, text: content } = stripBom(rawContent);\n\t\t\t\t\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\t\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\t\t\t\t\tconst { baseContent, newContent } = applyEditsToNormalizedContent(\n\t\t\t\t\t\t\t\t\tnormalizedContent,\n\t\t\t\t\t\t\t\t\tedits,\n\t\t\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t// Check if aborted before writing.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\t\t\t\t\tawait ops.writeFile(absolutePath, finalContent);\n\n\t\t\t\t\t\t\t\t// Check if aborted after writing.\n\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Clean up abort handler.\n\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\t\ttext:\n\t\t\t\t\t\t\t\t\t\t\t\tmode === \"single\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t? `Successfully replaced text in ${path}.`\n\t\t\t\t\t\t\t\t\t\t\t\t\t: `Successfully replaced ${edits.length} block(s) in ${path}.`,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tdetails: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\t\t\t// Clean up abort handler.\n\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})();\n\t\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tif (context.argsComplete) {\n\t\t\t\tconst previewInput = getRenderablePreviewInput(\n\t\t\t\t\targs as { path?: string; oldText?: string; newText?: string; edits?: ReplaceEdit[] },\n\t\t\t\t);\n\t\t\t\tif (previewInput) {\n\t\t\t\t\tconst argsKey = JSON.stringify({ path: previewInput.path, edits: previewInput.edits });\n\t\t\t\t\tif (context.state.argsKey !== argsKey) {\n\t\t\t\t\t\tcontext.state.argsKey = argsKey;\n\t\t\t\t\t\tcomputeEditsDiff(previewInput.path, previewInput.edits, context.cwd).then((preview) => {\n\t\t\t\t\t\t\tif (context.state.argsKey === argsKey) {\n\t\t\t\t\t\t\t\tcontext.state.preview = preview;\n\t\t\t\t\t\t\t\tcontext.invalidate();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatEditCall(args, context.state, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, _options, theme, context) {\n\t\t\tconst output = formatEditResult(context.args, context.state, result as any, theme, context.isError);\n\t\t\tif (!output) {\n\t\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\t\tcomponent.clear();\n\t\t\t\treturn component;\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(output);\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createEditTool(cwd: string, options?: EditToolOptions): AgentTool<typeof editSchema> {\n\treturn wrapToolDefinition(createEditToolDefinition(cwd, options));\n}\n\n/** Default edit tool using process.cwd() for backwards compatibility. */\nexport const editToolDefinition = createEditToolDefinition(process.cwd());\nexport const editTool = createEditTool(process.cwd());\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"file-mutation-queue.d.ts","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoBjG","sourcesContent":["import { realpath } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nconst fileMutationQueues = new Map<string, Promise<void>>();\n\nasync function getMutationQueueKey(filePath: string): Promise<string> {\n\tconst resolvedPath = resolve(filePath);\n\ttry {\n\t\treturn await realpath(resolvedPath);\n\t} catch {\n\t\treturn resolvedPath;\n\t}\n}\n\n/**\n * Serialize file mutation operations targeting the same file.\n * Operations for different files still run in parallel.\n */\nexport async function withFileMutationQueue<T>(filePath: string, fn: () => Promise<T>): Promise<T> {\n\tconst key = await getMutationQueueKey(filePath);\n\tconst currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n\n\tlet releaseNext!: () => void;\n\tconst nextQueue = new Promise<void>((resolveQueue) => {\n\t\treleaseNext = resolveQueue;\n\t});\n\tconst chainedQueue = currentQueue.then(() => nextQueue);\n\tfileMutationQueues.set(key, chainedQueue);\n\n\tawait currentQueue;\n\ttry {\n\t\treturn await fn();\n\t} finally {\n\t\treleaseNext();\n\t\tif (fileMutationQueues.get(key) === chainedQueue) {\n\t\t\tfileMutationQueues.delete(key);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"file-mutation-queue.d.ts","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoBjG","sourcesContent":["import { realpathSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nconst fileMutationQueues = new Map<string, Promise<void>>();\n\nfunction getMutationQueueKey(filePath: string): string {\n\tconst resolvedPath = resolve(filePath);\n\ttry {\n\t\treturn realpathSync.native(resolvedPath);\n\t} catch {\n\t\treturn resolvedPath;\n\t}\n}\n\n/**\n * Serialize file mutation operations targeting the same file.\n * Operations for different files still run in parallel.\n */\nexport async function withFileMutationQueue<T>(filePath: string, fn: () => Promise<T>): Promise<T> {\n\tconst key = getMutationQueueKey(filePath);\n\tconst currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n\n\tlet releaseNext!: () => void;\n\tconst nextQueue = new Promise<void>((resolveQueue) => {\n\t\treleaseNext = resolveQueue;\n\t});\n\tconst chainedQueue = currentQueue.then(() => nextQueue);\n\tfileMutationQueues.set(key, chainedQueue);\n\n\tawait currentQueue;\n\ttry {\n\t\treturn await fn();\n\t} finally {\n\t\treleaseNext();\n\t\tif (fileMutationQueues.get(key) === chainedQueue) {\n\t\t\tfileMutationQueues.delete(key);\n\t\t}\n\t}\n}\n"]}
@@ -1,10 +1,10 @@
1
- import { realpath } from "node:fs/promises";
1
+ import { realpathSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
3
  const fileMutationQueues = new Map();
4
- async function getMutationQueueKey(filePath) {
4
+ function getMutationQueueKey(filePath) {
5
5
  const resolvedPath = resolve(filePath);
6
6
  try {
7
- return await realpath(resolvedPath);
7
+ return realpathSync.native(resolvedPath);
8
8
  }
9
9
  catch {
10
10
  return resolvedPath;
@@ -15,7 +15,7 @@ async function getMutationQueueKey(filePath) {
15
15
  * Operations for different files still run in parallel.
16
16
  */
17
17
  export async function withFileMutationQueue(filePath, fn) {
18
- const key = await getMutationQueueKey(filePath);
18
+ const key = getMutationQueueKey(filePath);
19
19
  const currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();
20
20
  let releaseNext;
21
21
  const nextQueue = new Promise((resolveQueue) => {
@@ -1 +1 @@
1
- {"version":3,"file":"file-mutation-queue.js","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAyB,CAAC;AAE5D,KAAK,UAAU,mBAAmB,CAAC,QAAgB,EAAmB;IACrE,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC;QACJ,OAAO,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,YAAY,CAAC;IACrB,CAAC;AAAA,CACD;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAI,QAAgB,EAAE,EAAoB,EAAc;IAClG,MAAM,GAAG,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAEtE,IAAI,WAAwB,CAAC;IAC7B,MAAM,SAAS,GAAG,IAAI,OAAO,CAAO,CAAC,YAAY,EAAE,EAAE,CAAC;QACrD,WAAW,GAAG,YAAY,CAAC;IAAA,CAC3B,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACxD,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAE1C,MAAM,YAAY,CAAC;IACnB,IAAI,CAAC;QACJ,OAAO,MAAM,EAAE,EAAE,CAAC;IACnB,CAAC;YAAS,CAAC;QACV,WAAW,EAAE,CAAC;QACd,IAAI,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,YAAY,EAAE,CAAC;YAClD,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;IACF,CAAC;AAAA,CACD","sourcesContent":["import { realpath } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nconst fileMutationQueues = new Map<string, Promise<void>>();\n\nasync function getMutationQueueKey(filePath: string): Promise<string> {\n\tconst resolvedPath = resolve(filePath);\n\ttry {\n\t\treturn await realpath(resolvedPath);\n\t} catch {\n\t\treturn resolvedPath;\n\t}\n}\n\n/**\n * Serialize file mutation operations targeting the same file.\n * Operations for different files still run in parallel.\n */\nexport async function withFileMutationQueue<T>(filePath: string, fn: () => Promise<T>): Promise<T> {\n\tconst key = await getMutationQueueKey(filePath);\n\tconst currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n\n\tlet releaseNext!: () => void;\n\tconst nextQueue = new Promise<void>((resolveQueue) => {\n\t\treleaseNext = resolveQueue;\n\t});\n\tconst chainedQueue = currentQueue.then(() => nextQueue);\n\tfileMutationQueues.set(key, chainedQueue);\n\n\tawait currentQueue;\n\ttry {\n\t\treturn await fn();\n\t} finally {\n\t\treleaseNext();\n\t\tif (fileMutationQueues.get(key) === chainedQueue) {\n\t\t\tfileMutationQueues.delete(key);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"file-mutation-queue.js","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAyB,CAAC;AAE5D,SAAS,mBAAmB,CAAC,QAAgB,EAAU;IACtD,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC;QACJ,OAAO,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,YAAY,CAAC;IACrB,CAAC;AAAA,CACD;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAI,QAAgB,EAAE,EAAoB,EAAc;IAClG,MAAM,GAAG,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,YAAY,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAEtE,IAAI,WAAwB,CAAC;IAC7B,MAAM,SAAS,GAAG,IAAI,OAAO,CAAO,CAAC,YAAY,EAAE,EAAE,CAAC;QACrD,WAAW,GAAG,YAAY,CAAC;IAAA,CAC3B,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACxD,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAE1C,MAAM,YAAY,CAAC;IACnB,IAAI,CAAC;QACJ,OAAO,MAAM,EAAE,EAAE,CAAC;IACnB,CAAC;YAAS,CAAC;QACV,WAAW,EAAE,CAAC;QACd,IAAI,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,YAAY,EAAE,CAAC;YAClD,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;IACF,CAAC;AAAA,CACD","sourcesContent":["import { realpathSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nconst fileMutationQueues = new Map<string, Promise<void>>();\n\nfunction getMutationQueueKey(filePath: string): string {\n\tconst resolvedPath = resolve(filePath);\n\ttry {\n\t\treturn realpathSync.native(resolvedPath);\n\t} catch {\n\t\treturn resolvedPath;\n\t}\n}\n\n/**\n * Serialize file mutation operations targeting the same file.\n * Operations for different files still run in parallel.\n */\nexport async function withFileMutationQueue<T>(filePath: string, fn: () => Promise<T>): Promise<T> {\n\tconst key = getMutationQueueKey(filePath);\n\tconst currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n\n\tlet releaseNext!: () => void;\n\tconst nextQueue = new Promise<void>((resolveQueue) => {\n\t\treleaseNext = resolveQueue;\n\t});\n\tconst chainedQueue = currentQueue.then(() => nextQueue);\n\tfileMutationQueues.set(key, chainedQueue);\n\n\tawait currentQueue;\n\ttry {\n\t\treturn await fn();\n\t} finally {\n\t\treleaseNext();\n\t\tif (fileMutationQueues.get(key) === chainedQueue) {\n\t\t\tfileMutationQueues.delete(key);\n\t\t}\n\t}\n}\n"]}
@@ -27,8 +27,12 @@ export declare const allTools: {
27
27
  }>, any>;
28
28
  edit: AgentTool<import("@sinclair/typebox").TObject<{
29
29
  path: import("@sinclair/typebox").TString;
30
- oldText: import("@sinclair/typebox").TString;
31
- newText: import("@sinclair/typebox").TString;
30
+ oldText: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
31
+ newText: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
32
+ edits: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
33
+ oldText: import("@sinclair/typebox").TString;
34
+ newText: import("@sinclair/typebox").TString;
35
+ }>>>;
32
36
  }>, any>;
33
37
  write: AgentTool<import("@sinclair/typebox").TObject<{
34
38
  path: import("@sinclair/typebox").TString;
@@ -69,8 +73,12 @@ export declare const allToolDefinitions: {
69
73
  }>;
70
74
  edit: ToolDefinition<import("@sinclair/typebox").TObject<{
71
75
  path: import("@sinclair/typebox").TString;
72
- oldText: import("@sinclair/typebox").TString;
73
- newText: import("@sinclair/typebox").TString;
76
+ oldText: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
77
+ newText: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
78
+ edits: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
79
+ oldText: import("@sinclair/typebox").TString;
80
+ newText: import("@sinclair/typebox").TString;
81
+ }>>>;
74
82
  }>, import("./edit.js").EditToolDetails | undefined, {
75
83
  argsKey?: string | undefined;
76
84
  preview?: import("./edit-diff.js").EditDiffError | import("./edit-diff.js").EditDiffResult | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tbashTool,\n\tbashToolDefinition,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.js\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n\teditTool,\n\teditToolDefinition,\n} from \"./edit.js\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n\tfindTool,\n\tfindToolDefinition,\n} from \"./find.js\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n\tgrepTool,\n\tgrepToolDefinition,\n} from \"./grep.js\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n\tlsTool,\n\tlsToolDefinition,\n} from \"./ls.js\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n\treadTool,\n\treadToolDefinition,\n} from \"./read.js\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.js\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n\twriteTool,\n\twriteToolDefinition,\n} from \"./write.js\";\n\nimport type { AgentTool } from \"@hyperspaceng/neural-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport {\n\ttype BashToolOptions,\n\tbashTool,\n\tbashToolDefinition,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n} from \"./bash.js\";\nimport { createEditTool, createEditToolDefinition, editTool, editToolDefinition } from \"./edit.js\";\nimport { createFindTool, createFindToolDefinition, findTool, findToolDefinition } from \"./find.js\";\nimport { createGrepTool, createGrepToolDefinition, grepTool, grepToolDefinition } from \"./grep.js\";\nimport { createLsTool, createLsToolDefinition, lsTool, lsToolDefinition } from \"./ls.js\";\nimport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadToolOptions,\n\treadTool,\n\treadToolDefinition,\n} from \"./read.js\";\nimport { createWriteTool, createWriteToolDefinition, writeTool, writeToolDefinition } from \"./write.js\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\n\nexport const codingTools: Tool[] = [readTool, bashTool, editTool, writeTool];\nexport const readOnlyTools: Tool[] = [readTool, grepTool, findTool, lsTool];\n\nexport const allTools = {\n\tread: readTool,\n\tbash: bashTool,\n\tedit: editTool,\n\twrite: writeTool,\n\tgrep: grepTool,\n\tfind: findTool,\n\tls: lsTool,\n};\n\nexport const allToolDefinitions = {\n\tread: readToolDefinition,\n\tbash: bashToolDefinition,\n\tedit: editToolDefinition,\n\twrite: writeToolDefinition,\n\tgrep: grepToolDefinition,\n\tfind: findToolDefinition,\n\tls: lsToolDefinition,\n};\n\nexport type ToolName = keyof typeof allTools;\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd),\n\t\tcreateWriteToolDefinition(cwd),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd),\n\t\tcreateFindToolDefinition(cwd),\n\t\tcreateLsToolDefinition(cwd),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd),\n\t\twrite: createWriteToolDefinition(cwd),\n\t\tgrep: createGrepToolDefinition(cwd),\n\t\tfind: createFindToolDefinition(cwd),\n\t\tls: createLsToolDefinition(cwd),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd),\n\t\tcreateWriteTool(cwd),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [createReadTool(cwd, options?.read), createGrepTool(cwd), createFindTool(cwd), createLsTool(cwd)];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd),\n\t\twrite: createWriteTool(cwd),\n\t\tgrep: createGrepTool(cwd),\n\t\tfind: createFindTool(cwd),\n\t\tls: createLsTool(cwd),\n\t};\n}\n"]}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tbashTool,\n\tbashToolDefinition,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.js\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n\teditTool,\n\teditToolDefinition,\n} from \"./edit.js\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n\tfindTool,\n\tfindToolDefinition,\n} from \"./find.js\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n\tgrepTool,\n\tgrepToolDefinition,\n} from \"./grep.js\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n\tlsTool,\n\tlsToolDefinition,\n} from \"./ls.js\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n\treadTool,\n\treadToolDefinition,\n} from \"./read.js\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.js\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n\twriteTool,\n\twriteToolDefinition,\n} from \"./write.js\";\n\nimport type { AgentTool } from \"@hyperspaceng/neural-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport {\n\ttype BashToolOptions,\n\tbashTool,\n\tbashToolDefinition,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n} from \"./bash.js\";\nimport { createEditTool, createEditToolDefinition, editTool, editToolDefinition } from \"./edit.js\";\nimport { createFindTool, createFindToolDefinition, findTool, findToolDefinition } from \"./find.js\";\nimport { createGrepTool, createGrepToolDefinition, grepTool, grepToolDefinition } from \"./grep.js\";\nimport { createLsTool, createLsToolDefinition, lsTool, lsToolDefinition } from \"./ls.js\";\nimport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadToolOptions,\n\treadTool,\n\treadToolDefinition,\n} from \"./read.js\";\nimport { createWriteTool, createWriteToolDefinition, writeTool, writeToolDefinition } from \"./write.js\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\n\nexport const codingTools: Tool[] = [readTool, bashTool, editTool, writeTool];\nexport const readOnlyTools: Tool[] = [readTool, grepTool, findTool, lsTool];\n\nexport const allTools = {\n\tread: readTool,\n\tbash: bashTool,\n\tedit: editTool,\n\twrite: writeTool,\n\tgrep: grepTool,\n\tfind: findTool,\n\tls: lsTool,\n};\n\nexport const allToolDefinitions = {\n\tread: readToolDefinition,\n\tbash: bashToolDefinition,\n\tedit: editToolDefinition,\n\twrite: writeToolDefinition,\n\tgrep: grepToolDefinition,\n\tfind: findToolDefinition,\n\tls: lsToolDefinition,\n};\n\nexport type ToolName = keyof typeof allTools;\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd),\n\t\tcreateWriteToolDefinition(cwd),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd),\n\t\tcreateFindToolDefinition(cwd),\n\t\tcreateLsToolDefinition(cwd),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd),\n\t\twrite: createWriteToolDefinition(cwd),\n\t\tgrep: createGrepToolDefinition(cwd),\n\t\tfind: createFindToolDefinition(cwd),\n\t\tls: createLsToolDefinition(cwd),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd),\n\t\tcreateWriteTool(cwd),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [createReadTool(cwd, options?.read), createGrepTool(cwd), createFindTool(cwd), createLsTool(cwd)];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd),\n\t\twrite: createWriteTool(cwd),\n\t\tgrep: createGrepTool(cwd),\n\t\tfind: createFindTool(cwd),\n\t\tls: createLsTool(cwd),\n\t};\n}\n"]}