Add codebase indexing system (Milestone 4)
- Add project type detection (Node.js, Python, Rust, Go, generic) - Add file scanner with ignore patterns and hash tracking - Add TypeScript/JavaScript parser (exports, imports, classes, functions) - Add Python parser (imports, classes, functions, __all__) - Add relationship mapper for import dependencies - Add architecture summary generation with tech stack detection - Add incremental update support via file hash comparison - Add CLI command: cortex index [path] [--update] [--dry-run] - Add MCP tools: memory_index, memory_components
This commit is contained in:
61
src/cli/commands/index-cmd.ts
Normal file
61
src/cli/commands/index-cmd.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { Command } from 'commander';
|
||||
import chalk from 'chalk';
|
||||
import { indexProject } from '../../core/indexer';
|
||||
|
||||
export const indexCommand = new Command('index')
|
||||
.description('Index a codebase to create component nodes')
|
||||
.argument('[path]', 'Path to index', '.')
|
||||
.option('--update', 'Only update changed files (incremental)')
|
||||
.option('--dry-run', 'Preview what would be indexed without making changes')
|
||||
.option('--depth <n>', 'Maximum directory depth', '10')
|
||||
.option('--lang <language>', 'Only index specific language (ts, js, py)')
|
||||
.option('--ignore <patterns>', 'Additional ignore patterns (comma-separated)')
|
||||
.action(async (inputPath: string, opts) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
if (opts.dryRun) {
|
||||
console.log(chalk.yellow('Dry run mode - no changes will be made\n'));
|
||||
}
|
||||
|
||||
console.log(chalk.cyan(`Indexing ${inputPath}...`));
|
||||
|
||||
try {
|
||||
const result = await indexProject(inputPath, {
|
||||
update: opts.update,
|
||||
dryRun: opts.dryRun,
|
||||
maxDepth: parseInt(opts.depth),
|
||||
language: opts.lang,
|
||||
ignore: opts.ignore?.split(',').map((s: string) => s.trim()),
|
||||
});
|
||||
|
||||
const elapsed = ((Date.now() - startTime) / 1000).toFixed(2);
|
||||
|
||||
console.log();
|
||||
console.log(chalk.green(`✓ Indexed ${result.projectName} (${result.projectType})`));
|
||||
console.log();
|
||||
console.log(` Files scanned: ${result.files.length}`);
|
||||
console.log(` Components created: ${result.componentsCreated}`);
|
||||
console.log(` Components updated: ${result.componentsUpdated}`);
|
||||
console.log(` Components removed: ${result.componentsRemoved}`);
|
||||
console.log(` Relationships: ${result.relationshipsCreated}`);
|
||||
if (result.architectureNodeId) {
|
||||
console.log(` Architecture node: ${result.architectureNodeId.slice(0, 8)}`);
|
||||
}
|
||||
console.log();
|
||||
console.log(chalk.dim(`Completed in ${elapsed}s`));
|
||||
|
||||
if (opts.dryRun && result.files.length > 0) {
|
||||
console.log();
|
||||
console.log(chalk.yellow('Files that would be indexed:'));
|
||||
for (const file of result.files.slice(0, 20)) {
|
||||
console.log(` ${file}`);
|
||||
}
|
||||
if (result.files.length > 20) {
|
||||
console.log(chalk.dim(` ... and ${result.files.length - 20} more`));
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error(chalk.red(`Error: ${err.message}`));
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
@@ -16,6 +16,7 @@ import { diffCommand } from './commands/diff';
|
||||
import { restoreCommand } from './commands/restore';
|
||||
import { captureCommand, captureHookCommand, configCommand } from './commands/capture';
|
||||
import { contextCommand, contextHookCommand } from './commands/context';
|
||||
import { indexCommand } from './commands/index-cmd';
|
||||
import { closeDb } from '../core/db';
|
||||
|
||||
const program = new Command();
|
||||
@@ -44,6 +45,7 @@ program.addCommand(captureHookCommand);
|
||||
program.addCommand(contextCommand);
|
||||
program.addCommand(contextHookCommand);
|
||||
program.addCommand(configCommand);
|
||||
program.addCommand(indexCommand);
|
||||
|
||||
program.hook('postAction', () => {
|
||||
closeDb();
|
||||
|
||||
Reference in New Issue
Block a user