@soulcraft/brainy 0.61.1 → 0.61.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/brainy.js CHANGED
@@ -204,24 +204,138 @@ program
204
204
  console.log(chalk.cyan('Restart Claude Code to activate memory.'))
205
205
  } else {
206
206
  console.log(chalk.yellow('No Brain Cloud found. Setting up:'))
207
- console.log('\n1. Visit: ' + chalk.cyan('https://soulcraft.com'))
208
- console.log('2. Sign up for Brain Cloud')
209
- console.log('3. Run ' + chalk.green('brainy connect') + ' again')
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')
210
210
  }
211
211
  } catch (error) {
212
212
  console.log(chalk.red('āŒ Setup failed:'), error.message)
213
213
  }
214
214
  }))
215
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'))
287
+ }
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
+
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'))
320
+ }
321
+ }))
322
+
323
+ // Legacy cloud command (for backward compatibility)
216
324
  program
217
- .command('cloud [action]')
218
- .description('Manage Brain Cloud connection')
325
+ .command('cloud-legacy [action]')
326
+ .description('Legacy Brain Cloud connection (deprecated - use "brainy cloud")')
219
327
  .option('--connect <id>', 'Connect to existing Brain Cloud instance')
220
328
  .option('--export <id>', 'Export all data from Brain Cloud instance')
221
329
  .option('--status <id>', 'Check status of Brain Cloud instance')
222
330
  .option('--dashboard <id>', 'Open dashboard for Brain Cloud instance')
223
331
  .option('--migrate', 'Migrate between local and cloud')
224
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('')
225
339
  // For now, show connection instructions
226
340
  console.log(chalk.cyan('\nāš›ļø BRAIN CLOUD - AI Memory That Never Forgets'))
227
341
  console.log(chalk.gray('━'.repeat(50)))
@@ -357,12 +471,176 @@ program
357
471
  // AUGMENTATION MANAGEMENT (Direct Commands)
358
472
  // ========================================
359
473
 
474
+ const augment = program
475
+ .command('augment')
476
+ .description('Manage brain augmentations')
477
+
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('')
486
+
487
+ // Check for Brain Cloud
488
+ try {
489
+ await import('@soulcraft/brain-cloud')
490
+ const hasLicense = process.env.BRAINY_LICENSE_KEY
491
+
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()
505
+
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}`)
513
+ })
514
+ console.log('')
515
+ }
516
+
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')
529
+ }
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('')
537
+ }
538
+
539
+ console.log(chalk.dim('šŸš€ Join Early Access: https://soulcraft.com/brain-cloud'))
540
+ console.log(chalk.dim('šŸ“¦ Install: npm install @soulcraft/brain-cloud'))
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'))
553
+ console.log('')
554
+ console.log('Get your license at: ' + chalk.green('app.soulcraft.com'))
555
+ console.log('(14-day free trial available)')
556
+ console.log('')
557
+
558
+ rl.question('License key: ', async (key) => {
559
+ if (key.startsWith('lic_')) {
560
+ // Save to config
561
+ const fs = await import('fs/promises')
562
+ const os = await import('os')
563
+ const configPath = `${os.homedir()}/.brainy`
564
+
565
+ await fs.mkdir(configPath, { recursive: true })
566
+ await fs.writeFile(`${configPath}/license`, key)
567
+
568
+ console.log(chalk.green('āœ… License saved!'))
569
+ console.log('')
570
+ console.log('Install Brain Cloud:')
571
+ console.log(chalk.cyan(' npm install @soulcraft/brain-cloud'))
572
+ console.log('')
573
+ console.log('Then use in your code:')
574
+ console.log(chalk.gray(' import { AIMemory } from "@soulcraft/brain-cloud"'))
575
+ console.log(chalk.gray(' cortex.register(new AIMemory())'))
576
+ } else {
577
+ console.log(chalk.red('Invalid license key'))
578
+ }
579
+ rl.close()
580
+ })
581
+ }))
582
+
583
+ augment
584
+ .command('info <name>')
585
+ .description('Get info about an augmentation')
586
+ .action(wrapAction(async (name) => {
587
+ const augmentations = {
588
+ 'ai-memory': {
589
+ name: 'AI Memory',
590
+ description: 'Persistent memory across all AI sessions',
591
+ category: 'Memory',
592
+ tier: 'Premium',
593
+ popular: true,
594
+ example: `
595
+ import { AIMemory } from '@soulcraft/brain-cloud'
596
+
597
+ const cortex = new Cortex()
598
+ cortex.register(new AIMemory())
599
+
600
+ // Now your AI remembers everything
601
+ await brain.add("User prefers dark mode")
602
+ // This persists across sessions automatically`
603
+ },
604
+ 'agent-coordinator': {
605
+ name: 'Agent Coordinator',
606
+ description: 'Multi-agent handoffs and orchestration',
607
+ category: 'Coordination',
608
+ tier: 'Premium',
609
+ popular: true
610
+ },
611
+ 'notion-sync': {
612
+ name: 'Notion Sync',
613
+ description: 'Bidirectional Notion database sync',
614
+ category: 'Enterprise',
615
+ tier: 'Premium'
616
+ }
617
+ }
618
+
619
+ const aug = augmentations[name]
620
+ if (aug) {
621
+ console.log(chalk.cyan(`šŸ“¦ ${aug.name}`) + (aug.popular ? chalk.yellow(' ⭐ Popular') : ''))
622
+ console.log('')
623
+ console.log(`Category: ${aug.category}`)
624
+ console.log(`Tier: ${aug.tier}`)
625
+ console.log(`Description: ${aug.description}`)
626
+ if (aug.example) {
627
+ console.log('')
628
+ console.log('Example:')
629
+ console.log(chalk.gray(aug.example))
630
+ }
631
+ } else {
632
+ console.log(chalk.red(`Unknown augmentation: ${name}`))
633
+ }
634
+ }))
635
+
360
636
  program
