@soulcraft/brainy 3.19.0 → 3.20.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 +2 -0
- package/bin/brainy-minimal.js +82 -0
- package/bin/brainy.js +9 -2335
- package/dist/api/DataAPI.d.ts +1 -1
- package/dist/augmentations/cacheAugmentation.d.ts +1 -1
- package/dist/augmentations/metricsAugmentation.d.ts +20 -20
- package/dist/brainy.d.ts +1 -1
- package/dist/brainyData.js +1 -2
- package/dist/cli/catalog.js +8 -12
- package/dist/cli/commands/conversation.d.ts +22 -0
- package/dist/cli/commands/conversation.js +528 -0
- package/dist/cli/commands/core.d.ts +14 -2
- package/dist/cli/commands/core.js +195 -35
- 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 +18 -8
- package/dist/cli/commands/types.d.ts +30 -0
- package/dist/cli/commands/types.js +194 -0
- package/dist/cli/commands/utility.js +39 -98
- package/dist/cli/commands/vfs.d.ts +73 -0
- package/dist/cli/commands/vfs.js +372 -0
- package/dist/cli/index.js +244 -7
- package/dist/cli/interactive.d.ts +8 -3
- package/dist/cli/interactive.js +35 -11
- package/dist/hnsw/hnswIndexOptimized.d.ts +1 -1
- package/dist/mcp/brainyMCPBroadcast.d.ts +2 -2
- package/dist/mcp/brainyMCPBroadcast.js +1 -1
- package/dist/mcp/brainyMCPClient.js +8 -4
- package/dist/neural/types.d.ts +2 -2
- package/dist/streaming/pipeline.d.ts +1 -1
- package/dist/universal/fs.d.ts +24 -66
- package/package.json +5 -2
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Commands for Type Management
|
|
3
|
+
* Consistent with BrainyTypes public API
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
import inquirer from 'inquirer';
|
|
8
|
+
import { BrainyTypes } from '../../index.js';
|
|
9
|
+
/**
|
|
10
|
+
* List types - matches BrainyTypes.nouns and BrainyTypes.verbs
|
|
11
|
+
* Usage: brainy types
|
|
12
|
+
*/
|
|
13
|
+
export async function types(options) {
|
|
14
|
+
try {
|
|
15
|
+
// Default to showing both if neither flag specified
|
|
16
|
+
const showNouns = options.noun || (!options.noun && !options.verb);
|
|
17
|
+
const showVerbs = options.verb || (!options.noun && !options.verb);
|
|
18
|
+
const result = {};
|
|
19
|
+
if (showNouns)
|
|
20
|
+
result.nouns = BrainyTypes.nouns;
|
|
21
|
+
if (showVerbs)
|
|
22
|
+
result.verbs = BrainyTypes.verbs;
|
|
23
|
+
if (options.json) {
|
|
24
|
+
console.log(JSON.stringify(result, null, 2));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// Display nouns
|
|
28
|
+
if (showNouns) {
|
|
29
|
+
console.log(chalk.bold.cyan('\n📚 Noun Types (31):\n'));
|
|
30
|
+
const nounChunks = [];
|
|
31
|
+
for (let i = 0; i < BrainyTypes.nouns.length; i += 3) {
|
|
32
|
+
nounChunks.push(BrainyTypes.nouns.slice(i, i + 3));
|
|
33
|
+
}
|
|
34
|
+
for (const chunk of nounChunks) {
|
|
35
|
+
console.log(' ' + chunk.map(n => chalk.green(n.padEnd(20))).join(''));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Display verbs
|
|
39
|
+
if (showVerbs) {
|
|
40
|
+
console.log(chalk.bold.cyan('\n🔗 Verb Types (40):\n'));
|
|
41
|
+
const verbChunks = [];
|
|
42
|
+
for (let i = 0; i < BrainyTypes.verbs.length; i += 3) {
|
|
43
|
+
verbChunks.push(BrainyTypes.verbs.slice(i, i + 3));
|
|
44
|
+
}
|
|
45
|
+
for (const chunk of verbChunks) {
|
|
46
|
+
console.log(' ' + chunk.map(v => chalk.blue(v.padEnd(20))).join(''));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
console.log(chalk.dim('\n💡 Use "brainy suggest <data>" to get AI-powered type suggestions'));
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
console.error(chalk.red('Error:', error.message));
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Suggest type - matches BrainyTypes.suggestNoun() and suggestVerb()
|
|
58
|
+
* Usage: brainy suggest <data>
|
|
59
|
+
* Interactive if data not provided
|
|
60
|
+
*/
|
|
61
|
+
export async function suggest(data, options = {}) {
|
|
62
|
+
try {
|
|
63
|
+
// Interactive mode if no data provided
|
|
64
|
+
if (!data) {
|
|
65
|
+
const answers = await inquirer.prompt([
|
|
66
|
+
{
|
|
67
|
+
type: 'list',
|
|
68
|
+
name: 'kind',
|
|
69
|
+
message: 'What type do you want to suggest?',
|
|
70
|
+
choices: ['Noun', 'Verb'],
|
|
71
|
+
default: 'Noun'
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
type: 'input',
|
|
75
|
+
name: 'data',
|
|
76
|
+
message: 'Enter data (JSON or text):',
|
|
77
|
+
validate: (input) => input.length > 0 || 'Data is required'
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
type: 'input',
|
|
81
|
+
name: 'hint',
|
|
82
|
+
message: 'Relationship hint (optional):',
|
|
83
|
+
when: (answers) => answers.kind === 'Verb'
|
|
84
|
+
}
|
|
85
|
+
]);
|
|
86
|
+
data = answers.data;
|
|
87
|
+
options.verb = answers.kind === 'Verb';
|
|
88
|
+
// For verbs, parse source/target if provided as JSON
|
|
89
|
+
if (options.verb && answers.hint) {
|
|
90
|
+
data = JSON.stringify({ hint: answers.hint });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const spinner = ora('Analyzing with AI...').start();
|
|
94
|
+
let parsedData;
|
|
95
|
+
try {
|
|
96
|
+
parsedData = JSON.parse(data);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
parsedData = { content: data };
|
|
100
|
+
}
|
|
101
|
+
let suggestion;
|
|
102
|
+
if (options.verb) {
|
|
103
|
+
// For verb suggestions, need source and target
|
|
104
|
+
const source = parsedData.source || { type: 'unknown' };
|
|
105
|
+
const target = parsedData.target || { type: 'unknown' };
|
|
106
|
+
const hint = parsedData.hint || parsedData.relationship || parsedData.verb;
|
|
107
|
+
suggestion = await BrainyTypes.suggestVerb(source, target, hint);
|
|
108
|
+
spinner.succeed('Verb type analyzed');
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
suggestion = await BrainyTypes.suggestNoun(parsedData);
|
|
112
|
+
spinner.succeed('Noun type analyzed');
|
|
113
|
+
}
|
|
114
|
+
if (options.json) {
|
|
115
|
+
console.log(JSON.stringify(suggestion, null, 2));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// Display results
|
|
119
|
+
console.log(chalk.bold.green(`\n✨ Suggested: ${suggestion.type}`));
|
|
120
|
+
console.log(chalk.cyan(`Confidence: ${(suggestion.confidence * 100).toFixed(1)}%`));
|
|
121
|
+
if (suggestion.alternatives && suggestion.alternatives.length > 0) {
|
|
122
|
+
console.log(chalk.yellow('\nAlternatives:'));
|
|
123
|
+
for (const alt of suggestion.alternatives.slice(0, 3)) {
|
|
124
|
+
console.log(` ${alt.type} (${(alt.confidence * 100).toFixed(1)}%)`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
console.error(chalk.red('Error:', error.message));
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Validate type - matches BrainyTypes.isValidNoun() and isValidVerb()
|
|
135
|
+
* Usage: brainy validate <type>
|
|
136
|
+
*/
|
|
137
|
+
export async function validate(type, options = {}) {
|
|
138
|
+
try {
|
|
139
|
+
// Interactive mode if no type provided
|
|
140
|
+
if (!type) {
|
|
141
|
+
const answers = await inquirer.prompt([
|
|
142
|
+
{
|
|
143
|
+
type: 'list',
|
|
144
|
+
name: 'kind',
|
|
145
|
+
message: 'Validate as:',
|
|
146
|
+
choices: ['Noun Type', 'Verb Type'],
|
|
147
|
+
default: 'Noun Type'
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'input',
|
|
151
|
+
name: 'type',
|
|
152
|
+
message: 'Enter type to validate:',
|
|
153
|
+
validate: (input) => input.length > 0 || 'Type is required'
|
|
154
|
+
}
|
|
155
|
+
]);
|
|
156
|
+
type = answers.type;
|
|
157
|
+
options.verb = answers.kind === 'Verb Type';
|
|
158
|
+
}
|
|
159
|
+
const isValid = options.verb
|
|
160
|
+
? BrainyTypes.isValidVerb(type)
|
|
161
|
+
: BrainyTypes.isValidNoun(type);
|
|
162
|
+
if (options.json) {
|
|
163
|
+
console.log(JSON.stringify({
|
|
164
|
+
type,
|
|
165
|
+
kind: options.verb ? 'verb' : 'noun',
|
|
166
|
+
valid: isValid
|
|
167
|
+
}, null, 2));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (isValid) {
|
|
171
|
+
console.log(chalk.green(`✅ "${type}" is valid`));
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
console.log(chalk.red(`❌ "${type}" is invalid`));
|
|
175
|
+
// Show valid options
|
|
176
|
+
const validTypes = options.verb ? BrainyTypes.verbs : BrainyTypes.nouns;
|
|
177
|
+
const similar = validTypes.filter(t => t.toLowerCase().includes(type.toLowerCase()) ||
|
|
178
|
+
type.toLowerCase().includes(t.toLowerCase())).slice(0, 5);
|
|
179
|
+
if (similar.length > 0) {
|
|
180
|
+
console.log(chalk.yellow('\nDid you mean:'));
|
|
181
|
+
similar.forEach(s => console.log(` ${s}`));
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
console.log(chalk.dim(`\nRun "brainy types" to see all valid types`));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
process.exit(isValid ? 0 : 1);
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
console.error(chalk.red('Error:', error.message));
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import ora from 'ora';
|
|
8
8
|
import Table from 'cli-table3';
|
|
9
|
-
import {
|
|
9
|
+
import { Brainy } from '../../brainy.js';
|
|
10
|
+
import { NounType } from '../../types/graphTypes.js';
|
|
10
11
|
let brainyInstance = null;
|
|
11
|
-
const getBrainy =
|
|
12
|
+
const getBrainy = () => {
|
|
12
13
|
if (!brainyInstance) {
|
|
13
|
-
brainyInstance = new
|
|
14
|
-
await brainyInstance.init();
|
|
14
|
+
brainyInstance = new Brainy();
|
|
15
15
|
}
|
|
16
16
|
return brainyInstance;
|
|
17
17
|
};
|
|
@@ -35,10 +35,16 @@ export const utilityCommands = {
|
|
|
35
35
|
async stats(options) {
|
|
36
36
|
const spinner = ora('Gathering statistics...').start();
|
|
37
37
|
try {
|
|
38
|
-
const brain =
|
|
39
|
-
const
|
|
38
|
+
const brain = getBrainy();
|
|
39
|
+
const nounCount = await brain.getNounCount();
|
|
40
|
+
const verbCount = await brain.getVerbCount();
|
|
40
41
|
const memUsage = process.memoryUsage();
|
|
41
42
|
spinner.succeed('Statistics gathered');
|
|
43
|
+
const stats = {
|
|
44
|
+
nounCount,
|
|
45
|
+
verbCount,
|
|
46
|
+
totalItems: nounCount + verbCount
|
|
47
|
+
};
|
|
42
48
|
if (options.json) {
|
|
43
49
|
formatOutput(stats, options);
|
|
44
50
|
return;
|
|
@@ -49,53 +55,8 @@ export const utilityCommands = {
|
|
|
49
55
|
head: [chalk.cyan('Metric'), chalk.cyan('Value')],
|
|
50
56
|
style: { head: [], border: [] }
|
|
51
57
|
});
|
|
52
|
-
coreTable.push(['Total Items', chalk.green(stats.
|
|
58
|
+
coreTable.push(['Total Items', chalk.green(stats.totalItems)], ['Nouns', chalk.green(stats.nounCount)], ['Verbs (Relationships)', chalk.green(stats.verbCount)]);
|
|
53
59
|
console.log(coreTable.toString());
|
|
54
|
-
// Service breakdown if available
|
|
55
|
-
if (options.byService && stats.serviceBreakdown) {
|
|
56
|
-
console.log(chalk.cyan('\n🔧 Service Breakdown\n'));
|
|
57
|
-
const serviceTable = new Table({
|
|
58
|
-
head: [chalk.cyan('Service'), chalk.cyan('Nouns'), chalk.cyan('Verbs'), chalk.cyan('Metadata')],
|
|
59
|
-
style: { head: [], border: [] }
|
|
60
|
-
});
|
|
61
|
-
Object.entries(stats.serviceBreakdown).forEach(([service, serviceStats]) => {
|
|
62
|
-
serviceTable.push([
|
|
63
|
-
service,
|
|
64
|
-
serviceStats.nounCount || 0,
|
|
65
|
-
serviceStats.verbCount || 0,
|
|
66
|
-
serviceStats.metadataCount || 0
|
|
67
|
-
]);
|
|
68
|
-
});
|
|
69
|
-
console.log(serviceTable.toString());
|
|
70
|
-
}
|
|
71
|
-
// Storage info
|
|
72
|
-
if (stats.storage) {
|
|
73
|
-
console.log(chalk.cyan('\n💾 Storage\n'));
|
|
74
|
-
const storageTable = new Table({
|
|
75
|
-
head: [chalk.cyan('Property'), chalk.cyan('Value')],
|
|
76
|
-
style: { head: [], border: [] }
|
|
77
|
-
});
|
|
78
|
-
storageTable.push(['Type', stats.storage.type || 'Unknown'], ['Size', stats.storage.size ? formatBytes(stats.storage.size) : 'N/A'], ['Location', stats.storage.location || 'N/A']);
|
|
79
|
-
console.log(storageTable.toString());
|
|
80
|
-
}
|
|
81
|
-
// Performance metrics
|
|
82
|
-
if (stats.performance && options.detailed) {
|
|
83
|
-
console.log(chalk.cyan('\n⚡ Performance\n'));
|
|
84
|
-
const perfTable = new Table({
|
|
85
|
-
head: [chalk.cyan('Metric'), chalk.cyan('Value')],
|
|
86
|
-
style: { head: [], border: [] }
|
|
87
|
-
});
|
|
88
|
-
if (stats.performance.avgQueryTime) {
|
|
89
|
-
perfTable.push(['Avg Query Time', `${stats.performance.avgQueryTime.toFixed(2)} ms`]);
|
|
90
|
-
}
|
|
91
|
-
if (stats.performance.totalQueries) {
|
|
92
|
-
perfTable.push(['Total Queries', stats.performance.totalQueries]);
|
|
93
|
-
}
|
|
94
|
-
if (stats.performance.cacheHitRate) {
|
|
95
|
-
perfTable.push(['Cache Hit Rate', `${(stats.performance.cacheHitRate * 100).toFixed(1)}%`]);
|
|
96
|
-
}
|
|
97
|
-
console.log(perfTable.toString());
|
|
98
|
-
}
|
|
99
60
|
// Memory usage
|
|
100
61
|
console.log(chalk.cyan('\n🧠 Memory Usage\n'));
|
|
101
62
|
const memTable = new Table({
|
|
@@ -104,16 +65,6 @@ export const utilityCommands = {
|
|
|
104
65
|
});
|
|
105
66
|
memTable.push(['Heap Used', formatBytes(memUsage.heapUsed)], ['Heap Total', formatBytes(memUsage.heapTotal)], ['RSS', formatBytes(memUsage.rss)], ['External', formatBytes(memUsage.external)]);
|
|
106
67
|
console.log(memTable.toString());
|
|
107
|
-
// Index info
|
|
108
|
-
if (stats.index && options.detailed) {
|
|
109
|
-
console.log(chalk.cyan('\n🎯 Vector Index\n'));
|
|
110
|
-
const indexTable = new Table({
|
|
111
|
-
head: [chalk.cyan('Property'), chalk.cyan('Value')],
|
|
112
|
-
style: { head: [], border: [] }
|
|
113
|
-
});
|
|
114
|
-
indexTable.push(['Dimensions', stats.index.dimensions || 'N/A'], ['Indexed Vectors', stats.index.vectorCount || 0], ['Index Size', stats.index.indexSize ? formatBytes(stats.index.indexSize) : 'N/A']);
|
|
115
|
-
console.log(indexTable.toString());
|
|
116
|
-
}
|
|
117
68
|
}
|
|
118
69
|
catch (error) {
|
|
119
70
|
spinner.fail('Failed to gather statistics');
|
|
@@ -127,40 +78,30 @@ export const utilityCommands = {
|
|
|
127
78
|
async clean(options) {
|
|
128
79
|
const spinner = ora('Cleaning database...').start();
|
|
129
80
|
try {
|
|
130
|
-
const brain =
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
tasks.push('Rebuilt search index');
|
|
141
|
-
// Implementation would go here
|
|
142
|
-
await new Promise(resolve => setTimeout(resolve, 1000)); // Simulate work
|
|
143
|
-
}
|
|
144
|
-
if (tasks.length === 0) {
|
|
145
|
-
spinner.text = 'Running general cleanup...';
|
|
146
|
-
tasks.push('General cleanup completed');
|
|
147
|
-
// Run general cleanup tasks
|
|
148
|
-
await new Promise(resolve => setTimeout(resolve, 500)); // Simulate work
|
|
81
|
+
const brain = getBrainy();
|
|
82
|
+
// For now, only support full clear
|
|
83
|
+
// removeOrphans and rebuildIndex would require new Brainy APIs
|
|
84
|
+
if (options.removeOrphans || options.rebuildIndex) {
|
|
85
|
+
spinner.warn('Advanced cleanup options not yet implemented');
|
|
86
|
+
console.log(chalk.yellow('\n⚠️ Advanced cleanup features coming in v3.21.0:'));
|
|
87
|
+
console.log(chalk.dim(' • --remove-orphans: Remove disconnected items'));
|
|
88
|
+
console.log(chalk.dim(' • --rebuild-index: Rebuild vector index'));
|
|
89
|
+
console.log(chalk.dim('\nUse "brainy clean" without options to clear the database'));
|
|
90
|
+
return;
|
|
149
91
|
}
|
|
150
|
-
|
|
92
|
+
// Show warning before clearing
|
|
93
|
+
console.log(chalk.yellow('\n⚠️ WARNING: This will permanently delete ALL data!'));
|
|
94
|
+
const dataApi = await brain.data();
|
|
95
|
+
// Clear all data
|
|
96
|
+
spinner.text = 'Clearing all data...';
|
|
97
|
+
await dataApi.clear({ entities: true, relations: true });
|
|
98
|
+
spinner.succeed('Database cleared');
|
|
151
99
|
if (!options.json) {
|
|
152
|
-
console.log(chalk.green('\n✓
|
|
153
|
-
|
|
154
|
-
console.log(chalk.dim(` • ${task}`));
|
|
155
|
-
});
|
|
156
|
-
// Get new stats
|
|
157
|
-
const stats = await brain.getStatistics();
|
|
158
|
-
console.log(chalk.cyan('\nDatabase Status:'));
|
|
159
|
-
console.log(` Total items: ${stats.nounCount + stats.verbCount}`);
|
|
160
|
-
console.log(` Index status: ${chalk.green('Healthy')}`);
|
|
100
|
+
console.log(chalk.green('\n✓ Database cleared successfully'));
|
|
101
|
+
console.log(chalk.dim(' All nouns, verbs, and metadata have been removed'));
|
|
161
102
|
}
|
|
162
103
|
else {
|
|
163
|
-
formatOutput({
|
|
104
|
+
formatOutput({ cleared: true, success: true }, options);
|
|
164
105
|
}
|
|
165
106
|
}
|
|
166
107
|
catch (error) {
|
|
@@ -181,7 +122,7 @@ export const utilityCommands = {
|
|
|
181
122
|
summary: {}
|
|
182
123
|
};
|
|
183
124
|
try {
|
|
184
|
-
const brain =
|
|
125
|
+
const brain = getBrainy();
|
|
185
126
|
// Benchmark different operations
|
|
186
127
|
const benchmarks = [
|
|
187
128
|
{ name: 'add', enabled: operations === 'all' || operations.includes('add') },
|
|
@@ -198,17 +139,17 @@ export const utilityCommands = {
|
|
|
198
139
|
const start = Date.now();
|
|
199
140
|
switch (bench.name) {
|
|
200
141
|
case 'add':
|
|
201
|
-
await brain.add(`Test item ${i}`, { benchmark: true });
|
|
142
|
+
await brain.add({ data: `Test item ${i}`, type: NounType.Thing, metadata: { benchmark: true } });
|
|
202
143
|
break;
|
|
203
144
|
case 'search':
|
|
204
|
-
await brain.
|
|
145
|
+
await brain.find({ query: 'test', limit: 10 });
|
|
205
146
|
break;
|
|
206
147
|
case 'similarity':
|
|
207
|
-
const neural = brain.neural;
|
|
148
|
+
const neural = brain.neural();
|
|
208
149
|
await neural.similar('test1', 'test2');
|
|
209
150
|
break;
|
|
210
151
|
case 'cluster':
|
|
211
|
-
const neuralApi = brain.neural;
|
|
152
|
+
const neuralApi = brain.neural();
|
|
212
153
|
await neuralApi.clusters();
|
|
213
154
|
break;
|
|
214
155
|
}
|
|
@@ -232,7 +173,7 @@ export const utilityCommands = {
|
|
|
232
173
|
const totalOps = Object.values(results.operations).reduce((sum, op) => sum + parseFloat(op.ops), 0);
|
|
233
174
|
results.summary = {
|
|
234
175
|
totalOperations: Object.keys(results.operations).length,
|
|
235
|
-
averageOpsPerSec: (totalOps / Object.keys(results.operations).length).toFixed(2)
|
|
176
|
+
averageOpsPerSec: totalOps > 0 ? (totalOps / Object.keys(results.operations).length).toFixed(2) : '0'
|
|
236
177
|
};
|
|
237
178
|
if (!options.json) {
|
|
238
179
|
// Display results table
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VFS CLI Commands - Virtual File System Operations
|
|
3
|
+
*
|
|
4
|
+
* Complete filesystem-like interface for Brainy's VFS
|
|
5
|
+
*/
|
|
6
|
+
interface VFSOptions {
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
pretty?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const vfsCommands: {
|
|
12
|
+
/**
|
|
13
|
+
* Read file from VFS
|
|
14
|
+
*/
|
|
15
|
+
read(path: string, options: VFSOptions & {
|
|
16
|
+
output?: string;
|
|
17
|
+
encoding?: string;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Write file to VFS
|
|
21
|
+
*/
|
|
22
|
+
write(path: string, options: VFSOptions & {
|
|
23
|
+
content?: string;
|
|
24
|
+
file?: string;
|
|
25
|
+
encoding?: string;
|
|
26
|
+
}): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* List directory contents
|
|
29
|
+
*/
|
|
30
|
+
ls(path: string, options: VFSOptions & {
|
|
31
|
+
long?: boolean;
|
|
32
|
+
all?: boolean;
|
|
33
|
+
}): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Get file/directory stats
|
|
36
|
+
*/
|
|
37
|
+
stat(path: string, options: VFSOptions): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Create directory
|
|
40
|
+
*/
|
|
41
|
+
mkdir(path: string, options: VFSOptions & {
|
|
42
|
+
parents?: boolean;
|
|
43
|
+
}): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Remove file or directory
|
|
46
|
+
*/
|
|
47
|
+
rm(path: string, options: VFSOptions & {
|
|
48
|
+
recursive?: boolean;
|
|
49
|
+
force?: boolean;
|
|
50
|
+
}): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Search files by content
|
|
53
|
+
*/
|
|
54
|
+
search(query: string, options: VFSOptions & {
|
|
55
|
+
path?: string;
|
|
56
|
+
limit?: string;
|
|
57
|
+
type?: string;
|
|
58
|
+
}): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Find similar files
|
|
61
|
+
*/
|
|
62
|
+
similar(path: string, options: VFSOptions & {
|
|
63
|
+
limit?: string;
|
|
64
|
+
threshold?: string;
|
|
65
|
+
}): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Get directory tree structure
|
|
68
|
+
*/
|
|
69
|
+
tree(path: string, options: VFSOptions & {
|
|
70
|
+
depth?: string;
|
|
71
|
+
}): Promise<void>;
|
|
72
|
+
};
|
|
73
|
+
export {};
|