2025-08-07 19:33:03 -07:00
#!/usr/bin/env node
/ * *
2025-08-14 09:42:44 -07:00
* Brainy CLI - Cleaned Up & Beautiful
* 🧠 ⚛ ️ ONE way to do everything
*
* After the Great Cleanup of 2025 :
* - 5 commands total ( was 40 + )
* - Clear , obvious naming
* - Interactive mode for beginners
2025-08-07 19:33:03 -07:00
* /
// @ts-ignore
import { program } from 'commander'
2025-08-14 09:42:44 -07:00
import { Cortex } from '../dist/cortex.js'
2025-08-07 19:33:03 -07:00
// @ts-ignore
import chalk from 'chalk'
import { readFileSync } from 'fs'
import { dirname , join } from 'path'
import { fileURLToPath } from 'url'
2025-08-10 16:25:12 -07:00
import { createInterface } from 'readline'
2025-08-07 19:33:03 -07:00
const _ _dirname = dirname ( fileURLToPath ( import . meta . url ) )
const packageJson = JSON . parse ( readFileSync ( join ( _ _dirname , '..' , 'package.json' ) , 'utf8' ) )
2025-08-14 09:42:44 -07:00
// Create single Cortex instance (the ONE orchestrator)
2025-08-07 19:33:03 -07:00
const cortex = new Cortex ( )
2025-08-14 09:42:44 -07:00
// Beautiful colors
const colors = {
primary : chalk . hex ( '#3A5F4A' ) ,
success : chalk . hex ( '#2D4A3A' ) ,
info : chalk . hex ( '#4A6B5A' ) ,
warning : chalk . hex ( '#D67441' ) ,
error : chalk . hex ( '#B85C35' )
}
2025-08-08 18:05:12 -07:00
// Helper functions
2025-08-07 19:33:03 -07:00
const exitProcess = ( code = 0 ) => {
2025-08-08 18:05:12 -07:00
setTimeout ( ( ) => process . exit ( code ) , 100 )
2025-08-07 19:33:03 -07:00
}
const wrapAction = ( fn ) => {
return async ( ... args ) => {
try {
await fn ( ... args )
exitProcess ( 0 )
} catch ( error ) {
2025-08-14 09:42:44 -07:00
console . error ( colors . error ( 'Error:' ) , error . message )
2025-08-07 19:33:03 -07:00
exitProcess ( 1 )
}
}
}
2025-08-08 18:05:12 -07:00
// ========================================
2025-08-14 09:42:44 -07:00
// MAIN PROGRAM - CLEAN & SIMPLE
2025-08-08 18:05:12 -07:00
// ========================================
2025-08-07 19:33:03 -07:00
program
2025-08-08 18:05:12 -07:00
. name ( 'brainy' )
2025-08-14 09:42:44 -07:00
. description ( '🧠⚛️ Brainy - Your AI-Powered Second Brain' )
2025-08-07 19:33:03 -07:00
. version ( packageJson . version )
2025-08-08 18:05:12 -07:00
// ========================================
2025-08-14 09:42:44 -07:00
// THE 5 COMMANDS (ONE WAY TO DO EVERYTHING)
2025-08-08 18:05:12 -07:00
// ========================================
2025-08-14 09:42:44 -07:00
// Command 1: ADD - Add data (smart by default)
2025-08-07 19:33:03 -07:00
program
. command ( 'add [data]' )
2025-08-14 09:42:44 -07:00
. description ( 'Add data to your brain (smart auto-detection)' )
. option ( '-m, --metadata <json>' , 'Metadata as JSON' )
. option ( '-i, --id <id>' , 'Custom ID' )
. option ( '--literal' , 'Skip AI processing (literal storage)' )
2025-08-08 18:05:12 -07:00
. action ( wrapAction ( async ( data , options ) => {
2025-08-14 09:42:44 -07:00
if ( ! data ) {
console . log ( colors . info ( '🧠 Interactive add mode' ) )
const rl = createInterface ( {
input : process . stdin ,
output : process . stdout
} )
data = await new Promise ( resolve => {
rl . question ( colors . primary ( 'What would you like to add? ' ) , ( answer ) => {
rl . close ( )
resolve ( answer )
} )
} )
}
2025-08-07 19:33:03 -07:00
let metadata = { }
if ( options . metadata ) {
try {
metadata = JSON . parse ( options . metadata )
} catch {
2025-08-14 09:42:44 -07:00
console . error ( colors . error ( 'Invalid JSON metadata' ) )
2025-08-07 19:33:03 -07:00
process . exit ( 1 )
}
}
if ( options . id ) {
metadata . id = options . id
}
2025-08-12 11:49:38 -07:00
2025-08-14 09:42:44 -07:00
console . log ( options . literal
? colors . info ( '🔒 Literal storage' )
: colors . success ( '🧠 Smart mode (auto-detects types)' )
)
await cortex . add ( data , metadata )
console . log ( colors . success ( '✅ Added successfully!' ) )
2025-08-12 11:49:38 -07:00
} ) )
2025-08-14 09:42:44 -07:00
// Command 2: IMPORT - Bulk/external data
2025-08-12 11:49:38 -07:00
program
2025-08-14 09:42:44 -07:00
. command ( 'import <source>' )
. description ( 'Import bulk data from files, URLs, or streams' )
. option ( '-t, --type <type>' , 'Source type (file, url, stream)' )
. option ( '-c, --chunk-size <size>' , 'Chunk size for large imports' , '1000' )
. action ( wrapAction ( async ( source , options ) => {
console . log ( colors . info ( '📥 Starting neural import...' ) )
console . log ( colors . info ( ` Source: ${ source } ` ) )
// Use the unified import system from the cleanup plan
const { NeuralImport } = await import ( '../dist/cortex/neuralImport.js' )
const importer = new NeuralImport ( )
const result = await importer . import ( source , {
chunkSize : parseInt ( options . chunkSize )
} )
2025-08-12 11:49:38 -07:00
2025-08-14 09:42:44 -07:00
console . log ( colors . success ( ` ✅ Imported ${ result . count } items ` ) )
if ( result . detectedTypes ) {
console . log ( colors . info ( '🔍 Detected types:' ) , result . detectedTypes )
}
2025-08-08 18:05:12 -07:00
} ) )
2025-08-07 19:33:03 -07:00
2025-08-14 09:42:44 -07:00
// Command 3: SEARCH - Triple-power search
2025-08-07 19:33:03 -07:00
program
. command ( 'search <query>' )
2025-08-14 09:42:44 -07:00
. description ( 'Search your brain (vector + graph + facets)' )
. option ( '-l, --limit <number>' , 'Results limit' , '10' )
. option ( '-f, --filter <json>' , 'Metadata filters' )
. option ( '-d, --depth <number>' , 'Relationship depth' , '2' )
2025-08-08 18:05:12 -07:00
. action ( wrapAction ( async ( query , options ) => {
2025-08-14 09:42:44 -07:00
console . log ( colors . info ( ` 🔍 Searching: " ${ query } " ` ) )
const searchOptions = {
limit : parseInt ( options . limit ) ,
depth : parseInt ( options . depth )
}
2025-08-07 19:33:03 -07:00
if ( options . filter ) {
try {
searchOptions . filter = JSON . parse ( options . filter )
} catch {
2025-08-14 09:42:44 -07:00
console . error ( colors . error ( 'Invalid filter JSON' ) )
2025-08-07 19:33:03 -07:00
process . exit ( 1 )
}
}
2025-08-14 09:42:44 -07:00
const results = await cortex . search ( query , searchOptions )
2025-08-12 11:49:38 -07:00
2025-08-14 09:42:44 -07:00
if ( results . length === 0 ) {
console . log ( colors . warning ( 'No results found' ) )
return
2025-08-12 18:19:38 -07:00
}
2025-08-14 09:42:44 -07:00
console . log ( colors . success ( ` ✅ Found ${ results . length } results: ` ) )
results . forEach ( ( result , i ) => {
console . log ( colors . primary ( ` \n ${ i + 1 } . ${ result . content } ` ) )
if ( result . score ) {
console . log ( colors . info ( ` Relevance: ${ ( result . score * 100 ) . toFixed ( 1 ) } % ` ) )
}
if ( result . type ) {
console . log ( colors . info ( ` Type: ${ result . type } ` ) )
}
} )
2025-08-07 19:33:03 -07:00
} ) )
2025-08-14 09:42:44 -07:00
// Command 4: STATUS - Database health & info
2025-08-07 19:33:03 -07:00
program
2025-08-14 09:42:44 -07:00
. command ( 'status' )
. description ( 'Show brain status and health' )
. option ( '-v, --verbose' , 'Detailed information' )
2025-08-07 19:33:03 -07:00
. action ( wrapAction ( async ( options ) => {
2025-08-14 09:42:44 -07:00
console . log ( colors . primary ( '🧠 Brain Status' ) )
console . log ( colors . primary ( '=' . repeat ( 50 ) ) )
2025-08-11 13:02:29 -07:00
try {
2025-08-14 09:42:44 -07:00
const { BrainyData } = await import ( '../dist/brainyData.js' )
const brainy = new BrainyData ( )
await brainy . init ( )
2025-08-09 18:27:21 -07:00
2025-08-14 09:42:44 -07:00
// Get basic stats
const stats = await brainy . getStatistics ( )
console . log ( colors . success ( '💚 Status: Healthy' ) )
console . log ( colors . info ( ` 📊 Items: ${ stats . total || 0 } ` ) )
console . log ( colors . info ( ` 🧠 Memory: ${ ( process . memoryUsage ( ) . heapUsed / 1024 / 1024 ) . toFixed ( 1 ) } MB ` ) )
2025-08-09 18:27:21 -07:00
2025-08-14 09:42:44 -07:00
if ( options . verbose ) {
console . log ( colors . info ( '\n📋 Detailed Statistics:' ) )
console . log ( JSON . stringify ( stats , null , 2 ) )
2025-08-09 18:27:21 -07:00
2025-08-14 09:42:44 -07:00
console . log ( colors . info ( '\n🔌 Active Augmentations:' ) )
const augmentations = cortex . getAllAugmentations ( )
if ( augmentations . length === 0 ) {
console . log ( colors . warning ( ' No augmentations active' ) )
2025-08-09 18:27:21 -07:00
} else {
2025-08-14 09:42:44 -07:00
augmentations . forEach ( aug => {
console . log ( colors . success ( ` ✅ ${ aug . name } ` ) )
2025-08-09 18:27:21 -07:00
} )
}
}
2025-08-14 09:42:44 -07:00
} catch ( error ) {
console . log ( colors . error ( '❌ Status: Error' ) )
console . log ( colors . error ( error . message ) )
2025-08-09 14:36:05 -07:00
}
} ) )
2025-08-14 09:42:44 -07:00
// Command 5: HELP - Interactive guidance
program
. command ( 'help [command]' )
. description ( 'Get help or enter interactive mode' )
. action ( wrapAction ( async ( command ) => {
if ( command ) {
program . help ( )
return
2025-08-11 13:02:29 -07:00
}
2025-08-14 09:42:44 -07:00
// Interactive mode for beginners
console . log ( colors . primary ( '🧠⚛️ Welcome to Brainy!' ) )
console . log ( colors . info ( 'Your AI-powered second brain' ) )
console . log ( )
2025-08-11 09:57:12 -07:00
const rl = createInterface ( {
input : process . stdin ,
output : process . stdout
} )
2025-08-14 09:42:44 -07:00
console . log ( colors . primary ( 'What would you like to do?' ) )
console . log ( colors . info ( '1. Add some data' ) )
console . log ( colors . info ( '2. Search your brain' ) )
console . log ( colors . info ( '3. Import a file' ) )
console . log ( colors . info ( '4. Check status' ) )
console . log ( colors . info ( '5. Show all commands' ) )
console . log ( )
const choice = await new Promise ( resolve => {
rl . question ( colors . primary ( 'Enter your choice (1-5): ' ) , ( answer ) => {
rl . close ( )
resolve ( answer )
} )
2025-08-11 09:57:12 -07:00
} )
2025-08-14 09:42:44 -07:00
switch ( choice ) {
case '1' :
console . log ( colors . success ( '\n🧠 Use: brainy add "your data here"' ) )
console . log ( colors . info ( 'Example: brainy add "John works at Google"' ) )
break
case '2' :
console . log ( colors . success ( '\n🔍 Use: brainy search "your query"' ) )
console . log ( colors . info ( 'Example: brainy search "Google employees"' ) )
break
case '3' :
console . log ( colors . success ( '\n📥 Use: brainy import <file-or-url>' ) )
console . log ( colors . info ( 'Example: brainy import data.txt' ) )
break
case '4' :
console . log ( colors . success ( '\n📊 Use: brainy status' ) )
console . log ( colors . info ( 'Shows your brain health and statistics' ) )
break
case '5' :
program . help ( )
break
default :
console . log ( colors . warning ( 'Invalid choice. Use "brainy --help" for all commands.' ) )
2025-08-08 18:05:12 -07:00
}
2025-08-07 19:33:03 -07:00
} ) )
2025-08-08 18:05:12 -07:00
// ========================================
2025-08-14 09:42:44 -07:00
// FALLBACK - Show interactive help if no command
2025-08-08 18:05:12 -07:00
// ========================================
2025-08-07 19:33:03 -07:00
2025-08-14 09:42:44 -07:00
// If no arguments provided, show interactive help
if ( process . argv . length === 2 ) {
program . parse ( [ 'node' , 'brainy' , 'help' ] )
} else {
program . parse ( process . argv )
2025-08-07 19:33:03 -07:00
}