@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/README.md +345 -448
- package/bin/brainy.js +605 -15
- package/dist/augmentationPipeline.d.ts +19 -12
- package/dist/augmentationPipeline.js +19 -11
- package/dist/cli/catalog.d.ts +47 -0
- package/dist/cli/catalog.js +325 -0
- package/dist/cortex/cliWrapper.d.ts +32 -0
- package/dist/cortex/cliWrapper.js +209 -0
- package/dist/cortex/cortex-legacy.d.ts +264 -0
- package/dist/cortex/cortex-legacy.js +2463 -0
- package/dist/cortex/serviceIntegration.d.ts +1 -1
- package/dist/cortex/serviceIntegration.js +1 -1
- package/dist/cortex.d.ts +11 -0
- package/dist/cortex.js +14 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.js +13 -3
- package/package.json +1 -2
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.
|
|
209
|
-
console.log('3. Run ' + chalk.green('brainy
|
|
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('
|
|
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.
|
|
430
|
-
console.log(' ā¢
|
|
431
|
-
console.log(' ā¢
|
|
432
|
-
console.log('
|
|
433
|
-
console.log('
|
|
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('
|
|
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('
|
|
592
|
-
console.log(chalk.green(' brainy
|
|
593
|
-
console.log(' brainy cloud
|
|
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
|
}
|