mcp-code-context 2.1.3 → 2.3.1

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 (128) hide show
  1. package/.io/RULES.md +12 -0
  2. package/CHANGELOG.md +118 -58
  3. package/CONTRIBUTING.md +243 -0
  4. package/README.md +58 -7
  5. package/RELEASE_NOTES_v2.2.0.md +286 -0
  6. package/RELEASE_NOTES_v2.3.0.md +228 -0
  7. package/RELEASE_NOTES_v2.3.1.md +110 -0
  8. package/dist/src/ast/writers/safeRename.d.ts +14 -0
  9. package/dist/src/ast/writers/safeRename.js +258 -0
  10. package/dist/src/ast/writers/safeRename.js.map +1 -0
  11. package/dist/src/ast/writers/symbolWriter.d.ts +2 -0
  12. package/dist/src/ast/writers/symbolWriter.js +9 -14
  13. package/dist/src/ast/writers/symbolWriter.js.map +1 -1
  14. package/dist/src/cache/astCache.d.ts +33 -0
  15. package/dist/src/cache/astCache.js +113 -0
  16. package/dist/src/cache/astCache.js.map +1 -0
  17. package/dist/src/handlers/readHandlers.d.ts +70 -0
  18. package/dist/src/handlers/readHandlers.js +431 -0
  19. package/dist/src/handlers/readHandlers.js.map +1 -0
  20. package/dist/src/handlers/utilHandlers.d.ts +31 -0
  21. package/dist/src/handlers/utilHandlers.js +69 -0
  22. package/dist/src/handlers/utilHandlers.js.map +1 -0
  23. package/dist/src/handlers/writeHandlers.d.ts +57 -0
  24. package/dist/src/handlers/writeHandlers.js +475 -0
  25. package/dist/src/handlers/writeHandlers.js.map +1 -0
  26. package/dist/src/index.d.ts +6 -107
  27. package/dist/src/index.js +147 -965
  28. package/dist/src/index.js.map +1 -1
  29. package/dist/src/tools/readFileLines.d.ts +26 -0
  30. package/dist/src/tools/readFileLines.js +77 -0
  31. package/dist/src/tools/readFileLines.js.map +1 -0
  32. package/dist/src/tools/searchCodePattern.d.ts +32 -0
  33. package/dist/src/tools/searchCodePattern.js +80 -0
  34. package/dist/src/tools/searchCodePattern.js.map +1 -0
  35. package/dist/src/utils/arrayUtils.d.ts +12 -0
  36. package/dist/src/utils/arrayUtils.js +27 -0
  37. package/dist/src/utils/arrayUtils.js.map +1 -0
  38. package/dist/src/utils/backupManager.d.ts +13 -6
  39. package/dist/src/utils/backupManager.js +73 -8
  40. package/dist/src/utils/backupManager.js.map +1 -1
  41. package/dist/src/utils/constants.d.ts +46 -0
  42. package/dist/src/utils/constants.js +112 -0
  43. package/dist/src/utils/constants.js.map +1 -0
  44. package/dist/src/utils/ignoreManager.d.ts +8 -0
  45. package/dist/src/utils/ignoreManager.js +49 -0
  46. package/dist/src/utils/ignoreManager.js.map +1 -1
  47. package/dist/src/utils/normalization.d.ts +49 -0
  48. package/dist/src/utils/normalization.js +173 -0
  49. package/dist/src/utils/normalization.js.map +1 -0
  50. package/dist/src/utils/projectRoot.d.ts +17 -0
  51. package/dist/src/utils/projectRoot.js +42 -0
  52. package/dist/src/utils/projectRoot.js.map +1 -0
  53. package/dist/src/utils/secureValidation.d.ts +15 -0
  54. package/dist/src/utils/secureValidation.js +41 -0
  55. package/dist/src/utils/secureValidation.js.map +1 -0
  56. package/dist/src/utils/transactionManager.d.ts +45 -0
  57. package/dist/src/utils/transactionManager.js +102 -0
  58. package/dist/src/utils/transactionManager.js.map +1 -0
  59. package/dist/src/utils/validation.d.ts +87 -0
  60. package/dist/src/utils/validation.js +231 -0
  61. package/dist/src/utils/validation.js.map +1 -0
  62. package/docs/ARCHITECTURE.md +300 -0
  63. package/docs/architecture/ADR-001-modular-handlers.md +119 -0
  64. package/llms.txt +62 -7
  65. package/package.json +5 -5
  66. package/AGENT_INSTRUCTIONS.md +0 -135
  67. package/DEPLOYMENT_INSTRUCTIONS.md +0 -110
  68. package/dist/src/tests/test-confirmation-flow.d.ts +0 -1
  69. package/dist/src/tests/test-confirmation-flow.js +0 -43
  70. package/dist/src/tests/test-confirmation-flow.js.map +0 -1
  71. package/dist/tests/debug-replace.d.ts +0 -1
  72. package/dist/tests/debug-replace.js +0 -17
  73. package/dist/tests/debug-replace.js.map +0 -1
  74. package/dist/tests/test-confirmation-flow.d.ts +0 -1
  75. package/dist/tests/test-confirmation-flow.js +0 -43
  76. package/dist/tests/test-confirmation-flow.js.map +0 -1
  77. package/dist/tests/test-dart.d.ts +0 -1
  78. package/dist/tests/test-dart.js +0 -242
  79. package/dist/tests/test-dart.js.map +0 -1
  80. package/dist/tests/test-php-ast.d.ts +0 -1
  81. package/dist/tests/test-php-ast.js +0 -152
  82. package/dist/tests/test-php-ast.js.map +0 -1
  83. package/dist/tests/test-php.d.ts +0 -1
  84. package/dist/tests/test-php.js +0 -234
  85. package/dist/tests/test-php.js.map +0 -1
  86. package/dist/tests/test-smoke.d.ts +0 -5
  87. package/dist/tests/test-smoke.js +0 -83
  88. package/dist/tests/test-smoke.js.map +0 -1
  89. package/dist/tests/writers/test-crlf-handling.d.ts +0 -4
  90. package/dist/tests/writers/test-crlf-handling.js +0 -73
  91. package/dist/tests/writers/test-crlf-handling.js.map +0 -1
  92. package/dist/tests/writers/test-write-smoke.d.ts +0 -9
  93. package/dist/tests/writers/test-write-smoke.js +0 -346
  94. package/dist/tests/writers/test-write-smoke.js.map +0 -1
  95. package/src/ast/dartCompressor.ts +0 -1013
  96. package/src/ast/phpCompressor.ts +0 -814
  97. package/src/ast/semanticCompressor.ts +0 -808
  98. package/src/ast/writers/dartWriter.ts +0 -648
  99. package/src/ast/writers/phpWriter.ts +0 -508
  100. package/src/ast/writers/pyWriter.ts +0 -446
  101. package/src/ast/writers/symbolWriter.ts +0 -277
  102. package/src/ast/writers/tsWriter.ts +0 -418
  103. package/src/index.ts +0 -1553
  104. package/src/utils/backupManager.ts +0 -66
  105. package/src/utils/confirmationCache.ts +0 -61
  106. package/src/utils/diffEngine.ts +0 -223
  107. package/src/utils/fuzzyMatch.ts +0 -86
  108. package/src/utils/ignoreManager.ts +0 -144
  109. package/tests/test-confirmation-flow.ts +0 -49
  110. package/tests/test-dart.d.ts +0 -1
  111. package/tests/test-dart.js +0 -209
  112. package/tests/test-dart.js.map +0 -1
  113. package/tests/test-dart.ts +0 -265
  114. package/tests/test-php-ast.d.ts +0 -1
  115. package/tests/test-php-ast.js +0 -152
  116. package/tests/test-php-ast.js.map +0 -1
  117. package/tests/test-php-ast.ts +0 -155
  118. package/tests/test-php.d.ts +0 -1
  119. package/tests/test-php.js +0 -234
  120. package/tests/test-php.js.map +0 -1
  121. package/tests/test-php.ts +0 -261
  122. package/tests/test-smoke.d.ts +0 -5
  123. package/tests/test-smoke.js +0 -83
  124. package/tests/test-smoke.js.map +0 -1
  125. package/tests/test-smoke.ts +0 -93
  126. package/tests/writers/test-crlf-handling.ts +0 -100
  127. package/tests/writers/test-write-smoke.ts +0 -568
  128. package/tsconfig.json +0 -19
