@soulcraft/brainy 0.62.3 → 1.0.0-rc.1

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 (36) hide show
  1. package/README.md +3 -3
  2. package/bin/brainy.js +903 -1153
  3. package/dist/augmentationPipeline.d.ts +60 -0
  4. package/dist/augmentationPipeline.js +94 -0
  5. package/dist/augmentations/{cortexSense.d.ts → neuralImport.d.ts} +14 -11
  6. package/dist/augmentations/{cortexSense.js → neuralImport.js} +14 -11
  7. package/dist/brainyData.d.ts +199 -18
  8. package/dist/brainyData.js +601 -18
  9. package/dist/chat/BrainyChat.d.ts +113 -0
  10. package/dist/chat/BrainyChat.js +368 -0
  11. package/dist/chat/ChatCLI.d.ts +61 -0
  12. package/dist/chat/ChatCLI.js +351 -0
  13. package/dist/connectors/interfaces/IConnector.d.ts +3 -3
  14. package/dist/connectors/interfaces/IConnector.js +1 -1
  15. package/dist/cortex/neuralImport.js +1 -3
  16. package/dist/index.d.ts +4 -6
  17. package/dist/index.js +6 -7
  18. package/dist/pipeline.d.ts +15 -271
  19. package/dist/pipeline.js +25 -586
  20. package/dist/shared/default-augmentations.d.ts +3 -3
  21. package/dist/shared/default-augmentations.js +10 -10
  22. package/package.json +3 -1
  23. package/dist/chat/brainyChat.d.ts +0 -42
  24. package/dist/chat/brainyChat.js +0 -340
  25. package/dist/cortex/cliWrapper.d.ts +0 -32
  26. package/dist/cortex/cliWrapper.js +0 -209
  27. package/dist/cortex/cortex-legacy.d.ts +0 -264
  28. package/dist/cortex/cortex-legacy.js +0 -2463
  29. package/dist/cortex/cortex.d.ts +0 -264
  30. package/dist/cortex/cortex.js +0 -2463
  31. package/dist/cortex/serviceIntegration.d.ts +0 -156
  32. package/dist/cortex/serviceIntegration.js +0 -384
  33. package/dist/sequentialPipeline.d.ts +0 -113
  34. package/dist/sequentialPipeline.js +0 -417
  35. package/dist/utils/modelLoader.d.ts +0 -12
  36. package/dist/utils/modelLoader.js +0 -88
package/bin/brainy.js CHANGED
@@ -1,13 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * Brainy CLI - Redesigned for Better UX
5
- * Direct commands + Augmentation system
4
+ * Brainy CLI - Cleaned Up & Beautiful
5
+ * 🧠⚛️ ONE way to do everything
6
+ *
7
+ * After the Great Cleanup of 2025:
8
+ * - 5 commands total (was 40+)
9
+ * - Clear, obvious naming
10
+ * - Interactive mode for beginners
6
11
  */
7
12
 
8
13
  // @ts-ignore
9
14
  import { program } from 'commander'
10
- import { Cortex } from '../dist/cortex/cortex.js'
15
+ import { BrainyData } from '../dist/brainyData.js'
11
16
  // @ts-ignore
12
17
  import chalk from 'chalk'
13
18
  import { readFileSync } from 'fs'
@@ -15,13 +20,27 @@ import { dirname, join } from 'path'
15
20
  import { fileURLToPath } from 'url'
16
21
  import { createInterface } from 'readline'
17
22
 
18
- // Use native fetch (available in Node.js 18+)
19
-
20
23
  const __dirname = dirname(fileURLToPath(import.meta.url))
21
24
  const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'))
22
25
 
23
- // Create Cortex instance
24
- const cortex = new Cortex()
26
+ // Create single BrainyData instance (the ONE data orchestrator)
27
+ let brainy = null
28
+ const getBrainy = async () => {
29
+ if (!brainy) {
30
+ brainy = new BrainyData()
31
+ await brainy.init()
32
+ }
33
+ return brainy
34
+ }
35
+
36
+ // Beautiful colors
37
+ const colors = {
38
+ primary: chalk.hex('#3A5F4A'),
39
+ success: chalk.hex('#2D4A3A'),
40
+ info: chalk.hex('#4A6B5A'),
41
+ warning: chalk.hex('#D67441'),
42
+ error: chalk.hex('#B85C35')
43
+ }
25
44
 
26
45
  // Helper functions
27
46
  const exitProcess = (code = 0) => {
@@ -34,1289 +53,1020 @@ const wrapAction = (fn) => {
34
53
  await fn(...args)
35
54
  exitProcess(0)
36
55
  } catch (error) {
37
- console.error(chalk.red('Error:'), error.message)
56
+ console.error(colors.error('Error:'), error.message)
38
57
  exitProcess(1)
39
58
  }
40
59
  }
41
60
  }
42
61
 
