mcp-code-context 3.9.2 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/INSTRUCTIONS.md +15 -4
  3. package/README.md +109 -5
  4. package/dist/src/core/engine.d.ts +1 -1
  5. package/dist/src/core/engine.js +1 -1
  6. package/dist/src/core/indexManager.d.ts +1 -1
  7. package/dist/src/core/indexManager.js +1 -1
  8. package/dist/src/core/sessionManager.d.ts +1 -1
  9. package/dist/src/core/sessionManager.js +1 -1
  10. package/dist/src/core/validator.d.ts +1 -1
  11. package/dist/src/core/validator.js +1 -1
  12. package/dist/src/index.d.ts +4 -2
  13. package/dist/src/index.js +119 -14
  14. package/dist/src/index.js.map +1 -1
  15. package/dist/src/operations/apiRoutes.d.ts +31 -0
  16. package/dist/src/operations/apiRoutes.js +170 -0
  17. package/dist/src/operations/apiRoutes.js.map +1 -0
  18. package/dist/src/operations/architectureLinter.d.ts +45 -0
  19. package/dist/src/operations/architectureLinter.js +223 -0
  20. package/dist/src/operations/architectureLinter.js.map +1 -0
  21. package/dist/src/operations/astComplexity.d.ts +38 -0
  22. package/dist/src/operations/astComplexity.js +243 -0
  23. package/dist/src/operations/astComplexity.js.map +1 -0
  24. package/dist/src/operations/astMockGenerator.d.ts +34 -0
  25. package/dist/src/operations/astMockGenerator.js +203 -0
  26. package/dist/src/operations/astMockGenerator.js.map +1 -0
  27. package/dist/src/operations/astQuery.d.ts +47 -0
  28. package/dist/src/operations/astQuery.js +169 -0
  29. package/dist/src/operations/astQuery.js.map +1 -0
  30. package/dist/src/operations/astTransform.d.ts +1 -1
  31. package/dist/src/operations/astTransform.js +11 -2
  32. package/dist/src/operations/astTransform.js.map +1 -1
  33. package/dist/src/operations/asyncBlockers.d.ts +33 -0
  34. package/dist/src/operations/asyncBlockers.js +162 -0
  35. package/dist/src/operations/asyncBlockers.js.map +1 -0
  36. package/dist/src/operations/blastRadiusReport.d.ts +43 -0
  37. package/dist/src/operations/blastRadiusReport.js +236 -0
  38. package/dist/src/operations/blastRadiusReport.js.map +1 -0
  39. package/dist/src/operations/callHierarchy.d.ts +28 -0
  40. package/dist/src/operations/callHierarchy.js +166 -0
  41. package/dist/src/operations/callHierarchy.js.map +1 -0
  42. package/dist/src/operations/circularDependencies.d.ts +28 -0
  43. package/dist/src/operations/circularDependencies.js +201 -0
  44. package/dist/src/operations/circularDependencies.js.map +1 -0
  45. package/dist/src/operations/classHierarchyFlattener.d.ts +35 -0
  46. package/dist/src/operations/classHierarchyFlattener.js +185 -0
  47. package/dist/src/operations/classHierarchyFlattener.js.map +1 -0
  48. package/dist/src/operations/compress.d.ts +2 -2
  49. package/dist/src/operations/compress.js +154 -20
  50. package/dist/src/operations/compress.js.map +1 -1
  51. package/dist/src/operations/conceptSearch.d.ts +19 -0
  52. package/dist/src/operations/conceptSearch.js +176 -0
  53. package/dist/src/operations/conceptSearch.js.map +1 -0
  54. package/dist/src/operations/confirmationStore.d.ts +1 -1
  55. package/dist/src/operations/confirmationStore.js +1 -1
  56. package/dist/src/operations/conflictPredictor.d.ts +21 -0
  57. package/dist/src/operations/conflictPredictor.js +139 -0
  58. package/dist/src/operations/conflictPredictor.js.map +1 -0
  59. package/dist/src/operations/contextCompactor.d.ts +38 -0
  60. package/dist/src/operations/contextCompactor.js +348 -0
  61. package/dist/src/operations/contextCompactor.js.map +1 -0
  62. package/dist/src/operations/cstCodemod.d.ts +34 -0
  63. package/dist/src/operations/cstCodemod.js +205 -0
  64. package/dist/src/operations/cstCodemod.js.map +1 -0
  65. package/dist/src/operations/deadSymbols.d.ts +32 -0
  66. package/dist/src/operations/deadSymbols.js +178 -0
  67. package/dist/src/operations/deadSymbols.js.map +1 -0
  68. package/dist/src/operations/envContract.d.ts +35 -0
  69. package/dist/src/operations/envContract.js +194 -0
  70. package/dist/src/operations/envContract.js.map +1 -0
  71. package/dist/src/operations/errorAudit.d.ts +36 -0
  72. package/dist/src/operations/errorAudit.js +201 -0
  73. package/dist/src/operations/errorAudit.js.map +1 -0
  74. package/dist/src/operations/importIntegrity.d.ts +48 -0
  75. package/dist/src/operations/importIntegrity.js +395 -0
  76. package/dist/src/operations/importIntegrity.js.map +1 -0
  77. package/dist/src/operations/incrementalDiff.d.ts +47 -0
  78. package/dist/src/operations/incrementalDiff.js +216 -0
  79. package/dist/src/operations/incrementalDiff.js.map +1 -0
  80. package/dist/src/operations/lexicalScope.d.ts +51 -0
  81. package/dist/src/operations/lexicalScope.js +212 -0
  82. package/dist/src/operations/lexicalScope.js.map +1 -0
  83. package/dist/src/operations/read.d.ts +21 -0
  84. package/dist/src/operations/read.js +21 -0
  85. package/dist/src/operations/read.js.map +1 -1
  86. package/dist/src/operations/readCore.js +37 -17
  87. package/dist/src/operations/readCore.js.map +1 -1
  88. package/dist/src/operations/rename.js +35 -24
  89. package/dist/src/operations/rename.js.map +1 -1
  90. package/dist/src/operations/sqlValidator.d.ts +36 -0
  91. package/dist/src/operations/sqlValidator.js +202 -0
  92. package/dist/src/operations/sqlValidator.js.map +1 -0
  93. package/dist/src/operations/symbolQuery.js +112 -23
  94. package/dist/src/operations/symbolQuery.js.map +1 -1
  95. package/dist/src/operations/taintAnalysis.d.ts +46 -0
  96. package/dist/src/operations/taintAnalysis.js +220 -0
  97. package/dist/src/operations/taintAnalysis.js.map +1 -0
  98. package/dist/src/operations/testImpact.d.ts +31 -0
  99. package/dist/src/operations/testImpact.js +179 -0
  100. package/dist/src/operations/testImpact.js.map +1 -0
  101. package/dist/src/operations/typeInference.d.ts +54 -0
  102. package/dist/src/operations/typeInference.js +565 -0
  103. package/dist/src/operations/typeInference.js.map +1 -0
  104. package/dist/src/operations/wireContract.d.ts +34 -0
  105. package/dist/src/operations/wireContract.js +185 -0
  106. package/dist/src/operations/wireContract.js.map +1 -0
  107. package/dist/src/operations/write.d.ts +2 -2
  108. package/dist/src/operations/write.js +151 -82
  109. package/dist/src/operations/write.js.map +1 -1
  110. package/dist/src/parsers/base.d.ts +9 -1
  111. package/dist/src/parsers/base.js +61 -1
  112. package/dist/src/parsers/base.js.map +1 -1
  113. package/dist/src/parsers/csharp.d.ts +1 -1
  114. package/dist/src/parsers/csharp.js +1 -1
  115. package/dist/src/parsers/dartTreeSitter.d.ts +1 -1
  116. package/dist/src/parsers/dartTreeSitter.js +1 -1
  117. package/dist/src/parsers/go.d.ts +1 -1
  118. package/dist/src/parsers/go.js +1 -1
  119. package/dist/src/parsers/java.d.ts +1 -1
  120. package/dist/src/parsers/java.js +1 -1
  121. package/dist/src/parsers/kotlin.d.ts +1 -1
  122. package/dist/src/parsers/kotlin.js +1 -1
  123. package/dist/src/parsers/php.d.ts +1 -1
  124. package/dist/src/parsers/php.js +1 -1
  125. package/dist/src/parsers/python.d.ts +1 -1
  126. package/dist/src/parsers/python.js +1 -1
  127. package/dist/src/parsers/registry.d.ts +1 -1
  128. package/dist/src/parsers/registry.js +1 -1
  129. package/dist/src/parsers/ruby.d.ts +1 -1
  130. package/dist/src/parsers/ruby.js +1 -1
  131. package/dist/src/parsers/rust.d.ts +1 -1
  132. package/dist/src/parsers/rust.js +1 -1
  133. package/dist/src/parsers/typescript.d.ts +1 -1
  134. package/dist/src/parsers/typescript.js +1 -1
  135. package/dist/src/tools/context.d.ts +4 -0
  136. package/dist/src/tools/context.js +14 -0
  137. package/dist/src/tools/context.js.map +1 -1
  138. package/dist/src/tools/pipeline.js +26 -0
  139. package/dist/src/tools/pipeline.js.map +1 -1
  140. package/dist/src/tools/readHandlers.d.ts +150 -0
  141. package/dist/src/tools/readHandlers.js +622 -17
  142. package/dist/src/tools/readHandlers.js.map +1 -1
  143. package/dist/src/tools/toolDefinitions.d.ts +2184 -0
  144. package/dist/src/tools/toolDefinitionsCore.d.ts +2184 -0
  145. package/dist/src/tools/toolDefinitionsCore.js +381 -1
  146. package/dist/src/tools/toolDefinitionsCore.js.map +1 -1
  147. package/dist/src/tools/writeHandlers.js +3 -1
  148. package/dist/src/tools/writeHandlers.js.map +1 -1
  149. package/dist/src/utils/appDir.d.ts +1 -1
  150. package/dist/src/utils/appDir.js +1 -1
  151. package/dist/src/utils/auditLogger.d.ts +1 -1
  152. package/dist/src/utils/auditLogger.js +1 -1
  153. package/dist/src/utils/backupManager.d.ts +1 -1
  154. package/dist/src/utils/backupManager.js +1 -1
  155. package/dist/src/utils/conceptEngine.d.ts +56 -0
  156. package/dist/src/utils/conceptEngine.js +234 -0
  157. package/dist/src/utils/conceptEngine.js.map +1 -0
  158. package/dist/src/utils/constants.d.ts +1 -1
  159. package/dist/src/utils/constants.js +2 -1
  160. package/dist/src/utils/constants.js.map +1 -1
  161. package/dist/src/utils/diff.d.ts +1 -1
  162. package/dist/src/utils/diff.js +1 -1
  163. package/dist/src/utils/fileLock.d.ts +1 -1
  164. package/dist/src/utils/fileLock.js +1 -1
  165. package/dist/src/utils/fileWalker.d.ts +1 -1
  166. package/dist/src/utils/fileWalker.js +1 -1
  167. package/dist/src/utils/fileWatcher.d.ts +1 -1
  168. package/dist/src/utils/fileWatcher.js +1 -1
  169. package/dist/src/utils/fuzzySearch.d.ts +1 -1
  170. package/dist/src/utils/fuzzySearch.js +1 -1
  171. package/dist/src/utils/gemfileParser.d.ts +1 -1
  172. package/dist/src/utils/gemfileParser.js +1 -1
  173. package/dist/src/utils/logger.d.ts +1 -1
  174. package/dist/src/utils/logger.js +1 -1
  175. package/dist/src/utils/metaprogramming.d.ts +1 -1
  176. package/dist/src/utils/metaprogramming.js +1 -1
  177. package/dist/src/utils/railsRoutes.d.ts +1 -1
  178. package/dist/src/utils/railsRoutes.js +1 -1
  179. package/dist/src/utils/rateLimiter.d.ts +26 -1
  180. package/dist/src/utils/rateLimiter.js +26 -1
  181. package/dist/src/utils/rateLimiter.js.map +1 -1
  182. package/dist/src/utils/streaming.d.ts +1 -1
  183. package/dist/src/utils/streaming.js +1 -1
  184. package/dist/src/utils/telemetry.d.ts +1 -1
  185. package/dist/src/utils/telemetry.js +1 -1
  186. package/dist/src/utils/virtualSchema.d.ts +31 -0
  187. package/dist/src/utils/virtualSchema.js +367 -0
  188. package/dist/src/utils/virtualSchema.js.map +1 -0
  189. package/llms.txt +13 -3
  190. package/package.json +4 -2
  191. package/skills/code-context-logo.png +0 -0
  192. package/skills/code-context-pro/SKILL.md +149 -0
  193. package/skills/code-context-pro/references/benchmarks.md +25 -0
  194. package/skills/code-context-pro/references/decision-tree.md +32 -0
  195. package/skills/code-context-pro/references/multi-ide-setup.md +104 -0
  196. package/skills/code-context-pro.zip +0 -0
  197. package/HIRE_ME.md +0 -234
  198. package/SPONSORS.md +0 -104
