@codragraph/cli 2.1.1 → 2.1.5
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 +36 -9
- package/dist/cli/ai-context.js +298 -1
- package/dist/cli/analyze.js +19 -2
- package/dist/cli/index.js +33 -12
- package/dist/cli/serve.d.ts +1 -0
- package/dist/cli/serve.js +3 -1
- package/dist/cli/setup.js +36 -19
- package/dist/cli/status.d.ts +13 -0
- package/dist/cli/status.js +99 -0
- package/dist/cli/tool.js +73 -33
- package/dist/config/ignore-service.js +3 -0
- package/dist/core/cgdb/pool-adapter.js +130 -20
- package/dist/core/graphstore/cgdb-row-source.js +3 -2
- package/dist/core/group/bridge-db.js +42 -10
- package/dist/core/ingestion/parsing-processor.js +7 -1
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +4 -0
- package/dist/core/ingestion/workers/parse-worker.js +1 -1
- package/dist/core/ingestion/workers/worker-pool.d.ts +14 -1
- package/dist/core/ingestion/workers/worker-pool.js +33 -17
- package/dist/core/run-analyze.d.ts +20 -0
- package/dist/core/run-analyze.js +225 -1
- package/dist/core/search/bm25-index.d.ts +0 -11
- package/dist/core/search/bm25-index.js +7 -84
- package/dist/core/search/hybrid-search.js +11 -3
- package/dist/mcp/local/local-backend.d.ts +2 -0
- package/dist/mcp/local/local-backend.js +235 -18
- package/dist/mcp/resources.js +2 -2
- package/dist/server/api.d.ts +14 -2
- package/dist/server/api.js +90 -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/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 +18 -110
- package/hooks/claude/pre-tool-use.sh +6 -1
- package/package.json +3 -1
- package/scripts/build.js +62 -4
- package/scripts/patch-tree-sitter-swift.cjs +0 -1
- package/skills/codragraph-cli.md +1 -1
- 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/README.md
CHANGED
|
@@ -25,6 +25,13 @@ That's it. This indexes the codebase, installs agent skills, registers Claude Co
|
|
|
25
25
|
|
|
26
26
|
The same CLI commands work in Windows PowerShell, macOS bash/zsh, and Linux shells. Use `npx @codragraph/cli ...` for no-install runs or `codragraph ...` after a global install.
|
|
27
27
|
|
|
28
|
+
Smart analyze rebuilds when indexed source, Markdown/MDX graph docs, language
|
|
29
|
+
config, schema, compression, or requested embedding settings changed. Generated
|
|
30
|
+
agent context, lockfile-only, and ignored asset changes reuse the existing
|
|
31
|
+
graph and advance metadata. Each pass refreshes `.codragraph/structure/`, a
|
|
32
|
+
compact what/why/how/when/where markdown pack with branch/index state, bounded
|
|
33
|
+
history, and SQLite seed SQL for external agent memory.
|
|
34
|
+
|
|
28
35
|
To configure MCP for your editor, run `npx @codragraph/cli setup` once — or set it up manually below.
|
|
29
36
|
|
|
30
37
|
`codragraph setup` auto-detects your editors and writes the correct global MCP config. You only need to run it once.
|
|
@@ -55,16 +62,16 @@ If you prefer to configure manually instead of using `codragraph setup`:
|
|
|
55
62
|
|
|
56
63
|
```bash
|
|
57
64
|
# macOS / Linux
|
|
58
|
-
claude mcp add codragraph -- npx -y @codragraph/cli@2.1.
|
|
65
|
+
claude mcp add codragraph -- npx -y @codragraph/cli@2.1.5 mcp
|
|
59
66
|
|
|
60
67
|
# Windows
|
|
61
|
-
claude mcp add codragraph -- cmd /c npx -y @codragraph/cli@2.1.
|
|
68
|
+
claude mcp add codragraph -- cmd /c npx -y @codragraph/cli@2.1.5 mcp
|
|
62
69
|
```
|
|
63
70
|
|
|
64
71
|
### Codex (full support — MCP + skills)
|
|
65
72
|
|
|
66
73
|
```bash
|
|
67
|
-
codex mcp add codragraph -- npx -y @codragraph/cli@2.1.
|
|
74
|
+
codex mcp add codragraph -- npx -y @codragraph/cli@2.1.5 mcp
|
|
68
75
|
```
|
|
69
76
|
|
|
70
77
|
### Cursor / Windsurf
|
|
@@ -76,7 +83,7 @@ Add to `~/.cursor/mcp.json` (global — works for all projects):
|
|
|
76
83
|
"mcpServers": {
|
|
77
84
|
"codragraph": {
|
|
78
85
|
"command": "npx",
|
|
79
|
-
"args": ["-y", "@codragraph/cli@2.1.
|
|
86
|
+
"args": ["-y", "@codragraph/cli@2.1.5", "mcp"]
|
|
80
87
|
}
|
|
81
88
|
}
|
|
82
89
|
}
|
|
@@ -91,7 +98,7 @@ Add to `~/.config/opencode/config.json`:
|
|
|
91
98
|
"mcp": {
|
|
92
99
|
"codragraph": {
|
|
93
100
|
"command": "npx",
|
|
94
|
-
"args": ["-y", "@codragraph/cli@2.1.
|
|
101
|
+
"args": ["-y", "@codragraph/cli@2.1.5", "mcp"]
|
|
95
102
|
}
|
|
96
103
|
}
|
|
97
104
|
}
|
|
@@ -172,7 +179,8 @@ codragraph feature-context Settings # Focus files, line ranges, flows, dependenc
|
|
|
172
179
|
codragraph context-pack Settings # Compact agent context pack for one feature
|
|
173
180
|
codragraph cluster-impact Settings --direction both # Feature-level blast radius
|
|
174
181
|
codragraph mcp # Start MCP server (stdio) — serves all indexed repos
|
|
175
|
-
codragraph serve # Start local HTTP
|
|
182
|
+
codragraph serve # Start local HTTP API + bundled web UI
|
|
183
|
+
codragraph serve --web hosted # API only; connect from hosted web UI
|
|
176
184
|
codragraph index # Register an existing .codragraph/ folder into the global registry
|
|
177
185
|
codragraph list # List all indexed repositories
|
|
178
186
|
codragraph status # Show index status for current repo
|
|
@@ -296,9 +304,9 @@ It is fixed in **codragraph v1.6.2+**. Upgrade to the current workspace
|
|
|
296
304
|
version, or pin the version your team has validated:
|
|
297
305
|
|
|
298
306
|
```bash
|
|
299
|
-
npx @codragraph/cli@2.1.
|
|
307
|
+
npx @codragraph/cli@2.1.5 analyze # no global install
|
|
300
308
|
# or
|
|
301
|
-
npm install -g @codragraph/cli@2.1.
|
|
309
|
+
npm install -g @codragraph/cli@2.1.5 # upgrade a global install
|
|
302
310
|
```
|
|
303
311
|
|
|
304
312
|
If you still hit npm install issues after upgrading, these generic workarounds
|
|
@@ -341,6 +349,23 @@ echo "vendor/" >> .codragraphignore
|
|
|
341
349
|
echo "dist/" >> .codragraphignore
|
|
342
350
|
```
|
|
343
351
|
|
|
352
|
+
If the analyzer reports a worker sub-batch timeout or falls back to sequential
|
|
353
|
+
parsing while files are still being processed, reduce worker batch memory and
|
|
354
|
+
allow a longer idle window:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
# macOS/Linux bash/zsh
|
|
358
|
+
CODRAGRAPH_WORKER_SUB_BATCH_SIZE=100 CODRAGRAPH_WORKER_IDLE_TIMEOUT_MS=180000 npx @codragraph/cli analyze
|
|
359
|
+
|
|
360
|
+
# Windows PowerShell
|
|
361
|
+
$env:CODRAGRAPH_WORKER_SUB_BATCH_SIZE = "100"
|
|
362
|
+
$env:CODRAGRAPH_WORKER_IDLE_TIMEOUT_MS = "180000"
|
|
363
|
+
npx @codragraph/cli analyze
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
The worker timer is an idle guard. Parser progress resets it, so a slow repo
|
|
367
|
+
should keep moving instead of paying the old 30-second wall-clock fallback.
|
|
368
|
+
|
|
344
369
|
If you want to know **which phase** is dragging the heap up before
|
|
345
370
|
deciding what to mitigate, run `codragraph profile-heap`. It writes a
|
|
346
371
|
v8 heap snapshot at every phase boundary plus a JSONL timeline of
|
|
@@ -402,7 +427,9 @@ Values above **32768 KB (32 MB)** are clamped to the tree-sitter parser ceiling;
|
|
|
402
427
|
|
|
403
428
|
CodraGraph also has a browser-based UI at [codragraph.vercel.app](https://codragraph.vercel.app) — 100% client-side, your code never leaves the browser.
|
|
404
429
|
|
|
405
|
-
**Local Backend Mode:** Run `codragraph serve` and open the web
|
|
430
|
+
**Local Backend Mode:** Run `codragraph serve` and open `http://localhost:4747`. The installed CLI serves the bundled dashboard from `dist/web` and does not package `apps/web/node_modules`. It auto-detects the server and shows all your indexed repos, feature clusters, dependency context, and full AI chat support. No need to re-upload or re-index. The agent's tools (Cypher queries, search, code navigation) route through the backend HTTP API automatically.
|
|
431
|
+
|
|
432
|
+
**Hosted Dashboard Mode:** Run `codragraph serve --web hosted`, then open the hosted dashboard and connect it to `http://localhost:4747`. The UI is hosted, but project data still comes from your local API.
|
|
406
433
|
|
|
407
434
|
## License
|
|
408
435
|
|
package/dist/cli/ai-context.js
CHANGED
|
@@ -8,11 +8,14 @@
|
|
|
8
8
|
import fs from 'fs/promises';
|
|
9
9
|
import path from 'path';
|
|
10
10
|
import { fileURLToPath } from 'url';
|
|
11
|
+
import { execFileSync } from 'node:child_process';
|
|
11
12
|
// ESM equivalent of __dirname
|
|
12
13
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
14
|
const __dirname = path.dirname(__filename);
|
|
14
15
|
const CODRAGRAPH_START_MARKER = '<!-- codragraph:start -->';
|
|
15
16
|
const CODRAGRAPH_END_MARKER = '<!-- codragraph:end -->';
|
|
17
|
+
const AGENT_STRUCTURE_DIR = 'structure';
|
|
18
|
+
const AGENT_HISTORY_LIMIT = 20;
|
|
16
19
|
/**
|
|
17
20
|
* Find the index of a section marker that occupies its own line.
|
|
18
21
|
* Unlike `indexOf`, this rejects inline prose references like
|
|
@@ -113,6 +116,7 @@ This project is indexed by CodraGraph as **${projectName}**${noStats ? '' : ` ($
|
|
|
113
116
|
| \`codragraph://repo/${projectName}/feature/{name}\` | Focused files, line ranges, flows, dependencies |
|
|
114
117
|
| \`codragraph://repo/${projectName}/processes\` | All execution flows |
|
|
115
118
|
| \`codragraph://repo/${projectName}/process/{name}\` | Step-by-step execution trace |
|
|
119
|
+
| \`.codragraph/structure/README.md\` | Local what/why/how/when/where memory, branch state, and SQLite seed |
|
|
116
120
|
|
|
117
121
|
${groupNames && groupNames.length > 0
|
|
118
122
|
? `## Cross-Repo Groups
|
|
@@ -122,7 +126,7 @@ This repository is listed under CodraGraph **group(s): ${groupNames.join(', ')}*
|
|
|
122
126
|
`
|
|
123
127
|
: ''}## CLI
|
|
124
128
|
|
|
125
|
-
Commands are cross-platform:
|
|
129
|
+
Commands are cross-platform: \`codragraph ...\`, \`npx @codragraph/cli ...\`, or \`bunx @codragraph/cli ...\`. Scripts: \`npm --prefix ...\` or \`bun run --filter ...\`.
|
|
126
130
|
|
|
127
131
|
${skillsTable}
|
|
128
132
|
|
|
@@ -174,6 +178,292 @@ async function upsertCodraGraphSection(filePath, content) {
|
|
|
174
178
|
await fs.writeFile(filePath, newContent, 'utf-8');
|
|
175
179
|
return 'appended';
|
|
176
180
|
}
|
|
181
|
+
async function readJsonFile(filePath) {
|
|
182
|
+
try {
|
|
183
|
+
return JSON.parse(await fs.readFile(filePath, 'utf-8'));
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function gitValue(repoPath, args) {
|
|
190
|
+
try {
|
|
191
|
+
return execFileSync('git', args, {
|
|
192
|
+
cwd: repoPath,
|
|
193
|
+
encoding: 'utf-8',
|
|
194
|
+
timeout: 3000,
|
|
195
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
196
|
+
}).trim();
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
return '';
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function statValue(value) {
|
|
203
|
+
return value === undefined || value === null || value === '' ? 'unknown' : String(value);
|
|
204
|
+
}
|
|
205
|
+
function shortCommit(value) {
|
|
206
|
+
return value ? value.slice(0, 12) : 'unknown';
|
|
207
|
+
}
|
|
208
|
+
function sqlString(value) {
|
|
209
|
+
return String(value ?? '').replace(/'/g, "''");
|
|
210
|
+
}
|
|
211
|
+
async function buildAgentStructureState(repoPath, storagePath, projectName, stats) {
|
|
212
|
+
const meta = await readJsonFile(path.join(storagePath, 'meta.json'));
|
|
213
|
+
const currentGitHead = gitValue(repoPath, ['rev-parse', 'HEAD']);
|
|
214
|
+
const currentBranch = gitValue(repoPath, ['branch', '--show-current']) ||
|
|
215
|
+
gitValue(repoPath, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
216
|
+
return {
|
|
217
|
+
projectName,
|
|
218
|
+
repoPath,
|
|
219
|
+
storagePath,
|
|
220
|
+
generatedAt: new Date().toISOString(),
|
|
221
|
+
indexedAt: meta?.indexedAt,
|
|
222
|
+
currentBranch: currentBranch || undefined,
|
|
223
|
+
currentGitHead: currentGitHead || undefined,
|
|
224
|
+
indexedCommit: meta?.lastCommit || currentGitHead || undefined,
|
|
225
|
+
remoteUrl: meta?.remoteUrl,
|
|
226
|
+
schemaVersion: meta?.schemaVersion,
|
|
227
|
+
compress: meta?.compress,
|
|
228
|
+
graphstoreBranch: meta?.currentBranch,
|
|
229
|
+
graphstoreHeadCommit: meta?.headCommit,
|
|
230
|
+
stats: {
|
|
231
|
+
files: stats.files ?? meta?.stats?.files,
|
|
232
|
+
nodes: stats.nodes ?? meta?.stats?.nodes,
|
|
233
|
+
edges: stats.edges ?? meta?.stats?.edges,
|
|
234
|
+
communities: stats.communities ?? meta?.stats?.communities,
|
|
235
|
+
clusters: stats.clusters ?? meta?.stats?.featureClusters,
|
|
236
|
+
processes: stats.processes ?? meta?.stats?.processes,
|
|
237
|
+
embeddings: meta?.stats?.embeddings,
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function buildStructureDocs(state) {
|
|
242
|
+
const statsTable = `| Metric | Value |
|
|
243
|
+
|---|---|
|
|
244
|
+
| Files | ${statValue(state.stats.files)} |
|
|
245
|
+
| Symbols | ${statValue(state.stats.nodes)} |
|
|
246
|
+
| Relationships | ${statValue(state.stats.edges)} |
|
|
247
|
+
| Feature clusters | ${statValue(state.stats.clusters)} |
|
|
248
|
+
| Execution flows | ${statValue(state.stats.processes)} |
|
|
249
|
+
| Embeddings | ${statValue(state.stats.embeddings)} |
|
|
250
|
+
| Compression | ${statValue(state.compress)} |
|
|
251
|
+
| Schema version | ${statValue(state.schemaVersion)} |`;
|
|
252
|
+
const branchTable = `| Field | Value |
|
|
253
|
+
|---|---|
|
|
254
|
+
| Current git branch | ${statValue(state.currentBranch)} |
|
|
255
|
+
| Current git HEAD | ${statValue(state.currentGitHead)} |
|
|
256
|
+
| Indexed commit | ${statValue(state.indexedCommit)} |
|
|
257
|
+
| Indexed at | ${statValue(state.indexedAt)} |
|
|
258
|
+
| Graphstore branch | ${statValue(state.graphstoreBranch)} |
|
|
259
|
+
| Graphstore head commit | ${statValue(state.graphstoreHeadCommit)} |
|
|
260
|
+
| Remote | ${statValue(state.remoteUrl)} |`;
|
|
261
|
+
return {
|
|
262
|
+
'README.md': `# CodraGraph Agent Structure
|
|
263
|
+
|
|
264
|
+
Generated: ${state.generatedAt}
|
|
265
|
+
|
|
266
|
+
This folder is the small, pre-seeded context pack for AI agents. It is rebuilt
|
|
267
|
+
by \`codragraph analyze\` so agents can read stable markdown instead of guessing
|
|
268
|
+
from stale terminal output.
|
|
269
|
+
|
|
270
|
+
Read order:
|
|
271
|
+
|
|
272
|
+
1. [WHAT.md](WHAT.md) - what this index represents.
|
|
273
|
+
2. [WHY.md](WHY.md) - why the agent should use graph context first.
|
|
274
|
+
3. [HOW.md](HOW.md) - how to query, analyze, and recover safely.
|
|
275
|
+
4. [WHEN.md](WHEN.md) - when to refresh, reuse, or clean the index.
|
|
276
|
+
5. [WHERE.md](WHERE.md) - where local storage, MCP, HTTP, and docs live.
|
|
277
|
+
6. [BRANCHES.md](BRANCHES.md) - branch, commit, and graphstore state.
|
|
278
|
+
7. [SQLITE.md](SQLITE.md) - SQLite-compatible seed data for external agent memory.
|
|
279
|
+
`,
|
|
280
|
+
'WHAT.md': `# What
|
|
281
|
+
|
|
282
|
+
CodraGraph index name: **${state.projectName}**
|
|
283
|
+
|
|
284
|
+
This index stores a local code graph for the repository at:
|
|
285
|
+
|
|
286
|
+
\`${state.repoPath}\`
|
|
287
|
+
|
|
288
|
+
The graph includes file structure, symbols, relationships, imports, execution
|
|
289
|
+
flows, feature clusters, Markdown graph docs, and optional embeddings. Agents
|
|
290
|
+
should use this pack as the first local orientation layer, then ask MCP/CLI for
|
|
291
|
+
live graph details.
|
|
292
|
+
|
|
293
|
+
${statsTable}
|
|
294
|
+
`,
|
|
295
|
+
'WHY.md': `# Why
|
|
296
|
+
|
|
297
|
+
AI agents should not rebuild project understanding from raw grep every time.
|
|
298
|
+
This folder gives them a compact, reusable map of the current indexed state.
|
|
299
|
+
|
|
300
|
+
Use it to avoid:
|
|
301
|
+
|
|
302
|
+
- Querying the wrong registered repo.
|
|
303
|
+
- Running multiple analyzers against the same .codragraph store.
|
|
304
|
+
- Treating stale branch or commit context as fresh.
|
|
305
|
+
- Enabling embeddings by default when BM25 and graph search are enough.
|
|
306
|
+
- Deleting index files when a targeted analyze or clean command is safer.
|
|
307
|
+
`,
|
|
308
|
+
'HOW.md': `# How
|
|
309
|
+
|
|
310
|
+
Safe command flow for agents:
|
|
311
|
+
|
|
312
|
+
1. Read this folder and \`AGENTS.md\` / \`CLAUDE.md\`.
|
|
313
|
+
2. Run \`codragraph status\` or \`npx @codragraph/cli status\`.
|
|
314
|
+
3. Use MCP \`query\`, \`context\`, \`impact\`, and \`detect_changes\` for graph work.
|
|
315
|
+
4. Run \`codragraph analyze\` only when the index is missing or stale.
|
|
316
|
+
5. Use \`--repo ${state.projectName}\` when running from outside this checkout.
|
|
317
|
+
|
|
318
|
+
Do not run \`analyze\`, \`detect-changes\`, \`clean\`, or DB-writing commands from
|
|
319
|
+
editor hooks. Hooks should stay bounded and read-only.
|
|
320
|
+
`,
|
|
321
|
+
'WHEN.md': `# When
|
|
322
|
+
|
|
323
|
+
Refresh with \`codragraph analyze\` when:
|
|
324
|
+
|
|
325
|
+
- The repo was never indexed.
|
|
326
|
+
- MCP or CLI reports stale graph context.
|
|
327
|
+
- Source files, Markdown graph docs, language config, or path topology changed.
|
|
328
|
+
- Schema, compression, or embedding settings changed.
|
|
329
|
+
|
|
330
|
+
Reuse the existing graph when only generated agent context, lockfiles, or
|
|
331
|
+
ignored assets changed. Use \`codragraph analyze --force\` when ignore rules
|
|
332
|
+
changed or corruption is suspected. Ask before \`codragraph clean --force\`.
|
|
333
|
+
`,
|
|
334
|
+
'WHERE.md': `# Where
|
|
335
|
+
|
|
336
|
+
| Item | Location |
|
|
337
|
+
|---|---|
|
|
338
|
+
| Repository | \`${state.repoPath}\` |
|
|
339
|
+
| Local index storage | \`${state.storagePath}\` |
|
|
340
|
+
| Agent structure pack | \`${path.join(state.storagePath, AGENT_STRUCTURE_DIR)}\` |
|
|
341
|
+
| Root agent instructions | \`AGENTS.md\`, \`CLAUDE.md\` |
|
|
342
|
+
| Claude skills | \`.claude/skills/@codragraph/cli/\` |
|
|
343
|
+
| HTTP API | \`http://127.0.0.1:4747/api/info\` after \`codragraph serve\` |
|
|
344
|
+
| MCP tools | \`codragraph mcp\` |
|
|
345
|
+
`,
|
|
346
|
+
'BRANCHES.md': `# Branches And Commits
|
|
347
|
+
|
|
348
|
+
${branchTable}
|
|
349
|
+
|
|
350
|
+
The indexed commit is the source-of-truth for whether graph answers are fresh.
|
|
351
|
+
If \`Current git HEAD\` and \`Indexed commit\` differ, agents should say the graph
|
|
352
|
+
is stale and run \`codragraph analyze\` before relying on impact, context, or
|
|
353
|
+
detect-changes output.
|
|
354
|
+
`,
|
|
355
|
+
'INDEX.md': `# Index Snapshot
|
|
356
|
+
|
|
357
|
+
${statsTable}
|
|
358
|
+
|
|
359
|
+
Storage notes:
|
|
360
|
+
|
|
361
|
+
- BM25 and graph traversal work without embeddings.
|
|
362
|
+
- Embeddings are optional and should be preserved with \`--embeddings\` only
|
|
363
|
+
when semantic/vector search is intentionally required.
|
|
364
|
+
- Compression mode is recorded in \`.codragraph/meta.json\`.
|
|
365
|
+
- This markdown pack is small and should not be embedded or vectorized.
|
|
366
|
+
`,
|
|
367
|
+
'SQLITE.md': `# SQLite Seed
|
|
368
|
+
|
|
369
|
+
\`agent-memory.sql\` is a SQLite-compatible seed file for external agent memory
|
|
370
|
+
stores. CodraGraph writes it as plain SQL so installs stay light on Node 20 and
|
|
371
|
+
do not pull native SQLite dependencies into the CLI hot path.
|
|
372
|
+
|
|
373
|
+
Optional import:
|
|
374
|
+
|
|
375
|
+
\`\`\`sh
|
|
376
|
+
sqlite3 agent-memory.sqlite < agent-memory.sql
|
|
377
|
+
\`\`\`
|
|
378
|
+
|
|
379
|
+
The canonical live source remains \`.codragraph/meta.json\` plus the graph DB.
|
|
380
|
+
`,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function buildSqlSeed(state) {
|
|
384
|
+
const rows = [
|
|
385
|
+
['project_name', state.projectName],
|
|
386
|
+
['repo_path', state.repoPath],
|
|
387
|
+
['storage_path', state.storagePath],
|
|
388
|
+
['generated_at', state.generatedAt],
|
|
389
|
+
['indexed_at', state.indexedAt],
|
|
390
|
+
['current_branch', state.currentBranch],
|
|
391
|
+
['current_git_head', state.currentGitHead],
|
|
392
|
+
['indexed_commit', state.indexedCommit],
|
|
393
|
+
['remote_url', state.remoteUrl],
|
|
394
|
+
['schema_version', state.schemaVersion],
|
|
395
|
+
['compress', state.compress],
|
|
396
|
+
['graphstore_branch', state.graphstoreBranch],
|
|
397
|
+
['graphstore_head_commit', state.graphstoreHeadCommit],
|
|
398
|
+
['stats_json', JSON.stringify(state.stats)],
|
|
399
|
+
];
|
|
400
|
+
const values = rows
|
|
401
|
+
.map(([key, value]) => `('${sqlString(key)}', '${sqlString(value)}', '${sqlString(state.generatedAt)}')`)
|
|
402
|
+
.join(',\n');
|
|
403
|
+
return `BEGIN;
|
|
404
|
+
CREATE TABLE IF NOT EXISTS codragraph_agent_context (
|
|
405
|
+
key TEXT PRIMARY KEY,
|
|
406
|
+
value TEXT NOT NULL,
|
|
407
|
+
updated_at TEXT NOT NULL
|
|
408
|
+
);
|
|
409
|
+
DELETE FROM codragraph_agent_context;
|
|
410
|
+
INSERT INTO codragraph_agent_context (key, value, updated_at) VALUES
|
|
411
|
+
${values};
|
|
412
|
+
COMMIT;
|
|
413
|
+
`;
|
|
414
|
+
}
|
|
415
|
+
async function buildHistoryContent(historyPath, state) {
|
|
416
|
+
const entryId = (state.indexedCommit || 'no-git').replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
417
|
+
const entry = `<!-- codragraph:history-entry:${entryId} -->
|
|
418
|
+
## ${shortCommit(state.indexedCommit)} - ${state.generatedAt}
|
|
419
|
+
|
|
420
|
+
- Branch: ${statValue(state.currentBranch)}
|
|
421
|
+
- Indexed commit: ${statValue(state.indexedCommit)}
|
|
422
|
+
- Git HEAD: ${statValue(state.currentGitHead)}
|
|
423
|
+
- Graphstore: ${statValue(state.graphstoreBranch)} / ${statValue(state.graphstoreHeadCommit)}
|
|
424
|
+
- Stats: ${statValue(state.stats.nodes)} symbols, ${statValue(state.stats.edges)} relationships, ${statValue(state.stats.processes)} flows
|
|
425
|
+
<!-- /codragraph:history-entry -->`;
|
|
426
|
+
let existing = '';
|
|
427
|
+
try {
|
|
428
|
+
existing = await fs.readFile(historyPath, 'utf-8');
|
|
429
|
+
}
|
|
430
|
+
catch {
|
|
431
|
+
/* first run */
|
|
432
|
+
}
|
|
433
|
+
const blocks = [];
|
|
434
|
+
const regex = /<!-- codragraph:history-entry:([^ ]+) -->[\s\S]*?<!-- \/codragraph:history-entry -->/g;
|
|
435
|
+
let match;
|
|
436
|
+
while ((match = regex.exec(existing)) !== null) {
|
|
437
|
+
if (match[1] !== entryId)
|
|
438
|
+
blocks.push(match[0]);
|
|
439
|
+
}
|
|
440
|
+
return `# Analyze History
|
|
441
|
+
|
|
442
|
+
Most recent CodraGraph analyze or smart-reuse events. Bounded to the latest
|
|
443
|
+
${AGENT_HISTORY_LIMIT} entries so this file remains small.
|
|
444
|
+
|
|
445
|
+
${[entry, ...blocks].slice(0, AGENT_HISTORY_LIMIT).join('\n\n')}
|
|
446
|
+
`;
|
|
447
|
+
}
|
|
448
|
+
async function generateAgentStructurePack(repoPath, storagePath, projectName, stats) {
|
|
449
|
+
const structureDir = path.join(storagePath, AGENT_STRUCTURE_DIR);
|
|
450
|
+
await fs.mkdir(structureDir, { recursive: true });
|
|
451
|
+
const state = await buildAgentStructureState(repoPath, storagePath, projectName, stats);
|
|
452
|
+
const docs = buildStructureDocs(state);
|
|
453
|
+
const written = [];
|
|
454
|
+
for (const [fileName, content] of Object.entries(docs)) {
|
|
455
|
+
await fs.writeFile(path.join(structureDir, fileName), content.trim() + '\n', 'utf-8');
|
|
456
|
+
written.push(fileName);
|
|
457
|
+
}
|
|
458
|
+
await fs.writeFile(path.join(structureDir, 'state.json'), JSON.stringify(state, null, 2) + '\n', 'utf-8');
|
|
459
|
+
written.push('state.json');
|
|
460
|
+
await fs.writeFile(path.join(structureDir, 'agent-memory.sql'), buildSqlSeed(state), 'utf-8');
|
|
461
|
+
written.push('agent-memory.sql');
|
|
462
|
+
const historyPath = path.join(structureDir, 'HISTORY.md');
|
|
463
|
+
await fs.writeFile(historyPath, await buildHistoryContent(historyPath, state), 'utf-8');
|
|
464
|
+
written.push('HISTORY.md');
|
|
465
|
+
return written;
|
|
466
|
+
}
|
|
177
467
|
/**
|
|
178
468
|
* Install CodraGraph skills to .claude/skills/codragraph/
|
|
179
469
|
* Works natively with Claude Code, Cursor, and GitHub Copilot
|
|
@@ -265,6 +555,13 @@ export async function generateAIContextFiles(repoPath, _storagePath, projectName
|
|
|
265
555
|
createdFiles.push('AGENTS.md (skipped via --skip-agents-md)');
|
|
266
556
|
createdFiles.push('CLAUDE.md (skipped via --skip-agents-md)');
|
|
267
557
|
}
|
|
558
|
+
try {
|
|
559
|
+
const structureFiles = await generateAgentStructurePack(repoPath, _storagePath, projectName, stats);
|
|
560
|
+
createdFiles.push(`.codragraph/structure/ (${structureFiles.length} files)`);
|
|
561
|
+
}
|
|
562
|
+
catch (err) {
|
|
563
|
+
console.warn('Warning: Could not generate .codragraph/structure agent pack:', err);
|
|
564
|
+
}
|
|
268
565
|
// Install skills to .claude/skills/codragraph/
|
|
269
566
|
const installedSkills = await installSkills(repoPath);
|
|
270
567
|
if (installedSkills.length > 0) {
|
package/dist/cli/analyze.js
CHANGED
|
@@ -19,6 +19,7 @@ import { getGitRoot, hasGitDir } from '../storage/git.js';
|
|
|
19
19
|
import { runFullAnalysis } from '../core/run-analyze.js';
|
|
20
20
|
import { getMaxFileSizeBannerMessage } from '../core/ingestion/utils/max-file-size.js';
|
|
21
21
|
import fs from 'fs/promises';
|
|
22
|
+
import { formatBytes, LARGE_INDEX_WARNING_BYTES, summarizeIndexStorage } from './status.js';
|
|
22
23
|
const require = createRequire(import.meta.url);
|
|
23
24
|
const pkg = require('../../package.json');
|
|
24
25
|
const CLI_PACKAGE_SPEC = `@codragraph/cli@${pkg.version}`;
|
|
@@ -255,7 +256,7 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
255
256
|
console.warn = origWarn;
|
|
256
257
|
console.error = origError;
|
|
257
258
|
bar.stop();
|
|
258
|
-
console.log('
|
|
259
|
+
console.log(` ${result.reuseReason ?? 'Already up to date'}\n`);
|
|
259
260
|
// Safe to return without process.exit(0) — the early-return path in
|
|
260
261
|
// runFullAnalysis never opens LadybugDB, so no native handles prevent exit.
|
|
261
262
|
return;
|
|
@@ -324,6 +325,20 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
324
325
|
console.log(`\n Repository indexed successfully (${totalTime}s)\n`);
|
|
325
326
|
console.log(` ${(s.nodes ?? 0).toLocaleString()} nodes | ${(s.edges ?? 0).toLocaleString()} edges | ${s.communities ?? 0} clusters | ${s.processes ?? 0} flows`);
|
|
326
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
|
+
}
|
|
327
342
|
// Surface @codragraph/compress's value prop with concrete numbers: how
|
|
328
343
|
// many tokens of distilled context did we generate. Best-effort — never
|
|
329
344
|
// fail the analyze for a stat read.
|
|
@@ -391,12 +406,13 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
391
406
|
// 'node.target'" crash happens inside npm *before* codragraph code runs,
|
|
392
407
|
// so it can't be caught here. This branch handles dependency-resolution
|
|
393
408
|
// errors that surface at runtime (e.g. dynamic require failures).
|
|
394
|
-
console.error(' This looks like
|
|
409
|
+
console.error(' This looks like a package-manager dependency resolution issue.');
|
|
395
410
|
console.error(' Suggestions:');
|
|
396
411
|
console.error(' 1. Clear the npm cache: npm cache clean --force');
|
|
397
412
|
console.error(' 2. Update npm: npm install -g npm@latest');
|
|
398
413
|
console.error(` 3. Reinstall codragraph: npm install -g ${CLI_PACKAGE_SPEC}`);
|
|
399
414
|
console.error(` 4. Or try npx directly: npx ${CLI_PACKAGE_SPEC} analyze`);
|
|
415
|
+
console.error(` 5. Bun alternative: bunx ${CLI_PACKAGE_SPEC} analyze`);
|
|
400
416
|
console.error('');
|
|
401
417
|
}
|
|
402
418
|
else if (msg.includes('MODULE_NOT_FOUND') ||
|
|
@@ -406,6 +422,7 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
406
422
|
console.error(' Suggestions:');
|
|
407
423
|
console.error(` 1. Reinstall: npm install -g ${CLI_PACKAGE_SPEC}`);
|
|
408
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`);
|
|
409
426
|
console.error('');
|
|
410
427
|
}
|
|
411
428
|
process.exitCode = 1;
|
package/dist/cli/index.js
CHANGED
|
@@ -8,6 +8,26 @@ import { registerGroupCommands } from './group.js';
|
|
|
8
8
|
const _require = createRequire(import.meta.url);
|
|
9
9
|
const pkg = _require('../../package.json');
|
|
10
10
|
const program = new Command();
|
|
11
|
+
const exitOneShot = (code) => {
|
|
12
|
+
const reallyExit = process
|
|
13
|
+
.reallyExit;
|
|
14
|
+
if (typeof reallyExit === 'function') {
|
|
15
|
+
reallyExit(code);
|
|
16
|
+
}
|
|
17
|
+
process.exit(code);
|
|
18
|
+
};
|
|
19
|
+
const createOneShotLazyAction = (loader, exportName) => {
|
|
20
|
+
const action = createLazyAction(loader, exportName);
|
|
21
|
+
return async (...args) => {
|
|
22
|
+
await action(...args);
|
|
23
|
+
const code = typeof process.exitCode === 'number'
|
|
24
|
+
? process.exitCode
|
|
25
|
+
: process.exitCode
|
|
26
|
+
? Number(process.exitCode) || 1
|
|
27
|
+
: 0;
|
|
28
|
+
exitOneShot(code);
|
|
29
|
+
};
|
|
30
|
+
};
|
|
11
31
|
program.name('codragraph').description('CodraGraph local CLI and MCP server').version(pkg.version);
|
|
12
32
|
program
|
|
13
33
|
.command('setup')
|
|
@@ -55,9 +75,10 @@ program
|
|
|
55
75
|
.action(createLazyAction(() => import('./index-repo.js'), 'indexCommand'));
|
|
56
76
|
program
|
|
57
77
|
.command('serve')
|
|
58
|
-
.description('Start local HTTP
|
|
78
|
+
.description('Start local HTTP API and web dashboard')
|
|
59
79
|
.option('-p, --port <port>', 'Port number', '4747')
|
|
60
80
|
.option('--host <host>', 'Bind address (default: 127.0.0.1, use 0.0.0.0 for remote access)')
|
|
81
|
+
.option('--web <mode>', 'Dashboard mode: local serves the bundled app, hosted prints hosted UI connection info, off serves API only', 'local')
|
|
61
82
|
.action(createLazyAction(() => import('./serve.js'), 'serveCommand'));
|
|
62
83
|
program
|
|
63
84
|
.command('mcp')
|
|
@@ -113,7 +134,7 @@ program
|
|
|
113
134
|
.option('-g, --goal <text>', 'What you want to find')
|
|
114
135
|
.option('-l, --limit <n>', 'Max processes to return (default: 5)')
|
|
115
136
|
.option('--content', 'Include full symbol source code')
|
|
116
|
-
.action(
|
|
137
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'queryCommand'));
|
|
117
138
|
program
|
|
118
139
|
.command('context [name]')
|
|
119
140
|
.description('360-degree view of a code symbol: callers, callees, processes')
|
|
@@ -121,7 +142,7 @@ program
|
|
|
121
142
|
.option('-u, --uid <uid>', 'Direct symbol UID (zero-ambiguity lookup)')
|
|
122
143
|
.option('-f, --file <path>', 'File path to disambiguate common names')
|
|
123
144
|
.option('--content', 'Include full symbol source code')
|
|
124
|
-
.action(
|
|
145
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'contextCommand'));
|
|
125
146
|
program
|
|
126
147
|
.command('impact <target>')
|
|
127
148
|
.description('Blast radius analysis: what breaks if you change a symbol')
|
|
@@ -129,49 +150,49 @@ program
|
|
|
129
150
|
.option('-r, --repo <name>', 'Target repository')
|
|
130
151
|
.option('--depth <n>', 'Max relationship depth (default: 3)')
|
|
131
152
|
.option('--include-tests', 'Include test files in results')
|
|
132
|
-
.action(
|
|
153
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'impactCommand'));
|
|
133
154
|
program
|
|
134
155
|
.command('cypher <query>')
|
|
135
156
|
.description('Execute raw Cypher query against the knowledge graph')
|
|
136
157
|
.option('-r, --repo <name>', 'Target repository')
|
|
137
|
-
.action(
|
|
158
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'cypherCommand'));
|
|
138
159
|
program
|
|
139
160
|
.command('feature-clusters')
|
|
140
161
|
.description('List human-facing feature clusters for targeted context building')
|
|
141
162
|
.option('-r, --repo <name>', 'Target repository')
|
|
142
163
|
.option('-l, --limit <n>', 'Max feature clusters to return (default: 100)')
|
|
143
|
-
.action(
|
|
164
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'featureClustersCommand'));
|
|
144
165
|
program
|
|
145
166
|
.command('cluster-query [query]')
|
|
146
167
|
.description('Alias for feature-clusters: list product/domain clusters')
|
|
147
168
|
.option('-r, --repo <name>', 'Target repository')
|
|
148
169
|
.option('-l, --limit <n>', 'Max feature clusters to return (default: 100)')
|
|
149
|
-
.action(
|
|
170
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'clusterQueryCommand'));
|
|
150
171
|
program
|
|
151
172
|
.command('feature-context <name>')
|
|
152
173
|
.description('Show members, line ranges, and dependencies for a feature cluster')
|
|
153
174
|
.option('-r, --repo <name>', 'Target repository')
|
|
154
175
|
.option('-l, --limit <n>', 'Max members to return (default: 100)')
|
|
155
|
-
.action(
|
|
176
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'featureContextCommand'));
|
|
156
177
|
program
|
|
157
178
|
.command('cluster-context <name>')
|
|
158
179
|
.description('Alias for feature-context: show a feature cluster context pack')
|
|
159
180
|
.option('-r, --repo <name>', 'Target repository')
|
|
160
181
|
.option('-l, --limit <n>', 'Max members to return (default: 100)')
|
|
161
|
-
.action(
|
|
182
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'clusterContextCommand'));
|
|
162
183
|
program
|
|
163
184
|
.command('context-pack <name>')
|
|
164
185
|
.description('Generate the compact agent context pack for a feature cluster')
|
|
165
186
|
.option('-r, --repo <name>', 'Target repository')
|
|
166
187
|
.option('-l, --limit <n>', 'Max members to return (default: 100)')
|
|
167
|
-
.action(
|
|
188
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'contextPackCommand'));
|
|
168
189
|
program
|
|
169
190
|
.command('cluster-impact <name>')
|
|
170
191
|
.description('Feature-level blast radius analysis for a cluster')
|
|
171
192
|
.option('-d, --direction <dir>', 'upstream, downstream, or both', 'upstream')
|
|
172
193
|
.option('-r, --repo <name>', 'Target repository')
|
|
173
194
|
.option('-l, --limit <n>', 'Max context-pack members to include (default: 100)')
|
|
174
|
-
.action(
|
|
195
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'clusterImpactCommand'));
|
|
175
196
|
program
|
|
176
197
|
.command('detect-changes')
|
|
177
198
|
.alias('detect_changes')
|
|
@@ -179,7 +200,7 @@ program
|
|
|
179
200
|
.option('-s, --scope <scope>', 'What to analyze: unstaged, staged, all, or compare', 'unstaged')
|
|
180
201
|
.option('-b, --base-ref <ref>', 'Branch/commit for compare scope (e.g. main)')
|
|
181
202
|
.option('-r, --repo <name>', 'Target repository')
|
|
182
|
-
.action(
|
|
203
|
+
.action(createOneShotLazyAction(() => import('./tool.js'), 'detectChangesCommand'));
|
|
183
204
|
// ─── Eval Server (persistent daemon for SWE-bench) ─────────────────
|
|
184
205
|
program
|
|
185
206
|
.command('eval-server')
|
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`);
|