CRITICAL CHECKPOINT - DO NOT PUSH TO GITHUB Recovery Status: - Successfully recovered brainy.ts from compiled JavaScript - All core v3.0 API methods functional (add, get, update, delete, relate, find, etc.) - Neural subsystem intact (562KB embedded patterns, NLP working) - Augmentation pipeline operational (20+ augmentations) - HNSW clustering system complete - Triple Intelligence compiled (needs constructor fix) - Test suite validates functionality Changes preserved: - 898 files with changes from last 3 days - 144,475 insertions - All augmentation improvements - All test coverage enhancements - Complete v3.0 feature set This is a LOCAL checkpoint only - contains recovered work after corruption incident. Created backup in .backups/brainy-full-20250910-151314.tar.gz Branch: recovery-checkpoint-20250910-151433 Date: Wed Sep 10 03:18:04 PM PDT 2025
348 lines
No EOL
13 KiB
JavaScript
348 lines
No EOL
13 KiB
JavaScript
/**
|
|
* Core CLI Commands - TypeScript Implementation
|
|
*
|
|
* Essential database operations: add, search, get, relate, import, export
|
|
*/
|
|
import chalk from 'chalk';
|
|
import ora from 'ora';
|
|
import { readFileSync, writeFileSync } from 'fs';
|
|
import { BrainyData } from '../../brainyData.js';
|
|
let brainyInstance = null;
|
|
const getBrainy = async () => {
|
|
if (!brainyInstance) {
|
|
brainyInstance = new BrainyData();
|
|
await brainyInstance.init();
|
|
}
|
|
return brainyInstance;
|
|
};
|
|
const formatOutput = (data, options) => {
|
|
if (options.json) {
|
|
console.log(options.pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data));
|
|
}
|
|
};
|
|
export const coreCommands = {
|
|
/**
|
|
* Add data to the neural database
|
|
*/
|
|
async add(text, options) {
|
|
const spinner = ora('Adding to neural database...').start();
|
|
try {
|
|
const brain = await getBrainy();
|
|
let metadata = {};
|
|
if (options.metadata) {
|
|
try {
|
|
metadata = JSON.parse(options.metadata);
|
|
}
|
|
catch {
|
|
spinner.fail('Invalid metadata JSON');
|
|
process.exit(1);
|
|
}
|
|
}
|
|
if (options.id) {
|
|
metadata.id = options.id;
|
|
}
|
|
if (options.type) {
|
|
metadata.type = options.type;
|
|
}
|
|
// Smart detection by default
|
|
const result = await brain.add(text, metadata);
|
|
spinner.succeed('Added successfully');
|
|
if (!options.json) {
|
|
console.log(chalk.green(`✓ Added with ID: ${result}`));
|
|
if (options.type) {
|
|
console.log(chalk.dim(` Type: ${options.type}`));
|
|
}
|
|
if (Object.keys(metadata).length > 0) {
|
|
console.log(chalk.dim(` Metadata: ${JSON.stringify(metadata)}`));
|
|
}
|
|
}
|
|
else {
|
|
formatOutput({ id: result, metadata }, options);
|
|
}
|
|
}
|
|
catch (error) {
|
|
spinner.fail('Failed to add data');
|
|
console.error(chalk.red(error.message));
|
|
process.exit(1);
|
|
}
|
|
},
|
|
/**
|
|
* Search the neural database
|
|
*/
|
|
async search(query, options) {
|
|
const spinner = ora('Searching neural database...').start();
|
|
try {
|
|
const brain = await getBrainy();
|
|
const searchOptions = {
|
|
limit: options.limit ? parseInt(options.limit) : 10
|
|
};
|
|
if (options.threshold) {
|
|
searchOptions.threshold = parseFloat(options.threshold);
|
|
}
|
|
if (options.metadata) {
|
|
try {
|
|
searchOptions.filter = JSON.parse(options.metadata);
|
|
}
|
|
catch {
|
|
spinner.fail('Invalid metadata filter JSON');
|
|
process.exit(1);
|
|
}
|
|
}
|
|
const results = await brain.search(query, searchOptions.limit, searchOptions);
|
|
spinner.succeed(`Found ${results.length} results`);
|
|
if (!options.json) {
|
|
if (results.length === 0) {
|
|
console.log(chalk.yellow('No results found'));
|
|
}
|
|
else {
|
|
results.forEach((result, i) => {
|
|
console.log(chalk.cyan(`\n${i + 1}. ${result.content || result.id}`));
|
|
if (result.score !== undefined) {
|
|
console.log(chalk.dim(` Similarity: ${(result.score * 100).toFixed(1)}%`));
|
|
}
|
|
if (result.metadata) {
|
|
console.log(chalk.dim(` Metadata: ${JSON.stringify(result.metadata)}`));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
formatOutput(results, options);
|
|
}
|
|
}
|
|
catch (error) {
|
|
spinner.fail('Search failed');
|
|
console.error(chalk.red(error.message));
|
|
process.exit(1);
|
|
}
|
|
},
|
|
/**
|
|
* Get item by ID
|
|
*/
|
|
async get(id, options) {
|
|
const spinner = ora('Fetching item...').start();
|
|
try {
|
|
const brain = await getBrainy();
|
|
// Try to get the item
|
|
const results = await brain.search(id, 1);
|
|
if (results.length === 0) {
|
|
spinner.fail('Item not found');
|
|
console.log(chalk.yellow(`No item found with ID: ${id}`));
|
|
process.exit(1);
|
|
}
|
|
const item = results[0];
|
|
spinner.succeed('Item found');
|
|
if (!options.json) {
|
|
console.log(chalk.cyan('\nItem Details:'));
|
|
console.log(` ID: ${item.id}`);
|
|
console.log(` Content: ${item.content || 'N/A'}`);
|
|
if (item.metadata) {
|
|
console.log(` Metadata: ${JSON.stringify(item.metadata, null, 2)}`);
|
|
}
|
|
if (options.withConnections) {
|
|
// Get verbs/relationships
|
|
// Get connections if method exists
|
|
const connections = brain.getConnections ? await brain.getConnections(id) : [];
|
|
if (connections && connections.length > 0) {
|
|
console.log(chalk.cyan('\nConnections:'));
|
|
connections.forEach((conn) => {
|
|
console.log(` ${conn.source} --[${conn.type}]--> ${conn.target}`);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
formatOutput(item, options);
|
|
}
|
|
}
|
|
catch (error) {
|
|
spinner.fail('Failed to get item');
|
|
console.error(chalk.red(error.message));
|
|
process.exit(1);
|
|
}
|
|
},
|
|
/**
|
|
* Create relationship between items
|
|
*/
|
|
async relate(source, verb, target, options) {
|
|
const spinner = ora('Creating relationship...').start();
|
|
try {
|
|
const brain = await getBrainy();
|
|
let metadata = {};
|
|
if (options.metadata) {
|
|
try {
|
|
metadata = JSON.parse(options.metadata);
|
|
}
|
|
catch {
|
|
spinner.fail('Invalid metadata JSON');
|
|
process.exit(1);
|
|
}
|
|
}
|
|
if (options.weight) {
|
|
metadata.weight = parseFloat(options.weight);
|
|
}
|
|
// Create the relationship
|
|
const result = await brain.addVerb(source, target, verb, metadata);
|
|
spinner.succeed('Relationship created');
|
|
if (!options.json) {
|
|
console.log(chalk.green(`✓ Created relationship with ID: ${result}`));
|
|
console.log(chalk.dim(` ${source} --[${verb}]--> ${target}`));
|
|
if (metadata.weight) {
|
|
console.log(chalk.dim(` Weight: ${metadata.weight}`));
|
|
}
|
|
}
|
|
else {
|
|
formatOutput({ id: result, source, verb, target, metadata }, options);
|
|
}
|
|
}
|
|
catch (error) {
|
|
spinner.fail('Failed to create relationship');
|
|
console.error(chalk.red(error.message));
|
|
process.exit(1);
|
|
}
|
|
},
|
|
/**
|
|
* Import data from file
|
|
*/
|
|
async import(file, options) {
|
|
const spinner = ora('Importing data...').start();
|
|
try {
|
|
const brain = await getBrainy();
|
|
const format = options.format || 'json';
|
|
const batchSize = options.batchSize ? parseInt(options.batchSize) : 100;
|
|
// Read file content
|
|
const content = readFileSync(file, 'utf-8');
|
|
let items = [];
|
|
switch (format) {
|
|
case 'json':
|
|
items = JSON.parse(content);
|
|
if (!Array.isArray(items)) {
|
|
items = [items];
|
|
}
|
|
break;
|
|
case 'jsonl':
|
|
items = content.split('\n')
|
|
.filter(line => line.trim())
|
|
.map(line => JSON.parse(line));
|
|
break;
|
|
case 'csv':
|
|
// Simple CSV parsing (first line is headers)
|
|
const lines = content.split('\n').filter(line => line.trim());
|
|
const headers = lines[0].split(',').map(h => h.trim());
|
|
items = lines.slice(1).map(line => {
|
|
const values = line.split(',').map(v => v.trim());
|
|
const obj = {};
|
|
headers.forEach((h, i) => {
|
|
obj[h] = values[i];
|
|
});
|
|
return obj;
|
|
});
|
|
break;
|
|
}
|
|
spinner.text = `Importing ${items.length} items...`;
|
|
// Process in batches
|
|
let imported = 0;
|
|
for (let i = 0; i < items.length; i += batchSize) {
|
|
const batch = items.slice(i, i + batchSize);
|
|
for (const item of batch) {
|
|
if (typeof item === 'string') {
|
|
await brain.add(item);
|
|
}
|
|
else if (item.content || item.text) {
|
|
await brain.add(item.content || item.text, item.metadata || item);
|
|
}
|
|
else {
|
|
await brain.add(JSON.stringify(item), { originalData: item });
|
|
}
|
|
imported++;
|
|
}
|
|
spinner.text = `Imported ${imported}/${items.length} items...`;
|
|
}
|
|
spinner.succeed(`Imported ${imported} items`);
|
|
if (!options.json) {
|
|
console.log(chalk.green(`✓ Successfully imported ${imported} items from ${file}`));
|
|
console.log(chalk.dim(` Format: ${format}`));
|
|
console.log(chalk.dim(` Batch size: ${batchSize}`));
|
|
}
|
|
else {
|
|
formatOutput({ imported, file, format, batchSize }, options);
|
|
}
|
|
}
|
|
catch (error) {
|
|
spinner.fail('Import failed');
|
|
console.error(chalk.red(error.message));
|
|
process.exit(1);
|
|
}
|
|
},
|
|
/**
|
|
* Export database
|
|
*/
|
|
async export(file, options) {
|
|
const spinner = ora('Exporting database...').start();
|
|
try {
|
|
const brain = await getBrainy();
|
|
const format = options.format || 'json';
|
|
// Export all data
|
|
const data = await brain.export({ format: 'json' });
|
|
let output = '';
|
|
switch (format) {
|
|
case 'json':
|
|
output = options.pretty
|
|
? JSON.stringify(data, null, 2)
|
|
: JSON.stringify(data);
|
|
break;
|
|
case 'jsonl':
|
|
if (Array.isArray(data)) {
|
|
output = data.map(item => JSON.stringify(item)).join('\n');
|
|
}
|
|
else {
|
|
output = JSON.stringify(data);
|
|
}
|
|
break;
|
|
case 'csv':
|
|
if (Array.isArray(data) && data.length > 0) {
|
|
// Get all unique keys for headers
|
|
const headers = new Set();
|
|
data.forEach(item => {
|
|
Object.keys(item).forEach(key => headers.add(key));
|
|
});
|
|
const headerArray = Array.from(headers);
|
|
// Create CSV
|
|
output = headerArray.join(',') + '\n';
|
|
output += data.map(item => {
|
|
return headerArray.map(h => {
|
|
const value = item[h];
|
|
if (typeof value === 'object') {
|
|
return JSON.stringify(value);
|
|
}
|
|
return value || '';
|
|
}).join(',');
|
|
}).join('\n');
|
|
}
|
|
break;
|
|
}
|
|
if (file) {
|
|
writeFileSync(file, output);
|
|
spinner.succeed(`Exported to ${file}`);
|
|
if (!options.json) {
|
|
console.log(chalk.green(`✓ Successfully exported database to ${file}`));
|
|
console.log(chalk.dim(` Format: ${format}`));
|
|
console.log(chalk.dim(` Items: ${Array.isArray(data) ? data.length : 1}`));
|
|
}
|
|
else {
|
|
formatOutput({ file, format, count: Array.isArray(data) ? data.length : 1 }, options);
|
|
}
|
|
}
|
|
else {
|
|
spinner.succeed('Export complete');
|
|
console.log(output);
|
|
}
|
|
}
|
|
catch (error) {
|
|
spinner.fail('Export failed');
|
|
console.error(chalk.red(error.message));
|
|
process.exit(1);
|
|
}
|
|
}
|
|
};
|
|
//# sourceMappingURL=core.js.map
|