@@ -2,23 +2,28 @@
2
2
  import * as path from "node:path";
3
3
  import * as fs from "node:fs/promises";
4
4
  import { SecurityValidator } from "../core/validator.js";
5
- import { extractSymbol, readLines, searchPattern, analyzeImpact, searchSymbols, explainSymbol, batchRead } from "../operations/read.js";
5
+ import { extractSymbol, readLines, searchPattern, analyzeImpact, searchSymbols, searchCodeConcept, verifyImportIntegrity, traceTaintFlow, backfillTypes, enforceArchitectureRules, compactContextLedger, generateAstImpactReport, queryCodeAst, incrementalAstDiff, getAstComplexityMatrix, generateAstMocks, detectDeadAstSymbols, resolveLexicalScope, validateSqlAst, astCodemodTranspile, detectAsyncEventloopBlockers, verifyEnvContractDrift, auditErrorHandlingContracts, extractApiRouteMatrix, flattenClassHierarchy, detectCircularDependencies, explainSymbol, batchRead } from "../operations/read.js";
6
6
  import { compressRepository } from "../operations/compress.js";
7
7
  import { streamFile } from "../utils/streaming.js";
8
8
  import { assertNoPendingWriteConflict } from "../utils/toctou.js";
9
9
  import { getSession, getCacheManager, getRegistry } from "./context.js";
