code-graph-context 2.5.4 → 2.6.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.
- package/dist/mcp/constants.js +70 -557
- package/dist/mcp/tools/detect-dead-code.tool.js +0 -16
- package/dist/mcp/tools/detect-duplicate-code.tool.js +0 -27
- package/dist/mcp/tools/impact-analysis.tool.js +0 -13
- package/dist/mcp/tools/index.js +4 -15
- package/dist/mcp/tools/list-projects.tool.js +0 -2
- package/dist/mcp/tools/list-watchers.tool.js +0 -2
- package/dist/mcp/tools/natural-language-to-cypher.tool.js +0 -6
- package/dist/mcp/tools/search-codebase.tool.js +0 -19
- package/dist/mcp/tools/swarm-claim-task.tool.js +220 -93
- package/dist/mcp/tools/swarm-cleanup.tool.js +0 -8
- package/dist/mcp/tools/swarm-complete-task.tool.js +79 -88
- package/dist/mcp/tools/swarm-get-tasks.tool.js +0 -9
- package/dist/mcp/tools/swarm-orchestrate.tool.js +55 -92
- package/dist/mcp/tools/swarm-post-task.tool.js +32 -11
- package/dist/mcp/tools/traverse-from-node.tool.js +0 -15
- package/package.json +1 -1
|
@@ -158,12 +158,6 @@ export const createDetectDeadCodeTool = (server) => {
|
|
|
158
158
|
if (!projectResult.success)
|
|
159
159
|
return projectResult.error;
|
|
160
160
|
const resolvedProjectId = projectResult.projectId;
|
|
161
|
-
await debugLog('Dead code detection started', {
|
|
162
|
-
projectId: resolvedProjectId,
|
|
163
|
-
excludePatterns,
|
|
164
|
-
excludeSemanticTypes,
|
|
165
|
-
minConfidence,
|
|
166
|
-
});
|
|
167
161
|
// Query project's actual semantic types (data-driven, per-project detection)
|
|
168
162
|
const semanticTypesResult = (await neo4jService.run(QUERIES.GET_PROJECT_SEMANTIC_TYPES, {
|
|
169
163
|
projectId: resolvedProjectId,
|
|
@@ -389,16 +383,6 @@ export const createDetectDeadCodeTool = (server) => {
|
|
|
389
383
|
affectedFiles,
|
|
390
384
|
};
|
|
391
385
|
}
|
|
392
|
-
await debugLog('Dead code detection complete', {
|
|
393
|
-
projectId: resolvedProjectId,
|
|
394
|
-
totalCount: deadCodeItems.length,
|
|
395
|
-
filteredCount: filteredItems.length,
|
|
396
|
-
filterCategory,
|
|
397
|
-
riskLevel,
|
|
398
|
-
summaryOnly,
|
|
399
|
-
offset,
|
|
400
|
-
limit,
|
|
401
|
-
});
|
|
402
386
|
return createSuccessResponse(JSON.stringify(result, null, 2));
|
|
403
387
|
}
|
|
404
388
|
catch (error) {
|
|
@@ -151,12 +151,6 @@ export const createDetectDuplicateCodeTool = (server) => {
|
|
|
151
151
|
if (!projectResult.success)
|
|
152
152
|
return projectResult.error;
|
|
153
153
|
const resolvedProjectId = projectResult.projectId;
|
|
154
|
-
await debugLog('Duplicate code detection started', {
|
|
155
|
-
projectId: resolvedProjectId,
|
|
156
|
-
type,
|
|
157
|
-
minSimilarity,
|
|
158
|
-
scope,
|
|
159
|
-
});
|
|
160
154
|
const coreTypes = getScopeFilter(scope);
|
|
161
155
|
const duplicateGroups = [];
|
|
162
156
|
let groupCounter = 1;
|
|
@@ -320,16 +314,6 @@ export const createDetectDuplicateCodeTool = (server) => {
|
|
|
320
314
|
usedInSemanticGroup.add(nodeId1);
|
|
321
315
|
usedInSemanticGroup.add(nodeId2);
|
|
322
316
|
}
|
|
323
|
-
// Log semantic query diagnostics
|
|
324
|
-
await debugLog('Semantic query diagnostics', {
|
|
325
|
-
rawResults: semanticQueryResults,
|
|
326
|
-
filteredAsSameFile,
|
|
327
|
-
filteredAsSeenPair,
|
|
328
|
-
filteredAsStructural,
|
|
329
|
-
filteredAsUsedInGroup,
|
|
330
|
-
structuralPairsCount: structuralPairs.size,
|
|
331
|
-
finalSemanticGroups: duplicateGroups.filter((g) => g.type === 'semantic').length,
|
|
332
|
-
});
|
|
333
317
|
}
|
|
334
318
|
// Sort by similarity (descending)
|
|
335
319
|
duplicateGroups.sort((a, b) => b.similarity - a.similarity);
|
|
@@ -367,8 +351,6 @@ export const createDetectDuplicateCodeTool = (server) => {
|
|
|
367
351
|
message: `${embeddingCount} nodes have embeddings but no semantic duplicates found above ${minSimilarity} similarity threshold.`,
|
|
368
352
|
};
|
|
369
353
|
}
|
|
370
|
-
// Log diagnostic so user sees it in debug output
|
|
371
|
-
await debugLog('Semantic duplicate diagnostic', semanticDiagnostic);
|
|
372
354
|
}
|
|
373
355
|
// Build summary with warning if no embeddings
|
|
374
356
|
let summary = totalGroups === 0
|
|
@@ -427,15 +409,6 @@ export const createDetectDuplicateCodeTool = (server) => {
|
|
|
427
409
|
if (semanticDiagnostic) {
|
|
428
410
|
result.semanticDiagnostic = semanticDiagnostic;
|
|
429
411
|
}
|
|
430
|
-
await debugLog('Duplicate code detection complete', {
|
|
431
|
-
projectId: resolvedProjectId,
|
|
432
|
-
totalGroups,
|
|
433
|
-
structuralGroups: allStructuralGroups.length,
|
|
434
|
-
semanticGroups: allSemanticGroups.length,
|
|
435
|
-
summaryOnly,
|
|
436
|
-
offset,
|
|
437
|
-
maxResults,
|
|
438
|
-
});
|
|
439
412
|
return createSuccessResponse(JSON.stringify(result, null, 2));
|
|
440
413
|
}
|
|
441
414
|
catch (error) {
|
|
@@ -81,13 +81,6 @@ export const createImpactAnalysisTool = (server) => {
|
|
|
81
81
|
if (!nodeId && !filePath) {
|
|
82
82
|
return createErrorResponse('Either nodeId or filePath must be provided');
|
|
83
83
|
}
|
|
84
|
-
await debugLog('Impact analysis started', {
|
|
85
|
-
projectId: resolvedProjectId,
|
|
86
|
-
nodeId,
|
|
87
|
-
filePath,
|
|
88
|
-
maxDepth,
|
|
89
|
-
frameworkConfig,
|
|
90
|
-
});
|
|
91
84
|
// Merge default weights with framework-specific weights
|
|
92
85
|
const weights = { ...DEFAULT_RELATIONSHIP_WEIGHTS, ...frameworkConfig?.relationshipWeights };
|
|
93
86
|
const highRiskTypes = new Set(frameworkConfig?.highRiskTypes ?? []);
|
|
@@ -213,12 +206,6 @@ export const createImpactAnalysisTool = (server) => {
|
|
|
213
206
|
affectedFiles,
|
|
214
207
|
criticalPaths,
|
|
215
208
|
};
|
|
216
|
-
await debugLog('Impact analysis complete', {
|
|
217
|
-
nodeId: nodeId ?? filePath,
|
|
218
|
-
riskLevel,
|
|
219
|
-
directCount: directDependents.length,
|
|
220
|
-
transitiveCount: transitiveDependents.length,
|
|
221
|
-
});
|
|
222
209
|
return createSuccessResponse(JSON.stringify(result, null, 2));
|
|
223
210
|
}
|
|
224
211
|
catch (error) {
|
package/dist/mcp/tools/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* MCP Tool Factory
|
|
3
3
|
* Centralized tool creation and registration
|
|
4
4
|
*/
|
|
5
|
-
import { debugLog } from '../utils.js';
|
|
6
5
|
import { createCheckParseStatusTool } from './check-parse-status.tool.js';
|
|
7
6
|
import { createDetectDeadCodeTool } from './detect-dead-code.tool.js';
|
|
8
7
|
import { createDetectDuplicateCodeTool } from './detect-duplicate-code.tool.js';
|
|
@@ -30,25 +29,15 @@ let globalToolCallCount = 0;
|
|
|
30
29
|
/**
|
|
31
30
|
* Log tool call start (exported for use by individual tools)
|
|
32
31
|
*/
|
|
33
|
-
export const logToolCallStart = async (
|
|
32
|
+
export const logToolCallStart = async (_toolName, _params) => {
|
|
34
33
|
globalToolCallCount++;
|
|
35
|
-
|
|
36
|
-
await debugLog(`Tool call START: ${toolName}`, {
|
|
37
|
-
callId,
|
|
38
|
-
totalCalls: globalToolCallCount,
|
|
39
|
-
params: params ? JSON.stringify(params).substring(0, 500) : 'none',
|
|
40
|
-
});
|
|
41
|
-
return callId;
|
|
34
|
+
return globalToolCallCount;
|
|
42
35
|
};
|
|
43
36
|
/**
|
|
44
37
|
* Log tool call end (exported for use by individual tools)
|
|
45
38
|
*/
|
|
46
|
-
export const logToolCallEnd = async (
|
|
47
|
-
|
|
48
|
-
callId,
|
|
49
|
-
success,
|
|
50
|
-
duration: duration ? `${duration}ms` : 'unknown',
|
|
51
|
-
});
|
|
39
|
+
export const logToolCallEnd = async (_toolName, _callId, _success, _duration) => {
|
|
40
|
+
// No-op - verbose logging disabled
|
|
52
41
|
};
|
|
53
42
|
/**
|
|
54
43
|
* Register all MCP tools with the server
|
|
@@ -14,7 +14,6 @@ export const createListProjectsTool = (server) => {
|
|
|
14
14
|
}, async () => {
|
|
15
15
|
const neo4jService = new Neo4jService();
|
|
16
16
|
try {
|
|
17
|
-
await debugLog('Listing projects');
|
|
18
17
|
const results = await neo4jService.run(LIST_PROJECTS_QUERY, {});
|
|
19
18
|
if (results.length === 0) {
|
|
20
19
|
return createSuccessResponse('No projects found. Use parse_typescript_project to add a project first.');
|
|
@@ -28,7 +27,6 @@ export const createListProjectsTool = (server) => {
|
|
|
28
27
|
edgeCount: r.edgeCount,
|
|
29
28
|
updatedAt: r.updatedAt?.toString() ?? 'Unknown',
|
|
30
29
|
}));
|
|
31
|
-
await debugLog('Projects listed', { count: projects.length });
|
|
32
30
|
// Format output for readability
|
|
33
31
|
const header = `Found ${projects.length} project(s):\n\n`;
|
|
34
32
|
const formatStats = (p) => {
|
|
@@ -12,7 +12,6 @@ export const createListWatchersTool = (server) => {
|
|
|
12
12
|
inputSchema: {},
|
|
13
13
|
}, async () => {
|
|
14
14
|
try {
|
|
15
|
-
await debugLog('Listing watchers');
|
|
16
15
|
const watchers = watchManager.listWatchers();
|
|
17
16
|
if (watchers.length === 0) {
|
|
18
17
|
return createSuccessResponse('No active file watchers.\n\n' +
|
|
@@ -20,7 +19,6 @@ export const createListWatchersTool = (server) => {
|
|
|
20
19
|
'- Use start_watch_project with a projectId\n' +
|
|
21
20
|
'- Or use parse_typescript_project with watch: true (requires async: false)');
|
|
22
21
|
}
|
|
23
|
-
await debugLog('Watchers listed', { count: watchers.length });
|
|
24
22
|
const header = `Found ${watchers.length} active watcher(s):\n\n`;
|
|
25
23
|
const watcherList = watchers
|
|
26
24
|
.map((w) => {
|
|
@@ -47,7 +47,6 @@ export const createNaturalLanguageToCypherTool = (server) => {
|
|
|
47
47
|
await debugLog('Natural language service not available', { projectId: resolvedProjectId, query });
|
|
48
48
|
return createSuccessResponse(MESSAGES.errors.serviceNotInitialized);
|
|
49
49
|
}
|
|
50
|
-
await debugLog('Natural language to Cypher conversion started', { projectId: resolvedProjectId, query });
|
|
51
50
|
const cypherResult = await naturalLanguageToCypherService.promptToQuery(query, resolvedProjectId);
|
|
52
51
|
// Validate Cypher syntax using EXPLAIN (no execution, just parse)
|
|
53
52
|
const parameters = { ...cypherResult.parameters, projectId: resolvedProjectId };
|
|
@@ -67,11 +66,6 @@ export const createNaturalLanguageToCypherTool = (server) => {
|
|
|
67
66
|
}
|
|
68
67
|
// Execute the validated query
|
|
69
68
|
const results = await neo4jService.run(cypherResult.cypher, parameters);
|
|
70
|
-
await debugLog('Cypher query executed', {
|
|
71
|
-
projectId: resolvedProjectId,
|
|
72
|
-
cypher: cypherResult.cypher,
|
|
73
|
-
resultsCount: results.length,
|
|
74
|
-
});
|
|
75
69
|
const formattedResponse = formatQueryResults(results, query, cypherResult);
|
|
76
70
|
return createSuccessResponse(JSON.stringify(formattedResponse, null, 2));
|
|
77
71
|
}
|
|
@@ -63,7 +63,6 @@ export const createSearchCodebaseTool = (server) => {
|
|
|
63
63
|
const sanitizedMaxNodesPerChain = sanitizeNumericInput(maxNodesPerChain, 5);
|
|
64
64
|
const sanitizedSkip = sanitizeNumericInput(skip, 0);
|
|
65
65
|
const sanitizedSnippetLength = sanitizeNumericInput(snippetLength, DEFAULTS.codeSnippetLength);
|
|
66
|
-
await debugLog('Search codebase started', { projectId: resolvedProjectId, query });
|
|
67
66
|
const embeddingsService = new EmbeddingsService();
|
|
68
67
|
const traversalHandler = new TraversalHandler(neo4jService);
|
|
69
68
|
const embedding = await embeddingsService.embedText(query);
|
|
@@ -75,7 +74,6 @@ export const createSearchCodebaseTool = (server) => {
|
|
|
75
74
|
minSimilarity,
|
|
76
75
|
});
|
|
77
76
|
if (vectorResults.length === 0) {
|
|
78
|
-
await debugLog('No relevant code found', { projectId: resolvedProjectId, query, minSimilarity });
|
|
79
77
|
return createSuccessResponse(`No code found with similarity >= ${minSimilarity}. ` +
|
|
80
78
|
`Try rephrasing your query or lowering the minSimilarity threshold. Query: "${query}"`);
|
|
81
79
|
}
|
|
@@ -84,26 +82,9 @@ export const createSearchCodebaseTool = (server) => {
|
|
|
84
82
|
const similarityScore = vectorResults[0].score;
|
|
85
83
|
// Check if best match meets threshold - prevents traversing low-relevance results
|
|
86
84
|
if (similarityScore < minSimilarity) {
|
|
87
|
-
await debugLog('Best match below similarity threshold', {
|
|
88
|
-
projectId: resolvedProjectId,
|
|
89
|
-
query,
|
|
90
|
-
score: similarityScore,
|
|
91
|
-
threshold: minSimilarity,
|
|
92
|
-
});
|
|
93
85
|
return createSuccessResponse(`No sufficiently relevant code found. Best match score: ${similarityScore.toFixed(3)} ` +
|
|
94
86
|
`(threshold: ${minSimilarity}). Try rephrasing your query.`);
|
|
95
87
|
}
|
|
96
|
-
await debugLog('Vector search completed, starting traversal', {
|
|
97
|
-
projectId: resolvedProjectId,
|
|
98
|
-
nodeId,
|
|
99
|
-
similarityScore,
|
|
100
|
-
resultsCount: vectorResults.length,
|
|
101
|
-
maxDepth: sanitizedMaxDepth,
|
|
102
|
-
maxNodesPerChain: sanitizedMaxNodesPerChain,
|
|
103
|
-
skip: sanitizedSkip,
|
|
104
|
-
includeCode,
|
|
105
|
-
snippetLength: sanitizedSnippetLength,
|
|
106
|
-
});
|
|
107
88
|
// Include similarity score in the title so users can see relevance
|
|
108
89
|
const scoreDisplay = typeof similarityScore === 'number' ? similarityScore.toFixed(3) : 'N/A';
|
|
109
90
|
return await traversalHandler.traverseFromNode(nodeId, embedding, {
|