@caupulican/pi-adaptative 0.85.3 → 0.85.4

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 (192) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/core/agent-session-services.d.ts.map +1 -1
  3. package/dist/core/agent-session-services.js +2 -0
  4. package/dist/core/agent-session-services.js.map +1 -1
  5. package/dist/core/agent-session.d.ts +6 -5
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +76 -87
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/auth-guidance.d.ts.map +1 -1
  10. package/dist/core/auth-guidance.js +3 -0
  11. package/dist/core/auth-guidance.js.map +1 -1
  12. package/dist/core/autonomy/lane-tool-surface.d.ts +2 -0
  13. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  14. package/dist/core/autonomy/lane-tool-surface.js +4 -3
  15. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  16. package/dist/core/background-lane-controller.d.ts +4 -0
  17. package/dist/core/background-lane-controller.d.ts.map +1 -1
  18. package/dist/core/background-lane-controller.js +2 -0
  19. package/dist/core/background-lane-controller.js.map +1 -1
  20. package/dist/core/background-tool-task-controller.d.ts +12 -7
  21. package/dist/core/background-tool-task-controller.d.ts.map +1 -1
  22. package/dist/core/background-tool-task-controller.js +55 -19
  23. package/dist/core/background-tool-task-controller.js.map +1 -1
  24. package/dist/core/bedrock-scope.d.ts +26 -0
  25. package/dist/core/bedrock-scope.d.ts.map +1 -0
  26. package/dist/core/bedrock-scope.js +178 -0
  27. package/dist/core/bedrock-scope.js.map +1 -0
  28. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  29. package/dist/core/delegation/worker-delegation-controller.js +6 -0
  30. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  31. package/dist/core/extensions/loader.d.ts.map +1 -1
  32. package/dist/core/extensions/loader.js +3 -0
  33. package/dist/core/extensions/loader.js.map +1 -1
  34. package/dist/core/foreground-recovery-controller.d.ts +25 -2
  35. package/dist/core/foreground-recovery-controller.d.ts.map +1 -1
  36. package/dist/core/foreground-recovery-controller.js +111 -2
  37. package/dist/core/foreground-recovery-controller.js.map +1 -1
  38. package/dist/core/foreground-terminal-handoff-controller.d.ts +27 -0
  39. package/dist/core/foreground-terminal-handoff-controller.d.ts.map +1 -0
  40. package/dist/core/foreground-terminal-handoff-controller.js +56 -0
  41. package/dist/core/foreground-terminal-handoff-controller.js.map +1 -0
  42. package/dist/core/goal-loop-controller.d.ts.map +1 -1
  43. package/dist/core/goal-loop-controller.js +5 -0
  44. package/dist/core/goal-loop-controller.js.map +1 -1
  45. package/dist/core/goals/goal-auto-continue-controller.d.ts +3 -0
  46. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -1
  47. package/dist/core/goals/goal-auto-continue-controller.js +28 -7
  48. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -1
  49. package/dist/core/human-input-controller.d.ts +9 -0
  50. package/dist/core/human-input-controller.d.ts.map +1 -1
  51. package/dist/core/human-input-controller.js +60 -5
  52. package/dist/core/human-input-controller.js.map +1 -1
  53. package/dist/core/human-input.d.ts +12 -0
  54. package/dist/core/human-input.d.ts.map +1 -1
  55. package/dist/core/human-input.js +59 -12
  56. package/dist/core/human-input.js.map +1 -1
  57. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  58. package/dist/core/local-runtime-controller.js +15 -9
  59. package/dist/core/local-runtime-controller.js.map +1 -1
  60. package/dist/core/memory/providers/file-store.d.ts +1 -0
  61. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  62. package/dist/core/memory/providers/file-store.js +252 -125
  63. package/dist/core/memory/providers/file-store.js.map +1 -1
  64. package/dist/core/model-capability.d.ts +15 -1
  65. package/dist/core/model-capability.d.ts.map +1 -1
  66. package/dist/core/model-capability.js +24 -1
  67. package/dist/core/model-capability.js.map +1 -1
  68. package/dist/core/model-registry.d.ts +5 -0
  69. package/dist/core/model-registry.d.ts.map +1 -1
  70. package/dist/core/model-registry.js +18 -0
  71. package/dist/core/model-registry.js.map +1 -1
  72. package/dist/core/model-router-controller.d.ts +6 -6
  73. package/dist/core/model-router-controller.d.ts.map +1 -1
  74. package/dist/core/model-router-controller.js +5 -5
  75. package/dist/core/model-router-controller.js.map +1 -1
  76. package/dist/core/models/context-sizing.d.ts +1 -0
  77. package/dist/core/models/context-sizing.d.ts.map +1 -1
  78. package/dist/core/models/context-sizing.js +4 -1
  79. package/dist/core/models/context-sizing.js.map +1 -1
  80. package/dist/core/models/default-model-suggestions.d.ts.map +1 -1
  81. package/dist/core/models/default-model-suggestions.js +20 -10
  82. package/dist/core/models/default-model-suggestions.js.map +1 -1
  83. package/dist/core/models/llamacpp-runtime.d.ts +32 -11
  84. package/dist/core/models/llamacpp-runtime.d.ts.map +1 -1
  85. package/dist/core/models/llamacpp-runtime.js +79 -28
  86. package/dist/core/models/llamacpp-runtime.js.map +1 -1
  87. package/dist/core/models/local-execution-planner.d.ts +24 -0
  88. package/dist/core/models/local-execution-planner.d.ts.map +1 -0
  89. package/dist/core/models/local-execution-planner.js +119 -0
  90. package/dist/core/models/local-execution-planner.js.map +1 -0
  91. package/dist/core/models/local-inference-profile.d.ts +34 -0
  92. package/dist/core/models/local-inference-profile.d.ts.map +1 -0
  93. package/dist/core/models/local-inference-profile.js +74 -0
  94. package/dist/core/models/local-inference-profile.js.map +1 -0
  95. package/dist/core/models/local-runtime.d.ts +23 -4
  96. package/dist/core/models/local-runtime.d.ts.map +1 -1
  97. package/dist/core/models/local-runtime.js +11 -8
  98. package/dist/core/models/local-runtime.js.map +1 -1
  99. package/dist/core/models/managed-ollama-model.d.ts +26 -0
  100. package/dist/core/models/managed-ollama-model.d.ts.map +1 -0
  101. package/dist/core/models/managed-ollama-model.js +59 -0
  102. package/dist/core/models/managed-ollama-model.js.map +1 -0
  103. package/dist/core/models/model-ref.js +11 -11
  104. package/dist/core/models/model-ref.js.map +1 -1
  105. package/dist/core/models/prism-llamacpp-lifecycle.d.ts +10 -20
  106. package/dist/core/models/prism-llamacpp-lifecycle.d.ts.map +1 -1
  107. package/dist/core/models/prism-llamacpp-lifecycle.js +11 -31
  108. package/dist/core/models/prism-llamacpp-lifecycle.js.map +1 -1
  109. package/dist/core/models/prism-llamacpp-server-probe.d.ts +10 -0
  110. package/dist/core/models/prism-llamacpp-server-probe.d.ts.map +1 -0
  111. package/dist/core/models/prism-llamacpp-server-probe.js +36 -0
  112. package/dist/core/models/prism-llamacpp-server-probe.js.map +1 -0
  113. package/dist/core/models/runtime-arbiter.d.ts +3 -0
  114. package/dist/core/models/runtime-arbiter.d.ts.map +1 -1
  115. package/dist/core/models/runtime-arbiter.js +2 -1
  116. package/dist/core/models/runtime-arbiter.js.map +1 -1
  117. package/dist/core/research/research-lane-controller.d.ts.map +1 -1
  118. package/dist/core/research/research-lane-controller.js +14 -5
  119. package/dist/core/research/research-lane-controller.js.map +1 -1
  120. package/dist/core/runtime-builder.d.ts +5 -1
  121. package/dist/core/runtime-builder.d.ts.map +1 -1
  122. package/dist/core/runtime-builder.js +37 -4
  123. package/dist/core/runtime-builder.js.map +1 -1
  124. package/dist/core/scout-controller.d.ts +3 -2
  125. package/dist/core/scout-controller.d.ts.map +1 -1
  126. package/dist/core/scout-controller.js +1 -0
  127. package/dist/core/scout-controller.js.map +1 -1
  128. package/dist/core/sdk.d.ts.map +1 -1
  129. package/dist/core/sdk.js +10 -8
  130. package/dist/core/sdk.js.map +1 -1
  131. package/dist/core/settings-manager.d.ts +13 -0
  132. package/dist/core/settings-manager.d.ts.map +1 -1
  133. package/dist/core/settings-manager.js +59 -0
  134. package/dist/core/settings-manager.js.map +1 -1
  135. package/dist/core/system-prompt-builder.d.ts +5 -2
  136. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  137. package/dist/core/system-prompt-builder.js +22 -10
  138. package/dist/core/system-prompt-builder.js.map +1 -1
  139. package/dist/core/system-prompt.d.ts +3 -0
  140. package/dist/core/system-prompt.d.ts.map +1 -1
  141. package/dist/core/system-prompt.js +181 -55
  142. package/dist/core/system-prompt.js.map +1 -1
  143. package/dist/core/tool-protocol-controller.d.ts.map +1 -1
  144. package/dist/core/tool-protocol-controller.js +5 -3
  145. package/dist/core/tool-protocol-controller.js.map +1 -1
  146. package/dist/core/tools/edit-diff.d.ts +2 -0
  147. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  148. package/dist/core/tools/edit-diff.js +9 -1
  149. package/dist/core/tools/edit-diff.js.map +1 -1
  150. package/dist/core/tools/edit.d.ts +5 -8
  151. package/dist/core/tools/edit.d.ts.map +1 -1
  152. package/dist/core/tools/edit.js +88 -55
  153. package/dist/core/tools/edit.js.map +1 -1
  154. package/dist/core/tools/file-mutation-intent.d.ts +42 -15
  155. package/dist/core/tools/file-mutation-intent.d.ts.map +1 -1
  156. package/dist/core/tools/file-mutation-intent.js +271 -77
  157. package/dist/core/tools/file-mutation-intent.js.map +1 -1
  158. package/dist/core/tools/index.d.ts +1 -1
  159. package/dist/core/tools/index.d.ts.map +1 -1
  160. package/dist/core/tools/index.js +1 -1
  161. package/dist/core/tools/index.js.map +1 -1
  162. package/dist/core/tools/write.d.ts +5 -10
  163. package/dist/core/tools/write.d.ts.map +1 -1
  164. package/dist/core/tools/write.js +92 -73
  165. package/dist/core/tools/write.js.map +1 -1
  166. package/dist/index.d.ts +1 -1
  167. package/dist/index.d.ts.map +1 -1
  168. package/dist/index.js +1 -1
  169. package/dist/index.js.map +1 -1
  170. package/dist/modes/interactive/auth-dialogs-controller.d.ts +6 -0
  171. package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -1
  172. package/dist/modes/interactive/auth-dialogs-controller.js +59 -12
  173. package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -1
  174. package/dist/modes/interactive/local-model-commands.d.ts +1 -1
  175. package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
  176. package/dist/modes/interactive/local-model-commands.js +51 -8
  177. package/dist/modes/interactive/local-model-commands.js.map +1 -1
  178. package/docs/providers.md +34 -10
  179. package/docs/tool-boundary-performance-roadmap-2026-08-02.md +21 -18
  180. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  181. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  182. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  183. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  184. package/examples/extensions/minimal-mode.ts +1 -1
  185. package/examples/extensions/prompt-customizer.ts +2 -2
  186. package/examples/extensions/sandbox/package-lock.json +2 -2
  187. package/examples/extensions/sandbox/package.json +1 -1
  188. package/examples/extensions/ssh.ts +17 -0
  189. package/examples/extensions/with-deps/package-lock.json +2 -2
  190. package/examples/extensions/with-deps/package.json +1 -1
  191. package/npm-shrinkwrap.json +240 -260
  192. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"edit-diff.js","sourceRoot":"","sources":["../../../src/core/tools/edit-diff.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared diff computation utilities for the edit tool.\n * Used by both edit.ts (for execution) and tool-execution.ts (for preview rendering).\n */\n\nimport * as Diff from \"diff\";\nimport { constants } from \"fs\";\nimport { access, readFile } from \"fs/promises\";\nimport { resolveToCwd } from \"./path-utils.ts\";\n\nexport function detectLineEnding(content: string): \"\\r\\n\" | \"\\n\" {\n\tconst crlfIdx = content.indexOf(\"\\r\\n\");\n\tconst lfIdx = content.indexOf(\"\\n\");\n\tif (lfIdx === -1) return \"\\n\";\n\tif (crlfIdx === -1) return \"\\n\";\n\treturn crlfIdx < lfIdx ? \"\\r\\n\" : \"\\n\";\n}\n\nexport function normalizeToLF(text: string): string {\n\treturn text.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n}\n\nexport function restoreLineEndings(text: string, ending: \"\\r\\n\" | \"\\n\"): string {\n\treturn ending === \"\\r\\n\" ? text.replace(/\\n/g, \"\\r\\n\") : text;\n}\n\n/**\n * Normalize text for fuzzy matching. Applies progressive transformations:\n * - Strip trailing whitespace from each line\n * - Normalize smart quotes to ASCII equivalents\n * - Normalize Unicode dashes/hyphens to ASCII hyphen\n * - Normalize special Unicode spaces to regular space\n */\nexport function normalizeForFuzzyMatch(text: string): string {\n\treturn normalizeFuzzyCharacters(text).replace(/[^\\S\\n]+(?=\\n|$)/gu, \"\");\n}\n\nfunction normalizeFuzzyCharacters(text: string): string {\n\treturn (\n\t\ttext\n\t\t\t.normalize(\"NFKC\")\n\t\t\t// Smart single quotes → '\n\t\t\t.replace(/[\\u2018\\u2019\\u201A\\u201B]/g, \"'\")\n\t\t\t// Smart double quotes → \"\n\t\t\t.replace(/[\\u201C\\u201D\\u201E\\u201F]/g, '\"')\n\t\t\t// Various dashes/hyphens → -\n\t\t\t// U+2010 hyphen, U+2011 non-breaking hyphen, U+2012 figure dash,\n\t\t\t// U+2013 en-dash, U+2014 em-dash, U+2015 horizontal bar, U+2212 minus\n\t\t\t.replace(/[\\u2010\\u2011\\u2012\\u2013\\u2014\\u2015\\u2212]/g, \"-\")\n\t\t\t// Special spaces → regular space\n\t\t\t// U+00A0 NBSP, U+2002-U+200A various spaces, U+202F narrow NBSP,\n\t\t\t// U+205F medium math space, U+3000 ideographic space\n\t\t\t.replace(/[\\u00A0\\u2002-\\u200A\\u202F\\u205F\\u3000]/g, \" \")\n\t);\n}\n\nexport interface FuzzyMatchResult {\n\t/** Whether a match was found */\n\tfound: boolean;\n\t/** The index where the match starts (in the content that should be used for replacement) */\n\tindex: number;\n\t/** Length of the matched text */\n\tmatchLength: number;\n\t/** Whether fuzzy matching was used (false = exact match) */\n\tusedFuzzyMatch: boolean;\n\t/** The original content replacements should be applied to. */\n\tcontentForReplacement: string;\n}\n\nexport interface Edit {\n\toldText: string;\n\tnewText: string;\n\t/** Inclusive 1-based line bounds from the read that supplied oldText. */\n\trange?: EditRange;\n}\n\nexport interface EditRange {\n\tstartLine: number;\n\tendLine: number;\n}\n\ninterface PlannedEdit {\n\teditIndex: number;\n\tmatchIndex: number;\n\tmatchLength: number;\n\tnewText: string;\n\texpectedText: string;\n}\n\nexport interface EditMatchPlan {\n\t/** Length of the LF-normalized source against which this plan was validated. */\n\tbaseLength: number;\n\teditCount: number;\n\t/** Compact, source-ordered replacement spans; the source body is not retained. */\n\tedits: readonly PlannedEdit[];\n}\n\nexport interface AppliedEditsResult {\n\tbaseContent: string;\n\tnewContent: string;\n}\n\n/**\n * Find oldText in content, trying exact match first, then fuzzy match.\n * Fuzzy matching searches normalized text, but returned spans still refer to\n * the original content so replacement does not normalize unrelated text.\n */\nexport function fuzzyFindText(content: string, oldText: string): FuzzyMatchResult {\n\t// Try exact match first\n\tconst exactIndex = content.indexOf(oldText);\n\tif (exactIndex !== -1) {\n\t\treturn {\n\t\t\tfound: true,\n\t\t\tindex: exactIndex,\n\t\t\tmatchLength: oldText.length,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\n\t// Try fuzzy match - work entirely in normalized space\n\tconst fuzzyContent = normalizeForFuzzyMatch(content);\n\tconst fuzzyOldText = normalizeForFuzzyMatch(oldText);\n\tconst fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);\n\n\tif (fuzzyIndex === -1) {\n\t\treturn {\n\t\t\tfound: false,\n\t\t\tindex: -1,\n\t\t\tmatchLength: 0,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\n\treturn {\n\t\tfound: true,\n\t\tindex: fuzzyIndex,\n\t\tmatchLength: fuzzyOldText.length,\n\t\tusedFuzzyMatch: true,\n\t\tcontentForReplacement: content,\n\t};\n}\n\n/** Strip UTF-8 BOM if present, return both the BOM (if any) and the text without it */\nexport function stripBom(content: string): { bom: string; text: string } {\n\treturn content.startsWith(\"\\uFEFF\") ? { bom: \"\\uFEFF\", text: content.slice(1) } : { bom: \"\", text: content };\n}\n\nfunction countExactOccurrences(content: string, oldText: string): number {\n\tif (oldText.length === 0) return 0;\n\tlet count = 0;\n\tlet searchFrom = 0;\n\twhile (searchFrom <= content.length - oldText.length) {\n\t\tconst index = content.indexOf(oldText, searchFrom);\n\t\tif (index === -1) break;\n\t\tcount++;\n\t\tsearchFrom = index + 1;\n\t}\n\treturn count;\n}\n\nfunction getLineStarts(content: string): number[] {\n\tconst starts = [0];\n\tfor (let i = 0; i < content.length; i++) {\n\t\tif (content[i] === \"\\n\") starts.push(i + 1);\n\t}\n\treturn starts;\n}\n\nfunction lineColumnAt(lineStarts: number[], index: number): { lineIndex: number; column: number } {\n\tlet low = 0;\n\tlet high = lineStarts.length - 1;\n\twhile (low <= high) {\n\t\tconst mid = Math.floor((low + high) / 2);\n\t\tif (lineStarts[mid] <= index) low = mid + 1;\n\t\telse high = mid - 1;\n\t}\n\tconst lineIndex = Math.max(0, high);\n\treturn { lineIndex, column: index - lineStarts[lineIndex] };\n}\n\nfunction lineTextAt(content: string, lineStarts: number[], lineIndex: number): string {\n\tconst start = lineStarts[lineIndex];\n\tconst nextStart = lineStarts[lineIndex + 1] ?? content.length;\n\tconst end = nextStart > start && content[nextStart - 1] === \"\\n\" ? nextStart - 1 : nextStart;\n\treturn content.slice(start, end);\n}\n\nfunction normalizedColumnToOriginalColumn(line: string, normalizedColumn: number): number {\n\tif (normalizedColumn <= 0) return 0;\n\tconst boundaries = [0];\n\tfor (let index = 0; index < line.length; ) {\n\t\tconst codePoint = line.codePointAt(index);\n\t\tindex += codePoint !== undefined && codePoint > 0xffff ? 2 : 1;\n\t\tboundaries.push(index);\n\t}\n\n\tlet low = 1;\n\tlet high = boundaries.length - 1;\n\twhile (low < high) {\n\t\tconst mid = Math.floor((low + high) / 2);\n\t\tif (normalizeForFuzzyMatch(line.slice(0, boundaries[mid])).length >= normalizedColumn) high = mid;\n\t\telse low = mid + 1;\n\t}\n\treturn boundaries[low] ?? line.length;\n}\n\nfunction mapFuzzySpanToOriginal(\n\toriginalContent: string,\n\toriginalLineStarts: number[],\n\tfuzzyLineStarts: number[],\n\tnormalizedIndex: number,\n\tnormalizedLength: number,\n): { index: number; length: number } {\n\tconst start = lineColumnAt(fuzzyLineStarts, normalizedIndex);\n\tconst end = lineColumnAt(fuzzyLineStarts, normalizedIndex + normalizedLength);\n\tconst startLine = lineTextAt(originalContent, originalLineStarts, start.lineIndex);\n\tconst endLine = lineTextAt(originalContent, originalLineStarts, end.lineIndex);\n\tconst originalStart =\n\t\toriginalLineStarts[start.lineIndex] + normalizedColumnToOriginalColumn(startLine, start.column);\n\tconst originalEnd = originalLineStarts[end.lineIndex] + normalizedColumnToOriginalColumn(endLine, end.column);\n\treturn { index: originalStart, length: originalEnd - originalStart };\n}\n\nfunction getNotFoundError(path: string, editIndex: number, totalEdits: number, range?: EditRange): Error {\n\tconst rangeSuffix = range ? ` within lines ${range.startLine}-${range.endLine}` : \"\";\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\t\t\t`Could not find the exact text in ${path}${rangeSuffix}. The old text must match exactly including all whitespace and newlines.`,\n\t\t);\n\t}\n\treturn new Error(\n\t\t`Could not find edits[${editIndex}] in ${path}${rangeSuffix}. The oldText must match exactly including all whitespace and newlines.`,\n\t);\n}\n\nfunction getDuplicateError(path: string, editIndex: number, totalEdits: number, occurrences: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\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);\n\t}\n\treturn new Error(\n\t\t`Found ${occurrences} occurrences of edits[${editIndex}] in ${path}. Each oldText must be unique. Please provide more context to make it unique.`,\n\t);\n}\n\nfunction getEmptyOldTextError(path: string, editIndex: number, totalEdits: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(`oldText must not be empty in ${path}.`);\n\t}\n\treturn new Error(`edits[${editIndex}].oldText must not be empty in ${path}.`);\n}\n\nfunction getNoChangeError(path: string, totalEdits: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\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);\n\t}\n\treturn new Error(`No changes made to ${path}. The replacements produced identical content.`);\n}\n\ninterface MatchWindow {\n\tstart: number;\n\tend: number;\n}\n\nfunction validateRange(\n\trange: EditRange | undefined,\n\tlineStarts: number[] | undefined,\n\tcontentLength: number,\n\tpath: string,\n\teditIndex: number,\n\ttotalEdits: number,\n): MatchWindow {\n\tif (!range) return { start: 0, end: contentLength };\n\tconst label = totalEdits === 1 ? \"range\" : `edits[${editIndex}].range`;\n\tif (\n\t\t!Number.isSafeInteger(range.startLine) ||\n\t\t!Number.isSafeInteger(range.endLine) ||\n\t\trange.startLine < 1 ||\n\t\trange.endLine < range.startLine\n\t) {\n\t\tthrow new Error(`${label} in ${path} must contain inclusive positive line numbers with startLine <= endLine.`);\n\t}\n\tif (!lineStarts || range.endLine > lineStarts.length) {\n\t\tthrow new Error(`${label} in ${path} exceeds the file's ${lineStarts?.length ?? 0} lines.`);\n\t}\n\treturn {\n\t\tstart: lineStarts[range.startLine - 1],\n\t\tend: lineStarts[range.endLine] ?? contentLength,\n\t};\n}\n\nfunction findWithin(content: string, oldText: string, window: MatchWindow): number {\n\tif (oldText.length === 0 || oldText.length > window.end - window.start) return -1;\n\tconst index = content.indexOf(oldText, window.start);\n\treturn index !== -1 && index + oldText.length <= window.end ? index : -1;\n}\n\nfunction rangesOverlap(previous: PlannedEdit, current: PlannedEdit): boolean {\n\treturn previous.matchIndex + previous.matchLength > current.matchIndex;\n}\n\n/**\n * Match and validate one or more replacements against LF-normalized content.\n *\n * The returned plan retains only the validated spans and their replacement\n * text. Exact matching uses native substring search, bounded by optional line\n * ranges, while uniqueness is still proven across the whole source.\n */\nexport function planEditsToNormalizedContent(normalizedContent: string, edits: Edit[], path: string): EditMatchPlan {\n\tlet originalLineStarts: number[] | undefined;\n\tlet fuzzyContent: string | undefined;\n\tlet fuzzyLineStarts: number[] | undefined;\n\tconst needsLineStarts = edits.some((edit) => edit.range !== undefined);\n\tif (needsLineStarts) originalLineStarts = getLineStarts(normalizedContent);\n\n\tconst matchedEdits: PlannedEdit[] = [];\n\tfor (let i = 0; i < edits.length; i++) {\n\t\tconst sourceEdit = edits[i];\n\t\tconst oldText = normalizeToLF(sourceEdit.oldText);\n\t\tconst newText = normalizeToLF(sourceEdit.newText);\n\t\tif (oldText.length === 0) throw getEmptyOldTextError(path, i, edits.length);\n\n\t\tconst exactWindow = validateRange(\n\t\t\tsourceEdit.range,\n\t\t\toriginalLineStarts,\n\t\t\tnormalizedContent.length,\n\t\t\tpath,\n\t\t\ti,\n\t\t\tedits.length,\n\t\t);\n\t\tlet matchIndex = findWithin(normalizedContent, oldText, exactWindow);\n\t\tlet matchLength = oldText.length;\n\t\tlet occurrences: number;\n\n\t\tif (matchIndex !== -1) {\n\t\t\toccurrences = countExactOccurrences(normalizedContent, oldText);\n\t\t} else {\n\t\t\tfuzzyContent ??= normalizeForFuzzyMatch(normalizedContent);\n\t\t\tfuzzyLineStarts ??= getLineStarts(fuzzyContent);\n\t\t\toriginalLineStarts ??= getLineStarts(normalizedContent);\n\t\t\tconst fuzzyOldText = normalizeForFuzzyMatch(oldText);\n\t\t\tconst fuzzyWindow = validateRange(\n\t\t\t\tsourceEdit.range,\n\t\t\t\tfuzzyLineStarts,\n\t\t\t\tfuzzyContent.length,\n\t\t\t\tpath,\n\t\t\t\ti,\n\t\t\t\tedits.length,\n\t\t\t);\n\t\t\tconst fuzzyIndex = findWithin(fuzzyContent, fuzzyOldText, fuzzyWindow);\n\t\t\tif (fuzzyIndex === -1) throw getNotFoundError(path, i, edits.length, sourceEdit.range);\n\t\t\toccurrences = countExactOccurrences(fuzzyContent, fuzzyOldText);\n\t\t\tconst replacementSpan = mapFuzzySpanToOriginal(\n\t\t\t\tnormalizedContent,\n\t\t\t\toriginalLineStarts,\n\t\t\t\tfuzzyLineStarts,\n\t\t\t\tfuzzyIndex,\n\t\t\t\tfuzzyOldText.length,\n\t\t\t);\n\t\t\tmatchIndex = replacementSpan.index;\n\t\t\tmatchLength = replacementSpan.length;\n\t\t}\n\n\t\tif (occurrences > 1) {\n\t\t\tthrow getDuplicateError(path, i, edits.length, occurrences);\n\t\t}\n\n\t\tmatchedEdits.push({\n\t\t\teditIndex: i,\n\t\t\tmatchIndex,\n\t\t\tmatchLength,\n\t\t\tnewText,\n\t\t\texpectedText: normalizedContent.slice(matchIndex, matchIndex + matchLength),\n\t\t});\n\t}\n\n\tmatchedEdits.sort((a, b) => a.matchIndex - b.matchIndex);\n\tfor (let i = 1; i < matchedEdits.length; i++) {\n\t\tconst previous = matchedEdits[i - 1];\n\t\tconst current = matchedEdits[i];\n\t\tif (rangesOverlap(previous, current)) {\n\t\t\tthrow new Error(\n\t\t\t\t`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${path}. Merge them into one edit or target disjoint regions.`,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn { baseLength: normalizedContent.length, editCount: edits.length, edits: matchedEdits };\n}\n\n/** Apply a validated match plan to the same LF-normalized source in one linear join. */\nexport function applyEditMatchPlan(normalizedContent: string, plan: EditMatchPlan, path: string): AppliedEditsResult {\n\tif (normalizedContent.length !== plan.baseLength) {\n\t\tthrow new Error(`The validated edit plan for ${path} is stale because the source length changed.`);\n\t}\n\n\tconst parts: string[] = [];\n\tlet sourceIndex = 0;\n\tfor (const edit of plan.edits) {\n\t\tif (!normalizedContent.startsWith(edit.expectedText, edit.matchIndex)) {\n\t\t\tthrow new Error(`The validated edit plan for ${path} is stale at edits[${edit.editIndex}].`);\n\t\t}\n\t\tparts.push(normalizedContent.slice(sourceIndex, edit.matchIndex), edit.newText);\n\t\tsourceIndex = edit.matchIndex + edit.matchLength;\n\t}\n\tparts.push(normalizedContent.slice(sourceIndex));\n\tconst newContent = parts.join(\"\");\n\n\tif (normalizedContent === newContent) throw getNoChangeError(path, plan.editCount);\n\treturn { baseContent: normalizedContent, newContent };\n}\n\nexport function applyEditsToNormalizedContent(\n\tnormalizedContent: string,\n\tedits: Edit[],\n\tpath: string,\n): AppliedEditsResult {\n\treturn applyEditMatchPlan(normalizedContent, planEditsToNormalizedContent(normalizedContent, edits, path), path);\n}\n\n/** Generate a standard unified patch. */\nexport function generateUnifiedPatch(path: string, oldContent: string, newContent: string, contextLines = 4): string {\n\treturn Diff.createTwoFilesPatch(path, path, oldContent, newContent, undefined, undefined, {\n\t\tcontext: contextLines,\n\t\theaderOptions: Diff.FILE_HEADERS_ONLY,\n\t});\n}\n\n/**\n * Generate a display-oriented diff string with line numbers and context.\n * Returns both the diff string and the first changed line number (in the new file).\n */\nexport function generateDiffString(\n\toldContent: string,\n\tnewContent: string,\n\tcontextLines = 4,\n): { diff: string; firstChangedLine: number | undefined } {\n\tconst parts = Diff.diffLines(oldContent, newContent);\n\tconst output: string[] = [];\n\n\tconst oldLines = oldContent.split(\"\\n\");\n\tconst newLines = newContent.split(\"\\n\");\n\tconst maxLineNum = Math.max(oldLines.length, newLines.length);\n\tconst lineNumWidth = String(maxLineNum).length;\n\n\tlet oldLineNum = 1;\n\tlet newLineNum = 1;\n\tlet lastWasChange = false;\n\tlet firstChangedLine: number | undefined;\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tconst raw = part.value.split(\"\\n\");\n\t\tif (raw[raw.length - 1] === \"\") {\n\t\t\traw.pop();\n\t\t}\n\n\t\tif (part.added || part.removed) {\n\t\t\t// Capture the first changed line (in the new file)\n\t\t\tif (firstChangedLine === undefined) {\n\t\t\t\tfirstChangedLine = newLineNum;\n\t\t\t}\n\n\t\t\t// Show the change\n\t\t\tfor (const line of raw) {\n\t\t\t\tif (part.added) {\n\t\t\t\t\tconst lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`+${lineNum} ${line}`);\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t} else {\n\t\t\t\t\t// removed\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`-${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlastWasChange = true;\n\t\t} else {\n\t\t\t// Context lines - only show a few before/after changes\n\t\t\tconst nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n\t\t\tconst hasLeadingChange = lastWasChange;\n\t\t\tconst hasTrailingChange = nextPartIsChange;\n\n\t\t\tif (hasLeadingChange && hasTrailingChange) {\n\t\t\t\tif (raw.length <= contextLines * 2) {\n\t\t\t\t\tfor (const line of raw) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst leadingLines = raw.slice(0, contextLines);\n\t\t\t\t\tconst trailingLines = raw.slice(raw.length - contextLines);\n\t\t\t\t\tconst skippedLines = raw.length - leadingLines.length - trailingLines.length;\n\n\t\t\t\t\tfor (const line of leadingLines) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\n\t\t\t\t\tfor (const line of trailingLines) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (hasLeadingChange) {\n\t\t\t\tconst shownLines = raw.slice(0, contextLines);\n\t\t\t\tconst skippedLines = raw.length - shownLines.length;\n\n\t\t\t\tfor (const line of shownLines) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\n\t\t\t\tif (skippedLines > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\t\t\t\t}\n\t\t\t} else if (hasTrailingChange) {\n\t\t\t\tconst skippedLines = Math.max(0, raw.length - contextLines);\n\t\t\t\tif (skippedLines > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\t\t\t\t}\n\n\t\t\t\tfor (const line of raw.slice(skippedLines)) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Skip these context lines entirely\n\t\t\t\toldLineNum += raw.length;\n\t\t\t\tnewLineNum += raw.length;\n\t\t\t}\n\n\t\t\tlastWasChange = false;\n\t\t}\n\t}\n\n\treturn { diff: output.join(\"\\n\"), firstChangedLine };\n}\n\nexport interface EditDiffResult {\n\tdiff: string;\n\tfirstChangedLine: number | undefined;\n}\n\nexport interface EditDiffError {\n\terror: string;\n}\n\nexport interface EditPlannedDiffResult extends EditDiffResult {\n\tplan: EditMatchPlan;\n}\n\n/**\n * Compute the diff for one or more edit operations without applying them.\n * Used for preview rendering in the TUI before the tool executes.\n */\nexport async function computeEditsPlannedDiff(\n\tpath: string,\n\tedits: Edit[],\n\tcwd: string,\n): Promise<EditPlannedDiffResult | EditDiffError> {\n\tconst absolutePath = resolveToCwd(path, cwd);\n\n\ttry {\n\t\t// Check if file exists and is readable\n\t\ttry {\n\t\t\tawait access(absolutePath, constants.R_OK);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error && \"code\" in error ? `Error code: ${error.code}` : String(error);\n\t\t\treturn { error: `Could not edit file: ${path}. ${errorMessage}.` };\n\t\t}\n\n\t\t// Read the file\n\t\tconst rawContent = await readFile(absolutePath, \"utf-8\");\n\n\t\t// Strip BOM before matching (LLM won't include invisible BOM in oldText)\n\t\tconst { text: content } = stripBom(rawContent);\n\t\tconst normalizedContent = normalizeToLF(content);\n\t\tconst plan = planEditsToNormalizedContent(normalizedContent, edits, path);\n\t\tconst { baseContent, newContent } = applyEditMatchPlan(normalizedContent, plan, path);\n\n\t\t// Generate the diff\n\t\treturn { ...generateDiffString(baseContent, newContent), plan };\n\t} catch (err) {\n\t\treturn { error: err instanceof Error ? err.message : String(err) };\n\t}\n}\n\nexport async function computeEditsDiff(\n\tpath: string,\n\tedits: Edit[],\n\tcwd: string,\n): Promise<EditDiffResult | EditDiffError> {\n\tconst result = await computeEditsPlannedDiff(path, edits, cwd);\n\tif (\"error\" in result) return result;\n\treturn { diff: result.diff, firstChangedLine: result.firstChangedLine };\n}\n\n/**\n * Compute the diff for a single edit operation without applying it.\n * Kept as a convenience wrapper for single-edit callers.\n */\nexport async function computeEditDiff(\n\tpath: string,\n\toldText: string,\n\tnewText: string,\n\tcwd: string,\n): Promise<EditDiffResult | EditDiffError> {\n\treturn computeEditsDiff(path, [{ oldText, newText }], cwd);\n}\n"]}
