@colbymchenry/codegraph 0.6.8 → 0.7.3
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 +179 -476
- package/dist/bin/codegraph.d.ts +0 -5
- package/dist/bin/codegraph.d.ts.map +1 -1
- package/dist/bin/codegraph.js +217 -237
- package/dist/bin/codegraph.js.map +1 -1
- package/dist/bin/uninstall.d.ts +0 -1
- package/dist/bin/uninstall.d.ts.map +1 -1
- package/dist/bin/uninstall.js +3 -29
- package/dist/bin/uninstall.js.map +1 -1
- package/dist/context/index.d.ts +3 -5
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +531 -52
- package/dist/context/index.js.map +1 -1
- package/dist/db/migrations.d.ts +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +10 -1
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/queries.d.ts +53 -0
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +244 -14
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +1 -16
- package/dist/extraction/dfm-extractor.d.ts +31 -0
- package/dist/extraction/dfm-extractor.d.ts.map +1 -0
- package/dist/extraction/dfm-extractor.js +151 -0
- package/dist/extraction/dfm-extractor.js.map +1 -0
- package/dist/extraction/grammars.d.ts +9 -1
- package/dist/extraction/grammars.d.ts.map +1 -1
- package/dist/extraction/grammars.js +34 -2
- package/dist/extraction/grammars.js.map +1 -1
- package/dist/extraction/index.d.ts +7 -1
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +373 -22
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/c-cpp.d.ts +4 -0
- package/dist/extraction/languages/c-cpp.d.ts.map +1 -0
- package/dist/extraction/languages/c-cpp.js +126 -0
- package/dist/extraction/languages/c-cpp.js.map +1 -0
- package/dist/extraction/languages/csharp.d.ts +3 -0
- package/dist/extraction/languages/csharp.d.ts.map +1 -0
- package/dist/extraction/languages/csharp.js +72 -0
- package/dist/extraction/languages/csharp.js.map +1 -0
- package/dist/extraction/languages/dart.d.ts +3 -0
- package/dist/extraction/languages/dart.d.ts.map +1 -0
- package/dist/extraction/languages/dart.js +192 -0
- package/dist/extraction/languages/dart.js.map +1 -0
- package/dist/extraction/languages/go.d.ts +3 -0
- package/dist/extraction/languages/go.d.ts.map +1 -0
- package/dist/extraction/languages/go.js +58 -0
- package/dist/extraction/languages/go.js.map +1 -0
- package/dist/extraction/languages/index.d.ts +10 -0
- package/dist/extraction/languages/index.d.ts.map +1 -0
- package/dist/extraction/languages/index.js +43 -0
- package/dist/extraction/languages/index.js.map +1 -0
- package/dist/extraction/languages/java.d.ts +3 -0
- package/dist/extraction/languages/java.d.ts.map +1 -0
- package/dist/extraction/languages/java.js +64 -0
- package/dist/extraction/languages/java.js.map +1 -0
- package/dist/extraction/languages/javascript.d.ts +3 -0
- package/dist/extraction/languages/javascript.d.ts.map +1 -0
- package/dist/extraction/languages/javascript.js +90 -0
- package/dist/extraction/languages/javascript.js.map +1 -0
- package/dist/extraction/languages/kotlin.d.ts +3 -0
- package/dist/extraction/languages/kotlin.d.ts.map +1 -0
- package/dist/extraction/languages/kotlin.js +253 -0
- package/dist/extraction/languages/kotlin.js.map +1 -0
- package/dist/extraction/languages/pascal.d.ts +3 -0
- package/dist/extraction/languages/pascal.d.ts.map +1 -0
- package/dist/extraction/languages/pascal.js +66 -0
- package/dist/extraction/languages/pascal.js.map +1 -0
- package/dist/extraction/languages/php.d.ts +3 -0
- package/dist/extraction/languages/php.d.ts.map +1 -0
- package/dist/extraction/languages/php.js +107 -0
- package/dist/extraction/languages/php.js.map +1 -0
- package/dist/extraction/languages/python.d.ts +3 -0
- package/dist/extraction/languages/python.d.ts.map +1 -0
- package/dist/extraction/languages/python.js +56 -0
- package/dist/extraction/languages/python.js.map +1 -0
- package/dist/extraction/languages/ruby.d.ts +3 -0
- package/dist/extraction/languages/ruby.d.ts.map +1 -0
- package/dist/extraction/languages/ruby.js +114 -0
- package/dist/extraction/languages/ruby.js.map +1 -0
- package/dist/extraction/languages/rust.d.ts +3 -0
- package/dist/extraction/languages/rust.d.ts.map +1 -0
- package/dist/extraction/languages/rust.js +109 -0
- package/dist/extraction/languages/rust.js.map +1 -0
- package/dist/extraction/languages/swift.d.ts +3 -0
- package/dist/extraction/languages/swift.d.ts.map +1 -0
- package/dist/extraction/languages/swift.js +91 -0
- package/dist/extraction/languages/swift.js.map +1 -0
- package/dist/extraction/languages/typescript.d.ts +3 -0
- package/dist/extraction/languages/typescript.d.ts.map +1 -0
- package/dist/extraction/languages/typescript.js +129 -0
- package/dist/extraction/languages/typescript.js.map +1 -0
- package/dist/extraction/liquid-extractor.d.ts +52 -0
- package/dist/extraction/liquid-extractor.d.ts.map +1 -0
- package/dist/extraction/liquid-extractor.js +313 -0
- package/dist/extraction/liquid-extractor.js.map +1 -0
- package/dist/extraction/parse-worker.d.ts +8 -0
- package/dist/extraction/parse-worker.d.ts.map +1 -0
- package/dist/extraction/parse-worker.js +57 -0
- package/dist/extraction/parse-worker.js.map +1 -0
- package/dist/extraction/svelte-extractor.d.ts +56 -0
- package/dist/extraction/svelte-extractor.d.ts.map +1 -0
- package/dist/extraction/svelte-extractor.js +272 -0
- package/dist/extraction/svelte-extractor.js.map +1 -0
- package/dist/extraction/tree-sitter-helpers.d.ts +28 -0
- package/dist/extraction/tree-sitter-helpers.d.ts.map +1 -0
- package/dist/extraction/tree-sitter-helpers.js +103 -0
- package/dist/extraction/tree-sitter-helpers.js.map +1 -0
- package/dist/extraction/tree-sitter-types.d.ts +179 -0
- package/dist/extraction/tree-sitter-types.d.ts.map +1 -0
- package/dist/extraction/tree-sitter-types.js +10 -0
- package/dist/extraction/tree-sitter-types.js.map +1 -0
- package/dist/extraction/tree-sitter.d.ts +67 -125
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +1052 -1855
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/graph/traversal.d.ts.map +1 -1
- package/dist/graph/traversal.js +27 -3
- package/dist/graph/traversal.js.map +1 -1
- package/dist/index.d.ts +29 -53
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +88 -114
- package/dist/index.js.map +1 -1
- package/dist/installer/claude-md-template.d.ts +1 -1
- package/dist/installer/claude-md-template.d.ts.map +1 -1
- package/dist/installer/claude-md-template.js +15 -15
- package/dist/installer/config-writer.d.ts +1 -10
- package/dist/installer/config-writer.d.ts.map +1 -1
- package/dist/installer/config-writer.js +0 -79
- package/dist/installer/config-writer.js.map +1 -1
- package/dist/installer/index.d.ts +3 -4
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +118 -116
- package/dist/installer/index.js.map +1 -1
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +25 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/tools.d.ts +33 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +432 -21
- package/dist/mcp/tools.js.map +1 -1
- package/dist/resolution/frameworks/csharp.js +29 -84
- package/dist/resolution/frameworks/csharp.js.map +1 -1
- package/dist/resolution/frameworks/express.js +44 -48
- package/dist/resolution/frameworks/express.js.map +1 -1
- package/dist/resolution/frameworks/go.js +34 -70
- package/dist/resolution/frameworks/go.js.map +1 -1
- package/dist/resolution/frameworks/java.js +29 -87
- package/dist/resolution/frameworks/java.js.map +1 -1
- package/dist/resolution/frameworks/laravel.js +6 -6
- package/dist/resolution/frameworks/laravel.js.map +1 -1
- package/dist/resolution/frameworks/python.js +33 -98
- package/dist/resolution/frameworks/python.js.map +1 -1
- package/dist/resolution/frameworks/react.js +53 -76
- package/dist/resolution/frameworks/react.js.map +1 -1
- package/dist/resolution/frameworks/ruby.js +12 -24
- package/dist/resolution/frameworks/ruby.js.map +1 -1
- package/dist/resolution/frameworks/rust.js +26 -66
- package/dist/resolution/frameworks/rust.js.map +1 -1
- package/dist/resolution/frameworks/svelte.js +11 -31
- package/dist/resolution/frameworks/svelte.js.map +1 -1
- package/dist/resolution/frameworks/swift.js +42 -160
- package/dist/resolution/frameworks/swift.js.map +1 -1
- package/dist/resolution/index.d.ts +19 -6
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +300 -141
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/name-matcher.d.ts +5 -0
- package/dist/resolution/name-matcher.d.ts.map +1 -1
- package/dist/resolution/name-matcher.js +148 -8
- package/dist/resolution/name-matcher.js.map +1 -1
- package/dist/resolution/types.d.ts +1 -1
- package/dist/resolution/types.d.ts.map +1 -1
- package/dist/search/query-utils.d.ts +26 -1
- package/dist/search/query-utils.d.ts.map +1 -1
- package/dist/search/query-utils.js +209 -9
- package/dist/search/query-utils.js.map +1 -1
- package/dist/sync/index.d.ts +2 -4
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +4 -3
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/watcher.d.ts +81 -0
- package/dist/sync/watcher.d.ts.map +1 -0
- package/dist/sync/watcher.js +184 -0
- package/dist/sync/watcher.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/shimmer-progress.d.ts +11 -0
- package/dist/ui/shimmer-progress.d.ts.map +1 -0
- package/dist/ui/shimmer-progress.js +90 -0
- package/dist/ui/shimmer-progress.js.map +1 -0
- package/dist/ui/shimmer-worker.d.ts +2 -0
- package/dist/ui/shimmer-worker.d.ts.map +1 -0
- package/dist/ui/shimmer-worker.js +112 -0
- package/dist/ui/shimmer-worker.js.map +1 -0
- package/dist/ui/types.d.ts +17 -0
- package/dist/ui/types.d.ts.map +1 -0
- package/dist/ui/types.js +3 -0
- package/dist/ui/types.js.map +1 -0
- package/dist/vectors/embedder.js +1 -1
- package/dist/vectors/embedder.js.map +1 -1
- package/package.json +7 -12
- package/scripts/postinstall.js +0 -68
package/dist/bin/codegraph.d.ts
CHANGED
|
@@ -16,11 +16,6 @@
|
|
|
16
16
|
* codegraph files [options] Show project file structure
|
|
17
17
|
* codegraph context <task> Build context for a task
|
|
18
18
|
* codegraph affected [files] Find test files affected by changes
|
|
19
|
-
* codegraph mark-dirty [path] Mark project as needing sync (hooks)
|
|
20
|
-
* codegraph sync-if-dirty [path] Sync if marked dirty (hooks)
|
|
21
|
-
*
|
|
22
|
-
* Note: Git hooks have been removed. CodeGraph sync is triggered automatically
|
|
23
|
-
* through codegraph's Claude Code hooks integration.
|
|
24
19
|
*/
|
|
25
20
|
export {};
|
|
26
21
|
//# sourceMappingURL=codegraph.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegraph.d.ts","sourceRoot":"","sources":["../../src/bin/codegraph.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"codegraph.d.ts","sourceRoot":"","sources":["../../src/bin/codegraph.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;GAiBG"}
|
package/dist/bin/codegraph.js
CHANGED
|
@@ -17,11 +17,6 @@
|
|
|
17
17
|
* codegraph files [options] Show project file structure
|
|
18
18
|
* codegraph context <task> Build context for a task
|
|
19
19
|
* codegraph affected [files] Find test files affected by changes
|
|
20
|
-
* codegraph mark-dirty [path] Mark project as needing sync (hooks)
|
|
21
|
-
* codegraph sync-if-dirty [path] Sync if marked dirty (hooks)
|
|
22
|
-
*
|
|
23
|
-
* Note: Git hooks have been removed. CodeGraph sync is triggered automatically
|
|
24
|
-
* through codegraph's Claude Code hooks integration.
|
|
25
20
|
*/
|
|
26
21
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
27
22
|
if (k2 === undefined) k2 = k;
|
|
@@ -60,8 +55,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
60
55
|
const commander_1 = require("commander");
|
|
61
56
|
const path = __importStar(require("path"));
|
|
62
57
|
const fs = __importStar(require("fs"));
|
|
63
|
-
const child_process_1 = require("child_process");
|
|
64
58
|
const directory_1 = require("../directory");
|
|
59
|
+
const shimmer_progress_1 = require("../ui/shimmer-progress");
|
|
65
60
|
// Lazy-load heavy modules (CodeGraph, runInstaller) to keep CLI startup fast.
|
|
66
61
|
async function loadCodeGraph() {
|
|
67
62
|
try {
|
|
@@ -76,6 +71,18 @@ async function loadCodeGraph() {
|
|
|
76
71
|
process.exit(1);
|
|
77
72
|
}
|
|
78
73
|
}
|
|
74
|
+
// Dynamic import helper — tsc compiles import() to require() in CJS mode,
|
|
75
|
+
// which fails for ESM-only packages. This bypasses the transformation.
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
77
|
+
const importESM = new Function('specifier', 'return import(specifier)');
|
|
78
|
+
// Warn about unsupported Node.js versions (Node 25+ has V8 turboshaft WASM bugs)
|
|
79
|
+
const nodeVersion = process.versions.node;
|
|
80
|
+
const nodeMajor = parseInt(nodeVersion.split('.')[0] ?? '0', 10);
|
|
81
|
+
if (nodeMajor >= 25) {
|
|
82
|
+
console.warn('\x1b[33m⚠\x1b[0m CodeGraph may crash on Node.js %s due to a V8 WASM compiler bug in Node 25+.', nodeVersion);
|
|
83
|
+
console.warn(' Please use Node.js 22 LTS instead: https://nodejs.org/en/download');
|
|
84
|
+
console.warn(' See: https://github.com/colbymchenry/codegraph/issues/81\n');
|
|
85
|
+
}
|
|
79
86
|
// Check if running with no arguments - run installer
|
|
80
87
|
if (process.argv.length === 2) {
|
|
81
88
|
Promise.resolve().then(() => __importStar(require('../installer'))).then(({ runInstaller }) => runInstaller()).catch((err) => {
|
|
@@ -178,32 +185,38 @@ function main() {
|
|
|
178
185
|
const remainingSeconds = seconds % 60;
|
|
179
186
|
return `${minutes}m ${remainingSeconds.toFixed(0)}s`;
|
|
180
187
|
}
|
|
188
|
+
// Shimmer progress renderer (runs in a worker thread for smooth animation)
|
|
189
|
+
// Imported at top of file from '../ui/shimmer-progress'
|
|
181
190
|
/**
|
|
182
|
-
* Create a progress
|
|
183
|
-
|
|
184
|
-
function progressBar(current, total, width = 30) {
|
|
185
|
-
const percent = total > 0 ? current / total : 0;
|
|
186
|
-
const filled = Math.round(width * percent);
|
|
187
|
-
const empty = width - filled;
|
|
188
|
-
const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
|
|
189
|
-
const percentStr = `${Math.round(percent * 100)}%`.padStart(4);
|
|
190
|
-
return `${bar} ${percentStr}`;
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Print a progress update (overwrites current line)
|
|
191
|
+
* Create a plain-text progress callback for --verbose mode.
|
|
192
|
+
* No animations, no ANSI tricks — just timestamped lines to stdout.
|
|
194
193
|
*/
|
|
195
|
-
function
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
194
|
+
function createVerboseProgress() {
|
|
195
|
+
let lastPhase = '';
|
|
196
|
+
let lastPct = -1;
|
|
197
|
+
const startTime = Date.now();
|
|
198
|
+
return (progress) => {
|
|
199
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
200
|
+
if (progress.phase !== lastPhase) {
|
|
201
|
+
lastPhase = progress.phase;
|
|
202
|
+
lastPct = -1;
|
|
203
|
+
console.log(`[${elapsed}s] Phase: ${progress.phase}`);
|
|
204
|
+
}
|
|
205
|
+
if (progress.total > 0) {
|
|
206
|
+
const pct = Math.floor((progress.current / progress.total) * 100);
|
|
207
|
+
// Log every 5% to keep output manageable
|
|
208
|
+
if (pct >= lastPct + 5 || progress.current === progress.total) {
|
|
209
|
+
lastPct = pct;
|
|
210
|
+
console.log(`[${elapsed}s] ${progress.current}/${progress.total} (${pct}%)${progress.currentFile ? ` — ${progress.currentFile}` : ''}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else if (progress.current > 0) {
|
|
214
|
+
// Scanning phase (no total yet) — log periodically
|
|
215
|
+
if (progress.current % 1000 === 0 || progress.current === 1) {
|
|
216
|
+
console.log(`[${elapsed}s] ${formatNumber(progress.current)} files found`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
201
219
|
};
|
|
202
|
-
const phaseName = phaseNames[progress.phase] || progress.phase;
|
|
203
|
-
const bar = progressBar(progress.current, progress.total);
|
|
204
|
-
const file = progress.currentFile ? chalk.dim(` ${progress.currentFile}`) : '';
|
|
205
|
-
// Clear line and print progress
|
|
206
|
-
process.stdout.write(`\r${chalk.cyan(phaseName)}: ${bar}${file}`.padEnd(100));
|
|
207
220
|
}
|
|
208
221
|
/**
|
|
209
222
|
* Print success message
|
|
@@ -229,6 +242,102 @@ function main() {
|
|
|
229
242
|
function warn(message) {
|
|
230
243
|
console.log(chalk.yellow('⚠') + ' ' + message);
|
|
231
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* Print indexing results using clack log methods
|
|
247
|
+
*/
|
|
248
|
+
function printIndexResult(clack, result, projectPath) {
|
|
249
|
+
const hasErrors = result.filesErrored > 0;
|
|
250
|
+
if (result.filesIndexed > 0) {
|
|
251
|
+
if (hasErrors) {
|
|
252
|
+
clack.log.success(`Indexed ${formatNumber(result.filesIndexed)} files (${formatNumber(result.filesErrored)} could not be parsed)`);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
clack.log.success(`Indexed ${formatNumber(result.filesIndexed)} files`);
|
|
256
|
+
}
|
|
257
|
+
clack.log.info(`${formatNumber(result.nodesCreated)} nodes, ${formatNumber(result.edgesCreated)} edges in ${formatDuration(result.durationMs)}`);
|
|
258
|
+
}
|
|
259
|
+
else if (hasErrors) {
|
|
260
|
+
clack.log.error(`Indexing failed — all ${formatNumber(result.filesErrored)} files had errors`);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
clack.log.warn('No files found to index');
|
|
264
|
+
}
|
|
265
|
+
if (hasErrors) {
|
|
266
|
+
const errorsByCode = new Map();
|
|
267
|
+
for (const err of result.errors) {
|
|
268
|
+
if (err.severity === 'error') {
|
|
269
|
+
const code = err.code || 'unknown';
|
|
270
|
+
errorsByCode.set(code, (errorsByCode.get(code) || 0) + 1);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
const codeLabels = {
|
|
274
|
+
parse_error: 'files failed to parse',
|
|
275
|
+
read_error: 'files could not be read',
|
|
276
|
+
size_exceeded: 'files exceeded size limit',
|
|
277
|
+
path_traversal: 'blocked paths',
|
|
278
|
+
unsupported_language: 'unsupported language',
|
|
279
|
+
parser_error: 'parser initialization failures',
|
|
280
|
+
};
|
|
281
|
+
const breakdown = Array.from(errorsByCode)
|
|
282
|
+
.map(([code, count]) => `${formatNumber(count)} ${codeLabels[code] || code}`)
|
|
283
|
+
.join('\n');
|
|
284
|
+
clack.note(breakdown, 'Error breakdown');
|
|
285
|
+
if (projectPath) {
|
|
286
|
+
writeErrorLog(projectPath, result.errors);
|
|
287
|
+
clack.log.info('See .codegraph/errors.log for details');
|
|
288
|
+
}
|
|
289
|
+
if (result.filesIndexed > 0) {
|
|
290
|
+
clack.log.info('The index is fully usable — only the failed files are missing.');
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
else if (projectPath) {
|
|
294
|
+
const logPath = path.join(projectPath, '.codegraph', 'errors.log');
|
|
295
|
+
if (fs.existsSync(logPath)) {
|
|
296
|
+
fs.unlinkSync(logPath);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Write detailed error log to .codegraph/errors.log
|
|
302
|
+
*/
|
|
303
|
+
function writeErrorLog(projectPath, errors) {
|
|
304
|
+
const cgDir = path.join(projectPath, '.codegraph');
|
|
305
|
+
if (!fs.existsSync(cgDir))
|
|
306
|
+
return;
|
|
307
|
+
const logPath = path.join(cgDir, 'errors.log');
|
|
308
|
+
// Group errors by file path
|
|
309
|
+
const errorsByFile = new Map();
|
|
310
|
+
const noFileErrors = [];
|
|
311
|
+
for (const err of errors) {
|
|
312
|
+
if (err.severity !== 'error')
|
|
313
|
+
continue;
|
|
314
|
+
if (err.filePath) {
|
|
315
|
+
let list = errorsByFile.get(err.filePath);
|
|
316
|
+
if (!list) {
|
|
317
|
+
list = [];
|
|
318
|
+
errorsByFile.set(err.filePath, list);
|
|
319
|
+
}
|
|
320
|
+
list.push({ message: err.message, code: err.code });
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
noFileErrors.push({ message: err.message, code: err.code });
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const lines = [
|
|
327
|
+
`CodeGraph Error Log — ${new Date().toISOString()}`,
|
|
328
|
+
`${errorsByFile.size} files with errors`,
|
|
329
|
+
'',
|
|
330
|
+
];
|
|
331
|
+
for (const [filePath, fileErrors] of errorsByFile) {
|
|
332
|
+
for (const err of fileErrors) {
|
|
333
|
+
lines.push(`${filePath}: ${err.message}`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
for (const err of noFileErrors) {
|
|
337
|
+
lines.push(err.message);
|
|
338
|
+
}
|
|
339
|
+
fs.writeFileSync(logPath, lines.join('\n') + '\n');
|
|
340
|
+
}
|
|
232
341
|
// =============================================================================
|
|
233
342
|
// Commands
|
|
234
343
|
// =============================================================================
|
|
@@ -239,47 +348,47 @@ function main() {
|
|
|
239
348
|
.command('init [path]')
|
|
240
349
|
.description('Initialize CodeGraph in a project directory')
|
|
241
350
|
.option('-i, --index', 'Run initial indexing after initialization')
|
|
351
|
+
.option('-v, --verbose', 'Show detailed worker lifecycle and memory info')
|
|
242
352
|
.action(async (pathArg, options) => {
|
|
243
|
-
const projectPath =
|
|
244
|
-
|
|
353
|
+
const projectPath = path.resolve(pathArg || process.cwd());
|
|
354
|
+
const clack = await importESM('@clack/prompts');
|
|
355
|
+
clack.intro('Initializing CodeGraph');
|
|
245
356
|
try {
|
|
246
|
-
// Check if already initialized
|
|
247
357
|
if ((0, directory_1.isInitialized)(projectPath)) {
|
|
248
|
-
warn(`
|
|
249
|
-
info('Use "codegraph index" to re-index or "codegraph sync" to update');
|
|
358
|
+
clack.log.warn(`Already initialized in ${projectPath}`);
|
|
359
|
+
clack.log.info('Use "codegraph index" to re-index or "codegraph sync" to update');
|
|
360
|
+
clack.outro('');
|
|
250
361
|
return;
|
|
251
362
|
}
|
|
252
|
-
// Initialize
|
|
253
363
|
const { default: CodeGraph } = await loadCodeGraph();
|
|
254
|
-
const cg = await CodeGraph.init(projectPath, {
|
|
255
|
-
|
|
256
|
-
});
|
|
257
|
-
success(`Initialized CodeGraph in ${projectPath}`);
|
|
258
|
-
info(`Created .codegraph/ directory`);
|
|
259
|
-
// Run initial index if requested
|
|
364
|
+
const cg = await CodeGraph.init(projectPath, { index: false });
|
|
365
|
+
clack.log.success(`Initialized in ${projectPath}`);
|
|
260
366
|
if (options.index) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if (result.success) {
|
|
268
|
-
success(`Indexed ${formatNumber(result.filesIndexed)} files`);
|
|
269
|
-
info(`Created ${formatNumber(result.nodesCreated)} nodes and ${formatNumber(result.edgesCreated)} edges`);
|
|
270
|
-
info(`Completed in ${formatDuration(result.durationMs)}`);
|
|
367
|
+
let result;
|
|
368
|
+
if (options.verbose) {
|
|
369
|
+
result = await cg.indexAll({
|
|
370
|
+
onProgress: createVerboseProgress(),
|
|
371
|
+
verbose: true,
|
|
372
|
+
});
|
|
271
373
|
}
|
|
272
374
|
else {
|
|
273
|
-
|
|
375
|
+
process.stdout.write(`${colors.dim}│${colors.reset}\n`);
|
|
376
|
+
const progress = (0, shimmer_progress_1.createShimmerProgress)();
|
|
377
|
+
result = await cg.indexAll({
|
|
378
|
+
onProgress: progress.onProgress,
|
|
379
|
+
});
|
|
380
|
+
await progress.stop();
|
|
274
381
|
}
|
|
382
|
+
printIndexResult(clack, result, projectPath);
|
|
275
383
|
}
|
|
276
384
|
else {
|
|
277
|
-
info('Run "codegraph index" to index the project');
|
|
385
|
+
clack.log.info('Run "codegraph index" to index the project');
|
|
278
386
|
}
|
|
387
|
+
clack.outro('Done');
|
|
279
388
|
cg.destroy();
|
|
280
389
|
}
|
|
281
390
|
catch (err) {
|
|
282
|
-
error(`Failed
|
|
391
|
+
clack.log.error(`Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
283
392
|
process.exit(1);
|
|
284
393
|
}
|
|
285
394
|
});
|
|
@@ -328,6 +437,7 @@ function main() {
|
|
|
328
437
|
.description('Index all files in the project')
|
|
329
438
|
.option('-f, --force', 'Force full re-index even if already indexed')
|
|
330
439
|
.option('-q, --quiet', 'Suppress progress output')
|
|
440
|
+
.option('-v, --verbose', 'Show detailed worker lifecycle and memory info')
|
|
331
441
|
.action(async (pathArg, options) => {
|
|
332
442
|
const projectPath = resolveProjectPath(pathArg);
|
|
333
443
|
try {
|
|
@@ -338,42 +448,42 @@ function main() {
|
|
|
338
448
|
}
|
|
339
449
|
const { default: CodeGraph } = await loadCodeGraph();
|
|
340
450
|
const cg = await CodeGraph.open(projectPath);
|
|
341
|
-
if (
|
|
342
|
-
|
|
451
|
+
if (options.quiet) {
|
|
452
|
+
// Quiet mode: no UI, just run
|
|
453
|
+
if (options.force)
|
|
454
|
+
cg.clear();
|
|
455
|
+
const result = await cg.indexAll();
|
|
456
|
+
if (!result.success)
|
|
457
|
+
process.exit(1);
|
|
458
|
+
cg.destroy();
|
|
459
|
+
return;
|
|
343
460
|
}
|
|
344
|
-
|
|
461
|
+
const clack = await importESM('@clack/prompts');
|
|
462
|
+
clack.intro('Indexing project');
|
|
345
463
|
if (options.force) {
|
|
346
464
|
cg.clear();
|
|
347
|
-
|
|
348
|
-
info('Cleared existing index');
|
|
349
|
-
}
|
|
465
|
+
clack.log.info('Cleared existing index');
|
|
350
466
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
}
|
|
358
|
-
if (result.success) {
|
|
359
|
-
if (!options.quiet) {
|
|
360
|
-
success(`Indexed ${formatNumber(result.filesIndexed)} files`);
|
|
361
|
-
info(`Created ${formatNumber(result.nodesCreated)} nodes and ${formatNumber(result.edgesCreated)} edges`);
|
|
362
|
-
info(`Completed in ${formatDuration(result.durationMs)}`);
|
|
363
|
-
}
|
|
467
|
+
let result;
|
|
468
|
+
if (options.verbose) {
|
|
469
|
+
result = await cg.indexAll({
|
|
470
|
+
onProgress: createVerboseProgress(),
|
|
471
|
+
verbose: true,
|
|
472
|
+
});
|
|
364
473
|
}
|
|
365
474
|
else {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
475
|
+
process.stdout.write(`${colors.dim}│${colors.reset}\n`);
|
|
476
|
+
const progress = (0, shimmer_progress_1.createShimmerProgress)();
|
|
477
|
+
result = await cg.indexAll({
|
|
478
|
+
onProgress: progress.onProgress,
|
|
479
|
+
});
|
|
480
|
+
await progress.stop();
|
|
481
|
+
}
|
|
482
|
+
printIndexResult(clack, result, projectPath);
|
|
483
|
+
if (!result.success) {
|
|
375
484
|
process.exit(1);
|
|
376
485
|
}
|
|
486
|
+
clack.outro('Done');
|
|
377
487
|
cg.destroy();
|
|
378
488
|
}
|
|
379
489
|
catch (err) {
|
|
@@ -399,32 +509,35 @@ function main() {
|
|
|
399
509
|
}
|
|
400
510
|
const { default: CodeGraph } = await loadCodeGraph();
|
|
401
511
|
const cg = await CodeGraph.open(projectPath);
|
|
512
|
+
if (options.quiet) {
|
|
513
|
+
await cg.sync();
|
|
514
|
+
cg.destroy();
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const clack = await importESM('@clack/prompts');
|
|
518
|
+
clack.intro('Syncing CodeGraph');
|
|
519
|
+
process.stdout.write(`${colors.dim}│${colors.reset}\n`);
|
|
520
|
+
const progress = (0, shimmer_progress_1.createShimmerProgress)();
|
|
402
521
|
const result = await cg.sync({
|
|
403
|
-
onProgress:
|
|
522
|
+
onProgress: progress.onProgress,
|
|
404
523
|
});
|
|
405
|
-
|
|
406
|
-
if (!options.quiet) {
|
|
407
|
-
process.stdout.write('\r' + ' '.repeat(100) + '\r');
|
|
408
|
-
}
|
|
524
|
+
await progress.stop();
|
|
409
525
|
const totalChanges = result.filesAdded + result.filesModified + result.filesRemoved;
|
|
410
|
-
if (
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
info(` Removed: ${result.filesRemoved}`);
|
|
424
|
-
}
|
|
425
|
-
info(`Updated ${formatNumber(result.nodesUpdated)} nodes in ${formatDuration(result.durationMs)}`);
|
|
426
|
-
}
|
|
526
|
+
if (totalChanges === 0) {
|
|
527
|
+
clack.log.info('Already up to date');
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
clack.log.success(`Synced ${formatNumber(totalChanges)} changed files`);
|
|
531
|
+
const details = [];
|
|
532
|
+
if (result.filesAdded > 0)
|
|
533
|
+
details.push(`Added: ${result.filesAdded}`);
|
|
534
|
+
if (result.filesModified > 0)
|
|
535
|
+
details.push(`Modified: ${result.filesModified}`);
|
|
536
|
+
if (result.filesRemoved > 0)
|
|
537
|
+
details.push(`Removed: ${result.filesRemoved}`);
|
|
538
|
+
clack.log.info(`${details.join(', ')} — ${formatNumber(result.nodesUpdated)} nodes in ${formatDuration(result.durationMs)}`);
|
|
427
539
|
}
|
|
540
|
+
clack.outro('Done');
|
|
428
541
|
cg.destroy();
|
|
429
542
|
}
|
|
430
543
|
catch (err) {
|
|
@@ -842,139 +955,6 @@ function main() {
|
|
|
842
955
|
process.exit(1);
|
|
843
956
|
}
|
|
844
957
|
});
|
|
845
|
-
/**
|
|
846
|
-
* codegraph visualize [path]
|
|
847
|
-
*/
|
|
848
|
-
program
|
|
849
|
-
.command('visualize [path]')
|
|
850
|
-
.description('Open interactive graph visualization in your browser')
|
|
851
|
-
.option('-p, --port <port>', 'Port to listen on (default: auto)', parseInt)
|
|
852
|
-
.option('--no-open', 'Do not open browser automatically')
|
|
853
|
-
.action(async (pathArg, options) => {
|
|
854
|
-
const projectPath = resolveProjectPath(pathArg);
|
|
855
|
-
try {
|
|
856
|
-
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
857
|
-
error(`CodeGraph not initialized in ${projectPath}`);
|
|
858
|
-
info('Run "codegraph init -i" first');
|
|
859
|
-
process.exit(1);
|
|
860
|
-
}
|
|
861
|
-
const { default: CodeGraph } = await loadCodeGraph();
|
|
862
|
-
const cg = await CodeGraph.open(projectPath);
|
|
863
|
-
const stats = cg.getStats();
|
|
864
|
-
console.log(chalk.bold('\n CodeGraph Explorer\n'));
|
|
865
|
-
info(`Project: ${projectPath}`);
|
|
866
|
-
info(`Indexed: ${formatNumber(stats.nodeCount)} nodes, ${formatNumber(stats.edgeCount)} edges, ${formatNumber(stats.fileCount)} files\n`);
|
|
867
|
-
const { VisualizerServer } = await Promise.resolve().then(() => __importStar(require('../visualizer/server')));
|
|
868
|
-
const server = new VisualizerServer(cg);
|
|
869
|
-
const { url } = await server.start({ port: options.port, openBrowser: options.open !== false });
|
|
870
|
-
success(`Visualizer running at ${chalk.cyan(url)}`);
|
|
871
|
-
console.log(chalk.dim(' Press Ctrl+C to stop\n'));
|
|
872
|
-
// Open browser
|
|
873
|
-
if (options.open !== false) {
|
|
874
|
-
const openCmd = process.platform === 'darwin' ? 'open' :
|
|
875
|
-
process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
876
|
-
(0, child_process_1.spawn)(openCmd, [url], { detached: true, stdio: 'ignore' }).unref();
|
|
877
|
-
}
|
|
878
|
-
// Handle shutdown — force exit on second Ctrl+C
|
|
879
|
-
let shuttingDown = false;
|
|
880
|
-
const shutdown = () => {
|
|
881
|
-
if (shuttingDown) {
|
|
882
|
-
process.exit(1);
|
|
883
|
-
}
|
|
884
|
-
shuttingDown = true;
|
|
885
|
-
console.log(chalk.dim('\n Shutting down...'));
|
|
886
|
-
server.stop().then(() => {
|
|
887
|
-
cg.close();
|
|
888
|
-
process.exit(0);
|
|
889
|
-
}).catch(() => process.exit(1));
|
|
890
|
-
// Force exit after 2s if graceful shutdown hangs
|
|
891
|
-
setTimeout(() => process.exit(1), 2000).unref();
|
|
892
|
-
};
|
|
893
|
-
process.on('SIGINT', shutdown);
|
|
894
|
-
process.on('SIGTERM', shutdown);
|
|
895
|
-
}
|
|
896
|
-
catch (err) {
|
|
897
|
-
error(`Failed to start visualizer: ${err instanceof Error ? err.message : String(err)}`);
|
|
898
|
-
process.exit(1);
|
|
899
|
-
}
|
|
900
|
-
});
|
|
901
|
-
/**
|
|
902
|
-
* codegraph mark-dirty [path]
|
|
903
|
-
*
|
|
904
|
-
* Touches .codegraph/.dirty to signal that files have changed.
|
|
905
|
-
* Used by Claude Code PostToolUse hooks to batch syncs.
|
|
906
|
-
* Runs silently and always exits 0.
|
|
907
|
-
*/
|
|
908
|
-
program
|
|
909
|
-
.command('mark-dirty [path]')
|
|
910
|
-
.description('Mark project as needing sync (used by Claude Code hooks)')
|
|
911
|
-
.action(async (pathArg) => {
|
|
912
|
-
try {
|
|
913
|
-
const startPath = path.resolve(pathArg || process.cwd());
|
|
914
|
-
const projectRoot = (0, directory_1.findNearestCodeGraphRoot)(startPath);
|
|
915
|
-
if (!projectRoot) {
|
|
916
|
-
// No .codegraph/ found — exit silently
|
|
917
|
-
process.exit(0);
|
|
918
|
-
}
|
|
919
|
-
const dirtyPath = path.join((0, directory_1.getCodeGraphDir)(projectRoot), '.dirty');
|
|
920
|
-
fs.writeFileSync(dirtyPath, Date.now().toString(), 'utf-8');
|
|
921
|
-
}
|
|
922
|
-
catch {
|
|
923
|
-
// Never fail — this runs in the background during edits
|
|
924
|
-
}
|
|
925
|
-
process.exit(0);
|
|
926
|
-
});
|
|
927
|
-
/**
|
|
928
|
-
* codegraph sync-if-dirty [path]
|
|
929
|
-
*
|
|
930
|
-
* Checks if .codegraph/.dirty exists and, if so, spawns a detached
|
|
931
|
-
* background process to run `codegraph sync`. The hook process exits
|
|
932
|
-
* immediately so Claude Code's Stop hook never blocks.
|
|
933
|
-
*
|
|
934
|
-
* Removes the marker BEFORE spawning so edits during sync
|
|
935
|
-
* create a new marker for the next Stop event.
|
|
936
|
-
* Runs silently and always exits 0.
|
|
937
|
-
*/
|
|
938
|
-
program
|
|
939
|
-
.command('sync-if-dirty [path]')
|
|
940
|
-
.description('Sync if project was marked dirty (used by Claude Code hooks)')
|
|
941
|
-
.action(async (pathArg) => {
|
|
942
|
-
try {
|
|
943
|
-
const startPath = path.resolve(pathArg || process.cwd());
|
|
944
|
-
const projectRoot = (0, directory_1.findNearestCodeGraphRoot)(startPath);
|
|
945
|
-
if (!projectRoot) {
|
|
946
|
-
process.exit(0);
|
|
947
|
-
}
|
|
948
|
-
const dirtyPath = path.join((0, directory_1.getCodeGraphDir)(projectRoot), '.dirty');
|
|
949
|
-
// No marker → nothing to do (sub-ms exit)
|
|
950
|
-
if (!fs.existsSync(dirtyPath)) {
|
|
951
|
-
process.exit(0);
|
|
952
|
-
}
|
|
953
|
-
// Remove marker FIRST so edits during sync create a new one
|
|
954
|
-
try {
|
|
955
|
-
fs.unlinkSync(dirtyPath);
|
|
956
|
-
}
|
|
957
|
-
catch { /* ignore */ }
|
|
958
|
-
// If not fully initialized (no DB), exit
|
|
959
|
-
if (!(0, directory_1.isInitialized)(projectRoot)) {
|
|
960
|
-
process.exit(0);
|
|
961
|
-
}
|
|
962
|
-
// Spawn sync as a detached background process
|
|
963
|
-
// so this hook exits immediately and doesn't block Claude Code.
|
|
964
|
-
// Uses process.argv[0]/[1] (e.g. node /path/to/codegraph.js) so it
|
|
965
|
-
// works whether invoked via global install, npx, or directly.
|
|
966
|
-
const child = (0, child_process_1.spawn)(process.argv[0], [process.argv[1], 'sync', '--quiet', projectRoot], {
|
|
967
|
-
detached: true,
|
|
968
|
-
stdio: 'ignore',
|
|
969
|
-
windowsHide: true,
|
|
970
|
-
});
|
|
971
|
-
child.unref();
|
|
972
|
-
}
|
|
973
|
-
catch {
|
|
974
|
-
// Never fail — this runs at the end of Claude responses
|
|
975
|
-
}
|
|
976
|
-
process.exit(0);
|
|
977
|
-
});
|
|
978
958
|
/**
|
|
979
959
|
* codegraph unlock [path]
|
|
980
960
|
*/
|