@soulcraft/brainy 3.50.2 ā 4.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 +201 -0
- package/README.md +358 -658
- package/dist/api/ConfigAPI.js +56 -19
- package/dist/api/DataAPI.js +24 -18
- package/dist/augmentations/storageAugmentations.d.ts +24 -0
- package/dist/augmentations/storageAugmentations.js +22 -0
- package/dist/brainy.js +32 -9
- package/dist/cli/commands/core.d.ts +20 -10
- package/dist/cli/commands/core.js +384 -82
- package/dist/cli/commands/import.d.ts +41 -0
- package/dist/cli/commands/import.js +456 -0
- package/dist/cli/commands/insights.d.ts +34 -0
- package/dist/cli/commands/insights.js +300 -0
- package/dist/cli/commands/neural.d.ts +6 -12
- package/dist/cli/commands/neural.js +113 -10
- package/dist/cli/commands/nlp.d.ts +28 -0
- package/dist/cli/commands/nlp.js +246 -0
- package/dist/cli/commands/storage.d.ts +64 -0
- package/dist/cli/commands/storage.js +730 -0
- package/dist/cli/index.js +210 -24
- package/dist/coreTypes.d.ts +206 -34
- package/dist/distributed/configManager.js +8 -6
- package/dist/distributed/shardMigration.js +2 -0
- package/dist/distributed/storageDiscovery.js +6 -4
- package/dist/embeddings/EmbeddingManager.d.ts +2 -2
- package/dist/embeddings/EmbeddingManager.js +5 -1
- package/dist/graph/lsm/LSMTree.js +32 -20
- package/dist/hnsw/typeAwareHNSWIndex.js +6 -2
- package/dist/storage/adapters/azureBlobStorage.d.ts +545 -0
- package/dist/storage/adapters/azureBlobStorage.js +1809 -0
- package/dist/storage/adapters/baseStorageAdapter.d.ts +16 -13
- package/dist/storage/adapters/fileSystemStorage.d.ts +21 -9
- package/dist/storage/adapters/fileSystemStorage.js +204 -127
- package/dist/storage/adapters/gcsStorage.d.ts +119 -9
- package/dist/storage/adapters/gcsStorage.js +317 -62
- package/dist/storage/adapters/memoryStorage.d.ts +30 -18
- package/dist/storage/adapters/memoryStorage.js +99 -94
- package/dist/storage/adapters/opfsStorage.d.ts +48 -10
- package/dist/storage/adapters/opfsStorage.js +201 -80
- package/dist/storage/adapters/r2Storage.d.ts +12 -5
- package/dist/storage/adapters/r2Storage.js +63 -15
- package/dist/storage/adapters/s3CompatibleStorage.d.ts +164 -17
- package/dist/storage/adapters/s3CompatibleStorage.js +472 -80
- package/dist/storage/adapters/typeAwareStorageAdapter.d.ts +38 -6
- package/dist/storage/adapters/typeAwareStorageAdapter.js +218 -39
- package/dist/storage/baseStorage.d.ts +41 -38
- package/dist/storage/baseStorage.js +110 -134
- package/dist/storage/storageFactory.d.ts +29 -2
- package/dist/storage/storageFactory.js +30 -1
- package/dist/utils/entityIdMapper.js +5 -2
- package/dist/utils/fieldTypeInference.js +8 -1
- package/dist/utils/metadataFilter.d.ts +3 -2
- package/dist/utils/metadataFilter.js +1 -0
- package/dist/utils/metadataIndex.js +2 -0
- package/dist/utils/metadataIndexChunking.js +9 -4
- package/dist/utils/periodicCleanup.js +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import Commands - Neural Import & Data Import
|
|
3
|
+
*
|
|
4
|
+
* Complete import system exposing ALL Brainy import capabilities:
|
|
5
|
+
* - UniversalImportAPI: Neural import with AI type matching
|
|
6
|
+
* - DirectoryImporter: VFS directory imports
|
|
7
|
+
* - DataAPI: Backup/restore
|
|
8
|
+
*
|
|
9
|
+
* Supports: files, directories, URLs, all formats
|
|
10
|
+
*/
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import ora from 'ora';
|
|
13
|
+
import inquirer from 'inquirer';
|
|
14
|
+
import { statSync, existsSync } from 'node:fs';
|
|
15
|
+
import { Brainy } from '../../brainy.js';
|
|
16
|
+
import { NounType } from '../../types/graphTypes.js';
|
|
17
|
+
let brainyInstance = null;
|
|
18
|
+
const getBrainy = () => {
|
|
19
|
+
if (!brainyInstance) {
|
|
20
|
+
brainyInstance = new Brainy();
|
|
21
|
+
}
|
|
22
|
+
return brainyInstance;
|
|
23
|
+
};
|
|
24
|
+
const formatOutput = (data, options) => {
|
|
25
|
+
if (options.json) {
|
|
26
|
+
console.log(options.pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data));
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
export const importCommands = {
|
|
30
|
+
/**
|
|
31
|
+
* Enhanced import using UniversalImportAPI
|
|
32
|
+
* Supports files, directories, URLs, all formats
|
|
33
|
+
*/
|
|
34
|
+
async import(source, options) {
|
|
35
|
+
let spinner = null;
|
|
36
|
+
try {
|
|
37
|
+
// Interactive mode if no source provided
|
|
38
|
+
if (!source) {
|
|
39
|
+
const answers = await inquirer.prompt([
|
|
40
|
+
{
|
|
41
|
+
type: 'input',
|
|
42
|
+
name: 'source',
|
|
43
|
+
message: 'Import source (file, directory, or URL):',
|
|
44
|
+
validate: (input) => input.trim().length > 0 || 'Source cannot be empty'
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: 'confirm',
|
|
48
|
+
name: 'recursive',
|
|
49
|
+
message: 'Import directories recursively?',
|
|
50
|
+
default: true,
|
|
51
|
+
when: (ans) => {
|
|
52
|
+
// Check if it's a directory
|
|
53
|
+
try {
|
|
54
|
+
return existsSync(ans.source) && statSync(ans.source).isDirectory();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: 'list',
|
|
63
|
+
name: 'format',
|
|
64
|
+
message: 'File format (auto-detect if not specified):',
|
|
65
|
+
choices: ['auto', 'json', 'csv', 'jsonl', 'yaml', 'markdown', 'html', 'xml', 'text'],
|
|
66
|
+
default: 'auto'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'confirm',
|
|
70
|
+
name: 'extractConcepts',
|
|
71
|
+
message: 'Extract concepts as entities?',
|
|
72
|
+
default: false
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: 'confirm',
|
|
76
|
+
name: 'extractEntities',
|
|
77
|
+
message: 'Extract named entities (NLP)?',
|
|
78
|
+
default: false
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
type: 'confirm',
|
|
82
|
+
name: 'detectRelationships',
|
|
83
|
+
message: 'Auto-detect relationships?',
|
|
84
|
+
default: true
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
type: 'confirm',
|
|
88
|
+
name: 'progress',
|
|
89
|
+
message: 'Show progress?',
|
|
90
|
+
default: true
|
|
91
|
+
}
|
|
92
|
+
]);
|
|
93
|
+
source = answers.source;
|
|
94
|
+
if (answers.recursive !== undefined)
|
|
95
|
+
options.recursive = answers.recursive;
|
|
96
|
+
if (answers.format && answers.format !== 'auto')
|
|
97
|
+
options.format = answers.format;
|
|
98
|
+
if (answers.extractConcepts)
|
|
99
|
+
options.extractConcepts = true;
|
|
100
|
+
if (answers.extractEntities)
|
|
101
|
+
options.extractEntities = true;
|
|
102
|
+
if (answers.detectRelationships !== undefined)
|
|
103
|
+
options.detectRelationships = answers.detectRelationships;
|
|
104
|
+
if (answers.progress)
|
|
105
|
+
options.progress = true;
|
|
106
|
+
}
|
|
107
|
+
// Determine if it's a file, directory, or URL
|
|
108
|
+
const isURL = source.startsWith('http://') || source.startsWith('https://');
|
|
109
|
+
let isDirectory = false;
|
|
110
|
+
if (!isURL && existsSync(source)) {
|
|
111
|
+
isDirectory = statSync(source).isDirectory();
|
|
112
|
+
}
|
|
113
|
+
if (isDirectory && !options.recursive) {
|
|
114
|
+
console.log(chalk.yellow('ā ļø Source is a directory. Use --recursive to import subdirectories.'));
|
|
115
|
+
const answer = await inquirer.prompt([{
|
|
116
|
+
type: 'confirm',
|
|
117
|
+
name: 'recursive',
|
|
118
|
+
message: 'Import recursively?',
|
|
119
|
+
default: true
|
|
120
|
+
}]);
|
|
121
|
+
options.recursive = answer.recursive;
|
|
122
|
+
}
|
|
123
|
+
spinner = ora('Initializing neural import...').start();
|
|
124
|
+
const brain = getBrainy();
|
|
125
|
+
// Load UniversalImportAPI
|
|
126
|
+
const { UniversalImportAPI } = await import('../../api/UniversalImportAPI.js');
|
|
127
|
+
const universalImport = new UniversalImportAPI(brain);
|
|
128
|
+
await universalImport.init();
|
|
129
|
+
spinner.text = 'Processing import...';
|
|
130
|
+
// Handle different source types
|
|
131
|
+
let result;
|
|
132
|
+
if (isURL) {
|
|
133
|
+
// URL import
|
|
134
|
+
spinner.text = `Fetching from ${source}...`;
|
|
135
|
+
result = await universalImport.importFromURL(source);
|
|
136
|
+
}
|
|
137
|
+
else if (isDirectory) {
|
|
138
|
+
// Directory import - process each file
|
|
139
|
+
spinner.text = `Scanning directory: ${source}...`;
|
|
140
|
+
const { promises: fs } = await import('node:fs');
|
|
141
|
+
const { join } = await import('node:path');
|
|
142
|
+
// Collect files
|
|
143
|
+
const files = [];
|
|
144
|
+
const collectFiles = async (dir) => {
|
|
145
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
146
|
+
for (const entry of entries) {
|
|
147
|
+
const fullPath = join(dir, entry.name);
|
|
148
|
+
// Skip node_modules
|
|
149
|
+
if (entry.name === 'node_modules' && options.skipNodeModules !== false) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// Skip hidden files
|
|
153
|
+
if (options.skipHidden && entry.name.startsWith('.')) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (entry.isFile()) {
|
|
157
|
+
files.push(fullPath);
|
|
158
|
+
}
|
|
159
|
+
else if (entry.isDirectory() && options.recursive !== false) {
|
|
160
|
+
await collectFiles(fullPath);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
await collectFiles(source);
|
|
165
|
+
spinner.succeed(`Found ${files.length} files`);
|
|
166
|
+
// Process files in batches
|
|
167
|
+
const batchSize = options.batchSize ? parseInt(options.batchSize) : 100;
|
|
168
|
+
let totalEntities = 0;
|
|
169
|
+
let totalRelationships = 0;
|
|
170
|
+
let filesProcessed = 0;
|
|
171
|
+
for (let i = 0; i < files.length; i += batchSize) {
|
|
172
|
+
const batch = files.slice(i, i + batchSize);
|
|
173
|
+
if (options.progress) {
|
|
174
|
+
spinner = ora(`Processing batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(files.length / batchSize)} (${filesProcessed}/${files.length} files)...`).start();
|
|
175
|
+
}
|
|
176
|
+
for (const file of batch) {
|
|
177
|
+
try {
|
|
178
|
+
const fileResult = await universalImport.importFromFile(file);
|
|
179
|
+
totalEntities += fileResult.stats.entitiesCreated;
|
|
180
|
+
totalRelationships += fileResult.stats.relationshipsCreated;
|
|
181
|
+
filesProcessed++;
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
if (options.verbose) {
|
|
185
|
+
console.log(chalk.yellow(`ā ļø Failed to import ${file}: ${error.message}`));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
result = {
|
|
191
|
+
stats: {
|
|
192
|
+
filesProcessed,
|
|
193
|
+
entitiesCreated: totalEntities,
|
|
194
|
+
relationshipsCreated: totalRelationships,
|
|
195
|
+
totalProcessed: filesProcessed
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
spinner.succeed('Directory import complete');
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
// File import
|
|
202
|
+
result = await universalImport.importFromFile(source);
|
|
203
|
+
}
|
|
204
|
+
spinner.succeed('Import complete');
|
|
205
|
+
// Post-processing: extract concepts if requested
|
|
206
|
+
if (options.extractConcepts && result.entities && result.entities.length > 0) {
|
|
207
|
+
spinner = ora('Extracting concepts...').start();
|
|
208
|
+
let conceptsExtracted = 0;
|
|
209
|
+
for (const entity of result.entities) {
|
|
210
|
+
try {
|
|
211
|
+
const text = typeof entity.data === 'string' ? entity.data :
|
|
212
|
+
entity.data?.text || entity.data?.content || JSON.stringify(entity.data);
|
|
213
|
+
const concepts = await brain.extractConcepts(text, {
|
|
214
|
+
confidence: options.confidence ? parseFloat(options.confidence) : 0.5
|
|
215
|
+
});
|
|
216
|
+
// Add concepts as entities
|
|
217
|
+
for (const concept of concepts) {
|
|
218
|
+
await brain.add({
|
|
219
|
+
data: concept,
|
|
220
|
+
type: NounType.Concept,
|
|
221
|
+
metadata: {
|
|
222
|
+
extractedFrom: entity.id,
|
|
223
|
+
extractionMethod: 'neural'
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
conceptsExtracted++;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
if (options.verbose) {
|
|
231
|
+
console.log(chalk.dim(`Could not extract concepts from entity ${entity.id}`));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
spinner.succeed(`Extracted ${conceptsExtracted} concepts`);
|
|
236
|
+
}
|
|
237
|
+
// Post-processing: extract entities if requested
|
|
238
|
+
if (options.extractEntities && result.entities && result.entities.length > 0) {
|
|
239
|
+
spinner = ora('Extracting named entities...').start();
|
|
240
|
+
let entitiesExtracted = 0;
|
|
241
|
+
for (const entity of result.entities) {
|
|
242
|
+
try {
|
|
243
|
+
const text = typeof entity.data === 'string' ? entity.data :
|
|
244
|
+
entity.data?.text || entity.data?.content || JSON.stringify(entity.data);
|
|
245
|
+
const extractedEntities = await brain.extract(text);
|
|
246
|
+
// Add extracted entities
|
|
247
|
+
for (const extracted of extractedEntities) {
|
|
248
|
+
const type = extracted.type || NounType.Thing;
|
|
249
|
+
await brain.add({
|
|
250
|
+
data: extracted.content || extracted.text,
|
|
251
|
+
type: type,
|
|
252
|
+
metadata: {
|
|
253
|
+
extractedFrom: entity.id,
|
|
254
|
+
extractionMethod: 'nlp',
|
|
255
|
+
confidence: extracted.confidence
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
entitiesExtracted++;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
if (options.verbose) {
|
|
263
|
+
console.log(chalk.dim(`Could not extract entities from entity ${entity.id}`));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
spinner.succeed(`Extracted ${entitiesExtracted} named entities`);
|
|
268
|
+
}
|
|
269
|
+
// Display results
|
|
270
|
+
if (!options.json && !options.quiet) {
|
|
271
|
+
console.log(chalk.cyan('\nš Import Results:\n'));
|
|
272
|
+
console.log(chalk.bold('Statistics:'));
|
|
273
|
+
console.log(` Entities created: ${chalk.green(result.stats.entitiesCreated)}`);
|
|
274
|
+
if (result.stats.relationshipsCreated > 0) {
|
|
275
|
+
console.log(` Relationships created: ${chalk.green(result.stats.relationshipsCreated)}`);
|
|
276
|
+
}
|
|
277
|
+
if (result.stats.filesProcessed) {
|
|
278
|
+
console.log(` Files processed: ${chalk.green(result.stats.filesProcessed)}`);
|
|
279
|
+
}
|
|
280
|
+
console.log(` Average confidence: ${chalk.yellow((result.stats.averageConfidence * 100).toFixed(1))}%`);
|
|
281
|
+
console.log(` Processing time: ${chalk.dim(result.stats.processingTimeMs)}ms`);
|
|
282
|
+
if (options.verbose && result.entities && result.entities.length > 0) {
|
|
283
|
+
console.log(chalk.bold('\nš¦ Imported Entities (first 10):'));
|
|
284
|
+
result.entities.slice(0, 10).forEach((entity, i) => {
|
|
285
|
+
console.log(` ${i + 1}. ${chalk.cyan(entity.type)} (${(entity.confidence * 100).toFixed(1)}% confidence)`);
|
|
286
|
+
const preview = typeof entity.data === 'string' ? entity.data : JSON.stringify(entity.data);
|
|
287
|
+
console.log(chalk.dim(` ${preview.substring(0, 60)}${preview.length > 60 ? '...' : ''}`));
|
|
288
|
+
});
|
|
289
|
+
if (result.entities.length > 10) {
|
|
290
|
+
console.log(chalk.dim(` ... and ${result.entities.length - 10} more entities`));
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (options.verbose && result.relationships && result.relationships.length > 0) {
|
|
294
|
+
console.log(chalk.bold('\nš Detected Relationships (first 5):'));
|
|
295
|
+
result.relationships.slice(0, 5).forEach((rel, i) => {
|
|
296
|
+
console.log(` ${i + 1}. ${chalk.dim(rel.from)} --[${chalk.green(rel.type)}]--> ${chalk.dim(rel.to)}`);
|
|
297
|
+
});
|
|
298
|
+
if (result.relationships.length > 5) {
|
|
299
|
+
console.log(chalk.dim(` ... and ${result.relationships.length - 5} more relationships`));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
console.log(chalk.cyan('\nā Neural import complete with AI type matching'));
|
|
303
|
+
}
|
|
304
|
+
else if (options.json) {
|
|
305
|
+
formatOutput(result, options);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
if (spinner)
|
|
310
|
+
spinner.fail('Import failed');
|
|
311
|
+
console.error(chalk.red('Import failed:', error.message));
|
|
312
|
+
if (options.verbose) {
|
|
313
|
+
console.error(chalk.dim(error.stack));
|
|
314
|
+
}
|
|
315
|
+
process.exit(1);
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
/**
|
|
319
|
+
* VFS-specific import (files/directories into VFS)
|
|
320
|
+
*/
|
|
321
|
+
async vfsImport(source, options) {
|
|
322
|
+
let spinner = null;
|
|
323
|
+
try {
|
|
324
|
+
// Interactive mode if no source provided
|
|
325
|
+
if (!source) {
|
|
326
|
+
const answers = await inquirer.prompt([
|
|
327
|
+
{
|
|
328
|
+
type: 'input',
|
|
329
|
+
name: 'source',
|
|
330
|
+
message: 'Source path (file or directory):',
|
|
331
|
+
validate: (input) => {
|
|
332
|
+
if (!input.trim())
|
|
333
|
+
return 'Source cannot be empty';
|
|
334
|
+
if (!existsSync(input))
|
|
335
|
+
return 'Path does not exist';
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
type: 'input',
|
|
341
|
+
name: 'target',
|
|
342
|
+
message: 'VFS target path:',
|
|
343
|
+
default: '/'
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
type: 'confirm',
|
|
347
|
+
name: 'recursive',
|
|
348
|
+
message: 'Import recursively?',
|
|
349
|
+
default: true,
|
|
350
|
+
when: (ans) => {
|
|
351
|
+
try {
|
|
352
|
+
return statSync(ans.source).isDirectory();
|
|
353
|
+
}
|
|
354
|
+
catch {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
type: 'confirm',
|
|
361
|
+
name: 'generateEmbeddings',
|
|
362
|
+
message: 'Generate embeddings for files?',
|
|
363
|
+
default: true
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
type: 'confirm',
|
|
367
|
+
name: 'extractMetadata',
|
|
368
|
+
message: 'Extract file metadata?',
|
|
369
|
+
default: true
|
|
370
|
+
}
|
|
371
|
+
]);
|
|
372
|
+
source = answers.source;
|
|
373
|
+
options.target = answers.target;
|
|
374
|
+
if (answers.recursive !== undefined)
|
|
375
|
+
options.recursive = answers.recursive;
|
|
376
|
+
if (answers.generateEmbeddings !== undefined)
|
|
377
|
+
options.generateEmbeddings = answers.generateEmbeddings;
|
|
378
|
+
if (answers.extractMetadata !== undefined)
|
|
379
|
+
options.extractMetadata = answers.extractMetadata;
|
|
380
|
+
}
|
|
381
|
+
spinner = ora('Initializing VFS import...').start();
|
|
382
|
+
const brain = getBrainy();
|
|
383
|
+
// Get VFS
|
|
384
|
+
const vfs = await brain.vfs();
|
|
385
|
+
// Load DirectoryImporter
|
|
386
|
+
const { DirectoryImporter } = await import('../../vfs/importers/DirectoryImporter.js');
|
|
387
|
+
const importer = new DirectoryImporter(vfs, brain);
|
|
388
|
+
spinner.text = 'Importing to VFS...';
|
|
389
|
+
// Import with progress tracking
|
|
390
|
+
const importOptions = {
|
|
391
|
+
targetPath: options.target || '/',
|
|
392
|
+
recursive: options.recursive !== false,
|
|
393
|
+
skipHidden: options.skipHidden || false,
|
|
394
|
+
skipNodeModules: options.skipNodeModules !== false,
|
|
395
|
+
batchSize: options.batchSize ? parseInt(options.batchSize) : 100,
|
|
396
|
+
generateEmbeddings: options.generateEmbeddings !== false,
|
|
397
|
+
extractMetadata: options.extractMetadata !== false,
|
|
398
|
+
showProgress: options.progress || false
|
|
399
|
+
};
|
|
400
|
+
const result = await importer.import(source, importOptions);
|
|
401
|
+
spinner.succeed('VFS import complete');
|
|
402
|
+
// Display results
|
|
403
|
+
if (!options.json && !options.quiet) {
|
|
404
|
+
console.log(chalk.cyan('\nš VFS Import Results:\n'));
|
|
405
|
+
console.log(chalk.bold('Statistics:'));
|
|
406
|
+
console.log(` Files imported: ${chalk.green(result.filesProcessed)}`);
|
|
407
|
+
console.log(` Directories created: ${chalk.green(result.directoriesCreated)}`);
|
|
408
|
+
console.log(` Total size: ${chalk.yellow(formatBytes(result.totalSize))}`);
|
|
409
|
+
console.log(` Duration: ${chalk.dim(result.duration)}ms`);
|
|
410
|
+
if (result.failed.length > 0) {
|
|
411
|
+
console.log(chalk.yellow(` Failed: ${result.failed.length}`));
|
|
412
|
+
if (options.verbose) {
|
|
413
|
+
console.log(chalk.bold('\nā ļø Failed Imports:'));
|
|
414
|
+
result.failed.slice(0, 10).forEach((fail) => {
|
|
415
|
+
console.log(` ${chalk.dim(fail.path)}: ${chalk.red(fail.error.message)}`);
|
|
416
|
+
});
|
|
417
|
+
if (result.failed.length > 10) {
|
|
418
|
+
console.log(chalk.dim(` ... and ${result.failed.length - 10} more`));
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (options.verbose && result.imported.length > 0) {
|
|
423
|
+
console.log(chalk.bold('\nā Imported Files (first 10):'));
|
|
424
|
+
result.imported.slice(0, 10).forEach((path) => {
|
|
425
|
+
console.log(` ${chalk.green('ā')} ${chalk.dim(path)}`);
|
|
426
|
+
});
|
|
427
|
+
if (result.imported.length > 10) {
|
|
428
|
+
console.log(chalk.dim(` ... and ${result.imported.length - 10} more files`));
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
console.log(chalk.cyan('\nā Files imported to VFS with embeddings'));
|
|
432
|
+
}
|
|
433
|
+
else if (options.json) {
|
|
434
|
+
formatOutput(result, options);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
catch (error) {
|
|
438
|
+
if (spinner)
|
|
439
|
+
spinner.fail('VFS import failed');
|
|
440
|
+
console.error(chalk.red('VFS import failed:', error.message));
|
|
441
|
+
if (options.verbose) {
|
|
442
|
+
console.error(chalk.dim(error.stack));
|
|
443
|
+
}
|
|
444
|
+
process.exit(1);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
function formatBytes(bytes) {
|
|
449
|
+
if (bytes === 0)
|
|
450
|
+
return '0 B';
|
|
451
|
+
const k = 1024;
|
|
452
|
+
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
453
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
454
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
455
|
+
}
|
|
456
|
+
//# sourceMappingURL=import.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Insights & Analytics Commands
|
|
3
|
+
*
|
|
4
|
+
* Database insights, field statistics, and query optimization
|
|
5
|
+
*/
|
|
6
|
+
interface InsightsOptions {
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
pretty?: boolean;
|
|
10
|
+
quiet?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const insightsCommands: {
|
|
13
|
+
/**
|
|
14
|
+
* Get comprehensive database insights
|
|
15
|
+
*/
|
|
16
|
+
insights(options: InsightsOptions): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Get available fields across all entities
|
|
19
|
+
*/
|
|
20
|
+
fields(options: InsightsOptions): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Get field values for a specific field
|
|
23
|
+
*/
|
|
24
|
+
fieldValues(field: string | undefined, options: InsightsOptions & {
|
|
25
|
+
limit?: string;
|
|
26
|
+
}): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Get optimal query plan for filters
|
|
29
|
+
*/
|
|
30
|
+
queryPlan(options: InsightsOptions & {
|
|
31
|
+
filters?: string;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
};
|
|
34
|
+
export {};
|