@soulcraft/brainy 0.63.0 → 1.0.0-rc.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 +296 -95
- package/bin/brainy.js +1121 -1409
- package/dist/brainyData.d.ts +185 -44
- package/dist/brainyData.js +727 -40
- package/dist/chat/BrainyChat.js +5 -11
- package/dist/cortex/neuralImport.js +1 -3
- package/dist/index.d.ts +3 -4
- package/dist/index.js +5 -6
- package/dist/pipeline.d.ts +15 -271
- package/dist/pipeline.js +25 -586
- package/package.json +3 -1
- package/dist/augmentations/cortexSense.d.ts +0 -196
- package/dist/augmentations/cortexSense.js +0 -747
- package/dist/chat/brainyChat.d.ts +0 -42
- package/dist/chat/brainyChat.js +0 -340
- package/dist/cortex/cliWrapper.d.ts +0 -32
- package/dist/cortex/cliWrapper.js +0 -209
- package/dist/cortex/cortex-legacy.d.ts +0 -269
- package/dist/cortex/cortex-legacy.js +0 -2523
- package/dist/cortex/cortex.d.ts +0 -264
- package/dist/cortex/cortex.js +0 -2463
- package/dist/cortex/serviceIntegration.d.ts +0 -156
- package/dist/cortex/serviceIntegration.js +0 -384
- package/dist/sequentialPipeline.d.ts +0 -113
- package/dist/sequentialPipeline.js +0 -417
- package/dist/utils/modelLoader.d.ts +0 -12
- 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 -
|
|
5
|
-
*
|
|
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 {
|
|
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
|
|
24
|
-
|
|
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,1559 +53,1252 @@ const wrapAction = (fn) => {
|
|
|
34
53
|
await fn(...args)
|
|
35
54
|
exitProcess(0)
|
|
36
55
|
} catch (error) {
|
|
37
|
-
console.error(
|
|
56
|
+
console.error(colors.error('Error:'), error.message)
|
|
38
57
|
exitProcess(1)
|
|
39
58
|
}
|
|
40
59
|
}
|
|
41
60
|
}
|
|
42
61
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
197
|
+
// MAIN PROGRAM - CLEAN & SIMPLE
|
|
57
198
|
// ========================================
|
|
58
199
|
|
|
59
200
|
program
|
|
60
201
|
.name('brainy')
|
|
61
|
-
.description('
|
|
202
|
+
.description('🧠⚛️ Brainy - Your AI-Powered Second Brain')
|
|
62
203
|
.version(packageJson.version)
|
|
63
204
|
|
|
64
205
|
// ========================================
|
|
65
|
-
//
|
|
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
|
|
71
|
-
.option('-s, --storage <type>', 'Storage type (filesystem, s3, r2, gcs
|
|
72
|
-
.option('-e, --encryption', 'Enable encryption for
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (options.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
console.
|
|
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'))
|
|
90
236
|
process.exit(1)
|
|
91
237
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
238
|
+
|
|
239
|
+
config.storageOptions = {
|
|
240
|
+
bucket: options.s3Bucket,
|
|
241
|
+
region: options.s3Region || 'us-east-1',
|
|
242
|
+
accessKeyId: options.accessKey,
|
|
243
|
+
secretAccessKey: options.secretKey
|
|
244
|
+
}
|
|
95
245
|
}
|
|
96
246
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
console.log(
|
|
103
|
-
|
|
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)
|
|
104
268
|
}
|
|
105
269
|
}))
|
|
106
270
|
|
|
271
|
+
// Command 1: ADD - Add data (smart by default)
|
|
107
272
|
program
|
|
108
|
-
.command('
|
|
109
|
-
.description('
|
|
110
|
-
.option('-m, --metadata <json>', 'Metadata
|
|
111
|
-
.option('-i, --id <id>', 'Custom ID')
|
|
273
|
+
.command('add [data]')
|
|
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)')
|
|
112
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
|
+
|
|
113
295
|
let metadata = {}
|
|
114
296
|
if (options.metadata) {
|
|
115
297
|
try {
|
|
116
298
|
metadata = JSON.parse(options.metadata)
|
|
117
299
|
} catch {
|
|
118
|
-
console.error(
|
|
300
|
+
console.error(colors.error('Invalid JSON metadata'))
|
|
119
301
|
process.exit(1)
|
|
120
302
|
}
|
|
121
303
|
}
|
|
122
304
|
if (options.id) {
|
|
123
305
|
metadata.id = options.id
|
|
124
306
|
}
|
|
307
|
+
if (options.encrypt) {
|
|
308
|
+
metadata.encrypted = true
|
|
309
|
+
}
|
|
125
310
|
|
|
126
|
-
console.log(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
program
|
|
131
|
-
.command('search <query>')
|
|
132
|
-
.description('Multi-dimensional search across vector, graph, and facets')
|
|
133
|
-
.option('-l, --limit <number>', 'Number of results', '10')
|
|
134
|
-
.option('-f, --filter <json>', 'Filter by metadata facets')
|
|
135
|
-
.option('-v, --verbs <types>', 'Include related data (comma-separated)')
|
|
136
|
-
.option('-d, --depth <number>', 'Relationship depth', '1')
|
|
137
|
-
.action(wrapAction(async (query, options) => {
|
|
138
|
-
const searchOptions = { limit: parseInt(options.limit) }
|
|
311
|
+
console.log(options.literal
|
|
312
|
+
? colors.info('🔒 Literal storage')
|
|
313
|
+
: colors.success('🧠 Smart mode (auto-detects types)')
|
|
314
|
+
)
|
|
139
315
|
|
|
140
|
-
if (options.
|
|
141
|
-
|
|
142
|
-
searchOptions.filter = JSON.parse(options.filter)
|
|
143
|
-
} catch {
|
|
144
|
-
console.error(chalk.red('Invalid filter JSON'))
|
|
145
|
-
process.exit(1)
|
|
146
|
-
}
|
|
316
|
+
if (options.encrypt) {
|
|
317
|
+
console.log(colors.warning('🔐 Encrypting sensitive data...'))
|
|
147
318
|
}
|
|
148
319
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
|
152
327
|
}
|
|
153
328
|
|
|
154
|
-
await
|
|
329
|
+
await brainyInstance.add(processedData, metadata, {
|
|
330
|
+
process: options.literal ? 'literal' : 'auto'
|
|
331
|
+
})
|
|
332
|
+
console.log(colors.success('✅ Added successfully!'))
|
|
155
333
|
}))
|
|
156
334
|
|
|
335
|
+
// Command 2: CHAT - Talk to your data with AI
|
|
157
336
|
program
|
|
158
|
-
.command('chat [
|
|
159
|
-
.description('
|
|
160
|
-
.option('-
|
|
161
|
-
.option('-
|
|
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')
|
|
162
342
|
.option('-h, --history [limit]', 'Show conversation history (default: 10)')
|
|
163
|
-
.option('--
|
|
164
|
-
.option('--
|
|
165
|
-
.option('--
|
|
166
|
-
.option('--
|
|
167
|
-
.action(
|
|
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) => {
|
|
168
348
|
const { BrainyData } = await import('../dist/brainyData.js')
|
|
349
|
+
const { BrainyChat } = await import('../dist/chat/BrainyChat.js')
|
|
169
350
|
|
|
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
|
|
170
356
|
const brainy = new BrainyData()
|
|
171
357
|
await brainy.init()
|
|
358
|
+
const chat = new BrainyChat(brainy)
|
|
172
359
|
|
|
173
|
-
// Handle
|
|
174
|
-
if (options.
|
|
175
|
-
console.log(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
console.log(
|
|
184
|
-
console.log(
|
|
185
|
-
|
|
186
|
-
console.log('Get started:')
|
|
187
|
-
console.log(' 1. ' + chalk.green('brainy cloud auth') + ' - Authenticate with Brain Cloud')
|
|
188
|
-
console.log(' 2. ' + chalk.cyan('https://app.soulcraft.com') + ' - Sign up for Brain Cloud')
|
|
189
|
-
console.log()
|
|
190
|
-
console.log('Falling back to terminal chat...')
|
|
191
|
-
console.log()
|
|
192
|
-
options.ui = 'terminal'
|
|
193
|
-
} else {
|
|
194
|
-
// Import and start coordination server
|
|
195
|
-
const { createCoordinationServer } = await import('@soulcraft/brain-cloud/coordination/server.js')
|
|
196
|
-
|
|
197
|
-
const server = createCoordinationServer({
|
|
198
|
-
brainy,
|
|
199
|
-
port: 3001
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
await server.start()
|
|
203
|
-
|
|
204
|
-
console.log(chalk.green('✅ Brain Cloud coordination interface started!'))
|
|
205
|
-
console.log()
|
|
206
|
-
console.log('🤝 Multi-agent coordination available at:')
|
|
207
|
-
console.log(' ' + chalk.cyan('http://localhost:3001/coordination'))
|
|
208
|
-
console.log()
|
|
209
|
-
console.log('💡 Features available:')
|
|
210
|
-
console.log(' • Visual agent coordination')
|
|
211
|
-
console.log(' • Real-time multi-agent handoffs')
|
|
212
|
-
console.log(' • Session management')
|
|
213
|
-
console.log(' • Premium Brain Cloud integration')
|
|
214
|
-
console.log()
|
|
215
|
-
|
|
216
|
-
// Try to open browser
|
|
217
|
-
try {
|
|
218
|
-
const { exec } = await import('child_process')
|
|
219
|
-
const { promisify } = await import('util')
|
|
220
|
-
const execAsync = promisify(exec)
|
|
221
|
-
|
|
222
|
-
const command = process.platform === 'win32' ? 'start' :
|
|
223
|
-
process.platform === 'darwin' ? 'open' : 'xdg-open'
|
|
224
|
-
|
|
225
|
-
await execAsync(`${command} "http://localhost:3001/coordination"`)
|
|
226
|
-
console.log(chalk.green('🌐 Opening coordination interface in your browser...'))
|
|
227
|
-
} catch (error) {
|
|
228
|
-
console.log(chalk.yellow('💡 Copy the URL above to open in your browser'))
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
console.log()
|
|
232
|
-
console.log(chalk.dim('Press Ctrl+C to stop the server'))
|
|
233
|
-
|
|
234
|
-
// Keep server running
|
|
235
|
-
process.on('SIGINT', async () => {
|
|
236
|
-
console.log('\n🛑 Stopping coordination server...')
|
|
237
|
-
await server.stop()
|
|
238
|
-
process.exit(0)
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
// Wait indefinitely
|
|
242
|
-
return new Promise(() => {})
|
|
243
|
-
}
|
|
244
|
-
} catch (error) {
|
|
245
|
-
console.log(chalk.red('❌ Failed to start web coordination interface:'), error.message)
|
|
246
|
-
console.log(chalk.yellow('Falling back to terminal chat...'))
|
|
247
|
-
console.log()
|
|
248
|
-
options.ui = 'terminal'
|
|
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!'))
|
|
366
|
+
} else {
|
|
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
|
+
})
|
|
249
373
|
}
|
|
374
|
+
return
|
|
250
375
|
}
|
|
251
376
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
} else if (question) {
|
|
265
|
-
// Single message mode
|
|
266
|
-
await chatCLI.sendMessage(question, {
|
|
267
|
-
sessionId: options.session,
|
|
268
|
-
speaker: options.role
|
|
269
|
-
})
|
|
270
|
-
} else {
|
|
271
|
-
// Interactive chat mode
|
|
272
|
-
await chatCLI.startInteractiveChat({
|
|
273
|
-
sessionId: options.session,
|
|
274
|
-
speaker: options.role,
|
|
275
|
-
newSession: options.new
|
|
276
|
-
})
|
|
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
|
|
277
389
|
}
|
|
278
|
-
}))
|
|
279
|
-
|
|
280
|
-
program
|
|
281
|
-
.command('stats')
|
|
282
|
-
.description('Show database statistics and insights')
|
|
283
|
-
.option('-d, --detailed', 'Show detailed statistics')
|
|
284
|
-
.action(wrapAction(async (options) => {
|
|
285
|
-
await cortex.stats(options.detailed)
|
|
286
|
-
}))
|
|
287
|
-
|
|
288
|
-
program
|
|
289
|
-
.command('health')
|
|
290
|
-
.description('Check system health')
|
|
291
|
-
.option('--auto-fix', 'Automatically apply safe repairs')
|
|
292
|
-
.action(wrapAction(async (options) => {
|
|
293
|
-
await cortex.health(options)
|
|
294
|
-
}))
|
|
295
|
-
|
|
296
|
-
program
|
|
297
|
-
.command('find')
|
|
298
|
-
.description('Advanced intelligent search (interactive)')
|
|
299
|
-
.action(wrapInteractive(async () => {
|
|
300
|
-
await cortex.advancedSearch()
|
|
301
|
-
}))
|
|
302
|
-
|
|
303
|
-
program
|
|
304
|
-
.command('explore [nodeId]')
|
|
305
|
-
.description('Explore data relationships interactively')
|
|
306
|
-
.action(wrapInteractive(async (nodeId) => {
|
|
307
|
-
await cortex.explore(nodeId)
|
|
308
|
-
}))
|
|
309
|
-
|
|
310
|
-
program
|
|
311
|
-
.command('backup')
|
|
312
|
-
.description('Create database backup')
|
|
313
|
-
.option('-c, --compress', 'Compress backup')
|
|
314
|
-
.option('-o, --output <file>', 'Output file')
|
|
315
|
-
.action(wrapAction(async (options) => {
|
|
316
|
-
await cortex.backup(options)
|
|
317
|
-
}))
|
|
318
|
-
|
|
319
|
-
program
|
|
320
|
-
.command('restore <file>')
|
|
321
|
-
.description('Restore from backup')
|
|
322
|
-
.action(wrapInteractive(async (file) => {
|
|
323
|
-
await cortex.restore(file)
|
|
324
|
-
}))
|
|
325
|
-
|
|
326
|
-
// Chat commands moved to main chat command above
|
|
327
|
-
|
|
328
|
-
// ========================================
|
|
329
|
-
// BRAIN CLOUD INTEGRATION
|
|
330
|
-
// ========================================
|
|
331
|
-
|
|
332
|
-
program
|
|
333
|
-
.command('connect')
|
|
334
|
-
.description('Connect to Brain Cloud for AI memory')
|
|
335
|
-
.action(wrapInteractive(async () => {
|
|
336
|
-
console.log(chalk.cyan('\n🧠 Brain Cloud Setup'))
|
|
337
|
-
console.log(chalk.gray('━'.repeat(40)))
|
|
338
390
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
if (
|
|
344
|
-
console.log(
|
|
345
|
-
console.log('\n🔧 Setting up AI memory:')
|
|
346
|
-
console.log(chalk.yellow(' • Update configuration'))
|
|
347
|
-
console.log(chalk.yellow(' • Add memory instructions'))
|
|
348
|
-
console.log(chalk.yellow(' • Enable cross-session memory'))
|
|
349
|
-
|
|
350
|
-
console.log(chalk.cyan('\n🚀 Configuring...'))
|
|
351
|
-
await setupBrainCloudMemory(customerId)
|
|
352
|
-
console.log(chalk.green('\n✅ AI memory connected!'))
|
|
353
|
-
console.log(chalk.cyan('Restart Claude Code to activate memory.'))
|
|
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'))
|
|
354
397
|
} else {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
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()
|
|
403
|
+
})
|
|
359
404
|
}
|
|
360
|
-
|
|
361
|
-
console.log(chalk.red('❌ Setup failed:'), error.message)
|
|
405
|
+
return
|
|
362
406
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
// ========================================
|
|
370
|
-
|
|
371
|
-
const cloud = program
|
|
372
|
-
.command('cloud')
|
|
373
|
-
.description('Brain Cloud premium features and management')
|
|
374
|
-
|
|
375
|
-
cloud
|
|
376
|
-
.command('setup')
|
|
377
|
-
.description('🚀 Auto-setup Brain Cloud (provisions cloud instance + configures locally)')
|
|
378
|
-
.option('--email <email>', 'Your email address')
|
|
379
|
-
.action(wrapInteractive(async (options) => {
|
|
380
|
-
console.log(chalk.cyan('🧠☁️ Brain Cloud Auto-Setup'))
|
|
381
|
-
console.log(chalk.gray('═'.repeat(50)))
|
|
382
|
-
console.log(chalk.yellow('Perfect for non-coders! One-click setup.\n'))
|
|
383
|
-
|
|
384
|
-
try {
|
|
385
|
-
// Step 1: Validate license
|
|
386
|
-
await validateLicense()
|
|
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()
|
|
387
413
|
|
|
388
|
-
//
|
|
389
|
-
await
|
|
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()
|
|
423
|
+
}
|
|
390
424
|
|
|
391
|
-
//
|
|
392
|
-
const
|
|
425
|
+
// Interactive chat loop
|
|
426
|
+
const rl = createInterface({
|
|
427
|
+
input: process.stdin,
|
|
428
|
+
output: process.stdout,
|
|
429
|
+
prompt: colors.primary('You: ')
|
|
430
|
+
})
|
|
393
431
|
|
|
394
|
-
|
|
395
|
-
await configureBrainy(instance)
|
|
432
|
+
rl.prompt()
|
|
396
433
|
|
|
397
|
-
|
|
398
|
-
|
|
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
|
+
}
|
|
440
|
+
|
|
441
|
+
if (input.trim()) {
|
|
442
|
+
// Store user message
|
|
443
|
+
await chat.addMessage(input.trim(), 'user')
|
|
444
|
+
|
|
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()
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
rl.prompt()
|
|
461
|
+
})
|
|
399
462
|
|
|
400
|
-
|
|
401
|
-
|
|
463
|
+
rl.on('close', () => {
|
|
464
|
+
exitProcess(0)
|
|
465
|
+
})
|
|
402
466
|
|
|
403
|
-
console.log('\n✅ Setup Complete!')
|
|
404
|
-
console.log(chalk.gray('═'.repeat(30)))
|
|
405
|
-
console.log('\nYour Brain Cloud instance is ready:')
|
|
406
|
-
console.log(`📱 Dashboard: ${chalk.cyan(instance.endpoints.dashboard)}`)
|
|
407
|
-
console.log(`🔗 API: ${chalk.gray(instance.endpoints.api)}`)
|
|
408
|
-
console.log('\n🚀 What\'s next?')
|
|
409
|
-
console.log('• Your AI now has persistent memory across all conversations')
|
|
410
|
-
console.log('• All devices sync automatically to your cloud instance')
|
|
411
|
-
console.log('• Agents coordinate seamlessly through handoffs')
|
|
412
|
-
console.log('\n💡 Try asking Claude: "Remember that I prefer TypeScript"')
|
|
413
|
-
console.log(' Then in a new conversation: "What do you know about my preferences?"')
|
|
414
|
-
|
|
415
|
-
} catch (error) {
|
|
416
|
-
console.error('\n❌ Setup failed:', error.message)
|
|
417
|
-
console.log('\n🆘 Need help? Contact support@soulcraft.com')
|
|
418
|
-
}
|
|
419
|
-
}))
|
|
420
|
-
|
|
421
|
-
cloud
|
|
422
|
-
.command('connect [id]')
|
|
423
|
-
.description('Connect to existing Brain Cloud instance')
|
|
424
|
-
.action(wrapInteractive(async (id) => {
|
|
425
|
-
if (id) {
|
|
426
|
-
console.log(chalk.green(`✅ Connecting to Brain Cloud instance: ${id}`))
|
|
427
|
-
// Connect to specific instance
|
|
428
467
|
} else {
|
|
429
|
-
//
|
|
430
|
-
console.log(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
468
|
+
// Single message mode
|
|
469
|
+
console.log(colors.success('You: ') + message)
|
|
470
|
+
|
|
471
|
+
try {
|
|
472
|
+
const response = await generateAIResponse(message, brainy, options)
|
|
473
|
+
console.log(colors.info('AI: ') + response)
|
|
474
|
+
|
|
475
|
+
// Store conversation
|
|
476
|
+
await chat.addMessage(message, 'user')
|
|
477
|
+
await chat.addMessage(response, 'assistant', { model: options.model })
|
|
478
|
+
|
|
479
|
+
} catch (error) {
|
|
480
|
+
console.log(colors.error('Error: ') + error.message)
|
|
481
|
+
console.log(colors.info('💡 Try: brainy chat --model local or provide --api-key'))
|
|
482
|
+
}
|
|
436
483
|
}
|
|
437
484
|
}))
|
|
438
485
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
.
|
|
442
|
-
.
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
.command('dashboard [id]')
|
|
449
|
-
.description('Open Brain Cloud dashboard')
|
|
450
|
-
.action(wrapInteractive(async (id) => {
|
|
451
|
-
const dashboardUrl = id
|
|
452
|
-
? `https://brainy-${id}.soulcraft-brain.workers.dev/dashboard`
|
|
453
|
-
: 'https://app.soulcraft.com'
|
|
454
|
-
|
|
455
|
-
console.log(chalk.cyan(`\n🌐 Opening Brain Cloud Dashboard: ${dashboardUrl}`))
|
|
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}`))
|
|
456
495
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
console.log(chalk.yellow('💡 Copy the URL above to open in your browser'))
|
|
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)
|
|
469
507
|
}
|
|
470
508
|
}))
|
|
471
509
|
|
|
472
|
-
//
|
|
510
|
+
// Command 3: SEARCH - Triple-power search
|
|
473
511
|
program
|
|
474
|
-
.command('
|
|
475
|
-
.description('
|
|
476
|
-
.option('--
|
|
477
|
-
.option('--
|
|
478
|
-
.option('--
|
|
479
|
-
.option('--
|
|
480
|
-
.
|
|
481
|
-
.action(wrapInteractive(async (action, options) => {
|
|
482
|
-
console.log(chalk.yellow('⚠️ Deprecated: Use "brainy cloud" commands instead'))
|
|
483
|
-
console.log(chalk.cyan('Examples:'))
|
|
484
|
-
console.log(' brainy cloud setup')
|
|
485
|
-
console.log(' brainy cloud connect <id>')
|
|
486
|
-
console.log(' brainy cloud dashboard')
|
|
487
|
-
console.log('')
|
|
488
|
-
// For now, show connection instructions
|
|
489
|
-
console.log(chalk.cyan('\n⚛️ BRAIN CLOUD - AI Memory That Never Forgets'))
|
|
490
|
-
console.log(chalk.gray('━'.repeat(50)))
|
|
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) => {
|
|
491
519
|
|
|
492
|
-
|
|
493
|
-
|
|
520
|
+
// Handle --fields option
|
|
521
|
+
if (options.fields) {
|
|
522
|
+
console.log(colors.primary('🔍 Available Filter Fields'))
|
|
523
|
+
console.log(colors.primary('=' .repeat(30)))
|
|
494
524
|
|
|
495
525
|
try {
|
|
496
|
-
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
headers: { 'x-customer-id': options.connect }
|
|
500
|
-
})
|
|
526
|
+
const { BrainyData } = await import('../dist/brainyData.js')
|
|
527
|
+
const brainy = new BrainyData()
|
|
528
|
+
await brainy.init()
|
|
501
529
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
console.log(
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
// Test memories endpoint
|
|
509
|
-
const memoriesResponse = await fetch(`https://api.soulcraft.com/brain-cloud/memories`, {
|
|
510
|
-
headers: { 'x-customer-id': options.connect }
|
|
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}`))
|
|
511
535
|
})
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
console.log(chalk.gray('📊 Your atomic memories:'))
|
|
517
|
-
memoriesData.memories.forEach(memory => {
|
|
518
|
-
const time = new Date(memory.created).toLocaleString()
|
|
519
|
-
console.log(chalk.gray(` • ${memory.content} (${time})`))
|
|
520
|
-
})
|
|
521
|
-
}
|
|
522
|
-
|
|
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"}'`))
|
|
523
540
|
} else {
|
|
524
|
-
console.log(
|
|
525
|
-
console.log(
|
|
526
|
-
console.log('\nSign up at: ' + chalk.cyan('https://app.soulcraft.com'))
|
|
541
|
+
console.log(colors.warning('No indexed fields available yet.'))
|
|
542
|
+
console.log(colors.info('Add some data with metadata to see available fields.'))
|
|
527
543
|
}
|
|
544
|
+
|
|
528
545
|
} catch (error) {
|
|
529
|
-
console.log(
|
|
530
|
-
console.log('\nSign up at: ' + chalk.cyan('https://app.soulcraft.com'))
|
|
546
|
+
console.log(colors.error(`Error: ${error.message}`))
|
|
531
547
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
548
|
+
return
|
|
549
|
+
}
|
|
550
|
+
console.log(colors.info(`🔍 Searching: "${query}"`))
|
|
551
|
+
|
|
552
|
+
const searchOptions = {
|
|
553
|
+
limit: parseInt(options.limit),
|
|
554
|
+
depth: parseInt(options.depth)
|
|
555
|
+
}
|
|
556
|
+
|
|
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)
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
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
|
|
572
|
+
}
|
|
573
|
+
|
|
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)}%`))
|
|
579
|
+
}
|
|
580
|
+
if (result.type) {
|
|
581
|
+
console.log(colors.info(` Type: ${result.type}`))
|
|
582
|
+
}
|
|
583
|
+
})
|
|
584
|
+
}))
|
|
585
|
+
|
|
586
|
+
// Command 4: UPDATE - Update existing data
|
|
587
|
+
program
|
|
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)
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
let metadata = undefined
|
|
604
|
+
if (options.metadata) {
|
|
535
605
|
try {
|
|
536
|
-
|
|
537
|
-
|
|
606
|
+
metadata = JSON.parse(options.metadata)
|
|
607
|
+
} catch {
|
|
608
|
+
console.error(colors.error('Invalid JSON metadata'))
|
|
609
|
+
process.exit(1)
|
|
610
|
+
}
|
|
611
|
+
}
|
|
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
|
+
}
|
|
626
|
+
} else {
|
|
627
|
+
console.log(colors.error('❌ Update failed'))
|
|
628
|
+
}
|
|
629
|
+
}))
|
|
630
|
+
|
|
631
|
+
// Command 5: DELETE - Remove data (soft delete by default)
|
|
632
|
+
program
|
|
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'))
|
|
643
|
+
} else {
|
|
644
|
+
console.log(colors.info('🔒 Soft delete - data marked as deleted but preserved'))
|
|
645
|
+
}
|
|
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
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}))
|
|
671
|
+
|
|
672
|
+
// Command 6: STATUS - Database health & info
|
|
673
|
+
program
|
|
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)))
|
|
681
|
+
|
|
682
|
+
try {
|
|
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
|
|
700
|
+
}
|
|
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}`))
|
|
538
718
|
})
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
console.log(
|
|
549
|
-
console.log(chalk.gray(`📊 Exported ${data.memories?.length || 0} memories`))
|
|
550
|
-
} else {
|
|
551
|
-
console.log(chalk.red('❌ Export failed - instance not found'))
|
|
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`))
|
|
552
729
|
}
|
|
553
|
-
|
|
554
|
-
|
|
730
|
+
if (stats.storage.location) {
|
|
731
|
+
console.log(colors.info(` Location: ${colors.success(stats.storage.location)}`))
|
|
732
|
+
}
|
|
733
|
+
console.log()
|
|
555
734
|
}
|
|
556
|
-
} else if (options.status) {
|
|
557
|
-
console.log(chalk.green(`🔍 Checking status of Brain Cloud instance: ${options.status}`))
|
|
558
735
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
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}`))
|
|
779
|
+
}
|
|
562
780
|
})
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
//
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
if (memoriesResponse.ok) {
|
|
576
|
-
const memoriesData = await memoriesResponse.json()
|
|
577
|
-
console.log(chalk.yellow(`📊 Total memories: ${memoriesData.count}`))
|
|
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)}`))
|
|
578
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"}\''))
|
|
579
808
|
} else {
|
|
580
|
-
console.log(
|
|
809
|
+
console.log(colors.warning(' No indexed fields available yet'))
|
|
810
|
+
console.log(colors.info(' Add some data to see available fields'))
|
|
581
811
|
}
|
|
582
812
|
} catch (error) {
|
|
583
|
-
console.log(
|
|
813
|
+
console.log(colors.warning(' Field discovery not available'))
|
|
584
814
|
}
|
|
585
|
-
|
|
586
|
-
console.log(chalk.green(`🌐 Opening dashboard for Brain Cloud instance: ${options.dashboard}`))
|
|
815
|
+
console.log()
|
|
587
816
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
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
|
+
}
|
|
591
822
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
const command = process.platform === 'win32' ? 'start' :
|
|
599
|
-
process.platform === 'darwin' ? 'open' : 'xdg-open'
|
|
600
|
-
|
|
601
|
-
await execAsync(`${command} "${dashboardUrl}"`)
|
|
602
|
-
console.log(chalk.green('✅ Dashboard opened!'))
|
|
603
|
-
} catch (error) {
|
|
604
|
-
console.log(chalk.yellow('💡 Copy the URL above to open in your browser'))
|
|
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)
|
|
605
829
|
}
|
|
606
|
-
} else {
|
|
607
|
-
console.log(chalk.yellow('📡 Brain Cloud Setup'))
|
|
608
|
-
console.log('\n1. Sign up at: ' + chalk.cyan('https://app.soulcraft.com'))
|
|
609
|
-
console.log('2. Get your customer ID')
|
|
610
|
-
console.log('3. Connect with: ' + chalk.green('brainy cloud --connect YOUR_ID'))
|
|
611
|
-
console.log('\nBenefits:')
|
|
612
|
-
console.log(' • ' + chalk.green('Never lose AI context again'))
|
|
613
|
-
console.log(' • ' + chalk.green('Sync across all devices'))
|
|
614
|
-
console.log(' • ' + chalk.green('Unlimited memory storage'))
|
|
615
|
-
console.log(' • ' + chalk.green('$19/month or free trial'))
|
|
616
830
|
}
|
|
617
831
|
}))
|
|
618
832
|
|
|
619
|
-
//
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
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
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
if (configActions[action]) {
|
|
865
|
+
await configActions[action]()
|
|
866
|
+
} else {
|
|
867
|
+
console.error(colors.error('Valid actions: get, set, list'))
|
|
868
|
+
process.exit(1)
|
|
869
|
+
}
|
|
870
|
+
}))
|
|
626
871
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
.
|
|
630
|
-
.
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
872
|
+
// Command 6: AUGMENT - Manage augmentations (The 8th Unified Method!)
|
|
873
|
+
program
|
|
874
|
+
.command('augment <action>')
|
|
875
|
+
.description('Manage augmentations to extend Brainy\'s capabilities')
|
|
876
|
+
.option('-n, --name <name>', 'Augmentation name')
|
|
877
|
+
.option('-t, --type <type>', 'Augmentation type (sense, conduit, cognition, memory)')
|
|
878
|
+
.option('-p, --path <path>', 'Path to augmentation module')
|
|
879
|
+
.option('-l, --list', 'List all augmentations')
|
|
880
|
+
.action(wrapAction(async (action, options) => {
|
|
881
|
+
const brainy = await initBrainy()
|
|
882
|
+
console.log(colors.brain('🧩 Augmentation Management'))
|
|
635
883
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
884
|
+
const actions = {
|
|
885
|
+
list: async () => {
|
|
886
|
+
const augmentations = brainy.listAugmentations()
|
|
887
|
+
if (augmentations.length === 0) {
|
|
888
|
+
console.log(colors.warning('No augmentations registered'))
|
|
889
|
+
return
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
const table = new Table({
|
|
893
|
+
head: [colors.brain('Name'), colors.brain('Type'), colors.brain('Status'), colors.brain('Description')],
|
|
894
|
+
style: { head: [], border: [] }
|
|
895
|
+
})
|
|
896
|
+
|
|
897
|
+
augmentations.forEach(aug => {
|
|
898
|
+
table.push([
|
|
899
|
+
colors.primary(aug.name),
|
|
900
|
+
colors.info(aug.type),
|
|
901
|
+
aug.enabled ? colors.success('✅ Enabled') : colors.dim('⚪ Disabled'),
|
|
902
|
+
colors.dim(aug.description || '')
|
|
903
|
+
])
|
|
904
|
+
})
|
|
905
|
+
|
|
906
|
+
console.log(table.toString())
|
|
907
|
+
console.log(colors.info(`\nTotal: ${augmentations.length} augmentations`))
|
|
908
|
+
},
|
|
640
909
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
910
|
+
enable: async () => {
|
|
911
|
+
if (!options.name) {
|
|
912
|
+
console.log(colors.error('Name required: --name <augmentation-name>'))
|
|
913
|
+
return
|
|
914
|
+
}
|
|
915
|
+
const success = brainy.enableAugmentation(options.name)
|
|
916
|
+
if (success) {
|
|
917
|
+
console.log(colors.success(`✅ Enabled augmentation: ${options.name}`))
|
|
918
|
+
} else {
|
|
919
|
+
console.log(colors.error(`Failed to enable: ${options.name} (not found)`))
|
|
920
|
+
}
|
|
921
|
+
},
|
|
922
|
+
|
|
923
|
+
disable: async () => {
|
|
924
|
+
if (!options.name) {
|
|
925
|
+
console.log(colors.error('Name required: --name <augmentation-name>'))
|
|
926
|
+
return
|
|
927
|
+
}
|
|
928
|
+
const success = brainy.disableAugmentation(options.name)
|
|
929
|
+
if (success) {
|
|
930
|
+
console.log(colors.warning(`⚪ Disabled augmentation: ${options.name}`))
|
|
931
|
+
} else {
|
|
932
|
+
console.log(colors.error(`Failed to disable: ${options.name} (not found)`))
|
|
933
|
+
}
|
|
934
|
+
},
|
|
935
|
+
|
|
936
|
+
register: async () => {
|
|
937
|
+
if (!options.path) {
|
|
938
|
+
console.log(colors.error('Path required: --path <augmentation-module>'))
|
|
939
|
+
return
|
|
940
|
+
}
|
|
654
941
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
console.log(
|
|
662
|
-
|
|
663
|
-
|
|
942
|
+
try {
|
|
943
|
+
// Dynamic import of custom augmentation
|
|
944
|
+
const customModule = await import(options.path)
|
|
945
|
+
const AugmentationClass = customModule.default || customModule[Object.keys(customModule)[0]]
|
|
946
|
+
|
|
947
|
+
if (!AugmentationClass) {
|
|
948
|
+
console.log(colors.error('No augmentation class found in module'))
|
|
949
|
+
return
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
const augmentation = new AugmentationClass()
|
|
953
|
+
brainy.register(augmentation)
|
|
954
|
+
console.log(colors.success(`✅ Registered augmentation: ${augmentation.name}`))
|
|
955
|
+
console.log(colors.info(`Type: ${augmentation.type}`))
|
|
956
|
+
if (augmentation.description) {
|
|
957
|
+
console.log(colors.dim(`Description: ${augmentation.description}`))
|
|
958
|
+
}
|
|
959
|
+
} catch (error) {
|
|
960
|
+
console.log(colors.error(`Failed to register augmentation: ${error.message}`))
|
|
961
|
+
}
|
|
962
|
+
},
|
|
963
|
+
|
|
964
|
+
unregister: async () => {
|
|
965
|
+
if (!options.name) {
|
|
966
|
+
console.log(colors.error('Name required: --name <augmentation-name>'))
|
|
967
|
+
return
|
|
664
968
|
}
|
|
665
969
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
970
|
+
brainy.unregister(options.name)
|
|
971
|
+
console.log(colors.warning(`🗑️ Unregistered augmentation: ${options.name}`))
|
|
972
|
+
},
|
|
973
|
+
|
|
974
|
+
'enable-type': async () => {
|
|
975
|
+
if (!options.type) {
|
|
976
|
+
console.log(colors.error('Type required: --type <augmentation-type>'))
|
|
977
|
+
console.log(colors.info('Valid types: sense, conduit, cognition, memory, perception, dialog, activation'))
|
|
978
|
+
return
|
|
675
979
|
}
|
|
676
|
-
|
|
677
|
-
|
|
980
|
+
|
|
981
|
+
const count = brainy.enableAugmentationType(options.type)
|
|
982
|
+
console.log(colors.success(`✅ Enabled ${count} ${options.type} augmentations`))
|
|
983
|
+
},
|
|
984
|
+
|
|
985
|
+
'disable-type': async () => {
|
|
986
|
+
if (!options.type) {
|
|
987
|
+
console.log(colors.error('Type required: --type <augmentation-type>'))
|
|
988
|
+
console.log(colors.info('Valid types: sense, conduit, cognition, memory, perception, dialog, activation'))
|
|
989
|
+
return
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
const count = brainy.disableAugmentationType(options.type)
|
|
993
|
+
console.log(colors.warning(`⚪ Disabled ${count} ${options.type} augmentations`))
|
|
678
994
|
}
|
|
679
|
-
} catch (error) {
|
|
680
|
-
// Fallback to static list if API is unavailable
|
|
681
|
-
console.log(chalk.cyan('🌟 Available (Brain Cloud):'))
|
|
682
|
-
console.log(' • ai-memory - ' + chalk.yellow('⭐ Popular') + ' - Persistent AI memory')
|
|
683
|
-
console.log(' • agent-coordinator - ' + chalk.yellow('⭐ Popular') + ' - Multi-agent handoffs')
|
|
684
|
-
console.log(' • notion-sync - Enterprise connector')
|
|
685
|
-
console.log('')
|
|
686
995
|
}
|
|
687
996
|
|
|
688
|
-
|
|
689
|
-
|
|
997
|
+
if (actions[action]) {
|
|
998
|
+
await actions[action]()
|
|
999
|
+
} else {
|
|
1000
|
+
console.log(colors.error('Valid actions: list, enable, disable, register, unregister, enable-type, disable-type'))
|
|
1001
|
+
console.log(colors.info('\nExamples:'))
|
|
1002
|
+
console.log(colors.dim(' brainy augment list # List all augmentations'))
|
|
1003
|
+
console.log(colors.dim(' brainy augment enable --name neural-import # Enable an augmentation'))
|
|
1004
|
+
console.log(colors.dim(' brainy augment register --path ./my-augmentation.js # Register custom augmentation'))
|
|
1005
|
+
console.log(colors.dim(' brainy augment enable-type --type sense # Enable all sense augmentations'))
|
|
1006
|
+
}
|
|
690
1007
|
}))
|
|
691
1008
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
.
|
|
695
|
-
.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
1009
|
+
// Command 7: EXPORT - Export your data
|
|
1010
|
+
program
|
|
1011
|
+
.command('export')
|
|
1012
|
+
.description('Export your brain data in various formats')
|
|
1013
|
+
.option('-f, --format <format>', 'Export format (json, csv, graph, embeddings)', 'json')
|
|
1014
|
+
.option('-o, --output <file>', 'Output file path')
|
|
1015
|
+
.option('--vectors', 'Include vector embeddings')
|
|
1016
|
+
.option('--no-metadata', 'Exclude metadata')
|
|
1017
|
+
.option('--no-relationships', 'Exclude relationships')
|
|
1018
|
+
.option('--filter <json>', 'Filter by metadata')
|
|
1019
|
+
.option('-l, --limit <number>', 'Limit number of items')
|
|
1020
|
+
.action(wrapAction(async (options) => {
|
|
1021
|
+
const brainy = await initBrainy()
|
|
1022
|
+
console.log(colors.brain('📤 Exporting Brain Data'))
|
|
700
1023
|
|
|
701
|
-
|
|
702
|
-
console.log('')
|
|
703
|
-
console.log(chalk.yellow('Note: Brainy core is 100% free and fully functional!'))
|
|
704
|
-
console.log('Brain Cloud adds optional team & sync features.')
|
|
705
|
-
console.log('')
|
|
706
|
-
console.log('Get Brain Cloud at: ' + chalk.green('app.soulcraft.com'))
|
|
707
|
-
console.log('(14-day free trial available)')
|
|
708
|
-
console.log('')
|
|
1024
|
+
const spinner = ora('Exporting data...').start()
|
|
709
1025
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
1026
|
+
try {
|
|
1027
|
+
const exportOptions = {
|
|
1028
|
+
format: options.format,
|
|
1029
|
+
includeVectors: options.vectors || false,
|
|
1030
|
+
includeMetadata: options.metadata !== false,
|
|
1031
|
+
includeRelationships: options.relationships !== false,
|
|
1032
|
+
filter: options.filter ? JSON.parse(options.filter) : {},
|
|
1033
|
+
limit: options.limit ? parseInt(options.limit) : undefined
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
const data = await brainy.export(exportOptions)
|
|
1037
|
+
|
|
1038
|
+
spinner.succeed('Export complete')
|
|
1039
|
+
|
|
1040
|
+
if (options.output) {
|
|
1041
|
+
// Write to file
|
|
1042
|
+
const fs = require('fs')
|
|
1043
|
+
const content = typeof data === 'string' ? data : JSON.stringify(data, null, 2)
|
|
1044
|
+
fs.writeFileSync(options.output, content)
|
|
1045
|
+
console.log(colors.success(`✅ Exported to: ${options.output}`))
|
|
719
1046
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
console.log(
|
|
723
|
-
console.log(
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
console.log(chalk.gray(' # Your augmentations will auto-load'))
|
|
1047
|
+
// Show summary
|
|
1048
|
+
const items = Array.isArray(data) ? data.length : (data.nodes ? data.nodes.length : 1)
|
|
1049
|
+
console.log(colors.info(`📊 Format: ${options.format}`))
|
|
1050
|
+
console.log(colors.info(`📁 Items: ${items}`))
|
|
1051
|
+
if (options.vectors) {
|
|
1052
|
+
console.log(colors.info(`🔢 Vectors: Included`))
|
|
1053
|
+
}
|
|
728
1054
|
} else {
|
|
729
|
-
|
|
1055
|
+
// Output to console
|
|
1056
|
+
if (typeof data === 'string') {
|
|
1057
|
+
console.log(data)
|
|
1058
|
+
} else {
|
|
1059
|
+
console.log(JSON.stringify(data, null, 2))
|
|
1060
|
+
}
|
|
730
1061
|
}
|
|
731
|
-
|
|
732
|
-
|
|
1062
|
+
} catch (error) {
|
|
1063
|
+
spinner.fail('Export failed')
|
|
1064
|
+
console.error(colors.error(error.message))
|
|
1065
|
+
process.exit(1)
|
|
1066
|
+
}
|
|
733
1067
|
}))
|
|
734
1068
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
.
|
|
738
|
-
.
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
1069
|
+
// Command 8: CLOUD - Premium features connection
|
|
1070
|
+
program
|
|
1071
|
+
.command('cloud <action>')
|
|
1072
|
+
.description('☁️ Brain Cloud - AI Memory, Team Sync, Enterprise Connectors (FREE TRIAL!)')
|
|
1073
|
+
.option('-i, --instance <id>', 'Brain Cloud instance ID')
|
|
1074
|
+
.option('-e, --email <email>', 'Your email for signup')
|
|
1075
|
+
.action(wrapAction(async (action, options) => {
|
|
1076
|
+
console.log(boxen(
|
|
1077
|
+
colors.brain('☁️ BRAIN CLOUD - SUPERCHARGE YOUR BRAIN! 🚀\n\n') +
|
|
1078
|
+
colors.success('✨ FREE TRIAL: First 100GB FREE!\n') +
|
|
1079
|
+
colors.info('💰 Then just $9/month (individuals) or $49/month (teams)\n\n') +
|
|
1080
|
+
colors.primary('Features:\n') +
|
|
1081
|
+
colors.dim(' • AI Memory that persists across sessions\n') +
|
|
1082
|
+
colors.dim(' • Multi-agent coordination\n') +
|
|
1083
|
+
colors.dim(' • Automatic backups & sync\n') +
|
|
1084
|
+
colors.dim(' • Premium connectors (Notion, Slack, etc.)'),
|
|
1085
|
+
{ padding: 1, borderStyle: 'round', borderColor: 'cyan' }
|
|
1086
|
+
))
|
|
1087
|
+
|
|
1088
|
+
const cloudActions = {
|
|
1089
|
+
setup: async () => {
|
|
1090
|
+
console.log(colors.brain('\n🚀 Quick Setup - 30 seconds to superpowers!\n'))
|
|
1091
|
+
|
|
1092
|
+
if (!options.email) {
|
|
1093
|
+
const { email } = await prompts({
|
|
1094
|
+
type: 'text',
|
|
1095
|
+
name: 'email',
|
|
1096
|
+
message: 'Enter your email for FREE trial:',
|
|
1097
|
+
validate: (value) => value.includes('@') || 'Please enter a valid email'
|
|
1098
|
+
})
|
|
1099
|
+
options.email = email
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
console.log(colors.success(`\n✅ Setting up Brain Cloud for: ${options.email}`))
|
|
1103
|
+
console.log(colors.info('\n📧 Check your email for activation link!'))
|
|
1104
|
+
console.log(colors.dim('\nOr visit: https://app.soulcraft.com/activate\n'))
|
|
1105
|
+
|
|
1106
|
+
// TODO: Actually call Brain Cloud API when ready
|
|
1107
|
+
console.log(colors.brain('🎉 Your Brain Cloud trial is ready!'))
|
|
1108
|
+
console.log(colors.success('\nNext steps:'))
|
|
1109
|
+
console.log(colors.dim(' 1. Check your email for API key'))
|
|
1110
|
+
console.log(colors.dim(' 2. Run: brainy cloud connect --key YOUR_KEY'))
|
|
1111
|
+
console.log(colors.dim(' 3. Start using persistent AI memory!'))
|
|
1112
|
+
},
|
|
1113
|
+
connect: async () => {
|
|
1114
|
+
console.log(colors.info('🔗 Connecting to Brain Cloud...'))
|
|
1115
|
+
// Dynamic import to avoid loading premium code unnecessarily
|
|
1116
|
+
try {
|
|
1117
|
+
const { BrainCloudSDK } = await import('@brainy-cloud/sdk')
|
|
1118
|
+
const connected = await BrainCloudSDK.connect(options.instance)
|
|
1119
|
+
if (connected) {
|
|
1120
|
+
console.log(colors.success('✅ Connected to Brain Cloud'))
|
|
1121
|
+
console.log(colors.info(`Instance: ${connected.instanceId}`))
|
|
1122
|
+
}
|
|
1123
|
+
} catch (error) {
|
|
1124
|
+
console.log(colors.warning('⚠️ Brain Cloud SDK not installed'))
|
|
1125
|
+
console.log(colors.info('Install with: npm install @brainy-cloud/sdk'))
|
|
1126
|
+
console.log(colors.info('Or visit: https://brain-cloud.soulcraft.com'))
|
|
1127
|
+
}
|
|
755
1128
|
},
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
1129
|
+
status: async () => {
|
|
1130
|
+
try {
|
|
1131
|
+
const { BrainCloudSDK } = await import('@brainy-cloud/sdk')
|
|
1132
|
+
const status = await BrainCloudSDK.getStatus()
|
|
1133
|
+
console.log(colors.success('☁️ Cloud Status: Connected'))
|
|
1134
|
+
console.log(colors.info(`Instance: ${status.instanceId}`))
|
|
1135
|
+
console.log(colors.info(`Augmentations: ${status.augmentationCount} available`))
|
|
1136
|
+
} catch {
|
|
1137
|
+
console.log(colors.warning('☁️ Cloud Status: Not connected'))
|
|
1138
|
+
console.log(colors.info('Use "brainy cloud connect" to connect'))
|
|
1139
|
+
}
|
|
762
1140
|
},
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
1141
|
+
augmentations: async () => {
|
|
1142
|
+
try {
|
|
1143
|
+
const { BrainCloudSDK } = await import('@brainy-cloud/sdk')
|
|
1144
|
+
const augs = await BrainCloudSDK.listAugmentations()
|
|
1145
|
+
console.log(colors.primary('🧩 Available Premium Augmentations:'))
|
|
1146
|
+
augs.forEach(aug => {
|
|
1147
|
+
console.log(colors.success(` ✅ ${aug.name} - ${aug.description}`))
|
|
1148
|
+
})
|
|
1149
|
+
} catch {
|
|
1150
|
+
console.log(colors.warning('Connect to Brain Cloud first: brainy cloud connect'))
|
|
1151
|
+
}
|
|
768
1152
|
}
|
|
769
1153
|
}
|
|
770
1154
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
console.log(chalk.cyan(`📦 ${aug.name}`) + (aug.popular ? chalk.yellow(' ⭐ Popular') : ''))
|
|
774
|
-
console.log('')
|
|
775
|
-
console.log(`Category: ${aug.category}`)
|
|
776
|
-
console.log(`Tier: ${aug.tier}`)
|
|
777
|
-
console.log(`Description: ${aug.description}`)
|
|
778
|
-
if (aug.example) {
|
|
779
|
-
console.log('')
|
|
780
|
-
console.log('Example:')
|
|
781
|
-
console.log(chalk.gray(aug.example))
|
|
782
|
-
}
|
|
1155
|
+
if (cloudActions[action]) {
|
|
1156
|
+
await cloudActions[action]()
|
|
783
1157
|
} else {
|
|
784
|
-
console.log(
|
|
1158
|
+
console.log(colors.error('Valid actions: connect, status, augmentations'))
|
|
1159
|
+
console.log(colors.info('Example: brainy cloud connect --instance demo-test-auto'))
|
|
785
1160
|
}
|
|
786
1161
|
}))
|
|
787
1162
|
|
|
1163
|
+
// Command 7: MIGRATE - Migration tools
|
|
788
1164
|
program
|
|
789
|
-
.command('
|
|
790
|
-
.description('
|
|
791
|
-
.option('-
|
|
792
|
-
.option('-
|
|
793
|
-
.action(wrapAction(async (
|
|
794
|
-
console.log(
|
|
1165
|
+
.command('migrate <action>')
|
|
1166
|
+
.description('Migration tools for upgrades')
|
|
1167
|
+
.option('-f, --from <version>', 'Migrate from version')
|
|
1168
|
+
.option('-b, --backup', 'Create backup before migration')
|
|
1169
|
+
.action(wrapAction(async (action, options) => {
|
|
1170
|
+
console.log(colors.primary('🔄 Brainy Migration Tools'))
|
|
795
1171
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
1172
|
+
const migrateActions = {
|
|
1173
|
+
check: async () => {
|
|
1174
|
+
console.log(colors.info('🔍 Checking for migration needs...'))
|
|
1175
|
+
// Check for deprecated methods, old config, etc.
|
|
1176
|
+
const issues = []
|
|
1177
|
+
|
|
802
1178
|
try {
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
1179
|
+
const { BrainyData } = await import('../dist/brainyData.js')
|
|
1180
|
+
const brainy = new BrainyData()
|
|
1181
|
+
|
|
1182
|
+
// Check for old API usage
|
|
1183
|
+
console.log(colors.success('✅ No migration issues found'))
|
|
1184
|
+
} catch (error) {
|
|
1185
|
+
console.log(colors.warning(`⚠️ Found issues: ${error.message}`))
|
|
1186
|
+
}
|
|
1187
|
+
},
|
|
1188
|
+
backup: async () => {
|
|
1189
|
+
console.log(colors.info('💾 Creating backup...'))
|
|
1190
|
+
const { BrainyData } = await import('../dist/brainyData.js')
|
|
1191
|
+
const brainy = new BrainyData()
|
|
1192
|
+
const backup = await brainy.createBackup()
|
|
1193
|
+
console.log(colors.success(`✅ Backup created: ${backup.path}`))
|
|
1194
|
+
},
|
|
1195
|
+
restore: async () => {
|
|
1196
|
+
if (!options.from) {
|
|
1197
|
+
console.error(colors.error('Please specify backup file: --from <path>'))
|
|
806
1198
|
process.exit(1)
|
|
807
1199
|
}
|
|
1200
|
+
console.log(colors.info(`📥 Restoring from: ${options.from}`))
|
|
1201
|
+
const { BrainyData } = await import('../dist/brainyData.js')
|
|
1202
|
+
const brainy = new BrainyData()
|
|
1203
|
+
await brainy.restoreBackup(options.from)
|
|
1204
|
+
console.log(colors.success('✅ Restore complete'))
|
|
808
1205
|
}
|
|
809
|
-
await cortex.addAugmentation(augmentation, undefined, config)
|
|
810
1206
|
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
.command('run <augmentation>')
|
|
815
|
-
.description('Run augmentation')
|
|
816
|
-
.option('-c, --config <json>', 'Runtime configuration as JSON')
|
|
817
|
-
.action(wrapAction(async (augmentation, options) => {
|
|
818
|
-
if (augmentation === 'brain-jar') {
|
|
819
|
-
await cortex.brainJarStart(options)
|
|
1207
|
+
|
|
1208
|
+
if (migrateActions[action]) {
|
|
1209
|
+
await migrateActions[action]()
|
|
820
1210
|
} else {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
await cortex.executePipelineStep(augmentation, inputData)
|
|
1211
|
+
console.log(colors.error('Valid actions: check, backup, restore'))
|
|
1212
|
+
console.log(colors.info('Example: brainy migrate check'))
|
|
824
1213
|
}
|
|
825
1214
|
}))
|
|
826
1215
|
|
|
1216
|
+
// Command 8: HELP - Interactive guidance
|
|
827
1217
|
program
|
|
828
|
-
.command('
|
|
829
|
-
.description('
|
|
830
|
-
.action(wrapAction(async (
|
|
831
|
-
if (
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
// Show specific augmentation status
|
|
835
|
-
await cortex.listAugmentations()
|
|
836
|
-
} else {
|
|
837
|
-
// Show all augmentation status
|
|
838
|
-
await cortex.listAugmentations()
|
|
1218
|
+
.command('help [command]')
|
|
1219
|
+
.description('Get help or enter interactive mode')
|
|
1220
|
+
.action(wrapAction(async (command) => {
|
|
1221
|
+
if (command) {
|
|
1222
|
+
program.help()
|
|
1223
|
+
return
|
|
839
1224
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
1225
|
+
|
|
1226
|
+
// Interactive mode for beginners
|
|
1227
|
+
console.log(colors.primary('🧠⚛️ Welcome to Brainy!'))
|
|
1228
|
+
console.log(colors.info('Your AI-powered second brain'))
|
|
1229
|
+
console.log()
|
|
1230
|
+
|
|
1231
|
+
const rl = createInterface({
|
|
1232
|
+
input: process.stdin,
|
|
1233
|
+
output: process.stdout
|
|
1234
|
+
})
|
|
1235
|
+
|
|
1236
|
+
console.log(colors.primary('What would you like to do?'))
|
|
1237
|
+
console.log(colors.info('1. Add some data'))
|
|
1238
|
+
console.log(colors.info('2. Chat with AI using your data'))
|
|
1239
|
+
console.log(colors.info('3. Search your brain'))
|
|
1240
|
+
console.log(colors.info('4. Update existing data'))
|
|
1241
|
+
console.log(colors.info('5. Delete data'))
|
|
1242
|
+
console.log(colors.info('6. Import a file'))
|
|
1243
|
+
console.log(colors.info('7. Check status'))
|
|
1244
|
+
console.log(colors.info('8. Connect to Brain Cloud'))
|
|
1245
|
+
console.log(colors.info('9. Configuration'))
|
|
1246
|
+
console.log(colors.info('10. Show all commands'))
|
|
1247
|
+
console.log()
|
|
1248
|
+
|
|
1249
|
+
const choice = await new Promise(resolve => {
|
|
1250
|
+
rl.question(colors.primary('Enter your choice (1-10): '), (answer) => {
|
|
1251
|
+
rl.close()
|
|
1252
|
+
resolve(answer)
|
|
1253
|
+
})
|
|
1254
|
+
})
|
|
1255
|
+
|
|
1256
|
+
switch (choice) {
|
|
1257
|
+
case '1':
|
|
1258
|
+
console.log(colors.success('\n🧠 Use: brainy add "your data here"'))
|
|
1259
|
+
console.log(colors.info('Example: brainy add "John works at Google"'))
|
|
1260
|
+
break
|
|
1261
|
+
case '2':
|
|
1262
|
+
console.log(colors.success('\n💬 Use: brainy chat "your question"'))
|
|
1263
|
+
console.log(colors.info('Example: brainy chat "Tell me about my data"'))
|
|
1264
|
+
console.log(colors.info('Supports: local (Ollama), OpenAI, Claude'))
|
|
1265
|
+
break
|
|
1266
|
+
case '3':
|
|
1267
|
+
console.log(colors.success('\n🔍 Use: brainy search "your query"'))
|
|
1268
|
+
console.log(colors.info('Example: brainy search "Google employees"'))
|
|
1269
|
+
break
|
|
1270
|
+
case '4':
|
|
1271
|
+
console.log(colors.success('\n📥 Use: brainy import <file-or-url>'))
|
|
1272
|
+
console.log(colors.info('Example: brainy import data.txt'))
|
|
1273
|
+
break
|
|
1274
|
+
case '5':
|
|
1275
|
+
console.log(colors.success('\n📊 Use: brainy status'))
|
|
1276
|
+
console.log(colors.info('Shows comprehensive brain statistics'))
|
|
1277
|
+
console.log(colors.info('Options: --simple (quick) or --verbose (detailed)'))
|
|
1278
|
+
break
|
|
1279
|
+
case '6':
|
|
1280
|
+
console.log(colors.success('\n☁️ Use: brainy cloud connect'))
|
|
1281
|
+
console.log(colors.info('Example: brainy cloud connect --instance demo-test-auto'))
|
|
1282
|
+
break
|
|
1283
|
+
case '7':
|
|
1284
|
+
console.log(colors.success('\n🔧 Use: brainy config <action>'))
|
|
1285
|
+
console.log(colors.info('Example: brainy config list'))
|
|
1286
|
+
break
|
|
1287
|
+
case '8':
|
|
1288
|
+
program.help()
|
|
1289
|
+
break
|
|
1290
|
+
default:
|
|
1291
|
+
console.log(colors.warning('Invalid choice. Use "brainy --help" for all commands.'))
|
|
850
1292
|
}
|
|
851
1293
|
}))
|
|
852
1294
|
|
|
853
|
-
program
|
|
854
|
-
.command('list')
|
|
855
|
-
.description('List installed augmentations')
|
|
856
|
-
.option('-a, --available', 'Show available augmentations')
|
|
857
|
-
.action(wrapAction(async (options) => {
|
|
858
|
-
if (options.available) {
|
|
859
|
-
console.log(chalk.green('✅ Built-in (Free):'))
|
|
860
|
-
console.log(' • neural-import - AI-powered data understanding')
|
|
861
|
-
console.log(' • basic-storage - Local persistence')
|
|
862
|
-
console.log('')
|
|
863
|
-
console.log(chalk.cyan('🌟 Premium (Brain Cloud):'))
|
|
864
|
-
console.log(' • ai-memory - ' + chalk.yellow('⭐ Most Popular') + ' - AI that remembers')
|
|
865
|
-
console.log(' • agent-coordinator - ' + chalk.yellow('⭐ Most Popular') + ' - Multi-agent orchestration')
|
|
866
|
-
console.log(' • notion-sync - Enterprise connector')
|
|
867
|
-
console.log(' • More at app.soulcraft.com/augmentations')
|
|
868
|
-
console.log('')
|
|
869
|
-
console.log(chalk.dim('Sign up: app.soulcraft.com (14-day free trial)'))
|
|
870
|
-
console.log(chalk.dim('Authenticate: brainy cloud auth'))
|
|
871
|
-
} else {
|
|
872
|
-
await cortex.listAugmentations()
|
|
873
|
-
}
|
|
874
|
-
}))
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
// ========================================
|
|
878
|
-
// BRAIN JAR SPECIFIC COMMANDS (Rich UX)
|
|
879
|
-
// ========================================
|
|
880
|
-
|
|
881
|
-
const brainJar = program.command('brain-jar')
|
|
882
|
-
.description('AI coordination and collaboration')
|
|
883
|
-
|
|
884
|
-
brainJar
|
|
885
|
-
.command('install')
|
|
886
|
-
.description('Install Brain Jar coordination')
|
|
887
|
-
.option('-m, --mode <type>', 'Installation mode (free|premium)', 'free')
|
|
888
|
-
.action(wrapAction(async (options) => {
|
|
889
|
-
await cortex.brainJarInstall(options.mode)
|
|
890
|
-
}))
|
|
891
|
-
|
|
892
|
-
brainJar
|
|
893
|
-
.command('start')
|
|
894
|
-
.description('Start Brain Jar coordination')
|
|
895
|
-
.option('-s, --server <url>', 'Custom server URL')
|
|
896
|
-
.option('-n, --name <name>', 'Agent name')
|
|
897
|
-
.option('-r, --role <role>', 'Agent role')
|
|
898
|
-
.action(wrapAction(async (options) => {
|
|
899
|
-
await cortex.brainJarStart(options)
|
|
900
|
-
}))
|
|
901
|
-
|
|
902
|
-
brainJar
|
|
903
|
-
.command('dashboard')
|
|
904
|
-
.description('Open Brain Jar dashboard')
|
|
905
|
-
.option('-o, --open', 'Auto-open in browser', true)
|
|
906
|
-
.action(wrapAction(async (options) => {
|
|
907
|
-
await cortex.brainJarDashboard(options.open)
|
|
908
|
-
}))
|
|
909
|
-
|
|
910
|
-
brainJar
|
|
911
|
-
.command('status')
|
|
912
|
-
.description('Show Brain Jar status')
|
|
913
|
-
.action(wrapAction(async () => {
|
|
914
|
-
await cortex.brainJarStatus()
|
|
915
|
-
}))
|
|
916
|
-
|
|
917
|
-
brainJar
|
|
918
|
-
.command('agents')
|
|
919
|
-
.description('List connected agents')
|
|
920
|
-
.action(wrapAction(async () => {
|
|
921
|
-
await cortex.brainJarAgents()
|
|
922
|
-
}))
|
|
923
|
-
|
|
924
|
-
brainJar
|
|
925
|
-
.command('message <text>')
|
|
926
|
-
.description('Send message to coordination channel')
|
|
927
|
-
.action(wrapAction(async (text) => {
|
|
928
|
-
await cortex.brainJarMessage(text)
|
|
929
|
-
}))
|
|
930
|
-
|
|
931
|
-
brainJar
|
|
932
|
-
.command('search <query>')
|
|
933
|
-
.description('Search coordination history')
|
|
934
|
-
.option('-l, --limit <number>', 'Number of results', '10')
|
|
935
|
-
.action(wrapAction(async (query, options) => {
|
|
936
|
-
await cortex.brainJarSearch(query, parseInt(options.limit))
|
|
937
|
-
}))
|
|
938
|
-
|
|
939
|
-
// ========================================
|
|
940
|
-
// CONFIGURATION COMMANDS
|
|
941
|
-
// ========================================
|
|
942
|
-
|
|
943
|
-
const config = program.command('config')
|
|
944
|
-
.description('Manage configuration')
|
|
945
|
-
|
|
946
|
-
config
|
|
947
|
-
.command('set <key> <value>')
|
|
948
|
-
.description('Set configuration value')
|
|
949
|
-
.option('-e, --encrypt', 'Encrypt this value')
|
|
950
|
-
.action(wrapAction(async (key, value, options) => {
|
|
951
|
-
await cortex.configSet(key, value, options)
|
|
952
|
-
}))
|
|
953
|
-
|
|
954
|
-
config
|
|
955
|
-
.command('get <key>')
|
|
956
|
-
.description('Get configuration value')
|
|
957
|
-
.action(wrapAction(async (key) => {
|
|
958
|
-
const value = await cortex.configGet(key)
|
|
959
|
-
if (value) {
|
|
960
|
-
console.log(chalk.green(`${key}: ${value}`))
|
|
961
|
-
} else {
|
|
962
|
-
console.log(chalk.yellow(`Key not found: ${key}`))
|
|
963
|
-
}
|
|
964
|
-
}))
|
|
965
|
-
|
|
966
|
-
config
|
|
967
|
-
.command('list')
|
|
968
|
-
.description('List all configuration')
|
|
969
|
-
.action(wrapAction(async () => {
|
|
970
|
-
await cortex.configList()
|
|
971
|
-
}))
|
|
972
|
-
|
|
973
|
-
// ========================================
|
|
974
|
-
// LEGACY CORTEX COMMANDS (Backward Compatibility)
|
|
975
|
-
// ========================================
|
|
976
|
-
|
|
977
|
-
const cortexCmd = program.command('cortex')
|
|
978
|
-
.description('Legacy Cortex commands (deprecated - use direct commands)')
|
|
979
|
-
|
|
980
|
-
cortexCmd
|
|
981
|
-
.command('chat [question]')
|
|
982
|
-
.description('Chat with your data')
|
|
983
|
-
.action(wrapInteractive(async (question) => {
|
|
984
|
-
console.log(chalk.yellow('⚠️ Deprecated: Use "brainy chat" instead'))
|
|
985
|
-
await cortex.chat(question)
|
|
986
|
-
}))
|
|
987
|
-
|
|
988
|
-
cortexCmd
|
|
989
|
-
.command('add [data]')
|
|
990
|
-
.description('Add data')
|
|
991
|
-
.action(wrapAction(async (data) => {
|
|
992
|
-
console.log(chalk.yellow('⚠️ Deprecated: Use "brainy add" instead'))
|
|
993
|
-
await cortex.add(data, {})
|
|
994
|
-
}))
|
|
995
|
-
|
|
996
|
-
// ========================================
|
|
997
|
-
// INTERACTIVE SHELL
|
|
998
|
-
// ========================================
|
|
999
|
-
|
|
1000
|
-
program
|
|
1001
|
-
.command('shell')
|
|
1002
|
-
.description('Interactive Brainy shell')
|
|
1003
|
-
.action(wrapInteractive(async () => {
|
|
1004
|
-
console.log(chalk.cyan('🧠 Brainy Interactive Shell'))
|
|
1005
|
-
console.log(chalk.dim('Type "help" for commands, "exit" to quit\n'))
|
|
1006
|
-
await cortex.chat()
|
|
1007
|
-
}))
|
|
1008
|
-
|
|
1009
|
-
// ========================================
|
|
1010
|
-
// AUGMENTATION CONTROL COMMANDS
|
|
1011
|
-
// ========================================
|
|
1012
|
-
|
|
1013
|
-
program
|
|
1014
|
-
.command('augment')
|
|
1015
|
-
.description('List all augmentations with their status')
|
|
1016
|
-
.action(wrapAction(async () => {
|
|
1017
|
-
const { BrainyData } = await import('../dist/brainyData.js')
|
|
1018
|
-
const brainy = new BrainyData()
|
|
1019
|
-
await brainy.init()
|
|
1020
|
-
|
|
1021
|
-
const augmentations = brainy.listAugmentations()
|
|
1022
|
-
|
|
1023
|
-
if (augmentations.length === 0) {
|
|
1024
|
-
console.log(chalk.yellow('No augmentations registered'))
|
|
1025
|
-
return
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
console.log(chalk.cyan('🔧 Augmentations Status\n'))
|
|
1029
|
-
|
|
1030
|
-
const grouped = augmentations.reduce((acc, aug) => {
|
|
1031
|
-
if (!acc[aug.type]) acc[aug.type] = []
|
|
1032
|
-
acc[aug.type].push(aug)
|
|
1033
|
-
return acc
|
|
1034
|
-
}, {})
|
|
1035
|
-
|
|
1036
|
-
for (const [type, augs] of Object.entries(grouped)) {
|
|
1037
|
-
console.log(chalk.bold(`${type.toUpperCase()}:`))
|
|
1038
|
-
for (const aug of augs) {
|
|
1039
|
-
const status = aug.enabled ? chalk.green('✅ enabled') : chalk.red('❌ disabled')
|
|
1040
|
-
console.log(` ${aug.name} - ${status}`)
|
|
1041
|
-
console.log(chalk.dim(` ${aug.description}`))
|
|
1042
|
-
}
|
|
1043
|
-
console.log('')
|
|
1044
|
-
}
|
|
1045
|
-
}))
|
|
1046
|
-
|
|
1047
|
-
program
|
|
1048
|
-
.command('augment enable <name>')
|
|
1049
|
-
.description('Enable an augmentation by name')
|
|
1050
|
-
.action(wrapAction(async (name) => {
|
|
1051
|
-
const { BrainyData } = await import('../dist/brainyData.js')
|
|
1052
|
-
const brainy = new BrainyData()
|
|
1053
|
-
await brainy.init()
|
|
1054
|
-
|
|
1055
|
-
const success = brainy.enableAugmentation(name)
|
|
1056
|
-
|
|
1057
|
-
if (success) {
|
|
1058
|
-
console.log(chalk.green(`✅ Enabled augmentation: ${name}`))
|
|
1059
|
-
} else {
|
|
1060
|
-
console.log(chalk.red(`❌ Augmentation not found: ${name}`))
|
|
1061
|
-
console.log(chalk.dim('Use "brainy augment" to see available augmentations'))
|
|
1062
|
-
}
|
|
1063
|
-
}))
|
|
1064
|
-
|
|
1065
|
-
program
|
|
1066
|
-
.command('augment disable <name>')
|
|
1067
|
-
.description('Disable an augmentation by name')
|
|
1068
|
-
.action(wrapAction(async (name) => {
|
|
1069
|
-
const { BrainyData } = await import('../dist/brainyData.js')
|
|
1070
|
-
const brainy = new BrainyData()
|
|
1071
|
-
await brainy.init()
|
|
1072
|
-
|
|
1073
|
-
const success = brainy.disableAugmentation(name)
|
|
1074
|
-
|
|
1075
|
-
if (success) {
|
|
1076
|
-
console.log(chalk.green(`✅ Disabled augmentation: ${name}`))
|
|
1077
|
-
} else {
|
|
1078
|
-
console.log(chalk.red(`❌ Augmentation not found: ${name}`))
|
|
1079
|
-
console.log(chalk.dim('Use "brainy augment" to see available augmentations'))
|
|
1080
|
-
}
|
|
1081
|
-
}))
|
|
1082
|
-
|
|
1083
|
-
program
|
|
1084
|
-
.command('augment status <name>')
|
|
1085
|
-
.description('Check if an augmentation is enabled')
|
|
1086
|
-
.action(wrapAction(async (name) => {
|
|
1087
|
-
const { BrainyData } = await import('../dist/brainyData.js')
|
|
1088
|
-
const brainy = new BrainyData()
|
|
1089
|
-
await brainy.init()
|
|
1090
|
-
|
|
1091
|
-
const enabled = brainy.isAugmentationEnabled(name)
|
|
1092
|
-
|
|
1093
|
-
if (enabled !== undefined) {
|
|
1094
|
-
const status = enabled ? chalk.green('✅ enabled') : chalk.red('❌ disabled')
|
|
1095
|
-
console.log(`${name}: ${status}`)
|
|
1096
|
-
} else {
|
|
1097
|
-
console.log(chalk.red(`❌ Augmentation not found: ${name}`))
|
|
1098
|
-
console.log(chalk.dim('Use "brainy augment" to see available augmentations'))
|
|
1099
|
-
}
|
|
1100
|
-
}))
|
|
1101
|
-
|
|
1102
|
-
// ========================================
|
|
1103
|
-
// PARSE AND HANDLE
|
|
1104
|
-
// ========================================
|
|
1105
|
-
|
|
1106
|
-
program.parse(process.argv)
|
|
1107
|
-
|
|
1108
|
-
// Show help if no command
|
|
1109
|
-
if (!process.argv.slice(2).length) {
|
|
1110
|
-
console.log(chalk.cyan('🧠 Brainy - Multi-Dimensional AI Database'))
|
|
1111
|
-
console.log(chalk.gray('Vector similarity, graph relationships, metadata facets, and AI context.\n'))
|
|
1112
|
-
|
|
1113
|
-
console.log(chalk.bold('Quick Start:'))
|
|
1114
|
-
console.log(' brainy init # Initialize project')
|
|
1115
|
-
console.log(' brainy add "some data" # Add multi-dimensional data')
|
|
1116
|
-
console.log(' brainy search "query" # Search across all dimensions')
|
|
1117
|
-
console.log(' brainy chat # 🧠 Magical AI chat with perfect memory')
|
|
1118
|
-
console.log('')
|
|
1119
|
-
console.log(chalk.bold('Chat & Memory:'))
|
|
1120
|
-
console.log(' brainy chat # Interactive chat with local memory')
|
|
1121
|
-
console.log(' brainy chat "question" # Single question with context')
|
|
1122
|
-
console.log(' brainy chat --list # List all chat sessions')
|
|
1123
|
-
console.log(' brainy chat --search "query" # Search all conversations')
|
|
1124
|
-
console.log(' brainy chat --history # Show conversation history')
|
|
1125
|
-
console.log(' brainy chat --ui=web # 🌐 Premium web coordination interface')
|
|
1126
|
-
console.log('')
|
|
1127
|
-
console.log(chalk.bold('Brain Cloud (Premium):'))
|
|
1128
|
-
console.log(chalk.green(' brainy cloud setup # Auto-setup with provisioning'))
|
|
1129
|
-
console.log(' brainy cloud connect <id> # Connect to existing instance')
|
|
1130
|
-
console.log(' brainy cloud dashboard # Open Brain Cloud dashboard')
|
|
1131
|
-
console.log('')
|
|
1132
|
-
console.log(chalk.bold('AI Coordination:'))
|
|
1133
|
-
console.log(' brainy install brain-jar # Install coordination')
|
|
1134
|
-
console.log(' brainy brain-jar start # Start coordination')
|
|
1135
|
-
console.log('')
|
|
1136
|
-
console.log(chalk.dim('Learn more: https://soulcraft.com'))
|
|
1137
|
-
console.log('')
|
|
1138
|
-
program.outputHelp()
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
// ========================================
|
|
1142
|
-
// BRAIN CLOUD MEMORY SETUP FUNCTIONS
|
|
1143
|
-
// ========================================
|
|
1144
|
-
|
|
1145
|
-
async function checkBrainCloudAuth() {
|
|
1146
|
-
try {
|
|
1147
|
-
// Check for license file
|
|
1148
|
-
const { readFile } = await import('fs/promises')
|
|
1149
|
-
const { join } = await import('path')
|
|
1150
|
-
const { homedir } = await import('os')
|
|
1151
|
-
|
|
1152
|
-
try {
|
|
1153
|
-
const licensePath = join(homedir(), '.brainy', 'license')
|
|
1154
|
-
const license = await readFile(licensePath, 'utf8')
|
|
1155
|
-
return license.trim().startsWith('lic_')
|
|
1156
|
-
} catch {}
|
|
1157
|
-
|
|
1158
|
-
// Check for existing customer ID
|
|
1159
|
-
return await detectCustomerId() !== null
|
|
1160
|
-
} catch {
|
|
1161
|
-
return false
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
async function detectCustomerId() {
|
|
1166
|
-
try {
|
|
1167
|
-
// Method 1: Check for existing brainy config
|
|
1168
|
-
const { readFile } = await import('fs/promises')
|
|
1169
|
-
const { join } = await import('path')
|
|
1170
|
-
|
|
1171
|
-
try {
|
|
1172
|
-
const configPath = join(process.cwd(), 'brainy-config.json')
|
|
1173
|
-
const config = JSON.parse(await readFile(configPath, 'utf8'))
|
|
1174
|
-
if (config.brainCloudCustomerId) {
|
|
1175
|
-
return config.brainCloudCustomerId
|
|
1176
|
-
}
|
|
1177
|
-
} catch {}
|
|
1178
|
-
|
|
1179
|
-
// Method 2: Check CLAUDE.md for existing customer ID
|
|
1180
|
-
try {
|
|
1181
|
-
const claudePath = join(process.cwd(), 'CLAUDE.md')
|
|
1182
|
-
const claudeContent = await readFile(claudePath, 'utf8')
|
|
1183
|
-
const match = claudeContent.match(/customer.*?([a-z0-9-]+)/i)
|
|
1184
|
-
if (match) return match[1]
|
|
1185
|
-
} catch {}
|
|
1186
|
-
|
|
1187
|
-
// Method 3: Test common demo IDs
|
|
1188
|
-
const testIds = ['demo-test-auto', 'demo-test123']
|
|
1189
|
-
for (const id of testIds) {
|
|
1190
|
-
try {
|
|
1191
|
-
const response = await fetch(`https://api.soulcraft.com/brain-cloud/health`, {
|
|
1192
|
-
headers: { 'x-customer-id': id }
|
|
1193
|
-
})
|
|
1194
|
-
if (response.ok) {
|
|
1195
|
-
return id
|
|
1196
|
-
}
|
|
1197
|
-
} catch {}
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
return null
|
|
1201
|
-
} catch (error) {
|
|
1202
|
-
return null
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
async function setupBrainCloudMemory(customerId) {
|
|
1207
|
-
const { writeFile, mkdir } = await import('fs/promises')
|
|
1208
|
-
const { join } = await import('path')
|
|
1209
|
-
|
|
1210
|
-
console.log(chalk.gray('📝 Setting up AI memory configuration...'))
|
|
1211
|
-
|
|
1212
|
-
// 1. Create/update .claude directory and MCP config
|
|
1213
|
-
try {
|
|
1214
|
-
await mkdir('.claude', { recursive: true })
|
|
1215
|
-
|
|
1216
|
-
const mcpConfig = {
|
|
1217
|
-
mcpServers: {
|
|
1218
|
-
"brain-cloud": {
|
|
1219
|
-
command: "node",
|
|
1220
|
-
args: ["brainy-mcp-server.js"],
|
|
1221
|
-
env: {
|
|
1222
|
-
CUSTOMER_ID: customerId,
|
|
1223
|
-
BRAIN_CLOUD_URL: "https://api.soulcraft.com/brain-cloud"
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
await writeFile('.claude/mcp_servers.json', JSON.stringify(mcpConfig, null, 2))
|
|
1230
|
-
console.log(chalk.green('✅ MCP configuration updated'))
|
|
1231
|
-
} catch (error) {
|
|
1232
|
-
console.log(chalk.yellow('⚠️ Could not update MCP config:', error.message))
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
// 2. Create/update CLAUDE.md with natural language instructions
|
|
1236
|
-
const claudeContent = `# 🧠 I Remember Everything Now!
|
|
1237
|
-
|
|
1238
|
-
Hi! I'm connected to your Brain Cloud (${customerId}) so I actually remember our conversations across sessions.
|
|
1239
|
-
|
|
1240
|
-
## Try Saying:
|
|
1241
|
-
- "What did we build together?"
|
|
1242
|
-
- "Remember that React project?"
|
|
1243
|
-
- "Show me what we worked on yesterday"
|
|
1244
|
-
- "Find my notes about APIs"
|
|
1245
|
-
- "Search for that bug we fixed"
|
|
1246
|
-
|
|
1247
|
-
## I Can Also:
|
|
1248
|
-
- Remember context from weeks ago
|
|
1249
|
-
- Work with other AI assistants who share the same memory
|
|
1250
|
-
- Keep everything synced across your devices
|
|
1251
|
-
- Search through all our conversations
|
|
1252
|
-
|
|
1253
|
-
## Multi-AI Coordination:
|
|
1254
|
-
When working with multiple AI assistants, we automatically coordinate:
|
|
1255
|
-
- **Jarvis** (Backend): APIs, databases, deployment
|
|
1256
|
-
- **Picasso** (Design): UI, themes, visual elements
|
|
1257
|
-
- **Claude** (Planning): Coordination, architecture, strategy
|
|
1258
|
-
|
|
1259
|
-
**Just talk to me normally - no commands needed!**
|
|
1260
|
-
|
|
1261
|
-
---
|
|
1262
|
-
*Brain Cloud Instance: ${customerId}*
|
|
1263
|
-
*Last Updated: ${new Date().toLocaleDateString()}*
|
|
1264
|
-
`
|
|
1265
|
-
|
|
1266
|
-
try {
|
|
1267
|
-
await writeFile('CLAUDE.md', claudeContent)
|
|
1268
|
-
console.log(chalk.green('✅ CLAUDE.md updated with memory instructions'))
|
|
1269
|
-
} catch (error) {
|
|
1270
|
-
console.log(chalk.yellow('⚠️ Could not update CLAUDE.md:', error.message))
|
|
1271
|
-
}
|
|
1272
|
-
|
|
1273
|
-
// 3. Save customer ID to brainy config
|
|
1274
|
-
try {
|
|
1275
|
-
const brainyConfig = {
|
|
1276
|
-
brainCloudCustomerId: customerId,
|
|
1277
|
-
brainCloudUrl: 'https://api.soulcraft.com/brain-cloud',
|
|
1278
|
-
lastConnected: new Date().toISOString()
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
await writeFile('brainy-config.json', JSON.stringify(brainyConfig, null, 2))
|
|
1282
|
-
console.log(chalk.green('✅ Brainy configuration saved'))
|
|
1283
|
-
} catch (error) {
|
|
1284
|
-
console.log(chalk.yellow('⚠️ Could not save brainy config:', error.message))
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
1295
|
// ========================================
|
|
1289
|
-
//
|
|
1296
|
+
// FALLBACK - Show interactive help if no command
|
|
1290
1297
|
// ========================================
|
|
1291
1298
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
stopSpinner()
|
|
1298
|
-
process.stdout.write(`${message} `)
|
|
1299
|
-
|
|
1300
|
-
const spinnerChars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
|
|
1301
|
-
let i = 0
|
|
1302
|
-
|
|
1303
|
-
spinner = setInterval(() => {
|
|
1304
|
-
process.stdout.write(`\r${message} ${spinnerChars[i]}`)
|
|
1305
|
-
i = (i + 1) % spinnerChars.length
|
|
1306
|
-
}, 100)
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
function stopSpinner() {
|
|
1310
|
-
if (spinner) {
|
|
1311
|
-
clearInterval(spinner)
|
|
1312
|
-
spinner = null
|
|
1313
|
-
process.stdout.write('\r')
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
|
-
async function validateLicense() {
|
|
1318
|
-
startSpinner('Validating Early Access license...')
|
|
1319
|
-
|
|
1320
|
-
const licenseKey = process.env.BRAINY_LICENSE_KEY
|
|
1321
|
-
|
|
1322
|
-
if (!licenseKey) {
|
|
1323
|
-
stopSpinner()
|
|
1324
|
-
console.log('\n❌ No license key found')
|
|
1325
|
-
console.log('\n🔑 Please set your Early Access license key:')
|
|
1326
|
-
console.log(' export BRAINY_LICENSE_KEY="lic_early_access_your_key"')
|
|
1327
|
-
console.log('\n📝 Don\'t have a key? Get one free at: https://soulcraft.com/brain-cloud')
|
|
1328
|
-
throw new Error('License key required')
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
if (!licenseKey.startsWith('lic_early_access_')) {
|
|
1332
|
-
stopSpinner()
|
|
1333
|
-
throw new Error('Invalid license key format. Early Access keys start with "lic_early_access_"')
|
|
1334
|
-
}
|
|
1335
|
-
|
|
1336
|
-
stopSpinner()
|
|
1337
|
-
console.log('✅ License validated')
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
async function ensureBrainyInstalled() {
|
|
1341
|
-
startSpinner('Checking Brainy installation...')
|
|
1342
|
-
|
|
1343
|
-
try {
|
|
1344
|
-
const { exec } = await import('child_process')
|
|
1345
|
-
const { promisify } = await import('util')
|
|
1346
|
-
const execAsync = promisify(exec)
|
|
1347
|
-
|
|
1348
|
-
await execAsync('brainy --version')
|
|
1349
|
-
stopSpinner()
|
|
1350
|
-
console.log('✅ Brainy CLI found')
|
|
1351
|
-
} catch (error) {
|
|
1352
|
-
stopSpinner()
|
|
1353
|
-
console.log('📦 Installing Brainy CLI...')
|
|
1354
|
-
|
|
1355
|
-
try {
|
|
1356
|
-
await execWithProgress('npm install -g @soulcraft/brainy')
|
|
1357
|
-
console.log('✅ Brainy CLI installed')
|
|
1358
|
-
} catch (installError) {
|
|
1359
|
-
throw new Error('Failed to install Brainy CLI. Please install manually: npm install -g @soulcraft/brainy')
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
async function provisionCloudInstance(userEmail) {
|
|
1365
|
-
const licenseKey = process.env.BRAINY_LICENSE_KEY
|
|
1366
|
-
startSpinner('Provisioning your cloud Brainy instance...')
|
|
1367
|
-
|
|
1368
|
-
try {
|
|
1369
|
-
const response = await fetch(`${PROVISIONING_API}/provision`, {
|
|
1370
|
-
method: 'POST',
|
|
1371
|
-
headers: {
|
|
1372
|
-
'Content-Type': 'application/json'
|
|
1373
|
-
},
|
|
1374
|
-
body: JSON.stringify({
|
|
1375
|
-
licenseKey,
|
|
1376
|
-
userEmail: userEmail || 'user@example.com'
|
|
1377
|
-
})
|
|
1378
|
-
})
|
|
1379
|
-
|
|
1380
|
-
if (!response.ok) {
|
|
1381
|
-
const error = await response.json()
|
|
1382
|
-
throw new Error(error.message || 'Provisioning failed')
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
|
-
const result = await response.json()
|
|
1386
|
-
stopSpinner()
|
|
1387
|
-
|
|
1388
|
-
if (result.instance.status === 'active') {
|
|
1389
|
-
console.log('✅ Cloud instance already active')
|
|
1390
|
-
return result.instance
|
|
1391
|
-
}
|
|
1392
|
-
|
|
1393
|
-
console.log('🚀 Provisioning started (2-3 minutes)')
|
|
1394
|
-
|
|
1395
|
-
// Wait for provisioning to complete
|
|
1396
|
-
return await waitForProvisioning(licenseKey)
|
|
1397
|
-
|
|
1398
|
-
} catch (error) {
|
|
1399
|
-
stopSpinner()
|
|
1400
|
-
throw new Error(`Provisioning failed: ${error.message}`)
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
async function waitForProvisioning(licenseKey) {
|
|
1405
|
-
const maxWaitTime = 5 * 60 * 1000 // 5 minutes
|
|
1406
|
-
const checkInterval = 15 * 1000 // 15 seconds
|
|
1407
|
-
const startTime = Date.now()
|
|
1408
|
-
|
|
1409
|
-
while (Date.now() - startTime < maxWaitTime) {
|
|
1410
|
-
startSpinner('Waiting for cloud instance to be ready...')
|
|
1411
|
-
|
|
1412
|
-
try {
|
|
1413
|
-
const response = await fetch(`${PROVISIONING_API}/status?licenseKey=${encodeURIComponent(licenseKey)}`)
|
|
1414
|
-
|
|
1415
|
-
if (response.ok) {
|
|
1416
|
-
const result = await response.json()
|
|
1417
|
-
|
|
1418
|
-
if (result.instance.status === 'active') {
|
|
1419
|
-
stopSpinner()
|
|
1420
|
-
console.log('✅ Cloud instance is ready')
|
|
1421
|
-
return result.instance
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
|
-
if (result.instance.status === 'failed') {
|
|
1425
|
-
stopSpinner()
|
|
1426
|
-
throw new Error('Instance provisioning failed')
|
|
1427
|
-
}
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
stopSpinner()
|
|
1431
|
-
await new Promise(resolve => setTimeout(resolve, checkInterval))
|
|
1432
|
-
|
|
1433
|
-
} catch (error) {
|
|
1434
|
-
stopSpinner()
|
|
1435
|
-
console.log('⏳ Still provisioning...')
|
|
1436
|
-
await new Promise(resolve => setTimeout(resolve, checkInterval))
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
throw new Error('Provisioning timeout. Please check your dashboard or contact support.')
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
|
-
async function configureBrainy(instance) {
|
|
1444
|
-
const { writeFile, mkdir } = await import('fs/promises')
|
|
1445
|
-
const { join } = await import('path')
|
|
1446
|
-
const { homedir } = await import('os')
|
|
1447
|
-
const { existsSync } = await import('fs')
|
|
1448
|
-
|
|
1449
|
-
startSpinner('Configuring local Brainy to use cloud instance...')
|
|
1450
|
-
|
|
1451
|
-
// Ensure config directory exists
|
|
1452
|
-
const BRAINY_CONFIG_DIR = join(homedir(), '.brainy')
|
|
1453
|
-
const BRAINY_CONFIG_FILE = join(BRAINY_CONFIG_DIR, 'config.json')
|
|
1454
|
-
|
|
1455
|
-
if (!existsSync(BRAINY_CONFIG_DIR)) {
|
|
1456
|
-
await mkdir(BRAINY_CONFIG_DIR, { recursive: true })
|
|
1457
|
-
}
|
|
1458
|
-
|
|
1459
|
-
// Create or update Brainy config
|
|
1460
|
-
let config = {}
|
|
1461
|
-
if (existsSync(BRAINY_CONFIG_FILE)) {
|
|
1462
|
-
try {
|
|
1463
|
-
const { readFile } = await import('fs/promises')
|
|
1464
|
-
const existing = await readFile(BRAINY_CONFIG_FILE, 'utf8')
|
|
1465
|
-
config = JSON.parse(existing)
|
|
1466
|
-
} catch (error) {
|
|
1467
|
-
console.log('⚠️ Could not read existing config, creating new one')
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
|
-
// Update config with cloud instance details
|
|
1472
|
-
config.cloudSync = {
|
|
1473
|
-
enabled: true,
|
|
1474
|
-
endpoint: instance.endpoints.api,
|
|
1475
|
-
instanceId: instance.id,
|
|
1476
|
-
licenseKey: process.env.BRAINY_LICENSE_KEY
|
|
1477
|
-
}
|
|
1478
|
-
|
|
1479
|
-
config.aiMemory = {
|
|
1480
|
-
enabled: true,
|
|
1481
|
-
storage: 'cloud',
|
|
1482
|
-
endpoint: instance.endpoints.api
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
|
-
config.agentCoordination = {
|
|
1486
|
-
enabled: true,
|
|
1487
|
-
endpoint: instance.endpoints.api
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
await writeFile(BRAINY_CONFIG_FILE, JSON.stringify(config, null, 2))
|
|
1491
|
-
|
|
1492
|
-
stopSpinner()
|
|
1493
|
-
console.log('✅ Local Brainy configured for cloud sync')
|
|
1494
|
-
}
|
|
1495
|
-
|
|
1496
|
-
async function installBrainCloudPackage() {
|
|
1497
|
-
startSpinner('Installing Brain Cloud augmentations...')
|
|
1498
|
-
|
|
1499
|
-
try {
|
|
1500
|
-
const { existsSync } = await import('fs')
|
|
1501
|
-
|
|
1502
|
-
// Check if we're in a project directory
|
|
1503
|
-
const hasPackageJson = existsSync('package.json')
|
|
1504
|
-
|
|
1505
|
-
if (hasPackageJson) {
|
|
1506
|
-
// Auto-configured with 'brainy cloud auth' - no package installation needed!
|
|
1507
|
-
console.log('✅ Brain Cloud package installed in current project')
|
|
1508
|
-
} else {
|
|
1509
|
-
// Install globally for non-project usage
|
|
1510
|
-
console.log('✅ Run \'brainy cloud auth\' to authenticate and auto-configure')
|
|
1511
|
-
console.log('✅ Brain Cloud package installed globally')
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
} catch (error) {
|
|
1515
|
-
stopSpinner()
|
|
1516
|
-
console.log('⚠️ Could not auto-install Brain Cloud package')
|
|
1517
|
-
console.log(' Authenticate manually: brainy cloud auth')
|
|
1518
|
-
// Don't throw error, this is optional
|
|
1519
|
-
}
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
async function testConnection(instance) {
|
|
1523
|
-
startSpinner('Testing cloud connection...')
|
|
1524
|
-
|
|
1525
|
-
try {
|
|
1526
|
-
const response = await fetch(`${instance.endpoints.api}/health`)
|
|
1527
|
-
|
|
1528
|
-
if (response.ok) {
|
|
1529
|
-
const health = await response.json()
|
|
1530
|
-
stopSpinner()
|
|
1531
|
-
console.log('✅ Cloud instance connection verified')
|
|
1532
|
-
|
|
1533
|
-
// Test memory storage
|
|
1534
|
-
const testMemory = {
|
|
1535
|
-
content: 'Test memory from auto-setup',
|
|
1536
|
-
source: 'brain-cloud-setup',
|
|
1537
|
-
importance: 'low',
|
|
1538
|
-
tags: ['setup', 'test']
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
|
-
const memoryResponse = await fetch(`${instance.endpoints.api}/api/memories`, {
|
|
1542
|
-
method: 'POST',
|
|
1543
|
-
headers: { 'Content-Type': 'application/json' },
|
|
1544
|
-
body: JSON.stringify(testMemory)
|
|
1545
|
-
})
|
|
1546
|
-
|
|
1547
|
-
if (memoryResponse.ok) {
|
|
1548
|
-
console.log('✅ Memory storage working')
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
} else {
|
|
1552
|
-
stopSpinner()
|
|
1553
|
-
console.log('⚠️ Cloud instance not responding yet (this is normal)')
|
|
1554
|
-
console.log(' Your instance may need a few more minutes to fully initialize')
|
|
1555
|
-
}
|
|
1556
|
-
} catch (error) {
|
|
1557
|
-
stopSpinner()
|
|
1558
|
-
console.log('⚠️ Could not test connection (this is usually fine)')
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
async function execWithProgress(command) {
|
|
1563
|
-
const { spawn } = await import('child_process')
|
|
1564
|
-
|
|
1565
|
-
return new Promise((resolve, reject) => {
|
|
1566
|
-
const child = spawn('sh', ['-c', command], {
|
|
1567
|
-
stdio: ['inherit', 'pipe', 'pipe'],
|
|
1568
|
-
shell: true
|
|
1569
|
-
})
|
|
1570
|
-
|
|
1571
|
-
let stdout = ''
|
|
1572
|
-
let stderr = ''
|
|
1573
|
-
|
|
1574
|
-
child.stdout?.on('data', (data) => {
|
|
1575
|
-
stdout += data.toString()
|
|
1576
|
-
process.stdout.write('.')
|
|
1577
|
-
})
|
|
1578
|
-
|
|
1579
|
-
child.stderr?.on('data', (data) => {
|
|
1580
|
-
stderr += data.toString()
|
|
1581
|
-
})
|
|
1582
|
-
|
|
1583
|
-
child.on('close', (code) => {
|
|
1584
|
-
process.stdout.write('\n')
|
|
1585
|
-
if (code === 0) {
|
|
1586
|
-
resolve(stdout)
|
|
1587
|
-
} else {
|
|
1588
|
-
reject(new Error(stderr || `Command failed with code ${code}`))
|
|
1589
|
-
}
|
|
1590
|
-
})
|
|
1591
|
-
})
|
|
1299
|
+
// If no arguments provided, show interactive help
|
|
1300
|
+
if (process.argv.length === 2) {
|
|
1301
|
+
program.parse(['node', 'brainy', 'help'])
|
|
1302
|
+
} else {
|
|
1303
|
+
program.parse(process.argv)
|
|
1592
1304
|
}
|