codemap-ai 0.1.2 → 3.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.
@@ -1,129 +1,92 @@
1
1
  import {
2
- GraphStorage
3
- } from "./chunk-FLUWKIEM.js";
2
+ FlowStorage
3
+ } from "./chunk-GX7ZMBC2.js";
4
4
 
5
- // src/mcp/server.ts
5
+ // src/mcp/flow-server.ts
6
6
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
7
7
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
8
  import {
9
9
  CallToolRequestSchema,
10
- ListToolsRequestSchema,
11
- ListResourcesRequestSchema,
12
- ReadResourceRequestSchema
10
+ ListToolsRequestSchema
13
11
  } from "@modelcontextprotocol/sdk/types.js";
14
12
  import { resolve } from "path";
13
+ import { existsSync } from "fs";
15
14
  var DB_PATH = process.env.CODEMAP_DB_PATH || ".codemap/graph.db";
16
15
  var PROJECT_ROOT = process.env.CODEMAP_PROJECT_ROOT || process.cwd();
17
16
  var storage = null;
18
17
  function getStorage() {
19
18
  if (!storage) {
20
19
  const dbPath = resolve(PROJECT_ROOT, DB_PATH);
21
- storage = new GraphStorage(dbPath);
20
+ if (!existsSync(dbPath)) {
21
+ throw new Error(`CodeMap database not found at ${dbPath}. Run 'codemap index' first.`);
22
+ }
23
+ storage = new FlowStorage(dbPath);
22
24
  }
23
25
  return storage;
24
26
  }
25
27
  var server = new Server(
26
28
  {
27
- name: "codemap",
28
- version: "0.1.0"
29
+ name: "codemap-flow",
30
+ version: "3.0.0"
29
31
  },
30
32
  {
31
33
  capabilities: {
32
- tools: {},
33
- resources: {}
34
+ tools: {}
34
35
  }
35
36
  }
36
37
  );