361
637
  .command('install <augmentation>')
362
- .description('Install augmentation')
638
+ .description('Install augmentation (legacy - use augment activate)')
363
639
  .option('-m, --mode <type>', 'Installation mode (free|premium)', 'free')
364
640
  .option('-c, --config <json>', 'Configuration as JSON')
365
641
  .action(wrapAction(async (augmentation, options) => {
642
+ console.log(chalk.yellow('Note: Use "brainy augment activate" for Brain Cloud'))
643
+
366
644
  if (augmentation === 'brain-jar') {
367
645
  await cortex.brainJarInstall(options.mode)
368
646
  } else {
@@ -426,13 +704,18 @@ program
426
704
  .option('-a, --available', 'Show available augmentations')
427
705
  .action(wrapAction(async (options) => {
428
706
  if (options.available) {
429
- console.log(chalk.cyan('Available Augmentations:'))
430
- console.log(' • brain-jar - AI coordination and collaboration')
431
- console.log(' • encryption - Data encryption and security')
432
- console.log(' • neural-import - AI-powered data analysis')
433
- console.log(' • performance-monitor - System monitoring')
707
+ console.log(chalk.green('āœ… Built-in (Free):'))
708
+ console.log(' • neural-import - AI-powered data understanding')
709
+ console.log(' • basic-storage - Local persistence')
710
+ console.log('')
711
+ console.log(chalk.cyan('🌟 Premium (Brain Cloud):'))
712
+ console.log(' • ai-memory - ' + chalk.yellow('⭐ Most Popular') + ' - AI that remembers')
713
+ console.log(' • agent-coordinator - ' + chalk.yellow('⭐ Most Popular') + ' - Multi-agent orchestration')
714
+ console.log(' • notion-sync - Enterprise connector')
715
+ console.log(' • More at app.soulcraft.com/augmentations')
434
716
  console.log('')
435
- console.log(chalk.dim('Install: brainy install <augmentation>'))
717
+ console.log(chalk.dim('Sign up: app.soulcraft.com (14-day free trial)'))
718
+ console.log(chalk.dim('Install: npm install @soulcraft/brain-cloud'))
436
719
  } else {
437
720
  await cortex.listAugmentations()
438
721
  }
@@ -588,9 +871,10 @@ if (!process.argv.slice(2).length) {
588
871
  console.log(' brainy search "query" # Search across all dimensions')
589
872
  console.log(' brainy chat # AI chat with full context')
590
873
  console.log('')
591
- console.log(chalk.bold('AI Memory:'))
592
- console.log(chalk.green(' brainy connect # Connect to Brain Cloud'))
593
- console.log(' brainy cloud --status <id> # Check cloud status')
874
+ console.log(chalk.bold('Brain Cloud (Premium):'))
875
+ console.log(chalk.green(' brainy cloud setup # Auto-setup with provisioning'))
876
+ console.log(' brainy cloud connect <id> # Connect to existing instance')
877
+ console.log(' brainy cloud dashboard # Open Brain Cloud dashboard')
594
878
  console.log('')
595
879
  console.log(chalk.bold('AI Coordination:'))
596
880
  console.log(' brainy install brain-jar # Install coordination')
@@ -726,4 +1010,310 @@ When working with multiple AI assistants, we automatically coordinate:
726
1010
  } catch (error) {
727
1011
  console.log(chalk.yellow('āš ļø Could not save brainy config:', error.message))
728
1012
  }
1013
+ }
1014
+
1015
+ // ========================================
1016
+ // AUTO-SETUP HELPER FUNCTIONS
1017
+ // ========================================
1018
+
1019
+ const PROVISIONING_API = 'https://provisioning.soulcraft.com'
1020
+
1021
+ let spinner = null
1022
+
1023
+ function startSpinner(message) {
1024
+ stopSpinner()
1025
+ process.stdout.write(`${message} `)
1026
+
1027
+ const spinnerChars = ['ā ‹', 'ā ™', 'ā ¹', 'ā ø', 'ā ¼', 'ā “', 'ā ¦', 'ā §', 'ā ‡', 'ā ']
1028
+ let i = 0
1029
+
1030
+ spinner = setInterval(() => {
1031
+ process.stdout.write(`\r${message} ${spinnerChars[i]}`)
1032
+ i = (i + 1) % spinnerChars.length
1033
+ }, 100)
1034
+ }
1035
+
1036
+ function stopSpinner() {
1037
+ if (spinner) {
1038
+ clearInterval(spinner)
1039
+ spinner = null
1040
+ process.stdout.write('\r')
1041
+ }
1042
+ }
1043
+
1044
+ async function validateLicense() {
1045
+ startSpinner('Validating Early Access license...')
1046
+
1047
+ const licenseKey = process.env.BRAINY_LICENSE_KEY
1048
+
1049
+ if (!licenseKey) {
1050
+ stopSpinner()
1051
+ console.log('\nāŒ No license key found')
1052
+ console.log('\nšŸ”‘ Please set your Early Access license key:')
1053
+ console.log(' export BRAINY_LICENSE_KEY="lic_early_access_your_key"')
1054
+ console.log('\nšŸ“ Don\'t have a key? Get one free at: https://soulcraft.com/brain-cloud')
1055
+ throw new Error('License key required')
1056
+ }
1057
+
1058
+ if (!licenseKey.startsWith('lic_early_access_')) {
1059
+ stopSpinner()
1060
+ throw new Error('Invalid license key format. Early Access keys start with "lic_early_access_"')
1061
+ }
1062
+
1063
+ stopSpinner()
1064
+ console.log('āœ… License validated')
1065
+ }
1066
+
1067
+ async function ensureBrainyInstalled() {
1068
+ startSpinner('Checking Brainy installation...')
1069
+
1070
+ try {
1071
+ const { exec } = await import('child_process')
1072
+ const { promisify } = await import('util')
1073
+ const execAsync = promisify(exec)
1074
+
1075
+ await execAsync('brainy --version')
1076
+ stopSpinner()
1077
+ console.log('āœ… Brainy CLI found')
1078
+ } catch (error) {
1079
+ stopSpinner()
1080
+ console.log('šŸ“¦ Installing Brainy CLI...')
1081
+
1082
+ try {
1083
+ await execWithProgress('npm install -g @soulcraft/brainy')
1084
+ console.log('āœ… Brainy CLI installed')
1085
+ } catch (installError) {
1086
+ throw new Error('Failed to install Brainy CLI. Please install manually: npm install -g @soulcraft/brainy')
1087
+ }
1088
+ }
1089
+ }
1090
+
1091
+ async function provisionCloudInstance(userEmail) {
1092
+ const licenseKey = process.env.BRAINY_LICENSE_KEY
1093
+ startSpinner('Provisioning your cloud Brainy instance...')
1094
+
1095
+ try {
1096
+ const response = await fetch(`${PROVISIONING_API}/provision`, {
1097
+ method: 'POST',
1098
+ headers: {
1099
+ 'Content-Type': 'application/json'
1100
+ },
1101
+ body: JSON.stringify({
1102
+ licenseKey,
1103
+ userEmail: userEmail || 'user@example.com'
1104
+ })
1105
+ })
1106
+
1107
+ if (!response.ok) {
1108
+ const error = await response.json()
1109
+ throw new Error(error.message || 'Provisioning failed')
1110
+ }
1111
+
1112
+ const result = await response.json()
1113
+ stopSpinner()
1114
+
1115
+ if (result.instance.status === 'active') {
1116
+ console.log('āœ… Cloud instance already active')
1117
+ return result.instance
1118
+ }
1119
+
1120
+ console.log('šŸš€ Provisioning started (2-3 minutes)')
1121
+
1122
+ // Wait for provisioning to complete
1123
+ return await waitForProvisioning(licenseKey)
1124
+
1125
+ } catch (error) {
1126
+ stopSpinner()
1127
+ throw new Error(`Provisioning failed: ${error.message}`)
1128
+ }
1129
+ }
1130
+
1131
+ async function waitForProvisioning(licenseKey) {
1132
+ const maxWaitTime = 5 * 60 * 1000 // 5 minutes
1133
+ const checkInterval = 15 * 1000 // 15 seconds
1134
+ const startTime = Date.now()
1135
+
1136
+ while (Date.now() - startTime < maxWaitTime) {
1137
+ startSpinner('Waiting for cloud instance to be ready...')
1138
+
1139
+ try {
1140
+ const response = await fetch(`${PROVISIONING_API}/status?licenseKey=${encodeURIComponent(licenseKey)}`)
1141
+
1142
+ if (response.ok) {
1143
+ const result = await response.json()
1144
+
1145
+ if (result.instance.status === 'active') {
1146
+ stopSpinner()
1147
+ console.log('āœ… Cloud instance is ready')
1148
+ return result.instance
1149
+ }
1150
+
1151
+ if (result.instance.status === 'failed') {
1152
+ stopSpinner()
1153
+ throw new Error('Instance provisioning failed')
1154
+ }
1155
+ }
1156
+
1157
+ stopSpinner()
1158
+ await new Promise(resolve => setTimeout(resolve, checkInterval))
1159
+
1160
+ } catch (error) {
1161
+ stopSpinner()
1162
+ console.log('ā³ Still provisioning...')
1163
+ await new Promise(resolve => setTimeout(resolve, checkInterval))
1164
+ }
1165
+ }
1166
+
1167
+ throw new Error('Provisioning timeout. Please check your dashboard or contact support.')
1168
+ }
1169
+
1170
+ async function configureBrainy(instance) {
1171
+ const { writeFile, mkdir } = await import('fs/promises')
1172
+ const { join } = await import('path')
1173
+ const { homedir } = await import('os')
1174
+ const { existsSync } = await import('fs')
1175
+
1176
+ startSpinner('Configuring local Brainy to use cloud instance...')
1177
+
1178
+ // Ensure config directory exists
1179
+ const BRAINY_CONFIG_DIR = join(homedir(), '.brainy')
1180
+ const BRAINY_CONFIG_FILE = join(BRAINY_CONFIG_DIR, 'config.json')
1181
+
1182
+ if (!existsSync(BRAINY_CONFIG_DIR)) {
1183
+ await mkdir(BRAINY_CONFIG_DIR, { recursive: true })
1184
+ }
1185
+
1186
+ // Create or update Brainy config
1187
+ let config = {}
1188
+ if (existsSync(BRAINY_CONFIG_FILE)) {
1189
+ try {
1190
+ const { readFile } = await import('fs/promises')
1191
+ const existing = await readFile(BRAINY_CONFIG_FILE, 'utf8')
1192
+ config = JSON.parse(existing)
1193
+ } catch (error) {
1194
+ console.log('āš ļø Could not read existing config, creating new one')
1195
+ }
1196
+ }
1197
+
1198
+ // Update config with cloud instance details
1199
+ config.cloudSync = {
1200
+ enabled: true,
1201
+ endpoint: instance.endpoints.api,
1202
+ instanceId: instance.id,
1203
+ licenseKey: process.env.BRAINY_LICENSE_KEY
1204
+ }
1205
+
1206
+ config.aiMemory = {
1207
+ enabled: true,
1208
+ storage: 'cloud',
1209
+ endpoint: instance.endpoints.api
1210
+ }
1211
+
1212
+ config.agentCoordination = {
1213
+ enabled: true,
1214
+ endpoint: instance.endpoints.api
1215
+ }
1216
+
1217
+ await writeFile(BRAINY_CONFIG_FILE, JSON.stringify(config, null, 2))
1218
+
1219
+ stopSpinner()
1220
+ console.log('āœ… Local Brainy configured for cloud sync')
1221
+ }
1222
+
1223
+ async function installBrainCloudPackage() {
1224
+ startSpinner('Installing Brain Cloud augmentations...')
1225
+
1226
+ try {
1227
+ const { existsSync } = await import('fs')
1228
+
1229
+ // Check if we're in a project directory
1230
+ const hasPackageJson = existsSync('package.json')
1231
+
1232
+ if (hasPackageJson) {
1233
+ await execWithProgress('npm install @soulcraft/brain-cloud')
1234
+ console.log('āœ… Brain Cloud package installed in current project')
1235
+ } else {
1236
+ // Install globally for non-project usage
1237
+ await execWithProgress('npm install -g @soulcraft/brain-cloud')
1238
+ console.log('āœ… Brain Cloud package installed globally')
1239
+ }
1240
+
1241
+ } catch (error) {
1242
+ stopSpinner()
1243
+ console.log('āš ļø Could not auto-install Brain Cloud package')
1244
+ console.log(' You can install it manually: npm install @soulcraft/brain-cloud')
1245
+ // Don't throw error, this is optional
1246
+ }
1247
+ }
1248
+
1249
+ async function testConnection(instance) {
1250
+ startSpinner('Testing cloud connection...')
1251
+
1252
+ try {
1253
+ const response = await fetch(`${instance.endpoints.api}/health`)
1254
+
1255
+ if (response.ok) {
1256
+ const health = await response.json()
1257
+ stopSpinner()
1258
+ console.log('āœ… Cloud instance connection verified')
1259
+
1260
+ // Test memory storage
1261
+ const testMemory = {
1262
+ content: 'Test memory from auto-setup',
1263
+ source: 'brain-cloud-setup',
1264
+ importance: 'low',
1265
+ tags: ['setup', 'test']
1266
+ }
1267
+
1268
+ const memoryResponse = await fetch(`${instance.endpoints.api}/api/memories`, {
1269
+ method: 'POST',
1270
+ headers: { 'Content-Type': 'application/json' },
1271
+ body: JSON.stringify(testMemory)
1272
+ })
1273
+
1274
+ if (memoryResponse.ok) {
1275
+ console.log('āœ… Memory storage working')
1276
+ }
1277
+
1278
+ } else {
1279
+ stopSpinner()
1280
+ console.log('āš ļø Cloud instance not responding yet (this is normal)')
1281
+ console.log(' Your instance may need a few more minutes to fully initialize')
1282
+ }
1283
+ } catch (error) {
1284
+ stopSpinner()
1285
+ console.log('āš ļø Could not test connection (this is usually fine)')
1286
+ }
1287
+ }
1288
+
1289
+ async function execWithProgress(command) {
1290
+ const { spawn } = await import('child_process')
1291
+
1292
+ return new Promise((resolve, reject) => {
1293
+ const child = spawn('sh', ['-c', command], {
1294
+ stdio: ['inherit', 'pipe', 'pipe'],
1295
+ shell: true
1296
+ })
1297
+
1298
+ let stdout = ''
1299
+ let stderr = ''
1300
+
1301
+ child.stdout?.on('data', (data) => {
1302
+ stdout += data.toString()
1303
+ process.stdout.write('.')
1304
+ })
1305
+
1306
+ child.stderr?.on('data', (data) => {
1307
+ stderr += data.toString()
1308
+ })
1309
+
1310
+ child.on('close', (code) => {
1311
+ process.stdout.write('\n')
1312
+ if (code === 0) {
1313
+ resolve(stdout)
1314
+ } else {
1315
+ reject(new Error(stderr || `Command failed with code ${code}`))
1316
+ }
1317
+ })
1318
+ })
729
1319
  }