@codragraph/cli 2.0.0 → 2.1.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.
Files changed (101) hide show
  1. package/README.md +60 -22
  2. package/dist/_shared/cgdb/schema-constants.d.ts +16 -0
  3. package/dist/_shared/cgdb/schema-constants.d.ts.map +1 -0
  4. package/dist/_shared/cgdb/schema-constants.js +70 -0
  5. package/dist/_shared/cgdb/schema-constants.js.map +1 -0
  6. package/dist/_shared/feature-clusters.d.ts +99 -0
  7. package/dist/_shared/feature-clusters.d.ts.map +1 -0
  8. package/dist/_shared/feature-clusters.js +2 -0
  9. package/dist/_shared/feature-clusters.js.map +1 -0
  10. package/dist/_shared/graph/types.d.ts +16 -2
  11. package/dist/_shared/graph/types.d.ts.map +1 -1
  12. package/dist/_shared/index.d.ts +3 -2
  13. package/dist/_shared/index.d.ts.map +1 -1
  14. package/dist/_shared/index.js +1 -1
  15. package/dist/_shared/index.js.map +1 -1
  16. package/dist/_shared/pipeline.d.ts +1 -1
  17. package/dist/_shared/pipeline.d.ts.map +1 -1
  18. package/dist/cli/ai-context.js +4 -0
  19. package/dist/cli/analyze.js +30 -27
  20. package/dist/cli/graphstore.js +21 -21
  21. package/dist/cli/index-repo.js +3 -3
  22. package/dist/cli/index.js +37 -0
  23. package/dist/cli/setup.js +9 -5
  24. package/dist/cli/tool.d.ts +25 -0
  25. package/dist/cli/tool.js +74 -0
  26. package/dist/cli/wiki.js +3 -3
  27. package/dist/config/supported-languages.d.ts +3 -3
  28. package/dist/config/supported-languages.js +3 -3
  29. package/dist/core/augmentation/engine.js +7 -7
  30. package/dist/core/cgdb/cgdb-adapter.d.ts +176 -0
  31. package/dist/core/cgdb/cgdb-adapter.js +1336 -0
  32. package/dist/core/cgdb/content-read.d.ts +46 -0
  33. package/dist/core/cgdb/content-read.js +64 -0
  34. package/dist/core/cgdb/csv-generator.d.ts +29 -0
  35. package/dist/core/cgdb/csv-generator.js +523 -0
  36. package/dist/core/cgdb/pool-adapter.d.ts +93 -0
  37. package/dist/core/cgdb/pool-adapter.js +550 -0
  38. package/dist/core/cgdb/schema.d.ts +63 -0
  39. package/dist/core/cgdb/schema.js +557 -0
  40. package/dist/core/embeddings/embedder.js +4 -2
  41. package/dist/core/embeddings/embedding-pipeline.js +4 -4
  42. package/dist/core/graphstore/cgdb-row-source.d.ts +19 -0
  43. package/dist/core/graphstore/cgdb-row-source.js +141 -0
  44. package/dist/core/graphstore/index.d.ts +2 -2
  45. package/dist/core/graphstore/index.js +4 -4
  46. package/dist/core/group/bridge-db.d.ts +2 -2
  47. package/dist/core/group/bridge-db.js +18 -18
  48. package/dist/core/group/bridge-schema.d.ts +4 -4
  49. package/dist/core/group/bridge-schema.js +4 -4
  50. package/dist/core/group/cross-impact.js +3 -3
  51. package/dist/core/group/service.d.ts +16 -0
  52. package/dist/core/group/service.js +360 -0
  53. package/dist/core/group/sync.js +4 -4
  54. package/dist/core/ingestion/emit-references.d.ts +1 -1
  55. package/dist/core/ingestion/emit-references.js +1 -1
  56. package/dist/core/ingestion/feature-cluster-processor.d.ts +62 -0
  57. package/dist/core/ingestion/feature-cluster-processor.js +626 -0
  58. package/dist/core/ingestion/finalize-orchestrator.js +1 -1
  59. package/dist/core/ingestion/model/registration-table.js +1 -0
  60. package/dist/core/ingestion/model/resolve.d.ts +2 -2
  61. package/dist/core/ingestion/model/resolve.js +3 -3
  62. package/dist/core/ingestion/model/semantic-model.d.ts +1 -1
  63. package/dist/core/ingestion/model/semantic-model.js +1 -1
  64. package/dist/core/ingestion/model/symbol-table.d.ts +1 -1
  65. package/dist/core/ingestion/model/symbol-table.js +1 -1
  66. package/dist/core/ingestion/pipeline-phases/feature-clusters.d.ts +17 -0
  67. package/dist/core/ingestion/pipeline-phases/feature-clusters.js +88 -0
  68. package/dist/core/ingestion/pipeline-phases/index.d.ts +1 -0
  69. package/dist/core/ingestion/pipeline-phases/index.js +1 -0
  70. package/dist/core/ingestion/pipeline.d.ts +4 -0
  71. package/dist/core/ingestion/pipeline.js +9 -5
  72. package/dist/core/run-analyze.d.ts +1 -0
  73. package/dist/core/run-analyze.js +36 -30
  74. package/dist/core/search/bm25-index.d.ts +3 -3
  75. package/dist/core/search/bm25-index.js +9 -9
  76. package/dist/core/search/hybrid-search.js +2 -2
  77. package/dist/core/wiki/generator.d.ts +2 -2
  78. package/dist/core/wiki/generator.js +4 -4
  79. package/dist/core/wiki/graph-queries.d.ts +2 -2
  80. package/dist/core/wiki/graph-queries.js +5 -5
  81. package/dist/mcp/core/cgdb-adapter.d.ts +5 -0
  82. package/dist/mcp/core/cgdb-adapter.js +5 -0
  83. package/dist/mcp/core/embedder.js +6 -3
  84. package/dist/mcp/local/local-backend.d.ts +14 -2
  85. package/dist/mcp/local/local-backend.js +396 -18
  86. package/dist/mcp/resources.js +139 -0
  87. package/dist/mcp/server.js +3 -3
  88. package/dist/mcp/tools.js +175 -3
  89. package/dist/server/analyze-worker.js +2 -2
  90. package/dist/server/api.js +147 -31
  91. package/dist/storage/repo-manager.d.ts +10 -5
  92. package/dist/storage/repo-manager.js +10 -6
  93. package/dist/types/pipeline.d.ts +2 -0
  94. package/hooks/claude/codragraph-hook.cjs +4 -4
  95. package/package.json +15 -6
  96. package/scripts/build.js +21 -21
  97. package/skills/codragraph-cli.md +17 -1
  98. package/skills/codragraph-guide.md +6 -2
  99. package/skills/codragraph-onboarding.md +2 -2
  100. package/vendor/tree-sitter-proto/bindings/node/index.js +3 -3
  101. package/vendor/tree-sitter-proto/src/node-types.json +1 -1
