claude-ide-bridge 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +263 -0
  3. package/dist/activityLog.d.ts +26 -0
  4. package/dist/activityLog.js +76 -0
  5. package/dist/activityLog.js.map +1 -0
  6. package/dist/bridge.d.ts +19 -0
  7. package/dist/bridge.js +277 -0
  8. package/dist/bridge.js.map +1 -0
  9. package/dist/config.d.ts +22 -0
  10. package/dist/config.js +221 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/errors.d.ts +16 -0
  13. package/dist/errors.js +20 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/extensionClient.d.ts +193 -0
  16. package/dist/extensionClient.js +698 -0
  17. package/dist/extensionClient.js.map +1 -0
  18. package/dist/fileLock.d.ts +12 -0
  19. package/dist/fileLock.js +30 -0
  20. package/dist/fileLock.js.map +1 -0
  21. package/dist/index.d.ts +2 -0
  22. package/dist/index.js +38 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/lockfile.d.ts +12 -0
  25. package/dist/lockfile.js +127 -0
  26. package/dist/lockfile.js.map +1 -0
  27. package/dist/logger.d.ts +16 -0
  28. package/dist/logger.js +68 -0
  29. package/dist/logger.js.map +1 -0
  30. package/dist/probe.d.ts +22 -0
  31. package/dist/probe.js +45 -0
  32. package/dist/probe.js.map +1 -0
  33. package/dist/server.d.ts +25 -0
  34. package/dist/server.js +265 -0
  35. package/dist/server.js.map +1 -0
  36. package/dist/tools/activityLog.d.ts +39 -0
  37. package/dist/tools/activityLog.js +49 -0
  38. package/dist/tools/activityLog.js.map +1 -0
  39. package/dist/tools/aiComments.d.ts +26 -0
  40. package/dist/tools/aiComments.js +196 -0
  41. package/dist/tools/aiComments.js.map +1 -0
  42. package/dist/tools/bridgeStatus.d.ts +21 -0
  43. package/dist/tools/bridgeStatus.js +41 -0
  44. package/dist/tools/bridgeStatus.js.map +1 -0
  45. package/dist/tools/checkDocumentDirty.d.ts +28 -0
  46. package/dist/tools/checkDocumentDirty.js +61 -0
  47. package/dist/tools/checkDocumentDirty.js.map +1 -0
  48. package/dist/tools/clipboard.d.ts +50 -0
  49. package/dist/tools/clipboard.js +82 -0
  50. package/dist/tools/clipboard.js.map +1 -0
  51. package/dist/tools/closeTabs.d.ts +49 -0
  52. package/dist/tools/closeTabs.js +77 -0
  53. package/dist/tools/closeTabs.js.map +1 -0
  54. package/dist/tools/debug.d.ts +154 -0
  55. package/dist/tools/debug.js +248 -0
  56. package/dist/tools/debug.js.map +1 -0
  57. package/dist/tools/decorations.d.ts +92 -0
  58. package/dist/tools/decorations.js +150 -0
  59. package/dist/tools/decorations.js.map +1 -0
  60. package/dist/tools/diffDebugger.d.ts +62 -0
  61. package/dist/tools/diffDebugger.js +245 -0
  62. package/dist/tools/diffDebugger.js.map +1 -0
  63. package/dist/tools/editText.d.ts +80 -0
  64. package/dist/tools/editText.js +274 -0
  65. package/dist/tools/editText.js.map +1 -0
  66. package/dist/tools/fileOperations.d.ts +111 -0
  67. package/dist/tools/fileOperations.js +280 -0
  68. package/dist/tools/fileOperations.js.map +1 -0
  69. package/dist/tools/fileWatcher.d.ts +54 -0
  70. package/dist/tools/fileWatcher.js +100 -0
  71. package/dist/tools/fileWatcher.js.map +1 -0
  72. package/dist/tools/findFiles.d.ts +31 -0
  73. package/dist/tools/findFiles.js +119 -0
  74. package/dist/tools/findFiles.js.map +1 -0
  75. package/dist/tools/fixAllLintErrors.d.ts +29 -0
  76. package/dist/tools/fixAllLintErrors.js +114 -0
  77. package/dist/tools/fixAllLintErrors.js.map +1 -0
  78. package/dist/tools/flowGuardian.d.ts +61 -0
  79. package/dist/tools/flowGuardian.js +311 -0
  80. package/dist/tools/flowGuardian.js.map +1 -0
  81. package/dist/tools/formatDocument.d.ts +30 -0
  82. package/dist/tools/formatDocument.js +132 -0
  83. package/dist/tools/formatDocument.js.map +1 -0
  84. package/dist/tools/formatFile.d.ts +28 -0
  85. package/dist/tools/formatFile.js +110 -0
  86. package/dist/tools/formatFile.js.map +1 -0
  87. package/dist/tools/getBufferContent.d.ts +38 -0
  88. package/dist/tools/getBufferContent.js +100 -0
  89. package/dist/tools/getBufferContent.js.map +1 -0
  90. package/dist/tools/getCurrentSelection.d.ts +43 -0
  91. package/dist/tools/getCurrentSelection.js +75 -0
  92. package/dist/tools/getCurrentSelection.js.map +1 -0
  93. package/dist/tools/getDiagnostics.d.ts +38 -0
  94. package/dist/tools/getDiagnostics.js +204 -0
  95. package/dist/tools/getDiagnostics.js.map +1 -0
  96. package/dist/tools/getDocumentSymbols.d.ts +27 -0
  97. package/dist/tools/getDocumentSymbols.js +133 -0
  98. package/dist/tools/getDocumentSymbols.js.map +1 -0
  99. package/dist/tools/getFileTree.d.ts +36 -0
  100. package/dist/tools/getFileTree.js +111 -0
  101. package/dist/tools/getFileTree.js.map +1 -0
  102. package/dist/tools/getGitDiff.d.ts +34 -0
  103. package/dist/tools/getGitDiff.js +57 -0
  104. package/dist/tools/getGitDiff.js.map +1 -0
  105. package/dist/tools/getGitLog.d.ts +30 -0
  106. package/dist/tools/getGitLog.js +65 -0
  107. package/dist/tools/getGitLog.js.map +1 -0
  108. package/dist/tools/getGitStatus.d.ts +26 -0
  109. package/dist/tools/getGitStatus.js +95 -0
  110. package/dist/tools/getGitStatus.js.map +1 -0
  111. package/dist/tools/getOpenEditors.d.ts +21 -0
  112. package/dist/tools/getOpenEditors.js +84 -0
  113. package/dist/tools/getOpenEditors.js.map +1 -0
  114. package/dist/tools/getProjectInfo.d.ts +20 -0
  115. package/dist/tools/getProjectInfo.js +315 -0
  116. package/dist/tools/getProjectInfo.js.map +1 -0
  117. package/dist/tools/getToolCapabilities.d.ts +23 -0
  118. package/dist/tools/getToolCapabilities.js +249 -0
  119. package/dist/tools/getToolCapabilities.js.map +1 -0
  120. package/dist/tools/getWorkspaceFolders.d.ts +21 -0
  121. package/dist/tools/getWorkspaceFolders.js +47 -0
  122. package/dist/tools/getWorkspaceFolders.js.map +1 -0
  123. package/dist/tools/gitHistory.d.ts +78 -0
  124. package/dist/tools/gitHistory.js +151 -0
  125. package/dist/tools/gitHistory.js.map +1 -0
  126. package/dist/tools/gitWrite.d.ts +335 -0
  127. package/dist/tools/gitWrite.js +859 -0
  128. package/dist/tools/gitWrite.js.map +1 -0
  129. package/dist/tools/github/actions.d.ts +67 -0
  130. package/dist/tools/github/actions.js +155 -0
  131. package/dist/tools/github/actions.js.map +1 -0
  132. package/dist/tools/github/index.d.ts +4 -0
  133. package/dist/tools/github/index.js +5 -0
  134. package/dist/tools/github/index.js.map +1 -0
  135. package/dist/tools/github/issues.d.ts +140 -0
  136. package/dist/tools/github/issues.js +279 -0
  137. package/dist/tools/github/issues.js.map +1 -0
  138. package/dist/tools/github/pr.d.ts +101 -0
  139. package/dist/tools/github/pr.js +215 -0
  140. package/dist/tools/github/pr.js.map +1 -0
  141. package/dist/tools/github/review.d.ts +101 -0
  142. package/dist/tools/github/review.js +292 -0
  143. package/dist/tools/github/review.js.map +1 -0
  144. package/dist/tools/github/shared.d.ts +4 -0
  145. package/dist/tools/github/shared.js +12 -0
  146. package/dist/tools/github/shared.js.map +1 -0
  147. package/dist/tools/github.d.ts +308 -0
  148. package/dist/tools/github.js +656 -0
  149. package/dist/tools/github.js.map +1 -0
  150. package/dist/tools/hoverAtCursor.d.ts +22 -0
  151. package/dist/tools/hoverAtCursor.js +51 -0
  152. package/dist/tools/hoverAtCursor.js.map +1 -0
  153. package/dist/tools/httpClient.d.ts +83 -0
  154. package/dist/tools/httpClient.js +335 -0
  155. package/dist/tools/httpClient.js.map +1 -0
  156. package/dist/tools/index.d.ts +7 -0
  157. package/dist/tools/index.js +246 -0
  158. package/dist/tools/index.js.map +1 -0
  159. package/dist/tools/inlayHints.d.ts +38 -0
  160. package/dist/tools/inlayHints.js +56 -0
  161. package/dist/tools/inlayHints.js.map +1 -0
  162. package/dist/tools/linters/biome.d.ts +2 -0
  163. package/dist/tools/linters/biome.js +44 -0
  164. package/dist/tools/linters/biome.js.map +1 -0
  165. package/dist/tools/linters/cargo.d.ts +2 -0
  166. package/dist/tools/linters/cargo.js +45 -0
  167. package/dist/tools/linters/cargo.js.map +1 -0
  168. package/dist/tools/linters/eslint.d.ts +2 -0
  169. package/dist/tools/linters/eslint.js +59 -0
  170. package/dist/tools/linters/eslint.js.map +1 -0
  171. package/dist/tools/linters/govet.d.ts +2 -0
  172. package/dist/tools/linters/govet.js +37 -0
  173. package/dist/tools/linters/govet.js.map +1 -0
  174. package/dist/tools/linters/pyright.d.ts +2 -0
  175. package/dist/tools/linters/pyright.js +34 -0
  176. package/dist/tools/linters/pyright.js.map +1 -0
  177. package/dist/tools/linters/ruff.d.ts +2 -0
  178. package/dist/tools/linters/ruff.js +30 -0
  179. package/dist/tools/linters/ruff.js.map +1 -0
  180. package/dist/tools/linters/types.d.ts +16 -0
  181. package/dist/tools/linters/types.js +2 -0
  182. package/dist/tools/linters/types.js.map +1 -0
  183. package/dist/tools/linters/typescript.d.ts +2 -0
  184. package/dist/tools/linters/typescript.js +38 -0
  185. package/dist/tools/linters/typescript.js.map +1 -0
  186. package/dist/tools/lsp.d.ts +310 -0
  187. package/dist/tools/lsp.js +684 -0
  188. package/dist/tools/lsp.js.map +1 -0
  189. package/dist/tools/notebook.d.ts +95 -0
  190. package/dist/tools/notebook.js +144 -0
  191. package/dist/tools/notebook.js.map +1 -0
  192. package/dist/tools/openDiff.d.ts +41 -0
  193. package/dist/tools/openDiff.js +116 -0
  194. package/dist/tools/openDiff.js.map +1 -0
  195. package/dist/tools/openFile.d.ts +34 -0
  196. package/dist/tools/openFile.js +102 -0
  197. package/dist/tools/openFile.js.map +1 -0
  198. package/dist/tools/organizeImports.d.ts +29 -0
  199. package/dist/tools/organizeImports.js +64 -0
  200. package/dist/tools/organizeImports.js.map +1 -0
  201. package/dist/tools/planPersistence.d.ts +196 -0
  202. package/dist/tools/planPersistence.js +437 -0
  203. package/dist/tools/planPersistence.js.map +1 -0
  204. package/dist/tools/replaceBlock.d.ts +40 -0
  205. package/dist/tools/replaceBlock.js +105 -0
  206. package/dist/tools/replaceBlock.js.map +1 -0
  207. package/dist/tools/runCommand.d.ts +43 -0
  208. package/dist/tools/runCommand.js +141 -0
  209. package/dist/tools/runCommand.js.map +1 -0
  210. package/dist/tools/runTests.d.ts +32 -0
  211. package/dist/tools/runTests.js +160 -0
  212. package/dist/tools/runTests.js.map +1 -0
  213. package/dist/tools/saveDocument.d.ts +28 -0
  214. package/dist/tools/saveDocument.js +58 -0
  215. package/dist/tools/saveDocument.js.map +1 -0
  216. package/dist/tools/searchAndReplace.d.ts +50 -0
  217. package/dist/tools/searchAndReplace.js +203 -0
  218. package/dist/tools/searchAndReplace.js.map +1 -0
  219. package/dist/tools/searchWorkspace.d.ts +52 -0
  220. package/dist/tools/searchWorkspace.js +159 -0
  221. package/dist/tools/searchWorkspace.js.map +1 -0
  222. package/dist/tools/setActiveWorkspaceFolder.d.ts +28 -0
  223. package/dist/tools/setActiveWorkspaceFolder.js +32 -0
  224. package/dist/tools/setActiveWorkspaceFolder.js.map +1 -0
  225. package/dist/tools/tasks.d.ts +56 -0
  226. package/dist/tools/tasks.js +89 -0
  227. package/dist/tools/tasks.js.map +1 -0
  228. package/dist/tools/terminal.d.ts +241 -0
  229. package/dist/tools/terminal.js +539 -0
  230. package/dist/tools/terminal.js.map +1 -0
  231. package/dist/tools/testRunners/cargoTest.d.ts +2 -0
  232. package/dist/tools/testRunners/cargoTest.js +123 -0
  233. package/dist/tools/testRunners/cargoTest.js.map +1 -0
  234. package/dist/tools/testRunners/goTest.d.ts +2 -0
  235. package/dist/tools/testRunners/goTest.js +106 -0
  236. package/dist/tools/testRunners/goTest.js.map +1 -0
  237. package/dist/tools/testRunners/pytest.d.ts +2 -0
  238. package/dist/tools/testRunners/pytest.js +133 -0
  239. package/dist/tools/testRunners/pytest.js.map +1 -0
  240. package/dist/tools/testRunners/types.d.ts +18 -0
  241. package/dist/tools/testRunners/types.js +2 -0
  242. package/dist/tools/testRunners/types.js.map +1 -0
  243. package/dist/tools/testRunners/vitestJest.d.ts +3 -0
  244. package/dist/tools/testRunners/vitestJest.js +178 -0
  245. package/dist/tools/testRunners/vitestJest.js.map +1 -0
  246. package/dist/tools/typeHierarchy.d.ts +45 -0
  247. package/dist/tools/typeHierarchy.js +65 -0
  248. package/dist/tools/typeHierarchy.js.map +1 -0
  249. package/dist/tools/utils.d.ts +54 -0
  250. package/dist/tools/utils.js +267 -0
  251. package/dist/tools/utils.js.map +1 -0
  252. package/dist/tools/vscodeCommands.d.ts +59 -0
  253. package/dist/tools/vscodeCommands.js +108 -0
  254. package/dist/tools/vscodeCommands.js.map +1 -0
  255. package/dist/tools/watchDiagnostics.d.ts +32 -0
  256. package/dist/tools/watchDiagnostics.js +87 -0
  257. package/dist/tools/watchDiagnostics.js.map +1 -0
  258. package/dist/tools/workspaceSettings.d.ts +67 -0
  259. package/dist/tools/workspaceSettings.js +102 -0
  260. package/dist/tools/workspaceSettings.js.map +1 -0
  261. package/dist/tools/workspaceSnapshots.d.ts +174 -0
  262. package/dist/tools/workspaceSnapshots.js +474 -0
  263. package/dist/tools/workspaceSnapshots.js.map +1 -0
  264. package/dist/transport.d.ts +57 -0
  265. package/dist/transport.js +417 -0
  266. package/dist/transport.js.map +1 -0
  267. package/dist/version.d.ts +2 -0
  268. package/dist/version.js +3 -0
  269. package/dist/version.js.map +1 -0
  270. package/dist/wsUtils.d.ts +9 -0
  271. package/dist/wsUtils.js +54 -0
  272. package/dist/wsUtils.js.map +1 -0
  273. package/package.json +69 -0
