@soulcraft/brainy 3.19.1 ā 3.20.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/bin/brainy-minimal.js +82 -0
- package/dist/cli/commands/conversation.js +10 -0
- package/dist/cli/commands/core.d.ts +14 -2
- package/dist/cli/commands/core.js +142 -26
- package/dist/cli/commands/data.d.ts +29 -0
- package/dist/cli/commands/data.js +139 -0
- package/dist/cli/commands/neural.d.ts +14 -0
- package/dist/cli/commands/neural.js +16 -5
- package/dist/cli/commands/utility.js +39 -97
- package/dist/cli/commands/vfs.d.ts +73 -0
- package/dist/cli/commands/vfs.js +372 -0
- package/dist/cli/index.js +201 -6
- package/dist/cli/interactive.d.ts +5 -0
- package/dist/cli/interactive.js +32 -8
- package/package.json +4 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Brainy CLI - Minimal Version (Conversation Commands Only)
|
|
5
|
+
*
|
|
6
|
+
* This is a temporary minimal CLI that only includes working conversation commands
|
|
7
|
+
* Full CLI will be restored in version 3.20.0
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Command } from 'commander'
|
|
11
|
+
import { readFileSync } from 'fs'
|
|
12
|
+
import { dirname, join } from 'path'
|
|
13
|
+
import { fileURLToPath } from 'url'
|
|
14
|
+
|
|
15
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
16
|
+
const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'))
|
|
17
|
+
|
|
18
|
+
const program = new Command()
|
|
19
|
+
|
|
20
|
+
program
|
|
21
|
+
.name('brainy')
|
|
22
|
+
.description('š§ Brainy - Infinite Agent Memory')
|
|
23
|
+
.version(packageJson.version)
|
|
24
|
+
|
|
25
|
+
// Dynamically load conversation command
|
|
26
|
+
const conversationCommand = await import('../dist/cli/commands/conversation.js').then(m => m.default)
|
|
27
|
+
|
|
28
|
+
program
|
|
29
|
+
.command('conversation')
|
|
30
|
+
.alias('conv')
|
|
31
|
+
.description('š¬ Infinite agent memory and context management')
|
|
32
|
+
.addCommand(
|
|
33
|
+
new Command('setup')
|
|
34
|
+
.description('Set up MCP server for Claude Code integration')
|
|
35
|
+
.action(async () => {
|
|
36
|
+
await conversationCommand.handler({ action: 'setup', _: [] })
|
|
37
|
+
})
|
|
38
|
+
)
|
|
39
|
+
.addCommand(
|
|
40
|
+
new Command('remove')
|
|
41
|
+
.description('Remove MCP server and clean up')
|
|
42
|
+
.action(async () => {
|
|
43
|
+
await conversationCommand.handler({ action: 'remove', _: [] })
|
|
44
|
+
})
|
|
45
|
+
)
|
|
46
|
+
.addCommand(
|
|
47
|
+
new Command('search')
|
|
48
|
+
.description('Search messages across conversations')
|
|
49
|
+
.requiredOption('-q, --query <query>', 'Search query')
|
|
50
|
+
.option('-c, --conversation-id <id>', 'Filter by conversation')
|
|
51
|
+
.option('-r, --role <role>', 'Filter by role')
|
|
52
|
+
.option('-l, --limit <number>', 'Maximum results', '10')
|
|
53
|
+
.action(async (options) => {
|
|
54
|
+
await conversationCommand.handler({ action: 'search', ...options, _: [] })
|
|
55
|
+
})
|
|
56
|
+
)
|
|
57
|
+
.addCommand(
|
|
58
|
+
new Command('context')
|
|
59
|
+
.description('Get relevant context for a query')
|
|
60
|
+
.requiredOption('-q, --query <query>', 'Context query')
|
|
61
|
+
.option('-l, --limit <number>', 'Maximum messages', '10')
|
|
62
|
+
.action(async (options) => {
|
|
63
|
+
await conversationCommand.handler({ action: 'context', ...options, _: [] })
|
|
64
|
+
})
|
|
65
|
+
)
|
|
66
|
+
.addCommand(
|
|
67
|
+
new Command('thread')
|
|
68
|
+
.description('Get full conversation thread')
|
|
69
|
+
.requiredOption('-c, --conversation-id <id>', 'Conversation ID')
|
|
70
|
+
.action(async (options) => {
|
|
71
|
+
await conversationCommand.handler({ action: 'thread', ...options, _: [] })
|
|
72
|
+
})
|
|
73
|
+
)
|
|
74
|
+
.addCommand(
|
|
75
|
+
new Command('stats')
|
|
76
|
+
.description('Show conversation statistics')
|
|
77
|
+
.action(async () => {
|
|
78
|
+
await conversationCommand.handler({ action: 'stats', _: [] })
|
|
79
|
+
})
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
program.parse(process.argv)
|
|
@@ -250,6 +250,8 @@ main()
|
|
|
250
250
|
});
|
|
251
251
|
await brain.init();
|
|
252
252
|
spinner.succeed('Initialized Brainy database');
|
|
253
|
+
// Shutdown Brainy to release resources
|
|
254
|
+
await brain.close();
|
|
253
255
|
// Success!
|
|
254
256
|
console.log(chalk.bold.green('\nā
Setup complete!\n'));
|
|
255
257
|
console.log(chalk.cyan('š Memory storage:'), brainyDir);
|
|
@@ -367,6 +369,7 @@ async function handleSearch(argv) {
|
|
|
367
369
|
spinner.succeed(`Found ${results.length} messages`);
|
|
368
370
|
if (results.length === 0) {
|
|
369
371
|
console.log(chalk.yellow('No messages found'));
|
|
372
|
+
await brain.close();
|
|
370
373
|
return;
|
|
371
374
|
}
|
|
372
375
|
// Display results
|
|
@@ -376,6 +379,7 @@ async function handleSearch(argv) {
|
|
|
376
379
|
console.log(chalk.dim(` Score: ${result.score.toFixed(3)} | Conv: ${result.conversationId}`));
|
|
377
380
|
console.log();
|
|
378
381
|
}
|
|
382
|
+
await brain.close();
|
|
379
383
|
}
|
|
380
384
|
/**
|
|
381
385
|
* Handle context command - Get relevant context
|
|
@@ -398,6 +402,7 @@ async function handleContext(argv) {
|
|
|
398
402
|
spinner.succeed(`Retrieved ${context.messages.length} relevant messages`);
|
|
399
403
|
if (context.messages.length === 0) {
|
|
400
404
|
console.log(chalk.yellow('No relevant context found'));
|
|
405
|
+
await brain.close();
|
|
401
406
|
return;
|
|
402
407
|
}
|
|
403
408
|
// Display context
|
|
@@ -420,6 +425,7 @@ async function handleContext(argv) {
|
|
|
420
425
|
console.log(chalk.dim(` - ${conv.title || conv.id} (${conv.relevance.toFixed(2)})`));
|
|
421
426
|
}
|
|
422
427
|
}
|
|
428
|
+
await brain.close();
|
|
423
429
|
}
|
|
424
430
|
/**
|
|
425
431
|
* Handle thread command - Get conversation thread
|
|
@@ -452,6 +458,7 @@ async function handleThread(argv) {
|
|
|
452
458
|
console.log(chalk.cyan(`${msg.role}:`), msg.content);
|
|
453
459
|
console.log(chalk.dim(` ${new Date(msg.createdAt).toLocaleString()}`));
|
|
454
460
|
}
|
|
461
|
+
await brain.close();
|
|
455
462
|
}
|
|
456
463
|
/**
|
|
457
464
|
* Handle stats command - Show statistics
|
|
@@ -487,6 +494,7 @@ async function handleStats(argv) {
|
|
|
487
494
|
console.log(chalk.dim(` ${phase}: ${count}`));
|
|
488
495
|
}
|
|
489
496
|
}
|
|
497
|
+
await brain.close();
|
|
490
498
|
}
|
|
491
499
|
/**
|
|
492
500
|
* Handle export command - Export conversation
|
|
@@ -505,6 +513,7 @@ async function handleExport(argv) {
|
|
|
505
513
|
const output = argv.output || `conversation_${argv.conversationId}.json`;
|
|
506
514
|
await fs.writeFile(output, JSON.stringify(exported, null, 2), 'utf8');
|
|
507
515
|
spinner.succeed(`Exported to ${output}`);
|
|
516
|
+
await brain.close();
|
|
508
517
|
}
|
|
509
518
|
/**
|
|
510
519
|
* Handle import command - Import conversation
|
|
@@ -523,6 +532,7 @@ async function handleImport(argv) {
|
|
|
523
532
|
const data = JSON.parse(await fs.readFile(inputFile, 'utf8'));
|
|
524
533
|
const conversationId = await conv.importConversation(data);
|
|
525
534
|
spinner.succeed(`Imported as conversation ${conversationId}`);
|
|
535
|
+
await brain.close();
|
|
526
536
|
}
|
|
527
537
|
export default conversationCommand;
|
|
528
538
|
//# sourceMappingURL=conversation.js.map
|
|
@@ -15,8 +15,20 @@ interface AddOptions extends CoreOptions {
|
|
|
15
15
|
}
|
|
16
16
|
interface SearchOptions extends CoreOptions {
|
|
17
17
|
limit?: string;
|
|
18
|
+
offset?: string;
|
|
18
19
|
threshold?: string;
|
|
19
|
-
|
|
20
|
+
type?: string;
|
|
21
|
+
where?: string;
|
|
22
|
+
near?: string;
|
|
23
|
+
connectedTo?: string;
|
|
24
|
+
connectedFrom?: string;
|
|
25
|
+
via?: string;
|
|
26
|
+
explain?: boolean;
|
|
27
|
+
includeRelations?: boolean;
|
|
28
|
+
fusion?: string;
|
|
29
|
+
vectorWeight?: string;
|
|
30
|
+
graphWeight?: string;
|
|
31
|
+
fieldWeight?: string;
|
|
20
32
|
}
|
|
21
33
|
interface GetOptions extends CoreOptions {
|
|
22
34
|
withConnections?: boolean;
|
|
@@ -38,7 +50,7 @@ export declare const coreCommands: {
|
|
|
38
50
|
*/
|
|
39
51
|
add(text: string, options: AddOptions): Promise<void>;
|
|
40
52
|
/**
|
|
41
|
-
* Search the neural database
|
|
53
|
+
* Search the neural database with Triple Intelligenceā¢
|
|
42
54
|
*/
|
|
43
55
|
search(query: string, options: SearchOptions): Promise<void>;
|
|
44
56
|
/**
|
|
@@ -9,10 +9,9 @@ import { readFileSync, writeFileSync } from 'node:fs';
|
|
|
9
9
|
import { Brainy } from '../../brainy.js';
|
|
10
10
|
import { BrainyTypes, NounType } from '../../index.js';
|
|
11
11
|
let brainyInstance = null;
|
|
12
|
-
const getBrainy =
|
|
12
|
+
const getBrainy = () => {
|
|
13
13
|
if (!brainyInstance) {
|
|
14
14
|
brainyInstance = new Brainy();
|
|
15
|
-
await brainyInstance.init();
|
|
16
15
|
}
|
|
17
16
|
return brainyInstance;
|
|
18
17
|
};
|
|
@@ -28,7 +27,7 @@ export const coreCommands = {
|
|
|
28
27
|
async add(text, options) {
|
|
29
28
|
const spinner = ora('Adding to neural database...').start();
|
|
30
29
|
try {
|
|
31
|
-
const brain =
|
|
30
|
+
const brain = getBrainy();
|
|
32
31
|
let metadata = {};
|
|
33
32
|
if (options.metadata) {
|
|
34
33
|
try {
|
|
@@ -93,43 +92,157 @@ export const coreCommands = {
|
|
|
93
92
|
}
|
|
94
93
|
},
|
|
95
94
|
/**
|
|
96
|
-
* Search the neural database
|
|
95
|
+
* Search the neural database with Triple Intelligenceā¢
|
|
97
96
|
*/
|
|
98
97
|
async search(query, options) {
|
|
99
|
-
const spinner = ora('Searching
|
|
98
|
+
const spinner = ora('Searching with Triple Intelligenceā¢...').start();
|
|
100
99
|
try {
|
|
101
|
-
const brain =
|
|
102
|
-
|
|
100
|
+
const brain = getBrainy();
|
|
101
|
+
// Build comprehensive search params
|
|
102
|
+
const searchParams = {
|
|
103
|
+
query,
|
|
103
104
|
limit: options.limit ? parseInt(options.limit) : 10
|
|
104
105
|
};
|
|
106
|
+
// Pagination
|
|
107
|
+
if (options.offset) {
|
|
108
|
+
searchParams.offset = parseInt(options.offset);
|
|
109
|
+
}
|
|
110
|
+
// Vector Intelligence - similarity threshold
|
|
105
111
|
if (options.threshold) {
|
|
106
|
-
|
|
112
|
+
searchParams.near = { threshold: parseFloat(options.threshold) };
|
|
107
113
|
}
|
|
108
|
-
|
|
114
|
+
// Metadata Intelligence - type filtering
|
|
115
|
+
if (options.type) {
|
|
116
|
+
const types = options.type.split(',').map(t => t.trim());
|
|
117
|
+
searchParams.type = types.length === 1 ? types[0] : types;
|
|
118
|
+
}
|
|
119
|
+
// Metadata Intelligence - field filtering
|
|
120
|
+
if (options.where) {
|
|
109
121
|
try {
|
|
110
|
-
|
|
122
|
+
searchParams.where = JSON.parse(options.where);
|
|
111
123
|
}
|
|
112
124
|
catch {
|
|
113
|
-
spinner.fail('Invalid
|
|
125
|
+
spinner.fail('Invalid --where JSON');
|
|
126
|
+
console.log(chalk.dim('Example: --where \'{"status":"active","priority":{"$gte":5}}\''));
|
|
114
127
|
process.exit(1);
|
|
115
128
|
}
|
|
116
129
|
}
|
|
117
|
-
|
|
130
|
+
// Vector Intelligence - proximity search
|
|
131
|
+
if (options.near) {
|
|
132
|
+
searchParams.near = {
|
|
133
|
+
id: options.near,
|
|
134
|
+
threshold: options.threshold ? parseFloat(options.threshold) : 0.7
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Graph Intelligence - connection constraints
|
|
138
|
+
if (options.connectedTo || options.connectedFrom || options.via) {
|
|
139
|
+
searchParams.connected = {};
|
|
140
|
+
if (options.connectedTo) {
|
|
141
|
+
searchParams.connected.to = options.connectedTo;
|
|
142
|
+
}
|
|
143
|
+
if (options.connectedFrom) {
|
|
144
|
+
searchParams.connected.from = options.connectedFrom;
|
|
145
|
+
}
|
|
146
|
+
if (options.via) {
|
|
147
|
+
const vias = options.via.split(',').map(v => v.trim());
|
|
148
|
+
searchParams.connected.via = vias.length === 1 ? vias[0] : vias;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Explanation
|
|
152
|
+
if (options.explain) {
|
|
153
|
+
searchParams.explain = true;
|
|
154
|
+
}
|
|
155
|
+
// Include relationships
|
|
156
|
+
if (options.includeRelations) {
|
|
157
|
+
searchParams.includeRelations = true;
|
|
158
|
+
}
|
|
159
|
+
// Triple Intelligence Fusion - custom weighting
|
|
160
|
+
if (options.fusion || options.vectorWeight || options.graphWeight || options.fieldWeight) {
|
|
161
|
+
searchParams.fusion = {
|
|
162
|
+
strategy: options.fusion || 'adaptive',
|
|
163
|
+
weights: {}
|
|
164
|
+
};
|
|
165
|
+
if (options.vectorWeight) {
|
|
166
|
+
searchParams.fusion.weights.vector = parseFloat(options.vectorWeight);
|
|
167
|
+
}
|
|
168
|
+
if (options.graphWeight) {
|
|
169
|
+
searchParams.fusion.weights.graph = parseFloat(options.graphWeight);
|
|
170
|
+
}
|
|
171
|
+
if (options.fieldWeight) {
|
|
172
|
+
searchParams.fusion.weights.field = parseFloat(options.fieldWeight);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const results = await brain.find(searchParams);
|
|
118
176
|
spinner.succeed(`Found ${results.length} results`);
|
|
119
177
|
if (!options.json) {
|
|
120
178
|
if (results.length === 0) {
|
|
121
|
-
console.log(chalk.yellow('
|
|
179
|
+
console.log(chalk.yellow('\nNo results found'));
|
|
180
|
+
// Show helpful hints
|
|
181
|
+
console.log(chalk.dim('\nTips:'));
|
|
182
|
+
console.log(chalk.dim(' ⢠Try different search terms'));
|
|
183
|
+
console.log(chalk.dim(' ⢠Remove filters (--type, --where, --connected-to)'));
|
|
184
|
+
console.log(chalk.dim(' ⢠Lower the --threshold value'));
|
|
122
185
|
}
|
|
123
186
|
else {
|
|
187
|
+
console.log(chalk.cyan(`\nš Triple Intelligence Results:\n`));
|
|
124
188
|
results.forEach((result, i) => {
|
|
125
|
-
|
|
189
|
+
const entity = result.entity || result;
|
|
190
|
+
console.log(chalk.bold(`${i + 1}. ${entity.id}`));
|
|
191
|
+
// Show score with breakdown
|
|
126
192
|
if (result.score !== undefined) {
|
|
127
|
-
console.log(chalk.
|
|
193
|
+
console.log(chalk.green(` Score: ${(result.score * 100).toFixed(1)}%`));
|
|
194
|
+
if (options.explain && result.scores) {
|
|
195
|
+
const scores = result.scores;
|
|
196
|
+
if (scores.vector !== undefined) {
|
|
197
|
+
console.log(chalk.dim(` Vector: ${(scores.vector * 100).toFixed(1)}%`));
|
|
198
|
+
}
|
|
199
|
+
if (scores.graph !== undefined) {
|
|
200
|
+
console.log(chalk.dim(` Graph: ${(scores.graph * 100).toFixed(1)}%`));
|
|
201
|
+
}
|
|
202
|
+
if (scores.field !== undefined) {
|
|
203
|
+
console.log(chalk.dim(` Field: ${(scores.field * 100).toFixed(1)}%`));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Show type
|
|
208
|
+
if (entity.type) {
|
|
209
|
+
console.log(chalk.dim(` Type: ${entity.type}`));
|
|
210
|
+
}
|
|
211
|
+
// Show content preview
|
|
212
|
+
if (entity.content) {
|
|
213
|
+
const preview = entity.content.substring(0, 80);
|
|
214
|
+
console.log(chalk.dim(` Content: ${preview}${entity.content.length > 80 ? '...' : ''}`));
|
|
215
|
+
}
|
|
216
|
+
// Show metadata
|
|
217
|
+
if (entity.metadata && Object.keys(entity.metadata).length > 0) {
|
|
218
|
+
console.log(chalk.dim(` Metadata: ${JSON.stringify(entity.metadata)}`));
|
|
128
219
|
}
|
|
129
|
-
|
|
130
|
-
|
|
220
|
+
// Show relationships
|
|
221
|
+
if (options.includeRelations && result.relations) {
|
|
222
|
+
const relations = result.relations;
|
|
223
|
+
if (relations.length > 0) {
|
|
224
|
+
console.log(chalk.dim(` Relations: ${relations.length} connections`));
|
|
225
|
+
}
|
|
131
226
|
}
|
|
227
|
+
console.log();
|
|
132
228
|
});
|
|
229
|
+
// Show search summary
|
|
230
|
+
console.log(chalk.cyan('Search Configuration:'));
|
|
231
|
+
if (searchParams.type) {
|
|
232
|
+
console.log(chalk.dim(` Type filter: ${Array.isArray(searchParams.type) ? searchParams.type.join(', ') : searchParams.type}`));
|
|
233
|
+
}
|
|
234
|
+
if (searchParams.where) {
|
|
235
|
+
console.log(chalk.dim(` Field filter: ${JSON.stringify(searchParams.where)}`));
|
|
236
|
+
}
|
|
237
|
+
if (searchParams.connected) {
|
|
238
|
+
console.log(chalk.dim(` Graph filter: ${JSON.stringify(searchParams.connected)}`));
|
|
239
|
+
}
|
|
240
|
+
if (searchParams.fusion) {
|
|
241
|
+
console.log(chalk.dim(` Fusion: ${searchParams.fusion.strategy}`));
|
|
242
|
+
if (searchParams.fusion.weights && Object.keys(searchParams.fusion.weights).length > 0) {
|
|
243
|
+
console.log(chalk.dim(` Weights: ${JSON.stringify(searchParams.fusion.weights)}`));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
133
246
|
}
|
|
134
247
|
}
|
|
135
248
|
else {
|
|
@@ -139,6 +252,9 @@ export const coreCommands = {
|
|
|
139
252
|
catch (error) {
|
|
140
253
|
spinner.fail('Search failed');
|
|
141
254
|
console.error(chalk.red(error.message));
|
|
255
|
+
if (options.verbose) {
|
|
256
|
+
console.error(chalk.dim(error.stack));
|
|
257
|
+
}
|
|
142
258
|
process.exit(1);
|
|
143
259
|
}
|
|
144
260
|
},
|
|
@@ -148,22 +264,21 @@ export const coreCommands = {
|
|
|
148
264
|
async get(id, options) {
|
|
149
265
|
const spinner = ora('Fetching item...').start();
|
|
150
266
|
try {
|
|
151
|
-
const brain =
|
|
267
|
+
const brain = getBrainy();
|
|
152
268
|
// Try to get the item
|
|
153
|
-
const
|
|
154
|
-
if (
|
|
269
|
+
const item = await brain.get(id);
|
|
270
|
+
if (!item) {
|
|
155
271
|
spinner.fail('Item not found');
|
|
156
272
|
console.log(chalk.yellow(`No item found with ID: ${id}`));
|
|
157
273
|
process.exit(1);
|
|
158
274
|
}
|
|
159
|
-
const item = results[0];
|
|
160
275
|
spinner.succeed('Item found');
|
|
161
276
|
if (!options.json) {
|
|
162
277
|
console.log(chalk.cyan('\nItem Details:'));
|
|
163
278
|
console.log(` ID: ${item.id}`);
|
|
164
279
|
console.log(` Content: ${item.content || 'N/A'}`);
|
|
165
|
-
if (item.
|
|
166
|
-
console.log(` Metadata: ${JSON.stringify(item.
|
|
280
|
+
if (item.metadata) {
|
|
281
|
+
console.log(` Metadata: ${JSON.stringify(item.metadata, null, 2)}`);
|
|
167
282
|
}
|
|
168
283
|
if (options.withConnections) {
|
|
169
284
|
// Get verbs/relationships
|
|
@@ -193,7 +308,7 @@ export const coreCommands = {
|
|
|
193
308
|
async relate(source, verb, target, options) {
|
|
194
309
|
const spinner = ora('Creating relationship...').start();
|
|
195
310
|
try {
|
|
196
|
-
const brain =
|
|
311
|
+
const brain = getBrainy();
|
|
197
312
|
let metadata = {};
|
|
198
313
|
if (options.metadata) {
|
|
199
314
|
try {
|
|
@@ -238,7 +353,7 @@ export const coreCommands = {
|
|
|
238
353
|
async import(file, options) {
|
|
239
354
|
const spinner = ora('Importing data...').start();
|
|
240
355
|
try {
|
|
241
|
-
const brain =
|
|
356
|
+
const brain = getBrainy();
|
|
242
357
|
const format = options.format || 'json';
|
|
243
358
|
const batchSize = options.batchSize ? parseInt(options.batchSize) : 100;
|
|
244
359
|
// Read file content
|
|
@@ -324,7 +439,7 @@ export const coreCommands = {
|
|
|
324
439
|
async export(file, options) {
|
|
325
440
|
const spinner = ora('Exporting database...').start();
|
|
326
441
|
try {
|
|
327
|
-
const brain =
|
|
442
|
+
const brain = getBrainy();
|
|
328
443
|
const format = options.format || 'json';
|
|
329
444
|
// Export all data
|
|
330
445
|
const dataApi = await brain.data();
|
|
@@ -390,3 +505,4 @@ export const coreCommands = {
|
|
|
390
505
|
}
|
|
391
506
|
}
|
|
392
507
|
};
|
|
508
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Management Commands
|
|
3
|
+
*
|
|
4
|
+
* Backup, restore, import, export operations
|
|
5
|
+
*/
|
|
6
|
+
interface DataOptions {
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
pretty?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const dataCommands: {
|
|
12
|
+
/**
|
|
13
|
+
* Backup database
|
|
14
|
+
*/
|
|
15
|
+
backup(file: string, options: DataOptions & {
|
|
16
|
+
compress?: boolean;
|
|
17
|
+
}): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Restore from backup
|
|
20
|
+
*/
|
|
21
|
+
restore(file: string, options: DataOptions & {
|
|
22
|
+
merge?: boolean;
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Get database statistics
|
|
26
|
+
*/
|
|
27
|
+
stats(options: DataOptions): Promise<void>;
|
|
28
|
+
};
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Management Commands
|
|
3
|
+
*
|
|
4
|
+
* Backup, restore, import, export operations
|
|
5
|
+
*/
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import ora from 'ora';
|
|
8
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
9
|
+
import { Brainy } from '../../brainy.js';
|
|
10
|
+
let brainyInstance = null;
|
|
11
|
+
const getBrainy = () => {
|
|
12
|
+
if (!brainyInstance) {
|
|
13
|
+
brainyInstance = new Brainy();
|
|
14
|
+
}
|
|
15
|
+
return brainyInstance;
|
|
16
|
+
};
|
|
17
|
+
const formatOutput = (data, options) => {
|
|
18
|
+
if (options.json) {
|
|
19
|
+
console.log(options.pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data));
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export const dataCommands = {
|
|
23
|
+
/**
|
|
24
|
+
* Backup database
|
|
25
|
+
*/
|
|
26
|
+
async backup(file, options) {
|
|
27
|
+
const spinner = ora('Creating backup...').start();
|
|
28
|
+
try {
|
|
29
|
+
const brain = getBrainy();
|
|
30
|
+
const dataApi = await brain.data();
|
|
31
|
+
const backup = await dataApi.backup({
|
|
32
|
+
compress: options.compress
|
|
33
|
+
});
|
|
34
|
+
spinner.text = 'Writing backup file...';
|
|
35
|
+
// Write backup to file
|
|
36
|
+
const content = typeof backup === 'string'
|
|
37
|
+
? backup
|
|
38
|
+
: JSON.stringify(backup, null, options.pretty ? 2 : 0);
|
|
39
|
+
writeFileSync(file, content);
|
|
40
|
+
spinner.succeed('Backup created');
|
|
41
|
+
if (!options.json) {
|
|
42
|
+
console.log(chalk.green(`ā Backup saved to: ${file}`));
|
|
43
|
+
if (backup.compressed) {
|
|
44
|
+
console.log(chalk.dim(` Original size: ${formatBytes(backup.originalSize)}`));
|
|
45
|
+
console.log(chalk.dim(` Compressed size: ${formatBytes(backup.compressedSize)}`));
|
|
46
|
+
console.log(chalk.dim(` Compression ratio: ${((backup.compressedSize / backup.originalSize) * 100).toFixed(1)}%`));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
formatOutput({ file, backup: true }, options);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
spinner.fail('Backup failed');
|
|
55
|
+
console.error(chalk.red(error.message));
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
/**
|
|
60
|
+
* Restore from backup
|
|
61
|
+
*/
|
|
62
|
+
async restore(file, options) {
|
|
63
|
+
const spinner = ora('Restoring from backup...').start();
|
|
64
|
+
try {
|
|
65
|
+
const brain = getBrainy();
|
|
66
|
+
const dataApi = await brain.data();
|
|
67
|
+
// Read backup file
|
|
68
|
+
const content = readFileSync(file, 'utf-8');
|
|
69
|
+
const backup = JSON.parse(content);
|
|
70
|
+
// Restore
|
|
71
|
+
await dataApi.restore({
|
|
72
|
+
backup,
|
|
73
|
+
merge: options.merge || false
|
|
74
|
+
});
|
|
75
|
+
spinner.succeed('Restore complete');
|
|
76
|
+
if (!options.json) {
|
|
77
|
+
console.log(chalk.green(`ā Restored from: ${file}`));
|
|
78
|
+
if (options.merge) {
|
|
79
|
+
console.log(chalk.dim(' Mode: Merged with existing data'));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
console.log(chalk.dim(' Mode: Replaced all data'));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
formatOutput({ file, restored: true }, options);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
spinner.fail('Restore failed');
|
|
91
|
+
console.error(chalk.red(error.message));
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
/**
|
|
96
|
+
* Get database statistics
|
|
97
|
+
*/
|
|
98
|
+
async stats(options) {
|
|
99
|
+
const spinner = ora('Gathering statistics...').start();
|
|
100
|
+
try {
|
|
101
|
+
const brain = getBrainy();
|
|
102
|
+
const dataApi = await brain.data();
|
|
103
|
+
const stats = await dataApi.getStats();
|
|
104
|
+
spinner.succeed('Statistics gathered');
|
|
105
|
+
if (!options.json) {
|
|
106
|
+
console.log(chalk.cyan('\nš Database Statistics:\n'));
|
|
107
|
+
console.log(chalk.bold('Entities:'));
|
|
108
|
+
console.log(` Total: ${chalk.green(stats.entities)}`);
|
|
109
|
+
console.log(chalk.bold('\nRelationships:'));
|
|
110
|
+
console.log(` Total: ${chalk.green(stats.relations)}`);
|
|
111
|
+
if (stats.storageSize) {
|
|
112
|
+
console.log(chalk.bold('\nStorage:'));
|
|
113
|
+
console.log(` Size: ${chalk.green(formatBytes(stats.storageSize))}`);
|
|
114
|
+
}
|
|
115
|
+
if (stats.vectorDimensions) {
|
|
116
|
+
console.log(chalk.bold('\nVector Index:'));
|
|
117
|
+
console.log(` Dimensions: ${stats.vectorDimensions}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
formatOutput(stats, options);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
spinner.fail('Failed to get statistics');
|
|
126
|
+
console.error(chalk.red(error.message));
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
function formatBytes(bytes) {
|
|
132
|
+
if (bytes === 0)
|
|
133
|
+
return '0 B';
|
|
134
|
+
const k = 1024;
|
|
135
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
136
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
137
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -22,4 +22,18 @@ export declare const neuralCommand: {
|
|
|
22
22
|
builder: (yargs: any) => any;
|
|
23
23
|
handler: (argv: CommandArguments) => Promise<void>;
|
|
24
24
|
};
|
|
25
|
+
declare function handleSimilarCommand(neural: any, argv: CommandArguments): Promise<void>;
|
|
26
|
+
declare function handleClustersCommand(neural: any, argv: CommandArguments): Promise<void>;
|
|
27
|
+
declare function handleHierarchyCommand(neural: any, argv: CommandArguments): Promise<void>;
|
|
28
|
+
declare function handleNeighborsCommand(neural: any, argv: CommandArguments): Promise<void>;
|
|
29
|
+
declare function handleOutliersCommand(neural: any, argv: CommandArguments): Promise<void>;
|
|
30
|
+
declare function handleVisualizeCommand(neural: any, argv: CommandArguments): Promise<void>;
|
|
31
|
+
export declare const neuralCommands: {
|
|
32
|
+
similar: typeof handleSimilarCommand;
|
|
33
|
+
cluster: typeof handleClustersCommand;
|
|
34
|
+
hierarchy: typeof handleHierarchyCommand;
|
|
35
|
+
related: typeof handleNeighborsCommand;
|
|
36
|
+
outliers: typeof handleOutliersCommand;
|
|
37
|
+
visualize: typeof handleVisualizeCommand;
|
|
38
|
+
};
|
|
25
39
|
export default neuralCommand;
|