@optave/codegraph 2.5.0 → 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/README.md +119 -47
- package/package.json +8 -7
- package/src/audit.js +423 -0
- package/src/batch.js +90 -0
- package/src/boundaries.js +346 -0
- package/src/branch-compare.js +568 -0
- package/src/builder.js +66 -2
- package/src/check.js +432 -0
- package/src/cli.js +375 -9
- package/src/cochange.js +5 -2
- package/src/communities.js +7 -1
- package/src/complexity.js +116 -9
- package/src/config.js +10 -0
- package/src/embedder.js +350 -38
- package/src/flow.js +4 -4
- package/src/index.js +28 -1
- package/src/manifesto.js +69 -1
- package/src/mcp.js +347 -19
- package/src/owners.js +359 -0
- package/src/paginate.js +35 -0
- package/src/queries.js +233 -19
- package/src/registry.js +6 -3
- package/src/snapshot.js +149 -0
- package/src/structure.js +5 -2
- package/src/triage.js +273 -0
package/src/mcp.js
CHANGED
|
@@ -50,6 +50,7 @@ const BASE_TOOLS = [
|
|
|
50
50
|
properties: {
|
|
51
51
|
file: { type: 'string', description: 'File path (partial match supported)' },
|
|
52
52
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
53
|
+
...PAGINATION_PROPS,
|
|
53
54
|
},
|
|
54
55
|
required: ['file'],
|
|
55
56
|
},
|
|
@@ -62,6 +63,7 @@ const BASE_TOOLS = [
|
|
|
62
63
|
properties: {
|
|
63
64
|
file: { type: 'string', description: 'File path to analyze' },
|
|
64
65
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
66
|
+
...PAGINATION_PROPS,
|
|
65
67
|
},
|
|
66
68
|
required: ['file'],
|
|
67
69
|
},
|
|
@@ -103,6 +105,7 @@ const BASE_TOOLS = [
|
|
|
103
105
|
description: 'Filter to a specific symbol kind',
|
|
104
106
|
},
|
|
105
107
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
108
|
+
...PAGINATION_PROPS,
|
|
106
109
|
},
|
|
107
110
|
required: ['name'],
|
|
108
111
|
},
|
|
@@ -126,6 +129,7 @@ const BASE_TOOLS = [
|
|
|
126
129
|
description: 'Filter to a specific symbol kind',
|
|
127
130
|
},
|
|
128
131
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
132
|
+
...PAGINATION_PROPS,
|
|
129
133
|
},
|
|
130
134
|
required: ['name'],
|
|
131
135
|
},
|
|
@@ -190,6 +194,7 @@ const BASE_TOOLS = [
|
|
|
190
194
|
description: 'Include test file source code',
|
|
191
195
|
default: false,
|
|
192
196
|
},
|
|
197
|
+
...PAGINATION_PROPS,
|
|
193
198
|
},
|
|
194
199
|
required: ['name'],
|
|
195
200
|
},
|
|
@@ -203,6 +208,7 @@ const BASE_TOOLS = [
|
|
|
203
208
|
properties: {
|
|
204
209
|
target: { type: 'string', description: 'File path or function name' },
|
|
205
210
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
211
|
+
...PAGINATION_PROPS,
|
|
206
212
|
},
|
|
207
213
|
required: ['target'],
|
|
208
214
|
},
|
|
@@ -241,19 +247,27 @@ const BASE_TOOLS = [
|
|
|
241
247
|
enum: ['json', 'mermaid'],
|
|
242
248
|
description: 'Output format (default: json)',
|
|
243
249
|
},
|
|
250
|
+
...PAGINATION_PROPS,
|
|
244
251
|
},
|
|
245
252
|
},
|
|
246
253
|
},
|
|
247
254
|
{
|
|
248
255
|
name: 'semantic_search',
|
|
249
256
|
description:
|
|
250
|
-
'Search code symbols by meaning using embeddings (requires prior `codegraph embed`)',
|
|
257
|
+
'Search code symbols by meaning using embeddings and/or keyword matching (requires prior `codegraph embed`). Default hybrid mode combines BM25 keyword + semantic search for best results.',
|
|
251
258
|
inputSchema: {
|
|
252
259
|
type: 'object',
|
|
253
260
|
properties: {
|
|
254
261
|
query: { type: 'string', description: 'Natural language search query' },
|
|
255
262
|
limit: { type: 'number', description: 'Max results to return', default: 15 },
|
|
256
263
|
min_score: { type: 'number', description: 'Minimum similarity score (0-1)', default: 0.2 },
|
|
264
|
+
mode: {
|
|
265
|
+
type: 'string',
|
|
266
|
+
enum: ['hybrid', 'semantic', 'keyword'],
|
|
267
|
+
description:
|
|
268
|
+
'Search mode: hybrid (BM25 + semantic, default), semantic (embeddings only), keyword (BM25 only)',
|
|
269
|
+
},
|
|
270
|
+
...PAGINATION_PROPS,
|
|
257
271
|
},
|
|
258
272
|
required: ['query'],
|
|
259
273
|
},
|
|
@@ -312,6 +326,7 @@ const BASE_TOOLS = [
|
|
|
312
326
|
description: 'Return all files without limit',
|
|
313
327
|
default: false,
|
|
314
328
|
},
|
|
329
|
+
...PAGINATION_PROPS,
|
|
315
330
|
},
|
|
316
331
|
},
|
|
317
332
|
},
|
|
@@ -352,6 +367,7 @@ const BASE_TOOLS = [
|
|
|
352
367
|
},
|
|
353
368
|
limit: { type: 'number', description: 'Number of results to return', default: 10 },
|
|
354
369
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
370
|
+
offset: { type: 'number', description: 'Skip this many results (pagination, default: 0)' },
|
|
355
371
|
},
|
|
356
372
|
},
|
|
357
373
|
},
|
|
@@ -373,6 +389,7 @@ const BASE_TOOLS = [
|
|
|
373
389
|
default: 0.3,
|
|
374
390
|
},
|
|
375
391
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
392
|
+
offset: { type: 'number', description: 'Skip this many results (pagination, default: 0)' },
|
|
376
393
|
},
|
|
377
394
|
},
|
|
378
395
|
},
|
|
@@ -399,6 +416,7 @@ const BASE_TOOLS = [
|
|
|
399
416
|
description: 'Filter to a specific symbol kind',
|
|
400
417
|
},
|
|
401
418
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
419
|
+
...PAGINATION_PROPS,
|
|
402
420
|
},
|
|
403
421
|
required: ['name'],
|
|
404
422
|
},
|
|
@@ -446,6 +464,7 @@ const BASE_TOOLS = [
|
|
|
446
464
|
type: 'string',
|
|
447
465
|
description: 'Filter by symbol kind (function, method, class, etc.)',
|
|
448
466
|
},
|
|
467
|
+
offset: { type: 'number', description: 'Skip this many results (pagination, default: 0)' },
|
|
449
468
|
},
|
|
450
469
|
},
|
|
451
470
|
},
|
|
@@ -462,6 +481,7 @@ const BASE_TOOLS = [
|
|
|
462
481
|
type: 'string',
|
|
463
482
|
description: 'Filter by symbol kind (function, method, class, etc.)',
|
|
464
483
|
},
|
|
484
|
+
...PAGINATION_PROPS,
|
|
465
485
|
},
|
|
466
486
|
},
|
|
467
487
|
},
|
|
@@ -488,6 +508,172 @@ const BASE_TOOLS = [
|
|
|
488
508
|
default: false,
|
|
489
509
|
},
|
|
490
510
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
511
|
+
...PAGINATION_PROPS,
|
|
512
|
+
},
|
|
513
|
+
},
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
name: 'code_owners',
|
|
517
|
+
description:
|
|
518
|
+
'Show CODEOWNERS mapping for files and functions. Shows ownership coverage, per-owner breakdown, and cross-owner boundary edges.',
|
|
519
|
+
inputSchema: {
|
|
520
|
+
type: 'object',
|
|
521
|
+
properties: {
|
|
522
|
+
file: { type: 'string', description: 'Scope to a specific file (partial match)' },
|
|
523
|
+
owner: { type: 'string', description: 'Filter to a specific owner (e.g. @team-name)' },
|
|
524
|
+
boundary: {
|
|
525
|
+
type: 'boolean',
|
|
526
|
+
description: 'Show cross-owner boundary edges',
|
|
527
|
+
default: false,
|
|
528
|
+
},
|
|
529
|
+
kind: {
|
|
530
|
+
type: 'string',
|
|
531
|
+
description: 'Filter by symbol kind (function, method, class, etc.)',
|
|
532
|
+
},
|
|
533
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
534
|
+
},
|
|
535
|
+
},
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
name: 'audit',
|
|
539
|
+
description:
|
|
540
|
+
'Composite report combining explain, fn-impact, and health metrics for a file or function. Returns structure, blast radius, complexity, and threshold breaches in one call.',
|
|
541
|
+
inputSchema: {
|
|
542
|
+
type: 'object',
|
|
543
|
+
properties: {
|
|
544
|
+
target: { type: 'string', description: 'File path or function name' },
|
|
545
|
+
depth: { type: 'number', description: 'Impact analysis depth (default: 3)', default: 3 },
|
|
546
|
+
file: { type: 'string', description: 'Scope to file (partial match)' },
|
|
547
|
+
kind: {
|
|
548
|
+
type: 'string',
|
|
549
|
+
description: 'Filter by symbol kind (function, method, class, etc.)',
|
|
550
|
+
},
|
|
551
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
552
|
+
},
|
|
553
|
+
required: ['target'],
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
name: 'batch_query',
|
|
558
|
+
description:
|
|
559
|
+
'Run a query command against multiple targets in one call. Returns all results in a single JSON payload — ideal for multi-agent dispatch.',
|
|
560
|
+
inputSchema: {
|
|
561
|
+
type: 'object',
|
|
562
|
+
properties: {
|
|
563
|
+
command: {
|
|
564
|
+
type: 'string',
|
|
565
|
+
enum: [
|
|
566
|
+
'fn-impact',
|
|
567
|
+
'context',
|
|
568
|
+
'explain',
|
|
569
|
+
'where',
|
|
570
|
+
'query',
|
|
571
|
+
'fn',
|
|
572
|
+
'impact',
|
|
573
|
+
'deps',
|
|
574
|
+
'flow',
|
|
575
|
+
'complexity',
|
|
576
|
+
],
|
|
577
|
+
description: 'The query command to run for each target',
|
|
578
|
+
},
|
|
579
|
+
targets: {
|
|
580
|
+
type: 'array',
|
|
581
|
+
items: { type: 'string' },
|
|
582
|
+
description: 'List of target names (symbol names or file paths depending on command)',
|
|
583
|
+
},
|
|
584
|
+
depth: {
|
|
585
|
+
type: 'number',
|
|
586
|
+
description: 'Traversal depth (for fn-impact, context, fn, flow)',
|
|
587
|
+
},
|
|
588
|
+
file: {
|
|
589
|
+
type: 'string',
|
|
590
|
+
description: 'Scope to file (partial match)',
|
|
591
|
+
},
|
|
592
|
+
kind: {
|
|
593
|
+
type: 'string',
|
|
594
|
+
enum: ALL_SYMBOL_KINDS,
|
|
595
|
+
description: 'Filter symbol kind',
|
|
596
|
+
},
|
|
597
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
598
|
+
},
|
|
599
|
+
required: ['command', 'targets'],
|
|
600
|
+
},
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
name: 'triage',
|
|
604
|
+
description:
|
|
605
|
+
'Ranked audit queue by composite risk score. Merges connectivity (fan-in), complexity (cognitive), churn (commit count), role classification, and maintainability index into a single weighted score.',
|
|
606
|
+
inputSchema: {
|
|
607
|
+
type: 'object',
|
|
608
|
+
properties: {
|
|
609
|
+
sort: {
|
|
610
|
+
type: 'string',
|
|
611
|
+
enum: ['risk', 'complexity', 'churn', 'fan-in', 'mi'],
|
|
612
|
+
description: 'Sort metric (default: risk)',
|
|
613
|
+
},
|
|
614
|
+
min_score: {
|
|
615
|
+
type: 'number',
|
|
616
|
+
description: 'Only return symbols with risk score >= this threshold (0-1)',
|
|
617
|
+
},
|
|
618
|
+
role: {
|
|
619
|
+
type: 'string',
|
|
620
|
+
enum: VALID_ROLES,
|
|
621
|
+
description: 'Filter by role classification',
|
|
622
|
+
},
|
|
623
|
+
file: { type: 'string', description: 'Scope to file (partial match)' },
|
|
624
|
+
kind: {
|
|
625
|
+
type: 'string',
|
|
626
|
+
enum: ['function', 'method', 'class'],
|
|
627
|
+
description: 'Filter by symbol kind',
|
|
628
|
+
},
|
|
629
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
630
|
+
weights: {
|
|
631
|
+
type: 'object',
|
|
632
|
+
description:
|
|
633
|
+
'Custom scoring weights (e.g. {"fanIn":1,"complexity":0,"churn":0,"role":0,"mi":0})',
|
|
634
|
+
},
|
|
635
|
+
...PAGINATION_PROPS,
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
name: 'branch_compare',
|
|
641
|
+
description:
|
|
642
|
+
'Compare code structure between two git refs (branches, tags, commits). Shows added/removed/changed symbols and transitive caller impact using temporary git worktrees.',
|
|
643
|
+
inputSchema: {
|
|
644
|
+
type: 'object',
|
|
645
|
+
properties: {
|
|
646
|
+
base: { type: 'string', description: 'Base git ref (branch, tag, or commit SHA)' },
|
|
647
|
+
target: { type: 'string', description: 'Target git ref to compare against base' },
|
|
648
|
+
depth: { type: 'number', description: 'Max transitive caller depth', default: 3 },
|
|
649
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
650
|
+
format: {
|
|
651
|
+
type: 'string',
|
|
652
|
+
enum: ['json', 'mermaid'],
|
|
653
|
+
description: 'Output format (default: json)',
|
|
654
|
+
},
|
|
655
|
+
},
|
|
656
|
+
required: ['base', 'target'],
|
|
657
|
+
},
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
name: 'check',
|
|
661
|
+
description:
|
|
662
|
+
'Run CI validation predicates against git changes. Checks for new cycles, blast radius violations, signature changes, and boundary violations. Returns pass/fail per predicate — ideal for CI gates.',
|
|
663
|
+
inputSchema: {
|
|
664
|
+
type: 'object',
|
|
665
|
+
properties: {
|
|
666
|
+
ref: { type: 'string', description: 'Git ref to diff against (default: HEAD)' },
|
|
667
|
+
staged: { type: 'boolean', description: 'Analyze staged changes instead of unstaged' },
|
|
668
|
+
cycles: { type: 'boolean', description: 'Enable cycles predicate (default: true)' },
|
|
669
|
+
blast_radius: {
|
|
670
|
+
type: 'number',
|
|
671
|
+
description: 'Max transitive callers threshold (null = disabled)',
|
|
672
|
+
},
|
|
673
|
+
signatures: { type: 'boolean', description: 'Enable signatures predicate (default: true)' },
|
|
674
|
+
boundaries: { type: 'boolean', description: 'Enable boundaries predicate (default: true)' },
|
|
675
|
+
depth: { type: 'number', description: 'Max BFS depth for blast radius (default: 3)' },
|
|
676
|
+
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
491
677
|
},
|
|
492
678
|
},
|
|
493
679
|
},
|
|
@@ -623,10 +809,18 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
623
809
|
});
|
|
624
810
|
break;
|
|
625
811
|
case 'file_deps':
|
|
626
|
-
result = fileDepsData(args.file, dbPath, {
|
|
812
|
+
result = fileDepsData(args.file, dbPath, {
|
|
813
|
+
noTests: args.no_tests,
|
|
814
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.file_deps, MCP_MAX_LIMIT),
|
|
815
|
+
offset: args.offset ?? 0,
|
|
816
|
+
});
|
|
627
817
|
break;
|
|
628
818
|
case 'impact_analysis':
|
|
629
|
-
result = impactAnalysisData(args.file, dbPath, {
|
|
819
|
+
result = impactAnalysisData(args.file, dbPath, {
|
|
820
|
+
noTests: args.no_tests,
|
|
821
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.impact_analysis, MCP_MAX_LIMIT),
|
|
822
|
+
offset: args.offset ?? 0,
|
|
823
|
+
});
|
|
630
824
|
break;
|
|
631
825
|
case 'find_cycles': {
|
|
632
826
|
const db = new Database(findDbPath(dbPath), { readonly: true });
|
|
@@ -644,6 +838,8 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
644
838
|
file: args.file,
|
|
645
839
|
kind: args.kind,
|
|
646
840
|
noTests: args.no_tests,
|
|
841
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.fn_deps, MCP_MAX_LIMIT),
|
|
842
|
+
offset: args.offset ?? 0,
|
|
647
843
|
});
|
|
648
844
|
break;
|
|
649
845
|
case 'fn_impact':
|
|
@@ -652,6 +848,8 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
652
848
|
file: args.file,
|
|
653
849
|
kind: args.kind,
|
|
654
850
|
noTests: args.no_tests,
|
|
851
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.fn_impact, MCP_MAX_LIMIT),
|
|
852
|
+
offset: args.offset ?? 0,
|
|
655
853
|
});
|
|
656
854
|
break;
|
|
657
855
|
case 'symbol_path':
|
|
@@ -673,10 +871,16 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
673
871
|
noSource: args.no_source,
|
|
674
872
|
noTests: args.no_tests,
|
|
675
873
|
includeTests: args.include_tests,
|
|
874
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.context, MCP_MAX_LIMIT),
|
|
875
|
+
offset: args.offset ?? 0,
|
|
676
876
|
});
|
|
677
877
|
break;
|
|
678
878
|
case 'explain':
|
|
679
|
-
result = explainData(args.target, dbPath, {
|
|
879
|
+
result = explainData(args.target, dbPath, {
|
|
880
|
+
noTests: args.no_tests,
|
|
881
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.explain, MCP_MAX_LIMIT),
|
|
882
|
+
offset: args.offset ?? 0,
|
|
883
|
+
});
|
|
680
884
|
break;
|
|
681
885
|
case 'where':
|
|
682
886
|
result = whereData(args.target, dbPath, {
|
|
@@ -700,22 +904,65 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
700
904
|
ref: args.ref,
|
|
701
905
|
depth: args.depth,
|
|
702
906
|
noTests: args.no_tests,
|
|
907
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.diff_impact, MCP_MAX_LIMIT),
|
|
908
|
+
offset: args.offset ?? 0,
|
|
703
909
|
});
|
|
704
910
|
}
|
|
705
911
|
break;
|
|
706
912
|
case 'semantic_search': {
|
|
707
|
-
const
|
|
708
|
-
|
|
709
|
-
limit: args.limit,
|
|
913
|
+
const mode = args.mode || 'hybrid';
|
|
914
|
+
const searchOpts = {
|
|
915
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.semantic_search, MCP_MAX_LIMIT),
|
|
916
|
+
offset: args.offset ?? 0,
|
|
710
917
|
minScore: args.min_score,
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
if (mode === 'keyword') {
|
|
921
|
+
const { ftsSearchData } = await import('./embedder.js');
|
|
922
|
+
result = ftsSearchData(args.query, dbPath, searchOpts);
|
|
923
|
+
if (result === null) {
|
|
924
|
+
return {
|
|
925
|
+
content: [
|
|
926
|
+
{
|
|
927
|
+
type: 'text',
|
|
928
|
+
text: 'No FTS5 index found. Run `codegraph embed` to build the keyword index.',
|
|
929
|
+
},
|
|
930
|
+
],
|
|
931
|
+
isError: true,
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
} else if (mode === 'semantic') {
|
|
935
|
+
const { searchData } = await import('./embedder.js');
|
|
936
|
+
result = await searchData(args.query, dbPath, searchOpts);
|
|
937
|
+
if (result === null) {
|
|
938
|
+
return {
|
|
939
|
+
content: [
|
|
940
|
+
{
|
|
941
|
+
type: 'text',
|
|
942
|
+
text: 'Semantic search unavailable. Run `codegraph embed` first.',
|
|
943
|
+
},
|
|
944
|
+
],
|
|
945
|
+
isError: true,
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
} else {
|
|
949
|
+
// hybrid (default) — falls back to semantic if no FTS5
|
|
950
|
+
const { hybridSearchData, searchData } = await import('./embedder.js');
|
|
951
|
+
result = await hybridSearchData(args.query, dbPath, searchOpts);
|
|
952
|
+
if (result === null) {
|
|
953
|
+
result = await searchData(args.query, dbPath, searchOpts);
|
|
954
|
+
if (result === null) {
|
|
955
|
+
return {
|
|
956
|
+
content: [
|
|
957
|
+
{
|
|
958
|
+
type: 'text',
|
|
959
|
+
text: 'Semantic search unavailable. Run `codegraph embed` first.',
|
|
960
|
+
},
|
|
961
|
+
],
|
|
962
|
+
isError: true,
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
}
|
|
719
966
|
}
|
|
720
967
|
break;
|
|
721
968
|
}
|
|
@@ -779,6 +1026,8 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
779
1026
|
depth: args.depth,
|
|
780
1027
|
sort: args.sort,
|
|
781
1028
|
full: args.full,
|
|
1029
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.structure, MCP_MAX_LIMIT),
|
|
1030
|
+
offset: args.offset ?? 0,
|
|
782
1031
|
});
|
|
783
1032
|
break;
|
|
784
1033
|
}
|
|
@@ -787,7 +1036,8 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
787
1036
|
result = hotspotsData(dbPath, {
|
|
788
1037
|
metric: args.metric,
|
|
789
1038
|
level: args.level,
|
|
790
|
-
limit: args.limit,
|
|
1039
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.hotspots, MCP_MAX_LIMIT),
|
|
1040
|
+
offset: args.offset ?? 0,
|
|
791
1041
|
noTests: args.no_tests,
|
|
792
1042
|
});
|
|
793
1043
|
break;
|
|
@@ -796,12 +1046,14 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
796
1046
|
const { coChangeData, coChangeTopData } = await import('./cochange.js');
|
|
797
1047
|
result = args.file
|
|
798
1048
|
? coChangeData(args.file, dbPath, {
|
|
799
|
-
limit: args.limit,
|
|
1049
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.co_changes, MCP_MAX_LIMIT),
|
|
1050
|
+
offset: args.offset ?? 0,
|
|
800
1051
|
minJaccard: args.min_jaccard,
|
|
801
1052
|
noTests: args.no_tests,
|
|
802
1053
|
})
|
|
803
1054
|
: coChangeTopData(dbPath, {
|
|
804
|
-
limit: args.limit,
|
|
1055
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.co_changes, MCP_MAX_LIMIT),
|
|
1056
|
+
offset: args.offset ?? 0,
|
|
805
1057
|
minJaccard: args.min_jaccard,
|
|
806
1058
|
noTests: args.no_tests,
|
|
807
1059
|
});
|
|
@@ -814,6 +1066,8 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
814
1066
|
file: args.file,
|
|
815
1067
|
kind: args.kind,
|
|
816
1068
|
noTests: args.no_tests,
|
|
1069
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.execution_flow, MCP_MAX_LIMIT),
|
|
1070
|
+
offset: args.offset ?? 0,
|
|
817
1071
|
});
|
|
818
1072
|
break;
|
|
819
1073
|
}
|
|
@@ -831,7 +1085,8 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
831
1085
|
result = complexityData(dbPath, {
|
|
832
1086
|
target: args.name,
|
|
833
1087
|
file: args.file,
|
|
834
|
-
limit: args.limit,
|
|
1088
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.complexity, MCP_MAX_LIMIT),
|
|
1089
|
+
offset: args.offset ?? 0,
|
|
835
1090
|
sort: args.sort,
|
|
836
1091
|
aboveThreshold: args.above_threshold,
|
|
837
1092
|
health: args.health,
|
|
@@ -846,6 +1101,8 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
846
1101
|
file: args.file,
|
|
847
1102
|
noTests: args.no_tests,
|
|
848
1103
|
kind: args.kind,
|
|
1104
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.manifesto, MCP_MAX_LIMIT),
|
|
1105
|
+
offset: args.offset ?? 0,
|
|
849
1106
|
});
|
|
850
1107
|
break;
|
|
851
1108
|
}
|
|
@@ -856,6 +1113,77 @@ export async function startMCPServer(customDbPath, options = {}) {
|
|
|
856
1113
|
resolution: args.resolution,
|
|
857
1114
|
drift: args.drift,
|
|
858
1115
|
noTests: args.no_tests,
|
|
1116
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.communities, MCP_MAX_LIMIT),
|
|
1117
|
+
offset: args.offset ?? 0,
|
|
1118
|
+
});
|
|
1119
|
+
break;
|
|
1120
|
+
}
|
|
1121
|
+
case 'code_owners': {
|
|
1122
|
+
const { ownersData } = await import('./owners.js');
|
|
1123
|
+
result = ownersData(dbPath, {
|
|
1124
|
+
file: args.file,
|
|
1125
|
+
owner: args.owner,
|
|
1126
|
+
boundary: args.boundary,
|
|
1127
|
+
kind: args.kind,
|
|
1128
|
+
noTests: args.no_tests,
|
|
1129
|
+
});
|
|
1130
|
+
break;
|
|
1131
|
+
}
|
|
1132
|
+
case 'audit': {
|
|
1133
|
+
const { auditData } = await import('./audit.js');
|
|
1134
|
+
result = auditData(args.target, dbPath, {
|
|
1135
|
+
depth: args.depth,
|
|
1136
|
+
file: args.file,
|
|
1137
|
+
kind: args.kind,
|
|
1138
|
+
noTests: args.no_tests,
|
|
1139
|
+
});
|
|
1140
|
+
break;
|
|
1141
|
+
}
|
|
1142
|
+
case 'batch_query': {
|
|
1143
|
+
const { batchData } = await import('./batch.js');
|
|
1144
|
+
result = batchData(args.command, args.targets, dbPath, {
|
|
1145
|
+
depth: args.depth,
|
|
1146
|
+
file: args.file,
|
|
1147
|
+
kind: args.kind,
|
|
1148
|
+
noTests: args.no_tests,
|
|
1149
|
+
});
|
|
1150
|
+
break;
|
|
1151
|
+
}
|
|
1152
|
+
case 'triage': {
|
|
1153
|
+
const { triageData } = await import('./triage.js');
|
|
1154
|
+
result = triageData(dbPath, {
|
|
1155
|
+
sort: args.sort,
|
|
1156
|
+
minScore: args.min_score,
|
|
1157
|
+
role: args.role,
|
|
1158
|
+
file: args.file,
|
|
1159
|
+
kind: args.kind,
|
|
1160
|
+
noTests: args.no_tests,
|
|
1161
|
+
weights: args.weights,
|
|
1162
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.triage, MCP_MAX_LIMIT),
|
|
1163
|
+
offset: args.offset ?? 0,
|
|
1164
|
+
});
|
|
1165
|
+
break;
|
|
1166
|
+
}
|
|
1167
|
+
case 'branch_compare': {
|
|
1168
|
+
const { branchCompareData, branchCompareMermaid } = await import('./branch-compare.js');
|
|
1169
|
+
const bcData = await branchCompareData(args.base, args.target, {
|
|
1170
|
+
depth: args.depth,
|
|
1171
|
+
noTests: args.no_tests,
|
|
1172
|
+
});
|
|
1173
|
+
result = args.format === 'mermaid' ? branchCompareMermaid(bcData) : bcData;
|
|
1174
|
+
break;
|
|
1175
|
+
}
|
|
1176
|
+
case 'check': {
|
|
1177
|
+
const { checkData } = await import('./check.js');
|
|
1178
|
+
result = checkData(dbPath, {
|
|
1179
|
+
ref: args.ref,
|
|
1180
|
+
staged: args.staged,
|
|
1181
|
+
cycles: args.cycles,
|
|
1182
|
+
blastRadius: args.blast_radius,
|
|
1183
|
+
signatures: args.signatures,
|
|
1184
|
+
boundaries: args.boundaries,
|
|
1185
|
+
depth: args.depth,
|
|
1186
|
+
noTests: args.no_tests,
|
|
859
1187
|
});
|
|
860
1188
|
break;
|
|
861
1189
|
}
|