1
+ {"version":3,"file":"edit-diff.js","sourceRoot":"","sources":["../../../src/core/tools/edit-diff.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared diff computation utilities for the edit tool.\n * Used by both edit.ts (for execution) and tool-execution.ts (for preview rendering).\n */\n\nimport { createHash } from \"node:crypto\";\nimport * as Diff from \"diff\";\nimport { constants } from \"fs\";\nimport { access, readFile } from \"fs/promises\";\nimport { resolveToCwd } from \"./path-utils.ts\";\n\nexport function detectLineEnding(content: string): \"\\r\\n\" | \"\\n\" {\n\tconst crlfIdx = content.indexOf(\"\\r\\n\");\n\tconst lfIdx = content.indexOf(\"\\n\");\n\tif (lfIdx === -1) return \"\\n\";\n\tif (crlfIdx === -1) return \"\\n\";\n\treturn crlfIdx < lfIdx ? \"\\r\\n\" : \"\\n\";\n}\n\nexport function normalizeToLF(text: string): string {\n\treturn text.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n}\n\nexport function digestNormalizedEditSource(content: string): string {\n\treturn createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\");\n}\n\nexport function restoreLineEndings(text: string, ending: \"\\r\\n\" | \"\\n\"): string {\n\treturn ending === \"\\r\\n\" ? text.replace(/\\n/g, \"\\r\\n\") : text;\n}\n\n/**\n * Normalize text for fuzzy matching. Applies progressive transformations:\n * - Strip trailing whitespace from each line\n * - Normalize smart quotes to ASCII equivalents\n * - Normalize Unicode dashes/hyphens to ASCII hyphen\n * - Normalize special Unicode spaces to regular space\n */\nexport function normalizeForFuzzyMatch(text: string): string {\n\treturn normalizeFuzzyCharacters(text).replace(/[^\\S\\n]+(?=\\n|$)/gu, \"\");\n}\n\nfunction normalizeFuzzyCharacters(text: string): string {\n\treturn (\n\t\ttext\n\t\t\t.normalize(\"NFKC\")\n\t\t\t// Smart single quotes → '\n\t\t\t.replace(/[\\u2018\\u2019\\u201A\\u201B]/g, \"'\")\n\t\t\t// Smart double quotes → \"\n\t\t\t.replace(/[\\u201C\\u201D\\u201E\\u201F]/g, '\"')\n\t\t\t// Various dashes/hyphens → -\n\t\t\t// U+2010 hyphen, U+2011 non-breaking hyphen, U+2012 figure dash,\n\t\t\t// U+2013 en-dash, U+2014 em-dash, U+2015 horizontal bar, U+2212 minus\n\t\t\t.replace(/[\\u2010\\u2011\\u2012\\u2013\\u2014\\u2015\\u2212]/g, \"-\")\n\t\t\t// Special spaces → regular space\n\t\t\t// U+00A0 NBSP, U+2002-U+200A various spaces, U+202F narrow NBSP,\n\t\t\t// U+205F medium math space, U+3000 ideographic space\n\t\t\t.replace(/[\\u00A0\\u2002-\\u200A\\u202F\\u205F\\u3000]/g, \" \")\n\t);\n}\n\nexport interface FuzzyMatchResult {\n\t/** Whether a match was found */\n\tfound: boolean;\n\t/** The index where the match starts (in the content that should be used for replacement) */\n\tindex: number;\n\t/** Length of the matched text */\n\tmatchLength: number;\n\t/** Whether fuzzy matching was used (false = exact match) */\n\tusedFuzzyMatch: boolean;\n\t/** The original content replacements should be applied to. */\n\tcontentForReplacement: string;\n}\n\nexport interface Edit {\n\toldText: string;\n\tnewText: string;\n\t/** Inclusive 1-based line bounds from the read that supplied oldText. */\n\trange?: EditRange;\n}\n\nexport interface EditRange {\n\tstartLine: number;\n\tendLine: number;\n}\n\ninterface PlannedEdit {\n\teditIndex: number;\n\tmatchIndex: number;\n\tmatchLength: number;\n\tnewText: string;\n\texpectedText: string;\n}\n\nexport interface EditMatchPlan {\n\t/** Length of the LF-normalized source against which this plan was validated. */\n\tbaseLength: number;\n\teditCount: number;\n\t/** Compact, source-ordered replacement spans; the source body is not retained. */\n\tedits: readonly PlannedEdit[];\n}\n\nexport interface AppliedEditsResult {\n\tbaseContent: string;\n\tnewContent: string;\n}\n\n/**\n * Find oldText in content, trying exact match first, then fuzzy match.\n * Fuzzy matching searches normalized text, but returned spans still refer to\n * the original content so replacement does not normalize unrelated text.\n */\nexport function fuzzyFindText(content: string, oldText: string): FuzzyMatchResult {\n\t// Try exact match first\n\tconst exactIndex = content.indexOf(oldText);\n\tif (exactIndex !== -1) {\n\t\treturn {\n\t\t\tfound: true,\n\t\t\tindex: exactIndex,\n\t\t\tmatchLength: oldText.length,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\n\t// Try fuzzy match - work entirely in normalized space\n\tconst fuzzyContent = normalizeForFuzzyMatch(content);\n\tconst fuzzyOldText = normalizeForFuzzyMatch(oldText);\n\tconst fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);\n\n\tif (fuzzyIndex === -1) {\n\t\treturn {\n\t\t\tfound: false,\n\t\t\tindex: -1,\n\t\t\tmatchLength: 0,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\n\treturn {\n\t\tfound: true,\n\t\tindex: fuzzyIndex,\n\t\tmatchLength: fuzzyOldText.length,\n\t\tusedFuzzyMatch: true,\n\t\tcontentForReplacement: content,\n\t};\n}\n\n/** Strip UTF-8 BOM if present, return both the BOM (if any) and the text without it */\nexport function stripBom(content: string): { bom: string; text: string } {\n\treturn content.startsWith(\"\\uFEFF\") ? { bom: \"\\uFEFF\", text: content.slice(1) } : { bom: \"\", text: content };\n}\n\nfunction countExactOccurrences(content: string, oldText: string): number {\n\tif (oldText.length === 0) return 0;\n\tlet count = 0;\n\tlet searchFrom = 0;\n\twhile (searchFrom <= content.length - oldText.length) {\n\t\tconst index = content.indexOf(oldText, searchFrom);\n\t\tif (index === -1) break;\n\t\tcount++;\n\t\tsearchFrom = index + 1;\n\t}\n\treturn count;\n}\n\nfunction getLineStarts(content: string): number[] {\n\tconst starts = [0];\n\tfor (let i = 0; i < content.length; i++) {\n\t\tif (content[i] === \"\\n\") starts.push(i + 1);\n\t}\n\treturn starts;\n}\n\nfunction lineColumnAt(lineStarts: number[], index: number): { lineIndex: number; column: number } {\n\tlet low = 0;\n\tlet high = lineStarts.length - 1;\n\twhile (low <= high) {\n\t\tconst mid = Math.floor((low + high) / 2);\n\t\tif (lineStarts[mid] <= index) low = mid + 1;\n\t\telse high = mid - 1;\n\t}\n\tconst lineIndex = Math.max(0, high);\n\treturn { lineIndex, column: index - lineStarts[lineIndex] };\n}\n\nfunction lineTextAt(content: string, lineStarts: number[], lineIndex: number): string {\n\tconst start = lineStarts[lineIndex];\n\tconst nextStart = lineStarts[lineIndex + 1] ?? content.length;\n\tconst end = nextStart > start && content[nextStart - 1] === \"\\n\" ? nextStart - 1 : nextStart;\n\treturn content.slice(start, end);\n}\n\nfunction normalizedColumnToOriginalColumn(line: string, normalizedColumn: number): number {\n\tif (normalizedColumn <= 0) return 0;\n\tconst boundaries = [0];\n\tfor (let index = 0; index < line.length; ) {\n\t\tconst codePoint = line.codePointAt(index);\n\t\tindex += codePoint !== undefined && codePoint > 0xffff ? 2 : 1;\n\t\tboundaries.push(index);\n\t}\n\n\tlet low = 1;\n\tlet high = boundaries.length - 1;\n\twhile (low < high) {\n\t\tconst mid = Math.floor((low + high) / 2);\n\t\tif (normalizeForFuzzyMatch(line.slice(0, boundaries[mid])).length >= normalizedColumn) high = mid;\n\t\telse low = mid + 1;\n\t}\n\treturn boundaries[low] ?? line.length;\n}\n\nfunction mapFuzzySpanToOriginal(\n\toriginalContent: string,\n\toriginalLineStarts: number[],\n\tfuzzyLineStarts: number[],\n\tnormalizedIndex: number,\n\tnormalizedLength: number,\n): { index: number; length: number } {\n\tconst start = lineColumnAt(fuzzyLineStarts, normalizedIndex);\n\tconst end = lineColumnAt(fuzzyLineStarts, normalizedIndex + normalizedLength);\n\tconst startLine = lineTextAt(originalContent, originalLineStarts, start.lineIndex);\n\tconst endLine = lineTextAt(originalContent, originalLineStarts, end.lineIndex);\n\tconst originalStart =\n\t\toriginalLineStarts[start.lineIndex] + normalizedColumnToOriginalColumn(startLine, start.column);\n\tconst originalEnd = originalLineStarts[end.lineIndex] + normalizedColumnToOriginalColumn(endLine, end.column);\n\treturn { index: originalStart, length: originalEnd - originalStart };\n}\n\nfunction getNotFoundError(path: string, editIndex: number, totalEdits: number, range?: EditRange): Error {\n\tconst rangeSuffix = range ? ` within lines ${range.startLine}-${range.endLine}` : \"\";\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\t\t\t`Could not find the exact text in ${path}${rangeSuffix}. The old text must match exactly including all whitespace and newlines.`,\n\t\t);\n\t}\n\treturn new Error(\n\t\t`Could not find edits[${editIndex}] in ${path}${rangeSuffix}. The oldText must match exactly including all whitespace and newlines.`,\n\t);\n}\n\nfunction getDuplicateError(path: string, editIndex: number, totalEdits: number, occurrences: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\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);\n\t}\n\treturn new Error(\n\t\t`Found ${occurrences} occurrences of edits[${editIndex}] in ${path}. Each oldText must be unique. Please provide more context to make it unique.`,\n\t);\n}\n\nfunction getEmptyOldTextError(path: string, editIndex: number, totalEdits: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(`oldText must not be empty in ${path}.`);\n\t}\n\treturn new Error(`edits[${editIndex}].oldText must not be empty in ${path}.`);\n}\n\nfunction getNoChangeError(path: string, totalEdits: number): Error {\n\tif (totalEdits === 1) {\n\t\treturn new Error(\n\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);\n\t}\n\treturn new Error(`No changes made to ${path}. The replacements produced identical content.`);\n}\n\ninterface MatchWindow {\n\tstart: number;\n\tend: number;\n}\n\nfunction validateRange(\n\trange: EditRange | undefined,\n\tlineStarts: number[] | undefined,\n\tcontentLength: number,\n\tpath: string,\n\teditIndex: number,\n\ttotalEdits: number,\n): MatchWindow {\n\tif (!range) return { start: 0, end: contentLength };\n\tconst label = totalEdits === 1 ? \"range\" : `edits[${editIndex}].range`;\n\tif (\n\t\t!Number.isSafeInteger(range.startLine) ||\n\t\t!Number.isSafeInteger(range.endLine) ||\n\t\trange.startLine < 1 ||\n\t\trange.endLine < range.startLine\n\t) {\n\t\tthrow new Error(`${label} in ${path} must contain inclusive positive line numbers with startLine <= endLine.`);\n\t}\n\tif (!lineStarts || range.endLine > lineStarts.length) {\n\t\tthrow new Error(`${label} in ${path} exceeds the file's ${lineStarts?.length ?? 0} lines.`);\n\t}\n\treturn {\n\t\tstart: lineStarts[range.startLine - 1],\n\t\tend: lineStarts[range.endLine] ?? contentLength,\n\t};\n}\n\nfunction findWithin(content: string, oldText: string, window: MatchWindow): number {\n\tif (oldText.length === 0 || oldText.length > window.end - window.start) return -1;\n\tconst index = content.indexOf(oldText, window.start);\n\treturn index !== -1 && index + oldText.length <= window.end ? index : -1;\n}\n\nfunction rangesOverlap(previous: PlannedEdit, current: PlannedEdit): boolean {\n\treturn previous.matchIndex + previous.matchLength > current.matchIndex;\n}\n\n/**\n * Match and validate one or more replacements against LF-normalized content.\n *\n * The returned plan retains only the validated spans and their replacement\n * text. Exact matching uses native substring search, bounded by optional line\n * ranges, while uniqueness is still proven across the whole source.\n */\nexport function planEditsToNormalizedContent(normalizedContent: string, edits: Edit[], path: string): EditMatchPlan {\n\tlet originalLineStarts: number[] | undefined;\n\tlet fuzzyContent: string | undefined;\n\tlet fuzzyLineStarts: number[] | undefined;\n\tconst needsLineStarts = edits.some((edit) => edit.range !== undefined);\n\tif (needsLineStarts) originalLineStarts = getLineStarts(normalizedContent);\n\n\tconst matchedEdits: PlannedEdit[] = [];\n\tfor (let i = 0; i < edits.length; i++) {\n\t\tconst sourceEdit = edits[i];\n\t\tconst oldText = normalizeToLF(sourceEdit.oldText);\n\t\tconst newText = normalizeToLF(sourceEdit.newText);\n\t\tif (oldText.length === 0) throw getEmptyOldTextError(path, i, edits.length);\n\n\t\tconst exactWindow = validateRange(\n\t\t\tsourceEdit.range,\n\t\t\toriginalLineStarts,\n\t\t\tnormalizedContent.length,\n\t\t\tpath,\n\t\t\ti,\n\t\t\tedits.length,\n\t\t);\n\t\tlet matchIndex = findWithin(normalizedContent, oldText, exactWindow);\n\t\tlet matchLength = oldText.length;\n\t\tlet occurrences: number;\n\n\t\tif (matchIndex !== -1) {\n\t\t\toccurrences = countExactOccurrences(normalizedContent, oldText);\n\t\t} else {\n\t\t\tfuzzyContent ??= normalizeForFuzzyMatch(normalizedContent);\n\t\t\tfuzzyLineStarts ??= getLineStarts(fuzzyContent);\n\t\t\toriginalLineStarts ??= getLineStarts(normalizedContent);\n\t\t\tconst fuzzyOldText = normalizeForFuzzyMatch(oldText);\n\t\t\tconst fuzzyWindow = validateRange(\n\t\t\t\tsourceEdit.range,\n\t\t\t\tfuzzyLineStarts,\n\t\t\t\tfuzzyContent.length,\n\t\t\t\tpath,\n\t\t\t\ti,\n\t\t\t\tedits.length,\n\t\t\t);\n\t\t\tconst fuzzyIndex = findWithin(fuzzyContent, fuzzyOldText, fuzzyWindow);\n\t\t\tif (fuzzyIndex === -1) throw getNotFoundError(path, i, edits.length, sourceEdit.range);\n\t\t\toccurrences = countExactOccurrences(fuzzyContent, fuzzyOldText);\n\t\t\tconst replacementSpan = mapFuzzySpanToOriginal(\n\t\t\t\tnormalizedContent,\n\t\t\t\toriginalLineStarts,\n\t\t\t\tfuzzyLineStarts,\n\t\t\t\tfuzzyIndex,\n\t\t\t\tfuzzyOldText.length,\n\t\t\t);\n\t\t\tmatchIndex = replacementSpan.index;\n\t\t\tmatchLength = replacementSpan.length;\n\t\t}\n\n\t\tif (occurrences > 1) {\n\t\t\tthrow getDuplicateError(path, i, edits.length, occurrences);\n\t\t}\n\n\t\tmatchedEdits.push({\n\t\t\teditIndex: i,\n\t\t\tmatchIndex,\n\t\t\tmatchLength,\n\t\t\tnewText,\n\t\t\texpectedText: normalizedContent.slice(matchIndex, matchIndex + matchLength),\n\t\t});\n\t}\n\n\tmatchedEdits.sort((a, b) => a.matchIndex - b.matchIndex);\n\tfor (let i = 1; i < matchedEdits.length; i++) {\n\t\tconst previous = matchedEdits[i - 1];\n\t\tconst current = matchedEdits[i];\n\t\tif (rangesOverlap(previous, current)) {\n\t\t\tthrow new Error(\n\t\t\t\t`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${path}. Merge them into one edit or target disjoint regions.`,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn { baseLength: normalizedContent.length, editCount: edits.length, edits: matchedEdits };\n}\n\n/** Apply a validated match plan to the same LF-normalized source in one linear join. */\nexport function applyEditMatchPlan(normalizedContent: string, plan: EditMatchPlan, path: string): AppliedEditsResult {\n\tif (normalizedContent.length !== plan.baseLength) {\n\t\tthrow new Error(`The validated edit plan for ${path} is stale because the source length changed.`);\n\t}\n\n\tconst parts: string[] = [];\n\tlet sourceIndex = 0;\n\tfor (const edit of plan.edits) {\n\t\tif (!normalizedContent.startsWith(edit.expectedText, edit.matchIndex)) {\n\t\t\tthrow new Error(`The validated edit plan for ${path} is stale at edits[${edit.editIndex}].`);\n\t\t}\n\t\tparts.push(normalizedContent.slice(sourceIndex, edit.matchIndex), edit.newText);\n\t\tsourceIndex = edit.matchIndex + edit.matchLength;\n\t}\n\tparts.push(normalizedContent.slice(sourceIndex));\n\tconst newContent = parts.join(\"\");\n\n\tif (normalizedContent === newContent) throw getNoChangeError(path, plan.editCount);\n\treturn { baseContent: normalizedContent, newContent };\n}\n\nexport function applyEditsToNormalizedContent(\n\tnormalizedContent: string,\n\tedits: Edit[],\n\tpath: string,\n): AppliedEditsResult {\n\treturn applyEditMatchPlan(normalizedContent, planEditsToNormalizedContent(normalizedContent, edits, path), path);\n}\n\n/** Generate a standard unified patch. */\nexport function generateUnifiedPatch(path: string, oldContent: string, newContent: string, contextLines = 4): string {\n\treturn Diff.createTwoFilesPatch(path, path, oldContent, newContent, undefined, undefined, {\n\t\tcontext: contextLines,\n\t\theaderOptions: Diff.FILE_HEADERS_ONLY,\n\t});\n}\n\n/**\n * Generate a display-oriented diff string with line numbers and context.\n * Returns both the diff string and the first changed line number (in the new file).\n */\nexport function generateDiffString(\n\toldContent: string,\n\tnewContent: string,\n\tcontextLines = 4,\n): { diff: string; firstChangedLine: number | undefined } {\n\tconst parts = Diff.diffLines(oldContent, newContent);\n\tconst output: string[] = [];\n\n\tconst oldLines = oldContent.split(\"\\n\");\n\tconst newLines = newContent.split(\"\\n\");\n\tconst maxLineNum = Math.max(oldLines.length, newLines.length);\n\tconst lineNumWidth = String(maxLineNum).length;\n\n\tlet oldLineNum = 1;\n\tlet newLineNum = 1;\n\tlet lastWasChange = false;\n\tlet firstChangedLine: number | undefined;\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tconst raw = part.value.split(\"\\n\");\n\t\tif (raw[raw.length - 1] === \"\") {\n\t\t\traw.pop();\n\t\t}\n\n\t\tif (part.added || part.removed) {\n\t\t\t// Capture the first changed line (in the new file)\n\t\t\tif (firstChangedLine === undefined) {\n\t\t\t\tfirstChangedLine = newLineNum;\n\t\t\t}\n\n\t\t\t// Show the change\n\t\t\tfor (const line of raw) {\n\t\t\t\tif (part.added) {\n\t\t\t\t\tconst lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`+${lineNum} ${line}`);\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t} else {\n\t\t\t\t\t// removed\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`-${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlastWasChange = true;\n\t\t} else {\n\t\t\t// Context lines - only show a few before/after changes\n\t\t\tconst nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n\t\t\tconst hasLeadingChange = lastWasChange;\n\t\t\tconst hasTrailingChange = nextPartIsChange;\n\n\t\t\tif (hasLeadingChange && hasTrailingChange) {\n\t\t\t\tif (raw.length <= contextLines * 2) {\n\t\t\t\t\tfor (const line of raw) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst leadingLines = raw.slice(0, contextLines);\n\t\t\t\t\tconst trailingLines = raw.slice(raw.length - contextLines);\n\t\t\t\t\tconst skippedLines = raw.length - leadingLines.length - trailingLines.length;\n\n\t\t\t\t\tfor (const line of leadingLines) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\n\t\t\t\t\tfor (const line of trailingLines) {\n\t\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\t\toldLineNum++;\n\t\t\t\t\t\tnewLineNum++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (hasLeadingChange) {\n\t\t\t\tconst shownLines = raw.slice(0, contextLines);\n\t\t\t\tconst skippedLines = raw.length - shownLines.length;\n\n\t\t\t\tfor (const line of shownLines) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\n\t\t\t\tif (skippedLines > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\t\t\t\t}\n\t\t\t} else if (hasTrailingChange) {\n\t\t\t\tconst skippedLines = Math.max(0, raw.length - contextLines);\n\t\t\t\tif (skippedLines > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skippedLines;\n\t\t\t\t\tnewLineNum += skippedLines;\n\t\t\t\t}\n\n\t\t\t\tfor (const line of raw.slice(skippedLines)) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Skip these context lines entirely\n\t\t\t\toldLineNum += raw.length;\n\t\t\t\tnewLineNum += raw.length;\n\t\t\t}\n\n\t\t\tlastWasChange = false;\n\t\t}\n\t}\n\n\treturn { diff: output.join(\"\\n\"), firstChangedLine };\n}\n\nexport interface EditDiffResult {\n\tdiff: string;\n\tfirstChangedLine: number | undefined;\n}\n\nexport interface EditDiffError {\n\terror: string;\n}\n\nexport interface EditPlannedDiffResult extends EditDiffResult {\n\tplan: EditMatchPlan;\n\tsourceDigest: string;\n}\n\n/**\n * Compute the diff for one or more edit operations without applying them.\n * Used for preview rendering in the TUI before the tool executes.\n */\nexport async function computeEditsPlannedDiff(\n\tpath: string,\n\tedits: Edit[],\n\tcwd: string,\n): Promise<EditPlannedDiffResult | EditDiffError> {\n\tconst absolutePath = resolveToCwd(path, cwd);\n\n\ttry {\n\t\t// Check if file exists and is readable\n\t\ttry {\n\t\t\tawait access(absolutePath, constants.R_OK);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error && \"code\" in error ? `Error code: ${error.code}` : String(error);\n\t\t\treturn { error: `Could not edit file: ${path}. ${errorMessage}.` };\n\t\t}\n\n\t\t// Read the file\n\t\tconst rawContent = await readFile(absolutePath, \"utf-8\");\n\n\t\t// Strip BOM before matching (LLM won't include invisible BOM in oldText)\n\t\tconst { text: content } = stripBom(rawContent);\n\t\tconst normalizedContent = normalizeToLF(content);\n\t\tconst plan = planEditsToNormalizedContent(normalizedContent, edits, path);\n\t\tconst { baseContent, newContent } = applyEditMatchPlan(normalizedContent, plan, path);\n\n\t\t// Generate the diff\n\t\treturn {\n\t\t\t...generateDiffString(baseContent, newContent),\n\t\t\tplan,\n\t\t\tsourceDigest: digestNormalizedEditSource(normalizedContent),\n\t\t};\n\t} catch (err) {\n\t\treturn { error: err instanceof Error ? err.message : String(err) };\n\t}\n}\n\nexport async function computeEditsDiff(\n\tpath: string,\n\tedits: Edit[],\n\tcwd: string,\n): Promise<EditDiffResult | EditDiffError> {\n\tconst result = await computeEditsPlannedDiff(path, edits, cwd);\n\tif (\"error\" in result) return result;\n\treturn { diff: result.diff, firstChangedLine: result.firstChangedLine };\n}\n\n/**\n * Compute the diff for a single edit operation without applying it.\n * Kept as a convenience wrapper for single-edit callers.\n */\nexport async function computeEditDiff(\n\tpath: string,\n\toldText: string,\n\tnewText: string,\n\tcwd: string,\n): Promise<EditDiffResult | EditDiffError> {\n\treturn computeEditsDiff(path, [{ oldText, newText }], cwd);\n}\n"]}
@@ -9,12 +9,7 @@ type EditRenderState = {
9
9
  callComponent?: EditCallRenderComponent;
10
10
  };