37
38
  server.setRequestHandler(ListToolsRequestSchema, async () => {
38
39
  return {
39
40
  tools: [
40
- {
41
- name: "codemap_search",
42
- description: "Search for functions, classes, or files in the codebase",
43
- inputSchema: {
44
- type: "object",
45
- properties: {
46
- query: {
47
- type: "string",
48
- description: "Search query (function name, class name, or file pattern)"
49
- },
50
- type: {
51
- type: "string",
52
- enum: ["function", "class", "method", "file", "all"],
53
- description: "Type of entity to search for",
54
- default: "all"
55
- }
56
- },
57
- required: ["query"]
58
- }
59
- },
60
- {
61
- name: "codemap_callers",
62
- description: "Find all functions/methods that call a specific function",
63
- inputSchema: {
64
- type: "object",
65
- properties: {
66
- functionName: {
67
- type: "string",
68
- description: "Name of the function to find callers for"
69
- }
70
- },
71
- required: ["functionName"]
72
- }
73
- },
74
- {
75
- name: "codemap_dependencies",
76
- description: "Get import/dependency information for a file",
77
- inputSchema: {
78
- type: "object",
79
- properties: {
80
- filePath: {
81
- type: "string",
82
- description: "Path to the file (relative or absolute)"
83
- }
84
- },
85
- required: ["filePath"]
86
- }
87
- },
88
41
  {
89
42
  name: "codemap_impact",
90
- description: "Analyze what files would be affected by changes to a file or function",
43
+ description: "Analyze what would break if you change a function/class. Shows all callers and affected files with risk assessment.",
91
44
  inputSchema: {
92
45
  type: "object",
93
46
  properties: {
94
47
  target: {
95
48
  type: "string",
96
- description: "File path or function name to analyze"
49
+ description: "Function or class name to analyze"
97
50
  },
98
51
  depth: {
99
52
  type: "number",
100
- description: "How many levels of dependencies to follow (default: 2)",
101
- default: 2
53
+ description: "How many levels deep to analyze (default: 3)",
54
+ default: 3
102
55
  }
103
56
  },
104
57
  required: ["target"]
105
58
  }
106
59
  },
107
60
  {
108
- name: "codemap_stats",
109
- description: "Get statistics about the codebase",
61
+ name: "codemap_trace_flow",
62
+ description: "Trace the execution flow between two functions. Shows the complete call path from source to target.",
110
63
  inputSchema: {
111
64
  type: "object",
112
- properties: {}
65
+ properties: {
66
+ from: {
67
+ type: "string",
68
+ description: "Starting function name"
69
+ },
70
+ to: {
71
+ type: "string",
72
+ description: "Target function name"
73
+ }
74
+ },
75
+ required: ["from", "to"]
113
76
  }
114
77
  },
115
78
  {
116
- name: "codemap_file_contents",
117
- description: "Get all functions and classes defined in a file",
79
+ name: "codemap_callers",
80
+ description: "Find all functions that call a specific function. Shows where and how a function is used.",
118
81
  inputSchema: {
119
82
  type: "object",
120
83
  properties: {
121
- filePath: {
84
+ function: {
122
85
  type: "string",
123
- description: "Path to the file"
86
+ description: "Function name to find callers for"
124
87
  }
125
88
  },
126
- required: ["filePath"]
89
+ required: ["function"]
127
90
  }
128
91
  }
129
92
  ]
@@ -134,161 +97,129 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
134
97
  const db = getStorage();
135
98
  try {
136
99
  switch (name) {
137
- case "codemap_search": {
138
- const query = args?.query;
139
- const type = args?.type || "all";
140
- let nodes = db.searchNodes(query);
141
- if (type !== "all") {
142
- nodes = nodes.filter((n) => n.type === type);
100
+ case "codemap_impact": {
101
+ const target = args?.target;
102
+ const depth = args?.depth || 3;
103
+ const nodes = db.searchNodesByName(target);
104
+ if (nodes.length === 0) {
105
+ return {
106
+ content: [
107
+ {
108
+ type: "text",
109
+ text: `No function or class found with name "${target}"`
110
+ }
111
+ ]
112
+ };
143
113
  }
144
- const results = nodes.slice(0, 20).map((n) => ({
145
- name: n.name,
146
- type: n.type,
147
- file: n.filePath,
148
- line: n.startLine,
149
- language: n.language
150
- }));
151
- return {
152
- content: [
153
- {
154
- type: "text",
155
- text: JSON.stringify(results, null, 2)
156
- }
157
- ]
158
- };
159
- }
160
- case "codemap_callers": {
161
- const functionName = args?.functionName;
162
- const callers = db.getCallers(functionName);
163
- const results = callers.map((n) => ({
164
- name: n.name,
165
- type: n.type,
166
- file: n.filePath,
167
- line: n.startLine
168
- }));
114
+ const targetNode = nodes[0];
115
+ const impacted = db.getImpactedNodes(targetNode.id, depth);
116
+ const affectedFiles = new Set(impacted.map((n) => n.filePath));
117
+ const directCallers = db.getResolvedCallers(targetNode.id);
118
+ let risk = "LOW";
119
+ if (directCallers.length > 10) risk = "HIGH";
120
+ else if (directCallers.length > 5) risk = "MEDIUM";
121
+ const response = `# Impact Analysis: ${targetNode.name}
122
+
123
+ **Location:** ${targetNode.filePath}:${targetNode.startLine}
124
+ **Type:** ${targetNode.type}
125
+ **Risk Level:** ${risk}
126
+
127
+ ## Direct Callers (${directCallers.length})
128
+ ${directCallers.slice(0, 10).map((c) => `- ${c.name} in ${c.filePath}:${c.startLine}`).join("\n")}
129
+ ${directCallers.length > 10 ? `
130
+ ... and ${directCallers.length - 10} more` : ""}
131
+
132
+ ## Total Impact
133
+ - **Affected functions:** ${impacted.length}
134
+ - **Affected files:** ${affectedFiles.size}
135
+
136
+ ## Affected Files
137
+ ${[...affectedFiles].slice(0, 20).map((f) => `- ${f}`).join("\n")}
138
+ ${affectedFiles.size > 20 ? `
139
+ ... and ${affectedFiles.size - 20} more` : ""}
140
+
141
+ \u26A0\uFE0F **Recommendation:** ${risk === "HIGH" ? "High-risk change. Review all callers before modifying." : risk === "MEDIUM" ? "Moderate risk. Test affected files after changes." : "Low risk. Changes unlikely to cause wide impact."}
142
+ `;
169
143
  return {
170
- content: [
171
- {
172
- type: "text",
173
- text: `Found ${results.length} callers of "${functionName}":
174
- ${JSON.stringify(results, null, 2)}`
175
- }
176
- ]
144
+ content: [{ type: "text", text: response }]
177
145
  };
178
146
  }
179
- case "codemap_dependencies": {
180
- const filePath = args?.filePath;
181
- const deps = db.getFileDependencies(filePath);
182
- return {
183
- content: [
184
- {
185
- type: "text",
186
- text: `Dependencies for ${filePath}:
147
+ case "codemap_trace_flow": {
148
+ const from = args?.from;
149
+ const to = args?.to;
150
+ const sourceNodes = db.searchNodesByName(from);
151
+ const targetNodes = db.searchNodesByName(to);
152
+ if (sourceNodes.length === 0) {
153
+ return {
154
+ content: [{ type: "text", text: `Source function "${from}" not found` }]
155
+ };
156
+ }
157
+ if (targetNodes.length === 0) {
158
+ return {
159
+ content: [{ type: "text", text: `Target function "${to}" not found` }]
160
+ };
161
+ }
162
+ const sourceNode = sourceNodes[0];
163
+ const targetNode = targetNodes[0];
164
+ const path = db.traceCallPath(sourceNode.id, targetNode.id);
165
+ if (!path) {
166
+ return {
167
+ content: [
168
+ {
169
+ type: "text",
170
+ text: `No call path found from "${from}" to "${to}". They may not be connected.`
171
+ }
172
+ ]
173
+ };
174
+ }
175
+ const response = `# Execution Flow: ${from} \u2192 ${to}
187
176
 
188
- Imports:
189
- ${deps.imports.map((i) => ` - ${i}`).join("\n")}
177
+ ${path.nodes.map(
178
+ (n, i) => `${i + 1}. **${n.name}**
179
+ File: ${n.file}:${n.line}${i < path.nodes.length - 1 ? "\n \u2193 calls" : ""}`
180
+ ).join("\n\n")}
190
181
 
191
- Imported by:
192
- ${deps.importedBy.map((i) => ` - ${i}`).join("\n")}`
193
- }
194
- ]
182
+ **Total steps:** ${path.nodes.length}
183
+ `;
184
+ return {
185
+ content: [{ type: "text", text: response }]
195
186
  };
196
187
  }
197
- case "codemap_impact": {
198
- const target = args?.target;
199
- const depth = args?.depth || 2;
200
- const nodes = db.searchNodes(target);
188
+ case "codemap_callers": {
189
+ const functionName = args?.function;
190
+ const nodes = db.searchNodesByName(functionName);
201
191
  if (nodes.length === 0) {
202
192
  return {
203
- content: [{ type: "text", text: `No matches found for "${target}"` }]
193
+ content: [{ type: "text", text: `Function "${functionName}" not found` }]
204
194
  };
205
195
  }
206
196
  const targetNode = nodes[0];
207
- const affected = /* @__PURE__ */ new Set();
208
- const queue = [{ id: targetNode.id, depth: 0 }];
209
- const visited = /* @__PURE__ */ new Set();
210
- while (queue.length > 0) {
211
- const current = queue.shift();
212
- if (visited.has(current.id) || current.depth > depth) continue;
213
- visited.add(current.id);
214
- const incomingEdges = db.getEdgesTo(current.id);
215
- for (const edge of incomingEdges) {
216
- const sourceNode = db.getNode(edge.sourceId);
217
- if (sourceNode) {
218
- affected.add(sourceNode.filePath);
219
- if (current.depth < depth) {
220
- queue.push({ id: sourceNode.id, depth: current.depth + 1 });
197
+ const callers = db.getResolvedCallers(targetNode.id);
198
+ if (callers.length === 0) {
199
+ return {
200
+ content: [
201
+ {
202
+ type: "text",
203
+ text: `No callers found for "${functionName}". It may be unused or only called externally.`
221
204
  }
222
- }
223
- }
224
- if (targetNode.type === "file" || targetNode.type === "function") {
225
- const importers = db.getFilesThatImport(targetNode.filePath);
226
- for (const importer of importers) {
227
- affected.add(importer);
228
- }
229
- }
205
+ ]
206
+ };
230
207
  }
231
- const affectedList = [...affected].filter((f) => f !== targetNode.filePath);
232
- return {
233
- content: [
234
- {
235
- type: "text",
236
- text: `Impact analysis for "${target}":
237
-
238
- Target: ${targetNode.name} (${targetNode.type}) in ${targetNode.filePath}
239
-
240
- Affected files (${affectedList.length}):
241
- ${affectedList.map((f) => ` - ${f}`).join("\n") || " (none found)"}`
242
- }
243
- ]
244
- };
245
- }
246
- case "codemap_stats": {
247
- const stats = db.getStats();
248
- const rootPath = db.getMeta("rootPath") || "unknown";
249
- const analyzedAt = db.getMeta("analyzedAt") || "unknown";
250
- return {
251
- content: [
252
- {
253
- type: "text",
254
- text: `CodeMap Statistics:
255
-
256
- Project: ${rootPath}
257
- Last analyzed: ${analyzedAt}
258
-
259
- Files: ${stats.totalFiles}
260
- Nodes: ${stats.totalNodes}
261
- Edges: ${stats.totalEdges}
208
+ const response = `# Callers of ${functionName}
262
209
 
263
- By type:
264
- ${Object.entries(stats.nodesByType).map(([t, c]) => ` - ${t}: ${c}`).join("\n")}
210
+ **Function:** ${targetNode.name} (${targetNode.type})
211
+ **Location:** ${targetNode.filePath}:${targetNode.startLine}
212
+ **Total callers:** ${callers.length}
265
213
 
266
- By language:
267
- ${Object.entries(stats.languages).map(([l, c]) => ` - ${l}: ${c}`).join("\n")}
214
+ ## Who Calls This Function
268
215
 
269
- Relationships:
270
- ${Object.entries(stats.edgesByType).map(([t, c]) => ` - ${t}: ${c}`).join("\n")}`
271
- }
272
- ]
273
- };
274
- }
275
- case "codemap_file_contents": {
276
- const filePath = args?.filePath;
277
- const nodes = db.getNodesByFile(filePath);
278
- const contents = nodes.filter((n) => n.type !== "file").map((n) => ({
279
- name: n.name,
280
- type: n.type,
281
- line: `${n.startLine}-${n.endLine}`,
282
- metadata: n.metadata
283
- }));
216
+ ${callers.map(
217
+ (c) => `- **${c.name}** (${c.type})
218
+ File: ${c.filePath}:${c.startLine}`
219
+ ).join("\n\n")}
220
+ `;
284
221
  return {
285
- content: [
286
- {
287
- type: "text",
288
- text: `Contents of ${filePath}:
289
- ${JSON.stringify(contents, null, 2)}`
290
- }
291
- ]
222
+ content: [{ type: "text", text: response }]
292
223
  };
293
224
  }
294
225
  default:
@@ -298,68 +229,16 @@ ${JSON.stringify(contents, null, 2)}`
298
229
  };
299
230
  }
300
231
  } catch (error) {
232
+ const errorMessage = error instanceof Error ? error.message : String(error);
301
233
  return {
302
- content: [
303
- {
304
- type: "text",
305
- text: `Error: ${error instanceof Error ? error.message : String(error)}`
306
- }
307
- ],
234
+ content: [{ type: "text", text: `Error: ${errorMessage}` }],
308
235
  isError: true
309
236
  };
310
237
  }
311
238
  });
312
- server.setRequestHandler(ListResourcesRequestSchema, async () => {
313
- return {
314
- resources: [
315
- {
316
- uri: "codemap://stats",
317
- name: "Codebase Statistics",
318
- description: "Overview statistics of the analyzed codebase",
319
- mimeType: "application/json"
320
- },
321
- {
322
- uri: "codemap://graph",
323
- name: "Dependency Graph",
324
- description: "Full dependency graph for visualization",
325
- mimeType: "application/json"
326
- }
327
- ]
328
- };
239
+ var transport = new StdioServerTransport();
240
+ server.connect(transport).catch((error) => {
241
+ console.error("Failed to start MCP server:", error);
242
+ process.exit(1);
329
243
  });
330
- server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
331
- const { uri } = request.params;
332
- const db = getStorage();
333
- if (uri === "codemap://stats") {
334
- const stats = db.getStats();
335
- return {
336
- contents: [
337
- {
338
- uri,
339
- mimeType: "application/json",
340
- text: JSON.stringify(stats, null, 2)
341
- }
342
- ]
343
- };
344
- }
345
- if (uri === "codemap://graph") {
346
- const graph = db.exportForVisualization();
347
- return {
348
- contents: [
349
- {
350
- uri,
351
- mimeType: "application/json",
352
- text: JSON.stringify(graph, null, 2)
353
- }
354
- ]
355
- };
356
- }
357
- throw new Error(`Unknown resource: ${uri}`);
358
- });
359
- async function main() {
360
- const transport = new StdioServerTransport();
361
- await server.connect(transport);
362
- console.error("CodeMap MCP server started");
363
- }
364
- main().catch(console.error);
365
244
  //# sourceMappingURL=mcp-server.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mcp/server.ts"],"sourcesContent":["/**\n * MCP Server for CodeMap - Integrates with Claude Code\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n ListResourcesRequestSchema,\n ReadResourceRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { GraphStorage } from \"../graph/storage.js\";\nimport { resolve } from \"path\";\n\n// Get config from environment\nconst DB_PATH = process.env.CODEMAP_DB_PATH || \".codemap/graph.db\";\nconst PROJECT_ROOT = process.env.CODEMAP_PROJECT_ROOT || process.cwd();\n\nlet storage: GraphStorage | null = null;\n\nfunction getStorage(): GraphStorage {\n if (!storage) {\n const dbPath = resolve(PROJECT_ROOT, DB_PATH);\n storage = new GraphStorage(dbPath);\n }\n return storage;\n}\n\nconst server = new Server(\n {\n name: \"codemap\",\n version: \"0.1.0\",\n },\n {\n capabilities: {\n tools: {},\n resources: {},\n },\n }\n);\n\n// ============ Tools ============\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: \"codemap_search\",\n description: \"Search for functions, classes, or files in the codebase\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description: \"Search query (function name, class name, or file pattern)\",\n },\n type: {\n type: \"string\",\n enum: [\"function\", \"class\", \"method\", \"file\", \"all\"],\n description: \"Type of entity to search for\",\n default: \"all\",\n },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"codemap_callers\",\n description: \"Find all functions/methods that call a specific function\",\n inputSchema: {\n type: \"object\",\n properties: {\n functionName: {\n type: \"string\",\n description: \"Name of the function to find callers for\",\n },\n },\n required: [\"functionName\"],\n },\n },\n {\n name: \"codemap_dependencies\",\n description: \"Get import/dependency information for a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n filePath: {\n type: \"string\",\n description: \"Path to the file (relative or absolute)\",\n },\n },\n required: [\"filePath\"],\n },\n },\n {\n name: \"codemap_impact\",\n description: \"Analyze what files would be affected by changes to a file or function\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: {\n type: \"string\",\n description: \"File path or function name to analyze\",\n },\n depth: {\n type: \"number\",\n description: \"How many levels of dependencies to follow (default: 2)\",\n default: 2,\n },\n },\n required: [\"target\"],\n },\n },\n {\n name: \"codemap_stats\",\n description: \"Get statistics about the codebase\",\n inputSchema: {\n type: \"object\",\n properties: {},\n },\n },\n {\n name: \"codemap_file_contents\",\n description: \"Get all functions and classes defined in a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n filePath: {\n type: \"string\",\n description: \"Path to the file\",\n },\n },\n required: [\"filePath\"],\n },\n },\n ],\n };\n});\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n const db = getStorage();\n\n try {\n switch (name) {\n case \"codemap_search\": {\n const query = args?.query as string;\n const type = (args?.type as string) || \"all\";\n\n let nodes = db.searchNodes(query);\n if (type !== \"all\") {\n nodes = nodes.filter((n) => n.type === type);\n }\n\n const results = nodes.slice(0, 20).map((n) => ({\n name: n.name,\n type: n.type,\n file: n.filePath,\n line: n.startLine,\n language: n.language,\n }));\n\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(results, null, 2),\n },\n ],\n };\n }\n\n case \"codemap_callers\": {\n const functionName = args?.functionName as string;\n const callers = db.getCallers(functionName);\n\n const results = callers.map((n) => ({\n name: n.name,\n type: n.type,\n file: n.filePath,\n line: n.startLine,\n }));\n\n return {\n content: [\n {\n type: \"text\",\n text: `Found ${results.length} callers of \"${functionName}\":\\n${JSON.stringify(results, null, 2)}`,\n },\n ],\n };\n }\n\n case \"codemap_dependencies\": {\n const filePath = args?.filePath as string;\n const deps = db.getFileDependencies(filePath);\n\n return {\n content: [\n {\n type: \"text\",\n text: `Dependencies for ${filePath}:\\n\\nImports:\\n${deps.imports.map((i) => ` - ${i}`).join(\"\\n\")}\\n\\nImported by:\\n${deps.importedBy.map((i) => ` - ${i}`).join(\"\\n\")}`,\n },\n ],\n };\n }\n\n case \"codemap_impact\": {\n const target = args?.target as string;\n const depth = (args?.depth as number) || 2;\n\n // Find the target\n const nodes = db.searchNodes(target);\n if (nodes.length === 0) {\n return {\n content: [{ type: \"text\", text: `No matches found for \"${target}\"` }],\n };\n }\n\n const targetNode = nodes[0];\n const affected: Set<string> = new Set();\n\n // BFS to find affected files\n const queue: Array<{ id: string; depth: number }> = [{ id: targetNode.id, depth: 0 }];\n const visited = new Set<string>();\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (visited.has(current.id) || current.depth > depth) continue;\n visited.add(current.id);\n\n // Find edges pointing to this node\n const incomingEdges = db.getEdgesTo(current.id);\n for (const edge of incomingEdges) {\n const sourceNode = db.getNode(edge.sourceId);\n if (sourceNode) {\n affected.add(sourceNode.filePath);\n if (current.depth < depth) {\n queue.push({ id: sourceNode.id, depth: current.depth + 1 });\n }\n }\n }\n\n // Also check file-level dependencies\n if (targetNode.type === \"file\" || targetNode.type === \"function\") {\n const importers = db.getFilesThatImport(targetNode.filePath);\n for (const importer of importers) {\n affected.add(importer);\n }\n }\n }\n\n const affectedList = [...affected].filter((f) => f !== targetNode.filePath);\n\n return {\n content: [\n {\n type: \"text\",\n text: `Impact analysis for \"${target}\":\\n\\nTarget: ${targetNode.name} (${targetNode.type}) in ${targetNode.filePath}\\n\\nAffected files (${affectedList.length}):\\n${affectedList.map((f) => ` - ${f}`).join(\"\\n\") || \" (none found)\"}`,\n },\n ],\n };\n }\n\n case \"codemap_stats\": {\n const stats = db.getStats();\n const rootPath = db.getMeta(\"rootPath\") || \"unknown\";\n const analyzedAt = db.getMeta(\"analyzedAt\") || \"unknown\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `CodeMap Statistics:\n\nProject: ${rootPath}\nLast analyzed: ${analyzedAt}\n\nFiles: ${stats.totalFiles}\nNodes: ${stats.totalNodes}\nEdges: ${stats.totalEdges}\n\nBy type:\n${Object.entries(stats.nodesByType).map(([t, c]) => ` - ${t}: ${c}`).join(\"\\n\")}\n\nBy language:\n${Object.entries(stats.languages).map(([l, c]) => ` - ${l}: ${c}`).join(\"\\n\")}\n\nRelationships:\n${Object.entries(stats.edgesByType).map(([t, c]) => ` - ${t}: ${c}`).join(\"\\n\")}`,\n },\n ],\n };\n }\n\n case \"codemap_file_contents\": {\n const filePath = args?.filePath as string;\n const nodes = db.getNodesByFile(filePath);\n\n const contents = nodes\n .filter((n) => n.type !== \"file\")\n .map((n) => ({\n name: n.name,\n type: n.type,\n line: `${n.startLine}-${n.endLine}`,\n metadata: n.metadata,\n }));\n\n return {\n content: [\n {\n type: \"text\",\n text: `Contents of ${filePath}:\\n${JSON.stringify(contents, null, 2)}`,\n },\n ],\n };\n }\n\n default:\n return {\n content: [{ type: \"text\", text: `Unknown tool: ${name}` }],\n isError: true,\n };\n }\n } catch (error) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n});\n\n// ============ Resources ============\n\nserver.setRequestHandler(ListResourcesRequestSchema, async () => {\n return {\n resources: [\n {\n uri: \"codemap://stats\",\n name: \"Codebase Statistics\",\n description: \"Overview statistics of the analyzed codebase\",\n mimeType: \"application/json\",\n },\n {\n uri: \"codemap://graph\",\n name: \"Dependency Graph\",\n description: \"Full dependency graph for visualization\",\n mimeType: \"application/json\",\n },\n ],\n };\n});\n\nserver.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const { uri } = request.params;\n const db = getStorage();\n\n if (uri === \"codemap://stats\") {\n const stats = db.getStats();\n return {\n contents: [\n {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(stats, null, 2),\n },\n ],\n };\n }\n\n if (uri === \"codemap://graph\") {\n const graph = db.exportForVisualization();\n return {\n contents: [\n {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(graph, null, 2),\n },\n ],\n };\n }\n\n throw new Error(`Unknown resource: ${uri}`);\n});\n\n// ============ Main ============\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"CodeMap MCP server started\");\n}\n\nmain().catch(console.error);\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/mcp/flow-server.ts"],"sourcesContent":["/**\n * MCP Server for CodeMap Flow Edition\n * Provides 3 focused tools: impact analysis, flow tracing, and caller lookup\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { FlowStorage } from \"../flow/storage.js\";\nimport { resolve } from \"path\";\nimport { existsSync } from \"fs\";\n\n// Get config from environment\nconst DB_PATH = process.env.CODEMAP_DB_PATH || \".codemap/graph.db\";\nconst PROJECT_ROOT = process.env.CODEMAP_PROJECT_ROOT || process.cwd();\n\nlet storage: FlowStorage | null = null;\n\nfunction getStorage(): FlowStorage {\n if (!storage) {\n const dbPath = resolve(PROJECT_ROOT, DB_PATH);\n if (!existsSync(dbPath)) {\n throw new Error(`CodeMap database not found at ${dbPath}. Run 'codemap index' first.`);\n }\n storage = new FlowStorage(dbPath);\n }\n return storage;\n}\n\nconst server = new Server(\n {\n name: \"codemap-flow\",\n version: \"3.0.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n }\n);\n\n// ============ Tools ============\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: \"codemap_impact\",\n description: \"Analyze what would break if you change a function/class. Shows all callers and affected files with risk assessment.\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: {\n type: \"string\",\n description: \"Function or class name to analyze\",\n },\n depth: {\n type: \"number\",\n description: \"How many levels deep to analyze (default: 3)\",\n default: 3,\n },\n },\n required: [\"target\"],\n },\n },\n {\n name: \"codemap_trace_flow\",\n description: \"Trace the execution flow between two functions. Shows the complete call path from source to target.\",\n inputSchema: {\n type: \"object\",\n properties: {\n from: {\n type: \"string\",\n description: \"Starting function name\",\n },\n to: {\n type: \"string\",\n description: \"Target function name\",\n },\n },\n required: [\"from\", \"to\"],\n },\n },\n {\n name: \"codemap_callers\",\n description: \"Find all functions that call a specific function. Shows where and how a function is used.\",\n inputSchema: {\n type: \"object\",\n properties: {\n function: {\n type: \"string\",\n description: \"Function name to find callers for\",\n },\n },\n required: [\"function\"],\n },\n },\n ],\n };\n});\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n const db = getStorage();\n\n try {\n switch (name) {\n case \"codemap_impact\": {\n const target = args?.target as string;\n const depth = (args?.depth as number) || 3;\n\n // Find the target node(s)\n const nodes = db.searchNodesByName(target);\n\n if (nodes.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No function or class found with name \"${target}\"`,\n },\n ],\n };\n }\n\n const targetNode = nodes[0];\n\n // Get impacted nodes\n const impacted = db.getImpactedNodes(targetNode.id, depth);\n\n // Get unique files\n const affectedFiles = new Set(impacted.map((n) => n.filePath));\n\n // Assess risk\n const directCallers = db.getResolvedCallers(targetNode.id);\n let risk = \"LOW\";\n if (directCallers.length > 10) risk = \"HIGH\";\n else if (directCallers.length > 5) risk = \"MEDIUM\";\n\n const response = `# Impact Analysis: ${targetNode.name}\n\n**Location:** ${targetNode.filePath}:${targetNode.startLine}\n**Type:** ${targetNode.type}\n**Risk Level:** ${risk}\n\n## Direct Callers (${directCallers.length})\n${directCallers.slice(0, 10).map((c) => `- ${c.name} in ${c.filePath}:${c.startLine}`).join(\"\\n\")}\n${directCallers.length > 10 ? `\\n... and ${directCallers.length - 10} more` : \"\"}\n\n## Total Impact\n- **Affected functions:** ${impacted.length}\n- **Affected files:** ${affectedFiles.size}\n\n## Affected Files\n${[...affectedFiles].slice(0, 20).map((f) => `- ${f}`).join(\"\\n\")}\n${affectedFiles.size > 20 ? `\\n... and ${affectedFiles.size - 20} more` : \"\"}\n\n⚠️ **Recommendation:** ${risk === \"HIGH\" ? \"High-risk change. Review all callers before modifying.\" : risk === \"MEDIUM\" ? \"Moderate risk. Test affected files after changes.\" : \"Low risk. Changes unlikely to cause wide impact.\"}\n`;\n\n return {\n content: [{ type: \"text\", text: response }],\n };\n }\n\n case \"codemap_trace_flow\": {\n const from = args?.from as string;\n const to = args?.to as string;\n\n // Find source and target nodes\n const sourceNodes = db.searchNodesByName(from);\n const targetNodes = db.searchNodesByName(to);\n\n if (sourceNodes.length === 0) {\n return {\n content: [{ type: \"text\", text: `Source function \"${from}\" not found` }],\n };\n }\n\n if (targetNodes.length === 0) {\n return {\n content: [{ type: \"text\", text: `Target function \"${to}\" not found` }],\n };\n }\n\n const sourceNode = sourceNodes[0];\n const targetNode = targetNodes[0];\n\n // Trace path\n const path = db.traceCallPath(sourceNode.id, targetNode.id);\n\n if (!path) {\n return {\n content: [\n {\n type: \"text\",\n text: `No call path found from \"${from}\" to \"${to}\". They may not be connected.`,\n },\n ],\n };\n }\n\n const response = `# Execution Flow: ${from} → ${to}\n\n${path.nodes\n .map(\n (n, i) =>\n `${i + 1}. **${n.name}**\\n File: ${n.file}:${n.line}${i < path.nodes.length - 1 ? \"\\n ↓ calls\" : \"\"}`\n )\n .join(\"\\n\\n\")}\n\n**Total steps:** ${path.nodes.length}\n`;\n\n return {\n content: [{ type: \"text\", text: response }],\n };\n }\n\n case \"codemap_callers\": {\n const functionName = args?.function as string;\n\n // Find the function\n const nodes = db.searchNodesByName(functionName);\n\n if (nodes.length === 0) {\n return {\n content: [{ type: \"text\", text: `Function \"${functionName}\" not found` }],\n };\n }\n\n const targetNode = nodes[0];\n\n // Get all callers\n const callers = db.getResolvedCallers(targetNode.id);\n\n if (callers.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No callers found for \"${functionName}\". It may be unused or only called externally.`,\n },\n ],\n };\n }\n\n const response = `# Callers of ${functionName}\n\n**Function:** ${targetNode.name} (${targetNode.type})\n**Location:** ${targetNode.filePath}:${targetNode.startLine}\n**Total callers:** ${callers.length}\n\n## Who Calls This Function\n\n${callers\n .map(\n (c) => `- **${c.name}** (${c.type})\n File: ${c.filePath}:${c.startLine}`\n )\n .join(\"\\n\\n\")}\n`;\n\n return {\n content: [{ type: \"text\", text: response }],\n };\n }\n\n default:\n return {\n content: [{ type: \"text\", text: `Unknown tool: ${name}` }],\n isError: true,\n };\n }\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: \"text\", text: `Error: ${errorMessage}` }],\n isError: true,\n };\n }\n});\n\n// Start server\nconst transport = new StdioServerTransport();\nserver.connect(transport).catch((error) => {\n console.error(\"Failed to start MCP server:\", error);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "codemap-ai",
3
- "version": "0.1.2",
4
- "description": "AI-powered codebase knowledge graph generator with Claude Code skills integration",
3
+ "version": "3.0.0",
4
+ "description": "Call graph analyzer for understanding code impact and execution flows - built for Claude Code",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -11,11 +11,11 @@
11
11
  },
12
12
  "repository": {
13
13
  "type": "git",
14
- "url": "https://github.com/yourusername/codemap-ai"
14
+ "url": "https://github.com/justaddai/codemap-ai"
15
15
  },
16
- "homepage": "https://github.com/yourusername/codemap-ai#readme",
16
+ "homepage": "https://github.com/justaddai/codemap-ai#readme",
17
17
  "bugs": {
18
- "url": "https://github.com/yourusername/codemap-ai/issues"
18
+ "url": "https://github.com/justaddai/codemap-ai/issues"
19
19
  },
20
20
  "scripts": {
21
21
  "build": "tsup",
@@ -26,45 +26,41 @@
26
26
  "prepublishOnly": "npm run build"
27
27
  },
28
28
  "keywords": [
29
- "code-analysis",
29
+ "call-graph",
30
+ "impact-analysis",
30
31
  "dependency-graph",
31
- "tree-sitter",
32
32
  "claude-code",
33
33
  "mcp-server",
34
- "ai-skills",
35
- "codebase-visualization"
34
+ "code-analysis",
35
+ "flow-tracing"
36
36
  ],
37
- "author": "Sahan Nishshanka (Hub.KI GmbH)",
37
+ "author": "Sahan Nishshanka, JUST ADD AI GmbH",
38
38
  "license": "MIT",
39
39
  "engines": {
40
40
  "node": ">=18.0.0"
41
41
  },
42
42
  "dependencies": {
43
- "@anthropic-ai/sdk": "^0.30.0",
44
43
  "@modelcontextprotocol/sdk": "^1.0.0",
45
44
  "better-sqlite3": "^11.0.0",
46
45
  "chalk": "^5.3.0",
47
46
  "commander": "^12.0.0",
48
- "express": "^4.18.2",
49
47
  "glob": "^10.3.10",
48
+ "js-yaml": "^4.1.1",
50
49
  "ora": "^8.0.1",
51
50
  "tree-sitter": "^0.21.0",
52
51
  "tree-sitter-javascript": "^0.21.0",
53
52
  "tree-sitter-python": "^0.21.0",
54
- "tree-sitter-typescript": "^0.21.0",
55
- "ws": "^8.16.0"
53
+ "tree-sitter-typescript": "^0.21.0"
56
54
  },
57
55
  "devDependencies": {
58
56
  "@types/better-sqlite3": "^7.6.9",
59
- "@types/express": "^4.17.21",
57
+ "@types/js-yaml": "^4.0.9",
60
58
  "@types/node": "^20.11.0",
61
- "@types/ws": "^8.5.10",
62
59
  "tsup": "^8.0.1",
63
60
  "typescript": "^5.3.3"
64
61
  },
65
62
  "files": [
66
63
  "dist",
67
- "web",
68
64
  "README.md"
69
65
  ]
70
66
  }