@@ -0,0 +1,475 @@
1
+ /**
2
+ * writeHandlers.ts — Write Tool Handlers
3
+ *
4
+ * Handles all write operations with two-phase confirmation:
5
+ * - write_file_surgical
6
+ * - insert_symbol
7
+ * - rename_symbol
8
+ * - remove_symbol
9
+ */
10
+ import * as fs from "node:fs";
11
+ import * as path from "node:path";
12
+ import { IgnoreManager } from "../utils/ignoreManager.js";
13
+ import { replaceSymbol, insertCode, renameInFile, renameReferencesInFile, removeSymbolFromFile, WRITABLE_EXTENSIONS, } from "../ast/writers/symbolWriter.js";
14
+ import { generateDiff, generateMultiFileDiff } from "../utils/diffEngine.js";
15
+ import { createBackup, restoreBackup } from "../utils/backupManager.js";
16
+ import { extractFallbackSymbols, findClosestSymbols } from "../utils/fuzzyMatch.js";
17
+ import { confirmationCache } from "../utils/confirmationCache.js";
18
+ import { invalidateFileCache } from "../cache/astCache.js";
19
+ import { TransactionManager } from "../utils/transactionManager.js";
20
+ import { validateSymbolName, } from "../utils/validation.js";
21
+ import { IMPORTABLE_EXTENSIONS } from "../utils/constants.js";
22
+ // ─── Handler: write_file_surgical ───────────────────────────────────
23
+ export async function handleWriteFileSurgical(args) {
24
+ const filePath = args.filePath;
25
+ const symbolName = args.symbolName;
26
+ const newContent = args.newContent;
27
+ const className = args.className;
28
+ const confirmationToken = args.confirmationToken;
29
+ const confirm = args.confirm;
30
+ if (!filePath)
31
+ return errorResponse("Missing required parameter: filePath");
32
+ // PHASE 2: Apply
33
+ if (confirmationToken && confirm) {
34
+ const pending = confirmationCache.consume(confirmationToken);
35
+ if (!pending || pending.operation !== "write_file_surgical") {
36
+ return errorResponse("Invalid or expired confirmation token");
37
+ }
38
+ const resolvedPath = pending.filePath;
39
+ try {
40
+ createBackup(resolvedPath);
41
+ }
42
+ catch (error) {
43
+ return errorResponse(`Backup failed: ${error instanceof Error ? error.message : String(error)}`);
44
+ }
45
+ try {
46
+ fs.writeFileSync(resolvedPath, pending.payload.newContentFull, "utf-8");
47
+ invalidateFileCache(resolvedPath);
48
+ }
49
+ catch (error) {
50
+ restoreBackup(resolvedPath);
51
+ return errorResponse(`Write failed: ${error instanceof Error ? error.message : String(error)}`);
52
+ }
53
+ return {
54
+ content: [
55
+ {
56
+ type: "text",
57
+ text: `// ✅ Symbol "${pending.payload.symbolName}" replaced\n// File: ${resolvedPath}\n\n${pending.payload.diff}`,
58
+ },
59
+ ],
60
+ };
61
+ }
62
+ // PHASE 1: Dry-Run
63
+ if (!symbolName)
64
+ return errorResponse("Missing required parameter: symbolName");
65
+ if (!newContent)
66
+ return errorResponse("Missing required parameter: newContent");
67
+ // Validate symbol name
68
+ const symbolValidation = validateSymbolName(symbolName);
69
+ if (!symbolValidation.valid) {
70
+ return errorResponse(symbolValidation.error);
71
+ }
72
+ // SECURITY: Use secure validation with project boundary enforcement
73
+ const { validateFilePathSecure } = await import("../utils/secureValidation.js");
74
+ const validation = validateFilePathSecure(filePath);
75
+ if (!validation.valid) {
76
+ return errorResponse(validation.error);
77
+ }
78
+ const resolvedPath = validation.resolvedPath;
79
+ const ext = path.extname(resolvedPath).toLowerCase();
80
+ if (!WRITABLE_EXTENSIONS.has(ext)) {
81
+ return errorResponse(`Unsupported file type: ${ext}`);
82
+ }
83
+ let content;
84
+ try {
85
+ content = fs.readFileSync(resolvedPath, "utf-8");
86
+ }
87
+ catch (error) {
88
+ return errorResponse(`Read failed: ${error instanceof Error ? error.message : String(error)}`);
89
+ }
90
+ const result = replaceSymbol(resolvedPath, content, symbolName, newContent, className);
91
+ if (!result.success) {
92
+ const isNotFoundError = result.error && result.error.includes("not found");
93
+ if (isNotFoundError) {
94
+ const available = extractFallbackSymbols(content);
95
+ const closest = findClosestSymbols(symbolName, available, 5);
96
+ const availableFormatted = available.slice(0, 15).map(s => `${s.name} (${s.type}${s.className ? ` in ${s.className}` : ''})`);
97
+ if (available.length > 15)
98
+ availableFormatted.push(`...and ${available.length - 15} more`);
99
+ const suggestions = [];
100
+ if (className) {
101
+ const inOtherClass = available.find(s => s.name === symbolName && s.className !== className);
102
+ if (inOtherClass)
103
+ suggestions.push(`Try className: '${inOtherClass.className}'`);
104
+ }
105
+ else {
106
+ const needsScope = available.filter(s => s.name === symbolName && s.className);
107
+ if (needsScope.length > 0)
108
+ suggestions.push(`Use className: '${needsScope[0].className}'`);
109
+ }
110
+ if (closest.length > 0) {
111
+ suggestions.push(`Similar: ${closest.map(s => s.name).join(', ')}`);
112
+ }
113
+ return {
114
+ isError: true,
115
+ content: [
116
+ {
117
+ type: "text",
118
+ text: JSON.stringify({
119
+ error: result.error,
120
+ available_symbols: availableFormatted,
121
+ suggestions
122
+ }, null, 2),
123
+ },
124
+ ],
125
+ };
126
+ }
127
+ return errorResponse(result.error || "Unknown error");
128
+ }
129
+ const diff = generateDiff(content, result.newContent, resolvedPath);
130
+ const token = confirmationCache.add("write_file_surgical", resolvedPath, {
131
+ symbolName,
132
+ newContentFull: result.newContent,
133
+ diff,
134
+ });
135
+ return {
136
+ content: [
137
+ {
138
+ type: "text",
139
+ text: `// 🔍 DRY-RUN: Review changes below\n// To apply: confirmationToken: "${token}", confirm: true\n\n${diff}`,
140
+ },
141
+ ],
142
+ };
143
+ }
144
+ // ─── Handler: insert_symbol ─────────────────────────────────────────
145
+ export async function handleInsertSymbol(args) {
146
+ const filePath = args.filePath;
147
+ const code = args.code;
148
+ const anchorSymbol = args.anchorSymbol || null;
149
+ const position = args.position || "after";
150
+ const className = args.className;
151
+ const confirmationToken = args.confirmationToken;
152
+ const confirm = args.confirm;
153
+ if (!filePath)
154
+ return errorResponse("Missing required parameter: filePath");
155
+ // PHASE 2
156
+ if (confirmationToken && confirm) {
157
+ const pending = confirmationCache.consume(confirmationToken);
158
+ if (!pending || pending.operation !== "insert_symbol") {
159
+ return errorResponse("Invalid or expired confirmation token");
160
+ }
161
+ const resolvedPath = pending.filePath;
162
+ try {
163
+ createBackup(resolvedPath);
164
+ }
165
+ catch (error) {
166
+ return errorResponse(`Backup failed: ${error instanceof Error ? error.message : String(error)}`);
167
+ }
168
+ try {
169
+ fs.writeFileSync(resolvedPath, pending.payload.newContentFull, "utf-8");
170
+ invalidateFileCache(resolvedPath);
171
+ }
172
+ catch (error) {
173
+ restoreBackup(resolvedPath);
174
+ return errorResponse(`Write failed: ${error instanceof Error ? error.message : String(error)}`);
175
+ }
176
+ return {
177
+ content: [
178
+ {
179
+ type: "text",
180
+ text: `// ✅ Code inserted\n// File: ${resolvedPath}\n\n${pending.payload.diff}`,
181
+ },
182
+ ],
183
+ };
184
+ }
185
+ // PHASE 1
186
+ if (!code)
187
+ return errorResponse("Missing required parameter: code");
188
+ // SECURITY: Use secure validation with project boundary enforcement
189
+ const { validateFilePathSecure } = await import("../utils/secureValidation.js");
190
+ const validation = validateFilePathSecure(filePath);
191
+ if (!validation.valid) {
192
+ return errorResponse(validation.error);
193
+ }
194
+ const resolvedPath = validation.resolvedPath;
195
+ const ext = path.extname(resolvedPath).toLowerCase();
196
+ if (!WRITABLE_EXTENSIONS.has(ext)) {
197
+ return errorResponse(`Unsupported file type: ${ext}`);
198
+ }
199
+ let fileContent;
200
+ try {
201
+ fileContent = fs.readFileSync(resolvedPath, "utf-8");
202
+ }
203
+ catch (error) {
204
+ return errorResponse(`Read failed: ${error instanceof Error ? error.message : String(error)}`);
205
+ }
206
+ const result = insertCode(resolvedPath, fileContent, code, anchorSymbol, position, className);
207
+ if (!result.success) {
208
+ return errorResponse(result.error || "Unknown error");
209
+ }
210
+ const diff = generateDiff(fileContent, result.newContent, resolvedPath);
211
+ const token = confirmationCache.add("insert_symbol", resolvedPath, {
212
+ newContentFull: result.newContent,
213
+ diff,
214
+ anchorSymbol,
215
+ position
216
+ });
217
+ return {
218
+ content: [
219
+ {
220
+ type: "text",
221
+ text: `// 🔍 DRY-RUN: Review changes below\n// To apply: confirmationToken: "${token}", confirm: true\n\n${diff}`,
222
+ },
223
+ ],
224
+ };
225
+ }
226
+ // ─── Handler: rename_symbol ─────────────────────────────────────────
227
+ export async function handleRenameSymbol(args) {
228
+ const filePath = args.filePath;
229
+ const oldName = args.oldName;
230
+ const newName = args.newName;
231
+ const rootDir = args.rootDir;
232
+ const confirmationToken = args.confirmationToken;
233
+ const confirm = args.confirm;
234
+ if (!filePath)
235
+ return errorResponse("Missing required parameter: filePath");
236
+ // PHASE 2
237
+ if (confirmationToken && confirm) {
238
+ const pending = confirmationCache.consume(confirmationToken);
239
+ if (!pending || pending.operation !== "rename_symbol") {
240
+ return errorResponse("Invalid or expired confirmation token");
241
+ }
242
+ const results = pending.payload.results;
243
+ const transaction = new TransactionManager();
244
+ transaction.stageMultiple(results.map((r) => ({
245
+ filePath: r.filePath,
246
+ newContent: r.newContent
247
+ })));
248
+ const commitResult = await transaction.commit();
249
+ if (!commitResult.success) {
250
+ return errorResponse(commitResult.error);
251
+ }
252
+ for (const res of results) {
253
+ invalidateFileCache(res.filePath);
254
+ }
255
+ return {
256
+ content: [{
257
+ type: "text",
258
+ text: `// ✅ Rename applied\n\n${pending.payload.diff}`,
259
+ }],
260
+ };
261
+ }
262
+ // PHASE 1
263
+ if (!oldName)
264
+ return errorResponse("Missing required parameter: oldName");
265
+ if (!newName)
266
+ return errorResponse("Missing required parameter: newName");
267
+ // Validate symbol names
268
+ const oldValidation = validateSymbolName(oldName);
269
+ if (!oldValidation.valid) {
270
+ return errorResponse(`Invalid oldName: ${oldValidation.error}`);
271
+ }
272
+ const newValidation = validateSymbolName(newName);
273
+ if (!newValidation.valid) {
274
+ return errorResponse(`Invalid newName: ${newValidation.error}`);
275
+ }
276
+ // SECURITY: Use secure validation with project boundary enforcement
277
+ const { validateFilePathSecure } = await import("../utils/secureValidation.js");
278
+ const validation = validateFilePathSecure(filePath);
279
+ if (!validation.valid) {
280
+ return errorResponse(validation.error);
281
+ }
282
+ const resolvedPath = validation.resolvedPath;
283
+ // SECURITY: Block cross-file rename for languages without AST support
284
+ const ext = path.extname(resolvedPath).toLowerCase();
285
+ if (['.dart', '.py', '.pyi'].includes(ext)) {
286
+ return errorResponse(`⚠️ Cross-file rename not supported for ${ext} files.\n\n` +
287
+ `Reason: No AST parser available for safe refactoring across multiple files.\n` +
288
+ `Risk: Regex-based rename may corrupt strings, comments, or unrelated code.\n\n` +
289
+ `Recommendation: Use IDE refactoring tools:\n` +
290
+ ` • Dart: VS Code with Dart extension (F2 key)\n` +
291
+ ` • Python: PyCharm, VS Code with Pylance (F2 key)\n\n` +
292
+ `Alternative: Use write_file_surgical to rename within a single file.`);
293
+ }
294
+ let sourceContent;
295
+ try {
296
+ sourceContent = fs.readFileSync(resolvedPath, "utf-8");
297
+ }
298
+ catch (error) {
299
+ return errorResponse(`Read failed: ${error instanceof Error ? error.message : String(error)}`);
300
+ }
301
+ const sourceResult = renameInFile(resolvedPath, sourceContent, oldName, newName);
302
+ if (!sourceResult.success) {
303
+ return errorResponse(sourceResult.error || `Symbol "${oldName}" not found`);
304
+ }
305
+ const results = [
306
+ {
307
+ filePath: resolvedPath,
308
+ oldContent: sourceContent,
309
+ newContent: sourceResult.newContent,
310
+ },
311
+ ];
312
+ const projectRoot = rootDir ? path.resolve(rootDir) : findProjectRoot(resolvedPath);
313
+ if (projectRoot) {
314
+ const ignoreManager = new IgnoreManager(projectRoot);
315
+ const allFiles = await ignoreManager.walkDirectoryAsync();
316
+ const { processBatched } = await import("../utils/arrayUtils.js");
317
+ const dependentResults = await processBatched(allFiles.filter(f => path.resolve(f) !== resolvedPath), async (dependentFile) => {
318
+ const ext = path.extname(dependentFile).toLowerCase();
319
+ if (!IMPORTABLE_EXTENSIONS.has(ext))
320
+ return null;
321
+ let depContent;
322
+ try {
323
+ depContent = await fs.promises.readFile(dependentFile, "utf-8");
324
+ }
325
+ catch {
326
+ return null;
327
+ }
328
+ const escaped = oldName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
329
+ const regex = new RegExp(`(?<=^|[^a-zA-Z0-9_$])(${escaped})(?=[^a-zA-Z0-9_$]|$)`);
330
+ if (!regex.test(depContent))
331
+ return null;
332
+ const depResult = renameReferencesInFile(dependentFile, depContent, oldName, newName);
333
+ if (depResult.success && depResult.newContent !== depContent) {
334
+ return {
335
+ filePath: path.resolve(dependentFile),
336
+ oldContent: depContent,
337
+ newContent: depResult.newContent,
338
+ };
339
+ }
340
+ return null;
341
+ }, 50);
342
+ results.push(...dependentResults.filter(r => r !== null));
343
+ }
344
+ const multiDiff = generateMultiFileDiff(results);
345
+ const token = confirmationCache.add("rename_symbol", resolvedPath, {
346
+ results,
347
+ diff: multiDiff
348
+ });
349
+ return {
350
+ content: [{
351
+ type: "text",
352
+ text: `// 🔍 DRY-RUN: Review changes below\n// To apply: confirmationToken: "${token}", confirm: true\n\n${multiDiff}`,
353
+ }],
354
+ };
355
+ }
356
+ // ─── Handler: remove_symbol ─────────────────────────────────────────
357
+ export async function handleRemoveSymbol(args) {
358
+ const filePath = args.filePath;
359
+ const symbolName = args.symbolName;
360
+ const className = args.className;
361
+ const force = args.force || false;
362
+ const confirmationToken = args.confirmationToken;
363
+ const confirm = args.confirm;
364
+ if (!filePath)
365
+ return errorResponse("Missing required parameter: filePath");
366
+ // PHASE 2
367
+ if (confirmationToken && confirm) {
368
+ const pending = confirmationCache.consume(confirmationToken);
369
+ if (!pending || pending.operation !== "remove_symbol") {
370
+ return errorResponse("Invalid or expired confirmation token");
371
+ }
372
+ const resolvedPath = pending.filePath;
373
+ try {
374
+ createBackup(resolvedPath);
375
+ }
376
+ catch (e) { }
377
+ try {
378
+ fs.writeFileSync(resolvedPath, pending.payload.newContentFull, "utf-8");
379
+ invalidateFileCache(resolvedPath);
380
+ }
381
+ catch (error) {
382
+ restoreBackup(resolvedPath);
383
+ return errorResponse(`Write failed: ${error instanceof Error ? error.message : String(error)}`);
384
+ }
385
+ return {
386
+ content: [{
387
+ type: "text",
388
+ text: `// ✅ Symbol "${pending.payload.symbolName}" removed\n\n${pending.payload.diff}`,
389
+ }],
390
+ };
391
+ }
392
+ if (!symbolName)
393
+ return errorResponse("Missing required parameter: symbolName");
394
+ // Validate symbol name
395
+ const symbolValidation = validateSymbolName(symbolName);
396
+ if (!symbolValidation.valid) {
397
+ return errorResponse(symbolValidation.error);
398
+ }
399
+ // SECURITY: Use secure validation with project boundary enforcement
400
+ const { validateFilePathSecure } = await import("../utils/secureValidation.js");
401
+ const validation = validateFilePathSecure(filePath);
402
+ if (!validation.valid) {
403
+ return errorResponse(validation.error);
404
+ }
405
+ const resolvedPath = validation.resolvedPath;
406
+ let fileContent;
407
+ try {
408
+ fileContent = fs.readFileSync(resolvedPath, "utf-8");
409
+ }
410
+ catch (error) {
411
+ return errorResponse(`Read failed: ${error instanceof Error ? error.message : String(error)}`);
412
+ }
413
+ // Safety check
414
+ if (!force) {
415
+ const projectRoot = findProjectRoot(resolvedPath);
416
+ if (projectRoot) {
417
+ const ignoreManager = new IgnoreManager(projectRoot);
418
+ const allFiles = await ignoreManager.walkDirectoryAsync();
419
+ for (const f of allFiles) {
420
+ if (path.resolve(f) === resolvedPath)
421
+ continue;
422
+ const fExt = path.extname(f).toLowerCase();
423
+ if (!IMPORTABLE_EXTENSIONS.has(fExt))
424
+ continue;
425
+ try {
426
+ const fContent = await fs.promises.readFile(f, "utf-8");
427
+ const escaped = symbolName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
428
+ const regex = new RegExp(`(?<=^|[^a-zA-Z0-9_$])(${escaped})(?=[^a-zA-Z0-9_$]|$)`);
429
+ if (regex.test(fContent)) {
430
+ return errorResponse(`Symbol "${symbolName}" used in ${path.relative(projectRoot, f)}. Use force: true to delete.`);
431
+ }
432
+ }
433
+ catch { }
434
+ }
435
+ }
436
+ }
437
+ const result = removeSymbolFromFile(resolvedPath, fileContent, symbolName, className);
438
+ if (!result.success) {
439
+ return errorResponse(result.error || "Unknown error");
440
+ }
441
+ const diff = generateDiff(fileContent, result.newContent, resolvedPath);
442
+ const token = confirmationCache.add("remove_symbol", resolvedPath, {
443
+ symbolName,
444
+ newContentFull: result.newContent,
445
+ diff
446
+ });
447
+ return {
448
+ content: [{
449
+ type: "text",
450
+ text: `// 🔍 DRY-RUN: Review changes below\n// To apply: confirmationToken: "${token}", confirm: true\n\n${diff}`,
451
+ }],
452
+ };
453
+ }
454
+ // ─── Utility Functions ──────────────────────────────────────────────
455
+ function errorResponse(message) {
456
+ return {
457
+ content: [{ type: "text", text: `❌ ${message}` }],
458
+ isError: true,
459
+ };
460
+ }
461
+ function findProjectRoot(filePath) {
462
+ const ROOT_MARKERS = ["package.json", ".git", "pubspec.yaml"];
463
+ let current = path.dirname(path.resolve(filePath));
464
+ const root = path.parse(current).root;
465
+ while (current !== root) {
466
+ for (const marker of ROOT_MARKERS) {
467
+ if (fs.existsSync(path.join(current, marker))) {
468
+ return current;
469
+ }
470
+ }
471
+ current = path.dirname(current);
472
+ }
473
+ return undefined;
474
+ }
475
+ //# sourceMappingURL=writeHandlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeHandlers.js","sourceRoot":"","sources":["../../../src/handlers/writeHandlers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,UAAU,EACV,YAAY,EACZ,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,GAGpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAEL,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,uEAAuE;AAEvE,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAA6B;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAkB,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAoB,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAoB,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,SAA+B,CAAC;IAEvD,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAuC,CAAC;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,OAA8B,CAAC;IAEpD,IAAI,CAAC,QAAQ;QAAE,OAAO,aAAa,CAAC,sCAAsC,CAAC,CAAC;IAE5E,iBAAiB;IACjB,IAAI,iBAAiB,IAAI,OAAO,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,qBAAqB,EAAE,CAAC;YAC5D,OAAO,aAAa,CAAC,uCAAuC,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;QACtC,IAAI,CAAC;YACH,YAAY,CAAC,YAAY,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,aAAa,CAAC,kBAAkB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACnG,CAAC;QAED,IAAI,CAAC;YACH,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;YACxE,mBAAmB,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,aAAa,CAAC,YAAY,CAAC,CAAC;YAC5B,OAAO,aAAa,CAAC,iBAAiB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClG,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,gBAAgB,OAAO,CAAC,OAAO,CAAC,UAAU,wBAAwB,YAAY,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE;iBAClH;aACF;SACF,CAAC;IACJ,CAAC;IAED,mBAAmB;IACnB,IAAI,CAAC,UAAU;QAAE,OAAO,aAAa,CAAC,wCAAwC,CAAC,CAAC;IAChF,IAAI,CAAC,UAAU;QAAE,OAAO,aAAa,CAAC,wCAAwC,CAAC,CAAC;IAEhF,uBAAuB;IACvB,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACxD,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC5B,OAAO,aAAa,CAAC,gBAAgB,CAAC,KAAM,CAAC,CAAC;IAChD,CAAC;IAED,oEAAoE;IACpE,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;IAChF,MAAM,UAAU,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,aAAa,CAAC,UAAU,CAAC,KAAM,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,CAAC,YAAa,CAAC;IAE9C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;IACrD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,aAAa,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,aAAa,CAAC,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,MAAM,GAAgB,aAAa,CAAC,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAEpG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC3E,IAAI,eAAe,EAAE,CAAC;YAClB,MAAM,SAAS,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,kBAAkB,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;YAE7D,MAAM,kBAAkB,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC9H,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE;gBAAE,kBAAkB,CAAC,IAAI,CAAC,UAAU,SAAS,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC;YAE3F,MAAM,WAAW,GAAG,EAAE,CAAC;YACvB,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;gBAC7F,IAAI,YAAY;oBAAE,WAAW,CAAC,IAAI,CAAC,mBAAmB,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC;YACnF,CAAC;iBAAM,CAAC;gBACN,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;gBAC/E,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;oBAAE,WAAW,CAAC,IAAI,CAAC,mBAAmB,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;YAC7F,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,WAAW,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACtE,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,KAAK,EAAE,MAAM,CAAC,KAAK;4BACnB,iBAAiB,EAAE,kBAAkB;4BACrC,WAAW;yBACZ,EAAE,IAAI,EAAE,CAAC,CAAC;qBACZ;iBACF;aACF,CAAC;QACN,CAAC;QACD,OAAO,aAAa,CAAC,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAEpE,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,qBAAqB,EAAE,YAAY,EAAE;QACvE,UAAU;QACV,cAAc,EAAE,MAAM,CAAC,UAAU;QACjC,IAAI;KACL,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,yEAAyE,KAAK,uBAAuB,IAAI,EAAE;aAClH;SACF;KACF,CAAC;AACJ,CAAC;AAED,uEAAuE;AAEvE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAA6B;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAkB,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAc,CAAC;IACjC,MAAM,YAAY,GAAI,IAAI,CAAC,YAAuB,IAAI,IAAI,CAAC;IAC3D,MAAM,QAAQ,GAAI,IAAI,CAAC,QAA2B,IAAI,OAAO,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,SAA+B,CAAC;IAEvD,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAuC,CAAC;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,OAA8B,CAAC;IAEpD,IAAI,CAAC,QAAQ;QAAE,OAAO,aAAa,CAAC,sCAAsC,CAAC,CAAC;IAE5E,UAAU;IACV,IAAI,iBAAiB,IAAI,OAAO,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,eAAe,EAAE,CAAC;YACtD,OAAO,aAAa,CAAC,uCAAuC,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;QACtC,IAAI,CAAC;YACH,YAAY,CAAC,YAAY,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,aAAa,CAAC,kBAAkB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACnG,CAAC;QAED,IAAI,CAAC;YACH,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;YACxE,mBAAmB,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,aAAa,CAAC,YAAY,CAAC,CAAC;YAC5B,OAAO,aAAa,CAAC,iBAAiB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClG,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,gCAAgC,YAAY,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE;iBAChF;aACF;SACF,CAAC;IACJ,CAAC;IAED,UAAU;IACV,IAAI,CAAC,IAAI;QAAE,OAAO,aAAa,CAAC,kCAAkC,CAAC,CAAC;IAEpE,oEAAoE;IACpE,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;IAChF,MAAM,UAAU,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,aAAa,CAAC,UAAU,CAAC,KAAM,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,CAAC,YAAa,CAAC;IAE9C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;IACrD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,aAAa,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACH,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,aAAa,CAAC,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,MAAM,GAAgB,UAAU,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE3G,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,aAAa,CAAC,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAExE,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,EAAE;QACjE,cAAc,EAAE,MAAM,CAAC,UAAU;QACjC,IAAI;QACJ,YAAY;QACZ,QAAQ;KACT,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,yEAAyE,KAAK,uBAAuB,IAAI,EAAE;aAClH;SACF;KACF,CAAC;AACJ,CAAC;AAED,uEAAuE;AAEvE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAA6B;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAkB,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAiB,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAiB,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,OAA6B,CAAC;IAEnD,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAuC,CAAC;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,OAA8B,CAAC;IAEpD,IAAI,CAAC,QAAQ;QAAE,OAAO,aAAa,CAAC,sCAAsC,CAAC,CAAC;IAE5E,UAAU;IACV,IAAI,iBAAiB,IAAI,OAAO,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,eAAe,EAAE,CAAC;YACtD,OAAO,aAAa,CAAC,uCAAuC,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QAExC,MAAM,WAAW,GAAG,IAAI,kBAAkB,EAAE,CAAC;QAC7C,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;YACjD,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB,CAAC,CAAC,CAAC,CAAC;QAEL,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC;QAChD,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;YAC1B,OAAO,aAAa,CAAC,YAAY,CAAC,KAAM,CAAC,CAAC;QAC5C,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,0BAA0B,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE;iBACvD,CAAC;SACH,CAAC;IACJ,CAAC;IAED,UAAU;IACV,IAAI,CAAC,OAAO;QAAE,OAAO,aAAa,CAAC,qCAAqC,CAAC,CAAC;IAC1E,IAAI,CAAC,OAAO;QAAE,OAAO,aAAa,CAAC,qCAAqC,CAAC,CAAC;IAE1E,wBAAwB;IACxB,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAClD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,aAAa,CAAC,oBAAoB,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAClD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,aAAa,CAAC,oBAAoB,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,oEAAoE;IACpE,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;IAChF,MAAM,UAAU,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,aAAa,CAAC,UAAU,CAAC,KAAM,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,CAAC,YAAa,CAAC;IAE9C,sEAAsE;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;IACrD,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,OAAO,aAAa,CAClB,0CAA0C,GAAG,aAAa;YAC1D,+EAA+E;YAC/E,gFAAgF;YAChF,8CAA8C;YAC9C,kDAAkD;YAClD,wDAAwD;YACxD,sEAAsE,CACvE,CAAC;IACJ,CAAC;IAED,IAAI,aAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,aAAa,CAAC,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACjF,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,aAAa,CAAC,YAAY,CAAC,KAAK,IAAI,WAAW,OAAO,aAAa,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,OAAO,GAAmE;QAC9E;YACE,QAAQ,EAAE,YAAY;YACtB,UAAU,EAAE,aAAa;YACzB,UAAU,EAAE,YAAY,CAAC,UAAU;SACpC;KACF,CAAC;IAEF,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IACpF,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,kBAAkB,EAAE,CAAC;QAE1D,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;QAClE,MAAM,gBAAgB,GAAG,MAAM,cAAc,CAC3C,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,EACtD,KAAK,EAAE,aAAa,EAAE,EAAE;YACtB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;YACtD,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC;YAEjD,IAAI,UAAkB,CAAC;YACvB,IAAI,CAAC;gBACH,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YAClE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;YAC/D,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,yBAAyB,OAAO,uBAAuB,CAAC,CAAC;YAClF,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;gBAAE,OAAO,IAAI,CAAC;YAEzC,MAAM,SAAS,GAAG,sBAAsB,CAAC,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACtF,IAAI,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;gBAC7D,OAAO;oBACL,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;oBACrC,UAAU,EAAE,UAAU;oBACtB,UAAU,EAAE,SAAS,CAAC,UAAU;iBACjC,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,EACD,EAAE,CACH,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,SAAS,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAEjD,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,EAAE;QACjE,OAAO;QACP,IAAI,EAAE,SAAS;KAChB,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,yEAAyE,KAAK,uBAAuB,SAAS,EAAE;aACvH,CAAC;KACH,CAAC;AACJ,CAAC;AAED,uEAAuE;AAEvE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAA6B;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAkB,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAoB,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,SAA+B,CAAC;IACvD,MAAM,KAAK,GAAI,IAAI,CAAC,KAAiB,IAAI,KAAK,CAAC;IAE/C,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAuC,CAAC;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,OAA8B,CAAC;IAEpD,IAAI,CAAC,QAAQ;QAAE,OAAO,aAAa,CAAC,sCAAsC,CAAC,CAAC;IAE5E,UAAU;IACV,IAAI,iBAAiB,IAAI,OAAO,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,eAAe,EAAE,CAAC;YACtD,OAAO,aAAa,CAAC,uCAAuC,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;QACtC,IAAI,CAAC;YAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAAC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC,CAAA,CAAC;QAEhD,IAAI,CAAC;YACH,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;YACxE,mBAAmB,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,aAAa,CAAC,YAAY,CAAC,CAAC;YAC5B,OAAO,aAAa,CAAC,iBAAiB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClG,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,gBAAgB,OAAO,CAAC,OAAO,CAAC,UAAU,gBAAgB,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE;iBACvF,CAAC;SACH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,UAAU;QAAE,OAAO,aAAa,CAAC,wCAAwC,CAAC,CAAC;IAEhF,uBAAuB;IACvB,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACxD,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC5B,OAAO,aAAa,CAAC,gBAAgB,CAAC,KAAM,CAAC,CAAC;IAChD,CAAC;IAED,oEAAoE;IACpE,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;IAChF,MAAM,UAAU,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,aAAa,CAAC,UAAU,CAAC,KAAM,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,CAAC,YAAa,CAAC;IAE9C,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACH,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,aAAa,CAAC,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;IAED,eAAe;IACf,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,WAAW,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;YACrD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,kBAAkB,EAAE,CAAC;YAE1D,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,YAAY;oBAAE,SAAS;gBAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC3C,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAE/C,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;oBACxD,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;oBAClE,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,yBAAyB,OAAO,uBAAuB,CAAC,CAAC;oBAElF,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACxB,OAAO,aAAa,CAAC,WAAW,UAAU,aAAa,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,8BAA8B,CAAC,CAAC;oBACvH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACtF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,aAAa,CAAC,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAExE,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,EAAE;QACjE,UAAU;QACV,cAAc,EAAE,MAAM,CAAC,UAAU;QACjC,IAAI;KACL,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,yEAAyE,KAAK,uBAAuB,IAAI,EAAE;aAClH,CAAC;KACH,CAAC;AACJ,CAAC;AAED,uEAAuE;AAEvE,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,OAAO,EAAE,EAAE,CAAC;QAC1D,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB;IACvC,MAAM,YAAY,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC9D,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;IAEtC,OAAO,OAAO,KAAK,IAAI,EAAE,CAAC;QACxB,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;YAClC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;gBAC9C,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -1,117 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * mcp-code-context — Semantic Code Context Server
3
+ * mcp-code-context — Semantic Code Context Server (v2.3.1 - Refactored)
4
4
  *
