@mduenas/codegraph 0.4.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.
Files changed (192) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +641 -0
  3. package/dist/bin/codegraph.d.ts +20 -0
  4. package/dist/bin/codegraph.d.ts.map +1 -0
  5. package/dist/bin/codegraph.js +704 -0
  6. package/dist/bin/codegraph.js.map +1 -0
  7. package/dist/config.d.ts +51 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +291 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/context/formatter.d.ts +30 -0
  12. package/dist/context/formatter.d.ts.map +1 -0
  13. package/dist/context/formatter.js +244 -0
  14. package/dist/context/formatter.js.map +1 -0
  15. package/dist/context/index.d.ts +86 -0
  16. package/dist/context/index.d.ts.map +1 -0
  17. package/dist/context/index.js +402 -0
  18. package/dist/context/index.js.map +1 -0
  19. package/dist/db/index.d.ts +64 -0
  20. package/dist/db/index.d.ts.map +1 -0
  21. package/dist/db/index.js +170 -0
  22. package/dist/db/index.js.map +1 -0
  23. package/dist/db/migrations.d.ts +44 -0
  24. package/dist/db/migrations.d.ts.map +1 -0
  25. package/dist/db/migrations.js +105 -0
  26. package/dist/db/migrations.js.map +1 -0
  27. package/dist/db/queries.d.ts +148 -0
  28. package/dist/db/queries.d.ts.map +1 -0
  29. package/dist/db/queries.js +669 -0
  30. package/dist/db/queries.js.map +1 -0
  31. package/dist/directory.d.ts +45 -0
  32. package/dist/directory.d.ts.map +1 -0
  33. package/dist/directory.js +191 -0
  34. package/dist/directory.js.map +1 -0
  35. package/dist/errors.d.ts +136 -0
  36. package/dist/errors.d.ts.map +1 -0
  37. package/dist/errors.js +219 -0
  38. package/dist/errors.js.map +1 -0
  39. package/dist/extraction/grammars.d.ts +36 -0
  40. package/dist/extraction/grammars.d.ts.map +1 -0
  41. package/dist/extraction/grammars.js +181 -0
  42. package/dist/extraction/grammars.js.map +1 -0
  43. package/dist/extraction/index.d.ts +91 -0
  44. package/dist/extraction/index.d.ts.map +1 -0
  45. package/dist/extraction/index.js +493 -0
  46. package/dist/extraction/index.js.map +1 -0
  47. package/dist/extraction/tree-sitter.d.ts +176 -0
  48. package/dist/extraction/tree-sitter.d.ts.map +1 -0
  49. package/dist/extraction/tree-sitter.js +1798 -0
  50. package/dist/extraction/tree-sitter.js.map +1 -0
  51. package/dist/graph/index.d.ts +8 -0
  52. package/dist/graph/index.d.ts.map +1 -0
  53. package/dist/graph/index.js +13 -0
  54. package/dist/graph/index.js.map +1 -0
  55. package/dist/graph/queries.d.ts +106 -0
  56. package/dist/graph/queries.d.ts.map +1 -0
  57. package/dist/graph/queries.js +355 -0
  58. package/dist/graph/queries.js.map +1 -0
  59. package/dist/graph/traversal.d.ts +127 -0
  60. package/dist/graph/traversal.d.ts.map +1 -0
  61. package/dist/graph/traversal.js +465 -0
  62. package/dist/graph/traversal.js.map +1 -0
  63. package/dist/index.d.ts +496 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +818 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/installer/banner.d.ts +40 -0
  68. package/dist/installer/banner.d.ts.map +1 -0
  69. package/dist/installer/banner.js +162 -0
  70. package/dist/installer/banner.js.map +1 -0
  71. package/dist/installer/claude-md-template.d.ts +10 -0
  72. package/dist/installer/claude-md-template.d.ts.map +1 -0
  73. package/dist/installer/claude-md-template.js +46 -0
  74. package/dist/installer/claude-md-template.js.map +1 -0
  75. package/dist/installer/config-writer.d.ts +36 -0
  76. package/dist/installer/config-writer.d.ts.map +1 -0
  77. package/dist/installer/config-writer.js +282 -0
  78. package/dist/installer/config-writer.js.map +1 -0
  79. package/dist/installer/index.d.ts +13 -0
  80. package/dist/installer/index.d.ts.map +1 -0
  81. package/dist/installer/index.js +155 -0
  82. package/dist/installer/index.js.map +1 -0
  83. package/dist/installer/prompts.d.ts +18 -0
  84. package/dist/installer/prompts.d.ts.map +1 -0
  85. package/dist/installer/prompts.js +113 -0
  86. package/dist/installer/prompts.js.map +1 -0
  87. package/dist/mcp/index.d.ts +64 -0
  88. package/dist/mcp/index.d.ts.map +1 -0
  89. package/dist/mcp/index.js +207 -0
  90. package/dist/mcp/index.js.map +1 -0
  91. package/dist/mcp/tools.d.ts +93 -0
  92. package/dist/mcp/tools.d.ts.map +1 -0
  93. package/dist/mcp/tools.js +442 -0
  94. package/dist/mcp/tools.js.map +1 -0
  95. package/dist/mcp/transport.d.ts +89 -0
  96. package/dist/mcp/transport.d.ts.map +1 -0
  97. package/dist/mcp/transport.js +170 -0
  98. package/dist/mcp/transport.js.map +1 -0
  99. package/dist/resolution/frameworks/csharp.d.ts +8 -0
  100. package/dist/resolution/frameworks/csharp.d.ts.map +1 -0
  101. package/dist/resolution/frameworks/csharp.js +274 -0
  102. package/dist/resolution/frameworks/csharp.js.map +1 -0
  103. package/dist/resolution/frameworks/express.d.ts +8 -0
  104. package/dist/resolution/frameworks/express.d.ts.map +1 -0
  105. package/dist/resolution/frameworks/express.js +208 -0
  106. package/dist/resolution/frameworks/express.js.map +1 -0
  107. package/dist/resolution/frameworks/go.d.ts +8 -0
  108. package/dist/resolution/frameworks/go.d.ts.map +1 -0
  109. package/dist/resolution/frameworks/go.js +225 -0
  110. package/dist/resolution/frameworks/go.js.map +1 -0
  111. package/dist/resolution/frameworks/index.d.ts +33 -0
  112. package/dist/resolution/frameworks/index.d.ts.map +1 -0
  113. package/dist/resolution/frameworks/index.js +113 -0
  114. package/dist/resolution/frameworks/index.js.map +1 -0
  115. package/dist/resolution/frameworks/java.d.ts +8 -0
  116. package/dist/resolution/frameworks/java.d.ts.map +1 -0
  117. package/dist/resolution/frameworks/java.js +239 -0
  118. package/dist/resolution/frameworks/java.js.map +1 -0
  119. package/dist/resolution/frameworks/laravel.d.ts +13 -0
  120. package/dist/resolution/frameworks/laravel.d.ts.map +1 -0
  121. package/dist/resolution/frameworks/laravel.js +198 -0
  122. package/dist/resolution/frameworks/laravel.js.map +1 -0
  123. package/dist/resolution/frameworks/python.d.ts +10 -0
  124. package/dist/resolution/frameworks/python.d.ts.map +1 -0
  125. package/dist/resolution/frameworks/python.js +331 -0
  126. package/dist/resolution/frameworks/python.js.map +1 -0
  127. package/dist/resolution/frameworks/react.d.ts +8 -0
  128. package/dist/resolution/frameworks/react.d.ts.map +1 -0
  129. package/dist/resolution/frameworks/react.js +294 -0
  130. package/dist/resolution/frameworks/react.js.map +1 -0
  131. package/dist/resolution/frameworks/ruby.d.ts +8 -0
  132. package/dist/resolution/frameworks/ruby.d.ts.map +1 -0
  133. package/dist/resolution/frameworks/ruby.js +262 -0
  134. package/dist/resolution/frameworks/ruby.js.map +1 -0
  135. package/dist/resolution/frameworks/rust.d.ts +8 -0
  136. package/dist/resolution/frameworks/rust.d.ts.map +1 -0
  137. package/dist/resolution/frameworks/rust.js +222 -0
  138. package/dist/resolution/frameworks/rust.js.map +1 -0
  139. package/dist/resolution/frameworks/swift.d.ts +10 -0
  140. package/dist/resolution/frameworks/swift.d.ts.map +1 -0
  141. package/dist/resolution/frameworks/swift.js +486 -0
  142. package/dist/resolution/frameworks/swift.js.map +1 -0
  143. package/dist/resolution/import-resolver.d.ts +20 -0
  144. package/dist/resolution/import-resolver.d.ts.map +1 -0
  145. package/dist/resolution/import-resolver.js +445 -0
  146. package/dist/resolution/import-resolver.js.map +1 -0
  147. package/dist/resolution/index.d.ts +72 -0
  148. package/dist/resolution/index.d.ts.map +1 -0
  149. package/dist/resolution/index.js +301 -0
  150. package/dist/resolution/index.js.map +1 -0
  151. package/dist/resolution/name-matcher.d.ts +27 -0
  152. package/dist/resolution/name-matcher.d.ts.map +1 -0
  153. package/dist/resolution/name-matcher.js +210 -0
  154. package/dist/resolution/name-matcher.js.map +1 -0
  155. package/dist/resolution/types.d.ts +108 -0
  156. package/dist/resolution/types.d.ts.map +1 -0
  157. package/dist/resolution/types.js +8 -0
  158. package/dist/resolution/types.js.map +1 -0
  159. package/dist/sync/git-hooks.d.ts +66 -0
  160. package/dist/sync/git-hooks.d.ts.map +1 -0
  161. package/dist/sync/git-hooks.js +281 -0
  162. package/dist/sync/git-hooks.js.map +1 -0
  163. package/dist/sync/index.d.ts +13 -0
  164. package/dist/sync/index.d.ts.map +1 -0
  165. package/dist/sync/index.js +18 -0
  166. package/dist/sync/index.js.map +1 -0
  167. package/dist/types.d.ts +410 -0
  168. package/dist/types.d.ts.map +1 -0
  169. package/dist/types.js +165 -0
  170. package/dist/types.js.map +1 -0
  171. package/dist/utils.d.ts +116 -0
  172. package/dist/utils.d.ts.map +1 -0
  173. package/dist/utils.js +295 -0
  174. package/dist/utils.js.map +1 -0
  175. package/dist/vectors/embedder.d.ts +140 -0
  176. package/dist/vectors/embedder.d.ts.map +1 -0
  177. package/dist/vectors/embedder.js +336 -0
  178. package/dist/vectors/embedder.js.map +1 -0
  179. package/dist/vectors/index.d.ts +9 -0
  180. package/dist/vectors/index.d.ts.map +1 -0
  181. package/dist/vectors/index.js +20 -0
  182. package/dist/vectors/index.js.map +1 -0
  183. package/dist/vectors/manager.d.ts +119 -0
  184. package/dist/vectors/manager.d.ts.map +1 -0
  185. package/dist/vectors/manager.js +274 -0
  186. package/dist/vectors/manager.js.map +1 -0
  187. package/dist/vectors/search.d.ts +134 -0
  188. package/dist/vectors/search.d.ts.map +1 -0
  189. package/dist/vectors/search.js +409 -0
  190. package/dist/vectors/search.js.map +1 -0
  191. package/package.json +67 -0
  192. package/scripts/postinstall.js +68 -0
