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