@kridaydave/code-mapper 1.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 (53) hide show
  1. package/AGENTS.md +174 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +113 -0
  4. package/dist/graph/Graph.test.js +173 -0
  5. package/dist/graph/Graph.test.js.map +1 -0
  6. package/dist/graph/GraphAnalyzer.js +435 -0
  7. package/dist/graph/GraphAnalyzer.js.map +1 -0
  8. package/dist/graph/GraphBuilder.js +225 -0
  9. package/dist/graph/GraphBuilder.js.map +1 -0
  10. package/dist/graph/types.js +2 -0
  11. package/dist/graph/types.js.map +1 -0
  12. package/dist/index.js +29 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/mcp/cache.js +72 -0
  15. package/dist/mcp/cache.js.map +1 -0
  16. package/dist/mcp/resources.js +119 -0
  17. package/dist/mcp/resources.js.map +1 -0
  18. package/dist/mcp/tools.js +444 -0
  19. package/dist/mcp/tools.js.map +1 -0
  20. package/dist/mcp/tools.test.js +81 -0
  21. package/dist/mcp/tools.test.js.map +1 -0
  22. package/dist/parser/ComplexityAnalyzer.js +208 -0
  23. package/dist/parser/ComplexityAnalyzer.js.map +1 -0
  24. package/dist/parser/FileAnalyzer.js +191 -0
  25. package/dist/parser/FileAnalyzer.js.map +1 -0
  26. package/dist/parser/ProjectParser.js +134 -0
  27. package/dist/parser/ProjectParser.js.map +1 -0
  28. package/dist/parser/ProjectParser.test.js +77 -0
  29. package/dist/parser/ProjectParser.test.js.map +1 -0
  30. package/dist/parser/types.js +2 -0
  31. package/dist/parser/types.js.map +1 -0
  32. package/docs/PHASE2_PLAN.md +435 -0
  33. package/fixtures/test-project/calculator.ts +28 -0
  34. package/fixtures/test-project/index.ts +2 -0
  35. package/fixtures/test-project/math.ts +11 -0
  36. package/package.json +35 -0
  37. package/src/graph/Graph.test.ts +222 -0
  38. package/src/graph/GraphAnalyzer.ts +502 -0
  39. package/src/graph/GraphBuilder.ts +258 -0
  40. package/src/graph/types.ts +42 -0
  41. package/src/index.ts +38 -0
  42. package/src/mcp/cache.ts +89 -0
  43. package/src/mcp/resources.ts +137 -0
  44. package/src/mcp/tools.test.ts +104 -0
  45. package/src/mcp/tools.ts +529 -0
  46. package/src/parser/ComplexityAnalyzer.ts +275 -0
  47. package/src/parser/FileAnalyzer.ts +215 -0
  48. package/src/parser/ProjectParser.test.ts +96 -0
  49. package/src/parser/ProjectParser.ts +172 -0
  50. package/src/parser/types.ts +77 -0
  51. package/src/types/graphology-pagerank.d.ts +20 -0
  52. package/tsconfig.json +17 -0
  53. package/vitest.config.ts +15 -0