@@ -0,0 +1,245 @@
1
+ import path from "node:path";
2
+ import { error, execSafe, optionalBool, optionalInt, optionalString, resolveFilePath, success, } from "./utils.js";
3
+ function parseDiffHunks(diffOutput) {
4
+ const regions = new Map();
5
+ let currentFile = null;
6
+ for (const line of diffOutput.split("\n")) {
7
+ // Track current file from +++ line
8
+ if (line.startsWith("+++ b/")) {
9
+ currentFile = line.slice(6);
10
+ if (!regions.has(currentFile)) {
11
+ regions.set(currentFile, []);
12
+ }
13
+ continue;
14
+ }
15
+ // Skip binary files
16
+ if (line.startsWith("Binary files")) {
17
+ currentFile = null;
18
+ continue;
19
+ }
20
+ // Parse hunk headers
21
+ if (currentFile && line.startsWith("@@")) {
22
+ const match = line.match(/@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@(.*)/);
23
+ if (match) {
24
+ const newStart = Number.parseInt(match[1], 10);
25
+ const newCount = match[2] !== undefined ? Number.parseInt(match[2], 10) : 1;
26
+ const header = match[3]?.trim() ?? "";
27
+ if (newCount === 0) {
28
+ // Pure deletion — record as a point
29
+ regions.get(currentFile)?.push({
30
+ startLine: newStart,
31
+ endLine: newStart,
32
+ header,
33
+ });
34
+ }
35
+ else {
36
+ regions.get(currentFile)?.push({
37
+ startLine: newStart,
38
+ endLine: newStart + newCount - 1,
39
+ header,
40
+ });
41
+ }
42
+ }
43
+ }
44
+ }
45
+ return regions;
46
+ }
47
+ function lineDistance(line, regionStart, regionEnd) {
48
+ if (line >= regionStart && line <= regionEnd)
49
+ return 0;
50
+ if (line < regionStart)
51
+ return regionStart - line;
52
+ return line - regionEnd;
53
+ }
54
+ export function createDiffDebugTool(workspace, getDiagnosticsFn) {
55
+ return {
56
+ schema: {
57
+ name: "diffDebug",
58
+ description: "Correlate git diffs with diagnostics to identify which changes likely introduced errors or warnings. Compares changed regions with diagnostic locations.",
59
+ annotations: { readOnlyHint: true },
60
+ inputSchema: {
61
+ type: "object",
62
+ properties: {
63
+ commitRange: {
64
+ type: "string",
65
+ description: "Git commit range for the diff (e.g., 'HEAD~3..HEAD'). Default: working tree vs HEAD",
66
+ },
67
+ staged: {
68
+ type: "boolean",
69
+ description: "If true and no commitRange, diff staged changes vs HEAD. Default: false",
70
+ },
71
+ filePath: {
72
+ type: "string",
73
+ description: "Optional file path to limit analysis to",
74
+ },
75
+ proximity: {
76
+ type: "integer",
77
+ description: "Number of lines around a changed region to consider 'nearby'. Default: 3",
78
+ },
79
+ severity: {
80
+ oneOf: [
81
+ { type: "string" },
82
+ { type: "array", items: { type: "string" } },
83
+ ],
84
+ description: "Filter diagnostics by severity: 'error', 'warning', 'information', 'hint'. Single value or array.",
85
+ },
86
+ source: {
87
+ oneOf: [
88
+ { type: "string" },
89
+ { type: "array", items: { type: "string" } },
90
+ ],
91
+ description: "Filter diagnostics by source (e.g., 'tsc', 'eslint', 'pyright'). Single value or array.",
92
+ },
93
+ },
94
+ additionalProperties: false,
95
+ },
96
+ },
97
+ handler: async (args, signal) => {
98
+ const commitRange = optionalString(args, "commitRange");
99
+ const staged = optionalBool(args, "staged") ?? false;
100
+ const rawPath = optionalString(args, "filePath");
101
+ const proximity = optionalInt(args, "proximity", 0, 50) ?? 3;
102
+ // Reject git flag injection and invalid characters in commit range
103
+ if (commitRange?.startsWith("-")) {
104
+ return error("commitRange must be a revision range, not a flag");
105
+ }
106
+ // Allow word chars, dots, dashes, slashes, and git range/ref syntax (~^@:.)
107
+ if (commitRange && !/^[\w.\-/^~@:.]+$/.test(commitRange)) {
108
+ return error("commitRange contains invalid characters — use a valid git revision range (e.g. 'HEAD~3..HEAD')");
109
+ }
110
+ // Build diff command
111
+ const diffArgs = ["diff", "-U0"];
112
+ if (commitRange) {
113
+ diffArgs.push(commitRange);
114
+ }
115
+ else if (staged) {
116
+ diffArgs.push("--cached");
117
+ }
118
+ if (rawPath) {
119
+ const filterPath = resolveFilePath(rawPath, workspace);
120
+ diffArgs.push("--", filterPath);
121
+ }
122
+ const diffResult = await execSafe("git", diffArgs, {
123
+ cwd: workspace,
124
+ signal,
125
+ });
126
+ if (diffResult.exitCode !== 0 && !diffResult.stdout) {
127
+ return error(`git diff failed: ${diffResult.stderr.trim()}`);
128
+ }
129
+ const changedRegions = parseDiffHunks(diffResult.stdout);
130
+ // Get diagnostics
131
+ const diagResult = await getDiagnosticsFn({}, signal);
132
+ let diagnostics = [];
133
+ try {
134
+ const rawText = diagResult.content?.[0]?.text;
135
+ if (rawText) {
136
+ const parsed = JSON.parse(rawText);
137
+ diagnostics = parsed.diagnostics ?? parsed.results ?? [];
138
+ }
139
+ }
140
+ catch {
141
+ // If parsing fails, no diagnostics to correlate
142
+ }
143
+ // Apply severity/source filters
144
+ const rawSeverity = args.severity;
145
+ const severityFilter = rawSeverity
146
+ ? (Array.isArray(rawSeverity) ? rawSeverity : [rawSeverity]).filter((s) => typeof s === "string")
147
+ : null;
148
+ const rawSource = args.source;
149
+ const sourceFilter = rawSource
150
+ ? (Array.isArray(rawSource) ? rawSource : [rawSource]).filter((s) => typeof s === "string")
151
+ : null;
152
+ if (severityFilter) {
153
+ diagnostics = diagnostics.filter((d) => severityFilter.includes(d.severity));
154
+ }
155
+ if (sourceFilter) {
156
+ diagnostics = diagnostics.filter((d) => sourceFilter.includes(d.source));
157
+ }
158
+ // Correlate
159
+ const correlations = [];
160
+ for (const diag of diagnostics) {
161
+ // Normalize diagnostic file path to workspace-relative
162
+ let diagRelative;
163
+ if (path.isAbsolute(diag.file)) {
164
+ diagRelative = path.relative(workspace, diag.file);
165
+ }
166
+ else {
167
+ diagRelative = diag.file;
168
+ }
169
+ // Filter by filePath if specified
170
+ if (rawPath) {
171
+ const filterRelative = path.relative(workspace, resolveFilePath(rawPath, workspace));
172
+ if (diagRelative !== filterRelative)
173
+ continue;
174
+ }
175
+ const regions = changedRegions.get(diagRelative);
176
+ if (!regions || regions.length === 0) {
177
+ correlations.push({
178
+ file: diagRelative,
179
+ diagnostic: {
180
+ line: diag.line,
181
+ column: diag.column,
182
+ severity: diag.severity,
183
+ message: diag.message,
184
+ source: diag.source,
185
+ },
186
+ diffHunk: null,
187
+ likelyIntroducedByChange: false,
188
+ distance: null,
189
+ });
190
+ continue;
191
+ }
192
+ let minDist = Number.POSITIVE_INFINITY;
193
+ let nearestHunk = null;
194
+ for (const region of regions) {
195
+ const dist = lineDistance(diag.line, region.startLine, region.endLine);
196
+ if (dist < minDist) {
197
+ minDist = dist;
198
+ nearestHunk = region;
199
+ }
200
+ }
201
+ correlations.push({
202
+ file: diagRelative,
203
+ diagnostic: {
204
+ line: diag.line,
205
+ column: diag.column,
206
+ severity: diag.severity,
207
+ message: diag.message,
208
+ source: diag.source,
209
+ },
210
+ diffHunk: nearestHunk
211
+ ? {
212
+ startLine: nearestHunk.startLine,
213
+ endLine: nearestHunk.endLine,
214
+ header: nearestHunk.header,
215
+ }
216
+ : null,
217
+ likelyIntroducedByChange: minDist <= proximity,
218
+ distance: minDist === Number.POSITIVE_INFINITY ? null : minDist,
219
+ });
220
+ }
221
+ // Sort: likely-introduced first, then by file/line
222
+ correlations.sort((a, b) => {
223
+ if (a.likelyIntroducedByChange !== b.likelyIntroducedByChange) {
224
+ return a.likelyIntroducedByChange ? -1 : 1;
225
+ }
226
+ if (a.file !== b.file)
227
+ return a.file.localeCompare(b.file);
228
+ return a.diagnostic.line - b.diagnostic.line;
229
+ });
230
+ const summary = {
231
+ totalDiagnostics: correlations.length,
232
+ likelyIntroduced: correlations.filter((c) => c.likelyIntroducedByChange)
233
+ .length,
234
+ unrelatedToChanges: correlations.filter((c) => !c.likelyIntroducedByChange).length,
235
+ filesAnalyzed: new Set(correlations.map((c) => c.file)).size,
236
+ filtersApplied: {
237
+ severity: severityFilter,
238
+ source: sourceFilter,
239
+ },
240
+ };
241
+ return success({ correlations, summary });
242
+ },
243
+ };
244
+ }
245
+ //# sourceMappingURL=diffDebugger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diffDebugger.js","sourceRoot":"","sources":["../../src/tools/diffDebugger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import type { FileLock } from "../fileLock.js";
2
+ import { type ExtensionClient } from "../extensionClient.js";
3
+ export interface TextEdit {
4
+ type: "insert" | "delete" | "replace";
5
+ line: number;
6
+ column: number;
7
+ endLine?: number;
8
+ endColumn?: number;
9
+ text?: string;
10
+ }
11
+ /**
12
+ * Apply text edits natively by reading the file, modifying in-memory, and writing back.
13
+ * Edits are sorted in reverse document order so that earlier edits don't shift later indices.
14
+ */
15
+ export declare function applyEditsToContent(content: string, edits: TextEdit[]): string;
16
+ export declare function createEditTextTool(workspace: string, extensionClient: ExtensionClient, fileLock?: FileLock): {
17
+ schema: {
18
+ name: string;
19
+ description: string;
20
+ annotations: {
21
+ destructiveHint: boolean;
22
+ };
23
+ inputSchema: {
24
+ type: "object";
25
+ required: string[];
26
+ properties: {
27
+ filePath: {
28
+ type: "string";
29
+ description: string;
30
+ };
31
+ edits: {
32
+ type: "array";
33
+ description: string;
34
+ items: {
35
+ type: "object";
36
+ required: string[];
37
+ properties: {
38
+ type: {
39
+ type: "string";
40
+ enum: string[];
41
+ description: string;
42
+ };
43
+ line: {
44
+ type: "integer";
45
+ description: string;
46
+ };
47
+ column: {
48
+ type: "integer";
49
+ description: string;
50
+ };
51
+ endLine: {
52
+ type: "integer";
53
+ description: string;
54
+ };
55
+ endColumn: {
56
+ type: "integer";
57
+ description: string;
58
+ };
59
+ text: {
60
+ type: "string";
61
+ description: string;
62
+ };
63
+ };
64
+ };
65
+ };
66
+ save: {
67
+ type: "boolean";
68
+ description: string;
69
+ };
70
+ };
71
+ additionalProperties: false;
72
+ };
73
+ };
74
+ handler: (args: Record<string, unknown>, signal?: AbortSignal) => Promise<{
75
+ content: Array<{
76
+ type: string;
77
+ text: string;
78
+ }>;
79
+ }>;
80
+ };
@@ -0,0 +1,274 @@
1
+ import fs from "node:fs";
2
+ import { ExtensionTimeoutError, } from "../extensionClient.js";
3
+ import { error, optionalBool, requireString, resolveFilePath, success, } from "./utils.js";
4
+ /**
5
+ * Apply text edits natively by reading the file, modifying in-memory, and writing back.
6
+ * Edits are sorted in reverse document order so that earlier edits don't shift later indices.
7
+ */
8
+ export function applyEditsToContent(content, edits) {
9
+ const lines = content.split("\n");
10
+ // Sort edits in forward order first to detect overlaps
11
+ const sortedForward = [...edits].sort((a, b) => {
12
+ if (a.line !== b.line)
13
+ return a.line - b.line;
14
+ return a.column - b.column;
15
+ });
16
+ // Check for overlapping ranges
17
+ for (let i = 0; i < sortedForward.length - 1; i++) {
18
+ const cur = sortedForward[i];
19
+ const next = sortedForward[i + 1];
20
+ if (!cur || !next)
21
+ continue;
22
+ const curEndLine = cur.endLine ?? cur.line;
23
+ const curEndCol = cur.endColumn ?? cur.column;
24
+ // Two edits overlap when the end of edit[i] is strictly past the start of edit[i+1]
25
+ const overlaps = curEndLine > next.line ||
26
+ (curEndLine === next.line && curEndCol > next.column);
27
+ if (overlaps) {
28
+ throw new Error(`overlapping edits detected: edit ending at line ${curEndLine} overlaps edit starting at line ${next.line}`);
29
+ }
30
+ }
31
+ // Sort edits in reverse order: last position first so indices stay stable
32
+ const sorted = sortedForward.slice().reverse();
33
+ for (const edit of sorted) {
34
+ const lineIdx = edit.line - 1; // 1-based → 0-based
35
+ const colIdx = edit.column - 1;
36
+ // Pad lines array if edit targets beyond EOF (prevents "undefined" in output)
37
+ while (lineIdx >= lines.length) {
38
+ lines.push("");
39
+ }
40
+ if (edit.type === "insert") {
41
+ const text = edit.text ?? "";
42
+ const insertLines = text.split("\n");
43
+ const currentLine = lines[lineIdx] ?? "";
44
+ const before = currentLine.slice(0, colIdx);
45
+ const after = currentLine.slice(colIdx);
46
+ if (insertLines.length === 1) {
47
+ lines[lineIdx] = before + insertLines[0] + after;
48
+ }
49
+ else {
50
+ // Multi-line insert: first fragment joins before, last fragment joins after
51
+ const newLines = [
52
+ before + insertLines[0],
53
+ ...insertLines.slice(1, -1),
54
+ insertLines[insertLines.length - 1] + after,
55
+ ];
56
+ lines.splice(lineIdx, 1, ...newLines);
57
+ }
58
+ }
59
+ else if (edit.type === "delete" || edit.type === "replace") {
60
+ const endLineIdx = Math.min((edit.endLine ?? edit.line) - 1, lines.length - 1);
61
+ const endColIdx = (edit.endColumn ?? edit.column) - 1;
62
+ const beforeText = (lines[lineIdx] ?? "").slice(0, colIdx);
63
+ const afterText = (lines[endLineIdx] ?? "").slice(endColIdx);
64
+ const replacement = edit.type === "replace" ? (edit.text ?? "") : "";
65
+ const replacementLines = replacement.split("\n");
66
+ if (replacementLines.length === 1) {
67
+ const merged = beforeText + replacementLines[0] + afterText;
68
+ lines.splice(lineIdx, endLineIdx - lineIdx + 1, merged);
69
+ }
70
+ else {
71
+ const newLines = [
72
+ beforeText + replacementLines[0],
73
+ ...replacementLines.slice(1, -1),
74
+ replacementLines[replacementLines.length - 1] + afterText,
75
+ ];
76
+ lines.splice(lineIdx, endLineIdx - lineIdx + 1, ...newLines);
77
+ }
78
+ }
79
+ }
80
+ return lines.join("\n");
81
+ }
82
+ export function createEditTextTool(workspace, extensionClient, fileLock) {
83
+ return {
84
+ schema: {
85
+ name: "editText",
86
+ description: "Insert, delete, or replace text at specific positions in a file. " +
87
+ "Supports multiple edits in a single atomic operation. " +
88
+ "All line and column numbers are 1-based. " +
89
+ "Uses VS Code WorkspaceEdit when connected, falls back to native fs read/write otherwise. " +
90
+ "Note: native fallback has no undo buffer — edits are written directly to disk.",
91
+ annotations: { destructiveHint: true },
92
+ inputSchema: {
93
+ type: "object",
94
+ required: ["filePath", "edits"],
95
+ properties: {
96
+ filePath: {
97
+ type: "string",
98
+ description: "Absolute or workspace-relative path to the file",
99
+ },
100
+ edits: {
101
+ type: "array",
102
+ description: "Array of edit operations to apply atomically",
103
+ items: {
104
+ type: "object",
105
+ required: ["type"],
106
+ properties: {
107
+ type: {
108
+ type: "string",
109
+ enum: ["insert", "delete", "replace"],
110
+ description: "Type of edit operation",
111
+ },
112
+ line: {
113
+ type: "integer",
114
+ description: "Line number (1-based)",
115
+ },
116
+ column: {
117
+ type: "integer",
118
+ description: "Column number (1-based)",
119
+ },
120
+ endLine: {
121
+ type: "integer",
122
+ description: "End line number (1-based, for delete/replace)",
123
+ },
124
+ endColumn: {
125
+ type: "integer",
126
+ description: "End column number (1-based, for delete/replace)",
127
+ },
128
+ text: {
129
+ type: "string",
130
+ description: "Text to insert or replace with",
131
+ },
132
+ },
133
+ },
134
+ },
135
+ save: {
136
+ type: "boolean",
137
+ description: "Save the file after applying edits (default: false)",
138
+ },
139
+ },
140
+ additionalProperties: false,
141
+ },
142
+ },
143
+ handler: async (args, signal) => {
144
+ const rawPath = requireString(args, "filePath");
145
+ const edits = args.edits;
146
+ const save = optionalBool(args, "save") ?? false;
147
+ if (!Array.isArray(edits) || edits.length === 0) {
148
+ return error("'edits' must be a non-empty array");
149
+ }
150
+ if (edits.length > 1000) {
151
+ return error("'edits' must have at most 1000 entries");
152
+ }
153
+ // Validate each edit
154
+ for (let i = 0; i < edits.length; i++) {
155
+ const edit = edits[i];
156
+ if (!edit || typeof edit !== "object") {
157
+ return error(`edits[${i}] must be an object`);
158
+ }
159
+ const type = edit.type;
160
+ if (type !== "insert" && type !== "delete" && type !== "replace") {
161
+ return error(`edits[${i}].type must be "insert", "delete", or "replace"`);
162
+ }
163
+ if (typeof edit.line !== "number") {
164
+ return error(`edits[${i}].line is required and must be a number`);
165
+ }
166
+ if (typeof edit.column !== "number") {
167
+ return error(`edits[${i}].column is required and must be a number`);
168
+ }
169
+ if (edit.line < 1 || edit.column < 1) {
170
+ return error(`edits[${i}].line and column must be >= 1 (1-based)`);
171
+ }
172
+ if (type === "insert" && typeof edit.text !== "string") {
173
+ return error(`edits[${i}].text is required for insert operations`);
174
+ }
175
+ if ((type === "delete" || type === "replace") &&
176
+ typeof edit.endLine !== "number") {
177
+ return error(`edits[${i}].endLine is required for ${type} operations`);
178
+ }
179
+ if ((type === "delete" || type === "replace") &&
180
+ typeof edit.endColumn !== "number") {
181
+ return error(`edits[${i}].endColumn is required for ${type} operations`);
182
+ }
183
+ if ((type === "delete" || type === "replace") &&
184
+ (edit.endLine < 1 || edit.endColumn < 1)) {
185
+ return error(`edits[${i}].endLine and endColumn must be >= 1 (1-based)`);
186
+ }
187
+ if ((type === "delete" || type === "replace") &&
188
+ (edit.endLine < edit.line ||
189
+ (edit.endLine === edit.line &&
190
+ edit.endColumn < edit.column))) {
191
+ return error(`edits[${i}].endLine:endColumn must be >= line:column (range cannot be reversed)`);
192
+ }
193
+ if (type === "replace" && typeof edit.text !== "string") {
194
+ return error(`edits[${i}].text is required for replace operations`);
195
+ }
196
+ }
197
+ const filePath = resolveFilePath(rawPath, workspace);
198
+ // Try extension first (supports undo, works with unsaved buffers)
199
+ if (extensionClient.isConnected()) {
200
+ try {
201
+ const result = await extensionClient.editText(filePath, edits, save);
202
+ if (result !== null) {
203
+ const parsed = result;
204
+ if (parsed.success === false) {
205
+ return error(parsed.error ?? "Failed to apply edits");
206
+ }
207
+ // Pass through extension result with source annotation
208
+ return success({ ...parsed, source: "vscode", filePath });
209
+ }
210
+ }
211
+ catch (err) {
212
+ if (!(err instanceof ExtensionTimeoutError))
213
+ throw err;
214
+ // Timeout — fall through to native fs fallback
215
+ }
216
+ }
217
+ if (signal?.aborted)
218
+ throw new Error("Request aborted");
219
+ // Native fs fallback — read, apply edits in-memory, write back
220
+ // Uses mtime-based optimistic concurrency to detect concurrent modifications
221
+ try {
222
+ let content;
223
+ let originalMtimeMs;
224
+ try {
225
+ const stat = await fs.promises.stat(filePath);
226
+ originalMtimeMs = stat.mtimeMs;
227
+ content = await fs.promises.readFile(filePath, {
228
+ encoding: "utf-8",
229
+ signal,
230
+ });
231
+ }
232
+ catch {
233
+ return error(`File not found: ${filePath}`);
234
+ }
235
+ const typedEdits = edits;
236
+ const newContent = applyEditsToContent(content, typedEdits);
237
+ // Acquire per-file lock before write to serialize concurrent edits from multiple sessions
238
+ const release = fileLock ? await fileLock.acquire(filePath) : null;
239
+ try {
240
+ // Check if file was modified between read and write
241
+ try {
242
+ const statAfter = await fs.promises.stat(filePath);
243
+ if (statAfter.mtimeMs !== originalMtimeMs) {
244
+ return error("File was modified concurrently — retry the edit");
245
+ }
246
+ }
247
+ catch {
248
+ // File was deleted between read and write
249
+ return error("File was deleted concurrently — cannot apply edits");
250
+ }
251
+ await fs.promises.writeFile(filePath, newContent, {
252
+ encoding: "utf-8",
253
+ signal,
254
+ });
255
+ }
256
+ finally {
257
+ release?.();
258
+ }
259
+ return success({
260
+ success: true,
261
+ editsApplied: typedEdits.length,
262
+ source: extensionClient.isConnected()
263
+ ? "native-fs (extension timed out)"
264
+ : "native-fs",
265
+ warning: "Edits applied directly to disk — no undo buffer available",
266
+ });
267
+ }
268
+ catch (err) {
269
+ return error(`Failed to apply edits: ${err instanceof Error ? err.message : String(err)}`);
270
+ }
271
+ },
272
+ };
273
+ }
274
+ //# sourceMappingURL=editText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editText.js","sourceRoot":"","sources":["../../src/tools/editText.ts"],"names":[],"mappings":"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"}