#!/usr/bin/env node /** * Brainy CLI - Enterprise Neural Intelligence System * * Full TypeScript implementation with type safety and shared code */ import { Command } from 'commander' import chalk from 'chalk' import { neuralCommands } from './commands/neural.js' import { coreCommands } from './commands/core.js' import { utilityCommands } from './commands/utility.js' import { vfsCommands } from './commands/vfs.js' import { dataCommands } from './commands/data.js' import { readFileSync } from 'fs' import { fileURLToPath } from 'url' import { dirname, join } from 'path' const __dirname = dirname(fileURLToPath(import.meta.url)) const packageJson = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf8')) const version = packageJson.version // CLI Configuration const program = new Command() program .name('brainy') .description('🧠 Enterprise Neural Intelligence Database') .version(version) .option('-v, --verbose', 'Verbose output') .option('--json', 'JSON output format') .option('--pretty', 'Pretty JSON output') .option('--no-color', 'Disable colored output') // ===== Core Commands ===== program .command('add ') .description('Add text or JSON to the neural database') .option('-i, --id ', 'Specify custom ID') .option('-m, --metadata ', 'Add metadata') .option('-t, --type ', 'Specify noun type') .action(coreCommands.add) program .command('find ') .description('Simple NLP search (just like code: brain.find("query"))') .option('-k, --limit ', 'Number of results', '10') .action(coreCommands.search) program .command('search ') .description('Advanced search with Triple Intelligence™ (vector + graph + field)') .option('-k, --limit ', 'Number of results', '10') .option('--offset ', 'Skip N results (pagination)') .option('-t, --threshold ', 'Similarity threshold (0-1)', '0.7') .option('--type ', 'Filter by type(s) - comma separated') .option('--where ', 'Metadata filters (JSON)') .option('--near ', 'Find items near this ID') .option('--connected-to ', 'Connected to this entity') .option('--connected-from ', 'Connected from this entity') .option('--via ', 'Via these relationships - comma separated') .option('--explain', 'Show scoring breakdown') .option('--include-relations', 'Include entity relationships') .option('--fusion ', 'Fusion strategy (adaptive|weighted|progressive)') .option('--vector-weight ', 'Vector search weight (0-1)') .option('--graph-weight ', 'Graph search weight (0-1)') .option('--field-weight ', 'Field search weight (0-1)') .action(coreCommands.search) program .command('get ') .description('Get item by ID') .option('--with-connections', 'Include connections') .action(coreCommands.get) program .command('relate ') .description('Create a relationship between items') .option('-w, --weight ', 'Relationship weight') .option('-m, --metadata ', 'Relationship metadata') .action(coreCommands.relate) program .command('import ') .description('Import data from file') .option('-f, --format ', 'Input format (json|csv|jsonl)', 'json') .option('--batch-size ', 'Batch size for import', '100') .action(coreCommands.import) program .command('export [file]') .description('Export database') .option('-f, --format ', 'Output format (json|csv|jsonl)', 'json') .action(coreCommands.export) // ===== Neural Commands ===== program .command('similar ') .alias('sim') .description('Calculate similarity between two items') .option('--explain', 'Show detailed explanation') .option('--breakdown', 'Show similarity breakdown') .action(neuralCommands.similar) program .command('cluster') .alias('clusters') .description('Find semantic clusters in the data') .option('--algorithm ', 'Clustering algorithm (hierarchical|kmeans|dbscan)', 'hierarchical') .option('--threshold ', 'Similarity threshold', '0.7') .option('--min-size ', 'Minimum cluster size', '2') .option('--max-clusters ', 'Maximum number of clusters') .option('--near ', 'Find clusters near a query') .option('--show', 'Show visual representation') .action(neuralCommands.cluster) program .command('related ') .alias('neighbors') .description('Find semantically related items') .option('-l, --limit ', 'Number of results', '10') .option('-r, --radius ', 'Semantic radius', '0.3') .option('--with-scores', 'Include similarity scores') .option('--with-edges', 'Include connections') .action(neuralCommands.related) program .command('hierarchy ') .alias('tree') .description('Show semantic hierarchy for an item') .option('-d, --depth ', 'Hierarchy depth', '3') .option('--parents-only', 'Show only parent hierarchy') .option('--children-only', 'Show only child hierarchy') .action(neuralCommands.hierarchy) program .command('path ') .description('Find semantic path between items (v3.21.0)') .option('--steps', 'Show step-by-step path') .option('--max-hops ', 'Maximum path length', '5') .action(() => { console.log(chalk.yellow('\n⚠️ Semantic path finding coming in v3.21.0')) console.log(chalk.dim('This feature requires implementing graph traversal algorithms')) console.log(chalk.dim('Use "brainy neighbors" and "brainy hierarchy" to explore connections')) }) program .command('outliers') .alias('anomalies') .description('Detect semantic outliers') .option('-t, --threshold ', 'Outlier threshold', '0.3') .option('--explain', 'Explain why items are outliers') .action(neuralCommands.outliers) program .command('visualize') .alias('viz') .description('Generate visualization data') .option('-f, --format ', 'Output format (json|d3|graphml)', 'json') .option('--max-nodes ', 'Maximum nodes', '500') .option('--dimensions ', '2D or 3D', '2') .option('-o, --output ', 'Output file') .action(neuralCommands.visualize) // ===== VFS Commands (Subcommand Group) ===== program .command('vfs') .description('📁 Virtual File System operations') .addCommand( new Command('read') .argument('', 'File path') .description('Read file from VFS') .option('-o, --output ', 'Save to local file') .option('--encoding ', 'File encoding', 'utf-8') .action((path, options) => { vfsCommands.read(path, options) }) ) .addCommand( new Command('write') .argument('', 'File path') .description('Write file to VFS') .option('-c, --content ', 'File content') .option('-f, --file ', 'Read from local file') .option('--encoding ', 'File encoding', 'utf-8') .action((path, options) => { vfsCommands.write(path, options) }) ) .addCommand( new Command('ls') .alias('list') .argument('', 'Directory path') .description('List directory contents') .option('-l, --long', 'Long format with details') .option('-a, --all', 'Show hidden files') .action((path, options) => { vfsCommands.ls(path, options) }) ) .addCommand( new Command('stat') .argument('', 'File/directory path') .description('Get file/directory statistics') .action((path, options) => { vfsCommands.stat(path, options) }) ) .addCommand( new Command('mkdir') .argument('', 'Directory path') .description('Create directory') .option('-p, --parents', 'Create parent directories') .action((path, options) => { vfsCommands.mkdir(path, options) }) ) .addCommand( new Command('rm') .argument('', 'File/directory path') .description('Remove file or directory') .option('-r, --recursive', 'Remove recursively') .option('-f, --force', 'Force removal') .action((path, options) => { vfsCommands.rm(path, options) }) ) .addCommand( new Command('search') .argument('', 'Search query') .description('Search files by content') .option('--path ', 'Search within path') .option('-l, --limit ', 'Max results', '10') .option('--type ', 'File type filter') .action((query, options) => { vfsCommands.search(query, options) }) ) .addCommand( new Command('similar') .argument('', 'File path') .description('Find similar files') .option('-l, --limit ', 'Max results', '10') .option('-t, --threshold ', 'Similarity threshold', '0.7') .action((path, options) => { vfsCommands.similar(path, options) }) ) .addCommand( new Command('tree') .argument('', 'Directory path') .description('Show directory tree') .option('-d, --depth ', 'Max depth', '3') .action((path, options) => { vfsCommands.tree(path, options) }) ) // ===== VFS Commands (Backward Compatibility - Deprecated) ===== program .command('vfs-read ') .description('[DEPRECATED] Use: brainy vfs read ') .option('-o, --output ', 'Save to local file') .option('--encoding ', 'File encoding', 'utf-8') .action((path, options) => { console.log(chalk.yellow('⚠️ Command "vfs-read" is deprecated. Use: brainy vfs read')) vfsCommands.read(path, options) }) program .command('vfs-write ') .description('[DEPRECATED] Use: brainy vfs write ') .option('-c, --content ', 'File content') .option('-f, --file ', 'Read from local file') .option('--encoding ', 'File encoding', 'utf-8') .action((path, options) => { console.log(chalk.yellow('⚠️ Command "vfs-write" is deprecated. Use: brainy vfs write')) vfsCommands.write(path, options) }) program .command('vfs-ls ') .alias('vfs-list') .description('[DEPRECATED] Use: brainy vfs ls ') .option('-l, --long', 'Long format with details') .option('-a, --all', 'Show hidden files') .action((path, options) => { console.log(chalk.yellow('⚠️ Command "vfs-ls" is deprecated. Use: brainy vfs ls')) vfsCommands.ls(path, options) }) program .command('vfs-stat ') .description('[DEPRECATED] Use: brainy vfs stat ') .action((path, options) => { console.log(chalk.yellow('⚠️ Command "vfs-stat" is deprecated. Use: brainy vfs stat')) vfsCommands.stat(path, options) }) program .command('vfs-mkdir ') .description('[DEPRECATED] Use: brainy vfs mkdir ') .option('-p, --parents', 'Create parent directories') .action((path, options) => { console.log(chalk.yellow('⚠️ Command "vfs-mkdir" is deprecated. Use: brainy vfs mkdir')) vfsCommands.mkdir(path, options) }) program .command('vfs-rm ') .description('[DEPRECATED] Use: brainy vfs rm ') .option('-r, --recursive', 'Remove recursively') .option('-f, --force', 'Force removal') .action((path, options) => { console.log(chalk.yellow('⚠️ Command "vfs-rm" is deprecated. Use: brainy vfs rm')) vfsCommands.rm(path, options) }) program .command('vfs-search ') .description('[DEPRECATED] Use: brainy vfs search ') .option('--path ', 'Search within path') .option('-l, --limit ', 'Max results', '10') .option('--type ', 'File type filter') .action((query, options) => { console.log(chalk.yellow('⚠️ Command "vfs-search" is deprecated. Use: brainy vfs search')) vfsCommands.search(query, options) }) program .command('vfs-similar ') .description('[DEPRECATED] Use: brainy vfs similar ') .option('-l, --limit ', 'Max results', '10') .option('-t, --threshold ', 'Similarity threshold', '0.7') .action((path, options) => { console.log(chalk.yellow('⚠️ Command "vfs-similar" is deprecated. Use: brainy vfs similar')) vfsCommands.similar(path, options) }) program .command('vfs-tree ') .description('[DEPRECATED] Use: brainy vfs tree ') .option('-d, --depth ', 'Max depth', '3') .action((path, options) => { console.log(chalk.yellow('⚠️ Command "vfs-tree" is deprecated. Use: brainy vfs tree')) vfsCommands.tree(path, options) }) // ===== Data Management Commands ===== program .command('backup ') .description('Create database backup') .option('--compress', 'Compress backup') .action(dataCommands.backup) program .command('restore ') .description('Restore from backup') .option('--merge', 'Merge with existing data (default: replace)') .action(dataCommands.restore) program .command('data-stats') .description('Show detailed database statistics') .action(dataCommands.stats) // ===== Utility Commands ===== program .command('stats') .alias('statistics') .description('Show quick database statistics') .option('--by-service', 'Group by service') .option('--detailed', 'Show detailed stats') .action(utilityCommands.stats) program .command('clean') .description('Clean and optimize database') .option('--remove-orphans', 'Remove orphaned items') .option('--rebuild-index', 'Rebuild search index') .action(utilityCommands.clean) program .command('benchmark') .alias('bench') .description('Run performance benchmarks') .option('--operations ', 'Operations to benchmark', 'all') .option('--iterations ', 'Number of iterations', '100') .action(utilityCommands.benchmark) // ===== Interactive Mode ===== program .command('interactive') .alias('i') .description('Start interactive REPL mode') .action(async () => { const { startInteractiveMode } = await import('./interactive.js') await startInteractiveMode() }) // ===== Error Handling ===== program.exitOverride() try { await program.parseAsync(process.argv) } catch (error: any) { if (error.code === 'commander.helpDisplayed') { process.exit(0) } console.error(chalk.red('Error:'), error.message) if (program.opts().verbose) { console.error(chalk.gray(error.stack)) } process.exit(1) } // Handle no command if (!process.argv.slice(2).length) { program.outputHelp() }