@codragraph/cli 2.1.0 → 2.1.4
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 +62 -21
- 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 +46 -26
- package/dist/cli/index.js +39 -1
- package/dist/cli/serve.d.ts +1 -0
- package/dist/cli/serve.js +3 -1
- package/dist/cli/setup.js +42 -21
- package/dist/cli/status.d.ts +13 -0
- package/dist/cli/status.js +99 -0
- package/dist/cli/tool.d.ts +25 -0
- package/dist/cli/tool.js +74 -0
- package/dist/config/ignore-service.js +2 -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/cgdb-row-source.js +3 -2
- package/dist/core/graphstore/index.d.ts +1 -1
- package/dist/core/graphstore/index.js +1 -1
- package/dist/core/group/bridge-db.js +42 -10
- 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 +21 -0
- package/dist/core/run-analyze.js +213 -6
- package/dist/core/search/hybrid-search.js +11 -3
- 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.d.ts +14 -2
- package/dist/server/api.js +206 -7
- package/dist/server/mcp-http.d.ts +22 -0
- package/dist/server/mcp-http.js +21 -2
- package/dist/server/web-dashboard.d.ts +28 -0
- package/dist/server/web-dashboard.js +61 -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/dist/web/assets/agent-D5lb0zXz.js +1089 -0
- package/dist/web/assets/architectureDiagram-EMZXCZ2Q-CZtc99v_.js +36 -0
- package/dist/web/assets/blockDiagram-IGV67L2C-BtoUp-6Y.js +132 -0
- package/dist/web/assets/c4Diagram-DFAF54RM-C4Hl3J2U.js +10 -0
- package/dist/web/assets/chunk-3GS5O3IE-DkUjU0WD.js +231 -0
- package/dist/web/assets/chunk-3YCYZ6SJ-CQkVgT_z.js +1 -0
- package/dist/web/assets/chunk-7RZVMHOQ-BitYcNVR.js +338 -0
- package/dist/web/assets/chunk-AEOMTBSW-BgTIXPsY.js +1 -0
- package/dist/web/assets/chunk-H3VCZNTA-Cx5XV_aC.js +13 -0
- package/dist/web/assets/chunk-HN6EAY2L-BBnyTNdB.js +1 -0
- package/dist/web/assets/chunk-KSICW3F5-BYzvDLNI.js +15 -0
- package/dist/web/assets/chunk-O5ABG6QK-dHwHzA6n.js +1 -0
- package/dist/web/assets/chunk-PK6DOVAG-CvsEnugt.js +206 -0
- package/dist/web/assets/chunk-RWUO3TPN-BgRTY0_k.js +1 -0
- package/dist/web/assets/chunk-TBF5ZNIQ-DL5stGM1.js +1 -0
- package/dist/web/assets/chunk-TU3PZOEN-RLyvLcv-.js +1 -0
- package/dist/web/assets/classDiagram-PPOCWD7C-DTr8QIOf.js +1 -0
- package/dist/web/assets/classDiagram-v2-23LJLIIU-DTr8QIOf.js +1 -0
- package/dist/web/assets/context-builder-22jU3V56.js +16 -0
- package/dist/web/assets/cose-bilkent-PNC4W37J-DVhePRYg.js +1 -0
- package/dist/web/assets/dagre-E77IOHMT-Dzx0A6ZU.js +4 -0
- package/dist/web/assets/diagram-H7BISOXX-CC9pRew1.js +43 -0
- package/dist/web/assets/diagram-JC5VWROH-Bau_i9tf.js +24 -0
- package/dist/web/assets/diagram-LXUTUG65-D9_FM2Gt.js +10 -0
- package/dist/web/assets/diagram-WEHSV5V5-BMlayouL.js +24 -0
- package/dist/web/assets/erDiagram-GCSMX5X6-C3dhDFA8.js +85 -0
- package/dist/web/assets/flowDiagram-OTCZ4VVT-CWSFWmhr.js +162 -0
- package/dist/web/assets/ganttDiagram-MUNLMDZQ-D3a67Yol.js +292 -0
- package/dist/web/assets/gitGraphDiagram-3HKGZ4G3-7jmry-vM.js +106 -0
- package/dist/web/assets/index-BgeqpYgd.js +1415 -0
- package/dist/web/assets/index-CT0GtFLZ.css +1 -0
- package/dist/web/assets/infoDiagram-MN7RKWGX-G7lhP0Ib.js +2 -0
- package/dist/web/assets/ishikawaDiagram-YMYX4NHK-DUoJvNP2.js +70 -0
- package/dist/web/assets/journeyDiagram-SO5T7YLQ-RMFPNNqz.js +139 -0
- package/dist/web/assets/kanban-definition-LJHFXRCJ-BzpDs1K9.js +89 -0
- package/dist/web/assets/katex-GD7MH7QM-DBQvrix-.js +261 -0
- package/dist/web/assets/mindmap-definition-2EUWGEK5-Bk0O4roa.js +96 -0
- package/dist/web/assets/pieDiagram-3IATQBI2-DKU7kpgS.js +30 -0
- package/dist/web/assets/quadrantDiagram-E256RVCF-BY0TGWCS.js +7 -0
- package/dist/web/assets/requirementDiagram-M5DCFWZL-DLHOVTSv.js +84 -0
- package/dist/web/assets/sankeyDiagram-L3NBLAOT-DVMj5rX2.js +10 -0
- package/dist/web/assets/sequenceDiagram-ZOUHS735-CJC73bV-.js +157 -0
- package/dist/web/assets/stateDiagram-MLPALWAM-BCFyESls.js +1 -0
- package/dist/web/assets/stateDiagram-v2-B5LQ5ZB2-DahzzIca.js +1 -0
- package/dist/web/assets/timeline-definition-5SPVSISX-TRSDRgPw.js +120 -0
- package/dist/web/assets/vennDiagram-IE5QUKF5-DNy7HRBM.js +34 -0
- package/dist/web/assets/wardley-RL74JXVD-BCRCBASE-B-eZEzf9.js +161 -0
- package/dist/web/assets/wardleyDiagram-XU3VSMPF-BP-r1xzR.js +20 -0
- package/dist/web/assets/xychartDiagram-ZHJ5623Y-Dr9r7a35.js +7 -0
- package/dist/web/codragraph-logo-512.png +0 -0
- package/dist/web/codragraph-logo.png +0 -0
- package/dist/web/favicon.png +0 -0
- package/dist/web/index.html +36 -0
- package/hooks/claude/codragraph-hook.cjs +24 -9
- package/hooks/claude/pre-tool-use.sh +6 -1
- package/package.json +15 -4
- package/scripts/build.js +75 -16
- package/scripts/patch-tree-sitter-swift.cjs +0 -1
- package/skills/codragraph-cli.md +17 -1
- package/skills/codragraph-guide.md +6 -2
- package/skills/codragraph-onboarding.md +2 -2
- package/vendor/leiden/index.cjs +272 -285
- package/vendor/leiden/utils.cjs +264 -274
- package/dist/_shared/lbug/schema-constants.d.ts +0 -16
- package/dist/_shared/lbug/schema-constants.d.ts.map +0 -1
- package/dist/_shared/lbug/schema-constants.js +0 -67
- package/dist/_shared/lbug/schema-constants.js.map +0 -1
- package/dist/core/graphstore/lbug-row-source.d.ts +0 -19
- package/dist/core/graphstore/lbug-row-source.js +0 -141
- package/dist/core/lbug/content-read.d.ts +0 -46
- package/dist/core/lbug/content-read.js +0 -64
- package/dist/core/lbug/csv-generator.d.ts +0 -29
- package/dist/core/lbug/csv-generator.js +0 -492
- package/dist/core/lbug/lbug-adapter.d.ts +0 -176
- package/dist/core/lbug/lbug-adapter.js +0 -1320
- package/dist/core/lbug/pool-adapter.d.ts +0 -93
- package/dist/core/lbug/pool-adapter.js +0 -550
- package/dist/core/lbug/schema.d.ts +0 -62
- package/dist/core/lbug/schema.js +0 -502
- package/dist/mcp/core/lbug-adapter.d.ts +0 -5
- package/dist/mcp/core/lbug-adapter.js +0 -5
package/dist/cli/analyze.js
CHANGED
|
@@ -12,12 +12,17 @@ import { execFileSync } from 'child_process';
|
|
|
12
12
|
import v8 from 'v8';
|
|
13
13
|
import cliProgress from 'cli-progress';
|
|
14
14
|
import * as fsSync from 'node:fs';
|
|
15
|
+
import { createRequire } from 'module';
|
|
15
16
|
import { closeCgdb } from '../core/cgdb/cgdb-adapter.js';
|
|
16
17
|
import { getStoragePaths, getGlobalRegistryPath, RegistryNameCollisionError, } from '../storage/repo-manager.js';
|
|
17
18
|
import { getGitRoot, hasGitDir } from '../storage/git.js';
|
|
18
19
|
import { runFullAnalysis } from '../core/run-analyze.js';
|
|
19
20
|
import { getMaxFileSizeBannerMessage } from '../core/ingestion/utils/max-file-size.js';
|
|
20
21
|
import fs from 'fs/promises';
|
|
22
|
+
import { formatBytes, LARGE_INDEX_WARNING_BYTES, summarizeIndexStorage } from './status.js';
|
|
23
|
+
const require = createRequire(import.meta.url);
|
|
24
|
+
const pkg = require('../../package.json');
|
|
25
|
+
const CLI_PACKAGE_SPEC = `@codragraph/cli@${pkg.version}`;
|
|
21
26
|
const HEAP_MB = 8192;
|
|
22
27
|
const HEAP_FLAG = `--max-old-space-size=${HEAP_MB}`;
|
|
23
28
|
/** Increase default stack size (KB) to prevent stack overflow on deep class hierarchies. */
|
|
@@ -105,25 +110,6 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
105
110
|
}
|
|
106
111
|
});
|
|
107
112
|
}
|
|
108
|
-
// ── First-run auto-setup ───────────────────────────────────────────
|
|
109
|
-
// Makes `npx @codragraph/cli analyze` a true one-command entry. We detect
|
|
110
|
-
// first-run by the absence of the global registry — analyze writes to it on
|
|
111
|
-
// every successful index, so it's a reliable "this user has never run us
|
|
112
|
-
// before" signal. Opt out with `--no-setup` for CI / headless contexts;
|
|
113
|
-
// commander maps `--no-setup` to `options.setup === false`.
|
|
114
|
-
if (options?.setup !== false) {
|
|
115
|
-
let registryExists = true;
|
|
116
|
-
try {
|
|
117
|
-
await fs.access(getGlobalRegistryPath());
|
|
118
|
-
}
|
|
119
|
-
catch {
|
|
120
|
-
registryExists = false;
|
|
121
|
-
}
|
|
122
|
-
if (!registryExists) {
|
|
123
|
-
const { runSetup } = await import('./setup.js');
|
|
124
|
-
await runSetup({ skipNextSteps: true, compactHeader: true });
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
113
|
console.log('\n CodraGraph Analyzer\n');
|
|
128
114
|
let repoPath;
|
|
129
115
|
if (inputPath) {
|
|
@@ -153,6 +139,23 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
153
139
|
if (!repoHasGit) {
|
|
154
140
|
console.log(' Warning: no .git directory found \u2014 commit-tracking and incremental updates disabled.\n');
|
|
155
141
|
}
|
|
142
|
+
// ── First-run auto-setup ───────────────────────────────────────────
|
|
143
|
+
// Makes `npx @codragraph/cli analyze` a true one-command entry. Validate
|
|
144
|
+
// the target repo first so invalid invocations fail fast without mutating
|
|
145
|
+
// editor/global config.
|
|
146
|
+
if (options?.setup !== false) {
|
|
147
|
+
let registryExists = true;
|
|
148
|
+
try {
|
|
149
|
+
await fs.access(getGlobalRegistryPath());
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
registryExists = false;
|
|
153
|
+
}
|
|
154
|
+
if (!registryExists) {
|
|
155
|
+
const { runSetup } = await import('./setup.js');
|
|
156
|
+
await runSetup({ skipNextSteps: true, compactHeader: true });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
156
159
|
// KuzuDB migration cleanup is handled by runFullAnalysis internally.
|
|
157
160
|
// Note: --skills is handled after runFullAnalysis using the returned pipelineResult.
|
|
158
161
|
if (process.env.CODRAGRAPH_NO_GITIGNORE) {
|
|
@@ -253,7 +256,7 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
253
256
|
console.warn = origWarn;
|
|
254
257
|
console.error = origError;
|
|
255
258
|
bar.stop();
|
|
256
|
-
console.log('
|
|
259
|
+
console.log(` ${result.reuseReason ?? 'Already up to date'}\n`);
|
|
257
260
|
// Safe to return without process.exit(0) — the early-return path in
|
|
258
261
|
// runFullAnalysis never opens LadybugDB, so no native handles prevent exit.
|
|
259
262
|
return;
|
|
@@ -299,7 +302,8 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
299
302
|
nodes: s.nodes ?? 0,
|
|
300
303
|
edges: s.edges ?? 0,
|
|
301
304
|
communities: s.communities,
|
|
302
|
-
clusters:
|
|
305
|
+
clusters: result.pipelineResult?.featureClusterResult?.stats.totalClusters ??
|
|
306
|
+
aggregatedClusterCount,
|
|
303
307
|
processes: s.processes,
|
|
304
308
|
}, skillResult.skills, { skipAgentsMd: options?.skipAgentsMd, noStats: options?.noStats });
|
|
305
309
|
}
|
|
@@ -321,6 +325,20 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
321
325
|
console.log(`\n Repository indexed successfully (${totalTime}s)\n`);
|
|
322
326
|
console.log(` ${(s.nodes ?? 0).toLocaleString()} nodes | ${(s.edges ?? 0).toLocaleString()} edges | ${s.communities ?? 0} clusters | ${s.processes ?? 0} flows`);
|
|
323
327
|
console.log(` ${repoPath}`);
|
|
328
|
+
try {
|
|
329
|
+
const { storagePath } = getStoragePaths(repoPath);
|
|
330
|
+
const storageSummary = await summarizeIndexStorage(storagePath);
|
|
331
|
+
if (storageSummary) {
|
|
332
|
+
console.log(` .codragraph size: ${formatBytes(storageSummary.bytes)}`);
|
|
333
|
+
if (storageSummary.bytes >= LARGE_INDEX_WARNING_BYTES) {
|
|
334
|
+
console.log(` Storage warning: index is >= ${formatBytes(LARGE_INDEX_WARNING_BYTES)}. ` +
|
|
335
|
+
`Use --compress brotli (or zstd on Node >=22.15) and reserve --embeddings for repos that need vector search.`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
/* size summary is best-effort */
|
|
341
|
+
}
|
|
324
342
|
// Surface @codragraph/compress's value prop with concrete numbers: how
|
|
325
343
|
// many tokens of distilled context did we generate. Best-effort — never
|
|
326
344
|
// fail the analyze for a stat read.
|
|
@@ -388,12 +406,13 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
388
406
|
// 'node.target'" crash happens inside npm *before* codragraph code runs,
|
|
389
407
|
// so it can't be caught here. This branch handles dependency-resolution
|
|
390
408
|
// errors that surface at runtime (e.g. dynamic require failures).
|
|
391
|
-
console.error(' This looks like
|
|
409
|
+
console.error(' This looks like a package-manager dependency resolution issue.');
|
|
392
410
|
console.error(' Suggestions:');
|
|
393
411
|
console.error(' 1. Clear the npm cache: npm cache clean --force');
|
|
394
412
|
console.error(' 2. Update npm: npm install -g npm@latest');
|
|
395
|
-
console.error(
|
|
396
|
-
console.error(
|
|
413
|
+
console.error(` 3. Reinstall codragraph: npm install -g ${CLI_PACKAGE_SPEC}`);
|
|
414
|
+
console.error(` 4. Or try npx directly: npx ${CLI_PACKAGE_SPEC} analyze`);
|
|
415
|
+
console.error(` 5. Bun alternative: bunx ${CLI_PACKAGE_SPEC} analyze`);
|
|
397
416
|
console.error('');
|
|
398
417
|
}
|
|
399
418
|
else if (msg.includes('MODULE_NOT_FOUND') ||
|
|
@@ -401,8 +420,9 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
401
420
|
msg.includes('ERR_MODULE_NOT_FOUND')) {
|
|
402
421
|
console.error(' A required module could not be loaded. The installation may be corrupt.');
|
|
403
422
|
console.error(' Suggestions:');
|
|
404
|
-
console.error(
|
|
405
|
-
console.error(
|
|
423
|
+
console.error(` 1. Reinstall: npm install -g ${CLI_PACKAGE_SPEC}`);
|
|
424
|
+
console.error(` 2. Clear cache: npm cache clean --force && npx ${CLI_PACKAGE_SPEC} analyze`);
|
|
425
|
+
console.error(` 3. Bun cache: bun pm cache rm && bunx ${CLI_PACKAGE_SPEC} analyze`);
|
|
406
426
|
console.error('');
|
|
407
427
|
}
|
|
408
428
|
process.exitCode = 1;
|
package/dist/cli/index.js
CHANGED
|
@@ -55,9 +55,10 @@ program
|
|
|
55
55
|
.action(createLazyAction(() => import('./index-repo.js'), 'indexCommand'));
|
|
56
56
|
program
|
|
57
57
|
.command('serve')
|
|
58
|
-
.description('Start local HTTP
|
|
58
|
+
.description('Start local HTTP API and web dashboard')
|
|
59
59
|
.option('-p, --port <port>', 'Port number', '4747')
|
|
60
60
|
.option('--host <host>', 'Bind address (default: 127.0.0.1, use 0.0.0.0 for remote access)')
|
|
61
|
+
.option('--web <mode>', 'Dashboard mode: local serves the bundled app, hosted prints hosted UI connection info, off serves API only', 'local')
|
|
61
62
|
.action(createLazyAction(() => import('./serve.js'), 'serveCommand'));
|
|
62
63
|
program
|
|
63
64
|
.command('mcp')
|
|
@@ -135,6 +136,43 @@ program
|
|
|
135
136
|
.description('Execute raw Cypher query against the knowledge graph')
|
|
136
137
|
.option('-r, --repo <name>', 'Target repository')
|
|
137
138
|
.action(createLazyAction(() => import('./tool.js'), 'cypherCommand'));
|
|
139
|
+
program
|
|
140
|
+
.command('feature-clusters')
|
|
141
|
+
.description('List human-facing feature clusters for targeted context building')
|
|
142
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
143
|
+
.option('-l, --limit <n>', 'Max feature clusters to return (default: 100)')
|
|
144
|
+
.action(createLazyAction(() => import('./tool.js'), 'featureClustersCommand'));
|
|
145
|
+
program
|
|
146
|
+
.command('cluster-query [query]')
|
|
147
|
+
.description('Alias for feature-clusters: list product/domain clusters')
|
|
148
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
149
|
+
.option('-l, --limit <n>', 'Max feature clusters to return (default: 100)')
|
|
150
|
+
.action(createLazyAction(() => import('./tool.js'), 'clusterQueryCommand'));
|
|
151
|
+
program
|
|
152
|
+
.command('feature-context <name>')
|
|
153
|
+
.description('Show members, line ranges, and dependencies for a feature cluster')
|
|
154
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
155
|
+
.option('-l, --limit <n>', 'Max members to return (default: 100)')
|
|
156
|
+
.action(createLazyAction(() => import('./tool.js'), 'featureContextCommand'));
|
|
157
|
+
program
|
|
158
|
+
.command('cluster-context <name>')
|
|
159
|
+
.description('Alias for feature-context: show a feature cluster context pack')
|
|
160
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
161
|
+
.option('-l, --limit <n>', 'Max members to return (default: 100)')
|
|
162
|
+
.action(createLazyAction(() => import('./tool.js'), 'clusterContextCommand'));
|
|
163
|
+
program
|
|
164
|
+
.command('context-pack <name>')
|
|
165
|
+
.description('Generate the compact agent context pack for a feature cluster')
|
|
166
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
167
|
+
.option('-l, --limit <n>', 'Max members to return (default: 100)')
|
|
168
|
+
.action(createLazyAction(() => import('./tool.js'), 'contextPackCommand'));
|
|
169
|
+
program
|
|
170
|
+
.command('cluster-impact <name>')
|
|
171
|
+
.description('Feature-level blast radius analysis for a cluster')
|
|
172
|
+
.option('-d, --direction <dir>', 'upstream, downstream, or both', 'upstream')
|
|
173
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
174
|
+
.option('-l, --limit <n>', 'Max context-pack members to include (default: 100)')
|
|
175
|
+
.action(createLazyAction(() => import('./tool.js'), 'clusterImpactCommand'));
|
|
138
176
|
program
|
|
139
177
|
.command('detect-changes')
|
|
140
178
|
.alias('detect_changes')
|
package/dist/cli/serve.d.ts
CHANGED
package/dist/cli/serve.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createServer } from '../server/api.js';
|
|
2
|
+
import { normalizeWebDashboardMode } from '../server/web-dashboard.js';
|
|
2
3
|
// Catch anything that would cause a silent exit
|
|
3
4
|
process.on('uncaughtException', (err) => {
|
|
4
5
|
console.error('\n[codragraph serve] Uncaught exception:', err.message);
|
|
@@ -19,7 +20,8 @@ export const serveCommand = async (options) => {
|
|
|
19
20
|
// hosted frontend at codragraph.vercel.app connects to localhost.
|
|
20
21
|
const host = options?.host ?? 'localhost';
|
|
21
22
|
try {
|
|
22
|
-
|
|
23
|
+
const web = normalizeWebDashboardMode(options?.web);
|
|
24
|
+
await createServer(port, host, { web });
|
|
23
25
|
}
|
|
24
26
|
catch (err) {
|
|
25
27
|
console.error(`\nFailed to start CodraGraph server:\n`);
|
package/dist/cli/setup.js
CHANGED
|
@@ -11,15 +11,19 @@ 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
|
-
* globally (or via npm -g / yarn global). Returns null when not found.
|
|
26
|
+
* globally (or via npm -g / bun -g / yarn global). Returns null when not found.
|
|
23
27
|
*
|
|
24
28
|
* Note: the npm package is `@codragraph/cli`, but the executable it installs
|
|
25
29
|
* is `codragraph` (see package.json `bin`). PATH lookup must use the bin name.
|
|
@@ -45,7 +49,7 @@ function resolveCodragraphBin() {
|
|
|
45
49
|
.filter(Boolean);
|
|
46
50
|
if (process.platform === 'win32') {
|
|
47
51
|
// Prefer a Windows-executable shim. If none is on PATH, return null so
|
|
48
|
-
// the caller falls through to the
|
|
52
|
+
// the caller falls through to the package-runner fallback.
|
|
49
53
|
const exe = lines.find((l) => /\.(cmd|exe|bat)$/i.test(l));
|
|
50
54
|
return exe ?? null;
|
|
51
55
|
}
|
|
@@ -59,39 +63,61 @@ 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
|
|
66
|
+
* `npx` / `bunx` package execution (cold-cache install of native deps can take
|
|
63
67
|
* >60 s, exceeding Claude Code's 30 s MCP connection timeout).
|
|
64
68
|
*
|
|
65
|
-
* Falls back to
|
|
66
|
-
*
|
|
69
|
+
* Falls back to the package runner that invoked setup when the binary isn't on
|
|
70
|
+
* PATH — e.g. first-time `npx @codragraph/cli` or `bunx @codragraph/cli` users.
|
|
67
71
|
*
|
|
68
72
|
* Windows note: even when the bin is on PATH, we launch via `cmd /c codragraph
|
|
69
73
|
* mcp` rather than writing the resolved path. Reason: `where codragraph`
|
|
70
74
|
* returns the extensionless Unix shim before `codragraph.cmd`, and Node's
|
|
71
75
|
* spawn/execFile cannot launch the extensionless shim on Windows. Letting
|
|
72
76
|
* cmd resolve via PATHEXT is the only reliable path that works for npm-,
|
|
73
|
-
* pnpm-, and yarn-installed shims alike.
|
|
77
|
+
* bun-, pnpm-, and yarn-installed shims alike.
|
|
74
78
|
*/
|
|
75
|
-
function
|
|
76
|
-
const
|
|
77
|
-
|
|
79
|
+
function isRunningUnderBun() {
|
|
80
|
+
const userAgent = (process.env.npm_config_user_agent ?? '').toLowerCase();
|
|
81
|
+
const rawExecPath = process.env.npm_execpath ?? '';
|
|
82
|
+
const execPath = process.platform === 'win32'
|
|
83
|
+
? path.win32.basename(rawExecPath).toLowerCase()
|
|
84
|
+
: path.basename(rawExecPath).toLowerCase();
|
|
85
|
+
return userAgent.startsWith('bun/') || execPath === 'bun' || execPath === 'bun.exe';
|
|
86
|
+
}
|
|
87
|
+
function getPackageRunnerMcpEntry() {
|
|
88
|
+
if (isRunningUnderBun()) {
|
|
78
89
|
if (process.platform === 'win32') {
|
|
79
|
-
return {
|
|
90
|
+
return {
|
|
91
|
+
command: 'cmd',
|
|
92
|
+
args: ['/c', 'bunx', CLI_PACKAGE_SPEC, 'mcp'],
|
|
93
|
+
};
|
|
80
94
|
}
|
|
81
|
-
return {
|
|
95
|
+
return {
|
|
96
|
+
command: 'bunx',
|
|
97
|
+
args: [CLI_PACKAGE_SPEC, 'mcp'],
|
|
98
|
+
};
|
|
82
99
|
}
|
|
83
|
-
// Fallback: npx (works without a global install, but slow cold-start)
|
|
84
100
|
if (process.platform === 'win32') {
|
|
85
101
|
return {
|
|
86
102
|
command: 'cmd',
|
|
87
|
-
args: ['/c', 'npx', '-y',
|
|
103
|
+
args: ['/c', 'npx', '-y', CLI_PACKAGE_SPEC, 'mcp'],
|
|
88
104
|
};
|
|
89
105
|
}
|
|
90
106
|
return {
|
|
91
107
|
command: 'npx',
|
|
92
|
-
args: ['-y',
|
|
108
|
+
args: ['-y', CLI_PACKAGE_SPEC, 'mcp'],
|
|
93
109
|
};
|
|
94
110
|
}
|
|
111
|
+
function getMcpEntry() {
|
|
112
|
+
const bin = resolveCodragraphBin();
|
|
113
|
+
if (bin) {
|
|
114
|
+
if (process.platform === 'win32') {
|
|
115
|
+
return { command: 'cmd', args: ['/c', 'codragraph', 'mcp'] };
|
|
116
|
+
}
|
|
117
|
+
return { command: bin, args: ['mcp'] };
|
|
118
|
+
}
|
|
119
|
+
return getPackageRunnerMcpEntry();
|
|
120
|
+
}
|
|
95
121
|
/**
|
|
96
122
|
* OpenCode uses a different MCP format: { type: "local", command: [...] }
|
|
97
123
|
* where command is a flat array (command + args combined).
|
|
@@ -104,13 +130,8 @@ function getOpenCodeMcpEntry() {
|
|
|
104
130
|
}
|
|
105
131
|
return { type: 'local', command: [bin, 'mcp'] };
|
|
106
132
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
type: 'local',
|
|
110
|
-
command: ['cmd', '/c', 'npx', '-y', '@codragraph/cli@latest', 'mcp'],
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
return { type: 'local', command: ['npx', '-y', '@codragraph/cli@latest', 'mcp'] };
|
|
133
|
+
const entry = getPackageRunnerMcpEntry();
|
|
134
|
+
return { type: 'local', command: [entry.command, ...entry.args] };
|
|
114
135
|
}
|
|
115
136
|
/**
|
|
116
137
|
* Merge codragraph entry into an existing MCP config JSON object.
|
package/dist/cli/status.d.ts
CHANGED
|
@@ -3,4 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Shows the indexing status of the current repository.
|
|
5
5
|
*/
|
|
6
|
+
import { type RepoMeta } from '../storage/repo-manager.js';
|
|
7
|
+
export declare const LARGE_INDEX_WARNING_BYTES: number;
|
|
8
|
+
export interface IndexStorageSummary {
|
|
9
|
+
path: string;
|
|
10
|
+
bytes: number;
|
|
11
|
+
fileCount: number;
|
|
12
|
+
unreadableEntries: number;
|
|
13
|
+
}
|
|
14
|
+
export declare const formatBytes: (bytes: number) => string;
|
|
15
|
+
export declare const summarizeIndexStorage: (storagePath: string) => Promise<IndexStorageSummary | null>;
|
|
16
|
+
export declare const formatIndexStatusLines: (summary: IndexStorageSummary | null, meta: Pick<RepoMeta, "stats" | "compress">, options?: {
|
|
17
|
+
largeIndexWarningBytes?: number;
|
|
18
|
+
}) => string[];
|
|
6
19
|
export declare const statusCommand: () => Promise<void>;
|
package/dist/cli/status.js
CHANGED
|
@@ -3,8 +3,99 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Shows the indexing status of the current repository.
|
|
5
5
|
*/
|
|
6
|
+
import fs from 'fs/promises';
|
|
7
|
+
import path from 'path';
|
|
6
8
|
import { findRepo, getStoragePaths, hasKuzuIndex } from '../storage/repo-manager.js';
|
|
7
9
|
import { getCurrentCommit, isGitRepo, getGitRoot } from '../storage/git.js';
|
|
10
|
+
export const LARGE_INDEX_WARNING_BYTES = 500 * 1024 * 1024;
|
|
11
|
+
const STORAGE_SCAN_BATCH_SIZE = 64;
|
|
12
|
+
export const formatBytes = (bytes) => {
|
|
13
|
+
if (!Number.isFinite(bytes) || bytes <= 0)
|
|
14
|
+
return '0 B';
|
|
15
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
16
|
+
let value = bytes;
|
|
17
|
+
let unitIndex = 0;
|
|
18
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
19
|
+
value /= 1024;
|
|
20
|
+
unitIndex += 1;
|
|
21
|
+
}
|
|
22
|
+
if (unitIndex === 0)
|
|
23
|
+
return `${Math.round(value)} ${units[unitIndex]}`;
|
|
24
|
+
return `${value.toFixed(1)} ${units[unitIndex]}`;
|
|
25
|
+
};
|
|
26
|
+
export const summarizeIndexStorage = async (storagePath) => {
|
|
27
|
+
let rootStat;
|
|
28
|
+
try {
|
|
29
|
+
rootStat = await fs.lstat(storagePath);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (error.code === 'ENOENT')
|
|
33
|
+
return null;
|
|
34
|
+
return { path: storagePath, bytes: 0, fileCount: 0, unreadableEntries: 1 };
|
|
35
|
+
}
|
|
36
|
+
if (!rootStat.isDirectory()) {
|
|
37
|
+
return { path: storagePath, bytes: rootStat.size, fileCount: 1, unreadableEntries: 0 };
|
|
38
|
+
}
|
|
39
|
+
const stack = [storagePath];
|
|
40
|
+
let bytes = 0;
|
|
41
|
+
let fileCount = 0;
|
|
42
|
+
let unreadableEntries = 0;
|
|
43
|
+
while (stack.length > 0) {
|
|
44
|
+
const current = stack.pop();
|
|
45
|
+
let entries;
|
|
46
|
+
try {
|
|
47
|
+
entries = await fs.readdir(current, { withFileTypes: true });
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
unreadableEntries += 1;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
for (let i = 0; i < entries.length; i += STORAGE_SCAN_BATCH_SIZE) {
|
|
54
|
+
const batch = entries.slice(i, i + STORAGE_SCAN_BATCH_SIZE);
|
|
55
|
+
const stats = await Promise.all(batch.map(async (entry) => {
|
|
56
|
+
const entryPath = path.join(current, entry.name);
|
|
57
|
+
try {
|
|
58
|
+
return { entryPath, stat: await fs.lstat(entryPath) };
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return { entryPath, stat: null };
|
|
62
|
+
}
|
|
63
|
+
}));
|
|
64
|
+
for (const { entryPath, stat } of stats) {
|
|
65
|
+
if (!stat) {
|
|
66
|
+
unreadableEntries += 1;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (stat.isDirectory()) {
|
|
70
|
+
stack.push(entryPath);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
bytes += stat.size;
|
|
74
|
+
fileCount += 1;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return { path: storagePath, bytes, fileCount, unreadableEntries };
|
|
79
|
+
};
|
|
80
|
+
export const formatIndexStatusLines = (summary, meta, options = {}) => {
|
|
81
|
+
const lines = [];
|
|
82
|
+
const threshold = options.largeIndexWarningBytes ?? LARGE_INDEX_WARNING_BYTES;
|
|
83
|
+
if (summary) {
|
|
84
|
+
const fileLabel = summary.fileCount === 1 ? 'file' : 'files';
|
|
85
|
+
lines.push(`Index size: ${formatBytes(summary.bytes)} (${summary.fileCount.toLocaleString('en-US')} ${fileLabel} under .codragraph)`);
|
|
86
|
+
if (summary.unreadableEntries > 0) {
|
|
87
|
+
const entryLabel = summary.unreadableEntries === 1 ? 'entry' : 'entries';
|
|
88
|
+
lines.push(`Index size note: ${summary.unreadableEntries.toLocaleString('en-US')} ${entryLabel} could not be read.`);
|
|
89
|
+
}
|
|
90
|
+
if (summary.bytes >= threshold) {
|
|
91
|
+
lines.push(`Storage warning: .codragraph is ${formatBytes(summary.bytes)} (>= ${formatBytes(threshold)}). Consider codragraph analyze --compress brotli (or zstd on Node >=22.15) and only use --embeddings when vectors are needed.`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const embeddings = meta.stats?.embeddings;
|
|
95
|
+
lines.push(`Embeddings: ${typeof embeddings === 'number' ? embeddings.toLocaleString('en-US') : 'unknown'}`);
|
|
96
|
+
lines.push(`Compression: ${meta.compress ?? 'none'}`);
|
|
97
|
+
return lines;
|
|
98
|
+
};
|
|
8
99
|
export const statusCommand = async () => {
|
|
9
100
|
const cwd = process.cwd();
|
|
10
101
|
if (!isGitRepo(cwd)) {
|
|
@@ -16,6 +107,7 @@ export const statusCommand = async () => {
|
|
|
16
107
|
// Check if there's a stale KuzuDB index that needs migration
|
|
17
108
|
const repoRoot = getGitRoot(cwd) ?? cwd;
|
|
18
109
|
const { storagePath } = getStoragePaths(repoRoot);
|
|
110
|
+
const storageSummary = await summarizeIndexStorage(storagePath);
|
|
19
111
|
if (await hasKuzuIndex(storagePath)) {
|
|
20
112
|
console.log('Repository has a stale KuzuDB index from a previous version.');
|
|
21
113
|
console.log('Run: codragraph analyze (rebuilds the index with LadybugDB)');
|
|
@@ -24,13 +116,20 @@ export const statusCommand = async () => {
|
|
|
24
116
|
console.log('Repository not indexed.');
|
|
25
117
|
console.log('Run: codragraph analyze');
|
|
26
118
|
}
|
|
119
|
+
if (storageSummary) {
|
|
120
|
+
for (const line of formatIndexStatusLines(storageSummary, {}))
|
|
121
|
+
console.log(line);
|
|
122
|
+
}
|
|
27
123
|
return;
|
|
28
124
|
}
|
|
29
125
|
const currentCommit = getCurrentCommit(repo.repoPath);
|
|
30
126
|
const isUpToDate = currentCommit === repo.meta.lastCommit;
|
|
127
|
+
const storageSummary = await summarizeIndexStorage(repo.storagePath);
|
|
31
128
|
console.log(`Repository: ${repo.repoPath}`);
|
|
32
129
|
console.log(`Indexed: ${new Date(repo.meta.indexedAt).toLocaleString()}`);
|
|
33
130
|
console.log(`Indexed commit: ${repo.meta.lastCommit?.slice(0, 7)}`);
|
|
34
131
|
console.log(`Current commit: ${currentCommit?.slice(0, 7)}`);
|
|
132
|
+
for (const line of formatIndexStatusLines(storageSummary, repo.meta))
|
|
133
|
+
console.log(line);
|
|
35
134
|
console.log(`Status: ${isUpToDate ? '✅ up-to-date' : '⚠️ stale (re-run codragraph analyze)'}`);
|
|
36
135
|
};
|
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
|
*/
|