43
- const wrapInteractive = (fn) => {
44
- return async (...args) => {
45
- try {
46
- await fn(...args)
47
- exitProcess(0)
48
- } catch (error) {
49
- console.error(chalk.red('Error:'), error.message)
50
- exitProcess(1)
62
+ // AI Response Generation with multiple model support
63
+ async function generateAIResponse(message, brainy, options) {
64
+ const model = options.model || 'local'
65
+
66
+ // Get relevant context from user's data
67
+ const contextResults = await brainy.search(message, 5, {
68
+ includeContent: true,
69
+ scoreThreshold: 0.3
70
+ })
71
+
72
+ const context = contextResults.map(r => r.content).join('\n')
73
+ const prompt = `Based on the following context from the user's data, answer their question:
74
+
75
+ Context:
76
+ ${context}
77
+
78
+ Question: ${message}
79
+
80
+ Answer:`
81
+
82
+ switch (model) {
83
+ case 'local':
84
+ case 'ollama':
85
+ return await callOllamaModel(prompt, options)
86
+
87
+ case 'openai':
88
+ case 'gpt-3.5-turbo':
89
+ case 'gpt-4':
90
+ return await callOpenAI(prompt, options)
91
+
92
+ case 'claude':
93
+ case 'claude-3':
94
+ return await callClaude(prompt, options)
95
+
96
+ default:
97
+ return await callOllamaModel(prompt, options)
98
+ }
99
+ }
100
+
101
+ // Ollama (local) integration
102
+ async function callOllamaModel(prompt, options) {
103
+ const baseUrl = options.baseUrl || 'http://localhost:11434'
104
+ const model = options.model === 'local' ? 'llama2' : options.model
105
+
106
+ try {
107
+ const response = await fetch(`${baseUrl}/api/generate`, {
108
+ method: 'POST',
109
+ headers: { 'Content-Type': 'application/json' },
110
+ body: JSON.stringify({
111
+ model: model,
112
+ prompt: prompt,
113
+ stream: false
114
+ })
115
+ })
116
+
117
+ if (!response.ok) {
118
+ throw new Error(`Ollama error: ${response.statusText}. Make sure Ollama is running: ollama serve`)
119
+ }
120
+
121
+ const data = await response.json()
122
+ return data.response || 'No response from local model'
123
+
124
+ } catch (error) {
125
+ throw new Error(`Local model error: ${error.message}. Try: ollama run llama2`)
126
+ }
127
+ }
128
+
129
+ // OpenAI integration
130
+ async function callOpenAI(prompt, options) {
131
+ if (!options.apiKey) {
132
+ throw new Error('OpenAI API key required. Use --api-key <key> or set OPENAI_API_KEY environment variable')
133
+ }
134
+
135
+ const model = options.model === 'openai' ? 'gpt-3.5-turbo' : options.model
136
+
137
+ try {
138
+ const response = await fetch('https://api.openai.com/v1/chat/completions', {
139
+ method: 'POST',
140
+ headers: {
141
+ 'Authorization': `Bearer ${options.apiKey}`,
142
+ 'Content-Type': 'application/json'
143
+ },
144
+ body: JSON.stringify({
145
+ model: model,
146
+ messages: [{ role: 'user', content: prompt }],
147
+ max_tokens: 500
148
+ })
149
+ })
150
+
151
+ if (!response.ok) {
152
+ throw new Error(`OpenAI error: ${response.statusText}`)
153
+ }
154
+
155
+ const data = await response.json()
156
+ return data.choices[0]?.message?.content || 'No response from OpenAI'
157
+
158
+ } catch (error) {
159
+ throw new Error(`OpenAI error: ${error.message}`)
160
+ }
161
+ }
162
+
163
+ // Claude integration
164
+ async function callClaude(prompt, options) {
165
+ if (!options.apiKey) {
166
+ throw new Error('Anthropic API key required. Use --api-key <key> or set ANTHROPIC_API_KEY environment variable')
167
+ }
168
+
169
+ try {
170
+ const response = await fetch('https://api.anthropic.com/v1/messages', {
171
+ method: 'POST',
172
+ headers: {
173
+ 'x-api-key': options.apiKey,
174
+ 'Content-Type': 'application/json',
175
+ 'anthropic-version': '2023-06-01'
176
+ },
177
+ body: JSON.stringify({
178
+ model: 'claude-3-haiku-20240307',
179
+ max_tokens: 500,
180
+ messages: [{ role: 'user', content: prompt }]
181
+ })
182
+ })
183
+
184
+ if (!response.ok) {
185
+ throw new Error(`Claude error: ${response.statusText}`)
51
186
  }
187
+
188
+ const data = await response.json()
189
+ return data.content[0]?.text || 'No response from Claude'
190
+
191
+ } catch (error) {
192
+ throw new Error(`Claude error: ${error.message}`)
52
193
  }
53
194
  }
54
195
 
55
196
  // ========================================
56
- // MAIN PROGRAM SETUP
197
+ // MAIN PROGRAM - CLEAN & SIMPLE
57
198
  // ========================================
58
199
 
59
200
  program
60
201
  .name('brainy')
61
- .description('🧠 Brainy - Multi-Dimensional AI Database')
202
+ .description('🧠⚛️ Brainy - Your AI-Powered Second Brain')
62
203
  .version(packageJson.version)
63
204
 
64
205
  // ========================================
65
- // CORE DATABASE COMMANDS (Direct Access)
206
+ // THE 5 COMMANDS (ONE WAY TO DO EVERYTHING)
66
207
  // ========================================
67
208
 
209
+ // Command 0: INIT - Initialize brainy (essential setup)
68
210
  program
69
211
  .command('init')
70
- .description('Initialize Brainy in your project')
71
- .option('-s, --storage <type>', 'Storage type (filesystem, s3, r2, gcs, memory)')
72
- .option('-e, --encryption', 'Enable encryption for secrets')
212
+ .description('Initialize Brainy in current directory')
213
+ .option('-s, --storage <type>', 'Storage type (filesystem, memory, s3, r2, gcs)')
214
+ .option('-e, --encryption', 'Enable encryption for sensitive data')
215
+ .option('--s3-bucket <bucket>', 'S3 bucket name')
216
+ .option('--s3-region <region>', 'S3 region')
217
+ .option('--access-key <key>', 'Storage access key')
218
+ .option('--secret-key <key>', 'Storage secret key')
73
219
  .action(wrapAction(async (options) => {
74
- await cortex.init(options)
220
+ console.log(colors.primary('🧠 Initializing Brainy'))
221
+ console.log()
222
+
223
+ const { BrainyData } = await import('../dist/brainyData.js')
224
+
225
+ const config = {
226
+ storage: options.storage || 'filesystem',
227
+ encryption: options.encryption || false
228
+ }
229
+
230
+ // Storage-specific configuration
231
+ if (options.storage === 's3' || options.storage === 'r2' || options.storage === 'gcs') {
232
+ if (!options.accessKey || !options.secretKey) {
233
+ console.log(colors.warning('⚠️ Cloud storage requires access credentials'))
234
+ console.log(colors.info('Use: --access-key <key> --secret-key <secret>'))
235
+ console.log(colors.info('Or set environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY'))
236
+ process.exit(1)
237
+ }
238
+
239
+ config.storageOptions = {
240
+ bucket: options.s3Bucket,
241
+ region: options.s3Region || 'us-east-1',
242
+ accessKeyId: options.accessKey,
243
+ secretAccessKey: options.secretKey
244
+ }
245
+ }
246
+
247
+ try {
248
+ const brainy = new BrainyData(config)
249
+ await brainy.init()
250
+
251
+ console.log(colors.success('✅ Brainy initialized successfully!'))
252
+ console.log(colors.info(`📁 Storage: ${config.storage}`))
253
+ console.log(colors.info(`🔒 Encryption: ${config.encryption ? 'Enabled' : 'Disabled'}`))
254
+
255
+ if (config.encryption) {
256
+ console.log(colors.warning('🔐 Encryption enabled - keep your keys secure!'))
257
+ }
258
+
259
+ console.log()
260
+ console.log(colors.success('🚀 Ready to go! Try:'))
261
+ console.log(colors.info(' brainy add "Hello, World!"'))
262
+ console.log(colors.info(' brainy search "hello"'))
263
+
264
+ } catch (error) {
265
+ console.log(colors.error('❌ Initialization failed:'))
266
+ console.log(colors.error(error.message))
267
+ process.exit(1)
268
+ }
75
269
  }))
76
270
 
271
+ // Command 1: ADD - Add data (smart by default)
77
272
  program
78
273
  .command('add [data]')
79
- .description('Add data across multiple dimensions (vector, graph, facets)')
80
- .option('-m, --metadata <json>', 'Metadata facets as JSON')
81
- .option('-i, --id <id>', 'Custom ID')
274
+ .description('Add data to your brain (smart auto-detection)')
275
+ .option('-m, --metadata <json>', 'Metadata as JSON')
276
+ .option('-i, --id <id>', 'Custom ID')
277
+ .option('--literal', 'Skip AI processing (literal storage)')
278
+ .option('--encrypt', 'Encrypt this data (for sensitive information)')
82
279
  .action(wrapAction(async (data, options) => {
280
+ if (!data) {
281
+ console.log(colors.info('🧠 Interactive add mode'))
282
+ const rl = createInterface({
283
+ input: process.stdin,
284
+ output: process.stdout
285
+ })
286
+
287
+ data = await new Promise(resolve => {
288
+ rl.question(colors.primary('What would you like to add? '), (answer) => {
289
+ rl.close()
290
+ resolve(answer)
291
+ })
292
+ })
293
+ }
294
+
83
295
  let metadata = {}
84
296
  if (options.metadata) {
85
297
  try {
86
298
  metadata = JSON.parse(options.metadata)
87
299
  } catch {
88
- console.error(chalk.red('Invalid JSON metadata'))
300
+ console.error(colors.error('Invalid JSON metadata'))
89
301
  process.exit(1)
90
302
  }
91
303
  }
92
304
  if (options.id) {
93
305
  metadata.id = options.id
94
306
  }
95
- await cortex.add(data, metadata)
96
- }))
97
-
98
- program
99
- .command('search <query>')
100
- .description('Multi-dimensional search across vector, graph, and facets')
101
- .option('-l, --limit <number>', 'Number of results', '10')
102
- .option('-f, --filter <json>', 'Filter by metadata facets')
103
- .option('-v, --verbs <types>', 'Include related data (comma-separated)')
104
- .option('-d, --depth <number>', 'Relationship depth', '1')
105
- .action(wrapAction(async (query, options) => {
106
- const searchOptions = { limit: parseInt(options.limit) }
307
+ if (options.encrypt) {
308
+ metadata.encrypted = true
309
+ }
107
310
 
108
- if (options.filter) {
109
- try {
110
- searchOptions.filter = JSON.parse(options.filter)
111
- } catch {
112
- console.error(chalk.red('Invalid filter JSON'))
113
- process.exit(1)
114
- }
311
+ console.log(options.literal
312
+ ? colors.info('🔒 Literal storage')
313
+ : colors.success('🧠 Smart mode (auto-detects types)')
314
+ )
315
+
316
+ if (options.encrypt) {
317
+ console.log(colors.warning('🔐 Encrypting sensitive data...'))
115
318
  }
116
319
 
117
- if (options.verbs) {
118
- searchOptions.verbs = options.verbs.split(',').map(v => v.trim())
119
- searchOptions.depth = parseInt(options.depth)
320
+ const brainyInstance = await getBrainy()
321
+
322
+ // Handle encryption at data level if requested
323
+ let processedData = data
324
+ if (options.encrypt) {
325
+ processedData = await brainyInstance.encryptData(data)
326
+ metadata.encrypted = true
120
327
  }
121
328
 
122
- await cortex.search(query, searchOptions)
123
- }))
124
-
125
- program
126
- .command('chat [question]')
127
- .description('AI-powered chat with multi-dimensional context')
128
- .option('-l, --llm <model>', 'LLM model to use')
129
- .action(wrapInteractive(async (question, options) => {
130
- await cortex.chat(question)
131
- }))
132
-
133
- program
134
- .command('stats')
135
- .description('Show database statistics and insights')
136
- .option('-d, --detailed', 'Show detailed statistics')
137
- .action(wrapAction(async (options) => {
138
- await cortex.stats(options.detailed)
139
- }))
140
-
141
- program
142
- .command('health')
143
- .description('Check system health')
144
- .option('--auto-fix', 'Automatically apply safe repairs')
145
- .action(wrapAction(async (options) => {
146
- await cortex.health(options)
147
- }))
148
-
149
- program
150
- .command('find')
151
- .description('Advanced intelligent search (interactive)')
152
- .action(wrapInteractive(async () => {
153
- await cortex.advancedSearch()
154
- }))
155
-
156
- program
157
- .command('explore [nodeId]')
158
- .description('Explore data relationships interactively')
159
- .action(wrapInteractive(async (nodeId) => {
160
- await cortex.explore(nodeId)
161
- }))
162
-
163
- program
164
- .command('backup')
165
- .description('Create database backup')
166
- .option('-c, --compress', 'Compress backup')
167
- .option('-o, --output <file>', 'Output file')
168
- .action(wrapAction(async (options) => {
169
- await cortex.backup(options)
170
- }))
171
-
172
- program
173
- .command('restore <file>')
174
- .description('Restore from backup')
175
- .action(wrapInteractive(async (file) => {
176
- await cortex.restore(file)
329
+ await brainyInstance.add(processedData, metadata, {
330
+ process: options.literal ? 'literal' : 'auto'
331
+ })
332
+ console.log(colors.success('✅ Added successfully!'))
177
333
  }))
178
334
 
179
- // ========================================
180
- // BRAIN CLOUD INTEGRATION
181
- // ========================================
182
-
335
+ // Command 2: CHAT - Talk to your data with AI
183
336
  program
184
- .command('connect')
185
- .description('Connect to Brain Cloud for AI memory')
186
- .action(wrapInteractive(async () => {
187
- console.log(chalk.cyan('\n🧠 Brain Cloud Setup'))
188
- console.log(chalk.gray(''.repeat(40)))
337
+ .command('chat [message]')
338
+ .description('AI chat with your brain data (supports local & cloud models)')
339
+ .option('-s, --session <id>', 'Use specific chat session')
340
+ .option('-n, --new', 'Start a new session')
341
+ .option('-l, --list', 'List all chat sessions')
342
+ .option('-h, --history [limit]', 'Show conversation history (default: 10)')
343
+ .option('--search <query>', 'Search all conversations')
344
+ .option('-m, --model <model>', 'LLM model (local/openai/claude/ollama)', 'local')
345
+ .option('--api-key <key>', 'API key for cloud models')
346
+ .option('--base-url <url>', 'Base URL for local models (default: http://localhost:11434)')
347
+ .action(wrapAction(async (message, options) => {
348
+ const { BrainyData } = await import('../dist/brainyData.js')
349
+ const { BrainyChat } = await import('../dist/chat/BrainyChat.js')
189
350
 
190
- try {
191
- // Detect customer ID
192
- const customerId = await detectCustomerId()
193
-
194
- if (customerId) {
195
- console.log(chalk.green(`✅ Found Brain Cloud: ${customerId}`))
196
- console.log('\n🔧 Setting up AI memory:')
197
- console.log(chalk.yellow(' • Update configuration'))
198
- console.log(chalk.yellow(' • Add memory instructions'))
199
- console.log(chalk.yellow(' • Enable cross-session memory'))
200
-
201
- console.log(chalk.cyan('\n🚀 Configuring...'))
202
- await setupBrainCloudMemory(customerId)
203
- console.log(chalk.green('\n✅ AI memory connected!'))
204
- console.log(chalk.cyan('Restart Claude Code to activate memory.'))
351
+ console.log(colors.primary('🧠💬 Brainy Chat - AI-Powered Conversation with Your Data'))
352
+ console.log(colors.info('Talk to your brain using your data as context'))
353
+ console.log()
354
+
355
+ // Initialize brainy and chat
356
+ const brainy = new BrainyData()
357
+ await brainy.init()
358
+ const chat = new BrainyChat(brainy)
359
+
360
+ // Handle different options
361
+ if (options.list) {
362
+ console.log(colors.primary('📋 Chat Sessions'))
363
+ const sessions = await chat.getSessions(20)
364
+ if (sessions.length === 0) {
365
+ console.log(colors.warning('No chat sessions found. Start chatting to create your first session!'))
205
366
  } else {
206
- console.log(chalk.yellow('No Brain Cloud found. Setting up:'))
207
- console.log('\n1. Visit: ' + chalk.cyan('https://soulcraft.com/brain-cloud'))
208
- console.log('2. Get your Early Access license key')
209
- console.log('3. Run ' + chalk.green('brainy cloud setup') + ' for auto-configuration')
367
+ sessions.forEach((session, i) => {
368
+ console.log(colors.success(`${i + 1}. ${session.id}`))
369
+ if (session.title) console.log(colors.info(` Title: ${session.title}`))
370
+ console.log(colors.info(` Messages: ${session.messageCount}`))
371
+ console.log(colors.info(` Last active: ${session.lastMessageAt.toLocaleDateString()}`))
372
+ })
210
373
  }
211
- } catch (error) {
212
- console.log(chalk.red('❌ Setup failed:'), error.message)
213
- }
214
- }))
215
-
216
- // Moved to brainy cloud setup command below for better separation
217
-
218
- // ========================================
219
- // BRAIN CLOUD COMMANDS (Premium Features)
220
- // ========================================
221
-
222
- const cloud = program
223
- .command('cloud')
224
- .description('Brain Cloud premium features and management')
225
-
226
- cloud
227
- .command('setup')
228
- .description('🚀 Auto-setup Brain Cloud (provisions cloud instance + configures locally)')
229
- .option('--email <email>', 'Your email address')
230
- .action(wrapInteractive(async (options) => {
231
- console.log(chalk.cyan('🧠☁️ Brain Cloud Auto-Setup'))
232
- console.log(chalk.gray('═'.repeat(50)))
233
- console.log(chalk.yellow('Perfect for non-coders! One-click setup.\n'))
234
-
235
- try {
236
- // Step 1: Validate license
237
- await validateLicense()
238
-
239
- // Step 2: Check if Brainy is installed
240
- await ensureBrainyInstalled()
241
-
242
- // Step 3: Provision cloud instance
243
- const instance = await provisionCloudInstance(options.email)
244
-
245
- // Step 4: Configure local Brainy
246
- await configureBrainy(instance)
247
-
248
- // Step 5: Install Brain Cloud package
249
- await installBrainCloudPackage()
250
-
251
- // Step 6: Test connection
252
- await testConnection(instance)
253
-
254
- console.log('\n✅ Setup Complete!')
255
- console.log(chalk.gray('═'.repeat(30)))
256
- console.log('\nYour Brain Cloud instance is ready:')
257
- console.log(`📱 Dashboard: ${chalk.cyan(instance.endpoints.dashboard)}`)
258
- console.log(`🔗 API: ${chalk.gray(instance.endpoints.api)}`)
259
- console.log('\n🚀 What\'s next?')
260
- console.log('• Your AI now has persistent memory across all conversations')
261
- console.log('• All devices sync automatically to your cloud instance')
262
- console.log('• Agents coordinate seamlessly through handoffs')
263
- console.log('\n💡 Try asking Claude: "Remember that I prefer TypeScript"')
264
- console.log(' Then in a new conversation: "What do you know about my preferences?"')
265
-
266
- } catch (error) {
267
- console.error('\n❌ Setup failed:', error.message)
268
- console.log('\n🆘 Need help? Contact support@soulcraft.com')
269
- }
270
- }))
271
-
272
- cloud
273
- .command('connect [id]')
274
- .description('Connect to existing Brain Cloud instance')
275
- .action(wrapInteractive(async (id) => {
276
- if (id) {
277
- console.log(chalk.green(`✅ Connecting to Brain Cloud instance: ${id}`))
278
- // Connect to specific instance
279
- } else {
280
- // Show connection instructions
281
- console.log(chalk.cyan('\n🔗 Brain Cloud Connection'))
282
- console.log(chalk.gray('━'.repeat(40)))
283
- console.log('\nOptions:')
284
- console.log('1. ' + chalk.green('brainy cloud setup') + ' - Auto-setup with provisioning')
285
- console.log('2. ' + chalk.green('brainy cloud connect <id>') + ' - Connect to existing instance')
286
- console.log('\nGet started: ' + chalk.cyan('https://soulcraft.com/brain-cloud'))
374
+ return
287
375
  }
288
- }))
289
-
290
- cloud
291
- .command('status [id]')
292
- .description('Check Brain Cloud instance status')
293
- .action(wrapInteractive(async (id) => {
294
- // Implementation moved from old cloud command
295
- console.log('Checking Brain Cloud status...')
296
- }))
297
-
298
- cloud
299
- .command('dashboard [id]')
300
- .description('Open Brain Cloud dashboard')
301
- .action(wrapInteractive(async (id) => {
302
- const dashboardUrl = id
303
- ? `https://brainy-${id}.soulcraft-brain.workers.dev/dashboard`
304
- : 'https://app.soulcraft.com'
305
-
306
- console.log(chalk.cyan(`\n🌐 Opening Brain Cloud Dashboard: ${dashboardUrl}`))
307
376
 
308
- try {
309
- const { exec } = await import('child_process')
310
- const { promisify } = await import('util')
311
- const execAsync = promisify(exec)
312
-
313
- const command = process.platform === 'win32' ? 'start' :
314
- process.platform === 'darwin' ? 'open' : 'xdg-open'
315
-
316
- await execAsync(`${command} "${dashboardUrl}"`)
317
- console.log(chalk.green('✅ Dashboard opened!'))
318
- } catch (error) {
319
- console.log(chalk.yellow('💡 Copy the URL above to open in your browser'))
377
+ if (options.search) {
378
+ console.log(colors.primary(`🔍 Searching conversations for: "${options.search}"`))
379
+ const results = await chat.searchMessages(options.search, { limit: 10 })
380
+ if (results.length === 0) {
381
+ console.log(colors.warning('No messages found'))
382
+ } else {
383
+ results.forEach((msg, i) => {
384
+ console.log(colors.success(`\n${i + 1}. [${msg.sessionId}] ${colors.info(msg.speaker)}:`))
385
+ console.log(` ${msg.content.substring(0, 200)}${msg.content.length > 200 ? '...' : ''}`)
386
+ })
387
+ }
388
+ return
320
389
  }
321
- }))
322
-
323
- // Legacy cloud command (for backward compatibility)
324
- program
325
- .command('cloud-legacy [action]')
326
- .description('Legacy Brain Cloud connection (deprecated - use "brainy cloud")')
327
- .option('--connect <id>', 'Connect to existing Brain Cloud instance')
328
- .option('--export <id>', 'Export all data from Brain Cloud instance')
329
- .option('--status <id>', 'Check status of Brain Cloud instance')
330
- .option('--dashboard <id>', 'Open dashboard for Brain Cloud instance')
331
- .option('--migrate', 'Migrate between local and cloud')
332
- .action(wrapInteractive(async (action, options) => {
333
- console.log(chalk.yellow('⚠️ Deprecated: Use "brainy cloud" commands instead'))
334
- console.log(chalk.cyan('Examples:'))
335
- console.log(' brainy cloud setup')
336
- console.log(' brainy cloud connect <id>')
337
- console.log(' brainy cloud dashboard')
338
- console.log('')
339
- // For now, show connection instructions
340
- console.log(chalk.cyan('\n⚛️ BRAIN CLOUD - AI Memory That Never Forgets'))
341
- console.log(chalk.gray('━'.repeat(50)))
342
390
 
343
- if (options.connect) {
344
- console.log(chalk.green(`✅ Connecting to Brain Cloud instance: ${options.connect}`))
345
-
346
- try {
347
- // Test connection to Brain Cloud worker
348
- const healthUrl = `https://api.soulcraft.com/brain-cloud/health`
349
- const response = await fetch(healthUrl, {
350
- headers: { 'x-customer-id': options.connect }
391
+ if (options.history) {
392
+ const limit = parseInt(options.history) || 10
393
+ console.log(colors.primary(`📜 Recent Chat History (${limit} messages)`))
394
+ const history = await chat.getHistory(limit)
395
+ if (history.length === 0) {
396
+ console.log(colors.warning('No chat history found'))
397
+ } else {
398
+ history.forEach(msg => {
399
+ const speaker = msg.speaker === 'user' ? colors.success('You') : colors.info('AI')
400
+ console.log(`${speaker}: ${msg.content}`)
401
+ console.log(colors.info(` ${msg.timestamp.toLocaleString()}`))
402
+ console.log()
351
403
  })
352
-
353
- if (response.ok) {
354
- const data = await response.json()
355
- console.log(chalk.green(`🧠 ${data.status}`))
356
- console.log(chalk.cyan(`💫 Instance: ${data.customerId}`))
357
- console.log(chalk.gray(`⏰ Connected at: ${new Date(data.timestamp).toLocaleString()}`))
358
-
359
- // Test memories endpoint
360
- const memoriesResponse = await fetch(`https://api.soulcraft.com/brain-cloud/memories`, {
361
- headers: { 'x-customer-id': options.connect }
362
- })
363
-
364
- if (memoriesResponse.ok) {
365
- const memoriesData = await memoriesResponse.json()
366
- console.log(chalk.yellow(`\n${memoriesData.message}`))
367
- console.log(chalk.gray('📊 Your atomic memories:'))
368
- memoriesData.memories.forEach(memory => {
369
- const time = new Date(memory.created).toLocaleString()
370
- console.log(chalk.gray(` • ${memory.content} (${time})`))
371
- })
372
- }
373
-
374
- } else {
375
- console.log(chalk.red('❌ Could not connect to Brain Cloud'))
376
- console.log(chalk.yellow('💡 Make sure you have an active instance'))
377
- console.log('\nSign up at: ' + chalk.cyan('https://app.soulcraft.com'))
378
- }
379
- } catch (error) {
380
- console.log(chalk.red('❌ Connection failed:'), error.message)
381
- console.log('\nSign up at: ' + chalk.cyan('https://app.soulcraft.com'))
382
404
  }
383
- } else if (options.export) {
384
- console.log(chalk.green(`📦 Exporting data from Brain Cloud instance: ${options.export}`))
405
+ return
406
+ }
407
+
408
+ // Start interactive chat or process single message
409
+ if (!message) {
410
+ console.log(colors.success('🎯 Interactive mode - type messages or "exit" to quit'))
411
+ console.log(colors.info(`Model: ${options.model}`))
412
+ console.log()
385
413
 
386
- try {
387
- const response = await fetch(`https://api.soulcraft.com/brain-cloud/export`, {
388
- headers: { 'x-customer-id': options.export }
389
- })
390
-
391
- if (response.ok) {
392
- const data = await response.json()
393
- const filename = `brainy-export-${options.export}-${Date.now()}.json`
394
-
395
- // Write to file
396
- const fs = await import('fs/promises')
397
- await fs.writeFile(filename, JSON.stringify(data, null, 2))
398
-
399
- console.log(chalk.green(`✅ Data exported to: ${filename}`))
400
- console.log(chalk.gray(`📊 Exported ${data.memories?.length || 0} memories`))
401
- } else {
402
- console.log(chalk.red('❌ Export failed - instance not found'))
403
- }
404
- } catch (error) {
405
- console.log(chalk.red('❌ Export error:'), error.message)
414
+ // Auto-discover previous session
415
+ const session = options.new ? null : await chat.initialize()
416
+ if (session) {
417
+ console.log(colors.success(`📋 Resumed session: ${session.id}`))
418
+ console.log()
419
+ } else {
420
+ const newSession = await chat.startNewSession()
421
+ console.log(colors.success(`🆕 Started new session: ${newSession.id}`))
422
+ console.log()
406
423
  }
407
- } else if (options.status) {
408
- console.log(chalk.green(`🔍 Checking status of Brain Cloud instance: ${options.status}`))
409
424
 
410
- try {
411
- const response = await fetch(`https://api.soulcraft.com/brain-cloud/health`, {
412
- headers: { 'x-customer-id': options.status }
413
- })
425
+ // Interactive chat loop
426
+ const rl = createInterface({
427
+ input: process.stdin,
428
+ output: process.stdout,
429
+ prompt: colors.primary('You: ')
430
+ })
431
+
432
+ rl.prompt()
433
+
434
+ rl.on('line', async (input) => {
435
+ if (input.trim().toLowerCase() === 'exit') {
436
+ console.log(colors.success('👋 Chat session saved to your brain!'))
437
+ rl.close()
438
+ return
439
+ }
414
440
 
415
- if (response.ok) {
416
- const data = await response.json()
417
- console.log(chalk.green(`✅ Instance Status: Active`))
418
- console.log(chalk.cyan(`🧠 ${data.status}`))
419
- console.log(chalk.gray(`⏰ Last check: ${new Date(data.timestamp).toLocaleString()}`))
441
+ if (input.trim()) {
442
+ // Store user message
443
+ await chat.addMessage(input.trim(), 'user')
420
444
 
421
- // Get memory count
422
- const memoriesResponse = await fetch(`https://api.soulcraft.com/brain-cloud/memories`, {
423
- headers: { 'x-customer-id': options.status }
424
- })
425
-
426
- if (memoriesResponse.ok) {
427
- const memoriesData = await memoriesResponse.json()
428
- console.log(chalk.yellow(`📊 Total memories: ${memoriesData.count}`))
445
+ // Generate AI response
446
+ try {
447
+ const response = await generateAIResponse(input.trim(), brainy, options)
448
+ console.log(colors.info('AI: ') + response)
449
+
450
+ // Store AI response
451
+ await chat.addMessage(response, 'assistant', { model: options.model })
452
+ console.log()
453
+ } catch (error) {
454
+ console.log(colors.error('AI Error: ') + error.message)
455
+ console.log(colors.warning('💡 Tip: Try setting --model local or providing --api-key'))
456
+ console.log()
429
457
  }
430
- } else {
431
- console.log(chalk.red('❌ Instance not found or inactive'))
432
458
  }
433
- } catch (error) {
434
- console.log(chalk.red('❌ Status check failed:'), error.message)
435
- }
436
- } else if (options.dashboard) {
437
- console.log(chalk.green(`🌐 Opening dashboard for Brain Cloud instance: ${options.dashboard}`))
459
+
460
+ rl.prompt()
461
+ })
462
+
463
+ rl.on('close', () => {
464
+ exitProcess(0)
465
+ })
438
466
 
439
- const dashboardUrl = `https://app.soulcraft.com/dashboard.html?customer_id=${options.dashboard}`
440
- console.log(chalk.cyan(`\n🔗 Dashboard URL: ${dashboardUrl}`))
441
- console.log(chalk.gray('Opening in your default browser...'))
467
+ } else {
468
+ // Single message mode
469
+ console.log(colors.success('You: ') + message)
442
470
 
443
471
  try {
444
- const { exec } = await import('child_process')
445
- const { promisify } = await import('util')
446
- const execAsync = promisify(exec)
472
+ const response = await generateAIResponse(message, brainy, options)
473
+ console.log(colors.info('AI: ') + response)
447
474
 
448
- // Cross-platform browser opening
449
- const command = process.platform === 'win32' ? 'start' :
450
- process.platform === 'darwin' ? 'open' : 'xdg-open'
475
+ // Store conversation
476
+ await chat.addMessage(message, 'user')
477
+ await chat.addMessage(response, 'assistant', { model: options.model })
451
478
 
452
- await execAsync(`${command} "${dashboardUrl}"`)
453
- console.log(chalk.green('✅ Dashboard opened!'))
454
479
  } catch (error) {
455
- console.log(chalk.yellow('💡 Copy the URL above to open in your browser'))
480
+ console.log(colors.error('Error: ') + error.message)
481
+ console.log(colors.info('💡 Try: brainy chat --model local or provide --api-key'))
456
482
  }
457
- } else {
458
- console.log(chalk.yellow('📡 Brain Cloud Setup'))
459
- console.log('\n1. Sign up at: ' + chalk.cyan('https://app.soulcraft.com'))
460
- console.log('2. Get your customer ID')
461
- console.log('3. Connect with: ' + chalk.green('brainy cloud --connect YOUR_ID'))
462
- console.log('\nBenefits:')
463
- console.log(' • ' + chalk.green('Never lose AI context again'))
464
- console.log(' • ' + chalk.green('Sync across all devices'))
465
- console.log(' • ' + chalk.green('Unlimited memory storage'))
466
- console.log(' • ' + chalk.green('$19/month or free trial'))
467
483
  }
468
484
  }))
469
485
 
470
- // ========================================
471
- // AUGMENTATION MANAGEMENT (Direct Commands)
472
- // ========================================
473
-
474
- const augment = program
475
- .command('augment')
476
- .description('Manage brain augmentations')
486
+ // Command 3: IMPORT - Bulk/external data
487
+ program
488
+ .command('import <source>')
489
+ .description('Import bulk data from files, URLs, or streams')
490
+ .option('-t, --type <type>', 'Source type (file, url, stream)')
491
+ .option('-c, --chunk-size <size>', 'Chunk size for large imports', '1000')
492
+ .action(wrapAction(async (source, options) => {
493
+ console.log(colors.info('📥 Starting neural import...'))
494
+ console.log(colors.info(`Source: ${source}`))
495
+
496
+ // Use the unified import system from the cleanup plan
497
+ const { NeuralImport } = await import('../dist/cortex/neuralImport.js')
498
+ const importer = new NeuralImport()
499
+
500
+ const result = await importer.import(source, {
501
+ chunkSize: parseInt(options.chunkSize)
502
+ })
503
+
504
+ console.log(colors.success(`✅ Imported ${result.count} items`))
505
+ if (result.detectedTypes) {
506
+ console.log(colors.info('🔍 Detected types:'), result.detectedTypes)
507
+ }
508
+ }))
477
509
 
478
- augment
479
- .command('list')
480
- .description('List available and active augmentations')
481
- .action(wrapAction(async () => {
482
- console.log(chalk.green(' Active (Built-in):'))
483
- console.log(' neural-import')
484
- console.log(' basic-storage')
485
- console.log('')
510
+ // Command 3: SEARCH - Triple-power search
511
+ program
512
+ .command('search <query>')
513
+ .description('Search your brain (vector + graph + facets)')
514
+ .option('-l, --limit <number>', 'Results limit', '10')
515
+ .option('-f, --filter <json>', 'Metadata filters (see "brainy fields" for available fields)')
516
+ .option('-d, --depth <number>', 'Relationship depth', '2')
517
+ .option('--fields', 'Show available filter fields and exit')
518
+ .action(wrapAction(async (query, options) => {
486
519
 
487
- // Check for Brain Cloud
488
- try {
489
- await import('@soulcraft/brain-cloud')
490
- const hasLicense = process.env.BRAINY_LICENSE_KEY
520
+ // Handle --fields option
521
+ if (options.fields) {
522
+ console.log(colors.primary('🔍 Available Filter Fields'))
523
+ console.log(colors.primary('=' .repeat(30)))
491
524
 
492
- if (hasLicense) {
493
- console.log(chalk.cyan('✅ Active (Premium):'))
494
- console.log(' • ai-memory')
495
- console.log(' • agent-coordinator')
496
- console.log('')
497
- }
498
- } catch {}
499
-
500
- // Fetch from catalog API
501
- try {
502
- const response = await fetch('http://localhost:3001/api/catalog/cli')
503
- if (response.ok) {
504
- const catalog = await response.json()
525
+ try {
526
+ const { BrainyData } = await import('../dist/brainyData.js')
527
+ const brainy = new BrainyData()
528
+ await brainy.init()
505
529
 
506
- // Show available augmentations
507
- const available = catalog.augmentations.filter(aug => aug.status === 'available')
508
- if (available.length > 0) {
509
- console.log(chalk.cyan('🌟 Available (Brain Cloud):'))
510
- available.forEach(aug => {
511
- const popular = aug.popular ? chalk.yellow(' ⭐ Popular') : ''
512
- console.log(` • ${aug.id} - ${aug.description}${popular}`)
530
+ const filterFields = await brainy.getFilterFields()
531
+ if (filterFields.length > 0) {
532
+ console.log(colors.success('Available fields for --filter option:'))
533
+ filterFields.forEach(field => {
534
+ console.log(colors.info(` ${field}`))
513
535
  })
514
- console.log('')
536
+ console.log()
537
+ console.log(colors.primary('Usage Examples:'))
538
+ console.log(colors.info(` brainy search "query" --filter '{"type":"person"}'`))
539
+ console.log(colors.info(` brainy search "query" --filter '{"category":"work","status":"active"}'`))
540
+ } else {
541
+ console.log(colors.warning('No indexed fields available yet.'))
542
+ console.log(colors.info('Add some data with metadata to see available fields.'))
515
543
  }
516
544
 
517
- // Show coming soon
518
- const comingSoon = catalog.augmentations.filter(aug => aug.status === 'coming-soon')
519
- if (comingSoon.length > 0) {
520
- console.log(chalk.dim('📦 Coming Soon:'))
521
- comingSoon.forEach(aug => {
522
- const eta = aug.eta ? ` (${aug.eta})` : ''
523
- console.log(chalk.dim(` • ${aug.id} - ${aug.description}${eta}`))
524
- })
525
- console.log('')
526
- }
527
- } else {
528
- throw new Error('API unavailable')
545
+ } catch (error) {
546
+ console.log(colors.error(`Error: ${error.message}`))
529
547
  }
530
- } catch (error) {
531
- // Fallback to static list if API is unavailable
532
- console.log(chalk.cyan('🌟 Available (Brain Cloud):'))
533
- console.log(' • ai-memory - ' + chalk.yellow('⭐ Popular') + ' - Persistent AI memory')
534
- console.log(' • agent-coordinator - ' + chalk.yellow('⭐ Popular') + ' - Multi-agent handoffs')
535
- console.log(' • notion-sync - Enterprise connector')
536
- console.log('')
548
+ return
537
549
  }
550
+ console.log(colors.info(`🔍 Searching: "${query}"`))
538
551
 
539
- console.log(chalk.dim('🚀 Join Early Access: https://soulcraft.com/brain-cloud'))
540
- console.log(chalk.dim('🌐 Authenticate: brainy cloud auth'))
541
- }))
542
-
543
- augment
544
- .command('activate')
545
- .description('Activate Brain Cloud with license key')
546
- .action(wrapAction(async () => {
547
- const rl = createInterface({
548
- input: process.stdin,
549
- output: process.stdout
550
- })
551
-
552
- console.log(chalk.cyan('☁️ Brain Cloud Activation (Optional Premium)'))
553
- console.log('')
554
- console.log(chalk.yellow('Note: Brainy core is 100% free and fully functional!'))
555
- console.log('Brain Cloud adds optional team & sync features.')
556
- console.log('')
557
- console.log('Get Brain Cloud at: ' + chalk.green('app.soulcraft.com'))
558
- console.log('(14-day free trial available)')
559
- console.log('')
552
+ const searchOptions = {
553
+ limit: parseInt(options.limit),
554
+ depth: parseInt(options.depth)
555
+ }
560
556
 
561
- rl.question('License key: ', async (key) => {
562
- if (key.startsWith('lic_')) {
563
- // Save to config
564
- const fs = await import('fs/promises')
565
- const os = await import('os')
566
- const configPath = `${os.homedir()}/.brainy`
567
-
568
- await fs.mkdir(configPath, { recursive: true })
569
- await fs.writeFile(`${configPath}/license`, key)
570
-
571
- console.log(chalk.green('✅ License saved!'))
572
- console.log('')
573
- console.log('// Brain Cloud is NOT an npm package!')
574
- console.log('// Augmentations auto-load based on your subscription')
575
- console.log('')
576
- console.log('Next steps:')
577
- console.log(chalk.cyan(' brainy cloud auth'))
578
- console.log(chalk.gray(' # Your augmentations will auto-load'))
579
- } else {
580
- console.log(chalk.red('Invalid license key'))
581
- }
582
- rl.close()
583
- })
584
- }))
585
-
586
- augment
587
- .command('info <name>')
588
- .description('Get info about an augmentation')
589
- .action(wrapAction(async (name) => {
590
- const augmentations = {
591
- 'ai-memory': {
592
- name: 'AI Memory',
593
- description: 'Persistent memory across all AI sessions',
594
- category: 'Memory',
595
- tier: 'Premium',
596
- popular: true,
597
- example: `
598
- // AI Memory auto-loads after 'brainy cloud auth' - no imports needed!
599
-
600
- const cortex = new Cortex()
601
- cortex.register(new AIMemory())
602
-
603
- // Now your AI remembers everything
604
- await brain.add("User prefers dark mode")
605
- // This persists across sessions automatically`
606
- },
607
- 'agent-coordinator': {
608
- name: 'Agent Coordinator',
609
- description: 'Multi-agent handoffs and orchestration',
610
- category: 'Coordination',
611
- tier: 'Premium',
612
- popular: true
613
- },
614
- 'notion-sync': {
615
- name: 'Notion Sync',
616
- description: 'Bidirectional Notion database sync',
617
- category: 'Enterprise',
618
- tier: 'Premium'
557
+ if (options.filter) {
558
+ try {
559
+ searchOptions.filter = JSON.parse(options.filter)
560
+ } catch {
561
+ console.error(colors.error('Invalid filter JSON'))
562
+ process.exit(1)
619
563
  }
620
564
  }
621
565
 
622
- const aug = augmentations[name]
623
- if (aug) {
624
- console.log(chalk.cyan(`📦 ${aug.name}`) + (aug.popular ? chalk.yellow(' ⭐ Popular') : ''))
625
- console.log('')
626
- console.log(`Category: ${aug.category}`)
627
- console.log(`Tier: ${aug.tier}`)
628
- console.log(`Description: ${aug.description}`)
629
- if (aug.example) {
630
- console.log('')
631
- console.log('Example:')
632
- console.log(chalk.gray(aug.example))
633
- }
634
- } else {
635
- console.log(chalk.red(`Unknown augmentation: ${name}`))
566
+ const brainyInstance = await getBrainy()
567
+ const results = await brainyInstance.search(query, searchOptions.limit || 10, searchOptions)
568
+
569
+ if (results.length === 0) {
570
+ console.log(colors.warning('No results found'))
571
+ return
636
572
  }
637
- }))
638
-
639
- program
640
- .command('install <augmentation>')
641
- .description('Install augmentation (legacy - use augment activate)')
642
- .option('-m, --mode <type>', 'Installation mode (free|premium)', 'free')
643
- .option('-c, --config <json>', 'Configuration as JSON')
644
- .action(wrapAction(async (augmentation, options) => {
645
- console.log(chalk.yellow('Note: Use "brainy augment activate" for Brain Cloud'))
646
573
 
647
- if (augmentation === 'brain-jar') {
648
- await cortex.brainJarInstall(options.mode)
649
- } else {
650
- // Generic augmentation install
651
- let config = {}
652
- if (options.config) {
653
- try {
654
- config = JSON.parse(options.config)
655
- } catch {
656
- console.error(chalk.red('Invalid JSON configuration'))
657
- process.exit(1)
658
- }
574
+ console.log(colors.success(`✅ Found ${results.length} results:`))
575
+ results.forEach((result, i) => {
576
+ console.log(colors.primary(`\n${i + 1}. ${result.content}`))
577
+ if (result.score) {
578
+ console.log(colors.info(` Relevance: ${(result.score * 100).toFixed(1)}%`))
659
579
  }
660
- await cortex.addAugmentation(augmentation, undefined, config)
661
- }
580
+ if (result.type) {
581
+ console.log(colors.info(` Type: ${result.type}`))
582
+ }
583
+ })
662
584
  }))
663
585
 
586
+ // Command 4: UPDATE - Update existing data
664
587
  program
665
- .command('run <augmentation>')
666
- .description('Run augmentation')
667
- .option('-c, --config <json>', 'Runtime configuration as JSON')
668
- .action(wrapAction(async (augmentation, options) => {
669
- if (augmentation === 'brain-jar') {
670
- await cortex.brainJarStart(options)
671
- } else {
672
- // Generic augmentation execution
673
- const inputData = options.config ? JSON.parse(options.config) : { run: true }
674
- await cortex.executePipelineStep(augmentation, inputData)
588
+ .command('update <id>')
589
+ .description('Update existing data with new content or metadata')
590
+ .option('-d, --data <data>', 'New data content')
591
+ .option('-m, --metadata <json>', 'New metadata as JSON')
592
+ .option('--no-merge', 'Replace metadata instead of merging')
593
+ .option('--no-reindex', 'Skip reindexing (faster but less accurate search)')
594
+ .option('--cascade', 'Update related verbs')
595
+ .action(wrapAction(async (id, options) => {
596
+ console.log(colors.info(`🔄 Updating: "${id}"`))
597
+
598
+ if (!options.data && !options.metadata) {
599
+ console.error(colors.error('Error: Must provide --data or --metadata'))
600
+ process.exit(1)
675
601
  }
676
- }))
677
-
678
- program
679
- .command('status [augmentation]')
680
- .description('Show augmentation status')
681
- .action(wrapAction(async (augmentation) => {
682
- if (augmentation === 'brain-jar') {
683
- await cortex.brainJarStatus()
684
- } else if (augmentation) {
685
- // Show specific augmentation status
686
- await cortex.listAugmentations()
687
- } else {
688
- // Show all augmentation status
689
- await cortex.listAugmentations()
602
+
603
+ let metadata = undefined
604
+ if (options.metadata) {
605
+ try {
606
+ metadata = JSON.parse(options.metadata)
607
+ } catch {
608
+ console.error(colors.error('Invalid JSON metadata'))
609
+ process.exit(1)
610
+ }
690
611
  }
691
- }))
692
-
693
- program
694
- .command('stop [augmentation]')
695
- .description('Stop augmentation')
696
- .action(wrapAction(async (augmentation) => {
697
- if (augmentation === 'brain-jar') {
698
- await cortex.brainJarStop()
612
+
613
+ const brainyInstance = await getBrainy()
614
+
615
+ const success = await brainyInstance.update(id, options.data, metadata, {
616
+ merge: options.merge !== false, // Default true unless --no-merge
617
+ reindex: options.reindex !== false, // Default true unless --no-reindex
618
+ cascade: options.cascade || false
619
+ })
620
+
621
+ if (success) {
622
+ console.log(colors.success('✅ Updated successfully!'))
623
+ if (options.cascade) {
624
+ console.log(colors.info('📎 Related verbs updated'))
625
+ }
699
626
  } else {
700
- console.log(chalk.yellow('Stop functionality for generic augmentations not yet implemented'))
627
+ console.log(colors.error(' Update failed'))
701
628
  }
702
629
  }))
703
630
 
631
+ // Command 5: DELETE - Remove data (soft delete by default)
704
632
  program
705
- .command('list')
706
- .description('List installed augmentations')
707
- .option('-a, --available', 'Show available augmentations')
708
- .action(wrapAction(async (options) => {
709
- if (options.available) {
710
- console.log(chalk.green('✅ Built-in (Free):'))
711
- console.log(' neural-import - AI-powered data understanding')
712
- console.log(' • basic-storage - Local persistence')
713
- console.log('')
714
- console.log(chalk.cyan('🌟 Premium (Brain Cloud):'))
715
- console.log(' • ai-memory - ' + chalk.yellow('⭐ Most Popular') + ' - AI that remembers')
716
- console.log(' • agent-coordinator - ' + chalk.yellow('⭐ Most Popular') + ' - Multi-agent orchestration')
717
- console.log(' • notion-sync - Enterprise connector')
718
- console.log(' • More at app.soulcraft.com/augmentations')
719
- console.log('')
720
- console.log(chalk.dim('Sign up: app.soulcraft.com (14-day free trial)'))
721
- console.log(chalk.dim('Authenticate: brainy cloud auth'))
633
+ .command('delete <id>')
634
+ .description('Delete data (soft delete by default, preserves indexes)')
635
+ .option('--hard', 'Permanent deletion (removes from indexes)')
636
+ .option('--cascade', 'Delete related verbs')
637
+ .option('--force', 'Force delete even if has relationships')
638
+ .action(wrapAction(async (id, options) => {
639
+ console.log(colors.info(`🗑️ Deleting: "${id}"`))
640
+
641
+ if (options.hard) {
642
+ console.log(colors.warning('⚠️ Hard delete - data will be permanently removed'))
722
643
  } else {
723
- await cortex.listAugmentations()
644
+ console.log(colors.info('🔒 Soft delete - data marked as deleted but preserved'))
724
645
  }
725
- }))
726
-
727
-
728
- // ========================================
729
- // BRAIN JAR SPECIFIC COMMANDS (Rich UX)
730
- // ========================================
731
-
732
- const brainJar = program.command('brain-jar')
733
- .description('AI coordination and collaboration')
734
-
735
- brainJar
736
- .command('install')
737
- .description('Install Brain Jar coordination')
738
- .option('-m, --mode <type>', 'Installation mode (free|premium)', 'free')
739
- .action(wrapAction(async (options) => {
740
- await cortex.brainJarInstall(options.mode)
741
- }))
742
-
743
- brainJar
744
- .command('start')
745
- .description('Start Brain Jar coordination')
746
- .option('-s, --server <url>', 'Custom server URL')
747
- .option('-n, --name <name>', 'Agent name')
748
- .option('-r, --role <role>', 'Agent role')
749
- .action(wrapAction(async (options) => {
750
- await cortex.brainJarStart(options)
751
- }))
752
-
753
- brainJar
754
- .command('dashboard')
755
- .description('Open Brain Jar dashboard')
756
- .option('-o, --open', 'Auto-open in browser', true)
757
- .action(wrapAction(async (options) => {
758
- await cortex.brainJarDashboard(options.open)
759
- }))
760
-
761
- brainJar
762
- .command('status')
763
- .description('Show Brain Jar status')
764
- .action(wrapAction(async () => {
765
- await cortex.brainJarStatus()
766
- }))
767
-
768
- brainJar
769
- .command('agents')
770
- .description('List connected agents')
771
- .action(wrapAction(async () => {
772
- await cortex.brainJarAgents()
773
- }))
774
-
775
- brainJar
776
- .command('message <text>')
777
- .description('Send message to coordination channel')
778
- .action(wrapAction(async (text) => {
779
- await cortex.brainJarMessage(text)
780
- }))
781
-
782
- brainJar
783
- .command('search <query>')
784
- .description('Search coordination history')
785
- .option('-l, --limit <number>', 'Number of results', '10')
786
- .action(wrapAction(async (query, options) => {
787
- await cortex.brainJarSearch(query, parseInt(options.limit))
788
- }))
789
-
790
- // ========================================
791
- // CONFIGURATION COMMANDS
792
- // ========================================
793
-
794
- const config = program.command('config')
795
- .description('Manage configuration')
796
-
797
- config
798
- .command('set <key> <value>')
799
- .description('Set configuration value')
800
- .option('-e, --encrypt', 'Encrypt this value')
801
- .action(wrapAction(async (key, value, options) => {
802
- await cortex.configSet(key, value, options)
803
- }))
804
-
805
- config
806
- .command('get <key>')
807
- .description('Get configuration value')
808
- .action(wrapAction(async (key) => {
809
- const value = await cortex.configGet(key)
810
- if (value) {
811
- console.log(chalk.green(`${key}: ${value}`))
812
- } else {
813
- console.log(chalk.yellow(`Key not found: ${key}`))
646
+
647
+ const brainyInstance = await getBrainy()
648
+
649
+ try {
650
+ const success = await brainyInstance.delete(id, {
651
+ soft: !options.hard, // Soft delete unless --hard specified
652
+ cascade: options.cascade || false,
653
+ force: options.force || false
654
+ })
655
+
656
+ if (success) {
657
+ console.log(colors.success('✅ Deleted successfully!'))
658
+ if (options.cascade) {
659
+ console.log(colors.info('📎 Related verbs also deleted'))
660
+ }
661
+ } else {
662
+ console.log(colors.error('❌ Delete failed'))
663
+ }
664
+ } catch (error) {
665
+ console.error(colors.error(`❌ Delete failed: ${error.message}`))
666
+ if (error.message.includes('has relationships')) {
667
+ console.log(colors.info('💡 Try: --cascade to delete relationships or --force to ignore them'))
668
+ }
814
669
  }
815
670
  }))
816
671
 
817
- config
818
- .command('list')
819
- .description('List all configuration')
820
- .action(wrapAction(async () => {
821
- await cortex.configList()
822
- }))
823
-
824
- // ========================================
825
- // LEGACY CORTEX COMMANDS (Backward Compatibility)
826
- // ========================================
827
-
828
- const cortexCmd = program.command('cortex')
829
- .description('Legacy Cortex commands (deprecated - use direct commands)')
830
-
831
- cortexCmd
832
- .command('chat [question]')
833
- .description('Chat with your data')
834
- .action(wrapInteractive(async (question) => {
835
- console.log(chalk.yellow('⚠️ Deprecated: Use "brainy chat" instead'))
836
- await cortex.chat(question)
837
- }))
838
-
839
- cortexCmd
840
- .command('add [data]')
841
- .description('Add data')
842
- .action(wrapAction(async (data) => {
843
- console.log(chalk.yellow('⚠️ Deprecated: Use "brainy add" instead'))
844
- await cortex.add(data, {})
845
- }))
846
-
847
- // ========================================
848
- // INTERACTIVE SHELL
849
- // ========================================
850
-
672
+ // Command 6: STATUS - Database health & info
851
673
  program
852
- .command('shell')
853
- .description('Interactive Brainy shell')
854
- .action(wrapInteractive(async () => {
855
- console.log(chalk.cyan('🧠 Brainy Interactive Shell'))
856
- console.log(chalk.dim('Type "help" for commands, "exit" to quit\n'))
857
- await cortex.chat()
858
- }))
859
-
860
- // ========================================
861
- // PARSE AND HANDLE
862
- // ========================================
863
-
864
- program.parse(process.argv)
865
-
866
- // Show help if no command
867
- if (!process.argv.slice(2).length) {
868
- console.log(chalk.cyan('🧠 Brainy - Multi-Dimensional AI Database'))
869
- console.log(chalk.gray('Vector similarity, graph relationships, metadata facets, and AI context.\n'))
870
-
871
- console.log(chalk.bold('Quick Start:'))
872
- console.log(' brainy init # Initialize project')
873
- console.log(' brainy add "some data" # Add multi-dimensional data')
874
- console.log(' brainy search "query" # Search across all dimensions')
875
- console.log(' brainy chat # AI chat with full context')
876
- console.log('')
877
- console.log(chalk.bold('Brain Cloud (Premium):'))
878
- console.log(chalk.green(' brainy cloud setup # Auto-setup with provisioning'))
879
- console.log(' brainy cloud connect <id> # Connect to existing instance')
880
- console.log(' brainy cloud dashboard # Open Brain Cloud dashboard')
881
- console.log('')
882
- console.log(chalk.bold('AI Coordination:'))
883
- console.log(' brainy install brain-jar # Install coordination')
884
- console.log(' brainy brain-jar start # Start coordination')
885
- console.log('')
886
- console.log(chalk.dim('Learn more: https://soulcraft.com'))
887
- console.log('')
888
- program.outputHelp()
889
- }
890
-
891
- // ========================================
892
- // BRAIN CLOUD MEMORY SETUP FUNCTIONS
893
- // ========================================
894
-
895
- async function detectCustomerId() {
896
- try {
897
- // Method 1: Check for existing brainy config
898
- const { readFile } = await import('fs/promises')
899
- const { join } = await import('path')
674
+ .command('status')
675
+ .description('Show brain status and comprehensive statistics')
676
+ .option('-v, --verbose', 'Show raw JSON statistics')
677
+ .option('-s, --simple', 'Show only basic info')
678
+ .action(wrapAction(async (options) => {
679
+ console.log(colors.primary('🧠 Brain Status & Statistics'))
680
+ console.log(colors.primary('=' .repeat(50)))
900
681
 
901
682
  try {
902
- const configPath = join(process.cwd(), 'brainy-config.json')
903
- const config = JSON.parse(await readFile(configPath, 'utf8'))
904
- if (config.brainCloudCustomerId) {
905
- return config.brainCloudCustomerId
683
+ const { BrainyData } = await import('../dist/brainyData.js')
684
+ const brainy = new BrainyData()
685
+ await brainy.init()
686
+
687
+ // Get comprehensive stats
688
+ const stats = await brainy.getStatistics()
689
+ const memUsage = process.memoryUsage()
690
+
691
+ // Basic Health Status
692
+ console.log(colors.success('💚 Status: Healthy'))
693
+ console.log(colors.info(`🚀 Version: ${packageJson.version}`))
694
+ console.log()
695
+
696
+ if (options.simple) {
697
+ console.log(colors.info(`📊 Total Items: ${stats.total || 0}`))
698
+ console.log(colors.info(`🧠 Memory: ${(memUsage.heapUsed / 1024 / 1024).toFixed(1)} MB`))
699
+ return
906
700
  }
907
- } catch {}
908
-
909
- // Method 2: Check CLAUDE.md for existing customer ID
910
- try {
911
- const claudePath = join(process.cwd(), 'CLAUDE.md')
912
- const claudeContent = await readFile(claudePath, 'utf8')
913
- const match = claudeContent.match(/customer.*?([a-z0-9-]+)/i)
914
- if (match) return match[1]
915
- } catch {}
916
-
917
- // Method 3: Test common demo IDs
918
- const testIds = ['demo-test-auto', 'demo-test123']
919
- for (const id of testIds) {
920
- try {
921
- const response = await fetch(`https://api.soulcraft.com/brain-cloud/health`, {
922
- headers: { 'x-customer-id': id }
701
+
702
+ // Core Statistics
703
+ console.log(colors.primary('📊 Core Database Statistics'))
704
+ console.log(colors.info(` Total Items: ${colors.success(stats.total || 0)}`))
705
+ console.log(colors.info(` Nouns: ${colors.success(stats.nounCount || 0)}`))
706
+ console.log(colors.info(` Verbs (Relationships): ${colors.success(stats.verbCount || 0)}`))
707
+ console.log(colors.info(` Metadata Records: ${colors.success(stats.metadataCount || 0)}`))
708
+ console.log()
709
+
710
+ // Per-Service Breakdown (if available)
711
+ if (stats.serviceBreakdown && Object.keys(stats.serviceBreakdown).length > 0) {
712
+ console.log(colors.primary('🔧 Per-Service Breakdown'))
713
+ Object.entries(stats.serviceBreakdown).forEach(([service, serviceStats]) => {
714
+ console.log(colors.info(` ${colors.success(service)}:`))
715
+ console.log(colors.info(` Nouns: ${serviceStats.nounCount}`))
716
+ console.log(colors.info(` Verbs: ${serviceStats.verbCount}`))
717
+ console.log(colors.info(` Metadata: ${serviceStats.metadataCount}`))
923
718
  })
924
- if (response.ok) {
925
- return id
719
+ console.log()
720
+ }
721
+
722
+ // Storage Information
723
+ if (stats.storage) {
724
+ console.log(colors.primary('💾 Storage Information'))
725
+ console.log(colors.info(` Type: ${colors.success(stats.storage.type || 'Unknown')}`))
726
+ if (stats.storage.size) {
727
+ const sizeInMB = (stats.storage.size / 1024 / 1024).toFixed(2)
728
+ console.log(colors.info(` Size: ${colors.success(sizeInMB)} MB`))
926
729
  }
927
- } catch {}
928
- }
929
-
930
- return null
931
- } catch (error) {
932
- return null
933
- }
934
- }
935
-
936
- async function setupBrainCloudMemory(customerId) {
937
- const { writeFile, mkdir } = await import('fs/promises')
938
- const { join } = await import('path')
939
-
940
- console.log(chalk.gray('📝 Setting up AI memory configuration...'))
941
-
942
- // 1. Create/update .claude directory and MCP config
943
- try {
944
- await mkdir('.claude', { recursive: true })
945
-
946
- const mcpConfig = {
947
- mcpServers: {
948
- "brain-cloud": {
949
- command: "node",
950
- args: ["brainy-mcp-server.js"],
951
- env: {
952
- CUSTOMER_ID: customerId,
953
- BRAIN_CLOUD_URL: "https://api.soulcraft.com/brain-cloud"
730
+ if (stats.storage.location) {
731
+ console.log(colors.info(` Location: ${colors.success(stats.storage.location)}`))
732
+ }
733
+ console.log()
734
+ }
735
+
736
+ // Performance Metrics
737
+ if (stats.performance) {
738
+ console.log(colors.primary('⚡ Performance Metrics'))
739
+ if (stats.performance.avgQueryTime) {
740
+ console.log(colors.info(` Avg Query Time: ${colors.success(stats.performance.avgQueryTime.toFixed(2))} ms`))
741
+ }
742
+ if (stats.performance.totalQueries) {
743
+ console.log(colors.info(` Total Queries: ${colors.success(stats.performance.totalQueries)}`))
744
+ }
745
+ if (stats.performance.cacheHitRate) {
746
+ console.log(colors.info(` Cache Hit Rate: ${colors.success((stats.performance.cacheHitRate * 100).toFixed(1))}%`))
747
+ }
748
+ console.log()
749
+ }
750
+
751
+ // Vector Index Information
752
+ if (stats.index) {
753
+ console.log(colors.primary('🎯 Vector Index'))
754
+ console.log(colors.info(` Dimensions: ${colors.success(stats.index.dimensions || 'N/A')}`))
755
+ console.log(colors.info(` Indexed Vectors: ${colors.success(stats.index.vectorCount || 0)}`))
756
+ if (stats.index.indexSize) {
757
+ console.log(colors.info(` Index Size: ${colors.success((stats.index.indexSize / 1024 / 1024).toFixed(2))} MB`))
758
+ }
759
+ console.log()
760
+ }
761
+
762
+ // Memory Usage Breakdown
763
+ console.log(colors.primary('🧠 Memory Usage'))
764
+ console.log(colors.info(` Heap Used: ${colors.success((memUsage.heapUsed / 1024 / 1024).toFixed(1))} MB`))
765
+ console.log(colors.info(` Heap Total: ${colors.success((memUsage.heapTotal / 1024 / 1024).toFixed(1))} MB`))
766
+ console.log(colors.info(` RSS: ${colors.success((memUsage.rss / 1024 / 1024).toFixed(1))} MB`))
767
+ console.log()
768
+
769
+ // Active Augmentations
770
+ console.log(colors.primary('🔌 Active Augmentations'))
771
+ const augmentations = cortex.getAllAugmentations()
772
+ if (augmentations.length === 0) {
773
+ console.log(colors.warning(' No augmentations currently active'))
774
+ } else {
775
+ augmentations.forEach(aug => {
776
+ console.log(colors.success(` ✅ ${aug.name}`))
777
+ if (aug.description) {
778
+ console.log(colors.info(` ${aug.description}`))
954
779
  }
780
+ })
781
+ }
782
+ console.log()
783
+
784
+ // Configuration Summary
785
+ if (stats.config) {
786
+ console.log(colors.primary('⚙️ Configuration'))
787
+ Object.entries(stats.config).forEach(([key, value]) => {
788
+ // Don't show sensitive values
789
+ if (key.toLowerCase().includes('key') || key.toLowerCase().includes('secret')) {
790
+ console.log(colors.info(` ${key}: ${colors.warning('[HIDDEN]')}`))
791
+ } else {
792
+ console.log(colors.info(` ${key}: ${colors.success(value)}`))
793
+ }
794
+ })
795
+ console.log()
796
+ }
797
+
798
+ // Available Fields for Advanced Search
799
+ console.log(colors.primary('🔍 Available Search Fields'))
800
+ try {
801
+ const filterFields = await brainy.getFilterFields()
802
+ if (filterFields.length > 0) {
803
+ console.log(colors.info(' Use these fields for advanced filtering:'))
804
+ filterFields.forEach(field => {
805
+ console.log(colors.success(` ${field}`))
806
+ })
807
+ console.log(colors.info('\n Example: brainy search "query" --filter \'{"type":"person"}\''))
808
+ } else {
809
+ console.log(colors.warning(' No indexed fields available yet'))
810
+ console.log(colors.info(' Add some data to see available fields'))
955
811
  }
812
+ } catch (error) {
813
+ console.log(colors.warning(' Field discovery not available'))
814
+ }
815
+ console.log()
816
+
817
+ // Show raw JSON if verbose
818
+ if (options.verbose) {
819
+ console.log(colors.primary('📋 Raw Statistics (JSON)'))
820
+ console.log(colors.info(JSON.stringify(stats, null, 2)))
821
+ }
822
+
823
+ } catch (error) {
824
+ console.log(colors.error('❌ Status: Error'))
825
+ console.log(colors.error(`Error: ${error.message}`))
826
+ if (options.verbose) {
827
+ console.log(colors.error('Stack trace:'))
828
+ console.log(error.stack)
956
829
  }
957
830
  }
958
-
959
- await writeFile('.claude/mcp_servers.json', JSON.stringify(mcpConfig, null, 2))
960
- console.log(chalk.green('✅ MCP configuration updated'))
961
- } catch (error) {
962
- console.log(chalk.yellow('⚠️ Could not update MCP config:', error.message))
963
- }
964
-
965
- // 2. Create/update CLAUDE.md with natural language instructions
966
- const claudeContent = `# 🧠 I Remember Everything Now!
967
-
968
- Hi! I'm connected to your Brain Cloud (${customerId}) so I actually remember our conversations across sessions.
969
-
970
- ## Try Saying:
971
- - "What did we build together?"
972
- - "Remember that React project?"
973
- - "Show me what we worked on yesterday"
974
- - "Find my notes about APIs"
975
- - "Search for that bug we fixed"
976
-
977
- ## I Can Also:
978
- - Remember context from weeks ago
979
- - Work with other AI assistants who share the same memory
980
- - Keep everything synced across your devices
981
- - Search through all our conversations
982
-
983
- ## Multi-AI Coordination:
984
- When working with multiple AI assistants, we automatically coordinate:
985
- - **Jarvis** (Backend): APIs, databases, deployment
986
- - **Picasso** (Design): UI, themes, visual elements
987
- - **Claude** (Planning): Coordination, architecture, strategy
988
-
989
- **Just talk to me normally - no commands needed!**
831
+ }))
990
832
 
991
- ---
992
- *Brain Cloud Instance: ${customerId}*
993
- *Last Updated: ${new Date().toLocaleDateString()}*
994
- `
995
-
996
- try {
997
- await writeFile('CLAUDE.md', claudeContent)
998
- console.log(chalk.green('✅ CLAUDE.md updated with memory instructions'))
999
- } catch (error) {
1000
- console.log(chalk.yellow('⚠️ Could not update CLAUDE.md:', error.message))
1001
- }
1002
-
1003
- // 3. Save customer ID to brainy config
1004
- try {
1005
- const brainyConfig = {
1006
- brainCloudCustomerId: customerId,
1007
- brainCloudUrl: 'https://api.soulcraft.com/brain-cloud',
1008
- lastConnected: new Date().toISOString()
833
+ // Command 5: CONFIG - Essential configuration
834
+ program
835
+ .command('config <action> [key] [value]')
836
+ .description('Configure brainy (get, set, list)')
837
+ .action(wrapAction(async (action, key, value) => {
838
+ const configActions = {
839
+ get: async () => {
840
+ if (!key) {
841
+ console.error(colors.error('Please specify a key: brainy config get <key>'))
842
+ process.exit(1)
843
+ }
844
+ const result = await cortex.configGet(key)
845
+ console.log(colors.success(`${key}: ${result || 'not set'}`))
846
+ },
847
+ set: async () => {
848
+ if (!key || !value) {
849
+ console.error(colors.error('Usage: brainy config set <key> <value>'))
850
+ process.exit(1)
851
+ }
852
+ await cortex.configSet(key, value)
853
+ console.log(colors.success(`✅ Set ${key} = ${value}`))
854
+ },
855
+ list: async () => {
856
+ const config = await cortex.configList()
857
+ console.log(colors.primary('🔧 Current Configuration:'))
858
+ Object.entries(config).forEach(([k, v]) => {
859
+ console.log(colors.info(` ${k}: ${v}`))
860
+ })
861
+ }
1009
862
  }
1010
863
 
1011
- await writeFile('brainy-config.json', JSON.stringify(brainyConfig, null, 2))
1012
- console.log(chalk.green('✅ Brainy configuration saved'))
1013
- } catch (error) {
1014
- console.log(chalk.yellow('⚠️ Could not save brainy config:', error.message))
1015
- }
1016
- }
1017
-
1018
- // ========================================
1019
- // AUTO-SETUP HELPER FUNCTIONS
1020
- // ========================================
1021
-
1022
- const PROVISIONING_API = 'https://provisioning.soulcraft.com'
1023
-
1024
- let spinner = null
1025
-
1026
- function startSpinner(message) {
1027
- stopSpinner()
1028
- process.stdout.write(`${message} `)
1029
-
1030
- const spinnerChars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
1031
- let i = 0
1032
-
1033
- spinner = setInterval(() => {
1034
- process.stdout.write(`\r${message} ${spinnerChars[i]}`)
1035
- i = (i + 1) % spinnerChars.length
1036
- }, 100)
1037
- }
1038
-
1039
- function stopSpinner() {
1040
- if (spinner) {
1041
- clearInterval(spinner)
1042
- spinner = null
1043
- process.stdout.write('\r')
1044
- }
1045
- }
1046
-
1047
- async function validateLicense() {
1048
- startSpinner('Validating Early Access license...')
1049
-
1050
- const licenseKey = process.env.BRAINY_LICENSE_KEY
1051
-
1052
- if (!licenseKey) {
1053
- stopSpinner()
1054
- console.log('\n❌ No license key found')
1055
- console.log('\n🔑 Please set your Early Access license key:')
1056
- console.log(' export BRAINY_LICENSE_KEY="lic_early_access_your_key"')
1057
- console.log('\n📝 Don\'t have a key? Get one free at: https://soulcraft.com/brain-cloud')
1058
- throw new Error('License key required')
1059
- }
1060
-
1061
- if (!licenseKey.startsWith('lic_early_access_')) {
1062
- stopSpinner()
1063
- throw new Error('Invalid license key format. Early Access keys start with "lic_early_access_"')
1064
- }
1065
-
1066
- stopSpinner()
1067
- console.log('✅ License validated')
1068
- }
1069
-
1070
- async function ensureBrainyInstalled() {
1071
- startSpinner('Checking Brainy installation...')
1072
-
1073
- try {
1074
- const { exec } = await import('child_process')
1075
- const { promisify } = await import('util')
1076
- const execAsync = promisify(exec)
1077
-
1078
- await execAsync('brainy --version')
1079
- stopSpinner()
1080
- console.log('✅ Brainy CLI found')
1081
- } catch (error) {
1082
- stopSpinner()
1083
- console.log('📦 Installing Brainy CLI...')
1084
-
1085
- try {
1086
- await execWithProgress('npm install -g @soulcraft/brainy')
1087
- console.log('✅ Brainy CLI installed')
1088
- } catch (installError) {
1089
- throw new Error('Failed to install Brainy CLI. Please install manually: npm install -g @soulcraft/brainy')
864
+ if (configActions[action]) {
865
+ await configActions[action]()
866
+ } else {
867
+ console.error(colors.error('Valid actions: get, set, list'))
868
+ process.exit(1)
1090
869
  }
1091
- }
1092
- }
1093
-
1094
- async function provisionCloudInstance(userEmail) {
1095
- const licenseKey = process.env.BRAINY_LICENSE_KEY
1096
- startSpinner('Provisioning your cloud Brainy instance...')
870
+ }))
1097
871
 
1098
- try {
1099
- const response = await fetch(`${PROVISIONING_API}/provision`, {
1100
- method: 'POST',
1101
- headers: {
1102
- 'Content-Type': 'application/json'
872
+ // Command 6: CLOUD - Premium features connection
873
+ program
874
+ .command('cloud <action>')
875
+ .description('Connect to Brain Cloud premium features')
876
+ .option('-i, --instance <id>', 'Brain Cloud instance ID')
877
+ .action(wrapAction(async (action, options) => {
878
+ console.log(colors.primary('☁️ Brain Cloud Premium Features'))
879
+
880
+ const cloudActions = {
881
+ connect: async () => {
882
+ console.log(colors.info('🔗 Connecting to Brain Cloud...'))
883
+ // Dynamic import to avoid loading premium code unnecessarily
884
+ try {
885
+ const { BrainCloudSDK } = await import('@brainy-cloud/sdk')
886
+ const connected = await BrainCloudSDK.connect(options.instance)
887
+ if (connected) {
888
+ console.log(colors.success('✅ Connected to Brain Cloud'))
889
+ console.log(colors.info(`Instance: ${connected.instanceId}`))
890
+ }
891
+ } catch (error) {
892
+ console.log(colors.warning('⚠️ Brain Cloud SDK not installed'))
893
+ console.log(colors.info('Install with: npm install @brainy-cloud/sdk'))
894
+ console.log(colors.info('Or visit: https://brain-cloud.soulcraft.com'))
895
+ }
1103
896
  },
1104
- body: JSON.stringify({
1105
- licenseKey,
1106
- userEmail: userEmail || 'user@example.com'
1107
- })
1108
- })
1109
-
1110
- if (!response.ok) {
1111
- const error = await response.json()
1112
- throw new Error(error.message || 'Provisioning failed')
897
+ status: async () => {
898
+ try {
899
+ const { BrainCloudSDK } = await import('@brainy-cloud/sdk')
900
+ const status = await BrainCloudSDK.getStatus()
901
+ console.log(colors.success('☁️ Cloud Status: Connected'))
902
+ console.log(colors.info(`Instance: ${status.instanceId}`))
903
+ console.log(colors.info(`Augmentations: ${status.augmentationCount} available`))
904
+ } catch {
905
+ console.log(colors.warning('☁️ Cloud Status: Not connected'))
906
+ console.log(colors.info('Use "brainy cloud connect" to connect'))
907
+ }
908
+ },
909
+ augmentations: async () => {
910
+ try {
911
+ const { BrainCloudSDK } = await import('@brainy-cloud/sdk')
912
+ const augs = await BrainCloudSDK.listAugmentations()
913
+ console.log(colors.primary('🧩 Available Premium Augmentations:'))
914
+ augs.forEach(aug => {
915
+ console.log(colors.success(` ✅ ${aug.name} - ${aug.description}`))
916
+ })
917
+ } catch {
918
+ console.log(colors.warning('Connect to Brain Cloud first: brainy cloud connect'))
919
+ }
920
+ }
1113
921
  }
1114
-
1115
- const result = await response.json()
1116
- stopSpinner()
1117
922
 
1118
- if (result.instance.status === 'active') {
1119
- console.log('✅ Cloud instance already active')
1120
- return result.instance
923
+ if (cloudActions[action]) {
924
+ await cloudActions[action]()
925
+ } else {
926
+ console.log(colors.error('Valid actions: connect, status, augmentations'))
927
+ console.log(colors.info('Example: brainy cloud connect --instance demo-test-auto'))
1121
928
  }
929
+ }))
1122
930
 
1123
- console.log('🚀 Provisioning started (2-3 minutes)')
1124
-
1125
- // Wait for provisioning to complete
1126
- return await waitForProvisioning(licenseKey)
1127
-
1128
- } catch (error) {
1129
- stopSpinner()
1130
- throw new Error(`Provisioning failed: ${error.message}`)
1131
- }
1132
- }
1133
-
1134
- async function waitForProvisioning(licenseKey) {
1135
- const maxWaitTime = 5 * 60 * 1000 // 5 minutes
1136
- const checkInterval = 15 * 1000 // 15 seconds
1137
- const startTime = Date.now()
1138
-
1139
- while (Date.now() - startTime < maxWaitTime) {
1140
- startSpinner('Waiting for cloud instance to be ready...')
931
+ // Command 7: MIGRATE - Migration tools
932
+ program
933
+ .command('migrate <action>')
934
+ .description('Migration tools for upgrades')
935
+ .option('-f, --from <version>', 'Migrate from version')
936
+ .option('-b, --backup', 'Create backup before migration')
937
+ .action(wrapAction(async (action, options) => {
938
+ console.log(colors.primary('🔄 Brainy Migration Tools'))
1141
939
 
1142
- try {
1143
- const response = await fetch(`${PROVISIONING_API}/status?licenseKey=${encodeURIComponent(licenseKey)}`)
1144
-
1145
- if (response.ok) {
1146
- const result = await response.json()
940
+ const migrateActions = {
941
+ check: async () => {
942
+ console.log(colors.info('🔍 Checking for migration needs...'))
943
+ // Check for deprecated methods, old config, etc.
944
+ const issues = []
1147
945
 
1148
- if (result.instance.status === 'active') {
1149
- stopSpinner()
1150
- console.log('✅ Cloud instance is ready')
1151
- return result.instance
946
+ try {
947
+ const { BrainyData } = await import('../dist/brainyData.js')
948
+ const brainy = new BrainyData()
949
+
950
+ // Check for old API usage
951
+ console.log(colors.success('✅ No migration issues found'))
952
+ } catch (error) {
953
+ console.log(colors.warning(`⚠️ Found issues: ${error.message}`))
1152
954
  }
1153
-
1154
- if (result.instance.status === 'failed') {
1155
- stopSpinner()
1156
- throw new Error('Instance provisioning failed')
955
+ },
956
+ backup: async () => {
957
+ console.log(colors.info('💾 Creating backup...'))
958
+ const { BrainyData } = await import('../dist/brainyData.js')
959
+ const brainy = new BrainyData()
960
+ const backup = await brainy.createBackup()
961
+ console.log(colors.success(`✅ Backup created: ${backup.path}`))
962
+ },
963
+ restore: async () => {
964
+ if (!options.from) {
965
+ console.error(colors.error('Please specify backup file: --from <path>'))
966
+ process.exit(1)
1157
967
  }
968
+ console.log(colors.info(`📥 Restoring from: ${options.from}`))
969
+ const { BrainyData } = await import('../dist/brainyData.js')
970
+ const brainy = new BrainyData()
971
+ await brainy.restoreBackup(options.from)
972
+ console.log(colors.success('✅ Restore complete'))
1158
973
  }
1159
-
1160
- stopSpinner()
1161
- await new Promise(resolve => setTimeout(resolve, checkInterval))
1162
-
1163
- } catch (error) {
1164
- stopSpinner()
1165
- console.log('⏳ Still provisioning...')
1166
- await new Promise(resolve => setTimeout(resolve, checkInterval))
1167
- }
1168
- }
1169
-
1170
- throw new Error('Provisioning timeout. Please check your dashboard or contact support.')
1171
- }
1172
-
1173
- async function configureBrainy(instance) {
1174
- const { writeFile, mkdir } = await import('fs/promises')
1175
- const { join } = await import('path')
1176
- const { homedir } = await import('os')
1177
- const { existsSync } = await import('fs')
1178
-
1179
- startSpinner('Configuring local Brainy to use cloud instance...')
1180
-
1181
- // Ensure config directory exists
1182
- const BRAINY_CONFIG_DIR = join(homedir(), '.brainy')
1183
- const BRAINY_CONFIG_FILE = join(BRAINY_CONFIG_DIR, 'config.json')
1184
-
1185
- if (!existsSync(BRAINY_CONFIG_DIR)) {
1186
- await mkdir(BRAINY_CONFIG_DIR, { recursive: true })
1187
- }
1188
-
1189
- // Create or update Brainy config
1190
- let config = {}
1191
- if (existsSync(BRAINY_CONFIG_FILE)) {
1192
- try {
1193
- const { readFile } = await import('fs/promises')
1194
- const existing = await readFile(BRAINY_CONFIG_FILE, 'utf8')
1195
- config = JSON.parse(existing)
1196
- } catch (error) {
1197
- console.log('⚠️ Could not read existing config, creating new one')
1198
974
  }
1199
- }
1200
-
1201
- // Update config with cloud instance details
1202
- config.cloudSync = {
1203
- enabled: true,
1204
- endpoint: instance.endpoints.api,
1205
- instanceId: instance.id,
1206
- licenseKey: process.env.BRAINY_LICENSE_KEY
1207
- }
1208
-
1209
- config.aiMemory = {
1210
- enabled: true,
1211
- storage: 'cloud',
1212
- endpoint: instance.endpoints.api
1213
- }
1214
-
1215
- config.agentCoordination = {
1216
- enabled: true,
1217
- endpoint: instance.endpoints.api
1218
- }
1219
-
1220
- await writeFile(BRAINY_CONFIG_FILE, JSON.stringify(config, null, 2))
1221
-
1222
- stopSpinner()
1223
- console.log('✅ Local Brainy configured for cloud sync')
1224
- }
1225
-
1226
- async function installBrainCloudPackage() {
1227
- startSpinner('Installing Brain Cloud augmentations...')
1228
-
1229
- try {
1230
- const { existsSync } = await import('fs')
1231
975
 
1232
- // Check if we're in a project directory
1233
- const hasPackageJson = existsSync('package.json')
1234
-
1235
- if (hasPackageJson) {
1236
- // Auto-configured with 'brainy cloud auth' - no package installation needed!
1237
- console.log('✅ Brain Cloud package installed in current project')
976
+ if (migrateActions[action]) {
977
+ await migrateActions[action]()
1238
978
  } else {
1239
- // Install globally for non-project usage
1240
- console.log(' Run \'brainy cloud auth\' to authenticate and auto-configure')
1241
- console.log('✅ Brain Cloud package installed globally')
979
+ console.log(colors.error('Valid actions: check, backup, restore'))
980
+ console.log(colors.info('Example: brainy migrate check'))
1242
981
  }
982
+ }))
1243
983
 
1244
- } catch (error) {
1245
- stopSpinner()
1246
- console.log('⚠️ Could not auto-install Brain Cloud package')
1247
- console.log(' Authenticate manually: brainy cloud auth')
1248
- // Don't throw error, this is optional
1249
- }
1250
- }
1251
-
1252
- async function testConnection(instance) {
1253
- startSpinner('Testing cloud connection...')
1254
-
1255
- try {
1256
- const response = await fetch(`${instance.endpoints.api}/health`)
1257
-
1258
- if (response.ok) {
1259
- const health = await response.json()
1260
- stopSpinner()
1261
- console.log('✅ Cloud instance connection verified')
1262
-
1263
- // Test memory storage
1264
- const testMemory = {
1265
- content: 'Test memory from auto-setup',
1266
- source: 'brain-cloud-setup',
1267
- importance: 'low',
1268
- tags: ['setup', 'test']
1269
- }
1270
-
1271
- const memoryResponse = await fetch(`${instance.endpoints.api}/api/memories`, {
1272
- method: 'POST',
1273
- headers: { 'Content-Type': 'application/json' },
1274
- body: JSON.stringify(testMemory)
1275
- })
1276
-
1277
- if (memoryResponse.ok) {
1278
- console.log('✅ Memory storage working')
1279
- }
1280
-
1281
- } else {
1282
- stopSpinner()
1283
- console.log('⚠️ Cloud instance not responding yet (this is normal)')
1284
- console.log(' Your instance may need a few more minutes to fully initialize')
984
+ // Command 8: HELP - Interactive guidance
985
+ program
986
+ .command('help [command]')
987
+ .description('Get help or enter interactive mode')
988
+ .action(wrapAction(async (command) => {
989
+ if (command) {
990
+ program.help()
991
+ return
1285
992
  }
1286
- } catch (error) {
1287
- stopSpinner()
1288
- console.log('⚠️ Could not test connection (this is usually fine)')
1289
- }
1290
- }
1291
-
1292
- async function execWithProgress(command) {
1293
- const { spawn } = await import('child_process')
1294
-
1295
- return new Promise((resolve, reject) => {
1296
- const child = spawn('sh', ['-c', command], {
1297
- stdio: ['inherit', 'pipe', 'pipe'],
1298
- shell: true
993
+
994
+ // Interactive mode for beginners
995
+ console.log(colors.primary('🧠⚛️ Welcome to Brainy!'))
996
+ console.log(colors.info('Your AI-powered second brain'))
997
+ console.log()
998
+
999
+ const rl = createInterface({
1000
+ input: process.stdin,
1001
+ output: process.stdout
1299
1002
  })
1300
-
1301
- let stdout = ''
1302
- let stderr = ''
1303
-
1304
- child.stdout?.on('data', (data) => {
1305
- stdout += data.toString()
1306
- process.stdout.write('.')
1003
+
1004
+ console.log(colors.primary('What would you like to do?'))
1005
+ console.log(colors.info('1. Add some data'))
1006
+ console.log(colors.info('2. Chat with AI using your data'))
1007
+ console.log(colors.info('3. Search your brain'))
1008
+ console.log(colors.info('4. Update existing data'))
1009
+ console.log(colors.info('5. Delete data'))
1010
+ console.log(colors.info('6. Import a file'))
1011
+ console.log(colors.info('7. Check status'))
1012
+ console.log(colors.info('8. Connect to Brain Cloud'))
1013
+ console.log(colors.info('9. Configuration'))
1014
+ console.log(colors.info('10. Show all commands'))
1015
+ console.log()
1016
+
1017
+ const choice = await new Promise(resolve => {
1018
+ rl.question(colors.primary('Enter your choice (1-10): '), (answer) => {
1019
+ rl.close()
1020
+ resolve(answer)
1021
+ })
1307
1022
  })
1023
+
1024
+ switch (choice) {
1025
+ case '1':
1026
+ console.log(colors.success('\n🧠 Use: brainy add "your data here"'))
1027
+ console.log(colors.info('Example: brainy add "John works at Google"'))
1028
+ break
1029
+ case '2':
1030
+ console.log(colors.success('\n💬 Use: brainy chat "your question"'))
1031
+ console.log(colors.info('Example: brainy chat "Tell me about my data"'))
1032
+ console.log(colors.info('Supports: local (Ollama), OpenAI, Claude'))
1033
+ break
1034
+ case '3':
1035
+ console.log(colors.success('\n🔍 Use: brainy search "your query"'))
1036
+ console.log(colors.info('Example: brainy search "Google employees"'))
1037
+ break
1038
+ case '4':
1039
+ console.log(colors.success('\n📥 Use: brainy import <file-or-url>'))
1040
+ console.log(colors.info('Example: brainy import data.txt'))
1041
+ break
1042
+ case '5':
1043
+ console.log(colors.success('\n📊 Use: brainy status'))
1044
+ console.log(colors.info('Shows comprehensive brain statistics'))
1045
+ console.log(colors.info('Options: --simple (quick) or --verbose (detailed)'))
1046
+ break
1047
+ case '6':
1048
+ console.log(colors.success('\n☁️ Use: brainy cloud connect'))
1049
+ console.log(colors.info('Example: brainy cloud connect --instance demo-test-auto'))
1050
+ break
1051
+ case '7':
1052
+ console.log(colors.success('\n🔧 Use: brainy config <action>'))
1053
+ console.log(colors.info('Example: brainy config list'))
1054
+ break
1055
+ case '8':
1056
+ program.help()
1057
+ break
1058
+ default:
1059
+ console.log(colors.warning('Invalid choice. Use "brainy --help" for all commands.'))
1060
+ }
1061
+ }))
1308
1062
 
1309
- child.stderr?.on('data', (data) => {
1310
- stderr += data.toString()
1311
- })
1063
+ // ========================================
1064
+ // FALLBACK - Show interactive help if no command
1065
+ // ========================================
1312
1066
 
1313
- child.on('close', (code) => {
1314
- process.stdout.write('\n')
1315
- if (code === 0) {
1316
- resolve(stdout)
1317
- } else {
1318
- reject(new Error(stderr || `Command failed with code ${code}`))
1319
- }
1320
- })
1321
- })
1067
+ // If no arguments provided, show interactive help
1068
+ if (process.argv.length === 2) {
1069
+ program.parse(['node', 'brainy', 'help'])
1070
+ } else {
1071
+ program.parse(process.argv)
1322
1072
  }