11
11
  declare const editSchema: Type.TUnion<[Type.TObject<{
12
- action: Type.TLiteral<"prepare">;
13
12
  path: Type.TString;
14
- }>, Type.TObject<{
15
- action: Type.TLiteral<"commit">;
16
- path: Type.TString;
17
- intentId: Type.TString;
18
13
  edits: Type.TArray<Type.TObject<{
19
14
  oldText: Type.TString;
20
15
  newText: Type.TString;
@@ -23,11 +18,13 @@ declare const editSchema: Type.TUnion<[Type.TObject<{
23
18
  endLine: Type.TInteger;
24
19
  }>>;
25
20
  }>>;
21
+ }>, Type.TObject<{
22
+ path: Type.TString;
23
+ payloadRef: Type.TString;
26
24
  }>]>;
27
25
  export type EditToolInput = Static<typeof editSchema>;
28
26
  export interface EditToolDetails {
29
- phase: "prepared" | "committed";
30
- intentId?: string;
27
+ phase: "edited";
31
28
  contentRef?: string;
32
29
  /** Display-oriented diff of the changes made */
33
30
  diff?: string;
@@ -51,7 +48,7 @@ export interface EditOperations {
51
48
  export interface EditToolOptions {
52
49
  /** Custom operations for file editing. Default: local filesystem */
53
50
  operations?: EditOperations;
54
- /** Session-owned two-phase intent and exact-content-reference authority. */
51
+ /** Session-owned harness preflight and exact-content-reference authority. */
55
52
  intentController?: FileMutationIntentController;
56
53
  }
57
54
  type EditCallRenderComponent = Box & {
@@ -1 +1 @@
1
- {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,GAAG,EAA2B,MAAM,oBAAoB,CAAC;AAElE,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAMN,KAAK,aAAa,EAClB,KAAK,cAAc,EAOnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAMzE,KAAK,WAAW,GAAG,cAAc,GAAG,aAAa,CAAC;AAElD,KAAK,eAAe,GAAG;IACtB,aAAa,CAAC,EAAE,uBAAuB,CAAC;CACxC,CAAC;AAoBF,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;IAmBd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAUtD,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,UAAU,GAAG,WAAW,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wFAAwF;IACxF,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,8BAA8B;IAC9B,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE;AAOD,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,4BAA4B,CAAC;CAChD;AA6CD,KAAK,uBAAuB,GAAG,GAAG,GAAG;IACpC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAgLF,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,EAAE,eAAe,CAAC,CAkLjF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG"}
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,GAAG,EAA2B,MAAM,oBAAoB,CAAC;AAElE,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAON,KAAK,aAAa,EAClB,KAAK,cAAc,EAOnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACN,4BAA4B,EAG5B,MAAM,2BAA2B,CAAC;AAMnC,KAAK,WAAW,GAAG,cAAc,GAAG,aAAa,CAAC;AAElD,KAAK,eAAe,GAAG;IACtB,aAAa,CAAC,EAAE,uBAAuB,CAAC;CACxC,CAAC;AAoBF,QAAA,MAAM,UAAU;;;;;;;;;;;;;IAiBd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAStD,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,QAAQ,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wFAAwF;IACxF,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,8BAA8B;IAC9B,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE;AAOD,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,4BAA4B,CAAC;CAChD;AA0DD,KAAK,uBAAuB,GAAG,GAAG,GAAG;IACpC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAwMF,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,EAAE,eAAe,CAAC,CA+LjF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG"}
@@ -2,9 +2,9 @@ import { Box, Container, Spacer, Text } from "@caupulican/pi-tui";
2
2
  import { readFile as fsReadFile, writeFile as fsWriteFile } from "fs/promises";
3
3
  import { Type } from "typebox";
4
4
  import { renderDiff } from "../../modes/interactive/components/diff.js";
5
- import { applyEditMatchPlan, applyEditsToNormalizedContent, computeEditsPlannedDiff, detectLineEnding, generateDiffString, generateUnifiedPatch, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
5
+ import { applyEditMatchPlan, applyEditsToNormalizedContent, computeEditsPlannedDiff, detectLineEnding, digestNormalizedEditSource, generateDiffString, generateUnifiedPatch, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
6
6
  import { isValidUTF8 } from "./file-encoding-policy.js";
7
- import { FileMutationIntentController } from "./file-mutation-intent.js";
7
+ import { FileMutationIntentController, FileMutationPreflightError, } from "./file-mutation-intent.js";
8
8
  import { withFileMutationQueue } from "./file-mutation-queue.js";
9
9
  import { resolveToCwd } from "./path-utils.js";
10
10
  import { renderToolPath, str } from "./render-utils.js";
@@ -20,43 +20,52 @@ const replaceEditSchema = Type.Object({
20
20
  const editPathSchema = Type.String({ minLength: 1 });
21
21
  const editSchema = Type.Union([
22
22
  Type.Object({
23
- action: Type.Literal("prepare"),
24
23
  path: editPathSchema,
25
- }, { additionalProperties: false }),
26
- Type.Object({
27
- action: Type.Literal("commit"),
28
- path: editPathSchema,
29
- intentId: Type.String({ minLength: 1 }),
30
24
  edits: Type.Array(replaceEditSchema, {
31
25
  minItems: 1,
32
26
  }),
33
27
  }, { additionalProperties: false }),
28
+ Type.Object({
29
+ path: editPathSchema,
30
+ payloadRef: Type.String({ minLength: 1 }),
31
+ }, { additionalProperties: false }),
34
32
  ]);
35
33
  const defaultEditOperations = {
36
34
  readFile: (path) => fsReadFile(path),
37
35
  writeFile: (path, content) => fsWriteFile(path, content, "utf-8"),
38
36
  };
39
37
  function prepareEditArguments(input) {
40
- if (!input || typeof input !== "object") {
38
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
41
39
  return input;
42
40
  }
43
- const args = input;
41
+ let args = input;
44
42
  const legacy = args;
45
- if (typeof legacy.oldText !== "string" || typeof legacy.newText !== "string") {
46
- return args;
43
+ if (typeof legacy.oldText === "string" && typeof legacy.newText === "string") {
44
+ const edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];
45
+ edits.push({ oldText: legacy.oldText, newText: legacy.newText });
46
+ const { oldText: _oldText, newText: _newText, ...rest } = legacy;
47
+ args = { ...rest, edits };
47
48
  }
48
- const edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];
49
- edits.push({ oldText: legacy.oldText, newText: legacy.newText });
50
- const { oldText: _oldText, newText: _newText, ...rest } = legacy;
51
- return { ...rest, edits };
49
+ return args;
52
50
  }
53
- function validateEditInput(input) {
54
- if (input.action === "prepare")
55
- return input;
56
- if (!Array.isArray(input.edits) || input.edits.length === 0) {
51
+ function validateEdits(edits) {
52
+ if (!Array.isArray(edits) || edits.length === 0) {
57
53
  throw new Error("Edit tool input is invalid. edits must contain at least one replacement.");
58
54
  }
59
- return { action: "commit", path: input.path, intentId: input.intentId, edits: input.edits };
55
+ for (const edit of edits) {
56
+ if (typeof edit !== "object" ||
57
+ edit === null ||
58
+ typeof edit.oldText !== "string" ||
59
+ typeof edit.newText !== "string") {
60
+ throw new Error("Edit tool input is invalid. Every edit requires string oldText and newText fields.");
61
+ }
62
+ }
63
+ return edits;
64
+ }
65
+ function validateEditInput(input) {
66
+ if ("payloadRef" in input)
67
+ return { path: input.path, payloadRef: input.payloadRef };
68
+ return { path: input.path, edits: validateEdits(input.edits) };
60
69
  }
61
70
  function createEditCallRenderComponent() {
62
71
  return Object.assign(new Box(1, 1, (text) => text), {
@@ -83,21 +92,17 @@ function getRenderablePreviewInput(args) {
83
92
  if (!args) {
84
93
  return null;
85
94
  }
86
- if (args.action !== "commit")
87
- return null;
88
95
  const path = typeof args.path === "string" ? args.path : typeof args.file_path === "string" ? args.file_path : null;
89
96
  if (!path) {
90
97
  return null;
91
98
  }
92
- if (typeof args.intentId !== "string" || args.intentId.length === 0)
93
- return null;
94
99
  if (Array.isArray(args.edits) &&
95
100
  args.edits.length > 0 &&
96
101
  args.edits.every((edit) => typeof edit?.oldText === "string" && typeof edit?.newText === "string")) {
97
- return { path, intentId: args.intentId, edits: args.edits };
102
+ return { path, edits: args.edits };
98
103
  }
99
104
  if (typeof args.oldText === "string" && typeof args.newText === "string") {
100
- return { path, intentId: args.intentId, edits: [{ oldText: args.oldText, newText: args.newText }] };
105
+ return { path, edits: [{ oldText: args.oldText, newText: args.newText }] };
101
106
  }
102
107
  return null;
103
108
  }
@@ -125,8 +130,7 @@ function editsMatch(left, right) {
125
130
  }
126
131
  function formatEditCall(args, theme, cwd) {
127
132
  const pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);
128
- const action = args?.action === "prepare" ? "prepare" : args?.action === "commit" ? "commit" : undefined;
129
- return `${theme.fg("toolTitle", theme.bold("edit"))}${action ? ` ${theme.fg("muted", action)}` : ""} ${pathDisplay}`;
133
+ return `${theme.fg("toolTitle", theme.bold("edit"))} ${pathDisplay}`;
130
134
  }
131
135
  function formatEditResult(args, preview, result, theme, isError) {
132
136
  const rawPath = str(args?.file_path ?? args?.path);
@@ -148,6 +152,23 @@ function formatEditResult(args, preview, result, theme, isError) {
148
152
  }
149
153
  return undefined;
150
154
  }
155
+ async function editPathFailureWithRetainedPayload(error, validated, intentController, signal) {
156
+ const failureIdentity = error.reason === "edit_missing" ? "edit_missing (ENOENT)" : "edit_not_file";
157
+ if (validated.payloadRef) {
158
+ await intentController.assertMutationPayload(validated.payloadRef, "edit", signal);
159
+ return new Error(`PI_FILE_MUTATION_RETARGET ${failureIdentity}: payloadRef ${validated.payloadRef}. Choose only a corrected path naming an existing file; the exact valid edit payload is retained for full revalidation.`);
160
+ }
161
+ try {
162
+ const retained = await intentController.retainMutationPayload("edit", JSON.stringify(validated.edits));
163
+ if (retained) {
164
+ return new Error(`PI_FILE_MUTATION_RETARGET ${failureIdentity}: payloadRef ${retained.payloadRef}. Choose only a corrected path naming an existing file; the exact valid edit payload is retained for full revalidation.`);
165
+ }
166
+ }
167
+ catch {
168
+ // The path failure remains authoritative when the bounded retry cache is unavailable.
169
+ }
170
+ return new Error(`${error.message} The edit payload could not be retained within the secure retry-cache bound.`);
171
+ }
151
172
  function getEditHeaderBg(preview, settledError, theme) {
152
173
  if (preview) {
153
174
  if ("error" in preview) {
@@ -195,10 +216,11 @@ export function createEditToolDefinition(cwd, options) {
195
216
  return {
196
217
  name: "edit",
197
218
  label: "edit",
198
- description: "Edit existing UTF-8 text: prepare(path), then commit(path,intentId,edits). oldText must be exact, unique, and non-overlapping; optional inclusive line ranges bind matches to prior reads; stale targets are rejected.",
199
- promptSnippet: "Preflight existing files; commit exact, stale-safe edits",
219
+ description: "Edit existing UTF-8 text in one call. Send path and all edits; after a path-only failure, reuse the returned payloadRef with only the corrected path. The harness preflights, revalidates, and stale-checks every exact replacement.",
220
+ promptSnippet: "Preflight existing files; apply exact, stale-safe edits",
200
221
  promptGuidelines: [
201
- "Before replacements, prepare(path); then commit once with intentId and all edits.",
222
+ "Call edit once with path and all replacements; preparation and stale-target checks are harness-owned.",
223
+ "If a path failure returns payloadRef, choose the correct existing path and reuse that reference instead of regenerating edits.",
202
224
  "oldText is exact, unique, minimal, and original-file based; pass the inclusive line range from the supplying read when known, batch separate edits, and merge overlaps.",
203
225
  ],
204
226
  parameters: editSchema,
@@ -208,6 +230,17 @@ export function createEditToolDefinition(cwd, options) {
208
230
  const validated = validateEditInput(input);
209
231
  const { path } = validated;
210
232
  const absolutePath = resolveToCwd(path, cwd);
233
+ let lease;
234
+ try {
235
+ lease = await intentController.prepare("edit", absolutePath, signal, path);
236
+ }
237
+ catch (error) {
238
+ if (error instanceof FileMutationPreflightError &&
239
+ (error.reason === "edit_missing" || error.reason === "edit_not_file")) {
240
+ throw await editPathFailureWithRetainedPayload(error, validated, intentController, signal);
241
+ }
242
+ throw error;
243
+ }
211
244
  return withFileMutationQueue(absolutePath, async () => {
212
245
  // Do not reject from an abort event listener here: that would release the
213
246
  // mutation queue while an in-flight filesystem operation may still finish.
@@ -218,20 +251,15 @@ export function createEditToolDefinition(cwd, options) {
218
251
  throw new Error("Operation aborted");
219
252
  };
220
253
  throwIfAborted();
221
- if (validated.action === "prepare") {
222
- const prepared = await intentController.prepare("edit", absolutePath, signal, path);
223
- return {
224
- content: [
225
- {
226
- type: "text",
227
- text: `Edit target accepted. Commit ${path} with intentId ${prepared.intentId}.`,
228
- },
229
- ],
230
- details: { phase: "prepared", intentId: prepared.intentId },
231
- };
254
+ let payloadRef;
255
+ let edits;
256
+ if (validated.edits !== undefined) {
257
+ edits = validated.edits;
258
+ }
259
+ else {
260
+ payloadRef = validated.payloadRef;
261
+ edits = validateEdits(JSON.parse(await intentController.readMutationPayload(payloadRef, "edit", signal)));
232
262
  }
233
- const { edits, intentId } = validated;
234
- const lease = intentController.consume(intentId, "edit", absolutePath);
235
263
  await intentController.assertCurrent(lease, signal);
236
264
  throwIfAborted();
237
265
  // Read the file.
@@ -245,33 +273,38 @@ export function createEditToolDefinition(cwd, options) {
245
273
  const { bom, text: content } = stripBom(rawContent);
246
274
  const originalEnding = detectLineEnding(content);
247
275
  const normalizedContent = normalizeToLF(content);
248
- const cachedForIntent = cachedMatchPlan?.intentId === intentId ? cachedMatchPlan : undefined;
249
- if (cachedForIntent)
276
+ const cachedForInput = cachedMatchPlan?.absolutePath === absolutePath && editsMatch(cachedMatchPlan.edits, edits)
277
+ ? cachedMatchPlan
278
+ : undefined;
279
+ if (cachedForInput)
250
280
  cachedMatchPlan = undefined;
251
- const matchPlanReused = cachedForIntent !== undefined &&
252
- cachedForIntent.absolutePath === absolutePath &&
253
- editsMatch(cachedForIntent.edits, edits);
281
+ const matchPlanReused = cachedForInput !== undefined &&
282
+ cachedForInput.sourceDigest === digestNormalizedEditSource(normalizedContent);
254
283
  const { baseContent, newContent } = matchPlanReused
255
- ? applyEditMatchPlan(normalizedContent, cachedForIntent.plan, path)
284
+ ? applyEditMatchPlan(normalizedContent, cachedForInput.plan, path)
256
285
  : applyEditsToNormalizedContent(normalizedContent, edits, path);
257
286
  throwIfAborted();
258
287
  const finalContent = bom + restoreLineEndings(newContent, originalEnding);
288
+ await intentController.assertCurrent(lease, signal);
289
+ throwIfAborted();
259
290
  await ops.writeFile(absolutePath, finalContent);
260
291
  throwIfAborted();
261
292
  const contentReference = intentController.rememberContent(absolutePath, finalContent);
293
+ if (payloadRef)
294
+ await intentController.discardMutationPayload(payloadRef);
262
295
  const diffResult = matchPlanReused
263
- ? { diff: cachedForIntent.diff, firstChangedLine: cachedForIntent.firstChangedLine }
296
+ ? { diff: cachedForInput.diff, firstChangedLine: cachedForInput.firstChangedLine }
264
297
  : generateDiffString(baseContent, newContent);
265
298
  const patch = generateUnifiedPatch(path, baseContent, newContent);
266
299
  return {
267
300
  content: [
268
301
  {
269
302
  type: "text",
270
- text: `Successfully replaced ${edits.length} block(s) in ${path}. Reuse exact bytes with contentRef ${contentReference.contentRef}.`,
303
+ text: `Successfully replaced ${edits.length} block(s) in ${path}; this edit is complete, so do not call edit again for this path. To copy these exact bytes to a different new path, call write once for that path with contentRef ${contentReference.contentRef}.`,
271
304
  },
272
305
  ],
273
306
  details: {
274
- phase: "committed",
307
+ phase: "edited",
275
308
  contentRef: contentReference.contentRef,
276
309
  diff: diffResult.diff,
277
310
  patch,
@@ -297,10 +330,10 @@ export function createEditToolDefinition(cwd, options) {
297
330
  if (component.previewRequestId === requestId) {
298
331
  if (!("error" in preview) && !options?.operations) {
299
332
  cachedMatchPlan = {
300
- intentId: previewInput.intentId,
301
333
  absolutePath: resolveToCwd(previewInput.path, context.cwd),
302
334
  edits: snapshotEdits(previewInput.edits),
303
335
  plan: preview.plan,
336
+ sourceDigest: preview.sourceDigest,
304
337
  diff: preview.diff,
305
338
  firstChangedLine: preview.firstChangedLine,
306
339
  };