@codragraph/cli 2.1.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.
- package/README.md +58 -20
- package/dist/_shared/cgdb/schema-constants.d.ts +2 -2
- package/dist/_shared/cgdb/schema-constants.d.ts.map +1 -1
- package/dist/_shared/cgdb/schema-constants.js +3 -0
- package/dist/_shared/cgdb/schema-constants.js.map +1 -1
- package/dist/_shared/feature-clusters.d.ts +99 -0
- package/dist/_shared/feature-clusters.d.ts.map +1 -0
- package/dist/_shared/feature-clusters.js +2 -0
- package/dist/_shared/feature-clusters.js.map +1 -0
- package/dist/_shared/graph/types.d.ts +16 -2
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +1 -0
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/pipeline.d.ts +1 -1
- package/dist/_shared/pipeline.d.ts.map +1 -1
- package/dist/cli/ai-context.js +4 -0
- package/dist/cli/analyze.js +27 -24
- package/dist/cli/index.js +37 -0
- package/dist/cli/setup.js +9 -5
- package/dist/cli/tool.d.ts +25 -0
- package/dist/cli/tool.js +74 -0
- package/dist/config/supported-languages.d.ts +3 -3
- package/dist/config/supported-languages.js +3 -3
- package/dist/core/cgdb/cgdb-adapter.js +19 -3
- package/dist/core/cgdb/csv-generator.js +33 -2
- package/dist/core/cgdb/schema.d.ts +2 -1
- package/dist/core/cgdb/schema.js +55 -0
- package/dist/core/embeddings/embedder.js +4 -2
- package/dist/core/graphstore/index.d.ts +1 -1
- package/dist/core/graphstore/index.js +1 -1
- package/dist/core/group/service.d.ts +16 -0
- package/dist/core/group/service.js +360 -0
- package/dist/core/ingestion/emit-references.d.ts +1 -1
- package/dist/core/ingestion/emit-references.js +1 -1
- package/dist/core/ingestion/feature-cluster-processor.d.ts +62 -0
- package/dist/core/ingestion/feature-cluster-processor.js +626 -0
- package/dist/core/ingestion/finalize-orchestrator.js +1 -1
- package/dist/core/ingestion/model/registration-table.js +1 -0
- package/dist/core/ingestion/model/resolve.d.ts +2 -2
- package/dist/core/ingestion/model/resolve.js +3 -3
- package/dist/core/ingestion/model/semantic-model.d.ts +1 -1
- package/dist/core/ingestion/model/semantic-model.js +1 -1
- package/dist/core/ingestion/model/symbol-table.d.ts +1 -1
- package/dist/core/ingestion/model/symbol-table.js +1 -1
- package/dist/core/ingestion/pipeline-phases/feature-clusters.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/feature-clusters.js +88 -0
- package/dist/core/ingestion/pipeline-phases/index.d.ts +1 -0
- package/dist/core/ingestion/pipeline-phases/index.js +1 -0
- package/dist/core/ingestion/pipeline.d.ts +4 -0
- package/dist/core/ingestion/pipeline.js +9 -5
- package/dist/core/run-analyze.d.ts +1 -0
- package/dist/core/run-analyze.js +12 -6
- package/dist/mcp/core/embedder.js +5 -2
- package/dist/mcp/local/local-backend.d.ts +12 -0
- package/dist/mcp/local/local-backend.js +381 -3
- package/dist/mcp/resources.js +139 -0
- package/dist/mcp/tools.js +174 -2
- package/dist/server/api.js +116 -0
- package/dist/storage/repo-manager.d.ts +6 -1
- package/dist/storage/repo-manager.js +5 -1
- package/dist/types/pipeline.d.ts +2 -0
- package/package.json +13 -4
- package/scripts/build.js +13 -12
- package/skills/codragraph-cli.md +17 -1
- package/skills/codragraph-guide.md +6 -2
- package/skills/codragraph-onboarding.md +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -135,6 +135,43 @@ program
|
|
|
135
135
|
.description('Execute raw Cypher query against the knowledge graph')
|
|
136
136
|
.option('-r, --repo <name>', 'Target repository')
|
|
137
137
|
.action(createLazyAction(() => import('./tool.js'), 'cypherCommand'));
|
|
138
|
+
program
|
|
139
|
+
.command('feature-clusters')
|
|
140
|
+
.description('List human-facing feature clusters for targeted context building')
|
|
141
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
142
|
+
.option('-l, --limit <n>', 'Max feature clusters to return (default: 100)')
|
|
143
|
+
.action(createLazyAction(() => import('./tool.js'), 'featureClustersCommand'));
|
|
144
|
+
program
|
|
145
|
+
.command('cluster-query [query]')
|
|
146
|
+
.description('Alias for feature-clusters: list product/domain clusters')
|
|
147
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
148
|
+
.option('-l, --limit <n>', 'Max feature clusters to return (default: 100)')
|
|
149
|
+
.action(createLazyAction(() => import('./tool.js'), 'clusterQueryCommand'));
|
|
150
|
+
program
|
|
151
|
+
.command('feature-context <name>')
|
|
152
|
+
.description('Show members, line ranges, and dependencies for a feature cluster')
|
|
153
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
154
|
+
.option('-l, --limit <n>', 'Max members to return (default: 100)')
|
|
155
|
+
.action(createLazyAction(() => import('./tool.js'), 'featureContextCommand'));
|
|
156
|
+
program
|
|
157
|
+
.command('cluster-context <name>')
|
|
158
|
+
.description('Alias for feature-context: show a feature cluster context pack')
|
|
159
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
160
|
+
.option('-l, --limit <n>', 'Max members to return (default: 100)')
|
|
161
|
+
.action(createLazyAction(() => import('./tool.js'), 'clusterContextCommand'));
|
|
162
|
+
program
|
|
163
|
+
.command('context-pack <name>')
|
|
164
|
+
.description('Generate the compact agent context pack for a feature cluster')
|
|
165
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
166
|
+
.option('-l, --limit <n>', 'Max members to return (default: 100)')
|
|
167
|
+
.action(createLazyAction(() => import('./tool.js'), 'contextPackCommand'));
|
|
168
|
+
program
|
|
169
|
+
.command('cluster-impact <name>')
|
|
170
|
+
.description('Feature-level blast radius analysis for a cluster')
|
|
171
|
+
.option('-d, --direction <dir>', 'upstream, downstream, or both', 'upstream')
|
|
172
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
173
|
+
.option('-l, --limit <n>', 'Max context-pack members to include (default: 100)')
|
|
174
|
+
.action(createLazyAction(() => import('./tool.js'), 'clusterImpactCommand'));
|
|
138
175
|
program
|
|
139
176
|
.command('detect-changes')
|
|
140
177
|
.alias('detect_changes')
|
package/dist/cli/setup.js
CHANGED
|
@@ -11,12 +11,16 @@ import os from 'os';
|
|
|
11
11
|
import { execFile, execFileSync } from 'child_process';
|
|
12
12
|
import { promisify } from 'util';
|
|
13
13
|
import { fileURLToPath } from 'url';
|
|
14
|
+
import { createRequire } from 'module';
|
|
14
15
|
import { glob } from 'glob';
|
|
15
16
|
import { parseTree, modify, applyEdits } from 'jsonc-parser';
|
|
16
17
|
import { getGlobalDir } from '../storage/repo-manager.js';
|
|
17
18
|
const __filename = fileURLToPath(import.meta.url);
|
|
18
19
|
const __dirname = path.dirname(__filename);
|
|
19
20
|
const execFileAsync = promisify(execFile);
|
|
21
|
+
const require = createRequire(import.meta.url);
|
|
22
|
+
const pkg = require('../../package.json');
|
|
23
|
+
const CLI_PACKAGE_SPEC = `@codragraph/cli@${pkg.version}`;
|
|
20
24
|
/**
|
|
21
25
|
* Resolve the absolute path to the `codragraph` binary if it's installed
|
|
22
26
|
* globally (or via npm -g / yarn global). Returns null when not found.
|
|
@@ -59,7 +63,7 @@ function resolveCodragraphBin() {
|
|
|
59
63
|
* The MCP server entry for all editors.
|
|
60
64
|
*
|
|
61
65
|
* Prefers the globally-installed `codragraph` binary (starts in ~1 s) over
|
|
62
|
-
* `npx -y @codragraph/cli
|
|
66
|
+
* `npx -y @codragraph/cli@<version>` (cold-cache install of native deps can take
|
|
63
67
|
* >60 s, exceeding Claude Code's 30 s MCP connection timeout).
|
|
64
68
|
*
|
|
65
69
|
* Falls back to npx when the binary isn't on PATH — e.g. first-time
|
|
@@ -84,12 +88,12 @@ function getMcpEntry() {
|
|
|
84
88
|
if (process.platform === 'win32') {
|
|
85
89
|
return {
|
|
86
90
|
command: 'cmd',
|
|
87
|
-
args: ['/c', 'npx', '-y',
|
|
91
|
+
args: ['/c', 'npx', '-y', CLI_PACKAGE_SPEC, 'mcp'],
|
|
88
92
|
};
|
|
89
93
|
}
|
|
90
94
|
return {
|
|
91
95
|
command: 'npx',
|
|
92
|
-
args: ['-y',
|
|
96
|
+
args: ['-y', CLI_PACKAGE_SPEC, 'mcp'],
|
|
93
97
|
};
|
|
94
98
|
}
|
|
95
99
|
/**
|
|
@@ -107,10 +111,10 @@ function getOpenCodeMcpEntry() {
|
|
|
107
111
|
if (process.platform === 'win32') {
|
|
108
112
|
return {
|
|
109
113
|
type: 'local',
|
|
110
|
-
command: ['cmd', '/c', 'npx', '-y',
|
|
114
|
+
command: ['cmd', '/c', 'npx', '-y', CLI_PACKAGE_SPEC, 'mcp'],
|
|
111
115
|
};
|
|
112
116
|
}
|
|
113
|
-
return { type: 'local', command: ['npx', '-y',
|
|
117
|
+
return { type: 'local', command: ['npx', '-y', CLI_PACKAGE_SPEC, 'mcp'] };
|
|
114
118
|
}
|
|
115
119
|
/**
|
|
116
120
|
* Merge codragraph entry into an existing MCP config JSON object.
|
package/dist/cli/tool.d.ts
CHANGED
|
@@ -36,6 +36,31 @@ export declare function impactCommand(target: string, options?: {
|
|
|
36
36
|
export declare function cypherCommand(query: string, options?: {
|
|
37
37
|
repo?: string;
|
|
38
38
|
}): Promise<void>;
|
|
39
|
+
export declare function featureClustersCommand(options?: {
|
|
40
|
+
repo?: string;
|
|
41
|
+
limit?: string;
|
|
42
|
+
}): Promise<void>;
|
|
43
|
+
export declare function clusterQueryCommand(query?: string, options?: {
|
|
44
|
+
repo?: string;
|
|
45
|
+
limit?: string;
|
|
46
|
+
}): Promise<void>;
|
|
47
|
+
export declare function featureContextCommand(name: string, options?: {
|
|
48
|
+
repo?: string;
|
|
49
|
+
limit?: string;
|
|
50
|
+
}): Promise<void>;
|
|
51
|
+
export declare function clusterContextCommand(name: string, options?: {
|
|
52
|
+
repo?: string;
|
|
53
|
+
limit?: string;
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
export declare function contextPackCommand(name: string, options?: {
|
|
56
|
+
repo?: string;
|
|
57
|
+
limit?: string;
|
|
58
|
+
}): Promise<void>;
|
|
59
|
+
export declare function clusterImpactCommand(name: string, options?: {
|
|
60
|
+
direction?: string;
|
|
61
|
+
repo?: string;
|
|
62
|
+
limit?: string;
|
|
63
|
+
}): Promise<void>;
|
|
39
64
|
export declare function detectChangesCommand(options?: {
|
|
40
65
|
scope?: string;
|
|
41
66
|
baseRef?: string;
|
package/dist/cli/tool.js
CHANGED
|
@@ -128,6 +128,80 @@ export async function cypherCommand(query, options) {
|
|
|
128
128
|
});
|
|
129
129
|
output(result);
|
|
130
130
|
}
|
|
131
|
+
export async function featureClustersCommand(options) {
|
|
132
|
+
const backend = await getBackend();
|
|
133
|
+
const result = await backend.callTool('feature_clusters', {
|
|
134
|
+
repo: options?.repo,
|
|
135
|
+
limit: options?.limit ? parseInt(options.limit, 10) : undefined,
|
|
136
|
+
});
|
|
137
|
+
output(result);
|
|
138
|
+
}
|
|
139
|
+
export async function clusterQueryCommand(query, options) {
|
|
140
|
+
const backend = await getBackend();
|
|
141
|
+
const result = await backend.callTool('cluster_query', {
|
|
142
|
+
query,
|
|
143
|
+
repo: options?.repo,
|
|
144
|
+
limit: options?.limit ? parseInt(options.limit, 10) : undefined,
|
|
145
|
+
});
|
|
146
|
+
output(result);
|
|
147
|
+
}
|
|
148
|
+
export async function featureContextCommand(name, options) {
|
|
149
|
+
if (!name?.trim()) {
|
|
150
|
+
console.error('Usage: codragraph feature-context <name>');
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
const backend = await getBackend();
|
|
154
|
+
const result = await backend.callTool('feature_context', {
|
|
155
|
+
name,
|
|
156
|
+
repo: options?.repo,
|
|
157
|
+
limit: options?.limit ? parseInt(options.limit, 10) : undefined,
|
|
158
|
+
});
|
|
159
|
+
output(result);
|
|
160
|
+
emitTokenStats(result);
|
|
161
|
+
}
|
|
162
|
+
export async function clusterContextCommand(name, options) {
|
|
163
|
+
if (!name?.trim()) {
|
|
164
|
+
console.error('Usage: codragraph cluster-context <name>');
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
const backend = await getBackend();
|
|
168
|
+
const result = await backend.callTool('cluster_context', {
|
|
169
|
+
name,
|
|
170
|
+
repo: options?.repo,
|
|
171
|
+
limit: options?.limit ? parseInt(options.limit, 10) : undefined,
|
|
172
|
+
});
|
|
173
|
+
output(result);
|
|
174
|
+
emitTokenStats(result);
|
|
175
|
+
}
|
|
176
|
+
export async function contextPackCommand(name, options) {
|
|
177
|
+
if (!name?.trim()) {
|
|
178
|
+
console.error('Usage: codragraph context-pack <name>');
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
const backend = await getBackend();
|
|
182
|
+
const result = await backend.callTool('context_pack', {
|
|
183
|
+
name,
|
|
184
|
+
repo: options?.repo,
|
|
185
|
+
limit: options?.limit ? parseInt(options.limit, 10) : undefined,
|
|
186
|
+
});
|
|
187
|
+
output(result);
|
|
188
|
+
emitTokenStats(result);
|
|
189
|
+
}
|
|
190
|
+
export async function clusterImpactCommand(name, options) {
|
|
191
|
+
if (!name?.trim()) {
|
|
192
|
+
console.error('Usage: codragraph cluster-impact <name>');
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
195
|
+
const backend = await getBackend();
|
|
196
|
+
const result = await backend.callTool('cluster_impact', {
|
|
197
|
+
name,
|
|
198
|
+
direction: options?.direction,
|
|
199
|
+
repo: options?.repo,
|
|
200
|
+
limit: options?.limit ? parseInt(options.limit, 10) : undefined,
|
|
201
|
+
});
|
|
202
|
+
output(result);
|
|
203
|
+
emitTokenStats(result);
|
|
204
|
+
}
|
|
131
205
|
function formatDetectChangesResult(result) {
|
|
132
206
|
if (result?.error)
|
|
133
207
|
return `Error: ${result.error}`;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Re-export SupportedLanguages from codragraph
|
|
2
|
+
* Re-export SupportedLanguages from @codragraph/shared (single source of truth).
|
|
3
3
|
*
|
|
4
4
|
* HOW TO ADD A NEW LANGUAGE:
|
|
5
5
|
*
|
|
6
|
-
* 1. Add the enum member in
|
|
6
|
+
* 1. Add the enum member in packages/shared/src/languages.ts
|
|
7
7
|
* 2. Run `tsc --noEmit` — compiler errors guide you to every dispatch table
|
|
8
8
|
* 3. Use the checklist in each ingestion file for what to add
|
|
9
|
-
* 4. Add tree-sitter-<lang> to
|
|
9
|
+
* 4. Add tree-sitter-<lang> to packages/core/package.json dependencies
|
|
10
10
|
* 5. Add file extension mapping in utils.ts getLanguageFromFilename()
|
|
11
11
|
* 6. Run full test suite
|
|
12
12
|
*/
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Re-export SupportedLanguages from codragraph
|
|
2
|
+
* Re-export SupportedLanguages from @codragraph/shared (single source of truth).
|
|
3
3
|
*
|
|
4
4
|
* HOW TO ADD A NEW LANGUAGE:
|
|
5
5
|
*
|
|
6
|
-
* 1. Add the enum member in
|
|
6
|
+
* 1. Add the enum member in packages/shared/src/languages.ts
|
|
7
7
|
* 2. Run `tsc --noEmit` — compiler errors guide you to every dispatch table
|
|
8
8
|
* 3. Use the checklist in each ingestion file for what to add
|
|
9
|
-
* 4. Add tree-sitter-<lang> to
|
|
9
|
+
* 4. Add tree-sitter-<lang> to packages/core/package.json dependencies
|
|
10
10
|
* 5. Add file extension mapping in utils.ts getLanguageFromFilename()
|
|
11
11
|
* 6. Run full test suite
|
|
12
12
|
*/
|
|
@@ -507,7 +507,8 @@ const getCopyQuery = (table, filePath) => {
|
|
|
507
507
|
// RFC 0001 Phase 2: every content-bearing table also lists
|
|
508
508
|
// `contentEncoding` immediately after `content` to match the schema +
|
|
509
509
|
// CSV layout. Tables without a content column (Folder, Community,
|
|
510
|
-
// Process, Route, Tool) are unchanged.
|
|
510
|
+
// Process, Route, Tool) are unchanged. FeatureCluster carries rich metadata
|
|
511
|
+
// but still has no content/file snippet column.
|
|
511
512
|
if (table === 'File') {
|
|
512
513
|
return `COPY ${t}(id, name, filePath, content, contentEncoding) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
513
514
|
}
|
|
@@ -520,6 +521,9 @@ const getCopyQuery = (table, filePath) => {
|
|
|
520
521
|
if (table === 'Process') {
|
|
521
522
|
return `COPY ${t}(id, label, heuristicLabel, processType, stepCount, communities, entryPointId, terminalId) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
522
523
|
}
|
|
524
|
+
if (table === 'FeatureCluster') {
|
|
525
|
+
return `COPY ${t}(id, name, slug, featureKind, summary, description, repo, service, signals, memberCount, entryPointIds, routes, tools, testCoverageHints, lastIndexedCommit, confidence, source) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
526
|
+
}
|
|
523
527
|
if (table === 'Section') {
|
|
524
528
|
return `COPY ${t}(id, name, filePath, startLine, endLine, level, content, contentEncoding, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
525
529
|
}
|
|
@@ -557,6 +561,9 @@ export const insertNodeToCgdb = async (label, properties, dbPath) => {
|
|
|
557
561
|
return 'NULL';
|
|
558
562
|
if (typeof v === 'number')
|
|
559
563
|
return String(v);
|
|
564
|
+
if (Array.isArray(v)) {
|
|
565
|
+
return `[${v.map((item) => `'${String(item).replace(/\\/g, '\\\\').replace(/'/g, "''")}'`).join(',')}]`;
|
|
566
|
+
}
|
|
560
567
|
// Escape backslashes first (for Windows paths), then single quotes
|
|
561
568
|
return `'${String(v).replace(/\\/g, '\\\\').replace(/'/g, "''").replace(/\n/g, '\\n').replace(/\r/g, '\\r')}'`;
|
|
562
569
|
};
|
|
@@ -575,6 +582,9 @@ export const insertNodeToCgdb = async (label, properties, dbPath) => {
|
|
|
575
582
|
: '';
|
|
576
583
|
query = `CREATE (n:Section {id: ${escapeValue(properties.id)}, name: ${escapeValue(properties.name)}, filePath: ${escapeValue(properties.filePath)}, startLine: ${properties.startLine || 0}, endLine: ${properties.endLine || 0}, level: ${properties.level || 1}, content: ${escapeValue(properties.content || '')}${descPart}})`;
|
|
577
584
|
}
|
|
585
|
+
else if (label === 'FeatureCluster') {
|
|
586
|
+
query = `CREATE (n:FeatureCluster {id: ${escapeValue(properties.id)}, name: ${escapeValue(properties.name)}, slug: ${escapeValue(properties.slug)}, featureKind: ${escapeValue(properties.featureKind || 'feature')}, summary: ${escapeValue(properties.summary || '')}, description: ${escapeValue(properties.description || '')}, repo: ${escapeValue(properties.repo || '')}, service: ${escapeValue(properties.service || '')}, signals: ${escapeValue(properties.signals || [])}, memberCount: ${properties.memberCount || 0}, entryPointIds: ${escapeValue(properties.entryPointIds || [])}, routes: ${escapeValue(properties.routes || [])}, tools: ${escapeValue(properties.tools || [])}, testCoverageHints: ${escapeValue(properties.testCoverageHints || [])}, lastIndexedCommit: ${escapeValue(properties.lastIndexedCommit || '')}, confidence: ${properties.confidence || 0}, source: ${escapeValue(properties.source || 'heuristic')}})`;
|
|
587
|
+
}
|
|
578
588
|
else if (TABLES_WITH_EXPORTED.has(label)) {
|
|
579
589
|
const descPart = properties.description
|
|
580
590
|
? `, description: ${escapeValue(properties.description)}`
|
|
@@ -635,6 +645,9 @@ export const batchInsertNodesToCgdb = async (nodes, dbPath) => {
|
|
|
635
645
|
return 'NULL';
|
|
636
646
|
if (typeof v === 'number')
|
|
637
647
|
return String(v);
|
|
648
|
+
if (Array.isArray(v)) {
|
|
649
|
+
return `[${v.map((item) => `'${String(item).replace(/\\/g, '\\\\').replace(/'/g, "''")}'`).join(',')}]`;
|
|
650
|
+
}
|
|
638
651
|
// Escape backslashes first (for Windows paths), then single quotes, then newlines
|
|
639
652
|
return `'${String(v).replace(/\\/g, '\\\\').replace(/'/g, "''").replace(/\n/g, '\\n').replace(/\r/g, '\\r')}'`;
|
|
640
653
|
};
|
|
@@ -661,6 +674,9 @@ export const batchInsertNodesToCgdb = async (nodes, dbPath) => {
|
|
|
661
674
|
: '';
|
|
662
675
|
query = `MERGE (n:Section {id: ${escapeValue(properties.id)}}) SET n.name = ${escapeValue(properties.name)}, n.filePath = ${escapeValue(properties.filePath)}, n.startLine = ${properties.startLine || 0}, n.endLine = ${properties.endLine || 0}, n.level = ${properties.level || 1}, n.content = ${escapeValue(properties.content || '')}${descPart}`;
|
|
663
676
|
}
|
|
677
|
+
else if (label === 'FeatureCluster') {
|
|
678
|
+
query = `MERGE (n:FeatureCluster {id: ${escapeValue(properties.id)}}) SET n.name = ${escapeValue(properties.name)}, n.slug = ${escapeValue(properties.slug)}, n.featureKind = ${escapeValue(properties.featureKind || 'feature')}, n.summary = ${escapeValue(properties.summary || '')}, n.description = ${escapeValue(properties.description || '')}, n.repo = ${escapeValue(properties.repo || '')}, n.service = ${escapeValue(properties.service || '')}, n.signals = ${escapeValue(properties.signals || [])}, n.memberCount = ${properties.memberCount || 0}, n.entryPointIds = ${escapeValue(properties.entryPointIds || [])}, n.routes = ${escapeValue(properties.routes || [])}, n.tools = ${escapeValue(properties.tools || [])}, n.testCoverageHints = ${escapeValue(properties.testCoverageHints || [])}, n.lastIndexedCommit = ${escapeValue(properties.lastIndexedCommit || '')}, n.confidence = ${properties.confidence || 0}, n.source = ${escapeValue(properties.source || 'heuristic')}`;
|
|
679
|
+
}
|
|
664
680
|
else if (TABLES_WITH_EXPORTED.has(label)) {
|
|
665
681
|
const descPart = properties.description
|
|
666
682
|
? `, n.description = ${escapeValue(properties.description)}`
|
|
@@ -1103,8 +1119,8 @@ export const deleteNodesForFile = async (filePath, dbPath) => {
|
|
|
1103
1119
|
// Delete nodes from each table that has filePath
|
|
1104
1120
|
// DETACH DELETE removes the node and all its relationships
|
|
1105
1121
|
for (const tableName of NODE_TABLES) {
|
|
1106
|
-
// Skip tables that don't have filePath (Community, Process)
|
|
1107
|
-
if (tableName === 'Community' || tableName === 'Process')
|
|
1122
|
+
// Skip tables that don't have filePath (Community, Process, FeatureCluster)
|
|
1123
|
+
if (tableName === 'Community' || tableName === 'Process' || tableName === 'FeatureCluster')
|
|
1108
1124
|
continue;
|
|
1109
1125
|
try {
|
|
1110
1126
|
// First count how many we'll delete
|
|
@@ -40,6 +40,13 @@ export const escapeCSVNumber = (value, defaultValue = -1) => {
|
|
|
40
40
|
return String(defaultValue);
|
|
41
41
|
return String(value);
|
|
42
42
|
};
|
|
43
|
+
const toCgdbStringArray = (value) => {
|
|
44
|
+
const values = Array.isArray(value) ? value : [];
|
|
45
|
+
return `[${values
|
|
46
|
+
.map((item) => String(item).replace(/\\/g, '\\\\').replace(/'/g, "''").replace(/,/g, '\\,'))
|
|
47
|
+
.map((item) => `'${item}'`)
|
|
48
|
+
.join(',')}]`;
|
|
49
|
+
};
|
|
43
50
|
// ============================================================================
|
|
44
51
|
// CONTENT EXTRACTION (lazy — reads from disk on demand)
|
|
45
52
|
// ============================================================================
|
|
@@ -231,6 +238,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir, compress) =>
|
|
|
231
238
|
const codeElemWriter = new BufferedCSVWriter(path.join(csvDir, 'codeelement.csv'), codeElementHeader);
|
|
232
239
|
const communityWriter = new BufferedCSVWriter(path.join(csvDir, 'community.csv'), 'id,label,heuristicLabel,keywords,description,enrichedBy,cohesion,symbolCount');
|
|
233
240
|
const processWriter = new BufferedCSVWriter(path.join(csvDir, 'process.csv'), 'id,label,heuristicLabel,processType,stepCount,communities,entryPointId,terminalId');
|
|
241
|
+
const featureClusterWriter = new BufferedCSVWriter(path.join(csvDir, 'featurecluster.csv'), 'id,name,slug,featureKind,summary,description,repo,service,signals,memberCount,entryPointIds,routes,tools,testCoverageHints,lastIndexedCommit,confidence,source');
|
|
234
242
|
// Section nodes have an extra 'level' column
|
|
235
243
|
const sectionWriter = new BufferedCSVWriter(path.join(csvDir, 'section.csv'), 'id,name,filePath,startLine,endLine,level,content,contentEncoding,description');
|
|
236
244
|
// Route nodes for API endpoint mapping
|
|
@@ -315,8 +323,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir, compress) =>
|
|
|
315
323
|
break;
|
|
316
324
|
}
|
|
317
325
|
case 'Process': {
|
|
318
|
-
const
|
|
319
|
-
const communitiesStr = `[${communities.map((c) => `'${c.replace(/'/g, "''")}'`).join(',')}]`;
|
|
326
|
+
const communitiesStr = toCgdbStringArray(node.properties.communities);
|
|
320
327
|
await processWriter.addRow([
|
|
321
328
|
escapeCSVField(node.id),
|
|
322
329
|
escapeCSVField(node.properties.name || ''),
|
|
@@ -329,6 +336,28 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir, compress) =>
|
|
|
329
336
|
].join(','));
|
|
330
337
|
break;
|
|
331
338
|
}
|
|
339
|
+
case 'FeatureCluster': {
|
|
340
|
+
await featureClusterWriter.addRow([
|
|
341
|
+
escapeCSVField(node.id),
|
|
342
|
+
escapeCSVField(node.properties.name || ''),
|
|
343
|
+
escapeCSVField(node.properties.slug || ''),
|
|
344
|
+
escapeCSVField(node.properties.featureKind || 'feature'),
|
|
345
|
+
escapeCSVField(node.properties.summary || ''),
|
|
346
|
+
escapeCSVField(node.properties.description || ''),
|
|
347
|
+
escapeCSVField(node.properties.repo || ''),
|
|
348
|
+
escapeCSVField(node.properties.service || ''),
|
|
349
|
+
escapeCSVField(toCgdbStringArray(node.properties.signals)),
|
|
350
|
+
escapeCSVNumber(node.properties.memberCount, 0),
|
|
351
|
+
escapeCSVField(toCgdbStringArray(node.properties.entryPointIds)),
|
|
352
|
+
escapeCSVField(toCgdbStringArray(node.properties.routes)),
|
|
353
|
+
escapeCSVField(toCgdbStringArray(node.properties.tools)),
|
|
354
|
+
escapeCSVField(toCgdbStringArray(node.properties.testCoverageHints)),
|
|
355
|
+
escapeCSVField(node.properties.lastIndexedCommit || ''),
|
|
356
|
+
escapeCSVNumber(node.properties.confidence, 0),
|
|
357
|
+
escapeCSVField(node.properties.source || 'heuristic'),
|
|
358
|
+
].join(','));
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
332
361
|
case 'Method': {
|
|
333
362
|
const content = await extractContent(node, contentCache);
|
|
334
363
|
const { wireContent, tag } = applyEncoding(content, compress);
|
|
@@ -441,6 +470,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir, compress) =>
|
|
|
441
470
|
codeElemWriter,
|
|
442
471
|
communityWriter,
|
|
443
472
|
processWriter,
|
|
473
|
+
featureClusterWriter,
|
|
444
474
|
sectionWriter,
|
|
445
475
|
routeWriter,
|
|
446
476
|
toolWriter,
|
|
@@ -473,6 +503,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir, compress) =>
|
|
|
473
503
|
['CodeElement', codeElemWriter],
|
|
474
504
|
['Community', communityWriter],
|
|
475
505
|
['Process', processWriter],
|
|
506
|
+
['FeatureCluster', featureClusterWriter],
|
|
476
507
|
['Section', sectionWriter],
|
|
477
508
|
['Route', routeWriter],
|
|
478
509
|
['Tool', toolWriter],
|
|
@@ -20,6 +20,7 @@ export declare const METHOD_SCHEMA = "\nCREATE NODE TABLE Method (\n id STRING,
|
|
|
20
20
|
export declare const CODE_ELEMENT_SCHEMA = "\nCREATE NODE TABLE CodeElement (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n contentEncoding STRING DEFAULT 'none',\n description STRING,\n PRIMARY KEY (id)\n)";
|
|
21
21
|
export declare const COMMUNITY_SCHEMA = "\nCREATE NODE TABLE Community (\n id STRING,\n label STRING,\n heuristicLabel STRING,\n keywords STRING[],\n description STRING,\n enrichedBy STRING,\n cohesion DOUBLE,\n symbolCount INT32,\n PRIMARY KEY (id)\n)";
|
|
22
22
|
export declare const PROCESS_SCHEMA = "\nCREATE NODE TABLE Process (\n id STRING,\n label STRING,\n heuristicLabel STRING,\n processType STRING,\n stepCount INT32,\n communities STRING[],\n entryPointId STRING,\n terminalId STRING,\n PRIMARY KEY (id)\n)";
|
|
23
|
+
export declare const FEATURE_CLUSTER_SCHEMA = "\nCREATE NODE TABLE FeatureCluster (\n id STRING,\n name STRING,\n slug STRING,\n featureKind STRING,\n summary STRING,\n description STRING,\n repo STRING,\n service STRING,\n signals STRING[],\n memberCount INT32,\n entryPointIds STRING[],\n routes STRING[],\n tools STRING[],\n testCoverageHints STRING[],\n lastIndexedCommit STRING,\n confidence DOUBLE,\n source STRING,\n PRIMARY KEY (id)\n)";
|
|
23
24
|
export declare const STRUCT_SCHEMA: string;
|
|
24
25
|
export declare const ENUM_SCHEMA: string;
|
|
25
26
|
export declare const MACRO_SCHEMA: string;
|
|
@@ -42,7 +43,7 @@ export declare const MODULE_SCHEMA: string;
|
|
|
42
43
|
export declare const ROUTE_SCHEMA = "\nCREATE NODE TABLE Route (\n id STRING,\n name STRING,\n filePath STRING,\n responseKeys STRING[],\n errorKeys STRING[],\n middleware STRING[],\n PRIMARY KEY (id)\n)";
|
|
43
44
|
export declare const TOOL_SCHEMA = "\nCREATE NODE TABLE Tool (\n id STRING,\n name STRING,\n filePath STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
|
|
44
45
|
export declare const SECTION_SCHEMA = "\nCREATE NODE TABLE Section (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n level INT64,\n content STRING,\n contentEncoding STRING DEFAULT 'none',\n description STRING,\n PRIMARY KEY (id)\n)";
|
|
45
|
-
export declare const RELATION_SCHEMA = "\nCREATE REL TABLE CodeRelation (\n FROM File TO File,\n FROM File TO Folder,\n FROM File TO Function,\n FROM File TO Class,\n FROM File TO Interface,\n FROM File TO Method,\n FROM File TO CodeElement,\n FROM File TO `Struct`,\n FROM File TO `Enum`,\n FROM File TO `Macro`,\n FROM File TO `Typedef`,\n FROM File TO `Union`,\n FROM File TO `Namespace`,\n FROM File TO `Trait`,\n FROM File TO `Impl`,\n FROM File TO `TypeAlias`,\n FROM File TO `Const`,\n FROM File TO `Static`,\n FROM File TO `Variable`,\n FROM File TO `Property`,\n FROM File TO `Record`,\n FROM File TO `Delegate`,\n FROM File TO `Annotation`,\n FROM File TO `Constructor`,\n FROM File TO `Template`,\n FROM File TO `Module`,\n FROM File TO Section,\n FROM Folder TO Folder,\n FROM Folder TO File,\n FROM Function TO Function,\n FROM Function TO Method,\n FROM Function TO Class,\n FROM Function TO Community,\n FROM Function TO `Macro`,\n FROM Function TO `Struct`,\n FROM Function TO `Template`,\n FROM Function TO `Enum`,\n FROM Function TO `Namespace`,\n FROM Function TO `TypeAlias`,\n FROM Function TO `Module`,\n FROM Function TO `Impl`,\n FROM Function TO Interface,\n FROM Function TO `Constructor`,\n FROM Function TO `Const`,\n FROM Function TO `Typedef`,\n FROM Function TO `Union`,\n FROM Function TO `Property`,\n FROM Function TO CodeElement,\n FROM Class TO Method,\n FROM Class TO Function,\n FROM Class TO Class,\n FROM Class TO Interface,\n FROM Class TO Community,\n FROM Class TO `Template`,\n FROM Class TO `TypeAlias`,\n FROM Class TO `Struct`,\n FROM Class TO `Enum`,\n FROM Class TO `Annotation`,\n FROM Class TO `Constructor`,\n FROM Class TO `Trait`,\n FROM Class TO `Macro`,\n FROM Class TO `Impl`,\n FROM Class TO `Union`,\n FROM Class TO `Namespace`,\n FROM Class TO `Typedef`,\n FROM Class TO `Property`,\n FROM Method TO Function,\n FROM Method TO Method,\n FROM Method TO Class,\n FROM Method TO Community,\n FROM Method TO `Template`,\n FROM Method TO `Struct`,\n FROM Method TO `TypeAlias`,\n FROM Method TO `Enum`,\n FROM Method TO `Macro`,\n FROM Method TO `Namespace`,\n FROM Method TO `Module`,\n FROM Method TO `Impl`,\n FROM Method TO Interface,\n FROM Method TO `Constructor`,\n FROM Method TO `Property`,\n FROM Method TO CodeElement,\n FROM `Template` TO `Template`,\n FROM `Template` TO Function,\n FROM `Template` TO Method,\n FROM `Template` TO Class,\n FROM `Template` TO `Struct`,\n FROM `Template` TO `TypeAlias`,\n FROM `Template` TO `Enum`,\n FROM `Template` TO `Macro`,\n FROM `Template` TO Interface,\n FROM `Template` TO `Constructor`,\n FROM `Module` TO `Module`,\n FROM Section TO Section,\n FROM Section TO File,\n FROM File TO Route,\n FROM Function TO Route,\n FROM Method TO Route,\n FROM File TO Tool,\n FROM Function TO Tool,\n FROM Method TO Tool,\n FROM CodeElement TO Community,\n FROM Interface TO Community,\n FROM Interface TO Function,\n FROM Interface TO Method,\n FROM Interface TO Class,\n FROM Interface TO Interface,\n FROM Interface TO `TypeAlias`,\n FROM Interface TO `Struct`,\n FROM Interface TO `Constructor`,\n FROM Interface TO `Property`,\n FROM `Struct` TO Community,\n FROM `Struct` TO `Trait`,\n FROM `Struct` TO `Struct`,\n FROM `Struct` TO Class,\n FROM `Struct` TO `Enum`,\n FROM `Struct` TO Function,\n FROM `Struct` TO Method,\n FROM `Struct` TO Interface,\n FROM `Struct` TO `Constructor`,\n FROM `Struct` TO `Property`,\n FROM `Enum` TO `Enum`,\n FROM `Enum` TO Community,\n FROM `Enum` TO Class,\n FROM `Enum` TO Interface,\n FROM `Macro` TO Community,\n FROM `Macro` TO Function,\n FROM `Macro` TO Method,\n FROM `Module` TO Function,\n FROM `Module` TO Method,\n FROM `Typedef` TO Community,\n FROM `Union` TO Community,\n FROM `Namespace` TO Community,\n FROM `Namespace` TO `Struct`,\n FROM `Trait` TO Method,\n FROM `Trait` TO `Constructor`,\n FROM `Trait` TO `Property`,\n FROM `Trait` TO Community,\n FROM `Impl` TO Method,\n FROM `Impl` TO `Constructor`,\n FROM `Impl` TO `Property`,\n FROM `Impl` TO Community,\n FROM `Impl` TO `Trait`,\n FROM `Impl` TO `Struct`,\n FROM `Impl` TO `Impl`,\n FROM `TypeAlias` TO Community,\n FROM `TypeAlias` TO `Trait`,\n FROM `TypeAlias` TO Class,\n FROM `Const` TO Community,\n FROM `Static` TO Community,\n FROM `Variable` TO Community,\n FROM `Property` TO Community,\n FROM `Record` TO Method,\n FROM `Record` TO `Constructor`,\n FROM `Record` TO `Property`,\n FROM `Record` TO Community,\n FROM `Delegate` TO Community,\n FROM `Annotation` TO Community,\n FROM `Constructor` TO Community,\n FROM `Constructor` TO Interface,\n FROM `Constructor` TO Class,\n FROM `Constructor` TO Method,\n FROM `Constructor` TO Function,\n FROM `Constructor` TO `Constructor`,\n FROM `Constructor` TO `Struct`,\n FROM `Constructor` TO `Macro`,\n FROM `Constructor` TO `Template`,\n FROM `Constructor` TO `TypeAlias`,\n FROM `Constructor` TO `Enum`,\n FROM `Constructor` TO `Annotation`,\n FROM `Constructor` TO `Impl`,\n FROM `Constructor` TO `Namespace`,\n FROM `Constructor` TO `Module`,\n FROM `Constructor` TO `Property`,\n FROM `Constructor` TO `Typedef`,\n FROM `Template` TO Community,\n FROM `Module` TO Community,\n FROM Function TO Process,\n FROM Method TO Process,\n FROM Class TO Process,\n FROM Interface TO Process,\n FROM `Struct` TO Process,\n FROM `Constructor` TO Process,\n FROM `Module` TO Process,\n FROM `Macro` TO Process,\n FROM `Impl` TO Process,\n FROM `Typedef` TO Process,\n FROM `TypeAlias` TO Process,\n FROM `Enum` TO Process,\n FROM `Union` TO Process,\n FROM `Namespace` TO Process,\n FROM `Trait` TO Process,\n FROM `Const` TO Process,\n FROM `Static` TO Process,\n FROM `Variable` TO Process,\n FROM `Property` TO Process,\n FROM `Record` TO Process,\n FROM `Delegate` TO Process,\n FROM `Annotation` TO Process,\n FROM `Template` TO Process,\n FROM CodeElement TO Process,\n FROM Route TO Process,\n FROM Tool TO Process,\n type STRING,\n confidence DOUBLE,\n reason STRING,\n step INT32\n)";
|
|
46
|
+
export declare const RELATION_SCHEMA = "\nCREATE REL TABLE CodeRelation (\n FROM File TO File,\n FROM File TO Folder,\n FROM File TO Function,\n FROM File TO Class,\n FROM File TO Interface,\n FROM File TO Method,\n FROM File TO CodeElement,\n FROM File TO `Struct`,\n FROM File TO `Enum`,\n FROM File TO `Macro`,\n FROM File TO `Typedef`,\n FROM File TO `Union`,\n FROM File TO `Namespace`,\n FROM File TO `Trait`,\n FROM File TO `Impl`,\n FROM File TO `TypeAlias`,\n FROM File TO `Const`,\n FROM File TO `Static`,\n FROM File TO `Variable`,\n FROM File TO `Property`,\n FROM File TO `Record`,\n FROM File TO `Delegate`,\n FROM File TO `Annotation`,\n FROM File TO `Constructor`,\n FROM File TO `Template`,\n FROM File TO `Module`,\n FROM File TO Section,\n FROM Folder TO Folder,\n FROM Folder TO File,\n FROM Function TO Function,\n FROM Function TO Method,\n FROM Function TO Class,\n FROM Function TO Community,\n FROM Function TO `Macro`,\n FROM Function TO `Struct`,\n FROM Function TO `Template`,\n FROM Function TO `Enum`,\n FROM Function TO `Namespace`,\n FROM Function TO `TypeAlias`,\n FROM Function TO `Module`,\n FROM Function TO `Impl`,\n FROM Function TO Interface,\n FROM Function TO `Constructor`,\n FROM Function TO `Const`,\n FROM Function TO `Typedef`,\n FROM Function TO `Union`,\n FROM Function TO `Property`,\n FROM Function TO CodeElement,\n FROM Class TO Method,\n FROM Class TO Function,\n FROM Class TO Class,\n FROM Class TO Interface,\n FROM Class TO Community,\n FROM Class TO `Template`,\n FROM Class TO `TypeAlias`,\n FROM Class TO `Struct`,\n FROM Class TO `Enum`,\n FROM Class TO `Annotation`,\n FROM Class TO `Constructor`,\n FROM Class TO `Trait`,\n FROM Class TO `Macro`,\n FROM Class TO `Impl`,\n FROM Class TO `Union`,\n FROM Class TO `Namespace`,\n FROM Class TO `Typedef`,\n FROM Class TO `Property`,\n FROM Method TO Function,\n FROM Method TO Method,\n FROM Method TO Class,\n FROM Method TO Community,\n FROM Method TO `Template`,\n FROM Method TO `Struct`,\n FROM Method TO `TypeAlias`,\n FROM Method TO `Enum`,\n FROM Method TO `Macro`,\n FROM Method TO `Namespace`,\n FROM Method TO `Module`,\n FROM Method TO `Impl`,\n FROM Method TO Interface,\n FROM Method TO `Constructor`,\n FROM Method TO `Property`,\n FROM Method TO CodeElement,\n FROM `Template` TO `Template`,\n FROM `Template` TO Function,\n FROM `Template` TO Method,\n FROM `Template` TO Class,\n FROM `Template` TO `Struct`,\n FROM `Template` TO `TypeAlias`,\n FROM `Template` TO `Enum`,\n FROM `Template` TO `Macro`,\n FROM `Template` TO Interface,\n FROM `Template` TO `Constructor`,\n FROM `Module` TO `Module`,\n FROM Section TO Section,\n FROM Section TO File,\n FROM File TO Route,\n FROM Function TO Route,\n FROM Method TO Route,\n FROM File TO Tool,\n FROM Function TO Tool,\n FROM Method TO Tool,\n FROM CodeElement TO Community,\n FROM Interface TO Community,\n FROM Interface TO Function,\n FROM Interface TO Method,\n FROM Interface TO Class,\n FROM Interface TO Interface,\n FROM Interface TO `TypeAlias`,\n FROM Interface TO `Struct`,\n FROM Interface TO `Constructor`,\n FROM Interface TO `Property`,\n FROM `Struct` TO Community,\n FROM `Struct` TO `Trait`,\n FROM `Struct` TO `Struct`,\n FROM `Struct` TO Class,\n FROM `Struct` TO `Enum`,\n FROM `Struct` TO Function,\n FROM `Struct` TO Method,\n FROM `Struct` TO Interface,\n FROM `Struct` TO `Constructor`,\n FROM `Struct` TO `Property`,\n FROM `Enum` TO `Enum`,\n FROM `Enum` TO Community,\n FROM `Enum` TO Class,\n FROM `Enum` TO Interface,\n FROM `Macro` TO Community,\n FROM `Macro` TO Function,\n FROM `Macro` TO Method,\n FROM `Module` TO Function,\n FROM `Module` TO Method,\n FROM `Typedef` TO Community,\n FROM `Union` TO Community,\n FROM `Namespace` TO Community,\n FROM `Namespace` TO `Struct`,\n FROM `Trait` TO Method,\n FROM `Trait` TO `Constructor`,\n FROM `Trait` TO `Property`,\n FROM `Trait` TO Community,\n FROM `Impl` TO Method,\n FROM `Impl` TO `Constructor`,\n FROM `Impl` TO `Property`,\n FROM `Impl` TO Community,\n FROM `Impl` TO `Trait`,\n FROM `Impl` TO `Struct`,\n FROM `Impl` TO `Impl`,\n FROM `TypeAlias` TO Community,\n FROM `TypeAlias` TO `Trait`,\n FROM `TypeAlias` TO Class,\n FROM `Const` TO Community,\n FROM `Static` TO Community,\n FROM `Variable` TO Community,\n FROM `Property` TO Community,\n FROM `Record` TO Method,\n FROM `Record` TO `Constructor`,\n FROM `Record` TO `Property`,\n FROM `Record` TO Community,\n FROM `Delegate` TO Community,\n FROM `Annotation` TO Community,\n FROM `Constructor` TO Community,\n FROM `Constructor` TO Interface,\n FROM `Constructor` TO Class,\n FROM `Constructor` TO Method,\n FROM `Constructor` TO Function,\n FROM `Constructor` TO `Constructor`,\n FROM `Constructor` TO `Struct`,\n FROM `Constructor` TO `Macro`,\n FROM `Constructor` TO `Template`,\n FROM `Constructor` TO `TypeAlias`,\n FROM `Constructor` TO `Enum`,\n FROM `Constructor` TO `Annotation`,\n FROM `Constructor` TO `Impl`,\n FROM `Constructor` TO `Namespace`,\n FROM `Constructor` TO `Module`,\n FROM `Constructor` TO `Property`,\n FROM `Constructor` TO `Typedef`,\n FROM `Template` TO Community,\n FROM `Module` TO Community,\n FROM Function TO Process,\n FROM Method TO Process,\n FROM Class TO Process,\n FROM Interface TO Process,\n FROM `Struct` TO Process,\n FROM `Constructor` TO Process,\n FROM `Module` TO Process,\n FROM `Macro` TO Process,\n FROM `Impl` TO Process,\n FROM `Typedef` TO Process,\n FROM `TypeAlias` TO Process,\n FROM `Enum` TO Process,\n FROM `Union` TO Process,\n FROM `Namespace` TO Process,\n FROM `Trait` TO Process,\n FROM `Const` TO Process,\n FROM `Static` TO Process,\n FROM `Variable` TO Process,\n FROM `Property` TO Process,\n FROM `Record` TO Process,\n FROM `Delegate` TO Process,\n FROM `Annotation` TO Process,\n FROM `Template` TO Process,\n FROM CodeElement TO Process,\n FROM Route TO Process,\n FROM Tool TO Process,\n FROM File TO FeatureCluster,\n FROM Function TO FeatureCluster,\n FROM Method TO FeatureCluster,\n FROM Class TO FeatureCluster,\n FROM Interface TO FeatureCluster,\n FROM CodeElement TO FeatureCluster,\n FROM Section TO FeatureCluster,\n FROM Route TO FeatureCluster,\n FROM Tool TO FeatureCluster,\n FROM Process TO FeatureCluster,\n FROM `Struct` TO FeatureCluster,\n FROM `Enum` TO FeatureCluster,\n FROM `Macro` TO FeatureCluster,\n FROM `Typedef` TO FeatureCluster,\n FROM `Union` TO FeatureCluster,\n FROM `Namespace` TO FeatureCluster,\n FROM `Trait` TO FeatureCluster,\n FROM `Impl` TO FeatureCluster,\n FROM `TypeAlias` TO FeatureCluster,\n FROM `Const` TO FeatureCluster,\n FROM `Static` TO FeatureCluster,\n FROM `Variable` TO FeatureCluster,\n FROM `Property` TO FeatureCluster,\n FROM `Record` TO FeatureCluster,\n FROM `Delegate` TO FeatureCluster,\n FROM `Annotation` TO FeatureCluster,\n FROM `Constructor` TO FeatureCluster,\n FROM `Template` TO FeatureCluster,\n FROM `Module` TO FeatureCluster,\n FROM FeatureCluster TO FeatureCluster,\n type STRING,\n confidence DOUBLE,\n reason STRING,\n step INT32\n)";
|
|
46
47
|
export declare const EMBEDDING_DIMS: number;
|
|
47
48
|
/** HNSW vector index name for the CodeEmbedding table. */
|
|
48
49
|
export declare const EMBEDDING_INDEX_NAME = "code_embedding_idx";
|
package/dist/core/cgdb/schema.js
CHANGED
|
@@ -139,6 +139,30 @@ CREATE NODE TABLE Process (
|
|
|
139
139
|
PRIMARY KEY (id)
|
|
140
140
|
)`;
|
|
141
141
|
// ============================================================================
|
|
142
|
+
// FEATURE CLUSTER NODE TABLE (human-facing feature/domain clusters)
|
|
143
|
+
// ============================================================================
|
|
144
|
+
export const FEATURE_CLUSTER_SCHEMA = `
|
|
145
|
+
CREATE NODE TABLE FeatureCluster (
|
|
146
|
+
id STRING,
|
|
147
|
+
name STRING,
|
|
148
|
+
slug STRING,
|
|
149
|
+
featureKind STRING,
|
|
150
|
+
summary STRING,
|
|
151
|
+
description STRING,
|
|
152
|
+
repo STRING,
|
|
153
|
+
service STRING,
|
|
154
|
+
signals STRING[],
|
|
155
|
+
memberCount INT32,
|
|
156
|
+
entryPointIds STRING[],
|
|
157
|
+
routes STRING[],
|
|
158
|
+
tools STRING[],
|
|
159
|
+
testCoverageHints STRING[],
|
|
160
|
+
lastIndexedCommit STRING,
|
|
161
|
+
confidence DOUBLE,
|
|
162
|
+
source STRING,
|
|
163
|
+
PRIMARY KEY (id)
|
|
164
|
+
)`;
|
|
165
|
+
// ============================================================================
|
|
142
166
|
// MULTI-LANGUAGE NODE TABLE SCHEMAS
|
|
143
167
|
// ============================================================================
|
|
144
168
|
// Generic code element with startLine/endLine for C, C++, Rust, Go, Java, C#
|
|
@@ -417,6 +441,36 @@ CREATE REL TABLE ${REL_TABLE_NAME} (
|
|
|
417
441
|
FROM CodeElement TO Process,
|
|
418
442
|
FROM Route TO Process,
|
|
419
443
|
FROM Tool TO Process,
|
|
444
|
+
FROM File TO FeatureCluster,
|
|
445
|
+
FROM Function TO FeatureCluster,
|
|
446
|
+
FROM Method TO FeatureCluster,
|
|
447
|
+
FROM Class TO FeatureCluster,
|
|
448
|
+
FROM Interface TO FeatureCluster,
|
|
449
|
+
FROM CodeElement TO FeatureCluster,
|
|
450
|
+
FROM Section TO FeatureCluster,
|
|
451
|
+
FROM Route TO FeatureCluster,
|
|
452
|
+
FROM Tool TO FeatureCluster,
|
|
453
|
+
FROM Process TO FeatureCluster,
|
|
454
|
+
FROM \`Struct\` TO FeatureCluster,
|
|
455
|
+
FROM \`Enum\` TO FeatureCluster,
|
|
456
|
+
FROM \`Macro\` TO FeatureCluster,
|
|
457
|
+
FROM \`Typedef\` TO FeatureCluster,
|
|
458
|
+
FROM \`Union\` TO FeatureCluster,
|
|
459
|
+
FROM \`Namespace\` TO FeatureCluster,
|
|
460
|
+
FROM \`Trait\` TO FeatureCluster,
|
|
461
|
+
FROM \`Impl\` TO FeatureCluster,
|
|
462
|
+
FROM \`TypeAlias\` TO FeatureCluster,
|
|
463
|
+
FROM \`Const\` TO FeatureCluster,
|
|
464
|
+
FROM \`Static\` TO FeatureCluster,
|
|
465
|
+
FROM \`Variable\` TO FeatureCluster,
|
|
466
|
+
FROM \`Property\` TO FeatureCluster,
|
|
467
|
+
FROM \`Record\` TO FeatureCluster,
|
|
468
|
+
FROM \`Delegate\` TO FeatureCluster,
|
|
469
|
+
FROM \`Annotation\` TO FeatureCluster,
|
|
470
|
+
FROM \`Constructor\` TO FeatureCluster,
|
|
471
|
+
FROM \`Template\` TO FeatureCluster,
|
|
472
|
+
FROM \`Module\` TO FeatureCluster,
|
|
473
|
+
FROM FeatureCluster TO FeatureCluster,
|
|
420
474
|
type STRING,
|
|
421
475
|
confidence DOUBLE,
|
|
422
476
|
reason STRING,
|
|
@@ -471,6 +525,7 @@ export const NODE_SCHEMA_QUERIES = [
|
|
|
471
525
|
CODE_ELEMENT_SCHEMA,
|
|
472
526
|
COMMUNITY_SCHEMA,
|
|
473
527
|
PROCESS_SCHEMA,
|
|
528
|
+
FEATURE_CLUSTER_SCHEMA,
|
|
474
529
|
// Multi-language support
|
|
475
530
|
STRUCT_SCHEMA,
|
|
476
531
|
ENUM_SCHEMA,
|
|
@@ -16,6 +16,7 @@ import { pipeline, env } from '@huggingface/transformers';
|
|
|
16
16
|
import { existsSync } from 'fs';
|
|
17
17
|
import { execFileSync } from 'child_process';
|
|
18
18
|
import { join, dirname } from 'path';
|
|
19
|
+
import { homedir } from 'os';
|
|
19
20
|
import { createRequire } from 'module';
|
|
20
21
|
import { DEFAULT_EMBEDDING_CONFIG } from './types.js';
|
|
21
22
|
import { isHttpMode, getHttpDimensions, httpEmbed } from './http-client.js';
|
|
@@ -134,8 +135,9 @@ export const initEmbedder = async (onProgress, config = {}, forceDevice) => {
|
|
|
134
135
|
// Default cache to user-writable location. transformers.js defaults to
|
|
135
136
|
// ./node_modules/.cache inside its own install dir, which is unwritable
|
|
136
137
|
// when codragraph is installed globally (e.g. /usr/lib/node_modules/).
|
|
137
|
-
// Respect HF_HOME if set, otherwise fall back to
|
|
138
|
-
|
|
138
|
+
// Respect HF_HOME if set, otherwise fall back to a user-writable cache
|
|
139
|
+
// path using Node's OS-aware home directory resolution.
|
|
140
|
+
env.cacheDir = process.env.HF_HOME ?? join(homedir(), '.cache', 'huggingface');
|
|
139
141
|
const isDev = process.env.NODE_ENV === 'development';
|
|
140
142
|
if (isDev) {
|
|
141
143
|
console.log(`🧠 Loading embedding model: ${finalConfig.modelId}`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* CodraGraph-side glue for the Phase 4 versioned graph store.
|
|
3
3
|
*
|
|
4
4
|
* The graphstore package itself is engine-agnostic; everything that
|
|
5
5
|
* touches LadybugDB lives here, in codragraph/. Best-effort by design:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* CodraGraph-side glue for the Phase 4 versioned graph store.
|
|
3
3
|
*
|
|
4
4
|
* The graphstore package itself is engine-agnostic; everything that
|
|
5
5
|
* touches LadybugDB lives here, in codragraph/. Best-effort by design:
|
|
@@ -41,6 +41,19 @@ export interface GroupToolPort {
|
|
|
41
41
|
file_path?: string;
|
|
42
42
|
include_content?: boolean;
|
|
43
43
|
}): Promise<unknown>;
|
|
44
|
+
featureClusters?(repo: GroupRepoHandle, params: {
|
|
45
|
+
query?: string;
|
|
46
|
+
limit?: number;
|
|
47
|
+
}): Promise<unknown>;
|
|
48
|
+
featureContext?(repo: GroupRepoHandle, params: {
|
|
49
|
+
name: string;
|
|
50
|
+
limit?: number;
|
|
51
|
+
}): Promise<unknown>;
|
|
52
|
+
featureImpact?(repo: GroupRepoHandle, params: {
|
|
53
|
+
name: string;
|
|
54
|
+
direction?: 'upstream' | 'downstream' | 'both';
|
|
55
|
+
limit?: number;
|
|
56
|
+
}): Promise<unknown>;
|
|
44
57
|
}
|
|
45
58
|
export declare class GroupService {
|
|
46
59
|
private readonly port;
|
|
@@ -51,5 +64,8 @@ export declare class GroupService {
|
|
|
51
64
|
groupImpact(params: Record<string, unknown>): Promise<unknown>;
|
|
52
65
|
groupContext(params: Record<string, unknown>): Promise<GroupContextResult>;
|
|
53
66
|
groupQuery(params: Record<string, unknown>): Promise<unknown>;
|
|
67
|
+
groupFeatureClusters(params: Record<string, unknown>): Promise<unknown>;
|
|
68
|
+
groupFeatureContext(params: Record<string, unknown>): Promise<unknown>;
|
|
69
|
+
groupFeatureImpact(params: Record<string, unknown>): Promise<unknown>;
|
|
54
70
|
groupStatus(params: Record<string, unknown>): Promise<unknown>;
|
|
55
71
|
}
|