code-auditor-mcp 1.1.1 → 1.2.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/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +35 -1
- package/dist/auditRunner.js.map +1 -1
- package/dist/mcp-standalone.js +311 -10
- package/dist/mcp-standalone.js.map +1 -1
- package/dist/mcp.js +153 -404
- package/dist/mcp.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/mcp.js
CHANGED
|
@@ -9,8 +9,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprot
|
|
|
9
9
|
console.error(chalk.blue('[INFO]'), 'MCP SDK loaded');
|
|
10
10
|
import { createAuditRunner } from './auditRunner.js';
|
|
11
11
|
console.error(chalk.blue('[INFO]'), 'Audit runner loaded');
|
|
12
|
-
import {
|
|
13
|
-
import { scanFunctionsInFile, scanFunctionsInDirectory } from './functionScanner.js';
|
|
12
|
+
import { searchFunctions, findDefinition, syncFileIndex } from './codeIndexService.js';
|
|
14
13
|
import { ConfigGeneratorFactory } from './generators/ConfigGeneratorFactory.js';
|
|
15
14
|
import { DEFAULT_SERVER_URL } from './constants.js';
|
|
16
15
|
console.error(chalk.blue('[INFO]'), 'Code index service loaded');
|
|
@@ -19,19 +18,20 @@ import fs from 'node:fs/promises';
|
|
|
19
18
|
import { CodeIndexDB } from './codeIndexDB.js';
|
|
20
19
|
console.error(chalk.blue('[INFO]'), 'All modules loaded successfully');
|
|
21
20
|
const tools = [
|
|
21
|
+
// Core Audit Tools
|
|
22
22
|
{
|
|
23
|
-
name: '
|
|
24
|
-
description: 'Run a comprehensive code audit on
|
|
23
|
+
name: 'audit',
|
|
24
|
+
description: 'Run a comprehensive code audit on files or directories',
|
|
25
25
|
parameters: [
|
|
26
26
|
{
|
|
27
27
|
name: 'path',
|
|
28
28
|
type: 'string',
|
|
29
29
|
required: false,
|
|
30
|
-
description: 'The directory path to audit (defaults to current directory)',
|
|
30
|
+
description: 'The file or directory path to audit (defaults to current directory)',
|
|
31
31
|
default: process.cwd(),
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
name: '
|
|
34
|
+
name: 'analyzers',
|
|
35
35
|
type: 'array',
|
|
36
36
|
required: false,
|
|
37
37
|
description: 'List of analyzers to run (solid, dry, security, component, data-access)',
|
|
@@ -45,29 +45,17 @@ const tools = [
|
|
|
45
45
|
default: 'warning',
|
|
46
46
|
enum: ['info', 'warning', 'critical'],
|
|
47
47
|
},
|
|
48
|
-
],
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
name: 'audit_analyze_file',
|
|
52
|
-
description: 'Analyze a specific file for code quality issues',
|
|
53
|
-
parameters: [
|
|
54
48
|
{
|
|
55
|
-
name: '
|
|
56
|
-
type: '
|
|
57
|
-
required: true,
|
|
58
|
-
description: 'The file path to analyze',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: 'analyzers',
|
|
62
|
-
type: 'array',
|
|
49
|
+
name: 'indexFunctions',
|
|
50
|
+
type: 'boolean',
|
|
63
51
|
required: false,
|
|
64
|
-
description: '
|
|
65
|
-
default:
|
|
52
|
+
description: 'Automatically index functions during audit',
|
|
53
|
+
default: true,
|
|
66
54
|
},
|
|
67
55
|
],
|
|
68
56
|
},
|
|
69
57
|
{
|
|
70
|
-
name: '
|
|
58
|
+
name: 'audit_health',
|
|
71
59
|
description: 'Quick health check of a codebase with key metrics',
|
|
72
60
|
parameters: [
|
|
73
61
|
{
|
|
@@ -84,41 +72,25 @@ const tools = [
|
|
|
84
72
|
description: 'Health score threshold (0-100) for pass/fail',
|
|
85
73
|
default: 70,
|
|
86
74
|
},
|
|
87
|
-
],
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
name: 'audit_list_analyzers',
|
|
91
|
-
description: 'List all available code analyzers and their capabilities',
|
|
92
|
-
parameters: [],
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
name: 'register_functions',
|
|
96
|
-
description: 'Register functions with metadata for code indexing',
|
|
97
|
-
parameters: [
|
|
98
75
|
{
|
|
99
|
-
name: '
|
|
100
|
-
type: 'array',
|
|
101
|
-
required: true,
|
|
102
|
-
description: 'Array of function objects with metadata',
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: 'overwrite',
|
|
76
|
+
name: 'indexFunctions',
|
|
106
77
|
type: 'boolean',
|
|
107
78
|
required: false,
|
|
108
|
-
description: '
|
|
109
|
-
default:
|
|
79
|
+
description: 'Automatically index functions during health check',
|
|
80
|
+
default: true,
|
|
110
81
|
},
|
|
111
82
|
],
|
|
112
83
|
},
|
|
84
|
+
// Code Index Tools
|
|
113
85
|
{
|
|
114
|
-
name: '
|
|
115
|
-
description: 'Search
|
|
86
|
+
name: 'search_code',
|
|
87
|
+
description: 'Search indexed functions with natural language queries',
|
|
116
88
|
parameters: [
|
|
117
89
|
{
|
|
118
90
|
name: 'query',
|
|
119
91
|
type: 'string',
|
|
120
92
|
required: true,
|
|
121
|
-
description: 'Search query (supports
|
|
93
|
+
description: 'Search query (supports natural language)',
|
|
122
94
|
},
|
|
123
95
|
{
|
|
124
96
|
name: 'filters',
|
|
@@ -142,41 +114,15 @@ const tools = [
|
|
|
142
114
|
},
|
|
143
115
|
],
|
|
144
116
|
},
|
|
145
|
-
{
|
|
146
|
-
name: 'index_functions',
|
|
147
|
-
description: 'Index functions from TypeScript/JavaScript files',
|
|
148
|
-
parameters: [
|
|
149
|
-
{
|
|
150
|
-
name: 'path',
|
|
151
|
-
type: 'string',
|
|
152
|
-
required: true,
|
|
153
|
-
description: 'File or directory path to index',
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
name: 'recursive',
|
|
157
|
-
type: 'boolean',
|
|
158
|
-
required: false,
|
|
159
|
-
description: 'Recursively index directories',
|
|
160
|
-
default: true,
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
name: 'fileTypes',
|
|
164
|
-
type: 'array',
|
|
165
|
-
required: false,
|
|
166
|
-
description: 'File extensions to process',
|
|
167
|
-
default: ['.ts', '.tsx', '.js', '.jsx'],
|
|
168
|
-
},
|
|
169
|
-
],
|
|
170
|
-
},
|
|
171
117
|
{
|
|
172
118
|
name: 'find_definition',
|
|
173
|
-
description: 'Find the definition of a specific function',
|
|
119
|
+
description: 'Find the exact definition of a specific function',
|
|
174
120
|
parameters: [
|
|
175
121
|
{
|
|
176
122
|
name: 'name',
|
|
177
123
|
type: 'string',
|
|
178
124
|
required: true,
|
|
179
|
-
description: 'Function name to
|
|
125
|
+
description: 'Function name to find',
|
|
180
126
|
},
|
|
181
127
|
{
|
|
182
128
|
name: 'filePath',
|
|
@@ -187,39 +133,35 @@ const tools = [
|
|
|
187
133
|
],
|
|
188
134
|
},
|
|
189
135
|
{
|
|
190
|
-
name: '
|
|
191
|
-
description: '
|
|
192
|
-
parameters: [],
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
name: 'clear_index',
|
|
196
|
-
description: 'Clear all indexed functions',
|
|
136
|
+
name: 'sync_index',
|
|
137
|
+
description: 'Synchronize, cleanup, or reset the code index',
|
|
197
138
|
parameters: [
|
|
198
139
|
{
|
|
199
|
-
name: '
|
|
200
|
-
type: '
|
|
140
|
+
name: 'mode',
|
|
141
|
+
type: 'string',
|
|
201
142
|
required: false,
|
|
202
|
-
description: '
|
|
203
|
-
default:
|
|
143
|
+
description: 'Operation mode: sync (update), cleanup (remove stale), or reset (clear all)',
|
|
144
|
+
default: 'sync',
|
|
145
|
+
enum: ['sync', 'cleanup', 'reset'],
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'path',
|
|
149
|
+
type: 'string',
|
|
150
|
+
required: false,
|
|
151
|
+
description: 'Optional specific path to sync',
|
|
204
152
|
},
|
|
205
153
|
],
|
|
206
154
|
},
|
|
155
|
+
// AI Configuration Tool
|
|
207
156
|
{
|
|
208
|
-
name: '
|
|
157
|
+
name: 'generate_ai_config',
|
|
209
158
|
description: 'Generate configuration files for AI coding assistants',
|
|
210
159
|
parameters: [
|
|
211
160
|
{
|
|
212
161
|
name: 'tools',
|
|
213
162
|
type: 'array',
|
|
214
163
|
required: true,
|
|
215
|
-
description: 'AI tools to
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
name: 'serverUrl',
|
|
219
|
-
type: 'string',
|
|
220
|
-
required: false,
|
|
221
|
-
description: 'MCP server URL',
|
|
222
|
-
default: DEFAULT_SERVER_URL,
|
|
164
|
+
description: 'AI tools to configure (cursor, continue, copilot, claude, zed, windsurf, cody, aider, cline, pearai)',
|
|
223
165
|
},
|
|
224
166
|
{
|
|
225
167
|
name: 'outputDir',
|
|
@@ -228,60 +170,8 @@ const tools = [
|
|
|
228
170
|
description: 'Output directory for configuration files',
|
|
229
171
|
default: '.',
|
|
230
172
|
},
|
|
231
|
-
{
|
|
232
|
-
name: 'overwrite',
|
|
233
|
-
type: 'boolean',
|
|
234
|
-
required: false,
|
|
235
|
-
description: 'Overwrite existing files',
|
|
236
|
-
default: false,
|
|
237
|
-
},
|
|
238
|
-
],
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
name: 'list_ai_tools',
|
|
242
|
-
description: 'List all supported AI tools for configuration generation',
|
|
243
|
-
parameters: [],
|
|
244
|
-
},
|
|
245
|
-
{
|
|
246
|
-
name: 'get_ai_tool_info',
|
|
247
|
-
description: 'Get detailed information about a specific AI tool',
|
|
248
|
-
parameters: [
|
|
249
|
-
{
|
|
250
|
-
name: 'tool',
|
|
251
|
-
type: 'string',
|
|
252
|
-
required: true,
|
|
253
|
-
description: 'AI tool name (cursor, continue, copilot, etc.)',
|
|
254
|
-
},
|
|
255
173
|
],
|
|
256
174
|
},
|
|
257
|
-
{
|
|
258
|
-
name: 'validate_ai_config',
|
|
259
|
-
description: 'Validate a generated AI tool configuration',
|
|
260
|
-
parameters: [
|
|
261
|
-
{
|
|
262
|
-
name: 'tool',
|
|
263
|
-
type: 'string',
|
|
264
|
-
required: true,
|
|
265
|
-
description: 'AI tool name',
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
name: 'config',
|
|
269
|
-
type: 'object',
|
|
270
|
-
required: true,
|
|
271
|
-
description: 'Configuration object to validate',
|
|
272
|
-
},
|
|
273
|
-
],
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
name: 'bulk_cleanup',
|
|
277
|
-
description: 'Remove index entries for deleted files',
|
|
278
|
-
parameters: [],
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
name: 'deep_sync',
|
|
282
|
-
description: 'Deep synchronize all indexed files to update signatures and remove stale entries',
|
|
283
|
-
parameters: [],
|
|
284
|
-
},
|
|
285
175
|
];
|
|
286
176
|
async function startMcpServer() {
|
|
287
177
|
console.error(chalk.blue('[INFO]'), 'Starting Code Auditor MCP Server...');
|
|
@@ -326,16 +216,46 @@ async function startMcpServer() {
|
|
|
326
216
|
try {
|
|
327
217
|
let result;
|
|
328
218
|
switch (name) {
|
|
329
|
-
case '
|
|
219
|
+
case 'audit': {
|
|
330
220
|
const auditPath = path.resolve(args.path || process.cwd());
|
|
221
|
+
const indexFunctions = args.indexFunctions !== false; // Default true
|
|
222
|
+
// Check if path is a file or directory
|
|
223
|
+
const stats = await fs.stat(auditPath).catch(() => null);
|
|
224
|
+
const isFile = stats?.isFile() || false;
|
|
331
225
|
const options = {
|
|
332
|
-
projectRoot: auditPath,
|
|
333
|
-
enabledAnalyzers: args.
|
|
226
|
+
projectRoot: isFile ? path.dirname(auditPath) : auditPath,
|
|
227
|
+
enabledAnalyzers: args.analyzers || ['solid', 'dry', 'security'],
|
|
334
228
|
minSeverity: (args.minSeverity || 'warning'),
|
|
335
229
|
verbose: false,
|
|
230
|
+
indexFunctions,
|
|
231
|
+
...(isFile && { includePaths: [auditPath] }),
|
|
336
232
|
};
|
|
337
233
|
const runner = createAuditRunner(options);
|
|
338
234
|
const auditResult = await runner.run();
|
|
235
|
+
// Handle function indexing if enabled and functions were collected
|
|
236
|
+
let indexingResult = null;
|
|
237
|
+
if (indexFunctions && auditResult.metadata.fileToFunctionsMap) {
|
|
238
|
+
try {
|
|
239
|
+
const syncStats = { added: 0, updated: 0, removed: 0 };
|
|
240
|
+
// Sync each file's functions to handle additions, updates, and removals
|
|
241
|
+
for (const [filePath, functions] of Object.entries(auditResult.metadata.fileToFunctionsMap)) {
|
|
242
|
+
const fileStats = await syncFileIndex(filePath, functions);
|
|
243
|
+
syncStats.added += fileStats.added;
|
|
244
|
+
syncStats.updated += fileStats.updated;
|
|
245
|
+
syncStats.removed += fileStats.removed;
|
|
246
|
+
}
|
|
247
|
+
indexingResult = {
|
|
248
|
+
success: true,
|
|
249
|
+
registered: syncStats.added + syncStats.updated,
|
|
250
|
+
failed: 0,
|
|
251
|
+
syncStats
|
|
252
|
+
};
|
|
253
|
+
console.error(chalk.blue('[INFO]'), `Synced functions: ${syncStats.added} added, ${syncStats.updated} updated, ${syncStats.removed} removed`);
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
console.error(chalk.yellow('[WARN]'), 'Failed to sync functions:', error);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
339
259
|
// Format for MCP
|
|
340
260
|
result = {
|
|
341
261
|
summary: {
|
|
@@ -349,46 +269,47 @@ async function startMcpServer() {
|
|
|
349
269
|
},
|
|
350
270
|
violations: getAllViolations(auditResult).slice(0, 100), // Limit to first 100
|
|
351
271
|
recommendations: auditResult.recommendations,
|
|
272
|
+
...(indexingResult && { functionIndexing: indexingResult }),
|
|
352
273
|
};
|
|
353
274
|
break;
|
|
354
275
|
}
|
|
355
|
-
case '
|
|
356
|
-
const absolutePath = path.resolve(args.filePath);
|
|
357
|
-
await fs.access(absolutePath); // Check file exists
|
|
358
|
-
const options = {
|
|
359
|
-
projectRoot: path.dirname(absolutePath),
|
|
360
|
-
enabledAnalyzers: args.analyzers || ['solid', 'dry', 'security'],
|
|
361
|
-
includePaths: [absolutePath],
|
|
362
|
-
verbose: false,
|
|
363
|
-
};
|
|
364
|
-
const runner = createAuditRunner(options);
|
|
365
|
-
const auditResult = await runner.run();
|
|
366
|
-
const fileViolations = getAllViolations(auditResult).filter(v => v.file === absolutePath);
|
|
367
|
-
result = {
|
|
368
|
-
file: absolutePath,
|
|
369
|
-
violations: fileViolations,
|
|
370
|
-
summary: {
|
|
371
|
-
total: fileViolations.length,
|
|
372
|
-
bySeverity: fileViolations
|
|
373
|
-
.reduce((acc, v) => {
|
|
374
|
-
acc[v.severity] = (acc[v.severity] || 0) + 1;
|
|
375
|
-
return acc;
|
|
376
|
-
}, {}),
|
|
377
|
-
},
|
|
378
|
-
};
|
|
379
|
-
break;
|
|
380
|
-
}
|
|
381
|
-
case 'audit_check_health': {
|
|
276
|
+
case 'audit_health': {
|
|
382
277
|
const auditPath = path.resolve(args.path || process.cwd());
|
|
383
278
|
const threshold = args.threshold || 70;
|
|
279
|
+
const indexFunctions = args.indexFunctions !== false; // Default true
|
|
384
280
|
const runner = createAuditRunner({
|
|
385
281
|
projectRoot: auditPath,
|
|
386
282
|
enabledAnalyzers: ['solid', 'dry', 'security'],
|
|
387
283
|
minSeverity: 'warning',
|
|
388
284
|
verbose: false,
|
|
285
|
+
indexFunctions, // Pass the flag to the runner
|
|
389
286
|
});
|
|
390
287
|
const auditResult = await runner.run();
|
|
391
288
|
const healthScore = calculateHealthScore(auditResult);
|
|
289
|
+
// Handle function indexing if enabled and functions were collected
|
|
290
|
+
let indexingResult = null;
|
|
291
|
+
if (indexFunctions && auditResult.metadata.fileToFunctionsMap) {
|
|
292
|
+
try {
|
|
293
|
+
const syncStats = { added: 0, updated: 0, removed: 0 };
|
|
294
|
+
// Sync each file's functions to handle additions, updates, and removals
|
|
295
|
+
for (const [filePath, functions] of Object.entries(auditResult.metadata.fileToFunctionsMap)) {
|
|
296
|
+
const fileStats = await syncFileIndex(filePath, functions);
|
|
297
|
+
syncStats.added += fileStats.added;
|
|
298
|
+
syncStats.updated += fileStats.updated;
|
|
299
|
+
syncStats.removed += fileStats.removed;
|
|
300
|
+
}
|
|
301
|
+
indexingResult = {
|
|
302
|
+
success: true,
|
|
303
|
+
registered: syncStats.added + syncStats.updated,
|
|
304
|
+
failed: 0,
|
|
305
|
+
syncStats
|
|
306
|
+
};
|
|
307
|
+
console.error(chalk.blue('[INFO]'), `Synced functions: ${syncStats.added} added, ${syncStats.updated} updated, ${syncStats.removed} removed`);
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
console.error(chalk.yellow('[WARN]'), 'Failed to sync functions:', error);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
392
313
|
result = {
|
|
393
314
|
healthScore,
|
|
394
315
|
threshold,
|
|
@@ -401,82 +322,11 @@ async function startMcpServer() {
|
|
|
401
322
|
warningViolations: auditResult.summary.warnings,
|
|
402
323
|
},
|
|
403
324
|
recommendation: getHealthRecommendation(healthScore, auditResult),
|
|
325
|
+
...(indexingResult && { functionIndexing: indexingResult }),
|
|
404
326
|
};
|
|
405
327
|
break;
|
|
406
328
|
}
|
|
407
|
-
case '
|
|
408
|
-
result = {
|
|
409
|
-
analyzers: [
|
|
410
|
-
{
|
|
411
|
-
id: 'solid',
|
|
412
|
-
name: 'SOLID Analyzer',
|
|
413
|
-
description: 'Checks adherence to SOLID principles',
|
|
414
|
-
checks: [
|
|
415
|
-
'Single Responsibility violations',
|
|
416
|
-
'Open/Closed violations',
|
|
417
|
-
'Liskov Substitution issues',
|
|
418
|
-
'Interface Segregation problems',
|
|
419
|
-
'Dependency Inversion violations',
|
|
420
|
-
],
|
|
421
|
-
},
|
|
422
|
-
{
|
|
423
|
-
id: 'dry',
|
|
424
|
-
name: 'DRY Analyzer',
|
|
425
|
-
description: 'Identifies code duplication',
|
|
426
|
-
checks: [
|
|
427
|
-
'Exact code duplicates',
|
|
428
|
-
'Similar code patterns',
|
|
429
|
-
'Duplicate imports',
|
|
430
|
-
'Repeated string literals',
|
|
431
|
-
],
|
|
432
|
-
},
|
|
433
|
-
{
|
|
434
|
-
id: 'security',
|
|
435
|
-
name: 'Security Analyzer',
|
|
436
|
-
description: 'Verifies security patterns',
|
|
437
|
-
checks: [
|
|
438
|
-
'Missing authentication',
|
|
439
|
-
'Authorization issues',
|
|
440
|
-
'SQL injection risks',
|
|
441
|
-
'Unvalidated inputs',
|
|
442
|
-
],
|
|
443
|
-
},
|
|
444
|
-
{
|
|
445
|
-
id: 'component',
|
|
446
|
-
name: 'Component Analyzer',
|
|
447
|
-
description: 'Analyzes UI components',
|
|
448
|
-
checks: [
|
|
449
|
-
'Missing error boundaries',
|
|
450
|
-
'Complex render methods',
|
|
451
|
-
'Deep nesting',
|
|
452
|
-
'Performance issues',
|
|
453
|
-
],
|
|
454
|
-
},
|
|
455
|
-
{
|
|
456
|
-
id: 'data-access',
|
|
457
|
-
name: 'Data Access Analyzer',
|
|
458
|
-
description: 'Reviews database patterns',
|
|
459
|
-
checks: [
|
|
460
|
-
'N+1 queries',
|
|
461
|
-
'Missing transactions',
|
|
462
|
-
'Direct DB access in UI',
|
|
463
|
-
'Performance issues',
|
|
464
|
-
],
|
|
465
|
-
},
|
|
466
|
-
],
|
|
467
|
-
};
|
|
468
|
-
break;
|
|
469
|
-
}
|
|
470
|
-
case 'register_functions': {
|
|
471
|
-
const functions = args.functions;
|
|
472
|
-
const overwrite = args.overwrite || false;
|
|
473
|
-
if (!Array.isArray(functions)) {
|
|
474
|
-
throw new Error('functions must be an array');
|
|
475
|
-
}
|
|
476
|
-
result = await registerFunctions(functions, { overwrite });
|
|
477
|
-
break;
|
|
478
|
-
}
|
|
479
|
-
case 'search_functions': {
|
|
329
|
+
case 'search_code': {
|
|
480
330
|
const query = args.query;
|
|
481
331
|
const filters = args.filters;
|
|
482
332
|
const limit = args.limit || 50;
|
|
@@ -493,36 +343,6 @@ async function startMcpServer() {
|
|
|
493
343
|
});
|
|
494
344
|
break;
|
|
495
345
|
}
|
|
496
|
-
case 'index_functions': {
|
|
497
|
-
const targetPath = path.resolve(args.path);
|
|
498
|
-
const recursive = args.recursive !== false;
|
|
499
|
-
const fileTypes = args.fileTypes || ['.ts', '.tsx', '.js', '.jsx'];
|
|
500
|
-
const stats = await fs.stat(targetPath);
|
|
501
|
-
if (stats.isFile()) {
|
|
502
|
-
// For single files, use sync to handle additions/updates/removals
|
|
503
|
-
const functions = await scanFunctionsInFile(targetPath);
|
|
504
|
-
const syncResult = await syncFileIndex(targetPath, functions);
|
|
505
|
-
result = {
|
|
506
|
-
success: true,
|
|
507
|
-
registered: syncResult.added + syncResult.updated,
|
|
508
|
-
failed: 0,
|
|
509
|
-
path: targetPath,
|
|
510
|
-
totalScanned: functions.length,
|
|
511
|
-
syncStats: syncResult
|
|
512
|
-
};
|
|
513
|
-
}
|
|
514
|
-
else {
|
|
515
|
-
// For directories, use regular registration (could be improved later)
|
|
516
|
-
const functions = await scanFunctionsInDirectory(targetPath, { recursive, fileTypes });
|
|
517
|
-
const registerResult = await registerFunctions(functions);
|
|
518
|
-
result = {
|
|
519
|
-
...registerResult,
|
|
520
|
-
path: targetPath,
|
|
521
|
-
totalScanned: functions.length,
|
|
522
|
-
};
|
|
523
|
-
}
|
|
524
|
-
break;
|
|
525
|
-
}
|
|
526
346
|
case 'find_definition': {
|
|
527
347
|
const name = args.name;
|
|
528
348
|
const filePath = args.filePath;
|
|
@@ -533,20 +353,7 @@ async function startMcpServer() {
|
|
|
533
353
|
result = definition || { error: 'Function not found' };
|
|
534
354
|
break;
|
|
535
355
|
}
|
|
536
|
-
case '
|
|
537
|
-
result = await getIndexStats();
|
|
538
|
-
break;
|
|
539
|
-
}
|
|
540
|
-
case 'clear_index': {
|
|
541
|
-
const confirm = args.confirm;
|
|
542
|
-
if (!confirm) {
|
|
543
|
-
throw new Error('Please set confirm: true to clear the index');
|
|
544
|
-
}
|
|
545
|
-
await clearIndex();
|
|
546
|
-
result = { message: 'Index cleared successfully' };
|
|
547
|
-
break;
|
|
548
|
-
}
|
|
549
|
-
case 'generate_ai_configs': {
|
|
356
|
+
case 'generate_ai_config': {
|
|
550
357
|
const tools = args.tools;
|
|
551
358
|
const serverUrl = args.serverUrl || DEFAULT_SERVER_URL;
|
|
552
359
|
const outputDir = args.outputDir || '.';
|
|
@@ -607,121 +414,63 @@ async function startMcpServer() {
|
|
|
607
414
|
};
|
|
608
415
|
break;
|
|
609
416
|
}
|
|
610
|
-
case '
|
|
611
|
-
const
|
|
612
|
-
const
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
417
|
+
case 'sync_index': {
|
|
418
|
+
const mode = args.mode || 'sync';
|
|
419
|
+
const targetPath = args.path;
|
|
420
|
+
const db = CodeIndexDB.getInstance();
|
|
421
|
+
await db.initialize();
|
|
422
|
+
switch (mode) {
|
|
423
|
+
case 'cleanup': {
|
|
424
|
+
const cleanupResult = await db.bulkCleanup();
|
|
425
|
+
result = {
|
|
426
|
+
mode: 'cleanup',
|
|
427
|
+
success: true,
|
|
428
|
+
scannedFiles: cleanupResult.scannedCount,
|
|
429
|
+
removedEntries: cleanupResult.removedCount,
|
|
430
|
+
removedFiles: cleanupResult.removedFiles,
|
|
431
|
+
errors: cleanupResult.errors,
|
|
432
|
+
message: `Cleaned up ${cleanupResult.removedCount} entries from ${cleanupResult.removedFiles.length} deleted files`
|
|
433
|
+
};
|
|
434
|
+
break;
|
|
619
435
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
instructions: generator.getInstructions(),
|
|
641
|
-
sampleConfig: JSON.parse(config.content)
|
|
642
|
-
};
|
|
643
|
-
break;
|
|
644
|
-
}
|
|
645
|
-
case 'validate_ai_config': {
|
|
646
|
-
const toolName = args.tool;
|
|
647
|
-
const config = args.config;
|
|
648
|
-
if (!toolName) {
|
|
649
|
-
throw new Error('tool parameter is required');
|
|
650
|
-
}
|
|
651
|
-
if (!config) {
|
|
652
|
-
throw new Error('config parameter is required');
|
|
653
|
-
}
|
|
654
|
-
const factory = new ConfigGeneratorFactory();
|
|
655
|
-
const generator = factory.createGenerator(toolName);
|
|
656
|
-
if (!generator) {
|
|
657
|
-
throw new Error(`Unknown tool: ${toolName}`);
|
|
658
|
-
}
|
|
659
|
-
// Generate reference config to compare structure
|
|
660
|
-
const referenceConfig = generator.generateConfig();
|
|
661
|
-
const reference = JSON.parse(referenceConfig.content);
|
|
662
|
-
// Basic validation - check if main structure matches
|
|
663
|
-
const errors = [];
|
|
664
|
-
const validateObject = (ref, actual, path = '') => {
|
|
665
|
-
for (const key in ref) {
|
|
666
|
-
const currentPath = path ? `${path}.${key}` : key;
|
|
667
|
-
if (!(key in actual)) {
|
|
668
|
-
errors.push(`Missing required field: ${currentPath}`);
|
|
436
|
+
case 'reset': {
|
|
437
|
+
await db.clearIndex();
|
|
438
|
+
result = {
|
|
439
|
+
mode: 'reset',
|
|
440
|
+
success: true,
|
|
441
|
+
message: 'Index cleared successfully'
|
|
442
|
+
};
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
case 'sync':
|
|
446
|
+
default: {
|
|
447
|
+
if (targetPath) {
|
|
448
|
+
// Sync specific file
|
|
449
|
+
const syncResult = await db.synchronizeFile(path.resolve(targetPath));
|
|
450
|
+
result = {
|
|
451
|
+
mode: 'sync',
|
|
452
|
+
success: true,
|
|
453
|
+
path: targetPath,
|
|
454
|
+
...(syncResult || { message: 'File not found' })
|
|
455
|
+
};
|
|
669
456
|
}
|
|
670
|
-
else
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
457
|
+
else {
|
|
458
|
+
// Deep sync all files
|
|
459
|
+
const syncResult = await db.deepSync();
|
|
460
|
+
result = {
|
|
461
|
+
mode: 'sync',
|
|
462
|
+
success: true,
|
|
463
|
+
syncedFiles: syncResult.syncedFiles,
|
|
464
|
+
addedFunctions: syncResult.addedFunctions,
|
|
465
|
+
updatedFunctions: syncResult.updatedFunctions,
|
|
466
|
+
removedFunctions: syncResult.removedFunctions,
|
|
467
|
+
errors: syncResult.errors,
|
|
468
|
+
message: `Synced ${syncResult.syncedFiles} files: ${syncResult.addedFunctions} added, ${syncResult.updatedFunctions} updated, ${syncResult.removedFunctions} removed`
|
|
469
|
+
};
|
|
677
470
|
}
|
|
471
|
+
break;
|
|
678
472
|
}
|
|
679
|
-
}
|
|
680
|
-
validateObject(reference, config);
|
|
681
|
-
result = {
|
|
682
|
-
valid: errors.length === 0,
|
|
683
|
-
tool: toolName,
|
|
684
|
-
errors: errors.length > 0 ? errors : undefined,
|
|
685
|
-
warnings: [] // Could add warnings for extra fields, deprecated settings, etc.
|
|
686
|
-
};
|
|
687
|
-
break;
|
|
688
|
-
}
|
|
689
|
-
case 'bulk_cleanup': {
|
|
690
|
-
const db = CodeIndexDB.getInstance();
|
|
691
|
-
await db.initialize();
|
|
692
|
-
const cleanupResult = await db.bulkCleanup();
|
|
693
|
-
result = {
|
|
694
|
-
success: true,
|
|
695
|
-
scannedFiles: cleanupResult.scannedCount,
|
|
696
|
-
removedEntries: cleanupResult.removedCount,
|
|
697
|
-
removedFiles: cleanupResult.removedFiles,
|
|
698
|
-
errors: cleanupResult.errors,
|
|
699
|
-
message: `Cleaned up ${cleanupResult.removedCount} entries from ${cleanupResult.removedFiles.length} deleted files`
|
|
700
|
-
};
|
|
701
|
-
break;
|
|
702
|
-
}
|
|
703
|
-
case 'deep_sync': {
|
|
704
|
-
const db = CodeIndexDB.getInstance();
|
|
705
|
-
await db.initialize();
|
|
706
|
-
// Progress tracking
|
|
707
|
-
const progressUpdates = [];
|
|
708
|
-
const syncResult = await db.deepSync((progress) => {
|
|
709
|
-
progressUpdates.push({
|
|
710
|
-
current: progress.current,
|
|
711
|
-
total: progress.total,
|
|
712
|
-
file: progress.file,
|
|
713
|
-
percentage: Math.round((progress.current / progress.total) * 100)
|
|
714
|
-
});
|
|
715
|
-
});
|
|
716
|
-
result = {
|
|
717
|
-
success: true,
|
|
718
|
-
syncedFiles: syncResult.syncedFiles,
|
|
719
|
-
addedFunctions: syncResult.addedFunctions,
|
|
720
|
-
updatedFunctions: syncResult.updatedFunctions,
|
|
721
|
-
removedFunctions: syncResult.removedFunctions,
|
|
722
|
-
errors: syncResult.errors,
|
|
723
|
-
message: `Synced ${syncResult.syncedFiles} files: ${syncResult.addedFunctions} added, ${syncResult.updatedFunctions} updated, ${syncResult.removedFunctions} removed`
|
|
724
|
-
};
|
|
473
|
+
}
|
|
725
474
|
break;
|
|
726
475
|
}
|
|
727
476
|
default:
|