10
- import { loadRailsSchema, modelToTable, formatSchemaAnnotation } from "../utils/railsSchema.js";
10
+ import { modelToTable } from "../utils/railsSchema.js";
11
+ import { loadUnifiedVirtualSchema, formatUnifiedSchemaAnnotation } from "../utils/virtualSchema.js";
11
12
  import { parseGemfile, formatGemAnnotation } from "../utils/gemfileParser.js";
12
13
  import { findMetaprogrammingEntryPoints, formatMetaprogrammingResults } from "../utils/metaprogramming.js";
13
14
  import { parseRailsRoutes } from "../utils/railsRoutes.js";
14
15
  import { resolveProjectRoot } from "../utils/projectRoot.js";
16
+ import { getImpactedTests } from "../operations/testImpact.js";
17
+ import { getCallHierarchy } from "../operations/callHierarchy.js";
18
+ import { validateWireContract } from "../operations/wireContract.js";
19
+ import { predictSemanticConflicts } from "../operations/conflictPredictor.js";
15
20
  export async function handleGetSemanticRepoMap(args) {
16
21
  if (!args.directoryPath) {
17
22
  throw new Error("directoryPath is required (e.g. C:\\code\\mcp-code-context)");
18
23
  }
19
24
  const directoryPath = String(args.directoryPath);
20
25
  const projectRoot = resolveProjectRoot(args, directoryPath);
21
- const format = args.format === "markdown" ? "markdown" : "xml";
26
+ const format = args.format === "markdown" ? "markdown" : args.format === "html" ? "html" : "xml";
22
27
  const validator = new SecurityValidator(projectRoot);
23
28
  const validation = await validator.validateFilePath(directoryPath);
24
29
  if (!validation.valid) {
@@ -77,32 +82,76 @@ export async function handleReadFileSurgical(args) {
77
82
  content = await fs.readFile(validation.resolvedPath, "utf-8");
78
83
  }
79
84
  }
80
- // ActiveRecord Virtual Schema injection
81
- if (path.extname(filePath) === ".rb") {
82
- // When extracting a symbol, `content` is only the method body — no class declaration.
83
- // We need the full file to detect AR inheritance, but guard with stat first to
84
- // avoid allocating >5MB files without the streaming guard.
85
+ // Unified Virtual ORM Schema injection (ActiveRecord, Eloquent, Django, Prisma, Drizzle)
86
+ const fileExt = path.extname(filePath);
87
+ if (fileExt === ".rb" || fileExt === ".php" || fileExt === ".py" || fileExt === ".ts" || fileExt === ".tsx" || fileExt === ".js" || fileExt === ".prisma") {
85
88
  let sourceForDetection = content;
86
89
  if (symbolName) {
87
90
  const fileStat = await fs.stat(validation.resolvedPath);
88
91
  if (fileStat.size <= 5 * 1024 * 1024) {
89
92
  sourceForDetection = await fs.readFile(validation.resolvedPath, "utf-8");
90
93
  }
91
- // Files >5MB: skip schema injection for symbol extracts — not worth the memory cost
92
94
  }
93
- const arMatch = sourceForDetection.match(/class\s+(\w+)\s*<\s*(?:ApplicationRecord|ActiveRecord::Base)/);
94
- if (arMatch) {
95
- const schema = await loadRailsSchema(projectRoot);
96
- if (schema) {
97
- const tableName = modelToTable(arMatch[1]);
98
- const columns = schema[tableName];
95
+ let modelName = null;
96
+ if (fileExt === ".rb") {
97
+ const m = sourceForDetection.match(/class\s+(\w+)\s*<\s*(?:ApplicationRecord|ActiveRecord::Base)/);
98
+ if (m) {
99
+ modelName = m[1];
100
+ }
101
+ }
102
+ else if (fileExt === ".php") {
103
+ const m = sourceForDetection.match(/class\s+(\w+)\s+extends\s+(?:Model|Authenticatable)/);
104
+ if (m) {
105
+ modelName = m[1];
106
+ }
107
+ }
108
+ else if (fileExt === ".py") {
109
+ const m = sourceForDetection.match(/class\s+(\w+)\s*\([^)]*models\.Model[^)]*\):/);
110
+ if (m) {
111
+ modelName = m[1];
112
+ }
113
+ }
114
+ else if (fileExt === ".prisma") {
115
+ const m = sourceForDetection.match(/model\s+(\w+)\s*\{/);
116
+ if (m) {
117
+ modelName = m[1];
118
+ }
119
+ }
120
+ else if (fileExt === ".ts" || fileExt === ".tsx" || fileExt === ".js") {
121
+ const drizzleM = sourceForDetection.match(/(?:export\s+const\s+(\w+)\s*=\s*)?(?:pgTable|mysqlTable|sqliteTable)\s*\(\s*["']([^"']+)["']/);
122
+ const prismaM = sourceForDetection.match(/(?:interface|type|class)\s+(\w+)\b/);
123
+ if (drizzleM) {
124
+ modelName = drizzleM[2] || drizzleM[1];
125
+ }
126
+ else if (prismaM) {
127
+ modelName = prismaM[1];
128
+ }
129
+ }
130
+ if (modelName) {
131
+ const unified = await loadUnifiedVirtualSchema(projectRoot, fileExt).catch(() => null);
132
+ if (unified && unified.schema) {
133
+ const tableName = modelToTable(modelName);
134
+ const columns = unified.schema[tableName] || unified.schema[modelName.toLowerCase()] || unified.schema[modelName];
99
135
  if (columns && Object.keys(columns).length > 0) {
100
- content = formatSchemaAnnotation(tableName, columns) + "\n" + content;
136
+ content = formatUnifiedSchemaAnnotation(unified.framework, tableName, columns) + "\n" + content;
101
137
  }
102
138
  }
103
139
  }
104
140
  }
105
- return { content: [{ type: "text", text: content }] };
141
+ // Vector 5: Token Budget Efficiency Header
142
+ let efficiencyHeader = "";
143
+ try {
144
+ const stat = await fs.stat(validation.resolvedPath);
145
+ const rawTokens = Math.max(1, Math.ceil(stat.size / 4));
146
+ const deliveredTokens = Math.max(1, Math.ceil(content.length / 4));
147
+ const saved = Math.max(0, rawTokens - deliveredTokens);
148
+ const ratio = ((saved / rawTokens) * 100).toFixed(1);
149
+ efficiencyHeader = `<!-- [CodeContext Efficiency]: Raw: ~${rawTokens} tokens | Delivered: ~${deliveredTokens} tokens | Saved: ~${saved} tokens (${ratio}% compression) -->\n\n`;
150
+ }
151
+ catch {
152
+ // Non-blocking header computation
153
+ }
154
+ return { content: [{ type: "text", text: efficiencyHeader + content }] };
106
155
  }
107
156
  export async function handleAnalyzeImpact(args) {
108
157
  const filePath = String(args.filePath);
@@ -201,6 +250,481 @@ export async function handleSearchSymbols(args) {
201
250
  throw new Error(result.error);
202
251
  return { content: [{ type: "text", text: result.content }] };
203
252
  }
253
+ // NEW-02b: search_code_concept (v5.0.0)
254
+ export async function handleSearchCodeConcept(args) {
255
+ const rootDir = (args.rootDir && args.rootDir !== "undefined") ? String(args.rootDir) : undefined;
256
+ const projectRoot = resolveProjectRoot(args, rootDir);
257
+ const targetDir = rootDir || projectRoot;
258
+ const validator = new SecurityValidator(projectRoot);
259
+ const validation = await validator.validateFilePath(targetDir);
260
+ if (!validation.valid)
261
+ throw new Error(validation.error);
262
+ const registry = getRegistry();
263
+ const result = await searchCodeConcept({
264
+ rootDir: validation.resolvedPath,
265
+ projectRoot,
266
+ query: String(args.query || ""),
267
+ threshold: args.threshold !== undefined ? Number(args.threshold) : undefined,
268
+ maxResults: args.maxResults !== undefined ? Number(args.maxResults) : undefined,
269
+ fileExtensions: args.fileExtensions,
270
+ excludeDirs: args.excludeDirs,
271
+ registry,
272
+ });
273
+ if (!result.success)
274
+ throw new Error(result.error);
275
+ return { content: [{ type: "text", text: result.content }] };
276
+ }
277
+ // NEW-02c: verify_import_integrity (v5.0.0)
278
+ export async function handleVerifyImportIntegrity(args) {
279
+ if (!args.filePath)
280
+ throw new Error("filePath is required for verify_import_integrity");
281
+ const filePath = String(args.filePath);
282
+ const projectRoot = resolveProjectRoot(args, filePath);
283
+ const validator = new SecurityValidator(projectRoot);
284
+ const validation = await validator.validateFilePath(filePath);
285
+ if (!validation.valid)
286
+ throw new Error(validation.error);
287
+ const registry = getRegistry();
288
+ const result = await verifyImportIntegrity({
289
+ filePath: validation.resolvedPath,
290
+ projectRoot,
291
+ content: args.content ? String(args.content) : undefined,
292
+ registry,
293
+ });
294
+ if (!result.success)
295
+ throw new Error(result.error);
296
+ return { content: [{ type: "text", text: result.content }] };
297
+ }
298
+ // NEW-02d: trace_taint_flow (v5.1.0)
299
+ export async function handleTraceTaintFlow(args) {
300
+ if (!args.filePath)
301
+ throw new Error("filePath is required for trace_taint_flow");
302
+ const filePath = String(args.filePath);
303
+ const projectRoot = resolveProjectRoot(args, filePath);
304
+ const validator = new SecurityValidator(projectRoot);
305
+ const validation = await validator.validateFilePath(filePath);
306
+ if (!validation.valid && !args.content)
307
+ throw new Error(validation.error);
308
+ const resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
309
+ const registry = getRegistry();
310
+ const result = await traceTaintFlow({
311
+ filePath: resolvedTarget,
312
+ projectRoot,
313
+ sourceParam: args.sourceParam ? String(args.sourceParam) : undefined,
314
+ dangerousSink: args.dangerousSink ? String(args.dangerousSink) : undefined,
315
+ content: args.content ? String(args.content) : undefined,
316
+ registry,
317
+ });
318
+ if (!result.success)
319
+ throw new Error(result.error);
320
+ return { content: [{ type: "text", text: result.content }] };
321
+ }
322
+ // NEW-02e: backfill_types (v4.5.0)
323
+ export async function handleBackfillTypes(args) {
324
+ if (!args.filePath)
325
+ throw new Error("filePath is required for backfill_types");
326
+ const filePath = String(args.filePath);
327
+ const projectRoot = resolveProjectRoot(args, filePath);
328
+ const validator = new SecurityValidator(projectRoot);
329
+ const validation = await validator.validateFilePath(filePath);
330
+ if (!validation.valid && !args.content)
331
+ throw new Error(validation.error);
332
+ const resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
333
+ const registry = getRegistry();
334
+ const result = await backfillTypes({
335
+ filePath: resolvedTarget,
336
+ projectRoot,
337
+ symbolName: args.symbolName ? String(args.symbolName) : undefined,
338
+ targetLanguage: args.targetLanguage,
339
+ content: args.content ? String(args.content) : undefined,
340
+ registry,
341
+ });
342
+ if (!result.success)
343
+ throw new Error(result.error);
344
+ return { content: [{ type: "text", text: result.content }] };
345
+ }
346
+ // NEW-02f: enforce_architecture_rules (v4.6.0)
347
+ export async function handleEnforceArchitectureRules(args) {
348
+ const filePath = args.filePath ? String(args.filePath) : undefined;
349
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
350
+ let resolvedTarget = filePath;
351
+ if (filePath) {
352
+ const validator = new SecurityValidator(projectRoot);
353
+ const validation = await validator.validateFilePath(filePath);
354
+ if (!validation.valid && !args.content)
355
+ throw new Error(validation.error);
356
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
357
+ }
358
+ const result = await enforceArchitectureRules({
359
+ filePath: resolvedTarget,
360
+ projectRoot,
361
+ rules: args.rules,
362
+ content: args.content ? String(args.content) : undefined,
363
+ });
364
+ if (!result.success)
365
+ throw new Error(result.error);
366
+ return { content: [{ type: "text", text: result.content }] };
367
+ }
368
+ // NEW-02g: compact_context_ledger (v4.7.0)
369
+ export async function handleCompactContextLedger(args) {
370
+ if (!args.filePaths)
371
+ throw new Error("filePaths is required for compact_context_ledger");
372
+ const projectRoot = resolveProjectRoot(args, ".");
373
+ const registry = getRegistry();
374
+ const result = await compactContextLedger({
375
+ filePaths: args.filePaths,
376
+ projectRoot,
377
+ dropPrivate: args.dropPrivate,
378
+ includeDocstrings: args.includeDocstrings,
379
+ content: args.content ? String(args.content) : undefined,
380
+ registry,
381
+ });
382
+ if (!result.success)
383
+ throw new Error(result.error);
384
+ return { content: [{ type: "text", text: result.content }] };
385
+ }
386
+ // NEW-02h: generate_ast_impact_report (v5.0.0)
387
+ export async function handleGenerateAstImpactReport(args) {
388
+ const projectRoot = resolveProjectRoot(args, ".");
389
+ const result = await generateAstImpactReport({
390
+ baseBranch: args.baseBranch ? String(args.baseBranch) : undefined,
391
+ targetBranch: args.targetBranch ? String(args.targetBranch) : undefined,
392
+ projectRoot,
393
+ includeTests: args.includeTests !== undefined ? Boolean(args.includeTests) : true,
394
+ includeArchitecture: args.includeArchitecture !== undefined ? Boolean(args.includeArchitecture) : true,
395
+ });
396
+ if (!result.success)
397
+ throw new Error(result.error);
398
+ return { content: [{ type: "text", text: result.content }] };
399
+ }
400
+ // NEW-02i: query_code_ast (v5.1.0)
401
+ export async function handleQueryCodeAst(args) {
402
+ const filePath = args.filePath ? String(args.filePath) : undefined;
403
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
404
+ let resolvedTarget = filePath;
405
+ if (filePath) {
406
+ const validator = new SecurityValidator(projectRoot);
407
+ const validation = await validator.validateFilePath(filePath);
408
+ if (!validation.valid && !args.code)
409
+ throw new Error(validation.error);
410
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
411
+ }
412
+ const registry = getRegistry();
413
+ const result = await queryCodeAst({
414
+ filePath: resolvedTarget,
415
+ projectRoot,
416
+ query: args.query ? String(args.query) : undefined,
417
+ template: args.template,
418
+ code: args.code ? String(args.code) : undefined,
419
+ limit: args.limit ? Number(args.limit) : undefined,
420
+ registry,
421
+ });
422
+ if (!result.success)
423
+ throw new Error(result.error);
424
+ return { content: [{ type: "text", text: result.content }] };
425
+ }
426
+ // NEW-02j: incremental_ast_diff (v5.1.0)
427
+ export async function handleIncrementalAstDiff(args) {
428
+ const filePath = args.filePath ? String(args.filePath) : undefined;
429
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
430
+ let resolvedTarget = filePath;
431
+ if (filePath) {
432
+ const validator = new SecurityValidator(projectRoot);
433
+ const validation = await validator.validateFilePath(filePath);
434
+ if (!validation.valid && !args.oldCode)
435
+ throw new Error(validation.error);
436
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
437
+ }
438
+ const registry = getRegistry();
439
+ const result = await incrementalAstDiff({
440
+ filePath: resolvedTarget,
441
+ projectRoot,
442
+ oldCode: args.oldCode ? String(args.oldCode) : undefined,
443
+ newCode: args.newCode ? String(args.newCode) : undefined,
444
+ registry,
445
+ });
446
+ if (!result.success)
447
+ throw new Error(result.error);
448
+ return { content: [{ type: "text", text: result.content }] };
449
+ }
450
+ // NEW-02k: get_ast_complexity_matrix (v5.6.0)
451
+ export async function handleGetAstComplexityMatrix(args) {
452
+ const filePath = args.filePath ? String(args.filePath) : undefined;
453
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
454
+ let resolvedTarget = filePath;
455
+ if (filePath) {
456
+ const validator = new SecurityValidator(projectRoot);
457
+ const validation = await validator.validateFilePath(filePath);
458
+ if (!validation.valid && !args.code)
459
+ throw new Error(validation.error);
460
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
461
+ }
462
+ const registry = getRegistry();
463
+ const result = await getAstComplexityMatrix({
464
+ filePath: resolvedTarget,
465
+ projectRoot,
466
+ code: args.code ? String(args.code) : undefined,
467
+ threshold: args.threshold ? Number(args.threshold) : undefined,
468
+ registry,
469
+ });
470
+ if (!result.success)
471
+ throw new Error(result.error);
472
+ return { content: [{ type: "text", text: result.content }] };
473
+ }
474
+ // NEW-02l: generate_ast_mocks (v5.6.0)
475
+ export async function handleGenerateAstMocks(args) {
476
+ if (!args.symbolName)
477
+ throw new Error("symbolName is required for generate_ast_mocks");
478
+ const filePath = args.filePath ? String(args.filePath) : undefined;
479
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
480
+ let resolvedTarget = filePath;
481
+ if (filePath) {
482
+ const validator = new SecurityValidator(projectRoot);
483
+ const validation = await validator.validateFilePath(filePath);
484
+ if (!validation.valid && !args.code)
485
+ throw new Error(validation.error);
486
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
487
+ }
488
+ const registry = getRegistry();
489
+ const result = await generateAstMocks({
490
+ filePath: resolvedTarget,
491
+ projectRoot,
492
+ symbolName: String(args.symbolName),
493
+ format: args.format,
494
+ code: args.code ? String(args.code) : undefined,
495
+ registry,
496
+ });
497
+ if (!result.success)
498
+ throw new Error(result.error);
499
+ return { content: [{ type: "text", text: result.content }] };
500
+ }
501
+ // NEW-02m: detect_dead_ast_symbols (v5.7.0)
502
+ export async function handleDetectDeadAstSymbols(args) {
503
+ const filePath = args.filePath ? String(args.filePath) : undefined;
504
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
505
+ let resolvedTarget = filePath;
506
+ if (filePath) {
507
+ const validator = new SecurityValidator(projectRoot);
508
+ const validation = await validator.validateFilePath(filePath);
509
+ if (!validation.valid && !args.code)
510
+ throw new Error(validation.error);
511
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
512
+ }
513
+ const registry = getRegistry();
514
+ const result = await detectDeadAstSymbols({
515
+ filePath: resolvedTarget,
516
+ projectRoot,
517
+ code: args.code ? String(args.code) : undefined,
518
+ registry,
519
+ });
520
+ if (!result.success)
521
+ throw new Error(result.error);
522
+ return { content: [{ type: "text", text: result.content }] };
523
+ }
524
+ // NEW-02n: resolve_lexical_scope (v5.7.0)
525
+ export async function handleResolveLexicalScope(args) {
526
+ const filePath = args.filePath ? String(args.filePath) : undefined;
527
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
528
+ let resolvedTarget = filePath;
529
+ if (filePath) {
530
+ const validator = new SecurityValidator(projectRoot);
531
+ const validation = await validator.validateFilePath(filePath);
532
+ if (!validation.valid && !args.code)
533
+ throw new Error(validation.error);
534
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
535
+ }
536
+ const registry = getRegistry();
537
+ const result = await resolveLexicalScope({
538
+ filePath: resolvedTarget,
539
+ projectRoot,
540
+ code: args.code ? String(args.code) : undefined,
541
+ proposedRename: args.proposedRename,
542
+ registry,
543
+ });
544
+ if (!result.success)
545
+ throw new Error(result.error);
546
+ return { content: [{ type: "text", text: result.content }] };
547
+ }
548
+ // NEW-02o: sql_ast_validator (v6.0.0)
549
+ export async function handleValidateSqlAst(args) {
550
+ const filePath = args.filePath ? String(args.filePath) : undefined;
551
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
552
+ let resolvedTarget = filePath;
553
+ if (filePath) {
554
+ const validator = new SecurityValidator(projectRoot);
555
+ const validation = await validator.validateFilePath(filePath);
556
+ if (!validation.valid && !args.code)
557
+ throw new Error(validation.error);
558
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
559
+ }
560
+ const registry = getRegistry();
561
+ const result = await validateSqlAst({
562
+ filePath: resolvedTarget,
563
+ projectRoot,
564
+ code: args.code ? String(args.code) : undefined,
565
+ registry,
566
+ });
567
+ if (!result.success)
568
+ throw new Error(result.error);
569
+ return { content: [{ type: "text", text: result.content }] };
570
+ }
571
+ // NEW-02p: ast_codemod_transpile (v6.0.0)
572
+ export async function handleAstCodemodTranspile(args) {
573
+ if (!args.rule)
574
+ throw new Error("rule is required for ast_codemod_transpile (e.g. 'cjs-to-esm', 'strip-console')");
575
+ const filePath = args.filePath ? String(args.filePath) : undefined;
576
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
577
+ let resolvedTarget = filePath;
578
+ if (filePath) {
579
+ const validator = new SecurityValidator(projectRoot);
580
+ const validation = await validator.validateFilePath(filePath);
581
+ if (!validation.valid && !args.code)
582
+ throw new Error(validation.error);
583
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
584
+ }
585
+ const registry = getRegistry();
586
+ const result = await astCodemodTranspile({
587
+ filePath: resolvedTarget,
588
+ projectRoot,
589
+ rule: args.rule,
590
+ code: args.code ? String(args.code) : undefined,
591
+ registry,
592
+ });
593
+ if (!result.success)
594
+ throw new Error(result.error);
595
+ return { content: [{ type: "text", text: result.content }] };
596
+ }
597
+ // NEW-02q: detect_async_eventloop_blockers (v7.0.0)
598
+ export async function handleDetectAsyncEventloopBlockers(args) {
599
+ const filePath = args.filePath ? String(args.filePath) : undefined;
600
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
601
+ let resolvedTarget = filePath;
602
+ if (filePath) {
603
+ const validator = new SecurityValidator(projectRoot);
604
+ const validation = await validator.validateFilePath(filePath);
605
+ if (!validation.valid && !args.code)
606
+ throw new Error(validation.error);
607
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
608
+ }
609
+ const registry = getRegistry();
610
+ const result = await detectAsyncEventloopBlockers({
611
+ filePath: resolvedTarget,
612
+ projectRoot,
613
+ code: args.code ? String(args.code) : undefined,
614
+ registry,
615
+ });
616
+ if (!result.success)
617
+ throw new Error(result.error);
618
+ return { content: [{ type: "text", text: result.content }] };
619
+ }
620
+ // NEW-02r: verify_env_contract_drift (v7.0.0)
621
+ export async function handleVerifyEnvContractDrift(args) {
622
+ const filePath = args.filePath ? String(args.filePath) : undefined;
623
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
624
+ let resolvedTarget = filePath;
625
+ if (filePath) {
626
+ const validator = new SecurityValidator(projectRoot);
627
+ const validation = await validator.validateFilePath(filePath);
628
+ if (!validation.valid && !args.code)
629
+ throw new Error(validation.error);
630
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
631
+ }
632
+ const registry = getRegistry();
633
+ const result = await verifyEnvContractDrift({
634
+ filePath: resolvedTarget,
635
+ projectRoot,
636
+ code: args.code ? String(args.code) : undefined,
637
+ envExampleContent: args.envExampleContent ? String(args.envExampleContent) : undefined,
638
+ registry,
639
+ });
640
+ if (!result.success)
641
+ throw new Error(result.error);
642
+ return { content: [{ type: "text", text: result.content }] };
643
+ }
644
+ // NEW-02s: audit_error_handling_contracts (v7.0.0)
645
+ export async function handleAuditErrorHandlingContracts(args) {
646
+ const filePath = args.filePath ? String(args.filePath) : undefined;
647
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
648
+ let resolvedTarget = filePath;
649
+ if (filePath) {
650
+ const validator = new SecurityValidator(projectRoot);
651
+ const validation = await validator.validateFilePath(filePath);
652
+ if (!validation.valid && !args.code)
653
+ throw new Error(validation.error);
654
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
655
+ }
656
+ const registry = getRegistry();
657
+ const result = await auditErrorHandlingContracts({
658
+ filePath: resolvedTarget,
659
+ projectRoot,
660
+ code: args.code ? String(args.code) : undefined,
661
+ registry,
662
+ });
663
+ if (!result.success)
664
+ throw new Error(result.error);
665
+ return { content: [{ type: "text", text: result.content }] };
666
+ }
667
+ // NEW-02t: extract_api_route_matrix (v7.0.0)
668
+ export async function handleExtractApiRouteMatrix(args) {
669
+ const filePath = args.filePath ? String(args.filePath) : undefined;
670
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
671
+ let resolvedTarget = filePath;
672
+ if (filePath) {
673
+ const validator = new SecurityValidator(projectRoot);
674
+ const validation = await validator.validateFilePath(filePath);
675
+ if (!validation.valid && !args.code)
676
+ throw new Error(validation.error);
677
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
678
+ }
679
+ const registry = getRegistry();
680
+ const result = await extractApiRouteMatrix({
681
+ filePath: resolvedTarget,
682
+ projectRoot,
683
+ code: args.code ? String(args.code) : undefined,
684
+ registry,
685
+ });
686
+ if (!result.success)
687
+ throw new Error(result.error);
688
+ return { content: [{ type: "text", text: result.content }] };
689
+ }
690
+ // NEW-02u: flatten_class_hierarchy (v7.0.0)
691
+ export async function handleFlattenClassHierarchy(args) {
692
+ const filePath = args.filePath ? String(args.filePath) : undefined;
693
+ const projectRoot = resolveProjectRoot(args, filePath || ".");
694
+ let resolvedTarget = filePath;
695
+ if (filePath) {
696
+ const validator = new SecurityValidator(projectRoot);
697
+ const validation = await validator.validateFilePath(filePath);
698
+ if (!validation.valid && !args.code)
699
+ throw new Error(validation.error);
700
+ resolvedTarget = validation.resolvedPath || path.resolve(projectRoot, filePath);
701
+ }
702
+ const registry = getRegistry();
703
+ const result = await flattenClassHierarchy({
704
+ filePath: resolvedTarget,
705
+ projectRoot,
706
+ className: args.className ? String(args.className) : undefined,
707
+ code: args.code ? String(args.code) : undefined,
708
+ registry,
709
+ });
710
+ if (!result.success)
711
+ throw new Error(result.error);
712
+ return { content: [{ type: "text", text: result.content }] };
713
+ }
714
+ // NEW-02v: detect_circular_dependencies (v7.0.0)
715
+ export async function handleDetectCircularDependencies(args) {
716
+ const projectRoot = resolveProjectRoot(args, ".");
717
+ const registry = getRegistry();
718
+ const result = await detectCircularDependencies({
719
+ projectRoot,
720
+ filesMap: args.filesMap,
721
+ filePaths: args.filePaths,
722
+ registry,
723
+ });
724
+ if (!result.success)
725
+ throw new Error(result.error);
726
+ return { content: [{ type: "text", text: result.content }] };
727
+ }
204
728
  // NEW-03: explain_symbol
205
729
  export async function handleExplainSymbol(args) {
206
730
  const filePath = String(args.filePath);
@@ -297,4 +821,85 @@ export async function handleGetRailsRoutes(args) {
297
821
  }
298
822
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
299
823
  }
824
+ // TIA: get_impacted_tests — map modified AST symbols to target test suites
825
+ export async function handleGetImpactedTests(args) {
826
+ if (!args.filePath)
827
+ throw new Error("filePath is required");
828
+ const filePath = String(args.filePath);
829
+ const projectRoot = resolveProjectRoot(args, filePath);
830
+ const symbolName = args.symbolName ? String(args.symbolName) : undefined;
831
+ const validator = new SecurityValidator(projectRoot);
832
+ const validation = await validator.validateFilePath(filePath);
833
+ if (!validation.valid)
834
+ throw new Error(validation.error);
835
+ const result = await getImpactedTests({
836
+ filePath: validation.resolvedPath,
837
+ symbolName,
838
+ projectRoot,
839
+ });
840
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
841
+ }
842
+ // 3-Hop Call Hierarchy: get_call_hierarchy
843
+ export async function handleGetCallHierarchy(args) {
844
+ if (!args.filePath)
845
+ throw new Error("filePath is required");
846
+ if (!args.symbolName)
847
+ throw new Error("symbolName is required");
848
+ const filePath = String(args.filePath);
849
+ const symbolName = String(args.symbolName);
850
+ const projectRoot = resolveProjectRoot(args, filePath);
851
+ const direction = args.direction || "both";
852
+ const maxHops = args.maxHops ? Number(args.maxHops) : 3;
853
+ const validator = new SecurityValidator(projectRoot);
854
+ const validation = await validator.validateFilePath(filePath);
855
+ if (!validation.valid)
856
+ throw new Error(validation.error);
857
+ const result = await getCallHierarchy({
858
+ filePath: validation.resolvedPath,
859
+ symbolName,
860
+ direction,
861
+ maxHops,
862
+ projectRoot,
863
+ });
864
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
865
+ }
866
+ // Cross-Language Wire Contract: validate_wire_contract
867
+ export async function handleValidateWireContract(args) {
868
+ if (!args.frontendFile)
869
+ throw new Error("frontendFile is required");
870
+ const frontendFile = String(args.frontendFile);
871
+ const projectRoot = resolveProjectRoot(args, frontendFile);
872
+ const backendFile = args.backendFile ? String(args.backendFile) : undefined;
873
+ const endpoint = args.endpoint ? String(args.endpoint) : undefined;
874
+ const validator = new SecurityValidator(projectRoot);
875
+ const feVal = await validator.validateFilePath(frontendFile);
876
+ if (!feVal.valid)
877
+ throw new Error(feVal.error);
878
+ let bePath = undefined;
879
+ if (backendFile) {
880
+ const beVal = await validator.validateFilePath(backendFile);
881
+ if (!beVal.valid)
882
+ throw new Error(beVal.error);
883
+ bePath = beVal.resolvedPath;
884
+ }
885
+ const result = await validateWireContract({
886
+ frontendFile: feVal.resolvedPath,
887
+ backendFile: bePath,
888
+ endpoint,
889
+ projectRoot,
890
+ });
891
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
892
+ }
893
+ // Semantic Merge Conflict Predictor: predict_semantic_conflicts
894
+ export async function handlePredictSemanticConflicts(args) {
895
+ const projectRoot = resolveProjectRoot(args);
896
+ const baseBranch = args.baseBranch ? String(args.baseBranch) : undefined;
897
+ const targetBranch = args.targetBranch ? String(args.targetBranch) : undefined;
898
+ const result = await predictSemanticConflicts({
899
+ baseBranch,
900
+ targetBranch,
901
+ projectRoot,
902
+ });
903
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
904
+ }
300
905
  //# sourceMappingURL=readHandlers.js.map