@optave/codegraph 2.1.1-dev.3c12b64 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -45
- package/package.json +5 -5
- package/src/builder.js +238 -33
- package/src/cli.js +96 -12
- package/src/config.js +1 -1
- package/src/cycles.js +13 -1
- package/src/db.js +4 -0
- package/src/embedder.js +1 -1
- package/src/export.js +20 -7
- package/src/extractors/csharp.js +6 -1
- package/src/extractors/go.js +6 -1
- package/src/extractors/java.js +4 -1
- package/src/extractors/javascript.js +145 -5
- package/src/extractors/php.js +8 -2
- package/src/extractors/python.js +8 -1
- package/src/extractors/ruby.js +4 -1
- package/src/extractors/rust.js +12 -2
- package/src/index.js +6 -0
- package/src/journal.js +109 -0
- package/src/mcp.js +131 -7
- package/src/parser.js +1 -0
- package/src/queries.js +1143 -38
- package/src/structure.js +21 -7
- package/src/watcher.js +25 -0
package/src/mcp.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { createRequire } from 'node:module';
|
|
9
9
|
import { findCycles } from './cycles.js';
|
|
10
10
|
import { findDbPath } from './db.js';
|
|
11
|
+
import { ALL_SYMBOL_KINDS } from './queries.js';
|
|
11
12
|
|
|
12
13
|
const REPO_PROP = {
|
|
13
14
|
repo: {
|
|
@@ -29,6 +30,7 @@ const BASE_TOOLS = [
|
|
|
29
30
|
description: 'Traversal depth for transitive callers',
|
|
30
31
|
default: 2,
|
|
31
32
|
},
|
|
33
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
32
34
|
},
|
|
33
35
|
required: ['name'],
|
|
34
36
|
},
|
|
@@ -40,6 +42,7 @@ const BASE_TOOLS = [
|
|
|
40
42
|
type: 'object',
|
|
41
43
|
properties: {
|
|
42
44
|
file: { type: 'string', description: 'File path (partial match supported)' },
|
|
45
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
43
46
|
},
|
|
44
47
|
required: ['file'],
|
|
45
48
|
},
|
|
@@ -51,6 +54,7 @@ const BASE_TOOLS = [
|
|
|
51
54
|
type: 'object',
|
|
52
55
|
properties: {
|
|
53
56
|
file: { type: 'string', description: 'File path to analyze' },
|
|
57
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
54
58
|
},
|
|
55
59
|
required: ['file'],
|
|
56
60
|
},
|
|
@@ -70,6 +74,7 @@ const BASE_TOOLS = [
|
|
|
70
74
|
type: 'object',
|
|
71
75
|
properties: {
|
|
72
76
|
limit: { type: 'number', description: 'Number of top files to show', default: 20 },
|
|
77
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
73
78
|
},
|
|
74
79
|
},
|
|
75
80
|
},
|
|
@@ -81,6 +86,15 @@ const BASE_TOOLS = [
|
|
|
81
86
|
properties: {
|
|
82
87
|
name: { type: 'string', description: 'Function/method/class name (partial match)' },
|
|
83
88
|
depth: { type: 'number', description: 'Transitive caller depth', default: 3 },
|
|
89
|
+
file: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'Scope search to functions in this file (partial match)',
|
|
92
|
+
},
|
|
93
|
+
kind: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
enum: ALL_SYMBOL_KINDS,
|
|
96
|
+
description: 'Filter to a specific symbol kind',
|
|
97
|
+
},
|
|
84
98
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
85
99
|
},
|
|
86
100
|
required: ['name'],
|
|
@@ -95,11 +109,88 @@ const BASE_TOOLS = [
|
|
|
95
109
|
properties: {
|
|
96
110
|
name: { type: 'string', description: 'Function/method/class name (partial match)' },
|
|
97
111
|
depth: { type: 'number', description: 'Max traversal depth', default: 5 },
|
|
112
|
+
file: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
description: 'Scope search to functions in this file (partial match)',
|
|
115
|
+
},
|
|
116
|
+
kind: {
|
|
117
|
+
type: 'string',
|
|
118
|
+
enum: ALL_SYMBOL_KINDS,
|
|
119
|
+
description: 'Filter to a specific symbol kind',
|
|
120
|
+
},
|
|
121
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
122
|
+
},
|
|
123
|
+
required: ['name'],
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'context',
|
|
128
|
+
description:
|
|
129
|
+
'Full context for a function: source code, dependencies with summaries, callers, signature, and related tests — everything needed to understand or modify a function in one call',
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: 'object',
|
|
132
|
+
properties: {
|
|
133
|
+
name: { type: 'string', description: 'Function/method/class name (partial match)' },
|
|
134
|
+
depth: {
|
|
135
|
+
type: 'number',
|
|
136
|
+
description: 'Include callee source up to N levels deep (0=no source, 1=direct)',
|
|
137
|
+
default: 0,
|
|
138
|
+
},
|
|
139
|
+
file: {
|
|
140
|
+
type: 'string',
|
|
141
|
+
description: 'Scope search to functions in this file (partial match)',
|
|
142
|
+
},
|
|
143
|
+
kind: {
|
|
144
|
+
type: 'string',
|
|
145
|
+
enum: ALL_SYMBOL_KINDS,
|
|
146
|
+
description: 'Filter to a specific symbol kind',
|
|
147
|
+
},
|
|
148
|
+
no_source: {
|
|
149
|
+
type: 'boolean',
|
|
150
|
+
description: 'Skip source extraction (metadata only)',
|
|
151
|
+
default: false,
|
|
152
|
+
},
|
|
98
153
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
154
|
+
include_tests: {
|
|
155
|
+
type: 'boolean',
|
|
156
|
+
description: 'Include test file source code',
|
|
157
|
+
default: false,
|
|
158
|
+
},
|
|
99
159
|
},
|
|
100
160
|
required: ['name'],
|
|
101
161
|
},
|
|
102
162
|
},
|
|
163
|
+
{
|
|
164
|
+
name: 'explain',
|
|
165
|
+
description:
|
|
166
|
+
'Structural summary of a file or function: public/internal API, data flow, dependencies. No LLM needed.',
|
|
167
|
+
inputSchema: {
|
|
168
|
+
type: 'object',
|
|
169
|
+
properties: {
|
|
170
|
+
target: { type: 'string', description: 'File path or function name' },
|
|
171
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
172
|
+
},
|
|
173
|
+
required: ['target'],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: 'where',
|
|
178
|
+
description:
|
|
179
|
+
'Find where a symbol is defined and used, or list symbols/imports/exports for a file. Minimal, fast lookup.',
|
|
180
|
+
inputSchema: {
|
|
181
|
+
type: 'object',
|
|
182
|
+
properties: {
|
|
183
|
+
target: { type: 'string', description: 'Symbol name or file path' },
|
|
184
|
+
file_mode: {
|
|
185
|
+
type: 'boolean',
|
|
186
|
+
description: 'Treat target as file path (list symbols/imports/exports)',
|
|
187
|
+
default: false,
|
|
188
|
+
},
|
|
189
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
190
|
+
},
|
|
191
|
+
required: ['target'],
|
|
192
|
+
},
|
|
193
|
+
},
|
|
103
194
|
{
|
|
104
195
|
name: 'diff_impact',
|
|
105
196
|
description: 'Analyze git diff to find which functions changed and their transitive callers',
|
|
@@ -195,6 +286,7 @@ const BASE_TOOLS = [
|
|
|
195
286
|
description: 'Rank files or directories',
|
|
196
287
|
},
|
|
197
288
|
limit: { type: 'number', description: 'Number of results to return', default: 10 },
|
|
289
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
198
290
|
},
|
|
199
291
|
},
|
|
200
292
|
},
|
|
@@ -245,12 +337,15 @@ export { TOOLS, buildToolList };
|
|
|
245
337
|
export async function startMCPServer(customDbPath, options = {}) {
|
|
246
338
|
const { allowedRepos } = options;
|
|
247
339
|
const multiRepo = options.multiRepo || !!allowedRepos;
|
|
248
|
-
let Server, StdioServerTransport;
|
|
340
|
+
let Server, StdioServerTransport, ListToolsRequestSchema, CallToolRequestSchema;
|
|
249
341
|
try {
|
|
250
342
|
const sdk = await import('@modelcontextprotocol/sdk/server/index.js');
|
|
251
343
|
Server = sdk.Server;
|
|
252
344
|
const transport = await import('@modelcontextprotocol/sdk/server/stdio.js');
|
|
253
345
|
StdioServerTransport = transport.StdioServerTransport;
|
|
346
|
+
const types = await import('@modelcontextprotocol/sdk/types.js');
|
|
347
|
+
ListToolsRequestSchema = types.ListToolsRequestSchema;
|
|
348
|
+
CallToolRequestSchema = types.CallToolRequestSchema;
|
|
254
349
|
} catch {
|
|
255
350
|
console.error(
|
|
256
351
|
'MCP server requires @modelcontextprotocol/sdk.\n' +
|
|
@@ -267,6 +362,9 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
267
362
|
fileDepsData,
|
|
268
363
|
fnDepsData,
|
|
269
364
|
fnImpactData,
|
|
365
|
+
contextData,
|
|
366
|
+
explainData,
|
|
367
|
+
whereData,
|
|
270
368
|
diffImpactData,
|
|
271
369
|
listFunctionsData,
|
|
272
370
|
} = await import('./queries.js');
|
|
@@ -279,9 +377,11 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
279
377
|
{ capabilities: { tools: {} } },
|
|
280
378
|
);
|
|
281
379
|
|
|
282
|
-
server.setRequestHandler(
|
|
380
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
381
|
+
tools: buildToolList(multiRepo),
|
|
382
|
+
}));
|
|
283
383
|
|
|
284
|
-
server.setRequestHandler(
|
|
384
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
285
385
|
const { name, arguments: args } = request.params;
|
|
286
386
|
|
|
287
387
|
try {
|
|
@@ -313,13 +413,13 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
313
413
|
let result;
|
|
314
414
|
switch (name) {
|
|
315
415
|
case 'query_function':
|
|
316
|
-
result = queryNameData(args.name, dbPath);
|
|
416
|
+
result = queryNameData(args.name, dbPath, { noTests: args.no_tests });
|
|
317
417
|
break;
|
|
318
418
|
case 'file_deps':
|
|
319
|
-
result = fileDepsData(args.file, dbPath);
|
|
419
|
+
result = fileDepsData(args.file, dbPath, { noTests: args.no_tests });
|
|
320
420
|
break;
|
|
321
421
|
case 'impact_analysis':
|
|
322
|
-
result = impactAnalysisData(args.file, dbPath);
|
|
422
|
+
result = impactAnalysisData(args.file, dbPath, { noTests: args.no_tests });
|
|
323
423
|
break;
|
|
324
424
|
case 'find_cycles': {
|
|
325
425
|
const db = new Database(findDbPath(dbPath), { readonly: true });
|
|
@@ -329,17 +429,40 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
329
429
|
break;
|
|
330
430
|
}
|
|
331
431
|
case 'module_map':
|
|
332
|
-
result = moduleMapData(dbPath, args.limit || 20);
|
|
432
|
+
result = moduleMapData(dbPath, args.limit || 20, { noTests: args.no_tests });
|
|
333
433
|
break;
|
|
334
434
|
case 'fn_deps':
|
|
335
435
|
result = fnDepsData(args.name, dbPath, {
|
|
336
436
|
depth: args.depth,
|
|
437
|
+
file: args.file,
|
|
438
|
+
kind: args.kind,
|
|
337
439
|
noTests: args.no_tests,
|
|
338
440
|
});
|
|
339
441
|
break;
|
|
340
442
|
case 'fn_impact':
|
|
341
443
|
result = fnImpactData(args.name, dbPath, {
|
|
342
444
|
depth: args.depth,
|
|
445
|
+
file: args.file,
|
|
446
|
+
kind: args.kind,
|
|
447
|
+
noTests: args.no_tests,
|
|
448
|
+
});
|
|
449
|
+
break;
|
|
450
|
+
case 'context':
|
|
451
|
+
result = contextData(args.name, dbPath, {
|
|
452
|
+
depth: args.depth,
|
|
453
|
+
file: args.file,
|
|
454
|
+
kind: args.kind,
|
|
455
|
+
noSource: args.no_source,
|
|
456
|
+
noTests: args.no_tests,
|
|
457
|
+
includeTests: args.include_tests,
|
|
458
|
+
});
|
|
459
|
+
break;
|
|
460
|
+
case 'explain':
|
|
461
|
+
result = explainData(args.target, dbPath, { noTests: args.no_tests });
|
|
462
|
+
break;
|
|
463
|
+
case 'where':
|
|
464
|
+
result = whereData(args.target, dbPath, {
|
|
465
|
+
file: args.file_mode,
|
|
343
466
|
noTests: args.no_tests,
|
|
344
467
|
});
|
|
345
468
|
break;
|
|
@@ -418,6 +541,7 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
418
541
|
metric: args.metric,
|
|
419
542
|
level: args.level,
|
|
420
543
|
limit: args.limit,
|
|
544
|
+
noTests: args.no_tests,
|
|
421
545
|
});
|
|
422
546
|
break;
|
|
423
547
|
}
|