5
5
  * A Model Context Protocol (MCP) server that compresses any code repository
6
6
  * into LLM-ready semantic context and provides surgical code editing.
7
7
  *
8
- * Read Tools:
9
- * 1. get_semantic_repo_map — Compressed structural map of a repo
10
- * 2. read_file_surgical — Full file or specific symbol extraction
11
- * 3. analyze_impact — Find all dependents of a modified file
12
- *
13
- * Write Tools:
14
- * 4. write_file_surgical — Replace a symbol's code in-place
15
- * 5. insert_symbol — Insert code at precise AST positions
16
- * 6. rename_symbol — Rename across entire repository
17
- * 7. remove_symbol — Safely delete symbols with dep checking
8
+ * Architecture: Modular handlers with centralized utilities
9
+ * - Read handlers: get_semantic_repo_map, read_file_surgical, analyze_impact, etc.
10
+ * - Write handlers: write_file_surgical, insert_symbol, rename_symbol, remove_symbol
11
+ * - Util handlers: rollback_file, clean_backups
18
12
  *
19
13
  * Transport: stdio (JSON-RPC over stdin/stdout)
20
14
  * Compatible with: Claude Desktop, Cursor, Windsurf, Copilot, Amazon Q, and any MCP client.
21
15
  */
22
- export declare function handleGetSemanticRepoMap(args: Record<string, unknown>): Promise<{
23
- content: {
24
- type: "text";
25
- text: string;
26
- }[];
27
- isError: boolean;
28
- } | {
29
- content: {
30
- type: "text";
31
- text: string;
32
- }[];
33
- }>;
34
- export declare function handleReadFileSurgical(args: Record<string, unknown>): Promise<{
35
- content: {
36
- type: "text";
37
- text: string;
38
- }[];
39
- isError: boolean;
40
- } | {
41
- content: {
42
- type: "text";
43
- text: string;
44
- }[];
45
- }>;
46
- export declare function handleAnalyzeImpact(args: Record<string, unknown>): Promise<{
47
- content: {
48
- type: "text";
49
- text: string;
50
- }[];
51
- isError: boolean;
52
- } | {
53
- content: {
54
- type: "text";
55
- text: string;
56
- }[];
57
- }>;
58
- export declare function handleWriteFileSurgical(args: Record<string, unknown>): Promise<{
59
- content: {
60
- type: "text";
61
- text: string;
62
- }[];
63
- isError: boolean;
64
- } | {
65
- content: {
66
- type: "text";
67
- text: string;
68
- }[];
69
- }>;
70
- export declare function handleInsertSymbol(args: Record<string, unknown>): Promise<{
71
- content: {
72
- type: "text";
73
- text: string;
74
- }[];
75
- isError: boolean;
76
- } | {
77
- content: {
78
- type: "text";
79
- text: string;
80
- }[];
81
- }>;
82
- export declare function handleRenameSymbol(args: Record<string, unknown>): Promise<{
83
- content: {
84
- type: "text";
85
- text: string;
86
- }[];
87
- isError: boolean;
88
- } | {
89
- content: {
90
- type: "text";
91
- text: string;
92
- }[];
93
- }>;
94
- export declare function handleRemoveSymbol(args: Record<string, unknown>): Promise<{
95
- content: {
96
- type: "text";
97
- text: string;
98
- }[];
99
- isError: boolean;
100
- } | {
101
- content: {
102
- type: "text";
103
- text: string;
104
- }[];
105
- }>;
106
- export declare function handleRollbackFile(args: Record<string, unknown>): Promise<{
107
- content: {
108
- type: "text";
109
- text: string;
110
- }[];
111
- isError: boolean;
112
- } | {
113
- content: {
114
- type: "text";
115
- text: string;
116
- }[];
117
- }>;
16
+ export {};