@@ -0,0 +1,704 @@
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 index [path] Index all files in the project
13
+ * codegraph sync [path] Sync changes since last index
14
+ * codegraph status [path] Show index status
15
+ * codegraph query <search> Search for symbols
16
+ * codegraph context <task> Build context for a task
17
+ * codegraph hooks install Install git hooks
18
+ * codegraph hooks remove Remove git hooks
19
+ */
20
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ var desc = Object.getOwnPropertyDescriptor(m, k);
23
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
24
+ desc = { enumerable: true, get: function() { return m[k]; } };
25
+ }
26
+ Object.defineProperty(o, k2, desc);
27
+ }) : (function(o, m, k, k2) {
28
+ if (k2 === undefined) k2 = k;
29
+ o[k2] = m[k];
30
+ }));
31
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
32
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
33
+ }) : function(o, v) {
34
+ o["default"] = v;
35
+ });
36
+ var __importStar = (this && this.__importStar) || (function () {
37
+ var ownKeys = function(o) {
38
+ ownKeys = Object.getOwnPropertyNames || function (o) {
39
+ var ar = [];
40
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
41
+ return ar;
42
+ };
43
+ return ownKeys(o);
44
+ };
45
+ return function (mod) {
46
+ if (mod && mod.__esModule) return mod;
47
+ var result = {};
48
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
49
+ __setModuleDefault(result, mod);
50
+ return result;
51
+ };
52
+ })();
53
+ var __importDefault = (this && this.__importDefault) || function (mod) {
54
+ return (mod && mod.__esModule) ? mod : { "default": mod };
55
+ };
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ const commander_1 = require("commander");
58
+ const path = __importStar(require("path"));
59
+ const fs = __importStar(require("fs"));
60
+ const index_1 = __importDefault(require("../index"));
61
+ const installer_1 = require("../installer");
62
+ // Check if running with no arguments - run installer
63
+ if (process.argv.length === 2) {
64
+ (0, installer_1.runInstaller)().catch((err) => {
65
+ console.error('Installation failed:', err.message);
66
+ process.exit(1);
67
+ });
68
+ }
69
+ else {
70
+ // Normal CLI flow
71
+ main();
72
+ }
73
+ function main() {
74
+ const program = new commander_1.Command();
75
+ // Version from package.json
76
+ const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json'), 'utf-8'));
77
+ // =============================================================================
78
+ // ANSI Color Helpers (avoid chalk ESM issues)
79
+ // =============================================================================
80
+ const colors = {
81
+ reset: '\x1b[0m',
82
+ bold: '\x1b[1m',
83
+ dim: '\x1b[2m',
84
+ red: '\x1b[31m',
85
+ green: '\x1b[32m',
86
+ yellow: '\x1b[33m',
87
+ blue: '\x1b[34m',
88
+ cyan: '\x1b[36m',
89
+ white: '\x1b[37m',
90
+ gray: '\x1b[90m',
91
+ };
92
+ const chalk = {
93
+ bold: (s) => `${colors.bold}${s}${colors.reset}`,
94
+ dim: (s) => `${colors.dim}${s}${colors.reset}`,
95
+ red: (s) => `${colors.red}${s}${colors.reset}`,
96
+ green: (s) => `${colors.green}${s}${colors.reset}`,
97
+ yellow: (s) => `${colors.yellow}${s}${colors.reset}`,
98
+ blue: (s) => `${colors.blue}${s}${colors.reset}`,
99
+ cyan: (s) => `${colors.cyan}${s}${colors.reset}`,
100
+ white: (s) => `${colors.white}${s}${colors.reset}`,
101
+ gray: (s) => `${colors.gray}${s}${colors.reset}`,
102
+ };
103
+ program
104
+ .name('codegraph')
105
+ .description('Code intelligence and knowledge graph for any codebase')
106
+ .version(packageJson.version);
107
+ // =============================================================================
108
+ // Helper Functions
109
+ // =============================================================================
110
+ /**
111
+ * Resolve project path from argument or current directory
112
+ */
113
+ function resolveProjectPath(pathArg) {
114
+ return path.resolve(pathArg || process.cwd());
115
+ }
116
+ /**
117
+ * Format a number with commas
118
+ */
119
+ function formatNumber(n) {
120
+ return n.toLocaleString();
121
+ }
122
+ /**
123
+ * Format duration in milliseconds to human readable
124
+ */
125
+ function formatDuration(ms) {
126
+ if (ms < 1000) {
127
+ return `${ms}ms`;
128
+ }
129
+ const seconds = ms / 1000;
130
+ if (seconds < 60) {
131
+ return `${seconds.toFixed(1)}s`;
132
+ }
133
+ const minutes = Math.floor(seconds / 60);
134
+ const remainingSeconds = seconds % 60;
135
+ return `${minutes}m ${remainingSeconds.toFixed(0)}s`;
136
+ }
137
+ /**
138
+ * Create a progress bar string
139
+ */
140
+ function progressBar(current, total, width = 30) {
141
+ const percent = total > 0 ? current / total : 0;
142
+ const filled = Math.round(width * percent);
143
+ const empty = width - filled;
144
+ const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
145
+ const percentStr = `${Math.round(percent * 100)}%`.padStart(4);
146
+ return `${bar} ${percentStr}`;
147
+ }
148
+ /**
149
+ * Print a progress update (overwrites current line)
150
+ */
151
+ function printProgress(progress) {
152
+ const phaseNames = {
153
+ scanning: 'Scanning files',
154
+ parsing: 'Parsing code',
155
+ storing: 'Storing data',
156
+ resolving: 'Resolving refs',
157
+ };
158
+ const phaseName = phaseNames[progress.phase] || progress.phase;
159
+ const bar = progressBar(progress.current, progress.total);
160
+ const file = progress.currentFile ? chalk.dim(` ${progress.currentFile}`) : '';
161
+ // Clear line and print progress
162
+ process.stdout.write(`\r${chalk.cyan(phaseName)}: ${bar}${file}`.padEnd(100));
163
+ }
164
+ /**
165
+ * Print success message
166
+ */
167
+ function success(message) {
168
+ console.log(chalk.green('✓') + ' ' + message);
169
+ }
170
+ /**
171
+ * Print error message
172
+ */
173
+ function error(message) {
174
+ console.error(chalk.red('✗') + ' ' + message);
175
+ }
176
+ /**
177
+ * Print info message
178
+ */
179
+ function info(message) {
180
+ console.log(chalk.blue('ℹ') + ' ' + message);
181
+ }
182
+ /**
183
+ * Print warning message
184
+ */
185
+ function warn(message) {
186
+ console.log(chalk.yellow('⚠') + ' ' + message);
187
+ }
188
+ // =============================================================================
189
+ // Commands
190
+ // =============================================================================
191
+ /**
192
+ * codegraph init [path]
193
+ */
194
+ program
195
+ .command('init [path]')
196
+ .description('Initialize CodeGraph in a project directory')
197
+ .option('-i, --index', 'Run initial indexing after initialization')
198
+ .option('--no-hooks', 'Skip git hooks installation')
199
+ .action(async (pathArg, options) => {
200
+ const projectPath = resolveProjectPath(pathArg);
201
+ console.log(chalk.bold('\nInitializing CodeGraph...\n'));
202
+ try {
203
+ // Check if already initialized
204
+ if (index_1.default.isInitialized(projectPath)) {
205
+ warn(`CodeGraph already initialized in ${projectPath}`);
206
+ info('Use "codegraph index" to re-index or "codegraph sync" to update');
207
+ return;
208
+ }
209
+ // Initialize
210
+ const cg = await index_1.default.init(projectPath, {
211
+ index: false, // We'll handle indexing ourselves for progress
212
+ });
213
+ success(`Initialized CodeGraph in ${projectPath}`);
214
+ info(`Created .codegraph/ directory`);
215
+ // Install git hooks if requested (default: true)
216
+ if (options.hooks !== false && cg.isGitRepository()) {
217
+ const hookResult = cg.installGitHooks();
218
+ if (hookResult.success) {
219
+ success('Installed git post-commit hook for auto-sync');
220
+ }
221
+ else {
222
+ warn(`Could not install git hooks: ${hookResult.message}`);
223
+ }
224
+ }
225
+ // Run initial index if requested
226
+ if (options.index) {
227
+ console.log('\nIndexing project...\n');
228
+ const result = await cg.indexAll({
229
+ onProgress: printProgress,
230
+ });
231
+ // Clear progress line
232
+ process.stdout.write('\r' + ' '.repeat(100) + '\r');
233
+ if (result.success) {
234
+ success(`Indexed ${formatNumber(result.filesIndexed)} files`);
235
+ info(`Created ${formatNumber(result.nodesCreated)} nodes and ${formatNumber(result.edgesCreated)} edges`);
236
+ info(`Completed in ${formatDuration(result.durationMs)}`);
237
+ }
238
+ else {
239
+ warn(`Indexing completed with ${result.errors.length} errors`);
240
+ }
241
+ }
242
+ else {
243
+ info('Run "codegraph index" to index the project');
244
+ }
245
+ cg.destroy();
246
+ }
247
+ catch (err) {
248
+ error(`Failed to initialize: ${err instanceof Error ? err.message : String(err)}`);
249
+ process.exit(1);
250
+ }
251
+ });
252
+ /**
253
+ * codegraph index [path]
254
+ */
255
+ program
256
+ .command('index [path]')
257
+ .description('Index all files in the project')
258
+ .option('-f, --force', 'Force full re-index even if already indexed')
259
+ .option('-q, --quiet', 'Suppress progress output')
260
+ .action(async (pathArg, options) => {
261
+ const projectPath = resolveProjectPath(pathArg);
262
+ try {
263
+ if (!index_1.default.isInitialized(projectPath)) {
264
+ error(`CodeGraph not initialized in ${projectPath}`);
265
+ info('Run "codegraph init" first');
266
+ process.exit(1);
267
+ }
268
+ const cg = await index_1.default.open(projectPath);
269
+ if (!options.quiet) {
270
+ console.log(chalk.bold('\nIndexing project...\n'));
271
+ }
272
+ // Clear existing data if force
273
+ if (options.force) {
274
+ cg.clear();
275
+ if (!options.quiet) {
276
+ info('Cleared existing index');
277
+ }
278
+ }
279
+ const result = await cg.indexAll({
280
+ onProgress: options.quiet ? undefined : printProgress,
281
+ });
282
+ // Clear progress line
283
+ if (!options.quiet) {
284
+ process.stdout.write('\r' + ' '.repeat(100) + '\r');
285
+ }
286
+ if (result.success) {
287
+ if (!options.quiet) {
288
+ success(`Indexed ${formatNumber(result.filesIndexed)} files`);
289
+ info(`Created ${formatNumber(result.nodesCreated)} nodes and ${formatNumber(result.edgesCreated)} edges`);
290
+ info(`Completed in ${formatDuration(result.durationMs)}`);
291
+ }
292
+ }
293
+ else {
294
+ if (!options.quiet) {
295
+ warn(`Indexing completed with ${result.errors.length} errors`);
296
+ for (const err of result.errors.slice(0, 5)) {
297
+ console.log(chalk.dim(` - ${err.message}`));
298
+ }
299
+ if (result.errors.length > 5) {
300
+ console.log(chalk.dim(` ... and ${result.errors.length - 5} more`));
301
+ }
302
+ }
303
+ process.exit(1);
304
+ }
305
+ cg.destroy();
306
+ }
307
+ catch (err) {
308
+ error(`Failed to index: ${err instanceof Error ? err.message : String(err)}`);
309
+ process.exit(1);
310
+ }
311
+ });
312
+ /**
313
+ * codegraph sync [path]
314
+ */
315
+ program
316
+ .command('sync [path]')
317
+ .description('Sync changes since last index')
318
+ .option('-q, --quiet', 'Suppress output (for git hooks)')
319
+ .action(async (pathArg, options) => {
320
+ const projectPath = resolveProjectPath(pathArg);
321
+ try {
322
+ if (!index_1.default.isInitialized(projectPath)) {
323
+ if (!options.quiet) {
324
+ error(`CodeGraph not initialized in ${projectPath}`);
325
+ }
326
+ process.exit(1);
327
+ }
328
+ const cg = await index_1.default.open(projectPath);
329
+ const result = await cg.sync({
330
+ onProgress: options.quiet ? undefined : printProgress,
331
+ });
332
+ // Clear progress line
333
+ if (!options.quiet) {
334
+ process.stdout.write('\r' + ' '.repeat(100) + '\r');
335
+ }
336
+ const totalChanges = result.filesAdded + result.filesModified + result.filesRemoved;
337
+ if (!options.quiet) {
338
+ if (totalChanges === 0) {
339
+ success('Already up to date');
340
+ }
341
+ else {
342
+ success(`Synced ${formatNumber(totalChanges)} changed files`);
343
+ if (result.filesAdded > 0) {
344
+ info(` Added: ${result.filesAdded}`);
345
+ }
346
+ if (result.filesModified > 0) {
347
+ info(` Modified: ${result.filesModified}`);
348
+ }
349
+ if (result.filesRemoved > 0) {
350
+ info(` Removed: ${result.filesRemoved}`);
351
+ }
352
+ info(`Updated ${formatNumber(result.nodesUpdated)} nodes in ${formatDuration(result.durationMs)}`);
353
+ }
354
+ }
355
+ cg.destroy();
356
+ }
357
+ catch (err) {
358
+ if (!options.quiet) {
359
+ error(`Failed to sync: ${err instanceof Error ? err.message : String(err)}`);
360
+ }
361
+ process.exit(1);
362
+ }
363
+ });
364
+ /**
365
+ * codegraph status [path]
366
+ */
367
+ program
368
+ .command('status [path]')
369
+ .description('Show index status and statistics')
370
+ .action(async (pathArg) => {
371
+ const projectPath = resolveProjectPath(pathArg);
372
+ try {
373
+ if (!index_1.default.isInitialized(projectPath)) {
374
+ console.log(chalk.bold('\nCodeGraph Status\n'));
375
+ info(`Project: ${projectPath}`);
376
+ warn('Not initialized');
377
+ info('Run "codegraph init" to initialize');
378
+ return;
379
+ }
380
+ const cg = await index_1.default.open(projectPath);
381
+ const stats = cg.getStats();
382
+ const changes = cg.getChangedFiles();
383
+ console.log(chalk.bold('\nCodeGraph Status\n'));
384
+ // Project info
385
+ console.log(chalk.cyan('Project:'), projectPath);
386
+ console.log();
387
+ // Index stats
388
+ console.log(chalk.bold('Index Statistics:'));
389
+ console.log(` Files: ${formatNumber(stats.fileCount)}`);
390
+ console.log(` Nodes: ${formatNumber(stats.nodeCount)}`);
391
+ console.log(` Edges: ${formatNumber(stats.edgeCount)}`);
392
+ console.log(` DB Size: ${(stats.dbSizeBytes / 1024 / 1024).toFixed(2)} MB`);
393
+ console.log();
394
+ // Node breakdown
395
+ console.log(chalk.bold('Nodes by Kind:'));
396
+ const nodesByKind = Object.entries(stats.nodesByKind)
397
+ .filter(([, count]) => count > 0)
398
+ .sort((a, b) => b[1] - a[1]);
399
+ for (const [kind, count] of nodesByKind) {
400
+ console.log(` ${kind.padEnd(15)} ${formatNumber(count)}`);
401
+ }
402
+ console.log();
403
+ // Language breakdown
404
+ console.log(chalk.bold('Files by Language:'));
405
+ const filesByLang = Object.entries(stats.filesByLanguage)
406
+ .filter(([, count]) => count > 0)
407
+ .sort((a, b) => b[1] - a[1]);
408
+ for (const [lang, count] of filesByLang) {
409
+ console.log(` ${lang.padEnd(15)} ${formatNumber(count)}`);
410
+ }
411
+ console.log();
412
+ // Pending changes
413
+ const totalChanges = changes.added.length + changes.modified.length + changes.removed.length;
414
+ if (totalChanges > 0) {
415
+ console.log(chalk.bold('Pending Changes:'));
416
+ if (changes.added.length > 0) {
417
+ console.log(` Added: ${changes.added.length} files`);
418
+ }
419
+ if (changes.modified.length > 0) {
420
+ console.log(` Modified: ${changes.modified.length} files`);
421
+ }
422
+ if (changes.removed.length > 0) {
423
+ console.log(` Removed: ${changes.removed.length} files`);
424
+ }
425
+ info('Run "codegraph sync" to update the index');
426
+ }
427
+ else {
428
+ success('Index is up to date');
429
+ }
430
+ console.log();
431
+ // Git hooks status
432
+ if (cg.isGitRepository()) {
433
+ const hookInstalled = cg.isGitHookInstalled();
434
+ if (hookInstalled) {
435
+ success('Git hooks: installed');
436
+ }
437
+ else {
438
+ warn('Git hooks: not installed');
439
+ info('Run "codegraph hooks install" to enable auto-sync');
440
+ }
441
+ }
442
+ cg.destroy();
443
+ }
444
+ catch (err) {
445
+ error(`Failed to get status: ${err instanceof Error ? err.message : String(err)}`);
446
+ process.exit(1);
447
+ }
448
+ });
449
+ /**
450
+ * codegraph query <search>
451
+ */
452
+ program
453
+ .command('query <search>')
454
+ .description('Search for symbols in the codebase')
455
+ .option('-p, --path <path>', 'Project path')
456
+ .option('-l, --limit <number>', 'Maximum results', '10')
457
+ .option('-k, --kind <kind>', 'Filter by node kind (function, class, etc.)')
458
+ .option('-j, --json', 'Output as JSON')
459
+ .action(async (search, options) => {
460
+ const projectPath = resolveProjectPath(options.path);
461
+ try {
462
+ if (!index_1.default.isInitialized(projectPath)) {
463
+ error(`CodeGraph not initialized in ${projectPath}`);
464
+ process.exit(1);
465
+ }
466
+ const cg = await index_1.default.open(projectPath);
467
+ const limit = parseInt(options.limit || '10', 10);
468
+ const results = cg.searchNodes(search, {
469
+ limit,
470
+ kinds: options.kind ? [options.kind] : undefined,
471
+ });
472
+ if (options.json) {
473
+ console.log(JSON.stringify(results, null, 2));
474
+ }
475
+ else {
476
+ if (results.length === 0) {
477
+ info(`No results found for "${search}"`);
478
+ }
479
+ else {
480
+ console.log(chalk.bold(`\nSearch Results for "${search}":\n`));
481
+ for (const result of results) {
482
+ const node = result.node;
483
+ const location = `${node.filePath}:${node.startLine}`;
484
+ const score = chalk.dim(`(${(result.score * 100).toFixed(0)}%)`);
485
+ console.log(chalk.cyan(node.kind.padEnd(12)) +
486
+ chalk.white(node.name) +
487
+ ' ' + score);
488
+ console.log(chalk.dim(` ${location}`));
489
+ if (node.signature) {
490
+ console.log(chalk.dim(` ${node.signature}`));
491
+ }
492
+ console.log();
493
+ }
494
+ }
495
+ }
496
+ cg.destroy();
497
+ }
498
+ catch (err) {
499
+ error(`Search failed: ${err instanceof Error ? err.message : String(err)}`);
500
+ process.exit(1);
501
+ }
502
+ });
503
+ /**
504
+ * codegraph context <task>
505
+ */
506
+ program
507
+ .command('context <task>')
508
+ .description('Build context for a task (outputs markdown)')
509
+ .option('-p, --path <path>', 'Project path')
510
+ .option('-n, --max-nodes <number>', 'Maximum nodes to include', '50')
511
+ .option('-c, --max-code <number>', 'Maximum code blocks', '10')
512
+ .option('--no-code', 'Exclude code blocks')
513
+ .option('-f, --format <format>', 'Output format (markdown, json)', 'markdown')
514
+ .action(async (task, options) => {
515
+ const projectPath = resolveProjectPath(options.path);
516
+ try {
517
+ if (!index_1.default.isInitialized(projectPath)) {
518
+ error(`CodeGraph not initialized in ${projectPath}`);
519
+ process.exit(1);
520
+ }
521
+ const cg = await index_1.default.open(projectPath);
522
+ const context = await cg.buildContext(task, {
523
+ maxNodes: parseInt(options.maxNodes || '50', 10),
524
+ maxCodeBlocks: parseInt(options.maxCode || '10', 10),
525
+ includeCode: options.code !== false,
526
+ format: options.format,
527
+ });
528
+ // Output the context
529
+ console.log(context);
530
+ cg.destroy();
531
+ }
532
+ catch (err) {
533
+ error(`Failed to build context: ${err instanceof Error ? err.message : String(err)}`);
534
+ process.exit(1);
535
+ }
536
+ });
537
+ /**
538
+ * codegraph hooks <action>
539
+ */
540
+ const hooksCommand = program
541
+ .command('hooks')
542
+ .description('Manage git hooks');
543
+ hooksCommand
544
+ .command('install')
545
+ .description('Install git post-commit hook for auto-sync')
546
+ .option('-p, --path <path>', 'Project path')
547
+ .action(async (options) => {
548
+ const projectPath = resolveProjectPath(options.path);
549
+ try {
550
+ if (!index_1.default.isInitialized(projectPath)) {
551
+ error(`CodeGraph not initialized in ${projectPath}`);
552
+ process.exit(1);
553
+ }
554
+ const cg = await index_1.default.open(projectPath);
555
+ if (!cg.isGitRepository()) {
556
+ error('Not a git repository');
557
+ cg.destroy();
558
+ process.exit(1);
559
+ }
560
+ const result = cg.installGitHooks();
561
+ if (result.success) {
562
+ success(result.message);
563
+ if (result.previousHookBackedUp) {
564
+ info('Previous hook backed up to post-commit.codegraph-backup');
565
+ }
566
+ }
567
+ else {
568
+ error(result.message);
569
+ process.exit(1);
570
+ }
571
+ cg.destroy();
572
+ }
573
+ catch (err) {
574
+ error(`Failed to install hooks: ${err instanceof Error ? err.message : String(err)}`);
575
+ process.exit(1);
576
+ }
577
+ });
578
+ hooksCommand
579
+ .command('remove')
580
+ .description('Remove git post-commit hook')
581
+ .option('-p, --path <path>', 'Project path')
582
+ .action(async (options) => {
583
+ const projectPath = resolveProjectPath(options.path);
584
+ try {
585
+ if (!index_1.default.isInitialized(projectPath)) {
586
+ error(`CodeGraph not initialized in ${projectPath}`);
587
+ process.exit(1);
588
+ }
589
+ const cg = await index_1.default.open(projectPath);
590
+ if (!cg.isGitRepository()) {
591
+ error('Not a git repository');
592
+ cg.destroy();
593
+ process.exit(1);
594
+ }
595
+ const result = cg.removeGitHooks();
596
+ if (result.success) {
597
+ success(result.message);
598
+ if (result.restoredFromBackup) {
599
+ info('Restored previous hook from backup');
600
+ }
601
+ }
602
+ else {
603
+ error(result.message);
604
+ process.exit(1);
605
+ }
606
+ cg.destroy();
607
+ }
608
+ catch (err) {
609
+ error(`Failed to remove hooks: ${err instanceof Error ? err.message : String(err)}`);
610
+ process.exit(1);
611
+ }
612
+ });
613
+ hooksCommand
614
+ .command('status')
615
+ .description('Check git hooks status')
616
+ .option('-p, --path <path>', 'Project path')
617
+ .action(async (options) => {
618
+ const projectPath = resolveProjectPath(options.path);
619
+ try {
620
+ if (!index_1.default.isInitialized(projectPath)) {
621
+ error(`CodeGraph not initialized in ${projectPath}`);
622
+ process.exit(1);
623
+ }
624
+ const cg = await index_1.default.open(projectPath);
625
+ if (!cg.isGitRepository()) {
626
+ info('Not a git repository');
627
+ cg.destroy();
628
+ return;
629
+ }
630
+ if (cg.isGitHookInstalled()) {
631
+ success('Git hook is installed');
632
+ }
633
+ else {
634
+ warn('Git hook is not installed');
635
+ info('Run "codegraph hooks install" to enable auto-sync');
636
+ }
637
+ cg.destroy();
638
+ }
639
+ catch (err) {
640
+ error(`Failed to check hooks: ${err instanceof Error ? err.message : String(err)}`);
641
+ process.exit(1);
642
+ }
643
+ });
644
+ /**
645
+ * codegraph serve
646
+ */
647
+ program
648
+ .command('serve')
649
+ .description('Start CodeGraph as an MCP server for AI assistants')
650
+ .option('-p, --path <path>', 'Project path (optional for MCP mode, uses rootUri from client)')
651
+ .option('--mcp', 'Run as MCP server (stdio transport)')
652
+ .action(async (options) => {
653
+ const projectPath = options.path ? resolveProjectPath(options.path) : undefined;
654
+ try {
655
+ if (options.mcp) {
656
+ // Start MCP server - it handles initialization lazily based on rootUri from client
657
+ const { MCPServer } = await Promise.resolve().then(() => __importStar(require('../mcp/index')));
658
+ const server = new MCPServer(projectPath);
659
+ await server.start();
660
+ // Server will run until terminated
661
+ }
662
+ else {
663
+ // Default: show info about MCP mode
664
+ console.log(chalk.bold('\nCodeGraph MCP Server\n'));
665
+ info('Use --mcp flag to start the MCP server');
666
+ console.log('\nTo use with Claude Code, add to your MCP configuration:');
667
+ console.log(chalk.dim(`
668
+ {
669
+ "mcpServers": {
670
+ "codegraph": {
671
+ "command": "codegraph",
672
+ "args": ["serve", "--mcp"]
673
+ }
674
+ }
675
+ }
676
+ `));
677
+ console.log('Available tools:');
678
+ console.log(chalk.cyan(' codegraph_search') + ' - Search for code symbols');
679
+ console.log(chalk.cyan(' codegraph_context') + ' - Build context for a task');
680
+ console.log(chalk.cyan(' codegraph_callers') + ' - Find callers of a symbol');
681
+ console.log(chalk.cyan(' codegraph_callees') + ' - Find what a symbol calls');
682
+ console.log(chalk.cyan(' codegraph_impact') + ' - Analyze impact of changes');
683
+ console.log(chalk.cyan(' codegraph_node') + ' - Get symbol details');
684
+ console.log(chalk.cyan(' codegraph_status') + ' - Get index status');
685
+ }
686
+ }
687
+ catch (err) {
688
+ error(`Failed to start server: ${err instanceof Error ? err.message : String(err)}`);
689
+ process.exit(1);
690
+ }
691
+ });
692
+ /**
693
+ * codegraph install
694
+ */
695
+ program
696
+ .command('install')
697
+ .description('Run interactive installer for Claude Code integration')
698
+ .action(async () => {
699
+ await (0, installer_1.runInstaller)();
700
+ });
701
+ // Parse and run
702
+ program.parse();
703
+ } // end main()
704
+ //# sourceMappingURL=codegraph.js.map