@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.
- package/LICENSE +21 -0
- package/README.md +641 -0
- package/dist/bin/codegraph.d.ts +20 -0
- package/dist/bin/codegraph.d.ts.map +1 -0
- package/dist/bin/codegraph.js +704 -0
- package/dist/bin/codegraph.js.map +1 -0
- package/dist/config.d.ts +51 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +291 -0
- package/dist/config.js.map +1 -0
- package/dist/context/formatter.d.ts +30 -0
- package/dist/context/formatter.d.ts.map +1 -0
- package/dist/context/formatter.js +244 -0
- package/dist/context/formatter.js.map +1 -0
- package/dist/context/index.d.ts +86 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +402 -0
- package/dist/context/index.js.map +1 -0
- package/dist/db/index.d.ts +64 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +170 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrations.d.ts +44 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +105 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/queries.d.ts +148 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +669 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/directory.d.ts +45 -0
- package/dist/directory.d.ts.map +1 -0
- package/dist/directory.js +191 -0
- package/dist/directory.js.map +1 -0
- package/dist/errors.d.ts +136 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +219 -0
- package/dist/errors.js.map +1 -0
- package/dist/extraction/grammars.d.ts +36 -0
- package/dist/extraction/grammars.d.ts.map +1 -0
- package/dist/extraction/grammars.js +181 -0
- package/dist/extraction/grammars.js.map +1 -0
- package/dist/extraction/index.d.ts +91 -0
- package/dist/extraction/index.d.ts.map +1 -0
- package/dist/extraction/index.js +493 -0
- package/dist/extraction/index.js.map +1 -0
- package/dist/extraction/tree-sitter.d.ts +176 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -0
- package/dist/extraction/tree-sitter.js +1798 -0
- package/dist/extraction/tree-sitter.js.map +1 -0
- package/dist/graph/index.d.ts +8 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +13 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/queries.d.ts +106 -0
- package/dist/graph/queries.d.ts.map +1 -0
- package/dist/graph/queries.js +355 -0
- package/dist/graph/queries.js.map +1 -0
- package/dist/graph/traversal.d.ts +127 -0
- package/dist/graph/traversal.d.ts.map +1 -0
- package/dist/graph/traversal.js +465 -0
- package/dist/graph/traversal.js.map +1 -0
- package/dist/index.d.ts +496 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +818 -0
- package/dist/index.js.map +1 -0
- package/dist/installer/banner.d.ts +40 -0
- package/dist/installer/banner.d.ts.map +1 -0
- package/dist/installer/banner.js +162 -0
- package/dist/installer/banner.js.map +1 -0
- package/dist/installer/claude-md-template.d.ts +10 -0
- package/dist/installer/claude-md-template.d.ts.map +1 -0
- package/dist/installer/claude-md-template.js +46 -0
- package/dist/installer/claude-md-template.js.map +1 -0
- package/dist/installer/config-writer.d.ts +36 -0
- package/dist/installer/config-writer.d.ts.map +1 -0
- package/dist/installer/config-writer.js +282 -0
- package/dist/installer/config-writer.js.map +1 -0
- package/dist/installer/index.d.ts +13 -0
- package/dist/installer/index.d.ts.map +1 -0
- package/dist/installer/index.js +155 -0
- package/dist/installer/index.js.map +1 -0
- package/dist/installer/prompts.d.ts +18 -0
- package/dist/installer/prompts.d.ts.map +1 -0
- package/dist/installer/prompts.js +113 -0
- package/dist/installer/prompts.js.map +1 -0
- package/dist/mcp/index.d.ts +64 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +207 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tools.d.ts +93 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +442 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/transport.d.ts +89 -0
- package/dist/mcp/transport.d.ts.map +1 -0
- package/dist/mcp/transport.js +170 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/resolution/frameworks/csharp.d.ts +8 -0
- package/dist/resolution/frameworks/csharp.d.ts.map +1 -0
- package/dist/resolution/frameworks/csharp.js +274 -0
- package/dist/resolution/frameworks/csharp.js.map +1 -0
- package/dist/resolution/frameworks/express.d.ts +8 -0
- package/dist/resolution/frameworks/express.d.ts.map +1 -0
- package/dist/resolution/frameworks/express.js +208 -0
- package/dist/resolution/frameworks/express.js.map +1 -0
- package/dist/resolution/frameworks/go.d.ts +8 -0
- package/dist/resolution/frameworks/go.d.ts.map +1 -0
- package/dist/resolution/frameworks/go.js +225 -0
- package/dist/resolution/frameworks/go.js.map +1 -0
- package/dist/resolution/frameworks/index.d.ts +33 -0
- package/dist/resolution/frameworks/index.d.ts.map +1 -0
- package/dist/resolution/frameworks/index.js +113 -0
- package/dist/resolution/frameworks/index.js.map +1 -0
- package/dist/resolution/frameworks/java.d.ts +8 -0
- package/dist/resolution/frameworks/java.d.ts.map +1 -0
- package/dist/resolution/frameworks/java.js +239 -0
- package/dist/resolution/frameworks/java.js.map +1 -0
- package/dist/resolution/frameworks/laravel.d.ts +13 -0
- package/dist/resolution/frameworks/laravel.d.ts.map +1 -0
- package/dist/resolution/frameworks/laravel.js +198 -0
- package/dist/resolution/frameworks/laravel.js.map +1 -0
- package/dist/resolution/frameworks/python.d.ts +10 -0
- package/dist/resolution/frameworks/python.d.ts.map +1 -0
- package/dist/resolution/frameworks/python.js +331 -0
- package/dist/resolution/frameworks/python.js.map +1 -0
- package/dist/resolution/frameworks/react.d.ts +8 -0
- package/dist/resolution/frameworks/react.d.ts.map +1 -0
- package/dist/resolution/frameworks/react.js +294 -0
- package/dist/resolution/frameworks/react.js.map +1 -0
- package/dist/resolution/frameworks/ruby.d.ts +8 -0
- package/dist/resolution/frameworks/ruby.d.ts.map +1 -0
- package/dist/resolution/frameworks/ruby.js +262 -0
- package/dist/resolution/frameworks/ruby.js.map +1 -0
- package/dist/resolution/frameworks/rust.d.ts +8 -0
- package/dist/resolution/frameworks/rust.d.ts.map +1 -0
- package/dist/resolution/frameworks/rust.js +222 -0
- package/dist/resolution/frameworks/rust.js.map +1 -0
- package/dist/resolution/frameworks/swift.d.ts +10 -0
- package/dist/resolution/frameworks/swift.d.ts.map +1 -0
- package/dist/resolution/frameworks/swift.js +486 -0
- package/dist/resolution/frameworks/swift.js.map +1 -0
- package/dist/resolution/import-resolver.d.ts +20 -0
- package/dist/resolution/import-resolver.d.ts.map +1 -0
- package/dist/resolution/import-resolver.js +445 -0
- package/dist/resolution/import-resolver.js.map +1 -0
- package/dist/resolution/index.d.ts +72 -0
- package/dist/resolution/index.d.ts.map +1 -0
- package/dist/resolution/index.js +301 -0
- package/dist/resolution/index.js.map +1 -0
- package/dist/resolution/name-matcher.d.ts +27 -0
- package/dist/resolution/name-matcher.d.ts.map +1 -0
- package/dist/resolution/name-matcher.js +210 -0
- package/dist/resolution/name-matcher.js.map +1 -0
- package/dist/resolution/types.d.ts +108 -0
- package/dist/resolution/types.d.ts.map +1 -0
- package/dist/resolution/types.js +8 -0
- package/dist/resolution/types.js.map +1 -0
- package/dist/sync/git-hooks.d.ts +66 -0
- package/dist/sync/git-hooks.d.ts.map +1 -0
- package/dist/sync/git-hooks.js +281 -0
- package/dist/sync/git-hooks.js.map +1 -0
- package/dist/sync/index.d.ts +13 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +18 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/types.d.ts +410 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +165 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +116 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +295 -0
- package/dist/utils.js.map +1 -0
- package/dist/vectors/embedder.d.ts +140 -0
- package/dist/vectors/embedder.d.ts.map +1 -0
- package/dist/vectors/embedder.js +336 -0
- package/dist/vectors/embedder.js.map +1 -0
- package/dist/vectors/index.d.ts +9 -0
- package/dist/vectors/index.d.ts.map +1 -0
- package/dist/vectors/index.js +20 -0
- package/dist/vectors/index.js.map +1 -0
- package/dist/vectors/manager.d.ts +119 -0
- package/dist/vectors/manager.d.ts.map +1 -0
- package/dist/vectors/manager.js +274 -0
- package/dist/vectors/manager.js.map +1 -0
- package/dist/vectors/search.d.ts +134 -0
- package/dist/vectors/search.d.ts.map +1 -0
- package/dist/vectors/search.js +409 -0
- package/dist/vectors/search.js.map +1 -0
- package/package.json +67 -0
- 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
|