@@ -41,6 +41,12 @@ export function getResourceTemplates() {
41
41
  description: 'All functional areas (Leiden clusters)',
42
42
  mimeType: 'text/yaml',
43
43
  },
44
+ {
45
+ uriTemplate: 'codragraph://repo/{name}/feature-clusters',
46
+ name: 'Repo Feature Clusters',
47
+ description: 'Human-facing product/domain feature areas with members and dependencies',
48
+ mimeType: 'text/yaml',
49
+ },
44
50
  {
45
51
  uriTemplate: 'codragraph://repo/{name}/processes',
46
52
  name: 'Repo Processes',
@@ -59,6 +65,12 @@ export function getResourceTemplates() {
59
65
  description: 'Deep dive into a specific functional area',
60
66
  mimeType: 'text/yaml',
61
67
  },
68
+ {
69
+ uriTemplate: 'codragraph://repo/{name}/feature/{featureName}',
70
+ name: 'Feature Context',
71
+ description: 'Members, line ranges, dependencies, and flows for one feature cluster',
72
+ mimeType: 'text/yaml',
73
+ },
62
74
  {
63
75
  uriTemplate: 'codragraph://repo/{name}/process/{processName}',
64
76
  name: 'Process Trace',
@@ -194,6 +206,14 @@ export function parseResourceUri(uri) {
194
206
  param: rest.replace(/^cluster\//, ''),
195
207
  };
196
208
  }
209
+ if (rest.startsWith('feature/')) {
210
+ return {
211
+ kind: 'repo',
212
+ repoName,
213
+ resourceType: 'feature',
214
+ param: rest.replace(/^feature\//, ''),
215
+ };
216
+ }
197
217
  if (rest.startsWith('process/')) {
198
218
  return {
199
219
  kind: 'repo',
@@ -229,12 +249,16 @@ export async function readResource(uri, backend) {
229
249
  return getContextResource(backend, repoName);
230
250
  case 'clusters':
231
251
  return getClustersResource(backend, repoName);
252
+ case 'feature-clusters':
253
+ return getFeatureClustersResource(backend, repoName);
232
254
  case 'processes':
233
255
  return getProcessesResource(backend, repoName);
234
256
  case 'schema':
235
257
  return getSchemaResource();
236
258
  case 'cluster':
237
259
  return getClusterDetailResource(parsed.param, backend, repoName);
260
+ case 'feature':
261
+ return getFeatureDetailResource(parsed.param, backend, repoName);
238
262
  case 'process':
239
263
  return getProcessDetailResource(parsed.param, backend, repoName);
240
264
  case 'graphstore/log':
@@ -308,6 +332,7 @@ async function getContextResource(backend, repoName) {
308
332
  lines.push(` files: ${context.stats.fileCount}`);
309
333
  lines.push(` symbols: ${context.stats.functionCount}`);
310
334
  lines.push(` processes: ${context.stats.processCount}`);
335
+ lines.push(` feature_clusters: ${repo.stats?.featureClusters || 0}`);
311
336
  lines.push('');
312
337
  lines.push('tools_available:');
313
338
  lines.push(' - query: Process-grouped code intelligence (execution flows related to a concept)');
@@ -323,8 +348,10 @@ async function getContextResource(backend, repoName) {
323
348
  lines.push('resources_available:');
324
349
  lines.push(' - codragraph://repos: All indexed repositories');
325
350
  lines.push(` - codragraph://repo/${context.projectName}/clusters: All functional areas`);
351
+ lines.push(` - codragraph://repo/${context.projectName}/feature-clusters: Human-facing feature areas`);
326
352
  lines.push(` - codragraph://repo/${context.projectName}/processes: All execution flows`);
327
353
  lines.push(` - codragraph://repo/${context.projectName}/cluster/{name}: Module details`);
354
+ lines.push(` - codragraph://repo/${context.projectName}/feature/{name}: Feature context pack`);
328
355
  lines.push(` - codragraph://repo/${context.projectName}/process/{name}: Process trace`);
329
356
  lines.push(' - codragraph://group/{name}/contracts: Group contract registry (optional ?type=&repo=&unmatchedOnly=)');
330
357
  lines.push(' - codragraph://group/{name}/status: Group index / contract staleness');
@@ -362,6 +389,39 @@ async function getClustersResource(backend, repoName) {
362
389
  /**
363
390
  * Processes resource — queries graph directly via backend.queryProcesses()
364
391
  */
392
+ /**
393
+ * Feature clusters resource - human-facing product/domain areas.
394
+ */
395
+ async function getFeatureClustersResource(backend, repoName) {
396
+ try {
397
+ const result = await backend.queryFeatureClusters(repoName, 100);
398
+ if (!result.clusters || result.clusters.length === 0) {
399
+ return 'feature_clusters: []\n# No feature clusters detected. Run: codragraph analyze';
400
+ }
401
+ const displayLimit = 30;
402
+ const lines = ['feature_clusters:'];
403
+ for (const cluster of result.clusters.slice(0, displayLimit)) {
404
+ lines.push(` - name: "${cluster.name || cluster.slug || cluster.id}"`);
405
+ lines.push(` slug: "${cluster.slug || ''}"`);
406
+ lines.push(` kind: ${cluster.featureKind || 'feature'}`);
407
+ if (cluster.summary)
408
+ lines.push(` summary: "${cluster.summary}"`);
409
+ lines.push(` members: ${cluster.memberCount || 0}`);
410
+ if (cluster.routes?.length)
411
+ lines.push(` routes: ${cluster.routes.length}`);
412
+ if (cluster.tools?.length)
413
+ lines.push(` tools: ${cluster.tools.length}`);
414
+ lines.push(` confidence: ${Math.round((cluster.confidence || 0) * 100)}%`);
415
+ }
416
+ if (result.clusters.length > displayLimit) {
417
+ lines.push(`\n# Showing top ${displayLimit} of ${result.clusters.length} feature clusters. Use feature_context for details.`);
418
+ }
419
+ return lines.join('\n');
420
+ }
421
+ catch (err) {
422
+ return `error: ${err.message}`;
423
+ }
424
+ }
365
425
  async function getProcessesResource(backend, repoName) {
366
426
  try {
367
427
  const result = await backend.queryProcesses(repoName, 50);
@@ -402,6 +462,7 @@ nodes:
402
462
  - CodeElement: Catch-all for other code elements
403
463
  - Community: Auto-detected functional area (Leiden algorithm)
404
464
  - Process: Execution flow trace
465
+ - FeatureCluster: Human-facing feature/domain cluster for targeted context
405
466
 
406
467
  additional_node_types: "Multi-language: Struct, Enum, Macro, Typedef, Union, Namespace, Trait, Impl, TypeAlias, Const, Static, Property, Record, Delegate, Annotation, Constructor, Template, Module (use backticks in queries: \`Struct\`, \`Enum\`, etc.)"
407
468
 
@@ -411,6 +472,7 @@ node_properties:
411
472
  Function: "parameterCount (INT32), returnType (STRING), isVariadic (BOOL), visibility (STRING), isStatic (BOOL), isAbstract (BOOL), isFinal (BOOL), isAsync (BOOL), parameterTypes (STRING[]), annotations (STRING[])"
412
473
  Property: "declaredType (STRING) — the field's type annotation (e.g., 'Address', 'City'). Used for field-access chain resolution."
413
474
  Constructor: "parameterCount (INT32), visibility (STRING), isStatic (BOOL), parameterTypes (STRING[])"
475
+ FeatureCluster: "name (STRING), slug (STRING), featureKind (STRING), summary (STRING), repo (STRING), service (STRING), memberCount (INT32), entryPointIds (STRING[]), routes (STRING[]), tools (STRING[]), testCoverageHints (STRING[]), lastIndexedCommit (STRING), confidence (DOUBLE), signals (STRING[])"
414
476
  Community: "heuristicLabel (STRING), cohesion (DOUBLE), symbolCount (INT32), keywords (STRING[]), description (STRING), enrichedBy (STRING)"
415
477
  Process: "heuristicLabel (STRING), processType (STRING — 'intra_community' or 'cross_community'), stepCount (INT32), communities (STRING[]), entryPointId (STRING), terminalId (STRING)"
416
478
 
@@ -428,6 +490,10 @@ relationships:
428
490
  - METHOD_IMPLEMENTS: ConcreteMethod implements InterfaceMethod (matched by name + parameterTypes)
429
491
  - MEMBER_OF: Symbol belongs to community
430
492
  - STEP_IN_PROCESS: Symbol is step N in process
493
+ - WRAPS: Wrapper/decorator relationship
494
+ - QUERIES: Data/query relationship
495
+ - FEATURE_MEMBER_OF: Symbol/file belongs to a FeatureCluster
496
+ - FEATURE_DEPENDS_ON: FeatureCluster depends on another FeatureCluster via member edges
431
497
 
432
498
  relationship_table: "All relationships use a single CodeRelation table with a 'type' property. Properties: type (STRING), confidence (DOUBLE), reason (STRING), step (INT32)"
433
499
 
@@ -487,6 +553,66 @@ async function getClusterDetailResource(name, backend, repoName) {
487
553
  /**
488
554
  * Process detail resource — queries graph directly via backend.queryProcessDetail()
489
555
  */
556
+ async function getFeatureDetailResource(name, backend, repoName) {
557
+ try {
558
+ const result = await backend.queryFeatureContext(name, repoName);
559
+ if (result.error) {
560
+ return `error: ${result.error}`;
561
+ }
562
+ const cluster = result.cluster;
563
+ const members = result.members || [];
564
+ const outgoing = result.dependencies?.outgoing || [];
565
+ const incoming = result.dependencies?.incoming || [];
566
+ const processes = result.processes || [];
567
+ const lines = [
568
+ `feature: "${cluster.name || cluster.slug || cluster.id}"`,
569
+ `slug: "${cluster.slug || ''}"`,
570
+ `kind: ${cluster.featureKind || 'feature'}`,
571
+ `members: ${cluster.memberCount || members.length}`,
572
+ `confidence: ${Math.round((cluster.confidence || 0) * 100)}%`,
573
+ ];
574
+ if (members.length > 0) {
575
+ lines.push('');
576
+ lines.push('members:');
577
+ for (const member of members.slice(0, 30)) {
578
+ lines.push(` - name: ${member.name}`);
579
+ lines.push(` type: ${member.type}`);
580
+ lines.push(` file: ${member.filePath || ''}`);
581
+ if (member.startLine !== undefined)
582
+ lines.push(` startLine: ${member.startLine}`);
583
+ if (member.endLine !== undefined)
584
+ lines.push(` endLine: ${member.endLine}`);
585
+ }
586
+ }
587
+ if (outgoing.length > 0 || incoming.length > 0) {
588
+ lines.push('');
589
+ lines.push('dependencies:');
590
+ if (outgoing.length > 0) {
591
+ lines.push(' outgoing:');
592
+ for (const dep of outgoing.slice(0, 15)) {
593
+ lines.push(` - ${dep.name || dep.slug || dep.id}`);
594
+ }
595
+ }
596
+ if (incoming.length > 0) {
597
+ lines.push(' incoming:');
598
+ for (const dep of incoming.slice(0, 15)) {
599
+ lines.push(` - ${dep.name || dep.slug || dep.id}`);
600
+ }
601
+ }
602
+ }
603
+ if (processes.length > 0) {
604
+ lines.push('');
605
+ lines.push('processes:');
606
+ for (const proc of processes.slice(0, 10)) {
607
+ lines.push(` - ${proc.heuristicLabel || proc.label || proc.id}`);
608
+ }
609
+ }
610
+ return lines.join('\n');
611
+ }
612
+ catch (err) {
613
+ return `error: ${err.message}`;
614
+ }
615
+ }
490
616
  async function getProcessDetailResource(name, backend, repoName) {
491
617
  try {
492
618
  const result = await backend.queryProcessDetail(name, repoName);
@@ -539,6 +665,12 @@ async function getSetupResource(backend) {
539
665
  '| `impact` | Symbol blast radius — what breaks at depth 1/2/3 with confidence |',
540
666
  '| `detect_changes` | Git-diff impact — what do your current changes affect |',
541
667
  '| `rename` | Multi-file coordinated rename with confidence-tagged edits |',
668
+ '| `feature_clusters` | Product/domain feature map for targeted context |',
669
+ '| `feature_context` | Members, line ranges, dependencies, and flows for one feature |',
670
+ '| `cluster_query` | Cluster-first alias for `feature_clusters` |',
671
+ '| `cluster_context` | Cluster-first alias for `feature_context` |',
672
+ '| `context_pack` | Compact context pack for one feature cluster |',
673
+ '| `cluster_impact` | Feature-level blast radius across cluster dependencies |',
542
674
  '| `cypher` | Raw graph queries |',
543
675
  '| `list_repos` | Discover indexed repos |',
544
676
  '',
@@ -546,8 +678,15 @@ async function getSetupResource(backend) {
546
678
  '',
547
679
  `- \`codragraph://repo/${repo.name}/context\` — Stats, staleness check`,
548
680
  `- \`codragraph://repo/${repo.name}/clusters\` — All functional areas`,
681
+ `- \`codragraph://repo/${repo.name}/feature-clusters\` — Human-facing feature areas`,
682
+ `- \`codragraph://repo/${repo.name}/feature/{name}\` — Feature context pack`,
549
683
  `- \`codragraph://repo/${repo.name}/processes\` — All execution flows`,
550
684
  `- \`codragraph://repo/${repo.name}/schema\` — Graph schema for Cypher`,
685
+ '',
686
+ '## Cross-platform commands',
687
+ '',
688
+ '- Use `npx @codragraph/cli ...` or `codragraph ...` in Windows PowerShell, macOS bash/zsh, and Linux shells.',
689
+ '- Prefer `npm --prefix <package> <script>` from repo root for package checks instead of shell-specific `cd dir && ...` chains.',
551
690
  ];
552
691
  sections.push(lines.join('\n'));
553
692
  }
@@ -15,7 +15,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
15
15
  import { CompatibleStdioServerTransport } from './compatible-stdio-transport.js';
16
16
  import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
17
17
  import { CODRAGRAPH_TOOLS } from './tools.js';
18
- import { realStdoutWrite } from './core/lbug-adapter.js';
18
+ import { realStdoutWrite } from './core/cgdb-adapter.js';
19
19
  import { getResourceDefinitions, getResourceTemplates, readResource } from './resources.js';
20
20
  /**
21
21
  * Next-step hints appended to tool responses.
@@ -208,7 +208,7 @@ export function createMCPServer(backend) {
208
208
  { name: 'repo', description: 'Repository (omit if only one indexed)', required: false },
209
209
  {
210
210
  name: 'symbolId',
211
- description: 'Stable symbol id (PK in the lbug node table)',
211
+ description: 'Stable symbol id (PK in the cgdb node table)',
212
212
  required: true,
213
213
  },
214
214
  {
@@ -484,7 +484,7 @@ Follow these steps:
484
484
  export async function startMCPServer(backend) {
485
485
  const server = createMCPServer(backend);
486
486
  // Use the shared stdout reference captured at module-load time by the
487
- // lbug-adapter. Avoids divergence if anything patches stdout between
487
+ // cgdb-adapter. Avoids divergence if anything patches stdout between
488
488
  // module load and server start.
489
489
  const _safeStdout = new Proxy(process.stdout, {
490
490
  get(target, prop, receiver) {
package/dist/mcp/tools.js CHANGED
@@ -84,6 +84,177 @@ SERVICE: optional monorepo path prefix (POSIX-style, case-sensitive segments). W
84
84
  required: ['query'],
85
85
  },
86
86
  },
87
+ {
88
+ name: 'feature_clusters',
89
+ description: `List human-facing feature clusters such as Settings, AI, Auth, Billing, MCP, or Ingestion.
90
+
91
+ WHEN TO USE: First step for targeted implementation/refactoring when you need the functional area map before loading files. This is the product/domain layer above algorithmic Community nodes.
92
+ AFTER THIS: Use feature_context(name) for members with file paths and line ranges, then context() or impact() on specific symbols.`,
93
+ inputSchema: {
94
+ type: 'object',
95
+ properties: {
96
+ query: {
97
+ type: 'string',
98
+ description: 'Optional cluster owner search term (e.g. "settings", "AI", "billing").',
99
+ },
100
+ repo: {
101
+ type: 'string',
102
+ description: 'Repository name or path. Omit if only one repo is indexed.',
103
+ },
104
+ limit: {
105
+ type: 'number',
106
+ description: 'Max feature clusters to return (default: 100)',
107
+ default: 100,
108
+ minimum: 1,
109
+ maximum: 500,
110
+ },
111
+ },
112
+ required: [],
113
+ },
114
+ },
115
+ {
116
+ name: 'feature_context',
117
+ description: `Get a complete context pack for one FeatureCluster.
118
+
119
+ Returns the cluster metadata, member symbols/files with line ranges, outgoing/incoming feature dependencies, and related execution processes.
120
+
121
+ WHEN TO USE: Before editing a feature area like Settings or AI. This narrows exploration to the exact files and symbols in that feature cluster.`,
122
+ inputSchema: {
123
+ type: 'object',
124
+ properties: {
125
+ name: {
126
+ type: 'string',
127
+ description: 'Feature cluster name, slug, or id (e.g. "Settings", "settings").',
128
+ },
129
+ repo: {
130
+ type: 'string',
131
+ description: 'Repository name or path. Omit if only one repo is indexed.',
132
+ },
133
+ limit: {
134
+ type: 'number',
135
+ description: 'Max members to return (default: 100)',
136
+ default: 100,
137
+ minimum: 1,
138
+ maximum: 500,
139
+ },
140
+ },
141
+ required: ['name'],
142
+ },
143
+ },
144
+ {
145
+ name: 'cluster_query',
146
+ description: `Cluster-first alias for feature_clusters.
147
+
148
+ WHEN TO USE: Ask which product/domain cluster owns an area like Settings, AI, Auth, or Billing before loading files.`,
149
+ inputSchema: {
150
+ type: 'object',
151
+ properties: {
152
+ query: {
153
+ type: 'string',
154
+ description: 'Optional cluster owner search term (e.g. "settings", "AI", "billing").',
155
+ },
156
+ repo: {
157
+ type: 'string',
158
+ description: 'Repository name or path. Omit if only one repo is indexed.',
159
+ },
160
+ limit: {
161
+ type: 'number',
162
+ description: 'Max feature clusters to return (default: 100)',
163
+ default: 100,
164
+ minimum: 1,
165
+ maximum: 500,
166
+ },
167
+ },
168
+ required: [],
169
+ },
170
+ },
171
+ {
172
+ name: 'cluster_context',
173
+ description: `Cluster-first alias for feature_context.
174
+
175
+ Returns a FeatureCluster context pack with members, entry points, routes, tools, tests, docs, dependencies, and safe edit surface.`,
176
+ inputSchema: {
177
+ type: 'object',
178
+ properties: {
179
+ name: {
180
+ type: 'string',
181
+ description: 'Feature cluster name, slug, or id (e.g. "Settings", "settings").',
182
+ },
183
+ repo: {
184
+ type: 'string',
185
+ description: 'Repository name or path. Omit if only one repo is indexed.',
186
+ },
187
+ limit: {
188
+ type: 'number',
189
+ description: 'Max members to return (default: 100)',
190
+ default: 100,
191
+ minimum: 1,
192
+ maximum: 500,
193
+ },
194
+ },
195
+ required: ['name'],
196
+ },
197
+ },
198
+ {
199
+ name: 'context_pack',
200
+ description: `Get the compact agent context pack for a FeatureCluster.
201
+
202
+ WHEN TO USE: Before a refactor or implementation task where the agent should avoid re-exploring the full repo.`,
203
+ inputSchema: {
204
+ type: 'object',
205
+ properties: {
206
+ name: {
207
+ type: 'string',
208
+ description: 'Feature cluster name, slug, or id (e.g. "AI", "ai").',
209
+ },
210
+ repo: {
211
+ type: 'string',
212
+ description: 'Repository name or path. Omit if only one repo is indexed.',
213
+ },
214
+ limit: {
215
+ type: 'number',
216
+ description: 'Max members to return (default: 100)',
217
+ default: 100,
218
+ minimum: 1,
219
+ maximum: 500,
220
+ },
221
+ },
222
+ required: ['name'],
223
+ },
224
+ },
225
+ {
226
+ name: 'cluster_impact',
227
+ description: `Assess feature-level blast radius for a FeatureCluster.
228
+
229
+ Returns upstream/downstream cluster dependencies plus the same context pack and safe edit surface used for targeted edits.`,
230
+ inputSchema: {
231
+ type: 'object',
232
+ properties: {
233
+ name: {
234
+ type: 'string',
235
+ description: 'Feature cluster name, slug, or id.',
236
+ },
237
+ direction: {
238
+ type: 'string',
239
+ enum: ['upstream', 'downstream', 'both'],
240
+ description: 'Dependency direction to inspect.',
241
+ default: 'upstream',
242
+ },
243
+ repo: {
244
+ type: 'string',
245
+ description: 'Repository name or path. Omit if only one repo is indexed.',
246
+ },
247
+ limit: {
248
+ type: 'number',
249
+ description: 'Max members to include in the context pack (default: 100)',
250
+ default: 100,
251
+ minimum: 1,
252
+ maximum: 500,
253
+ },
254
+ },
255
+ required: ['name'],
256
+ },
257
+ },
87
258
  {
88
259
  name: 'cypher',
89
260
  description: `Execute Cypher query against the code knowledge graph.
@@ -92,10 +263,10 @@ WHEN TO USE: Complex structural queries that search/explore can't answer. READ c
92
263
  AFTER THIS: Use context() on result symbols for deeper context.
93
264
 
94
265
  SCHEMA:
95
- - Nodes: File, Folder, Function, Class, Interface, Method, CodeElement, Community, Process, Route, Tool
266
+ - Nodes: File, Folder, Function, Class, Interface, Method, CodeElement, Community, Process, FeatureCluster, Route, Tool
96
267
  - Multi-language nodes (use backticks): \`Struct\`, \`Enum\`, \`Trait\`, \`Impl\`, etc.
97
268
  - All edges via single CodeRelation table with 'type' property
98
- - Edge types: CONTAINS, DEFINES, CALLS, IMPORTS, EXTENDS, IMPLEMENTS, HAS_METHOD, HAS_PROPERTY, ACCESSES, METHOD_OVERRIDES, METHOD_IMPLEMENTS, MEMBER_OF, STEP_IN_PROCESS, HANDLES_ROUTE, FETCHES, HANDLES_TOOL, ENTRY_POINT_OF
269
+ - Edge types: CONTAINS, DEFINES, CALLS, IMPORTS, EXTENDS, IMPLEMENTS, HAS_METHOD, HAS_PROPERTY, ACCESSES, METHOD_OVERRIDES, METHOD_IMPLEMENTS, MEMBER_OF, STEP_IN_PROCESS, HANDLES_ROUTE, FETCHES, HANDLES_TOOL, ENTRY_POINT_OF, WRAPS, QUERIES, FEATURE_MEMBER_OF, FEATURE_DEPENDS_ON
99
270
  - Edge properties: type (STRING), confidence (DOUBLE), reason (STRING), step (INT32)
100
271
 
101
272
  EXAMPLES:
@@ -129,6 +300,7 @@ TIPS:
129
300
  - All relationships use single CodeRelation table — filter with {type: 'CALLS'} etc.
130
301
  - Community = auto-detected functional area (Leiden algorithm). Properties: heuristicLabel, cohesion, symbolCount, keywords, description, enrichedBy
131
302
  - Process = execution flow trace from entry point to terminal. Properties: heuristicLabel, processType, stepCount, communities, entryPointId, terminalId
303
+ - FeatureCluster = product/domain area for targeted context packs. Properties: name, slug, featureKind, summary, repo, service, memberCount, entryPointIds, routes, tools, testCoverageHints, lastIndexedCommit, confidence, signals
132
304
  - Use heuristicLabel (not label) for human-readable community/process names`,
133
305
  inputSchema: {
134
306
  type: 'object',
@@ -806,7 +978,7 @@ Pair with codragraph_context first to get the symbol's stable id (e.g. \`fn:src/
806
978
  type: 'object',
807
979
  properties: {
808
980
  repo: { type: 'string', description: 'Indexed repo (omit if only one).' },
809
- symbolId: { type: 'string', description: 'Stable symbol id (PK in the lbug node table).' },
981
+ symbolId: { type: 'string', description: 'Stable symbol id (PK in the cgdb node table).' },
810
982
  table: {
811
983
  type: 'string',
812
984
  description: 'Optional table hint to narrow the search (Function, Class, Method, Interface, …).',
@@ -11,7 +11,7 @@
11
11
  * Child -> Parent: { type: 'error', message: string }
12
12
  */
13
13
  import { runFullAnalysis } from '../core/run-analyze.js';
14
- import { closeLbug } from '../core/lbug/lbug-adapter.js';
14
+ import { closeCgdb } from '../core/cgdb/cgdb-adapter.js';
15
15
  function send(msg) {
16
16
  process.send?.(msg);
17
17
  }
@@ -28,7 +28,7 @@ process.on('unhandledRejection', (reason) => {
28
28
  process.on('SIGTERM', async () => {
29
29
  send({ type: 'error', message: 'Analysis cancelled (worker received SIGTERM)' });
30
30
  try {
31
- await closeLbug();
31
+ await closeCgdb();
32
32
  }
33
33
  catch { }
34
34
  process.exit(0);