@soulcraft/brainy 1.4.0 → 2.0.0
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/CHANGELOG.md +188 -0
- package/LICENSE +2 -2
- package/README.md +201 -596
- package/bin/brainy-interactive.js +564 -0
- package/bin/brainy-ts.js +18 -0
- package/bin/brainy.js +672 -81
- package/dist/augmentationPipeline.d.ts +48 -220
- package/dist/augmentationPipeline.js +60 -508
- package/dist/augmentationRegistry.d.ts +22 -31
- package/dist/augmentationRegistry.js +28 -79
- package/dist/augmentations/apiServerAugmentation.d.ts +108 -0
- package/dist/augmentations/apiServerAugmentation.js +502 -0
- package/dist/augmentations/batchProcessingAugmentation.d.ts +95 -0
- package/dist/augmentations/batchProcessingAugmentation.js +567 -0
- package/dist/augmentations/brainyAugmentation.d.ts +153 -0
- package/dist/augmentations/brainyAugmentation.js +145 -0
- package/dist/augmentations/cacheAugmentation.d.ts +105 -0
- package/dist/augmentations/cacheAugmentation.js +238 -0
- package/dist/augmentations/conduitAugmentations.d.ts +54 -156
- package/dist/augmentations/conduitAugmentations.js +156 -1082
- package/dist/augmentations/connectionPoolAugmentation.d.ts +62 -0
- package/dist/augmentations/connectionPoolAugmentation.js +316 -0
- package/dist/augmentations/defaultAugmentations.d.ts +53 -0
- package/dist/augmentations/defaultAugmentations.js +88 -0
- package/dist/augmentations/entityRegistryAugmentation.d.ts +126 -0
- package/dist/augmentations/entityRegistryAugmentation.js +386 -0
- package/dist/augmentations/indexAugmentation.d.ts +117 -0
- package/dist/augmentations/indexAugmentation.js +284 -0
- package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +152 -0
- package/dist/augmentations/intelligentVerbScoringAugmentation.js +554 -0
- package/dist/augmentations/metricsAugmentation.d.ts +202 -0
- package/dist/augmentations/metricsAugmentation.js +291 -0
- package/dist/augmentations/monitoringAugmentation.d.ts +94 -0
- package/dist/augmentations/monitoringAugmentation.js +227 -0
- package/dist/augmentations/neuralImport.d.ts +50 -117
- package/dist/augmentations/neuralImport.js +255 -629
- package/dist/augmentations/requestDeduplicatorAugmentation.d.ts +52 -0
- package/dist/augmentations/requestDeduplicatorAugmentation.js +162 -0
- package/dist/augmentations/serverSearchAugmentations.d.ts +43 -22
- package/dist/augmentations/serverSearchAugmentations.js +125 -72
- package/dist/augmentations/storageAugmentation.d.ts +54 -0
- package/dist/augmentations/storageAugmentation.js +93 -0
- package/dist/augmentations/storageAugmentations.d.ts +96 -0
- package/dist/augmentations/storageAugmentations.js +182 -0
- package/dist/augmentations/synapseAugmentation.d.ts +156 -0
- package/dist/augmentations/synapseAugmentation.js +312 -0
- package/dist/augmentations/walAugmentation.d.ts +108 -0
- package/dist/augmentations/walAugmentation.js +515 -0
- package/dist/brainyData.d.ts +404 -130
- package/dist/brainyData.js +1336 -855
- package/dist/chat/BrainyChat.d.ts +16 -8
- package/dist/chat/BrainyChat.js +60 -32
- package/dist/chat/ChatCLI.d.ts +1 -1
- package/dist/chat/ChatCLI.js +6 -6
- package/dist/cli/catalog.d.ts +3 -3
- package/dist/cli/catalog.js +116 -70
- package/dist/cli/commands/core.d.ts +61 -0
- package/dist/cli/commands/core.js +348 -0
- package/dist/cli/commands/neural.d.ts +25 -0
- package/dist/cli/commands/neural.js +508 -0
- package/dist/cli/commands/utility.d.ts +37 -0
- package/dist/cli/commands/utility.js +276 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +167 -0
- package/dist/cli/interactive.d.ts +164 -0
- package/dist/cli/interactive.js +542 -0
- package/dist/cortex/neuralImport.js +5 -5
- package/dist/critical/model-guardian.js +11 -4
- package/dist/embeddings/lightweight-embedder.d.ts +23 -0
- package/dist/embeddings/lightweight-embedder.js +136 -0
- package/dist/embeddings/universal-memory-manager.d.ts +38 -0
- package/dist/embeddings/universal-memory-manager.js +206 -0
- package/dist/embeddings/worker-embedding.d.ts +7 -0
- package/dist/embeddings/worker-embedding.js +77 -0
- package/dist/embeddings/worker-manager.d.ts +28 -0
- package/dist/embeddings/worker-manager.js +162 -0
- package/dist/examples/basicUsage.js +7 -7
- package/dist/graph/pathfinding.d.ts +78 -0
- package/dist/graph/pathfinding.js +393 -0
- package/dist/hnsw/hnswIndex.d.ts +13 -0
- package/dist/hnsw/hnswIndex.js +35 -0
- package/dist/hnsw/hnswIndexOptimized.d.ts +1 -0
- package/dist/hnsw/hnswIndexOptimized.js +3 -0
- package/dist/index.d.ts +9 -11
- package/dist/index.js +21 -11
- package/dist/indices/fieldIndex.d.ts +76 -0
- package/dist/indices/fieldIndex.js +357 -0
- package/dist/mcp/brainyMCPAdapter.js +3 -2
- package/dist/mcp/mcpAugmentationToolset.js +11 -17
- package/dist/neural/embeddedPatterns.d.ts +41 -0
- package/dist/neural/embeddedPatterns.js +4044 -0
- package/dist/neural/naturalLanguageProcessor.d.ts +94 -0
- package/dist/neural/naturalLanguageProcessor.js +317 -0
- package/dist/neural/naturalLanguageProcessorStatic.d.ts +64 -0
- package/dist/neural/naturalLanguageProcessorStatic.js +151 -0
- package/dist/neural/neuralAPI.d.ts +255 -0
- package/dist/neural/neuralAPI.js +612 -0
- package/dist/neural/patternLibrary.d.ts +101 -0
- package/dist/neural/patternLibrary.js +313 -0
- package/dist/neural/patterns.d.ts +27 -0
- package/dist/neural/patterns.js +68 -0
- package/dist/neural/staticPatternMatcher.d.ts +35 -0
- package/dist/neural/staticPatternMatcher.js +153 -0
- package/dist/scripts/precomputePatternEmbeddings.d.ts +19 -0
- package/dist/scripts/precomputePatternEmbeddings.js +100 -0
- package/dist/storage/adapters/fileSystemStorage.d.ts +5 -0
- package/dist/storage/adapters/fileSystemStorage.js +20 -0
- package/dist/storage/adapters/s3CompatibleStorage.d.ts +5 -0
- package/dist/storage/adapters/s3CompatibleStorage.js +16 -0
- package/dist/storage/enhancedClearOperations.d.ts +83 -0
- package/dist/storage/enhancedClearOperations.js +345 -0
- package/dist/storage/storageFactory.js +31 -27
- package/dist/triple/TripleIntelligence.d.ts +134 -0
- package/dist/triple/TripleIntelligence.js +548 -0
- package/dist/types/augmentations.d.ts +45 -344
- package/dist/types/augmentations.js +5 -2
- package/dist/types/brainyDataInterface.d.ts +20 -10
- package/dist/types/graphTypes.d.ts +46 -0
- package/dist/types/graphTypes.js +16 -2
- package/dist/utils/BoundedRegistry.d.ts +29 -0
- package/dist/utils/BoundedRegistry.js +54 -0
- package/dist/utils/embedding.js +20 -3
- package/dist/utils/hybridModelManager.js +10 -5
- package/dist/utils/metadataFilter.d.ts +33 -19
- package/dist/utils/metadataFilter.js +58 -23
- package/dist/utils/metadataIndex.d.ts +37 -6
- package/dist/utils/metadataIndex.js +427 -64
- package/dist/utils/requestDeduplicator.d.ts +10 -0
- package/dist/utils/requestDeduplicator.js +24 -0
- package/dist/utils/unifiedCache.d.ts +103 -0
- package/dist/utils/unifiedCache.js +311 -0
- package/package.json +43 -128
- package/scripts/ensure-models.js +108 -0
- package/scripts/prepare-models.js +387 -0
- package/OFFLINE_MODELS.md +0 -56
- package/dist/intelligence/neuralEngine.d.ts +0 -207
- package/dist/intelligence/neuralEngine.js +0 -706
- package/dist/utils/modelLoader.d.ts +0 -32
- package/dist/utils/modelLoader.js +0 -219
- package/dist/utils/modelManager.d.ts +0 -77
- package/dist/utils/modelManager.js +0 -219
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Brainy Interactive Mode
|
|
5
|
+
*
|
|
6
|
+
* Professional, guided CLI experience for beginners
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { program } from 'commander'
|
|
10
|
+
import { BrainyData } from '../dist/brainyData.js'
|
|
11
|
+
import chalk from 'chalk'
|
|
12
|
+
import inquirer from 'inquirer'
|
|
13
|
+
import ora from 'ora'
|
|
14
|
+
import Table from 'cli-table3'
|
|
15
|
+
import boxen from 'boxen'
|
|
16
|
+
|
|
17
|
+
// Professional color scheme
|
|
18
|
+
const colors = {
|
|
19
|
+
primary: chalk.hex('#3A5F4A'), // Teal (from logo)
|
|
20
|
+
success: chalk.hex('#2D4A3A'), // Deep teal
|
|
21
|
+
info: chalk.hex('#4A6B5A'), // Medium teal
|
|
22
|
+
warning: chalk.hex('#D67441'), // Orange (from logo)
|
|
23
|
+
error: chalk.hex('#B85C35'), // Deep orange
|
|
24
|
+
brain: chalk.hex('#D67441'), // Brain orange
|
|
25
|
+
cream: chalk.hex('#F5E6A3'), // Cream background
|
|
26
|
+
dim: chalk.dim,
|
|
27
|
+
bold: chalk.bold,
|
|
28
|
+
cyan: chalk.cyan,
|
|
29
|
+
green: chalk.green,
|
|
30
|
+
yellow: chalk.yellow,
|
|
31
|
+
red: chalk.red
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Icons for consistent visual language
|
|
35
|
+
const icons = {
|
|
36
|
+
brain: '🧠',
|
|
37
|
+
search: '🔍',
|
|
38
|
+
add: '➕',
|
|
39
|
+
delete: '🗑️',
|
|
40
|
+
update: '🔄',
|
|
41
|
+
import: '📥',
|
|
42
|
+
export: '📤',
|
|
43
|
+
connect: '🔗',
|
|
44
|
+
question: '❓',
|
|
45
|
+
success: '✅',
|
|
46
|
+
error: '❌',
|
|
47
|
+
warning: '⚠️',
|
|
48
|
+
info: 'ℹ️',
|
|
49
|
+
sparkle: '✨',
|
|
50
|
+
rocket: '🚀',
|
|
51
|
+
thinking: '🤔',
|
|
52
|
+
chat: '💬',
|
|
53
|
+
stats: '📊',
|
|
54
|
+
config: '⚙️',
|
|
55
|
+
cloud: '☁️'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let brainyInstance = null
|
|
59
|
+
|
|
60
|
+
async function getBrainy() {
|
|
61
|
+
if (!brainyInstance) {
|
|
62
|
+
const spinner = ora('Initializing Brainy...').start()
|
|
63
|
+
try {
|
|
64
|
+
brainyInstance = new BrainyData()
|
|
65
|
+
await brainyInstance.init()
|
|
66
|
+
spinner.succeed('Brainy initialized')
|
|
67
|
+
} catch (error) {
|
|
68
|
+
spinner.fail('Failed to initialize Brainy')
|
|
69
|
+
console.error(colors.error(error.message))
|
|
70
|
+
process.exit(1)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return brainyInstance
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Professional welcome screen
|
|
78
|
+
*/
|
|
79
|
+
function showWelcome() {
|
|
80
|
+
console.clear()
|
|
81
|
+
|
|
82
|
+
const welcomeBox = boxen(
|
|
83
|
+
colors.primary(`${icons.brain} BRAINY - Neural Intelligence System\n`) +
|
|
84
|
+
colors.dim('\nYour AI-Powered Second Brain\n') +
|
|
85
|
+
colors.info('Version 1.6.0'),
|
|
86
|
+
{
|
|
87
|
+
padding: 1,
|
|
88
|
+
margin: 1,
|
|
89
|
+
borderStyle: 'round',
|
|
90
|
+
borderColor: 'cyan',
|
|
91
|
+
textAlignment: 'center'
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
console.log(welcomeBox)
|
|
96
|
+
console.log()
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Main interactive menu
|
|
101
|
+
*/
|
|
102
|
+
async function mainMenu() {
|
|
103
|
+
const { action } = await inquirer.prompt([{
|
|
104
|
+
type: 'list',
|
|
105
|
+
name: 'action',
|
|
106
|
+
message: colors.cyan('What would you like to do?'),
|
|
107
|
+
choices: [
|
|
108
|
+
new inquirer.Separator(colors.dim('── Core Operations ──')),
|
|
109
|
+
{ name: `${icons.add} Add data to your brain`, value: 'add' },
|
|
110
|
+
{ name: `${icons.search} Search your knowledge`, value: 'search' },
|
|
111
|
+
{ name: `${icons.chat} Chat with your data`, value: 'chat' },
|
|
112
|
+
{ name: `${icons.update} Update existing data`, value: 'update' },
|
|
113
|
+
{ name: `${icons.delete} Delete data`, value: 'delete' },
|
|
114
|
+
|
|
115
|
+
new inquirer.Separator(colors.dim('── Advanced Features ──')),
|
|
116
|
+
{ name: `${icons.connect} Create relationships`, value: 'relate' },
|
|
117
|
+
{ name: `${icons.import} Import from file/URL`, value: 'import' },
|
|
118
|
+
{ name: `${icons.export} Export your brain`, value: 'export' },
|
|
119
|
+
{ name: `${icons.brain} Neural operations`, value: 'neural' },
|
|
120
|
+
|
|
121
|
+
new inquirer.Separator(colors.dim('── System ──')),
|
|
122
|
+
{ name: `${icons.stats} View statistics`, value: 'stats' },
|
|
123
|
+
{ name: `${icons.config} Configuration`, value: 'config' },
|
|
124
|
+
{ name: `${icons.cloud} Brain Cloud`, value: 'cloud' },
|
|
125
|
+
{ name: `${icons.info} Help & Documentation`, value: 'help' },
|
|
126
|
+
|
|
127
|
+
new inquirer.Separator(),
|
|
128
|
+
{ name: 'Exit', value: 'exit' }
|
|
129
|
+
],
|
|
130
|
+
pageSize: 20
|
|
131
|
+
}])
|
|
132
|
+
|
|
133
|
+
return action
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Neural operations submenu
|
|
138
|
+
*/
|
|
139
|
+
async function neuralMenu() {
|
|
140
|
+
const { operation } = await inquirer.prompt([{
|
|
141
|
+
type: 'list',
|
|
142
|
+
name: 'operation',
|
|
143
|
+
message: colors.cyan('Select neural operation:'),
|
|
144
|
+
choices: [
|
|
145
|
+
{ name: `${icons.brain} Calculate similarity`, value: 'similar' },
|
|
146
|
+
{ name: `${icons.search} Find clusters`, value: 'cluster' },
|
|
147
|
+
{ name: `${icons.connect} Find related items`, value: 'related' },
|
|
148
|
+
{ name: `${icons.thinking} Build hierarchy`, value: 'hierarchy' },
|
|
149
|
+
{ name: `${icons.rocket} Find semantic path`, value: 'path' },
|
|
150
|
+
{ name: `${icons.warning} Detect outliers`, value: 'outliers' },
|
|
151
|
+
{ name: `${icons.sparkle} Generate visualization`, value: 'visualize' },
|
|
152
|
+
new inquirer.Separator(),
|
|
153
|
+
{ name: '← Back to main menu', value: 'back' }
|
|
154
|
+
]
|
|
155
|
+
}])
|
|
156
|
+
|
|
157
|
+
return operation
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Execute commands with beautiful feedback
|
|
162
|
+
*/
|
|
163
|
+
async function executeCommand(command) {
|
|
164
|
+
const brain = await getBrainy()
|
|
165
|
+
|
|
166
|
+
switch (command) {
|
|
167
|
+
case 'add':
|
|
168
|
+
await interactiveAdd(brain)
|
|
169
|
+
break
|
|
170
|
+
|
|
171
|
+
case 'search':
|
|
172
|
+
await interactiveSearch(brain)
|
|
173
|
+
break
|
|
174
|
+
|
|
175
|
+
case 'chat':
|
|
176
|
+
await interactiveChat(brain)
|
|
177
|
+
break
|
|
178
|
+
|
|
179
|
+
case 'update':
|
|
180
|
+
await interactiveUpdate(brain)
|
|
181
|
+
break
|
|
182
|
+
|
|
183
|
+
case 'delete':
|
|
184
|
+
await interactiveDelete(brain)
|
|
185
|
+
break
|
|
186
|
+
|
|
187
|
+
case 'relate':
|
|
188
|
+
await interactiveRelate(brain)
|
|
189
|
+
break
|
|
190
|
+
|
|
191
|
+
case 'import':
|
|
192
|
+
await interactiveImport(brain)
|
|
193
|
+
break
|
|
194
|
+
|
|
195
|
+
case 'export':
|
|
196
|
+
await interactiveExport(brain)
|
|
197
|
+
break
|
|
198
|
+
|
|
199
|
+
case 'neural':
|
|
200
|
+
const neuralOp = await neuralMenu()
|
|
201
|
+
if (neuralOp !== 'back') {
|
|
202
|
+
await executeNeuralOperation(neuralOp, brain)
|
|
203
|
+
}
|
|
204
|
+
break
|
|
205
|
+
|
|
206
|
+
case 'stats':
|
|
207
|
+
await showStatistics(brain)
|
|
208
|
+
break
|
|
209
|
+
|
|
210
|
+
case 'config':
|
|
211
|
+
await interactiveConfig(brain)
|
|
212
|
+
break
|
|
213
|
+
|
|
214
|
+
case 'cloud':
|
|
215
|
+
await showCloudInfo()
|
|
216
|
+
break
|
|
217
|
+
|
|
218
|
+
case 'help':
|
|
219
|
+
await showHelp()
|
|
220
|
+
break
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Interactive add with rich prompts
|
|
226
|
+
*/
|
|
227
|
+
async function interactiveAdd(brain) {
|
|
228
|
+
console.log(colors.primary(`\n${icons.add} Add Data\n`))
|
|
229
|
+
|
|
230
|
+
const { inputType } = await inquirer.prompt([{
|
|
231
|
+
type: 'list',
|
|
232
|
+
name: 'inputType',
|
|
233
|
+
message: 'How would you like to add data?',
|
|
234
|
+
choices: [
|
|
235
|
+
{ name: 'Type or paste text', value: 'text' },
|
|
236
|
+
{ name: 'Multi-line editor', value: 'editor' },
|
|
237
|
+
{ name: 'JSON object', value: 'json' },
|
|
238
|
+
{ name: 'Import from clipboard', value: 'clipboard' }
|
|
239
|
+
]
|
|
240
|
+
}])
|
|
241
|
+
|
|
242
|
+
let data = ''
|
|
243
|
+
|
|
244
|
+
switch (inputType) {
|
|
245
|
+
case 'text':
|
|
246
|
+
const { text } = await inquirer.prompt([{
|
|
247
|
+
type: 'input',
|
|
248
|
+
name: 'text',
|
|
249
|
+
message: 'Enter your data:',
|
|
250
|
+
validate: input => input.trim() ? true : 'Please enter some data'
|
|
251
|
+
}])
|
|
252
|
+
data = text
|
|
253
|
+
break
|
|
254
|
+
|
|
255
|
+
case 'editor':
|
|
256
|
+
const { editorText } = await inquirer.prompt([{
|
|
257
|
+
type: 'editor',
|
|
258
|
+
name: 'editorText',
|
|
259
|
+
message: 'Enter your data (opens editor):',
|
|
260
|
+
postfix: '.md'
|
|
261
|
+
}])
|
|
262
|
+
data = editorText
|
|
263
|
+
break
|
|
264
|
+
|
|
265
|
+
case 'json':
|
|
266
|
+
const { jsonText } = await inquirer.prompt([{
|
|
267
|
+
type: 'editor',
|
|
268
|
+
name: 'jsonText',
|
|
269
|
+
message: 'Enter JSON data:',
|
|
270
|
+
postfix: '.json',
|
|
271
|
+
default: '{\n \n}',
|
|
272
|
+
validate: input => {
|
|
273
|
+
try {
|
|
274
|
+
JSON.parse(input)
|
|
275
|
+
return true
|
|
276
|
+
} catch (e) {
|
|
277
|
+
return `Invalid JSON: ${e.message}`
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}])
|
|
281
|
+
data = jsonText
|
|
282
|
+
break
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Optional metadata
|
|
286
|
+
const { addMetadata } = await inquirer.prompt([{
|
|
287
|
+
type: 'confirm',
|
|
288
|
+
name: 'addMetadata',
|
|
289
|
+
message: 'Would you like to add metadata?',
|
|
290
|
+
default: false
|
|
291
|
+
}])
|
|
292
|
+
|
|
293
|
+
let metadata = {}
|
|
294
|
+
if (addMetadata) {
|
|
295
|
+
const { metadataJson } = await inquirer.prompt([{
|
|
296
|
+
type: 'editor',
|
|
297
|
+
name: 'metadataJson',
|
|
298
|
+
message: 'Enter metadata (JSON):',
|
|
299
|
+
postfix: '.json',
|
|
300
|
+
default: '{\n "type": "",\n "tags": [],\n "category": ""\n}',
|
|
301
|
+
validate: input => {
|
|
302
|
+
try {
|
|
303
|
+
JSON.parse(input)
|
|
304
|
+
return true
|
|
305
|
+
} catch (e) {
|
|
306
|
+
return `Invalid JSON: ${e.message}`
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}])
|
|
310
|
+
metadata = JSON.parse(metadataJson)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const spinner = ora('Adding data...').start()
|
|
314
|
+
try {
|
|
315
|
+
const id = await brain.add(data, metadata)
|
|
316
|
+
spinner.succeed(`Added successfully with ID: ${id}`)
|
|
317
|
+
|
|
318
|
+
// Show summary
|
|
319
|
+
console.log(boxen(
|
|
320
|
+
colors.success(`${icons.success} Data added successfully!\n\n`) +
|
|
321
|
+
colors.info(`ID: ${id}\n`) +
|
|
322
|
+
colors.dim(`Size: ${data.length} characters\n`) +
|
|
323
|
+
(Object.keys(metadata).length > 0 ? colors.dim(`Metadata: ${Object.keys(metadata).join(', ')}`) : ''),
|
|
324
|
+
{ padding: 1, borderColor: 'green', borderStyle: 'round' }
|
|
325
|
+
))
|
|
326
|
+
} catch (error) {
|
|
327
|
+
spinner.fail('Failed to add data')
|
|
328
|
+
console.error(colors.error(error.message))
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Interactive search with filters
|
|
334
|
+
*/
|
|
335
|
+
async function interactiveSearch(brain) {
|
|
336
|
+
console.log(colors.primary(`\n${icons.search} Search\n`))
|
|
337
|
+
|
|
338
|
+
const { query } = await inquirer.prompt([{
|
|
339
|
+
type: 'input',
|
|
340
|
+
name: 'query',
|
|
341
|
+
message: 'Enter search query:',
|
|
342
|
+
validate: input => input.trim() ? true : 'Please enter a search query'
|
|
343
|
+
}])
|
|
344
|
+
|
|
345
|
+
// Advanced options
|
|
346
|
+
const { useFilters } = await inquirer.prompt([{
|
|
347
|
+
type: 'confirm',
|
|
348
|
+
name: 'useFilters',
|
|
349
|
+
message: 'Apply filters?',
|
|
350
|
+
default: false
|
|
351
|
+
}])
|
|
352
|
+
|
|
353
|
+
let searchOptions = { limit: 10 }
|
|
354
|
+
|
|
355
|
+
if (useFilters) {
|
|
356
|
+
const { limit, threshold } = await inquirer.prompt([
|
|
357
|
+
{
|
|
358
|
+
type: 'number',
|
|
359
|
+
name: 'limit',
|
|
360
|
+
message: 'Maximum results:',
|
|
361
|
+
default: 10
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
type: 'number',
|
|
365
|
+
name: 'threshold',
|
|
366
|
+
message: 'Similarity threshold (0-1):',
|
|
367
|
+
default: 0.5,
|
|
368
|
+
validate: input => input >= 0 && input <= 1 ? true : 'Must be between 0 and 1'
|
|
369
|
+
}
|
|
370
|
+
])
|
|
371
|
+
|
|
372
|
+
searchOptions.limit = limit
|
|
373
|
+
searchOptions.threshold = threshold
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const spinner = ora('Searching...').start()
|
|
377
|
+
try {
|
|
378
|
+
const results = await brain.search(query, searchOptions.limit, searchOptions)
|
|
379
|
+
spinner.succeed(`Found ${results.length} results`)
|
|
380
|
+
|
|
381
|
+
if (results.length === 0) {
|
|
382
|
+
console.log(colors.warning('No results found'))
|
|
383
|
+
} else {
|
|
384
|
+
// Display results in a table
|
|
385
|
+
const table = new Table({
|
|
386
|
+
head: [colors.cyan('ID'), colors.cyan('Content'), colors.cyan('Score')],
|
|
387
|
+
style: { head: [], border: [] },
|
|
388
|
+
colWidths: [20, 50, 10]
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
results.forEach(result => {
|
|
392
|
+
const content = result.content || result.id
|
|
393
|
+
const truncated = content.length > 47 ? content.substring(0, 47) + '...' : content
|
|
394
|
+
const score = result.score ? `${(result.score * 100).toFixed(1)}%` : 'N/A'
|
|
395
|
+
|
|
396
|
+
table.push([
|
|
397
|
+
result.id.substring(0, 18),
|
|
398
|
+
truncated,
|
|
399
|
+
colors.green(score)
|
|
400
|
+
])
|
|
401
|
+
})
|
|
402
|
+
|
|
403
|
+
console.log(table.toString())
|
|
404
|
+
|
|
405
|
+
// Ask if user wants to see full details
|
|
406
|
+
const { viewDetails } = await inquirer.prompt([{
|
|
407
|
+
type: 'confirm',
|
|
408
|
+
name: 'viewDetails',
|
|
409
|
+
message: 'View full details of a result?',
|
|
410
|
+
default: false
|
|
411
|
+
}])
|
|
412
|
+
|
|
413
|
+
if (viewDetails) {
|
|
414
|
+
const { selectedId } = await inquirer.prompt([{
|
|
415
|
+
type: 'list',
|
|
416
|
+
name: 'selectedId',
|
|
417
|
+
message: 'Select result:',
|
|
418
|
+
choices: results.map(r => ({
|
|
419
|
+
name: `${r.id} - ${r.content?.substring(0, 50)}...`,
|
|
420
|
+
value: r.id
|
|
421
|
+
}))
|
|
422
|
+
}])
|
|
423
|
+
|
|
424
|
+
const selected = results.find(r => r.id === selectedId)
|
|
425
|
+
console.log(boxen(
|
|
426
|
+
colors.cyan('Full Details\n\n') +
|
|
427
|
+
colors.info(`ID: ${selected.id}\n\n`) +
|
|
428
|
+
`Content:\n${selected.content}\n\n` +
|
|
429
|
+
(selected.metadata ? `Metadata:\n${JSON.stringify(selected.metadata, null, 2)}` : ''),
|
|
430
|
+
{ padding: 1, borderColor: 'cyan', borderStyle: 'round' }
|
|
431
|
+
))
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
} catch (error) {
|
|
435
|
+
spinner.fail('Search failed')
|
|
436
|
+
console.error(colors.error(error.message))
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Show statistics with beautiful formatting
|
|
442
|
+
*/
|
|
443
|
+
async function showStatistics(brain) {
|
|
444
|
+
const spinner = ora('Gathering statistics...').start()
|
|
445
|
+
|
|
446
|
+
try {
|
|
447
|
+
const stats = await brain.getStatistics()
|
|
448
|
+
spinner.succeed('Statistics loaded')
|
|
449
|
+
|
|
450
|
+
console.log(boxen(
|
|
451
|
+
colors.primary(`${icons.stats} Database Statistics\n\n`) +
|
|
452
|
+
colors.info(`Total Items: ${colors.bold(stats.total || 0)}\n`) +
|
|
453
|
+
colors.info(`Nouns: ${stats.nounCount || 0}\n`) +
|
|
454
|
+
colors.info(`Relationships: ${stats.verbCount || 0}\n`) +
|
|
455
|
+
colors.info(`Metadata Records: ${stats.metadataCount || 0}\n\n`) +
|
|
456
|
+
colors.dim(`Memory Usage: ${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(1)} MB`),
|
|
457
|
+
{
|
|
458
|
+
padding: 1,
|
|
459
|
+
borderColor: 'blue',
|
|
460
|
+
borderStyle: 'round',
|
|
461
|
+
textAlignment: 'left'
|
|
462
|
+
}
|
|
463
|
+
))
|
|
464
|
+
} catch (error) {
|
|
465
|
+
spinner.fail('Failed to get statistics')
|
|
466
|
+
console.error(colors.error(error.message))
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Show help with examples
|
|
472
|
+
*/
|
|
473
|
+
async function showHelp() {
|
|
474
|
+
console.log(boxen(
|
|
475
|
+
colors.primary(`${icons.info} Brainy Help\n\n`) +
|
|
476
|
+
colors.cyan('Common Commands:\n') +
|
|
477
|
+
colors.dim(`
|
|
478
|
+
brainy add "text" Add data
|
|
479
|
+
brainy search "query" Search your brain
|
|
480
|
+
brainy chat Interactive AI chat
|
|
481
|
+
brainy status View statistics
|
|
482
|
+
brainy help This help menu
|
|
483
|
+
|
|
484
|
+
`) +
|
|
485
|
+
colors.cyan('Interactive Mode:\n') +
|
|
486
|
+
colors.dim(`
|
|
487
|
+
brainy Start interactive mode
|
|
488
|
+
brainy -i Alternative interactive mode
|
|
489
|
+
|
|
490
|
+
`) +
|
|
491
|
+
colors.cyan('Advanced Features:\n') +
|
|
492
|
+
colors.dim(`
|
|
493
|
+
brainy similar a b Calculate similarity
|
|
494
|
+
brainy cluster Find semantic clusters
|
|
495
|
+
brainy export Export your data
|
|
496
|
+
brainy cloud Brain Cloud features
|
|
497
|
+
`),
|
|
498
|
+
{ padding: 1, borderColor: 'yellow', borderStyle: 'round' }
|
|
499
|
+
))
|
|
500
|
+
|
|
501
|
+
const { learnMore } = await inquirer.prompt([{
|
|
502
|
+
type: 'confirm',
|
|
503
|
+
name: 'learnMore',
|
|
504
|
+
message: 'View detailed documentation?',
|
|
505
|
+
default: false
|
|
506
|
+
}])
|
|
507
|
+
|
|
508
|
+
if (learnMore) {
|
|
509
|
+
console.log(colors.info('\nDocumentation: https://github.com/TimeSoul/brainy'))
|
|
510
|
+
console.log(colors.info('Enterprise features: Coming in future releases'))
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Main interactive loop
|
|
516
|
+
*/
|
|
517
|
+
async function main() {
|
|
518
|
+
showWelcome()
|
|
519
|
+
|
|
520
|
+
let running = true
|
|
521
|
+
while (running) {
|
|
522
|
+
const action = await mainMenu()
|
|
523
|
+
|
|
524
|
+
if (action === 'exit') {
|
|
525
|
+
console.log(colors.success(`\n${icons.success} Thank you for using Brainy!\n`))
|
|
526
|
+
running = false
|
|
527
|
+
} else {
|
|
528
|
+
await executeCommand(action)
|
|
529
|
+
|
|
530
|
+
// Pause before returning to menu
|
|
531
|
+
await inquirer.prompt([{
|
|
532
|
+
type: 'input',
|
|
533
|
+
name: 'continue',
|
|
534
|
+
message: colors.dim('\nPress Enter to continue...'),
|
|
535
|
+
prefix: ''
|
|
536
|
+
}])
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
process.exit(0)
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// Handle errors gracefully
|
|
544
|
+
process.on('unhandledRejection', (error) => {
|
|
545
|
+
console.error(colors.error(`\n${icons.error} Unexpected error:`))
|
|
546
|
+
console.error(colors.red(error.message))
|
|
547
|
+
process.exit(1)
|
|
548
|
+
})
|
|
549
|
+
|
|
550
|
+
// Handle Ctrl+C gracefully
|
|
551
|
+
process.on('SIGINT', () => {
|
|
552
|
+
console.log(colors.info(`\n\n${icons.info} Exiting Brainy...`))
|
|
553
|
+
process.exit(0)
|
|
554
|
+
})
|
|
555
|
+
|
|
556
|
+
// Run if called directly
|
|
557
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
558
|
+
main().catch(error => {
|
|
559
|
+
console.error(colors.error('Fatal error:'), error)
|
|
560
|
+
process.exit(1)
|
|
561
|
+
})
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
export { main as startInteractiveMode }
|
package/bin/brainy-ts.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Modern TypeScript CLI Runner
|
|
5
|
+
*
|
|
6
|
+
* This is the entry point after npm install @soulcraft/brainy
|
|
7
|
+
* It runs the compiled TypeScript CLI code
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Use the compiled TypeScript CLI
|
|
11
|
+
import('../dist/cli/index.js').catch(err => {
|
|
12
|
+
// Fallback to legacy CLI if new one isn't built yet
|
|
13
|
+
import('./brainy.js').catch(() => {
|
|
14
|
+
console.error('Error: CLI not properly built. Please reinstall the package.')
|
|
15
|
+
console.error(err)
|
|
16
|
+
process.exit(1)
|
|
17
|
+
})
|
|
18
|
+
})
|