@colbymchenry/codegraph 0.7.10 → 0.9.0
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 +70 -54
- package/npm-shim.js +43 -0
- package/package.json +13 -51
- package/LICENSE +0 -21
- package/dist/bin/codegraph.d.ts +0 -21
- package/dist/bin/codegraph.d.ts.map +0 -1
- package/dist/bin/codegraph.js +0 -1232
- package/dist/bin/codegraph.js.map +0 -1
- package/dist/bin/node-version-check.d.ts +0 -20
- package/dist/bin/node-version-check.d.ts.map +0 -1
- package/dist/bin/node-version-check.js +0 -42
- package/dist/bin/node-version-check.js.map +0 -1
- package/dist/bin/uninstall.d.ts +0 -14
- package/dist/bin/uninstall.d.ts.map +0 -1
- package/dist/bin/uninstall.js +0 -36
- package/dist/bin/uninstall.js.map +0 -1
- package/dist/config.d.ts +0 -51
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -321
- package/dist/config.js.map +0 -1
- package/dist/context/formatter.d.ts +0 -30
- package/dist/context/formatter.d.ts.map +0 -1
- package/dist/context/formatter.js +0 -244
- package/dist/context/formatter.js.map +0 -1
- package/dist/context/index.d.ts +0 -97
- package/dist/context/index.d.ts.map +0 -1
- package/dist/context/index.js +0 -1048
- package/dist/context/index.js.map +0 -1
- package/dist/db/index.d.ts +0 -72
- package/dist/db/index.d.ts.map +0 -1
- package/dist/db/index.js +0 -200
- package/dist/db/index.js.map +0 -1
- package/dist/db/migrations.d.ts +0 -44
- package/dist/db/migrations.d.ts.map +0 -1
- package/dist/db/migrations.js +0 -131
- package/dist/db/migrations.js.map +0 -1
- package/dist/db/queries.d.ts +0 -253
- package/dist/db/queries.d.ts.map +0 -1
- package/dist/db/queries.js +0 -1207
- package/dist/db/queries.js.map +0 -1
- package/dist/db/schema.sql +0 -151
- package/dist/db/sqlite-adapter.d.ts +0 -52
- package/dist/db/sqlite-adapter.d.ts.map +0 -1
- package/dist/db/sqlite-adapter.js +0 -237
- package/dist/db/sqlite-adapter.js.map +0 -1
- package/dist/directory.d.ts +0 -57
- package/dist/directory.d.ts.map +0 -1
- package/dist/directory.js +0 -264
- package/dist/directory.js.map +0 -1
- package/dist/errors.d.ts +0 -136
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -219
- package/dist/errors.js.map +0 -1
- package/dist/extraction/dfm-extractor.d.ts +0 -31
- package/dist/extraction/dfm-extractor.d.ts.map +0 -1
- package/dist/extraction/dfm-extractor.js +0 -151
- package/dist/extraction/dfm-extractor.js.map +0 -1
- package/dist/extraction/grammars.d.ts +0 -78
- package/dist/extraction/grammars.d.ts.map +0 -1
- package/dist/extraction/grammars.js +0 -322
- package/dist/extraction/grammars.js.map +0 -1
- package/dist/extraction/index.d.ts +0 -130
- package/dist/extraction/index.d.ts.map +0 -1
- package/dist/extraction/index.js +0 -1279
- package/dist/extraction/index.js.map +0 -1
- package/dist/extraction/languages/c-cpp.d.ts +0 -4
- package/dist/extraction/languages/c-cpp.d.ts.map +0 -1
- package/dist/extraction/languages/c-cpp.js +0 -126
- package/dist/extraction/languages/c-cpp.js.map +0 -1
- package/dist/extraction/languages/csharp.d.ts +0 -3
- package/dist/extraction/languages/csharp.d.ts.map +0 -1
- package/dist/extraction/languages/csharp.js +0 -72
- package/dist/extraction/languages/csharp.js.map +0 -1
- package/dist/extraction/languages/dart.d.ts +0 -3
- package/dist/extraction/languages/dart.d.ts.map +0 -1
- package/dist/extraction/languages/dart.js +0 -192
- package/dist/extraction/languages/dart.js.map +0 -1
- package/dist/extraction/languages/go.d.ts +0 -3
- package/dist/extraction/languages/go.d.ts.map +0 -1
- package/dist/extraction/languages/go.js +0 -58
- package/dist/extraction/languages/go.js.map +0 -1
- package/dist/extraction/languages/index.d.ts +0 -10
- package/dist/extraction/languages/index.d.ts.map +0 -1
- package/dist/extraction/languages/index.js +0 -45
- package/dist/extraction/languages/index.js.map +0 -1
- package/dist/extraction/languages/java.d.ts +0 -3
- package/dist/extraction/languages/java.d.ts.map +0 -1
- package/dist/extraction/languages/java.js +0 -64
- package/dist/extraction/languages/java.js.map +0 -1
- package/dist/extraction/languages/javascript.d.ts +0 -3
- package/dist/extraction/languages/javascript.d.ts.map +0 -1
- package/dist/extraction/languages/javascript.js +0 -90
- package/dist/extraction/languages/javascript.js.map +0 -1
- package/dist/extraction/languages/kotlin.d.ts +0 -3
- package/dist/extraction/languages/kotlin.d.ts.map +0 -1
- package/dist/extraction/languages/kotlin.js +0 -253
- package/dist/extraction/languages/kotlin.js.map +0 -1
- package/dist/extraction/languages/pascal.d.ts +0 -3
- package/dist/extraction/languages/pascal.d.ts.map +0 -1
- package/dist/extraction/languages/pascal.js +0 -66
- package/dist/extraction/languages/pascal.js.map +0 -1
- package/dist/extraction/languages/php.d.ts +0 -3
- package/dist/extraction/languages/php.d.ts.map +0 -1
- package/dist/extraction/languages/php.js +0 -107
- package/dist/extraction/languages/php.js.map +0 -1
- package/dist/extraction/languages/python.d.ts +0 -3
- package/dist/extraction/languages/python.d.ts.map +0 -1
- package/dist/extraction/languages/python.js +0 -56
- package/dist/extraction/languages/python.js.map +0 -1
- package/dist/extraction/languages/ruby.d.ts +0 -3
- package/dist/extraction/languages/ruby.d.ts.map +0 -1
- package/dist/extraction/languages/ruby.js +0 -114
- package/dist/extraction/languages/ruby.js.map +0 -1
- package/dist/extraction/languages/rust.d.ts +0 -3
- package/dist/extraction/languages/rust.d.ts.map +0 -1
- package/dist/extraction/languages/rust.js +0 -109
- package/dist/extraction/languages/rust.js.map +0 -1
- package/dist/extraction/languages/scala.d.ts +0 -3
- package/dist/extraction/languages/scala.d.ts.map +0 -1
- package/dist/extraction/languages/scala.js +0 -139
- package/dist/extraction/languages/scala.js.map +0 -1
- package/dist/extraction/languages/swift.d.ts +0 -3
- package/dist/extraction/languages/swift.d.ts.map +0 -1
- package/dist/extraction/languages/swift.js +0 -91
- package/dist/extraction/languages/swift.js.map +0 -1
- package/dist/extraction/languages/typescript.d.ts +0 -3
- package/dist/extraction/languages/typescript.d.ts.map +0 -1
- package/dist/extraction/languages/typescript.js +0 -129
- package/dist/extraction/languages/typescript.js.map +0 -1
- package/dist/extraction/liquid-extractor.d.ts +0 -52
- package/dist/extraction/liquid-extractor.d.ts.map +0 -1
- package/dist/extraction/liquid-extractor.js +0 -313
- package/dist/extraction/liquid-extractor.js.map +0 -1
- package/dist/extraction/parse-worker.d.ts +0 -8
- package/dist/extraction/parse-worker.d.ts.map +0 -1
- package/dist/extraction/parse-worker.js +0 -94
- package/dist/extraction/parse-worker.js.map +0 -1
- package/dist/extraction/svelte-extractor.d.ts +0 -56
- package/dist/extraction/svelte-extractor.d.ts.map +0 -1
- package/dist/extraction/svelte-extractor.js +0 -272
- package/dist/extraction/svelte-extractor.js.map +0 -1
- package/dist/extraction/tree-sitter-helpers.d.ts +0 -28
- package/dist/extraction/tree-sitter-helpers.d.ts.map +0 -1
- package/dist/extraction/tree-sitter-helpers.js +0 -103
- package/dist/extraction/tree-sitter-helpers.js.map +0 -1
- package/dist/extraction/tree-sitter-types.d.ts +0 -179
- package/dist/extraction/tree-sitter-types.d.ts.map +0 -1
- package/dist/extraction/tree-sitter-types.js +0 -10
- package/dist/extraction/tree-sitter-types.js.map +0 -1
- package/dist/extraction/tree-sitter.d.ts +0 -233
- package/dist/extraction/tree-sitter.d.ts.map +0 -1
- package/dist/extraction/tree-sitter.js +0 -2393
- package/dist/extraction/tree-sitter.js.map +0 -1
- package/dist/extraction/vue-extractor.d.ts +0 -36
- package/dist/extraction/vue-extractor.d.ts.map +0 -1
- package/dist/extraction/vue-extractor.js +0 -163
- package/dist/extraction/vue-extractor.js.map +0 -1
- package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/dist/graph/index.d.ts +0 -8
- package/dist/graph/index.d.ts.map +0 -1
- package/dist/graph/index.js +0 -13
- package/dist/graph/index.js.map +0 -1
- package/dist/graph/queries.d.ts +0 -106
- package/dist/graph/queries.d.ts.map +0 -1
- package/dist/graph/queries.js +0 -366
- package/dist/graph/queries.js.map +0 -1
- package/dist/graph/traversal.d.ts +0 -127
- package/dist/graph/traversal.d.ts.map +0 -1
- package/dist/graph/traversal.js +0 -493
- package/dist/graph/traversal.js.map +0 -1
- package/dist/index.d.ts +0 -447
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -825
- package/dist/index.js.map +0 -1
- package/dist/installer/claude-md-template.d.ts +0 -14
- package/dist/installer/claude-md-template.d.ts.map +0 -1
- package/dist/installer/claude-md-template.js +0 -21
- package/dist/installer/claude-md-template.js.map +0 -1
- package/dist/installer/config-writer.d.ts +0 -29
- package/dist/installer/config-writer.d.ts.map +0 -1
- package/dist/installer/config-writer.js +0 -109
- package/dist/installer/config-writer.js.map +0 -1
- package/dist/installer/index.d.ts +0 -53
- package/dist/installer/index.d.ts.map +0 -1
- package/dist/installer/index.js +0 -338
- package/dist/installer/index.js.map +0 -1
- package/dist/installer/instructions-template.d.ts +0 -28
- package/dist/installer/instructions-template.d.ts.map +0 -1
- package/dist/installer/instructions-template.js +0 -63
- package/dist/installer/instructions-template.js.map +0 -1
- package/dist/installer/targets/claude.d.ts +0 -27
- package/dist/installer/targets/claude.d.ts.map +0 -1
- package/dist/installer/targets/claude.js +0 -246
- package/dist/installer/targets/claude.js.map +0 -1
- package/dist/installer/targets/codex.d.ts +0 -18
- package/dist/installer/targets/codex.d.ts.map +0 -1
- package/dist/installer/targets/codex.js +0 -185
- package/dist/installer/targets/codex.js.map +0 -1
- package/dist/installer/targets/cursor.d.ts +0 -35
- package/dist/installer/targets/cursor.d.ts.map +0 -1
- package/dist/installer/targets/cursor.js +0 -229
- package/dist/installer/targets/cursor.js.map +0 -1
- package/dist/installer/targets/opencode.d.ts +0 -30
- package/dist/installer/targets/opencode.d.ts.map +0 -1
- package/dist/installer/targets/opencode.js +0 -235
- package/dist/installer/targets/opencode.js.map +0 -1
- package/dist/installer/targets/registry.d.ts +0 -35
- package/dist/installer/targets/registry.d.ts.map +0 -1
- package/dist/installer/targets/registry.js +0 -83
- package/dist/installer/targets/registry.js.map +0 -1
- package/dist/installer/targets/shared.d.ts +0 -77
- package/dist/installer/targets/shared.d.ts.map +0 -1
- package/dist/installer/targets/shared.js +0 -246
- package/dist/installer/targets/shared.js.map +0 -1
- package/dist/installer/targets/toml.d.ts +0 -52
- package/dist/installer/targets/toml.d.ts.map +0 -1
- package/dist/installer/targets/toml.js +0 -147
- package/dist/installer/targets/toml.js.map +0 -1
- package/dist/installer/targets/types.d.ts +0 -116
- package/dist/installer/targets/types.d.ts.map +0 -1
- package/dist/installer/targets/types.js +0 -16
- package/dist/installer/targets/types.js.map +0 -1
- package/dist/mcp/index.d.ts +0 -86
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.js +0 -355
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/server-instructions.d.ts +0 -19
- package/dist/mcp/server-instructions.d.ts.map +0 -1
- package/dist/mcp/server-instructions.js +0 -59
- package/dist/mcp/server-instructions.js.map +0 -1
- package/dist/mcp/tools.d.ts +0 -200
- package/dist/mcp/tools.d.ts.map +0 -1
- package/dist/mcp/tools.js +0 -1319
- package/dist/mcp/tools.js.map +0 -1
- package/dist/mcp/transport.d.ts +0 -89
- package/dist/mcp/transport.d.ts.map +0 -1
- package/dist/mcp/transport.js +0 -170
- package/dist/mcp/transport.js.map +0 -1
- package/dist/resolution/frameworks/cargo-workspace.d.ts +0 -18
- package/dist/resolution/frameworks/cargo-workspace.d.ts.map +0 -1
- package/dist/resolution/frameworks/cargo-workspace.js +0 -225
- package/dist/resolution/frameworks/cargo-workspace.js.map +0 -1
- package/dist/resolution/frameworks/csharp.d.ts +0 -8
- package/dist/resolution/frameworks/csharp.d.ts.map +0 -1
- package/dist/resolution/frameworks/csharp.js +0 -213
- package/dist/resolution/frameworks/csharp.js.map +0 -1
- package/dist/resolution/frameworks/express.d.ts +0 -8
- package/dist/resolution/frameworks/express.d.ts.map +0 -1
- package/dist/resolution/frameworks/express.js +0 -225
- package/dist/resolution/frameworks/express.js.map +0 -1
- package/dist/resolution/frameworks/go.d.ts +0 -8
- package/dist/resolution/frameworks/go.d.ts.map +0 -1
- package/dist/resolution/frameworks/go.js +0 -158
- package/dist/resolution/frameworks/go.js.map +0 -1
- package/dist/resolution/frameworks/index.d.ts +0 -41
- package/dist/resolution/frameworks/index.d.ts.map +0 -1
- package/dist/resolution/frameworks/index.js +0 -129
- package/dist/resolution/frameworks/index.js.map +0 -1
- package/dist/resolution/frameworks/java.d.ts +0 -8
- package/dist/resolution/frameworks/java.d.ts.map +0 -1
- package/dist/resolution/frameworks/java.js +0 -177
- package/dist/resolution/frameworks/java.js.map +0 -1
- package/dist/resolution/frameworks/laravel.d.ts +0 -13
- package/dist/resolution/frameworks/laravel.d.ts.map +0 -1
- package/dist/resolution/frameworks/laravel.js +0 -248
- package/dist/resolution/frameworks/laravel.js.map +0 -1
- package/dist/resolution/frameworks/python.d.ts +0 -10
- package/dist/resolution/frameworks/python.d.ts.map +0 -1
- package/dist/resolution/frameworks/python.js +0 -278
- package/dist/resolution/frameworks/python.js.map +0 -1
- package/dist/resolution/frameworks/react.d.ts +0 -8
- package/dist/resolution/frameworks/react.d.ts.map +0 -1
- package/dist/resolution/frameworks/react.js +0 -272
- package/dist/resolution/frameworks/react.js.map +0 -1
- package/dist/resolution/frameworks/ruby.d.ts +0 -8
- package/dist/resolution/frameworks/ruby.d.ts.map +0 -1
- package/dist/resolution/frameworks/ruby.js +0 -198
- package/dist/resolution/frameworks/ruby.js.map +0 -1
- package/dist/resolution/frameworks/rust.d.ts +0 -8
- package/dist/resolution/frameworks/rust.d.ts.map +0 -1
- package/dist/resolution/frameworks/rust.js +0 -207
- package/dist/resolution/frameworks/rust.js.map +0 -1
- package/dist/resolution/frameworks/svelte.d.ts +0 -9
- package/dist/resolution/frameworks/svelte.d.ts.map +0 -1
- package/dist/resolution/frameworks/svelte.js +0 -249
- package/dist/resolution/frameworks/svelte.js.map +0 -1
- package/dist/resolution/frameworks/swift.d.ts +0 -10
- package/dist/resolution/frameworks/swift.d.ts.map +0 -1
- package/dist/resolution/frameworks/swift.js +0 -376
- package/dist/resolution/frameworks/swift.js.map +0 -1
- package/dist/resolution/frameworks/vue.d.ts +0 -9
- package/dist/resolution/frameworks/vue.d.ts.map +0 -1
- package/dist/resolution/frameworks/vue.js +0 -306
- package/dist/resolution/frameworks/vue.js.map +0 -1
- package/dist/resolution/import-resolver.d.ts +0 -40
- package/dist/resolution/import-resolver.d.ts.map +0 -1
- package/dist/resolution/import-resolver.js +0 -663
- package/dist/resolution/import-resolver.js.map +0 -1
- package/dist/resolution/index.d.ts +0 -106
- package/dist/resolution/index.d.ts.map +0 -1
- package/dist/resolution/index.js +0 -709
- package/dist/resolution/index.js.map +0 -1
- package/dist/resolution/name-matcher.d.ts +0 -32
- package/dist/resolution/name-matcher.d.ts.map +0 -1
- package/dist/resolution/name-matcher.js +0 -384
- package/dist/resolution/name-matcher.js.map +0 -1
- package/dist/resolution/path-aliases.d.ts +0 -68
- package/dist/resolution/path-aliases.d.ts.map +0 -1
- package/dist/resolution/path-aliases.js +0 -238
- package/dist/resolution/path-aliases.js.map +0 -1
- package/dist/resolution/strip-comments.d.ts +0 -27
- package/dist/resolution/strip-comments.d.ts.map +0 -1
- package/dist/resolution/strip-comments.js +0 -441
- package/dist/resolution/strip-comments.js.map +0 -1
- package/dist/resolution/types.d.ts +0 -172
- package/dist/resolution/types.d.ts.map +0 -1
- package/dist/resolution/types.js +0 -8
- package/dist/resolution/types.js.map +0 -1
- package/dist/search/query-parser.d.ts +0 -57
- package/dist/search/query-parser.d.ts.map +0 -1
- package/dist/search/query-parser.js +0 -177
- package/dist/search/query-parser.js.map +0 -1
- package/dist/search/query-utils.d.ts +0 -53
- package/dist/search/query-utils.d.ts.map +0 -1
- package/dist/search/query-utils.js +0 -347
- package/dist/search/query-utils.js.map +0 -1
- package/dist/sync/index.d.ts +0 -13
- package/dist/sync/index.d.ts.map +0 -1
- package/dist/sync/index.js +0 -17
- package/dist/sync/index.js.map +0 -1
- package/dist/sync/watcher.d.ts +0 -81
- package/dist/sync/watcher.d.ts.map +0 -1
- package/dist/sync/watcher.js +0 -184
- package/dist/sync/watcher.js.map +0 -1
- package/dist/types.d.ts +0 -423
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -256
- package/dist/types.js.map +0 -1
- package/dist/ui/glyphs.d.ts +0 -42
- package/dist/ui/glyphs.d.ts.map +0 -1
- package/dist/ui/glyphs.js +0 -78
- package/dist/ui/glyphs.js.map +0 -1
- package/dist/ui/shimmer-progress.d.ts +0 -11
- package/dist/ui/shimmer-progress.d.ts.map +0 -1
- package/dist/ui/shimmer-progress.js +0 -90
- package/dist/ui/shimmer-progress.js.map +0 -1
- package/dist/ui/shimmer-worker.d.ts +0 -2
- package/dist/ui/shimmer-worker.d.ts.map +0 -1
- package/dist/ui/shimmer-worker.js +0 -118
- package/dist/ui/shimmer-worker.js.map +0 -1
- package/dist/ui/types.d.ts +0 -17
- package/dist/ui/types.d.ts.map +0 -1
- package/dist/ui/types.js +0 -3
- package/dist/ui/types.js.map +0 -1
- package/dist/utils.d.ts +0 -205
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -549
- package/dist/utils.js.map +0 -1
- package/scripts/local-install.sh +0 -41
- package/scripts/patch-tree-sitter-dart.js +0 -112
- package/scripts/release.sh +0 -70
package/dist/bin/codegraph.js
DELETED
|
@@ -1,1232 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
/**
|
|
4
|
-
* CodeGraph CLI
|
|
5
|
-
*
|
|
6
|
-
* Command-line interface for CodeGraph code intelligence.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* codegraph Run interactive installer (when no args)
|
|
10
|
-
* codegraph install Run interactive installer
|
|
11
|
-
* codegraph init [path] Initialize CodeGraph in a project
|
|
12
|
-
* codegraph uninit [path] Remove CodeGraph from a project
|
|
13
|
-
* codegraph index [path] Index all files in the project
|
|
14
|
-
* codegraph sync [path] Sync changes since last index
|
|
15
|
-
* codegraph status [path] Show index status
|
|
16
|
-
* codegraph query <search> Search for symbols
|
|
17
|
-
* codegraph files [options] Show project file structure
|
|
18
|
-
* codegraph context <task> Build context for a task
|
|
19
|
-
* codegraph affected [files] Find test files affected by changes
|
|
20
|
-
*/
|
|
21
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
22
|
-
if (k2 === undefined) k2 = k;
|
|
23
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
24
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
25
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
26
|
-
}
|
|
27
|
-
Object.defineProperty(o, k2, desc);
|
|
28
|
-
}) : (function(o, m, k, k2) {
|
|
29
|
-
if (k2 === undefined) k2 = k;
|
|
30
|
-
o[k2] = m[k];
|
|
31
|
-
}));
|
|
32
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
33
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
34
|
-
}) : function(o, v) {
|
|
35
|
-
o["default"] = v;
|
|
36
|
-
});
|
|
37
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
38
|
-
var ownKeys = function(o) {
|
|
39
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
40
|
-
var ar = [];
|
|
41
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
42
|
-
return ar;
|
|
43
|
-
};
|
|
44
|
-
return ownKeys(o);
|
|
45
|
-
};
|
|
46
|
-
return function (mod) {
|
|
47
|
-
if (mod && mod.__esModule) return mod;
|
|
48
|
-
var result = {};
|
|
49
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
50
|
-
__setModuleDefault(result, mod);
|
|
51
|
-
return result;
|
|
52
|
-
};
|
|
53
|
-
})();
|
|
54
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
-
const commander_1 = require("commander");
|
|
56
|
-
const path = __importStar(require("path"));
|
|
57
|
-
const fs = __importStar(require("fs"));
|
|
58
|
-
const directory_1 = require("../directory");
|
|
59
|
-
const shimmer_progress_1 = require("../ui/shimmer-progress");
|
|
60
|
-
const glyphs_1 = require("../ui/glyphs");
|
|
61
|
-
const node_version_check_1 = require("./node-version-check");
|
|
62
|
-
// Lazy-load heavy modules (CodeGraph, runInstaller) to keep CLI startup fast.
|
|
63
|
-
async function loadCodeGraph() {
|
|
64
|
-
try {
|
|
65
|
-
return await Promise.resolve().then(() => __importStar(require('../index')));
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
69
|
-
console.error(`\x1b[31m${(0, glyphs_1.getGlyphs)().err}\x1b[0m Failed to load CodeGraph modules.`);
|
|
70
|
-
console.error(`\n Node: ${process.version} Platform: ${process.platform} ${process.arch}`);
|
|
71
|
-
console.error(`\n Error: ${msg}`);
|
|
72
|
-
console.error('\n Try reinstalling with: npm install -g @colbymchenry/codegraph\n');
|
|
73
|
-
process.exit(1);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
// Dynamic import helper — tsc compiles import() to require() in CJS mode,
|
|
77
|
-
// which fails for ESM-only packages. This bypasses the transformation.
|
|
78
|
-
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
79
|
-
const importESM = new Function('specifier', 'return import(specifier)');
|
|
80
|
-
// Block CodeGraph on Node.js 25.x — V8's turboshaft WASM JIT has a Zone
|
|
81
|
-
// allocator bug that reliably crashes when compiling tree-sitter
|
|
82
|
-
// grammars (see #54, #81, #140). The previous behaviour was a soft
|
|
83
|
-
// console.warn that scrolls off-screen before the OOM crash 30 seconds
|
|
84
|
-
// later, leading to a steady stream of "what is this OOM" reports.
|
|
85
|
-
// Hard-exit before any WASM work; allow override via env var for users
|
|
86
|
-
// who patched V8 themselves or want to test a future fix.
|
|
87
|
-
const nodeVersion = process.versions.node;
|
|
88
|
-
const nodeMajor = parseInt(nodeVersion.split('.')[0] ?? '0', 10);
|
|
89
|
-
if (nodeMajor >= 25) {
|
|
90
|
-
process.stderr.write((0, node_version_check_1.buildNode25BlockBanner)(nodeVersion) + '\n');
|
|
91
|
-
if (!process.env.CODEGRAPH_ALLOW_UNSAFE_NODE) {
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
// Override active — banner shown for visibility, continuing.
|
|
95
|
-
}
|
|
96
|
-
// Check if running with no arguments - run installer
|
|
97
|
-
if (process.argv.length === 2) {
|
|
98
|
-
Promise.resolve().then(() => __importStar(require('../installer'))).then(({ runInstaller }) => runInstaller()).catch((err) => {
|
|
99
|
-
console.error('Installation failed:', err instanceof Error ? err.message : String(err));
|
|
100
|
-
process.exit(1);
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
// Normal CLI flow
|
|
105
|
-
main();
|
|
106
|
-
}
|
|
107
|
-
process.on('uncaughtException', (error) => {
|
|
108
|
-
console.error('[CodeGraph] Uncaught exception:', error);
|
|
109
|
-
});
|
|
110
|
-
process.on('unhandledRejection', (reason) => {
|
|
111
|
-
console.error('[CodeGraph] Unhandled rejection:', reason);
|
|
112
|
-
});
|
|
113
|
-
function main() {
|
|
114
|
-
const program = new commander_1.Command();
|
|
115
|
-
// Version from package.json
|
|
116
|
-
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json'), 'utf-8'));
|
|
117
|
-
// =============================================================================
|
|
118
|
-
// ANSI Color Helpers (avoid chalk ESM issues)
|
|
119
|
-
// =============================================================================
|
|
120
|
-
const colors = {
|
|
121
|
-
reset: '\x1b[0m',
|
|
122
|
-
bold: '\x1b[1m',
|
|
123
|
-
dim: '\x1b[2m',
|
|
124
|
-
red: '\x1b[31m',
|
|
125
|
-
green: '\x1b[32m',
|
|
126
|
-
yellow: '\x1b[33m',
|
|
127
|
-
blue: '\x1b[34m',
|
|
128
|
-
cyan: '\x1b[36m',
|
|
129
|
-
white: '\x1b[37m',
|
|
130
|
-
gray: '\x1b[90m',
|
|
131
|
-
};
|
|
132
|
-
const chalk = {
|
|
133
|
-
bold: (s) => `${colors.bold}${s}${colors.reset}`,
|
|
134
|
-
dim: (s) => `${colors.dim}${s}${colors.reset}`,
|
|
135
|
-
red: (s) => `${colors.red}${s}${colors.reset}`,
|
|
136
|
-
green: (s) => `${colors.green}${s}${colors.reset}`,
|
|
137
|
-
yellow: (s) => `${colors.yellow}${s}${colors.reset}`,
|
|
138
|
-
blue: (s) => `${colors.blue}${s}${colors.reset}`,
|
|
139
|
-
cyan: (s) => `${colors.cyan}${s}${colors.reset}`,
|
|
140
|
-
white: (s) => `${colors.white}${s}${colors.reset}`,
|
|
141
|
-
gray: (s) => `${colors.gray}${s}${colors.reset}`,
|
|
142
|
-
};
|
|
143
|
-
program
|
|
144
|
-
.name('codegraph')
|
|
145
|
-
.description('Code intelligence and knowledge graph for any codebase')
|
|
146
|
-
.version(packageJson.version);
|
|
147
|
-
// =============================================================================
|
|
148
|
-
// Helper Functions
|
|
149
|
-
// =============================================================================
|
|
150
|
-
/**
|
|
151
|
-
* Resolve project path from argument or current directory
|
|
152
|
-
* Walks up parent directories to find nearest initialized CodeGraph project
|
|
153
|
-
* (must have .codegraph/codegraph.db, not just .codegraph/lessons.db)
|
|
154
|
-
*/
|
|
155
|
-
function resolveProjectPath(pathArg) {
|
|
156
|
-
const absolutePath = path.resolve(pathArg || process.cwd());
|
|
157
|
-
// If exact path is initialized (has codegraph.db), use it
|
|
158
|
-
if ((0, directory_1.isInitialized)(absolutePath)) {
|
|
159
|
-
return absolutePath;
|
|
160
|
-
}
|
|
161
|
-
// Walk up to find nearest parent with CodeGraph initialized
|
|
162
|
-
// Note: findNearestCodeGraphRoot finds any .codegraph folder, but we need one with codegraph.db
|
|
163
|
-
let current = absolutePath;
|
|
164
|
-
const root = path.parse(current).root;
|
|
165
|
-
while (current !== root) {
|
|
166
|
-
const parent = path.dirname(current);
|
|
167
|
-
if (parent === current)
|
|
168
|
-
break;
|
|
169
|
-
current = parent;
|
|
170
|
-
if ((0, directory_1.isInitialized)(current)) {
|
|
171
|
-
return current;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
// Not found - return original path (will fail later with helpful error)
|
|
175
|
-
return absolutePath;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Format a number with commas
|
|
179
|
-
*/
|
|
180
|
-
function formatNumber(n) {
|
|
181
|
-
return n.toLocaleString();
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Format duration in milliseconds to human readable
|
|
185
|
-
*/
|
|
186
|
-
function formatDuration(ms) {
|
|
187
|
-
if (ms < 1000) {
|
|
188
|
-
return `${ms}ms`;
|
|
189
|
-
}
|
|
190
|
-
const seconds = ms / 1000;
|
|
191
|
-
if (seconds < 60) {
|
|
192
|
-
return `${seconds.toFixed(1)}s`;
|
|
193
|
-
}
|
|
194
|
-
const minutes = Math.floor(seconds / 60);
|
|
195
|
-
const remainingSeconds = seconds % 60;
|
|
196
|
-
return `${minutes}m ${remainingSeconds.toFixed(0)}s`;
|
|
197
|
-
}
|
|
198
|
-
// Shimmer progress renderer (runs in a worker thread for smooth animation)
|
|
199
|
-
// Imported at top of file from '../ui/shimmer-progress'
|
|
200
|
-
/**
|
|
201
|
-
* Create a plain-text progress callback for --verbose mode.
|
|
202
|
-
* No animations, no ANSI tricks — just timestamped lines to stdout.
|
|
203
|
-
*/
|
|
204
|
-
function createVerboseProgress() {
|
|
205
|
-
let lastPhase = '';
|
|
206
|
-
let lastPct = -1;
|
|
207
|
-
const startTime = Date.now();
|
|
208
|
-
return (progress) => {
|
|
209
|
-
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
210
|
-
if (progress.phase !== lastPhase) {
|
|
211
|
-
lastPhase = progress.phase;
|
|
212
|
-
lastPct = -1;
|
|
213
|
-
console.log(`[${elapsed}s] Phase: ${progress.phase}`);
|
|
214
|
-
}
|
|
215
|
-
if (progress.total > 0) {
|
|
216
|
-
const pct = Math.floor((progress.current / progress.total) * 100);
|
|
217
|
-
// Log every 5% to keep output manageable
|
|
218
|
-
if (pct >= lastPct + 5 || progress.current === progress.total) {
|
|
219
|
-
lastPct = pct;
|
|
220
|
-
console.log(`[${elapsed}s] ${progress.current}/${progress.total} (${pct}%)${progress.currentFile ? ` ${(0, glyphs_1.getGlyphs)().dash} ${progress.currentFile}` : ''}`);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
else if (progress.current > 0) {
|
|
224
|
-
// Scanning phase (no total yet) — log periodically
|
|
225
|
-
if (progress.current % 1000 === 0 || progress.current === 1) {
|
|
226
|
-
console.log(`[${elapsed}s] ${formatNumber(progress.current)} files found`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Print success message
|
|
233
|
-
*/
|
|
234
|
-
function success(message) {
|
|
235
|
-
console.log(chalk.green((0, glyphs_1.getGlyphs)().ok) + ' ' + message);
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Print error message
|
|
239
|
-
*/
|
|
240
|
-
function error(message) {
|
|
241
|
-
console.error(chalk.red((0, glyphs_1.getGlyphs)().err) + ' ' + message);
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Print info message
|
|
245
|
-
*/
|
|
246
|
-
function info(message) {
|
|
247
|
-
console.log(chalk.blue((0, glyphs_1.getGlyphs)().info) + ' ' + message);
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Print warning message
|
|
251
|
-
*/
|
|
252
|
-
function warn(message) {
|
|
253
|
-
console.log(chalk.yellow((0, glyphs_1.getGlyphs)().warn) + ' ' + message);
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Print indexing results using clack log methods
|
|
257
|
-
*/
|
|
258
|
-
function printIndexResult(clack, result, projectPath) {
|
|
259
|
-
const hasErrors = result.filesErrored > 0;
|
|
260
|
-
// Surface non-file-level failures (e.g. lock-acquisition failure
|
|
261
|
-
// when another indexer is running) before the file-count branches.
|
|
262
|
-
// Without this the CLI falls through to "No files found to index",
|
|
263
|
-
// which is actively misleading — the index DID run, it just couldn't
|
|
264
|
-
// get the lock.
|
|
265
|
-
//
|
|
266
|
-
// If success is false but no severity:'error' entry exists in
|
|
267
|
-
// `result.errors` (degenerate case — shouldn't happen in practice
|
|
268
|
-
// but worth guarding because the result shape is plumbed through
|
|
269
|
-
// multiple call sites), fall back to a generic message rather than
|
|
270
|
-
// continuing to the misleading "No files found" branch or throwing.
|
|
271
|
-
if (!result.success && !hasErrors && result.filesIndexed === 0) {
|
|
272
|
-
const generic = result.errors.find((e) => e.severity === 'error');
|
|
273
|
-
clack.log.error(generic?.message ?? `Indexing failed ${(0, glyphs_1.getGlyphs)().dash} no further details available`);
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
if (result.filesIndexed > 0) {
|
|
277
|
-
if (hasErrors) {
|
|
278
|
-
clack.log.success(`Indexed ${formatNumber(result.filesIndexed)} files (${formatNumber(result.filesErrored)} could not be parsed)`);
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
clack.log.success(`Indexed ${formatNumber(result.filesIndexed)} files`);
|
|
282
|
-
}
|
|
283
|
-
clack.log.info(`${formatNumber(result.nodesCreated)} nodes, ${formatNumber(result.edgesCreated)} edges in ${formatDuration(result.durationMs)}`);
|
|
284
|
-
}
|
|
285
|
-
else if (hasErrors) {
|
|
286
|
-
clack.log.error(`Indexing failed ${(0, glyphs_1.getGlyphs)().dash} all ${formatNumber(result.filesErrored)} files had errors`);
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
clack.log.warn('No files found to index');
|
|
290
|
-
}
|
|
291
|
-
if (hasErrors) {
|
|
292
|
-
const errorsByCode = new Map();
|
|
293
|
-
for (const err of result.errors) {
|
|
294
|
-
if (err.severity === 'error') {
|
|
295
|
-
const code = err.code || 'unknown';
|
|
296
|
-
errorsByCode.set(code, (errorsByCode.get(code) || 0) + 1);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
const codeLabels = {
|
|
300
|
-
parse_error: 'files failed to parse',
|
|
301
|
-
read_error: 'files could not be read',
|
|
302
|
-
size_exceeded: 'files exceeded size limit',
|
|
303
|
-
path_traversal: 'blocked paths',
|
|
304
|
-
unsupported_language: 'unsupported language',
|
|
305
|
-
parser_error: 'parser initialization failures',
|
|
306
|
-
};
|
|
307
|
-
const breakdown = Array.from(errorsByCode)
|
|
308
|
-
.map(([code, count]) => `${formatNumber(count)} ${codeLabels[code] || code}`)
|
|
309
|
-
.join('\n');
|
|
310
|
-
clack.note(breakdown, 'Error breakdown');
|
|
311
|
-
if (projectPath) {
|
|
312
|
-
writeErrorLog(projectPath, result.errors);
|
|
313
|
-
clack.log.info('See .codegraph/errors.log for details');
|
|
314
|
-
}
|
|
315
|
-
if (result.filesIndexed > 0) {
|
|
316
|
-
clack.log.info(`The index is fully usable ${(0, glyphs_1.getGlyphs)().dash} only the failed files are missing.`);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
else if (projectPath) {
|
|
320
|
-
const logPath = path.join(projectPath, '.codegraph', 'errors.log');
|
|
321
|
-
if (fs.existsSync(logPath)) {
|
|
322
|
-
fs.unlinkSync(logPath);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Write detailed error log to .codegraph/errors.log
|
|
328
|
-
*/
|
|
329
|
-
function writeErrorLog(projectPath, errors) {
|
|
330
|
-
const cgDir = path.join(projectPath, '.codegraph');
|
|
331
|
-
if (!fs.existsSync(cgDir))
|
|
332
|
-
return;
|
|
333
|
-
const logPath = path.join(cgDir, 'errors.log');
|
|
334
|
-
// Group errors by file path
|
|
335
|
-
const errorsByFile = new Map();
|
|
336
|
-
const noFileErrors = [];
|
|
337
|
-
for (const err of errors) {
|
|
338
|
-
if (err.severity !== 'error')
|
|
339
|
-
continue;
|
|
340
|
-
if (err.filePath) {
|
|
341
|
-
let list = errorsByFile.get(err.filePath);
|
|
342
|
-
if (!list) {
|
|
343
|
-
list = [];
|
|
344
|
-
errorsByFile.set(err.filePath, list);
|
|
345
|
-
}
|
|
346
|
-
list.push({ message: err.message, code: err.code });
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
noFileErrors.push({ message: err.message, code: err.code });
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
const lines = [
|
|
353
|
-
`CodeGraph Error Log - ${new Date().toISOString()}`,
|
|
354
|
-
`${errorsByFile.size} files with errors`,
|
|
355
|
-
'',
|
|
356
|
-
];
|
|
357
|
-
for (const [filePath, fileErrors] of errorsByFile) {
|
|
358
|
-
for (const err of fileErrors) {
|
|
359
|
-
lines.push(`${filePath}: ${err.message}`);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
for (const err of noFileErrors) {
|
|
363
|
-
lines.push(err.message);
|
|
364
|
-
}
|
|
365
|
-
fs.writeFileSync(logPath, lines.join('\n') + '\n');
|
|
366
|
-
}
|
|
367
|
-
// =============================================================================
|
|
368
|
-
// Commands
|
|
369
|
-
// =============================================================================
|
|
370
|
-
/**
|
|
371
|
-
* codegraph init [path]
|
|
372
|
-
*/
|
|
373
|
-
program
|
|
374
|
-
.command('init [path]')
|
|
375
|
-
.description('Initialize CodeGraph in a project directory')
|
|
376
|
-
.option('-i, --index', 'Run initial indexing after initialization')
|
|
377
|
-
.option('-v, --verbose', 'Show detailed worker lifecycle and memory info')
|
|
378
|
-
.action(async (pathArg, options) => {
|
|
379
|
-
const projectPath = path.resolve(pathArg || process.cwd());
|
|
380
|
-
const clack = await importESM('@clack/prompts');
|
|
381
|
-
clack.intro('Initializing CodeGraph');
|
|
382
|
-
try {
|
|
383
|
-
if ((0, directory_1.isInitialized)(projectPath)) {
|
|
384
|
-
clack.log.warn(`Already initialized in ${projectPath}`);
|
|
385
|
-
clack.log.info('Use "codegraph index" to re-index or "codegraph sync" to update');
|
|
386
|
-
// Re-run agent surface wiring so re-running `init` is the
|
|
387
|
-
// documented way to recover a project that's missing its
|
|
388
|
-
// Cursor rules file (or future per-agent project surfaces).
|
|
389
|
-
try {
|
|
390
|
-
const { wireProjectSurfacesForGlobalAgents } = await Promise.resolve().then(() => __importStar(require('../installer')));
|
|
391
|
-
for (const { target, file } of wireProjectSurfacesForGlobalAgents()) {
|
|
392
|
-
clack.log.success(`${target.displayName}: ${file.action} ${file.path}`);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
catch { /* non-fatal */ }
|
|
396
|
-
clack.outro('');
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
const { default: CodeGraph } = await loadCodeGraph();
|
|
400
|
-
const cg = await CodeGraph.init(projectPath, { index: false });
|
|
401
|
-
clack.log.success(`Initialized in ${projectPath}`);
|
|
402
|
-
// Bootstrap project-local surfaces for any agent that's
|
|
403
|
-
// configured globally (Cursor needs ./.cursor/rules/codegraph.mdc
|
|
404
|
-
// to actually prefer codegraph over native grep). Silent when
|
|
405
|
-
// there's nothing to write.
|
|
406
|
-
try {
|
|
407
|
-
const { wireProjectSurfacesForGlobalAgents } = await Promise.resolve().then(() => __importStar(require('../installer')));
|
|
408
|
-
for (const { target, file } of wireProjectSurfacesForGlobalAgents()) {
|
|
409
|
-
clack.log.success(`${target.displayName}: ${file.action} ${file.path}`);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
catch (err) {
|
|
413
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
414
|
-
clack.log.warn(`Skipped wiring project-local agent surfaces: ${msg}`);
|
|
415
|
-
}
|
|
416
|
-
if (options.index) {
|
|
417
|
-
let result;
|
|
418
|
-
if (options.verbose) {
|
|
419
|
-
result = await cg.indexAll({
|
|
420
|
-
onProgress: createVerboseProgress(),
|
|
421
|
-
verbose: true,
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
else {
|
|
425
|
-
process.stdout.write(`${colors.dim}${(0, glyphs_1.getGlyphs)().rail}${colors.reset}\n`);
|
|
426
|
-
const progress = (0, shimmer_progress_1.createShimmerProgress)();
|
|
427
|
-
result = await cg.indexAll({
|
|
428
|
-
onProgress: progress.onProgress,
|
|
429
|
-
});
|
|
430
|
-
await progress.stop();
|
|
431
|
-
}
|
|
432
|
-
printIndexResult(clack, result, projectPath);
|
|
433
|
-
}
|
|
434
|
-
else {
|
|
435
|
-
clack.log.info('Run "codegraph index" to index the project');
|
|
436
|
-
}
|
|
437
|
-
clack.outro('Done');
|
|
438
|
-
cg.destroy();
|
|
439
|
-
}
|
|
440
|
-
catch (err) {
|
|
441
|
-
clack.log.error(`Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
442
|
-
process.exit(1);
|
|
443
|
-
}
|
|
444
|
-
});
|
|
445
|
-
/**
|
|
446
|
-
* codegraph uninit [path]
|
|
447
|
-
*/
|
|
448
|
-
program
|
|
449
|
-
.command('uninit [path]')
|
|
450
|
-
.description('Remove CodeGraph from a project (deletes .codegraph/ directory)')
|
|
451
|
-
.option('-f, --force', 'Skip confirmation prompt')
|
|
452
|
-
.action(async (pathArg, options) => {
|
|
453
|
-
const projectPath = resolveProjectPath(pathArg);
|
|
454
|
-
try {
|
|
455
|
-
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
456
|
-
warn(`CodeGraph is not initialized in ${projectPath}`);
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
459
|
-
if (!options.force) {
|
|
460
|
-
// Confirm with user
|
|
461
|
-
const readline = await Promise.resolve().then(() => __importStar(require('readline')));
|
|
462
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
463
|
-
const answer = await new Promise((resolve) => {
|
|
464
|
-
rl.question(chalk.yellow(`${(0, glyphs_1.getGlyphs)().warn} This will permanently delete all CodeGraph data. Continue? (y/N) `), resolve);
|
|
465
|
-
});
|
|
466
|
-
rl.close();
|
|
467
|
-
if (answer.toLowerCase() !== 'y') {
|
|
468
|
-
info('Cancelled');
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
const { default: CodeGraph } = await loadCodeGraph();
|
|
473
|
-
const cg = CodeGraph.openSync(projectPath);
|
|
474
|
-
cg.uninitialize();
|
|
475
|
-
success(`Removed CodeGraph from ${projectPath}`);
|
|
476
|
-
}
|
|
477
|
-
catch (err) {
|
|
478
|
-
error(`Failed to uninitialize: ${err instanceof Error ? err.message : String(err)}`);
|
|
479
|
-
process.exit(1);
|
|
480
|
-
}
|
|
481
|
-
});
|
|
482
|
-
/**
|
|
483
|
-
* codegraph index [path]
|
|
484
|
-
*/
|
|
485
|
-
program
|
|
486
|
-
.command('index [path]')
|
|
487
|
-
.description('Index all files in the project')
|
|
488
|
-
.option('-f, --force', 'Force full re-index even if already indexed')
|
|
489
|
-
.option('-q, --quiet', 'Suppress progress output')
|
|
490
|
-
.option('-v, --verbose', 'Show detailed worker lifecycle and memory info')
|
|
491
|
-
.action(async (pathArg, options) => {
|
|
492
|
-
const projectPath = resolveProjectPath(pathArg);
|
|
493
|
-
try {
|
|
494
|
-
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
495
|
-
error(`CodeGraph not initialized in ${projectPath}`);
|
|
496
|
-
info('Run "codegraph init" first');
|
|
497
|
-
process.exit(1);
|
|
498
|
-
}
|
|
499
|
-
const { default: CodeGraph } = await loadCodeGraph();
|
|
500
|
-
const cg = await CodeGraph.open(projectPath);
|
|
501
|
-
if (options.quiet) {
|
|
502
|
-
// Quiet mode: no UI, just run
|
|
503
|
-
if (options.force)
|
|
504
|
-
cg.clear();
|
|
505
|
-
const result = await cg.indexAll();
|
|
506
|
-
if (!result.success)
|
|
507
|
-
process.exit(1);
|
|
508
|
-
cg.destroy();
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
const clack = await importESM('@clack/prompts');
|
|
512
|
-
clack.intro('Indexing project');
|
|
513
|
-
if (options.force) {
|
|
514
|
-
cg.clear();
|
|
515
|
-
clack.log.info('Cleared existing index');
|
|
516
|
-
}
|
|
517
|
-
let result;
|
|
518
|
-
if (options.verbose) {
|
|
519
|
-
result = await cg.indexAll({
|
|
520
|
-
onProgress: createVerboseProgress(),
|
|
521
|
-
verbose: true,
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
else {
|
|
525
|
-
process.stdout.write(`${colors.dim}${(0, glyphs_1.getGlyphs)().rail}${colors.reset}\n`);
|
|
526
|
-
const progress = (0, shimmer_progress_1.createShimmerProgress)();
|
|
527
|
-
result = await cg.indexAll({
|
|
528
|
-
onProgress: progress.onProgress,
|
|
529
|
-
});
|
|
530
|
-
await progress.stop();
|
|
531
|
-
}
|
|
532
|
-
printIndexResult(clack, result, projectPath);
|
|
533
|
-
if (!result.success) {
|
|
534
|
-
process.exit(1);
|
|
535
|
-
}
|
|
536
|
-
clack.outro('Done');
|
|
537
|
-
cg.destroy();
|
|
538
|
-
}
|
|
539
|
-
catch (err) {
|
|
540
|
-
error(`Failed to index: ${err instanceof Error ? err.message : String(err)}`);
|
|
541
|
-
process.exit(1);
|
|
542
|
-
}
|
|
543
|
-
});
|
|
544
|
-
/**
|
|
545
|
-
* codegraph sync [path]
|
|
546
|
-
*/
|
|
547
|
-
program
|
|
548
|
-
.command('sync [path]')
|
|
549
|
-
.description('Sync changes since last index')
|
|
550
|
-
.option('-q, --quiet', 'Suppress output (for git hooks)')
|
|
551
|
-
.action(async (pathArg, options) => {
|
|
552
|
-
const projectPath = resolveProjectPath(pathArg);
|
|
553
|
-
try {
|
|
554
|
-
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
555
|
-
if (!options.quiet) {
|
|
556
|
-
error(`CodeGraph not initialized in ${projectPath}`);
|
|
557
|
-
}
|
|
558
|
-
process.exit(1);
|
|
559
|
-
}
|
|
560
|
-
const { default: CodeGraph } = await loadCodeGraph();
|
|
561
|
-
const cg = await CodeGraph.open(projectPath);
|
|
562
|
-
if (options.quiet) {
|
|
563
|
-
await cg.sync();
|
|
564
|
-
cg.destroy();
|
|
565
|
-
return;
|
|
566
|
-
}
|
|
567
|
-
const clack = await importESM('@clack/prompts');
|
|
568
|
-
clack.intro('Syncing CodeGraph');
|
|
569
|
-
process.stdout.write(`${colors.dim}${(0, glyphs_1.getGlyphs)().rail}${colors.reset}\n`);
|
|
570
|
-
const progress = (0, shimmer_progress_1.createShimmerProgress)();
|
|
571
|
-
const result = await cg.sync({
|
|
572
|
-
onProgress: progress.onProgress,
|
|
573
|
-
});
|
|
574
|
-
await progress.stop();
|
|
575
|
-
const totalChanges = result.filesAdded + result.filesModified + result.filesRemoved;
|
|
576
|
-
if (totalChanges === 0) {
|
|
577
|
-
clack.log.info('Already up to date');
|
|
578
|
-
}
|
|
579
|
-
else {
|
|
580
|
-
clack.log.success(`Synced ${formatNumber(totalChanges)} changed files`);
|
|
581
|
-
const details = [];
|
|
582
|
-
if (result.filesAdded > 0)
|
|
583
|
-
details.push(`Added: ${result.filesAdded}`);
|
|
584
|
-
if (result.filesModified > 0)
|
|
585
|
-
details.push(`Modified: ${result.filesModified}`);
|
|
586
|
-
if (result.filesRemoved > 0)
|
|
587
|
-
details.push(`Removed: ${result.filesRemoved}`);
|
|
588
|
-
clack.log.info(`${details.join(', ')} ${(0, glyphs_1.getGlyphs)().dash} ${formatNumber(result.nodesUpdated)} nodes in ${formatDuration(result.durationMs)}`);
|
|
589
|
-
}
|
|
590
|
-
clack.outro('Done');
|
|
591
|
-
cg.destroy();
|
|
592
|
-
}
|
|
593
|
-
catch (err) {
|
|
594
|
-
if (!options.quiet) {
|
|
595
|
-
error(`Failed to sync: ${err instanceof Error ? err.message : String(err)}`);
|
|
596
|
-
}
|
|
597
|
-
process.exit(1);
|
|
598
|
-
}
|
|
599
|
-
});
|
|
600
|
-
/**
|
|
601
|
-
* codegraph status [path]
|
|
602
|
-
*/
|
|
603
|
-
program
|
|
604
|
-
.command('status [path]')
|
|
605
|
-
.description('Show index status and statistics')
|
|
606
|
-
.option('-j, --json', 'Output as JSON')
|
|
607
|
-
.action(async (pathArg, options) => {
|
|
608
|
-
const projectPath = resolveProjectPath(pathArg);
|
|
609
|
-
try {
|
|
610
|
-
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
611
|
-
if (options.json) {
|
|
612
|
-
console.log(JSON.stringify({ initialized: false, projectPath }));
|
|
613
|
-
return;
|
|
614
|
-
}
|
|
615
|
-
console.log(chalk.bold('\nCodeGraph Status\n'));
|
|
616
|
-
info(`Project: ${projectPath}`);
|
|
617
|
-
warn('Not initialized');
|
|
618
|
-
info('Run "codegraph init" to initialize');
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
const { default: CodeGraph } = await loadCodeGraph();
|
|
622
|
-
const cg = await CodeGraph.open(projectPath);
|
|
623
|
-
const stats = cg.getStats();
|
|
624
|
-
const changes = cg.getChangedFiles();
|
|
625
|
-
const backend = cg.getBackend();
|
|
626
|
-
// JSON output mode
|
|
627
|
-
if (options.json) {
|
|
628
|
-
console.log(JSON.stringify({
|
|
629
|
-
initialized: true,
|
|
630
|
-
projectPath,
|
|
631
|
-
fileCount: stats.fileCount,
|
|
632
|
-
nodeCount: stats.nodeCount,
|
|
633
|
-
edgeCount: stats.edgeCount,
|
|
634
|
-
dbSizeBytes: stats.dbSizeBytes,
|
|
635
|
-
backend,
|
|
636
|
-
nodesByKind: stats.nodesByKind,
|
|
637
|
-
languages: Object.entries(stats.filesByLanguage).filter(([, count]) => count > 0).map(([lang]) => lang),
|
|
638
|
-
pendingChanges: {
|
|
639
|
-
added: changes.added.length,
|
|
640
|
-
modified: changes.modified.length,
|
|
641
|
-
removed: changes.removed.length,
|
|
642
|
-
},
|
|
643
|
-
}));
|
|
644
|
-
cg.destroy();
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
console.log(chalk.bold('\nCodeGraph Status\n'));
|
|
648
|
-
// Project info
|
|
649
|
-
console.log(chalk.cyan('Project:'), projectPath);
|
|
650
|
-
console.log();
|
|
651
|
-
// Index stats
|
|
652
|
-
console.log(chalk.bold('Index Statistics:'));
|
|
653
|
-
console.log(` Files: ${formatNumber(stats.fileCount)}`);
|
|
654
|
-
console.log(` Nodes: ${formatNumber(stats.nodeCount)}`);
|
|
655
|
-
console.log(` Edges: ${formatNumber(stats.edgeCount)}`);
|
|
656
|
-
console.log(` DB Size: ${(stats.dbSizeBytes / 1024 / 1024).toFixed(2)} MB`);
|
|
657
|
-
// Surface the active SQLite backend so users can spot the silent
|
|
658
|
-
// WASM fallback (5-10x slower). better-sqlite3 is in
|
|
659
|
-
// `optionalDependencies`, so `npm install` succeeds without it
|
|
660
|
-
// when the native build fails.
|
|
661
|
-
const backendLabel = backend === 'native'
|
|
662
|
-
? chalk.green('native')
|
|
663
|
-
: chalk.yellow(`wasm ${(0, glyphs_1.getGlyphs)().dash} slower fallback; run \`npm rebuild better-sqlite3\``);
|
|
664
|
-
console.log(` Backend: ${backendLabel}`);
|
|
665
|
-
console.log();
|
|
666
|
-
// Node breakdown
|
|
667
|
-
console.log(chalk.bold('Nodes by Kind:'));
|
|
668
|
-
const nodesByKind = Object.entries(stats.nodesByKind)
|
|
669
|
-
.filter(([, count]) => count > 0)
|
|
670
|
-
.sort((a, b) => b[1] - a[1]);
|
|
671
|
-
for (const [kind, count] of nodesByKind) {
|
|
672
|
-
console.log(` ${kind.padEnd(15)} ${formatNumber(count)}`);
|
|
673
|
-
}
|
|
674
|
-
console.log();
|
|
675
|
-
// Language breakdown
|
|
676
|
-
console.log(chalk.bold('Files by Language:'));
|
|
677
|
-
const filesByLang = Object.entries(stats.filesByLanguage)
|
|
678
|
-
.filter(([, count]) => count > 0)
|
|
679
|
-
.sort((a, b) => b[1] - a[1]);
|
|
680
|
-
for (const [lang, count] of filesByLang) {
|
|
681
|
-
console.log(` ${lang.padEnd(15)} ${formatNumber(count)}`);
|
|
682
|
-
}
|
|
683
|
-
console.log();
|
|
684
|
-
// Pending changes
|
|
685
|
-
const totalChanges = changes.added.length + changes.modified.length + changes.removed.length;
|
|
686
|
-
if (totalChanges > 0) {
|
|
687
|
-
console.log(chalk.bold('Pending Changes:'));
|
|
688
|
-
if (changes.added.length > 0) {
|
|
689
|
-
console.log(` Added: ${changes.added.length} files`);
|
|
690
|
-
}
|
|
691
|
-
if (changes.modified.length > 0) {
|
|
692
|
-
console.log(` Modified: ${changes.modified.length} files`);
|
|
693
|
-
}
|
|
694
|
-
if (changes.removed.length > 0) {
|
|
695
|
-
console.log(` Removed: ${changes.removed.length} files`);
|
|
696
|
-
}
|
|
697
|
-
info('Run "codegraph sync" to update the index');
|
|
698
|
-
}
|
|
699
|
-
else {
|
|
700
|
-
success('Index is up to date');
|
|
701
|
-
}
|
|
702
|
-
console.log();
|
|
703
|
-
cg.destroy();
|
|
704
|
-
}
|
|
705
|
-
catch (err) {
|
|
706
|
-
error(`Failed to get status: ${err instanceof Error ? err.message : String(err)}`);
|
|
707
|
-
process.exit(1);
|
|
708
|
-
}
|
|
709
|
-
});
|
|
710
|
-
/**
|
|
711
|
-
* codegraph query <search>
|
|
712
|
-
*/
|
|
713
|
-
program
|
|
714
|
-
.command('query <search>')
|
|
715
|
-
.description('Search for symbols in the codebase')
|
|
716
|
-
.option('-p, --path <path>', 'Project path')
|
|
717
|
-
.option('-l, --limit <number>', 'Maximum results', '10')
|
|
718
|
-
.option('-k, --kind <kind>', 'Filter by node kind (function, class, etc.)')
|
|
719
|
-
.option('-j, --json', 'Output as JSON')
|
|
720
|
-
.action(async (search, options) => {
|
|
721
|
-
const projectPath = resolveProjectPath(options.path);
|
|
722
|
-
try {
|
|
723
|
-
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
724
|
-
error(`CodeGraph not initialized in ${projectPath}`);
|
|
725
|
-
process.exit(1);
|
|
726
|
-
}
|
|
727
|
-
const { default: CodeGraph } = await loadCodeGraph();
|
|
728
|
-
const cg = await CodeGraph.open(projectPath);
|
|
729
|
-
const limit = parseInt(options.limit || '10', 10);
|
|
730
|
-
const results = cg.searchNodes(search, {
|
|
731
|
-
limit,
|
|
732
|
-
kinds: options.kind ? [options.kind] : undefined,
|
|
733
|
-
});
|
|
734
|
-
if (options.json) {
|
|
735
|
-
console.log(JSON.stringify(results, null, 2));
|
|
736
|
-
}
|
|
737
|
-
else {
|
|
738
|
-
if (results.length === 0) {
|
|
739
|
-
info(`No results found for "${search}"`);
|
|
740
|
-
}
|
|
741
|
-
else {
|
|
742
|
-
console.log(chalk.bold(`\nSearch Results for "${search}":\n`));
|
|
743
|
-
for (const result of results) {
|
|
744
|
-
const node = result.node;
|
|
745
|
-
const location = `${node.filePath}:${node.startLine}`;
|
|
746
|
-
const score = chalk.dim(`(${(result.score * 100).toFixed(0)}%)`);
|
|
747
|
-
console.log(chalk.cyan(node.kind.padEnd(12)) +
|
|
748
|
-
chalk.white(node.name) +
|
|
749
|
-
' ' + score);
|
|
750
|
-
console.log(chalk.dim(` ${location}`));
|
|
751
|
-
if (node.signature) {
|
|
752
|
-
console.log(chalk.dim(` ${node.signature}`));
|
|
753
|
-
}
|
|
754
|
-
console.log();
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
cg.destroy();
|
|
759
|
-
}
|
|
760
|
-
catch (err) {
|
|
761
|
-
error(`Search failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
762
|
-
process.exit(1);
|
|
763
|
-
}
|
|
764
|
-
});
|
|
765
|
-
/**
|
|
766
|
-
* codegraph files [path]
|
|
767
|
-
*/
|
|
768
|
-
program
|
|
769
|
-
.command('files')
|
|
770
|
-
.description('Show project file structure from the index')
|
|
771
|
-
.option('-p, --path <path>', 'Project path')
|
|
772
|
-
.option('--filter <dir>', 'Filter to files under this directory')
|
|
773
|
-
.option('--pattern <glob>', 'Filter files matching this glob pattern')
|
|
774
|
-
.option('--format <format>', 'Output format (tree, flat, grouped)', 'tree')
|
|
775
|
-
.option('--max-depth <number>', 'Maximum directory depth for tree format')
|
|
776
|
-
.option('--no-metadata', 'Hide file metadata (language, symbol count)')
|
|
777
|
-
.option('-j, --json', 'Output as JSON')
|
|
778
|
-
.action(async (options) => {
|
|
779
|
-
const projectPath = resolveProjectPath(options.path);
|
|
780
|
-
try {
|
|
781
|
-
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
782
|
-
error(`CodeGraph not initialized in ${projectPath}`);
|
|
783
|
-
process.exit(1);
|
|
784
|
-
}
|
|
785
|
-
const { default: CodeGraph } = await loadCodeGraph();
|
|
786
|
-
const cg = await CodeGraph.open(projectPath);
|
|
787
|
-
let files = cg.getFiles();
|
|
788
|
-
if (files.length === 0) {
|
|
789
|
-
info('No files indexed. Run "codegraph index" first.');
|
|
790
|
-
cg.destroy();
|
|
791
|
-
return;
|
|
792
|
-
}
|
|
793
|
-
// Filter by path prefix
|
|
794
|
-
if (options.filter) {
|
|
795
|
-
const filter = options.filter;
|
|
796
|
-
files = files.filter(f => f.path.startsWith(filter) || f.path.startsWith('./' + filter));
|
|
797
|
-
}
|
|
798
|
-
// Filter by glob pattern
|
|
799
|
-
if (options.pattern) {
|
|
800
|
-
const regex = globToRegex(options.pattern);
|
|
801
|
-
files = files.filter(f => regex.test(f.path));
|
|
802
|
-
}
|
|
803
|
-
if (files.length === 0) {
|
|
804
|
-
info('No files found matching the criteria.');
|
|
805
|
-
cg.destroy();
|
|
806
|
-
return;
|
|
807
|
-
}
|
|
808
|
-
// JSON output
|
|
809
|
-
if (options.json) {
|
|
810
|
-
const output = files.map(f => ({
|
|
811
|
-
path: f.path,
|
|
812
|
-
language: f.language,
|
|
813
|
-
nodeCount: f.nodeCount,
|
|
814
|
-
size: f.size,
|
|
815
|
-
}));
|
|
816
|
-
console.log(JSON.stringify(output, null, 2));
|
|
817
|
-
cg.destroy();
|
|
818
|
-
return;
|
|
819
|
-
}
|
|
820
|
-
const includeMetadata = options.metadata !== false;
|
|
821
|
-
const format = options.format || 'tree';
|
|
822
|
-
const maxDepth = options.maxDepth ? parseInt(options.maxDepth, 10) : undefined;
|
|
823
|
-
// Format output
|
|
824
|
-
switch (format) {
|
|
825
|
-
case 'flat':
|
|
826
|
-
console.log(chalk.bold(`\nFiles (${files.length}):\n`));
|
|
827
|
-
for (const file of files.sort((a, b) => a.path.localeCompare(b.path))) {
|
|
828
|
-
if (includeMetadata) {
|
|
829
|
-
console.log(` ${file.path} ${chalk.dim(`(${file.language}, ${file.nodeCount} symbols)`)}`);
|
|
830
|
-
}
|
|
831
|
-
else {
|
|
832
|
-
console.log(` ${file.path}`);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
break;
|
|
836
|
-
case 'grouped':
|
|
837
|
-
console.log(chalk.bold(`\nFiles by Language (${files.length} total):\n`));
|
|
838
|
-
const byLang = new Map();
|
|
839
|
-
for (const file of files) {
|
|
840
|
-
const existing = byLang.get(file.language) || [];
|
|
841
|
-
existing.push(file);
|
|
842
|
-
byLang.set(file.language, existing);
|
|
843
|
-
}
|
|
844
|
-
const sortedLangs = [...byLang.entries()].sort((a, b) => b[1].length - a[1].length);
|
|
845
|
-
for (const [lang, langFiles] of sortedLangs) {
|
|
846
|
-
console.log(chalk.cyan(`${lang} (${langFiles.length}):`));
|
|
847
|
-
for (const file of langFiles.sort((a, b) => a.path.localeCompare(b.path))) {
|
|
848
|
-
if (includeMetadata) {
|
|
849
|
-
console.log(` ${file.path} ${chalk.dim(`(${file.nodeCount} symbols)`)}`);
|
|
850
|
-
}
|
|
851
|
-
else {
|
|
852
|
-
console.log(` ${file.path}`);
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
console.log();
|
|
856
|
-
}
|
|
857
|
-
break;
|
|
858
|
-
case 'tree':
|
|
859
|
-
default:
|
|
860
|
-
console.log(chalk.bold(`\nProject Structure (${files.length} files):\n`));
|
|
861
|
-
printFileTree(files, includeMetadata, maxDepth, chalk);
|
|
862
|
-
break;
|
|
863
|
-
}
|
|
864
|
-
console.log();
|
|
865
|
-
cg.destroy();
|
|
866
|
-
}
|
|
867
|
-
catch (err) {
|
|
868
|
-
error(`Failed to list files: ${err instanceof Error ? err.message : String(err)}`);
|
|
869
|
-
process.exit(1);
|
|
870
|
-
}
|
|
871
|
-
});
|
|
872
|
-
/**
|
|
873
|
-
* Convert glob pattern to regex
|
|
874
|
-
*/
|
|
875
|
-
function globToRegex(pattern) {
|
|
876
|
-
const escaped = pattern
|
|
877
|
-
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
878
|
-
.replace(/\*\*/g, '{{GLOBSTAR}}')
|
|
879
|
-
.replace(/\*/g, '[^/]*')
|
|
880
|
-
.replace(/\?/g, '[^/]')
|
|
881
|
-
.replace(/\{\{GLOBSTAR\}\}/g, '.*');
|
|
882
|
-
return new RegExp(escaped);
|
|
883
|
-
}
|
|
884
|
-
/**
|
|
885
|
-
* Print files as a tree
|
|
886
|
-
*/
|
|
887
|
-
function printFileTree(files, includeMetadata, maxDepth, chalk) {
|
|
888
|
-
const root = { name: '', children: new Map() };
|
|
889
|
-
for (const file of files) {
|
|
890
|
-
const parts = file.path.split('/');
|
|
891
|
-
let current = root;
|
|
892
|
-
for (let i = 0; i < parts.length; i++) {
|
|
893
|
-
const part = parts[i];
|
|
894
|
-
if (!part)
|
|
895
|
-
continue;
|
|
896
|
-
if (!current.children.has(part)) {
|
|
897
|
-
current.children.set(part, { name: part, children: new Map() });
|
|
898
|
-
}
|
|
899
|
-
current = current.children.get(part);
|
|
900
|
-
if (i === parts.length - 1) {
|
|
901
|
-
current.file = { language: file.language, nodeCount: file.nodeCount };
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
const renderNode = (node, prefix, isLast, depth) => {
|
|
906
|
-
if (maxDepth !== undefined && depth > maxDepth)
|
|
907
|
-
return;
|
|
908
|
-
const glyphs = (0, glyphs_1.getGlyphs)();
|
|
909
|
-
const connector = isLast ? glyphs.treeLast : glyphs.treeBranch;
|
|
910
|
-
const childPrefix = isLast ? ' ' : glyphs.treePipe;
|
|
911
|
-
if (node.name) {
|
|
912
|
-
let line = prefix + connector + node.name;
|
|
913
|
-
if (node.file && includeMetadata) {
|
|
914
|
-
line += chalk.dim(` (${node.file.language}, ${node.file.nodeCount} symbols)`);
|
|
915
|
-
}
|
|
916
|
-
console.log(line);
|
|
917
|
-
}
|
|
918
|
-
const children = [...node.children.values()];
|
|
919
|
-
children.sort((a, b) => {
|
|
920
|
-
const aIsDir = a.children.size > 0 && !a.file;
|
|
921
|
-
const bIsDir = b.children.size > 0 && !b.file;
|
|
922
|
-
if (aIsDir !== bIsDir)
|
|
923
|
-
return aIsDir ? -1 : 1;
|
|
924
|
-
return a.name.localeCompare(b.name);
|
|
925
|
-
});
|
|
926
|
-
for (let i = 0; i < children.length; i++) {
|
|
927
|
-
const child = children[i];
|
|
928
|
-
const nextPrefix = node.name ? prefix + childPrefix : prefix;
|
|
929
|
-
renderNode(child, nextPrefix, i === children.length - 1, depth + 1);
|
|
930
|
-
}
|
|
931
|
-
};
|
|
932
|
-
renderNode(root, '', true, 0);
|
|
933
|
-
}
|
|
934
|
-
/**
|
|
935
|
-
* codegraph context <task>
|
|
936
|
-
*/
|
|
937
|
-
program
|
|
938
|
-
.command('context <task>')
|
|
939
|
-
.description('Build context for a task (outputs markdown)')
|
|
940
|
-
.option('-p, --path <path>', 'Project path')
|
|
941
|
-
.option('-n, --max-nodes <number>', 'Maximum nodes to include', '50')
|
|
942
|
-
.option('-c, --max-code <number>', 'Maximum code blocks', '10')
|
|
943
|
-
.option('--no-code', 'Exclude code blocks')
|
|
944
|
-
.option('-f, --format <format>', 'Output format (markdown, json)', 'markdown')
|
|
945
|
-
.action(async (task, options) => {
|
|
946
|
-
const projectPath = resolveProjectPath(options.path);
|
|
947
|
-
try {
|
|
948
|
-
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
949
|
-
error(`CodeGraph not initialized in ${projectPath}`);
|
|
950
|
-
process.exit(1);
|
|
951
|
-
}
|
|
952
|
-
const { default: CodeGraph } = await loadCodeGraph();
|
|
953
|
-
const cg = await CodeGraph.open(projectPath);
|
|
954
|
-
const context = await cg.buildContext(task, {
|
|
955
|
-
maxNodes: parseInt(options.maxNodes || '50', 10),
|
|
956
|
-
maxCodeBlocks: parseInt(options.maxCode || '10', 10),
|
|
957
|
-
includeCode: options.code !== false,
|
|
958
|
-
format: options.format,
|
|
959
|
-
});
|
|
960
|
-
// Output the context
|
|
961
|
-
console.log(context);
|
|
962
|
-
cg.destroy();
|
|
963
|
-
}
|
|
964
|
-
catch (err) {
|
|
965
|
-
error(`Failed to build context: ${err instanceof Error ? err.message : String(err)}`);
|
|
966
|
-
process.exit(1);
|
|
967
|
-
}
|
|
968
|
-
});
|
|
969
|
-
/**
|
|
970
|
-
* codegraph serve
|
|
971
|
-
*/
|
|
972
|
-
program
|
|
973
|
-
.command('serve')
|
|
974
|
-
.description('Start CodeGraph as an MCP server for AI assistants')
|
|
975
|
-
.option('-p, --path <path>', 'Project path (optional for MCP mode, uses rootUri from client)')
|
|
976
|
-
.option('--mcp', 'Run as MCP server (stdio transport)')
|
|
977
|
-
.action(async (options) => {
|
|
978
|
-
const projectPath = options.path ? resolveProjectPath(options.path) : undefined;
|
|
979
|
-
try {
|
|
980
|
-
if (options.mcp) {
|
|
981
|
-
// Start MCP server - it handles initialization lazily based on rootUri from client
|
|
982
|
-
const { MCPServer } = await Promise.resolve().then(() => __importStar(require('../mcp/index')));
|
|
983
|
-
const server = new MCPServer(projectPath);
|
|
984
|
-
await server.start();
|
|
985
|
-
// Server will run until terminated
|
|
986
|
-
}
|
|
987
|
-
else {
|
|
988
|
-
// Default: show info about MCP mode.
|
|
989
|
-
// Use stderr so stdout stays clean for any piped/stdio usage.
|
|
990
|
-
console.error(chalk.bold('\nCodeGraph MCP Server\n'));
|
|
991
|
-
console.error(chalk.blue((0, glyphs_1.getGlyphs)().info) + ' Use --mcp flag to start the MCP server');
|
|
992
|
-
console.error('\nTo use with Claude Code, add to your MCP configuration:');
|
|
993
|
-
console.error(chalk.dim(`
|
|
994
|
-
{
|
|
995
|
-
"mcpServers": {
|
|
996
|
-
"codegraph": {
|
|
997
|
-
"command": "codegraph",
|
|
998
|
-
"args": ["serve", "--mcp"]
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
`));
|
|
1003
|
-
console.error('Available tools:');
|
|
1004
|
-
console.error(chalk.cyan(' codegraph_search') + ' - Search for code symbols');
|
|
1005
|
-
console.error(chalk.cyan(' codegraph_context') + ' - Build context for a task');
|
|
1006
|
-
console.error(chalk.cyan(' codegraph_callers') + ' - Find callers of a symbol');
|
|
1007
|
-
console.error(chalk.cyan(' codegraph_callees') + ' - Find what a symbol calls');
|
|
1008
|
-
console.error(chalk.cyan(' codegraph_impact') + ' - Analyze impact of changes');
|
|
1009
|
-
console.error(chalk.cyan(' codegraph_node') + ' - Get symbol details');
|
|
1010
|
-
console.error(chalk.cyan(' codegraph_files') + ' - Get project file structure');
|
|
1011
|
-
console.error(chalk.cyan(' codegraph_status') + ' - Get index status');
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
|
-
catch (err) {
|
|
1015
|
-
error(`Failed to start server: ${err instanceof Error ? err.message : String(err)}`);
|
|
1016
|
-
process.exit(1);
|
|
1017
|
-
}
|
|
1018
|
-
});
|
|
1019
|
-
/**
|
|
1020
|
-
* codegraph unlock [path]
|
|
1021
|
-
*/
|
|
1022
|
-
program
|
|
1023
|
-
.command('unlock [path]')
|
|
1024
|
-
.description('Remove a stale lock file that is blocking indexing')
|
|
1025
|
-
.action(async (pathArg) => {
|
|
1026
|
-
const projectPath = resolveProjectPath(pathArg);
|
|
1027
|
-
try {
|
|
1028
|
-
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
1029
|
-
error(`CodeGraph not initialized in ${projectPath}`);
|
|
1030
|
-
return;
|
|
1031
|
-
}
|
|
1032
|
-
const lockPath = path.join((0, directory_1.getCodeGraphDir)(projectPath), 'codegraph.lock');
|
|
1033
|
-
if (!fs.existsSync(lockPath)) {
|
|
1034
|
-
info(`No lock file found ${(0, glyphs_1.getGlyphs)().dash} nothing to do`);
|
|
1035
|
-
return;
|
|
1036
|
-
}
|
|
1037
|
-
fs.unlinkSync(lockPath);
|
|
1038
|
-
success('Removed lock file. You can now run indexing again.');
|
|
1039
|
-
}
|
|
1040
|
-
catch (err) {
|
|
1041
|
-
error(`Failed to remove lock: ${err instanceof Error ? err.message : String(err)}`);
|
|
1042
|
-
process.exit(1);
|
|
1043
|
-
}
|
|
1044
|
-
});
|
|
1045
|
-
/**
|
|
1046
|
-
* codegraph affected [files...]
|
|
1047
|
-
*
|
|
1048
|
-
* Find test files affected by the given source files.
|
|
1049
|
-
* Traces dependency edges transitively to find test files that depend on changed code.
|
|
1050
|
-
*
|
|
1051
|
-
* Usage:
|
|
1052
|
-
* git diff --name-only | codegraph affected --stdin
|
|
1053
|
-
* codegraph affected src/lib/components/Editor.svelte src/routes/+page.svelte
|
|
1054
|
-
*/
|
|
1055
|
-
program
|
|
1056
|
-
.command('affected [files...]')
|
|
1057
|
-
.description('Find test files affected by changed source files')
|
|
1058
|
-
.option('-p, --path <path>', 'Project path')
|
|
1059
|
-
.option('--stdin', 'Read file list from stdin (one per line)')
|
|
1060
|
-
.option('-d, --depth <number>', 'Max dependency traversal depth', '5')
|
|
1061
|
-
.option('-f, --filter <glob>', 'Custom glob filter for test files (e.g. "e2e/*.spec.ts")')
|
|
1062
|
-
.option('-j, --json', 'Output as JSON')
|
|
1063
|
-
.option('-q, --quiet', 'Only output file paths, no decoration')
|
|
1064
|
-
.action(async (fileArgs, options) => {
|
|
1065
|
-
const projectPath = resolveProjectPath(options.path);
|
|
1066
|
-
try {
|
|
1067
|
-
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
1068
|
-
error(`CodeGraph not initialized in ${projectPath}`);
|
|
1069
|
-
process.exit(1);
|
|
1070
|
-
}
|
|
1071
|
-
// Collect changed files from args or stdin
|
|
1072
|
-
let changedFiles = [...(fileArgs || [])];
|
|
1073
|
-
if (options.stdin) {
|
|
1074
|
-
const stdinData = fs.readFileSync(0, 'utf-8');
|
|
1075
|
-
const stdinFiles = stdinData.split('\n').map(f => f.trim()).filter(Boolean);
|
|
1076
|
-
changedFiles.push(...stdinFiles);
|
|
1077
|
-
}
|
|
1078
|
-
if (changedFiles.length === 0) {
|
|
1079
|
-
if (!options.quiet)
|
|
1080
|
-
info('No files provided. Use file arguments or --stdin.');
|
|
1081
|
-
process.exit(0);
|
|
1082
|
-
}
|
|
1083
|
-
const { default: CodeGraph } = await loadCodeGraph();
|
|
1084
|
-
const cg = await CodeGraph.open(projectPath);
|
|
1085
|
-
const maxDepth = parseInt(options.depth || '5', 10);
|
|
1086
|
-
// Common test file patterns
|
|
1087
|
-
const defaultTestPatterns = [
|
|
1088
|
-
/\.spec\./,
|
|
1089
|
-
/\.test\./,
|
|
1090
|
-
/\/__tests__\//,
|
|
1091
|
-
/\/tests?\//,
|
|
1092
|
-
/\/e2e\//,
|
|
1093
|
-
/\/spec\//,
|
|
1094
|
-
];
|
|
1095
|
-
// Custom filter pattern
|
|
1096
|
-
let customFilter = null;
|
|
1097
|
-
if (options.filter) {
|
|
1098
|
-
// Convert glob to regex: ** → .+, * → [^/]*, . → \.
|
|
1099
|
-
const regex = options.filter
|
|
1100
|
-
.replace(/[+[\]{}()^$|\\]/g, '\\$&')
|
|
1101
|
-
.replace(/\./g, '\\.')
|
|
1102
|
-
.replace(/\*\*/g, '.+')
|
|
1103
|
-
.replace(/\*/g, '[^/]*');
|
|
1104
|
-
customFilter = new RegExp(regex);
|
|
1105
|
-
}
|
|
1106
|
-
function isTestFile(filePath) {
|
|
1107
|
-
if (customFilter)
|
|
1108
|
-
return customFilter.test(filePath);
|
|
1109
|
-
return defaultTestPatterns.some(p => p.test(filePath));
|
|
1110
|
-
}
|
|
1111
|
-
// BFS to find all transitive dependents of changed files, filtered to test files
|
|
1112
|
-
const affectedTests = new Set();
|
|
1113
|
-
const allDependents = new Set();
|
|
1114
|
-
for (const file of changedFiles) {
|
|
1115
|
-
// If the changed file is itself a test file, include it
|
|
1116
|
-
if (isTestFile(file)) {
|
|
1117
|
-
affectedTests.add(file);
|
|
1118
|
-
continue;
|
|
1119
|
-
}
|
|
1120
|
-
// BFS through dependents
|
|
1121
|
-
const queue = [{ file, depth: 0 }];
|
|
1122
|
-
const visited = new Set();
|
|
1123
|
-
visited.add(file);
|
|
1124
|
-
while (queue.length > 0) {
|
|
1125
|
-
const current = queue.shift();
|
|
1126
|
-
if (current.depth >= maxDepth)
|
|
1127
|
-
continue;
|
|
1128
|
-
const dependents = cg.getFileDependents(current.file);
|
|
1129
|
-
for (const dep of dependents) {
|
|
1130
|
-
if (visited.has(dep))
|
|
1131
|
-
continue;
|
|
1132
|
-
visited.add(dep);
|
|
1133
|
-
allDependents.add(dep);
|
|
1134
|
-
if (isTestFile(dep)) {
|
|
1135
|
-
affectedTests.add(dep);
|
|
1136
|
-
}
|
|
1137
|
-
else {
|
|
1138
|
-
queue.push({ file: dep, depth: current.depth + 1 });
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
const sortedTests = Array.from(affectedTests).sort();
|
|
1144
|
-
// Output
|
|
1145
|
-
if (options.json) {
|
|
1146
|
-
console.log(JSON.stringify({
|
|
1147
|
-
changedFiles,
|
|
1148
|
-
affectedTests: sortedTests,
|
|
1149
|
-
totalDependentsTraversed: allDependents.size,
|
|
1150
|
-
}, null, 2));
|
|
1151
|
-
}
|
|
1152
|
-
else if (options.quiet) {
|
|
1153
|
-
for (const t of sortedTests)
|
|
1154
|
-
console.log(t);
|
|
1155
|
-
}
|
|
1156
|
-
else {
|
|
1157
|
-
if (sortedTests.length === 0) {
|
|
1158
|
-
info('No test files affected by the changed files.');
|
|
1159
|
-
}
|
|
1160
|
-
else {
|
|
1161
|
-
console.log(chalk.bold(`\nAffected test files (${sortedTests.length}):\n`));
|
|
1162
|
-
for (const t of sortedTests) {
|
|
1163
|
-
console.log(' ' + chalk.cyan(t));
|
|
1164
|
-
}
|
|
1165
|
-
console.log();
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
cg.destroy();
|
|
1169
|
-
}
|
|
1170
|
-
catch (err) {
|
|
1171
|
-
error(`Affected analysis failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1172
|
-
process.exit(1);
|
|
1173
|
-
}
|
|
1174
|
-
});
|
|
1175
|
-
/**
|
|
1176
|
-
* codegraph install
|
|
1177
|
-
*/
|
|
1178
|
-
program
|
|
1179
|
-
.command('install')
|
|
1180
|
-
.description('Install codegraph MCP server into one or more agents (Claude Code, Cursor, Codex CLI, opencode)')
|
|
1181
|
-
.option('-t, --target <ids>', 'Target agent(s): comma-separated ids, or "auto"|"all"|"none". Default: prompt')
|
|
1182
|
-
.option('-l, --location <where>', 'Install location: "global" or "local". Default: prompt')
|
|
1183
|
-
.option('-y, --yes', 'Non-interactive: defaults to --location=global --target=auto, auto-allow on')
|
|
1184
|
-
.option('--no-permissions', 'Skip writing the auto-allow permissions list (Claude Code only)')
|
|
1185
|
-
.option('--print-config <id>', 'Print MCP config snippet for the named agent and exit (no file writes)')
|
|
1186
|
-
.action(async (opts) => {
|
|
1187
|
-
if (opts.printConfig) {
|
|
1188
|
-
const { getTarget, listTargetIds } = await Promise.resolve().then(() => __importStar(require('../installer/targets/registry')));
|
|
1189
|
-
const target = getTarget(opts.printConfig);
|
|
1190
|
-
if (!target) {
|
|
1191
|
-
const known = listTargetIds().join(', ');
|
|
1192
|
-
error(`Unknown target "${opts.printConfig}". Known: ${known}.`);
|
|
1193
|
-
process.exit(1);
|
|
1194
|
-
}
|
|
1195
|
-
const loc = (opts.location === 'local' ? 'local' : 'global');
|
|
1196
|
-
process.stdout.write(target.printConfig(loc));
|
|
1197
|
-
return;
|
|
1198
|
-
}
|
|
1199
|
-
const { runInstallerWithOptions } = await Promise.resolve().then(() => __importStar(require('../installer')));
|
|
1200
|
-
if (opts.location && opts.location !== 'global' && opts.location !== 'local') {
|
|
1201
|
-
error(`--location must be "global" or "local" (got "${opts.location}").`);
|
|
1202
|
-
process.exit(1);
|
|
1203
|
-
}
|
|
1204
|
-
try {
|
|
1205
|
-
// Commander's `--no-permissions` makes `opts.permissions === false`;
|
|
1206
|
-
// omitting the flag leaves it `true` (the positive-form default).
|
|
1207
|
-
// We MUST treat the default-true as "user did not override — let
|
|
1208
|
-
// the orchestrator prompt" and only forward an explicit `false`
|
|
1209
|
-
// (or `true` when --yes implies it). Otherwise the auto-allow
|
|
1210
|
-
// prompt is silently skipped on every interactive run.
|
|
1211
|
-
const explicitNoPermissions = opts.permissions === false;
|
|
1212
|
-
const autoAllow = explicitNoPermissions
|
|
1213
|
-
? false
|
|
1214
|
-
: opts.yes
|
|
1215
|
-
? true
|
|
1216
|
-
: undefined;
|
|
1217
|
-
await runInstallerWithOptions({
|
|
1218
|
-
target: opts.target,
|
|
1219
|
-
location: opts.location,
|
|
1220
|
-
autoAllow,
|
|
1221
|
-
yes: opts.yes,
|
|
1222
|
-
});
|
|
1223
|
-
}
|
|
1224
|
-
catch (err) {
|
|
1225
|
-
error(err instanceof Error ? err.message : String(err));
|
|
1226
|
-
process.exit(1);
|
|
1227
|
-
}
|
|
1228
|
-
});
|
|
1229
|
-
// Parse and run
|
|
1230
|
-
program.parse();
|
|
1231
|
-
} // end main()
|
|
1232
|
-
//# sourceMappingURL=codegraph.js.map
|