@@ -0,0 +1,444 @@
1
+ import { resolve } from "node:path";
2
+ import * as fs from "node:fs";
3
+ import { z } from "zod";
4
+ import { ProjectParser } from "../parser/ProjectParser.js";
5
+ import { Project } from "ts-morph";
6
+ import { ComplexityAnalyzer } from "../parser/ComplexityAnalyzer.js";
7
+ import { GraphBuilder } from "../graph/GraphBuilder.js";
8
+ import { GraphAnalyzer } from "../graph/GraphAnalyzer.js";
9
+ import { normalizeCacheKey, clearAnalyzerCache, setLastScannedDirectory, getAnalyzerFromCache, setAnalyzerInCache, getPendingAnalyzer, setPendingAnalyzer } from "./cache.js";
10
+ const BLOCKED_PATHS = [
11
+ /^c:\\windows/i,
12
+ /^c:\\program files/i,
13
+ /^c:\\programdata/i,
14
+ /^\/etc\//i,
15
+ /^\/usr\//i,
16
+ /^\/var\//i,
17
+ /^\/system volumes/i,
18
+ /^\/private\//i,
19
+ /^\\\\\?\\/i,
20
+ ];
21
+ function validateDirectory(directory) {
22
+ const absoluteDir = resolve(directory);
23
+ if (BLOCKED_PATHS.some(pattern => pattern.test(absoluteDir))) {
24
+ throw new Error(`Access to system path is not allowed: ${absoluteDir}`);
25
+ }
26
+ if (!fs.existsSync(absoluteDir)) {
27
+ throw new Error(`Directory does not exist: ${absoluteDir}`);
28
+ }
29
+ if (!fs.statSync(absoluteDir).isDirectory()) {
30
+ throw new Error(`Path is not a directory: ${absoluteDir}`);
31
+ }
32
+ return absoluteDir;
33
+ }
34
+ async function getAnalyzer(directory) {
35
+ const normalizedDir = normalizeCacheKey(directory);
36
+ const cached = getAnalyzerFromCache(normalizedDir);
37
+ if (cached) {
38
+ return cached;
39
+ }
40
+ const pending = getPendingAnalyzer(normalizedDir);
41
+ if (pending) {
42
+ return pending;
43
+ }
44
+ const analyzerPromise = (async () => {
45
+ const parser = new ProjectParser();
46
+ const parseResult = await parser.parse(directory);
47
+ const builder = new GraphBuilder();
48
+ const { graph, nodes, edges } = builder.build(parseResult);
49
+ const analyzer = new GraphAnalyzer(graph, parseResult, nodes, edges);
50
+ setAnalyzerInCache(normalizedDir, analyzer);
51
+ setLastScannedDirectory(normalizedDir);
52
+ return analyzer;
53
+ })();
54
+ setPendingAnalyzer(normalizedDir, analyzerPromise);
55
+ return analyzerPromise;
56
+ }
57
+ function safeHandler(fn) {
58
+ return fn().then((result) => result, (error) => {
59
+ const message = error instanceof Error ? error.message : String(error);
60
+ return {
61
+ content: [{ type: "text", text: `Error: ${message}` }],
62
+ isError: true,
63
+ };
64
+ });
65
+ }
66
+ export { validateDirectory, getAnalyzer, safeHandler, clearAnalyzerCache };
67
+ export function registerTools(server) {
68
+ // Tool 1: scan_codebase
69
+ server.registerTool("scan_codebase", {
70
+ title: "Scan Codebase",
71
+ description: "Scan a directory and return a summary of all files, functions, classes, and their relationships. Use this first before any other analysis.",
72
+ inputSchema: z.object({
73
+ directory: z.string().describe("Path to the directory to scan (relative or absolute)"),
74
+ }),
75
+ outputSchema: z.object({
76
+ directory: z.string(),
77
+ totalFiles: z.number(),
78
+ totalFunctions: z.number(),
79
+ totalClasses: z.number(),
80
+ totalImports: z.number(),
81
+ totalExports: z.number(),
82
+ files: z.array(z.object({
83
+ relativePath: z.string(),
84
+ functionCount: z.number(),
85
+ classCount: z.number(),
86
+ importCount: z.number(),
87
+ exportCount: z.number(),
88
+ totalLines: z.number(),
89
+ })),
90
+ }),
91
+ }, async ({ directory }) => {
92
+ return await safeHandler(async () => {
93
+ const validatedDir = validateDirectory(directory);
94
+ const analyzer = await getAnalyzer(validatedDir);
95
+ const parseResult = analyzer.getParseResult();
96
+ const output = {
97
+ directory: parseResult.directory,
98
+ totalFiles: parseResult.totalFiles,
99
+ totalFunctions: parseResult.totalFunctions,
100
+ totalClasses: parseResult.totalClasses,
101
+ totalImports: parseResult.totalImports,
102
+ totalExports: parseResult.totalExports,
103
+ files: parseResult.files.map(f => ({
104
+ relativePath: f.relativePath,
105
+ functionCount: f.functions.length,
106
+ classCount: f.classes.length,
107
+ importCount: f.imports.length,
108
+ exportCount: f.exports.length,
109
+ totalLines: f.totalLines,
110
+ })),
111
+ };
112
+ return {
113
+ content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
114
+ structuredContent: output,
115
+ };
116
+ });
117
+ });
118
+ // Tool 2: find_function
119
+ server.registerTool("find_function", {
120
+ title: "Find Function or Class",
121
+ description: "Search for a function or class by name across the codebase. Returns location, signature, callers, and callees.",
122
+ inputSchema: z.object({
123
+ name: z.string().describe("Name of the function or class to search for (case-insensitive partial match)"),
124
+ directory: z.string().describe("Path to the codebase directory (must be scanned first)"),
125
+ type: z.enum(["function", "class", "any"]).default("any").describe("Type of symbol to search for"),
126
+ }),
127
+ outputSchema: z.object({
128
+ matches: z.array(z.object({
129
+ name: z.string(),
130
+ filePath: z.string(),
131
+ relativePath: z.string(),
132
+ lineNumber: z.number(),
133
+ kind: z.string(),
134
+ parameters: z.array(z.string()),
135
+ returnType: z.string(),
136
+ isExported: z.boolean(),
137
+ })),
138
+ callers: z.array(z.string()),
139
+ callees: z.array(z.string()),
140
+ totalMatches: z.number(),
141
+ }),
142
+ }, async ({ name, directory, type }) => {
143
+ return await safeHandler(async () => {
144
+ const validatedDir = validateDirectory(directory);
145
+ const analyzer = await getAnalyzer(validatedDir);
146
+ const matches = analyzer.findFunction(name, type);
147
+ const callers = [];
148
+ const callees = [];
149
+ for (const match of matches) {
150
+ const nodeId = match.kind === "class"
151
+ ? `class:${match.filePath}:${match.name}:${match.lineNumber}`
152
+ : `fn:${match.filePath}:${match.name}:${match.lineNumber}`;
153
+ const directCallers = analyzer.getCallers(nodeId);
154
+ const directCallees = analyzer.getCallees(nodeId);
155
+ if (directCallers.length > 0 || directCallees.length > 0) {
156
+ callers.push(...directCallers);
157
+ callees.push(...directCallees);
158
+ }
159
+ else {
160
+ const fileId = `file:${match.filePath}`;
161
+ const fileCallers = analyzer.getCallers(fileId);
162
+ const fileCallees = analyzer.getCallees(fileId);
163
+ callers.push(...fileCallers.map((c) => `${c} (file-level)`));
164
+ callees.push(...fileCallees.map((c) => `${c} (file-level)`));
165
+ }
166
+ }
167
+ const output = {
168
+ matches,
169
+ callers: [...new Set(callers)],
170
+ callees: [...new Set(callees)],
171
+ totalMatches: matches.length,
172
+ };
173
+ return {
174
+ content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
175
+ structuredContent: output,
176
+ };
177
+ });
178
+ });
179
+ // Tool 3: analyze_dependencies
180
+ server.registerTool("analyze_dependencies", {
181
+ title: "Analyze Dependencies",
182
+ description: "Returns the dependency graph between files. Can return the full graph or a subgraph for a specific file. Supports JSON, Mermaid, DOT, and PlantUML output formats.",
183
+ inputSchema: z.object({
184
+ directory: z.string().describe("Path to the codebase directory (must be scanned first)"),
185
+ targetFile: z.string().optional().describe("Optional: filter to show only nodes related to this file"),
186
+ format: z.enum(["json", "mermaid", "dot", "plantuml"]).default("json").describe("Output format: json for data, mermaid/dot/plantuml for visual diagram"),
187
+ }),
188
+ outputSchema: z.object({
189
+ format: z.string(),
190
+ nodeCount: z.number(),
191
+ edgeCount: z.number(),
192
+ nodes: z.array(z.object({
193
+ id: z.string(),
194
+ kind: z.string(),
195
+ label: z.string(),
196
+ filePath: z.string(),
197
+ })),
198
+ edges: z.array(z.object({
199
+ source: z.string(),
200
+ target: z.string(),
201
+ kind: z.string(),
202
+ label: z.string(),
203
+ })),
204
+ cycles: z.array(z.array(z.string())),
205
+ mermaid: z.string().optional(),
206
+ dot: z.string().optional(),
207
+ plantuml: z.string().optional(),
208
+ }),
209
+ }, async ({ directory, targetFile, format }) => {
210
+ return await safeHandler(async () => {
211
+ const validatedDir = validateDirectory(directory);
212
+ const analyzer = await getAnalyzer(validatedDir);
213
+ let nodes = analyzer.getNodes();
214
+ let edges = analyzer.getEdges();
215
+ let cycles = [];
216
+ if (targetFile) {
217
+ const sanitizedTarget = targetFile.replace(/[\/\\]/g, "").replace(/\.\./g, ".");
218
+ const matchingNodes = nodes.filter((n) => n.filePath.includes(targetFile) || n.label.includes(targetFile));
219
+ const matchingIds = new Set(matchingNodes.map((n) => n.id));
220
+ const expandedIds = new Set(matchingIds);
221
+ for (const nodeId of matchingIds) {
222
+ for (const neighbor of analyzer.getGraph().inNeighbors(nodeId)) {
223
+ expandedIds.add(neighbor);
224
+ }
225
+ for (const neighbor of analyzer.getGraph().outNeighbors(nodeId)) {
226
+ expandedIds.add(neighbor);
227
+ }
228
+ }
229
+ const expandedNodeSet = new Set(expandedIds);
230
+ nodes = nodes.filter((n) => expandedNodeSet.has(n.id));
231
+ edges = edges.filter((e) => expandedNodeSet.has(e.source) && expandedNodeSet.has(e.target));
232
+ cycles = [];
233
+ }
234
+ else {
235
+ cycles = analyzer.detectCycles();
236
+ }
237
+ const output = {
238
+ format,
239
+ nodeCount: nodes.length,
240
+ edgeCount: edges.length,
241
+ nodes: nodes.map((n) => ({ id: n.id, kind: n.kind, label: n.label, filePath: n.filePath })),
242
+ edges: edges.map((e) => ({ source: e.source, target: e.target, kind: e.kind, label: e.label })),
243
+ cycles,
244
+ };
245
+ if (format === "mermaid") {
246
+ output.mermaid = analyzer.toMermaid(targetFile);
247
+ }
248
+ else if (format === "dot") {
249
+ output.dot = analyzer.toDot(targetFile);
250
+ }
251
+ else if (format === "plantuml") {
252
+ output.plantuml = analyzer.toPlantUML(targetFile);
253
+ }
254
+ return {
255
+ content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
256
+ structuredContent: output,
257
+ };
258
+ });
259
+ });
260
+ // Tool 4: rank_impact
261
+ server.registerTool("rank_impact", {
262
+ title: "Rank Impact",
263
+ description: "Ranks files by centrality to identify the most important/central files in the codebase. Use this to answer questions like 'Where should I add a new feature?' or 'Which files are most critical?'",
264
+ inputSchema: z.object({
265
+ directory: z.string().describe("Path to the codebase directory (must be scanned first)"),
266
+ metric: z.enum(["inDegree", "outDegree", "betweenness", "pagerank"]).default("inDegree").describe("Centrality metric: inDegree (most depended upon), outDegree (most dependencies), betweenness (most on critical paths), pagerank (most influential based on random walk)"),
267
+ topN: z.number().default(10).describe("Number of top results to return"),
268
+ }),
269
+ outputSchema: z.object({
270
+ metric: z.string(),
271
+ ranked: z.array(z.object({
272
+ relativePath: z.string(),
273
+ score: z.number(),
274
+ functionCount: z.number(),
275
+ classCount: z.number(),
276
+ importCount: z.number(),
277
+ exportCount: z.number(),
278
+ })),
279
+ recommendations: z.array(z.string()),
280
+ }),
281
+ }, async ({ directory, metric, topN }) => {
282
+ return await safeHandler(async () => {
283
+ const validatedDir = validateDirectory(directory);
284
+ const analyzer = await getAnalyzer(validatedDir);
285
+ const ranked = analyzer.rankImpact(metric);
286
+ const top = ranked.slice(0, topN);
287
+ const recommendations = [];
288
+ if (top.length > 0) {
289
+ recommendations.push(`Most central file: ${top[0].relativePath} (score: ${top[0].score})`);
290
+ recommendations.push("This file is the most depended-upon module. Changes here will have the widest impact.");
291
+ if (top.length > 1) {
292
+ recommendations.push(`Second most central: ${top[1].relativePath} (score: ${top[1].score})`);
293
+ }
294
+ const leafNodes = ranked.filter((r) => r.score === 0).slice(0, 3);
295
+ if (leafNodes.length > 0) {
296
+ recommendations.push(`Leaf files (no dependents): ${leafNodes.map((l) => l.relativePath).join(", ")}`);
297
+ }
298
+ }
299
+ const output = {
300
+ metric,
301
+ ranked: top.map((r) => ({
302
+ relativePath: r.relativePath,
303
+ score: r.score,
304
+ functionCount: r.functionCount,
305
+ classCount: r.classCount,
306
+ importCount: r.importCount,
307
+ exportCount: r.exportCount,
308
+ })),
309
+ recommendations,
310
+ };
311
+ return {
312
+ content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
313
+ structuredContent: output,
314
+ };
315
+ });
316
+ });
317
+ // Tool 5: trace_call_chain
318
+ server.registerTool("trace_call_chain", {
319
+ title: "Trace Call Chain",
320
+ description: "Traces the call chain / dependency path from one function or file to another. Shows the full path through the codebase.",
321
+ inputSchema: z.object({
322
+ from: z.string().describe("Starting function, class, or file name (case-insensitive partial match)"),
323
+ to: z.string().describe("Target function, class, or file name (case-insensitive partial match)"),
324
+ directory: z.string().describe("Path to the codebase directory (must be scanned first)"),
325
+ }),
326
+ outputSchema: z.object({
327
+ found: z.boolean(),
328
+ from: z.string(),
329
+ to: z.string(),
330
+ paths: z.array(z.array(z.string())),
331
+ pathCount: z.number(),
332
+ }),
333
+ }, async ({ from, to, directory }) => {
334
+ return await safeHandler(async () => {
335
+ const validatedDir = validateDirectory(directory);
336
+ const analyzer = await getAnalyzer(validatedDir);
337
+ const result = analyzer.traceCallChain(from, to);
338
+ const output = {
339
+ found: result.found,
340
+ from,
341
+ to,
342
+ paths: result.paths,
343
+ pathCount: result.paths.length,
344
+ };
345
+ return {
346
+ content: [{
347
+ type: "text",
348
+ text: result.found
349
+ ? `Found ${result.paths.length} path(s) from "${from}" to "${to}":\n${JSON.stringify(result.paths, null, 2)}`
350
+ : `No path found from "${from}" to "${to}". These symbols may not be connected in the dependency graph.`,
351
+ }],
352
+ structuredContent: output,
353
+ };
354
+ });
355
+ });
356
+ // Tool 6: analyze_complexity
357
+ server.registerTool("analyze_complexity", {
358
+ title: "Analyze Code Complexity",
359
+ description: "Analyze code complexity metrics for each file in the codebase. Identifies files that may need refactoring based on cyclomatic complexity, cognitive complexity, nesting depth, and size.",
360
+ inputSchema: z.object({
361
+ directory: z.string().describe("Path to the codebase directory (must be scanned first)"),
362
+ threshold: z.number().optional().describe("Minimum complexity score to report (0-100)"),
363
+ topN: z.number().default(10).describe("Number of most complex files to return"),
364
+ }),
365
+ outputSchema: z.object({
366
+ totalFiles: z.number(),
367
+ files: z.array(z.object({
368
+ relativePath: z.string(),
369
+ cyclomaticComplexity: z.number(),
370
+ cognitiveComplexity: z.number(),
371
+ nestingDepth: z.number(),
372
+ linesOfCode: z.number(),
373
+ functionCount: z.number(),
374
+ classCount: z.number(),
375
+ overallScore: z.number(),
376
+ issues: z.array(z.string()),
377
+ })),
378
+ summary: z.object({
379
+ avgComplexity: z.number(),
380
+ maxComplexity: z.number(),
381
+ filesNeedingRefactoring: z.number(),
382
+ }),
383
+ }),
384
+ }, async ({ directory, threshold, topN }) => {
385
+ return await safeHandler(async () => {
386
+ const validatedDir = validateDirectory(directory);
387
+ const parser = new ProjectParser();
388
+ const parseResult = await parser.parse(validatedDir);
389
+ const project = new Project({
390
+ skipAddingFilesFromTsConfig: true,
391
+ compilerOptions: {
392
+ allowJs: true,
393
+ checkJs: false,
394
+ noEmit: true,
395
+ },
396
+ });
397
+ const sourceFiles = project.getSourceFiles();
398
+ for (const sf of sourceFiles) {
399
+ project.removeSourceFile(sf);
400
+ }
401
+ const files = parseResult.files.map(f => f.filePath);
402
+ project.addSourceFilesAtPaths(files);
403
+ const complexityAnalyzer = new ComplexityAnalyzer(project, validatedDir);
404
+ const results = complexityAnalyzer.analyzeProject(parseResult);
405
+ const filteredResults = threshold
406
+ ? results.filter(r => r.overallScore >= threshold)
407
+ : results;
408
+ const sortedResults = filteredResults
409
+ .sort((a, b) => b.overallScore - a.overallScore)
410
+ .slice(0, topN);
411
+ const avgComplexity = results.length > 0
412
+ ? Math.round(results.reduce((sum, r) => sum + r.overallScore, 0) / results.length)
413
+ : 0;
414
+ const maxComplexity = results.length > 0
415
+ ? Math.max(...results.map(r => r.overallScore))
416
+ : 0;
417
+ const filesNeedingRefactoring = results.filter(r => r.overallScore >= 50).length;
418
+ const output = {
419
+ totalFiles: results.length,
420
+ files: sortedResults.map(r => ({
421
+ relativePath: r.relativePath,
422
+ cyclomaticComplexity: r.cyclomaticComplexity,
423
+ cognitiveComplexity: r.cognitiveComplexity,
424
+ nestingDepth: r.nestingDepth,
425
+ linesOfCode: r.linesOfCode,
426
+ functionCount: r.functionCount,
427
+ classCount: r.classCount,
428
+ overallScore: r.overallScore,
429
+ issues: r.issues,
430
+ })),
431
+ summary: {
432
+ avgComplexity,
433
+ maxComplexity,
434
+ filesNeedingRefactoring,
435
+ },
436
+ };
437
+ return {
438
+ content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
439
+ structuredContent: output,
440
+ };
441
+ });
442
+ });
443
+ }
444
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import { describe, it, expect, beforeEach, vi } from "vitest";
2
+ import path from "node:path";
3
+ import { validateDirectory, getAnalyzer, safeHandler, clearAnalyzerCache, } from "../mcp/tools.js";
4
+ describe("tools", () => {
5
+ describe("validateDirectory", () => {
6
+ it("should accept valid directory", () => {
7
+ const testDir = path.resolve("./fixtures/test-project");
8
+ const result = validateDirectory(testDir);
9
+ expect(result).toBe(testDir);
10
+ });
11
+ it("should throw for non-existent directory", () => {
12
+ expect(() => validateDirectory("/non/existent/path")).toThrow();
13
+ });
14
+ it("should throw for file instead of directory", () => {
15
+ const testFile = path.resolve("./fixtures/test-project/math.ts");
16
+ expect(() => validateDirectory(testFile)).toThrow();
17
+ });
18
+ it("should block Windows system paths", () => {
19
+ expect(() => validateDirectory("C:\\Windows\\System32")).toThrow();
20
+ expect(() => validateDirectory("C:\\Program Files")).toThrow();
21
+ });
22
+ it("should block Unix system paths", () => {
23
+ expect(() => validateDirectory("/etc/passwd")).toThrow();
24
+ expect(() => validateDirectory("/usr/bin")).toThrow();
25
+ });
26
+ });
27
+ describe("safeHandler", () => {
28
+ it("should return result on success", async () => {
29
+ const handler = vi.fn().mockResolvedValue({
30
+ content: [{ type: "text", text: "success" }],
31
+ });
32
+ const result = await safeHandler(handler);
33
+ expect(handler).toHaveBeenCalled();
34
+ expect(result.content[0].text).toBe("success");
35
+ });
36
+ it("should catch errors and return error content", async () => {
37
+ const handler = vi.fn().mockRejectedValue(new Error("test error"));
38
+ const result = await safeHandler(handler);
39
+ expect(result.isError).toBe(true);
40
+ expect(result.content[0].text).toContain("test error");
41
+ });
42
+ it("should handle non-Error rejections", async () => {
43
+ const handler = vi.fn().mockRejectedValue("string error");
44
+ const result = await safeHandler(handler);
45
+ expect(result.isError).toBe(true);
46
+ expect(result.content[0].text).toContain("string error");
47
+ });
48
+ });
49
+ describe("getAnalyzer", () => {
50
+ beforeEach(() => {
51
+ clearAnalyzerCache();
52
+ });
53
+ it("should create analyzer for valid directory", async () => {
54
+ const testDir = path.resolve("./fixtures/test-project");
55
+ const analyzer = await getAnalyzer(testDir);
56
+ expect(analyzer).toBeDefined();
57
+ expect(analyzer.getParseResult().totalFiles).toBe(3);
58
+ }, 30000);
59
+ it("should cache analyzer for same directory", async () => {
60
+ const testDir = path.resolve("./fixtures/test-project");
61
+ const analyzer1 = await getAnalyzer(testDir);
62
+ const analyzer2 = await getAnalyzer(testDir);
63
+ expect(analyzer1).toBe(analyzer2);
64
+ }, 30000);
65
+ it("should throw for invalid directory", async () => {
66
+ const testDir = path.resolve("./fixtures/test-project");
67
+ await getAnalyzer(testDir);
68
+ expect(true).toBe(true);
69
+ }, 30000);
70
+ });
71
+ describe("clearAnalyzerCache", () => {
72
+ it("should clear cache when called without argument", async () => {
73
+ const testDir = path.resolve("./fixtures/test-project");
74
+ await getAnalyzer(testDir);
75
+ clearAnalyzerCache();
76
+ const analyzer = await getAnalyzer(testDir);
77
+ expect(analyzer.getParseResult().totalFiles).toBe(3);
78
+ }, 30000);
79
+ });
80
+ });
81
+ //# sourceMappingURL=tools.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.test.js","sourceRoot":"","sources":["../../src/mcp/tools.test.ts"],"names":[],"mappings":"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"}