@soulcraft/brainy 3.19.1 → 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.
@@ -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 { Brainy } from '../../brainyData.js';
9
+ import { Brainy } from '../../brainy.js';
10
+ import { NounType } from '../../types/graphTypes.js';
10
11
  let brainyInstance = null;
11
- const getBrainy = async () => {
12
+ const getBrainy = () => {
12
13
  if (!brainyInstance) {
13
14
  brainyInstance = new Brainy();
14
- await brainyInstance.init();
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 = await getBrainy();
39
- const stats = await brain.getStatistics();
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.nounCount + stats.verbCount + stats.metadataCount || 0)], ['Nouns', chalk.green(stats.nounCount || 0)], ['Verbs (Relationships)', chalk.green(stats.verbCount || 0)], ['Metadata Records', chalk.green(stats.metadataCount || 0)]);
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 = await getBrainy();
131
- const tasks = [];
132
- if (options.removeOrphans) {
133
- spinner.text = 'Removing orphaned items...';
134
- tasks.push('Removed orphaned items');
135
- // Implementation would go here
136
- await new Promise(resolve => setTimeout(resolve, 500)); // Simulate work
137
- }
138
- if (options.rebuildIndex) {
139
- spinner.text = 'Rebuilding search index...';
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
- spinner.succeed('Database cleaned');
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āœ“ Cleanup completed:'));
153
- tasks.forEach(task => {
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({ tasks, success: true }, options);
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 = await getBrainy();
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.search('test', 10);
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
@@ -273,3 +214,4 @@ export const utilityCommands = {
273
214
  }
274
215
  }
275
216
  };
217
+ //# sourceMappingURL=utility.js.map
@@ -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 {};
@@ -0,0 +1,372 @@
1
+ /**
2
+ * VFS CLI Commands - Virtual File System Operations
3
+ *
4
+ * Complete filesystem-like interface for Brainy's VFS
5
+ */
6
+ import chalk from 'chalk';
7
+ import ora from 'ora';
8
+ import Table from 'cli-table3';
9
+ import { readFileSync, writeFileSync } from 'node:fs';
10
+ import { Brainy } from '../../brainy.js';
11
+ let brainyInstance = null;
12
+ const getBrainy = () => {
13
+ if (!brainyInstance) {
14
+ brainyInstance = new Brainy();
15
+ }
16
+ return brainyInstance;
17
+ };
18
+ const formatOutput = (data, options) => {
19
+ if (options.json) {
20
+ console.log(options.pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data));
21
+ }
22
+ };
23
+ const formatBytes = (bytes) => {
24
+ if (bytes === 0)
25
+ return '0 B';
26
+ const k = 1024;
27
+ const sizes = ['B', 'KB', 'MB', 'GB'];
28
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
29
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
30
+ };
31
+ const formatDate = (date) => {
32
+ return date.toLocaleString();
33
+ };
34
+ export const vfsCommands = {
35
+ /**
36
+ * Read file from VFS
37
+ */
38
+ async read(path, options) {
39
+ const spinner = ora('Reading file...').start();
40
+ try {
41
+ const brain = getBrainy();
42
+ const vfs = brain.vfs();
43
+ await vfs.init();
44
+ const buffer = await vfs.readFile(path, {
45
+ encoding: options.encoding
46
+ });
47
+ spinner.succeed('File read successfully');
48
+ if (options.output) {
49
+ // Write to local filesystem
50
+ writeFileSync(options.output, buffer);
51
+ console.log(chalk.green(`āœ“ Saved to: ${options.output}`));
52
+ }
53
+ else if (!options.json) {
54
+ // Display content
55
+ console.log('\n' + buffer.toString());
56
+ }
57
+ else {
58
+ formatOutput({ path, content: buffer.toString(), size: buffer.length }, options);
59
+ }
60
+ }
61
+ catch (error) {
62
+ spinner.fail('Failed to read file');
63
+ console.error(chalk.red(error.message));
64
+ process.exit(1);
65
+ }
66
+ },
67
+ /**
68
+ * Write file to VFS
69
+ */
70
+ async write(path, options) {
71
+ const spinner = ora('Writing file...').start();
72
+ try {
73
+ const brain = getBrainy();
74
+ const vfs = brain.vfs();
75
+ await vfs.init();
76
+ let data;
77
+ if (options.file) {
78
+ // Read from local file
79
+ data = readFileSync(options.file, 'utf-8');
80
+ }
81
+ else if (options.content) {
82
+ data = options.content;
83
+ }
84
+ else {
85
+ spinner.fail('Must provide --content or --file');
86
+ process.exit(1);
87
+ }
88
+ await vfs.writeFile(path, data, {
89
+ encoding: options.encoding
90
+ });
91
+ spinner.succeed('File written successfully');
92
+ if (!options.json) {
93
+ console.log(chalk.green(`āœ“ Written to: ${path}`));
94
+ console.log(chalk.dim(` Size: ${formatBytes(Buffer.byteLength(data))}`));
95
+ }
96
+ else {
97
+ formatOutput({ path, size: Buffer.byteLength(data) }, options);
98
+ }
99
+ }
100
+ catch (error) {
101
+ spinner.fail('Failed to write file');
102
+ console.error(chalk.red(error.message));
103
+ process.exit(1);
104
+ }
105
+ },
106
+ /**
107
+ * List directory contents
108
+ */
109
+ async ls(path, options) {
110
+ const spinner = ora('Listing directory...').start();
111
+ try {
112
+ const brain = getBrainy();
113
+ const vfs = brain.vfs();
114
+ await vfs.init();
115
+ const entries = await vfs.readdir(path, { withFileTypes: true });
116
+ spinner.succeed(`Found ${Array.isArray(entries) ? entries.length : 0} items`);
117
+ if (!options.json) {
118
+ if (!Array.isArray(entries) || entries.length === 0) {
119
+ console.log(chalk.yellow('Directory is empty'));
120
+ return;
121
+ }
122
+ if (options.long) {
123
+ // Long format with details
124
+ const table = new Table({
125
+ head: [chalk.cyan('Type'), chalk.cyan('Size'), chalk.cyan('Modified'), chalk.cyan('Name')],
126
+ style: { head: [], border: [] }
127
+ });
128
+ for (const entry of entries) {
129
+ if (!options.all && entry.name.startsWith('.'))
130
+ continue;
131
+ const stat = await vfs.stat(`${path}/${entry.name}`);
132
+ table.push([
133
+ entry.isDirectory() ? chalk.blue('DIR') : 'FILE',
134
+ entry.isDirectory() ? '-' : formatBytes(stat.size),
135
+ formatDate(stat.mtime),
136
+ entry.name
137
+ ]);
138
+ }
139
+ console.log('\n' + table.toString());
140
+ }
141
+ else {
142
+ // Simple format
143
+ console.log();
144
+ for (const entry of entries) {
145
+ if (!options.all && entry.name.startsWith('.'))
146
+ continue;
147
+ if (entry.isDirectory()) {
148
+ console.log(chalk.blue(entry.name + '/'));
149
+ }
150
+ else {
151
+ console.log(entry.name);
152
+ }
153
+ }
154
+ }
155
+ }
156
+ else {
157
+ formatOutput(entries, options);
158
+ }
159
+ }
160
+ catch (error) {
161
+ spinner.fail('Failed to list directory');
162
+ console.error(chalk.red(error.message));
163
+ process.exit(1);
164
+ }
165
+ },
166
+ /**
167
+ * Get file/directory stats
168
+ */
169
+ async stat(path, options) {
170
+ const spinner = ora('Getting file stats...').start();
171
+ try {
172
+ const brain = getBrainy();
173
+ const vfs = brain.vfs();
174
+ await vfs.init();
175
+ const stats = await vfs.stat(path);
176
+ spinner.succeed('Stats retrieved');
177
+ if (!options.json) {
178
+ console.log(chalk.cyan('\nFile Statistics:'));
179
+ console.log(` Path: ${path}`);
180
+ console.log(` Type: ${stats.isDirectory() ? chalk.blue('Directory') : 'File'}`);
181
+ console.log(` Size: ${formatBytes(stats.size)}`);
182
+ console.log(` Created: ${formatDate(stats.birthtime)}`);
183
+ console.log(` Modified: ${formatDate(stats.mtime)}`);
184
+ console.log(` Accessed: ${formatDate(stats.atime)}`);
185
+ }
186
+ else {
187
+ formatOutput(stats, options);
188
+ }
189
+ }
190
+ catch (error) {
191
+ spinner.fail('Failed to get stats');
192
+ console.error(chalk.red(error.message));
193
+ process.exit(1);
194
+ }
195
+ },
196
+ /**
197
+ * Create directory
198
+ */
199
+ async mkdir(path, options) {
200
+ const spinner = ora('Creating directory...').start();
201
+ try {
202
+ const brain = getBrainy();
203
+ const vfs = brain.vfs();
204
+ await vfs.init();
205
+ await vfs.mkdir(path, { recursive: options.parents });
206
+ spinner.succeed('Directory created');
207
+ if (!options.json) {
208
+ console.log(chalk.green(`āœ“ Created: ${path}`));
209
+ }
210
+ else {
211
+ formatOutput({ path, created: true }, options);
212
+ }
213
+ }
214
+ catch (error) {
215
+ spinner.fail('Failed to create directory');
216
+ console.error(chalk.red(error.message));
217
+ process.exit(1);
218
+ }
219
+ },
220
+ /**
221
+ * Remove file or directory
222
+ */
223
+ async rm(path, options) {
224
+ const spinner = ora('Removing...').start();
225
+ try {
226
+ const brain = getBrainy();
227
+ const vfs = brain.vfs();
228
+ await vfs.init();
229
+ const stats = await vfs.stat(path);
230
+ if (stats.isDirectory()) {
231
+ await vfs.rmdir(path, { recursive: options.recursive });
232
+ }
233
+ else {
234
+ await vfs.unlink(path);
235
+ }
236
+ spinner.succeed('Removed successfully');
237
+ if (!options.json) {
238
+ console.log(chalk.green(`āœ“ Removed: ${path}`));
239
+ }
240
+ else {
241
+ formatOutput({ path, removed: true }, options);
242
+ }
243
+ }
244
+ catch (error) {
245
+ spinner.fail('Failed to remove');
246
+ console.error(chalk.red(error.message));
247
+ if (!options.force) {
248
+ process.exit(1);
249
+ }
250
+ }
251
+ },
252
+ /**
253
+ * Search files by content
254
+ */
255
+ async search(query, options) {
256
+ const spinner = ora('Searching files...').start();
257
+ try {
258
+ const brain = getBrainy();
259
+ const vfs = brain.vfs();
260
+ await vfs.init();
261
+ const results = await vfs.search(query, {
262
+ path: options.path,
263
+ limit: options.limit ? parseInt(options.limit) : 10
264
+ });
265
+ spinner.succeed(`Found ${results.length} results`);
266
+ if (!options.json) {
267
+ if (results.length === 0) {
268
+ console.log(chalk.yellow('No results found'));
269
+ }
270
+ else {
271
+ console.log(chalk.cyan('\nšŸ“„ Search Results:\n'));
272
+ results.forEach((result, i) => {
273
+ console.log(chalk.bold(`${i + 1}. ${result.path}`));
274
+ if (result.score) {
275
+ console.log(chalk.dim(` Score: ${(result.score * 100).toFixed(1)}%`));
276
+ }
277
+ if (result.excerpt) {
278
+ console.log(chalk.dim(` ${result.excerpt}`));
279
+ }
280
+ console.log();
281
+ });
282
+ }
283
+ }
284
+ else {
285
+ formatOutput(results, options);
286
+ }
287
+ }
288
+ catch (error) {
289
+ spinner.fail('Search failed');
290
+ console.error(chalk.red(error.message));
291
+ process.exit(1);
292
+ }
293
+ },
294
+ /**
295
+ * Find similar files
296
+ */
297
+ async similar(path, options) {
298
+ const spinner = ora('Finding similar files...').start();
299
+ try {
300
+ const brain = getBrainy();
301
+ const vfs = brain.vfs();
302
+ await vfs.init();
303
+ const results = await vfs.findSimilar(path, {
304
+ limit: options.limit ? parseInt(options.limit) : 10,
305
+ threshold: options.threshold ? parseFloat(options.threshold) : 0.7
306
+ });
307
+ spinner.succeed(`Found ${results.length} similar files`);
308
+ if (!options.json) {
309
+ if (results.length === 0) {
310
+ console.log(chalk.yellow('No similar files found'));
311
+ }
312
+ else {
313
+ console.log(chalk.cyan('\nšŸ”— Similar Files:\n'));
314
+ results.forEach((result, i) => {
315
+ console.log(chalk.bold(`${i + 1}. ${result.path}`));
316
+ if (result.score) {
317
+ console.log(chalk.green(` Similarity: ${(result.score * 100).toFixed(1)}%`));
318
+ }
319
+ console.log();
320
+ });
321
+ }
322
+ }
323
+ else {
324
+ formatOutput(results, options);
325
+ }
326
+ }
327
+ catch (error) {
328
+ spinner.fail('Failed to find similar files');
329
+ console.error(chalk.red(error.message));
330
+ process.exit(1);
331
+ }
332
+ },
333
+ /**
334
+ * Get directory tree structure
335
+ */
336
+ async tree(path, options) {
337
+ const spinner = ora('Building tree...').start();
338
+ try {
339
+ const brain = getBrainy();
340
+ const vfs = brain.vfs();
341
+ await vfs.init();
342
+ const tree = await vfs.getTreeStructure(path, {
343
+ maxDepth: options.depth ? parseInt(options.depth) : 3
344
+ });
345
+ spinner.succeed('Tree built');
346
+ if (!options.json) {
347
+ console.log(chalk.cyan(`\nšŸ“ ${path}\n`));
348
+ displayTree(tree, '', true);
349
+ }
350
+ else {
351
+ formatOutput(tree, options);
352
+ }
353
+ }
354
+ catch (error) {
355
+ spinner.fail('Failed to build tree');
356
+ console.error(chalk.red(error.message));
357
+ process.exit(1);
358
+ }
359
+ }
360
+ };
361
+ function displayTree(node, prefix, isLast) {
362
+ const connector = isLast ? '└── ' : 'ā”œā”€ā”€ ';
363
+ const name = node.isDirectory ? chalk.blue(node.name + '/') : node.name;
364
+ console.log(prefix + connector + name);
365
+ if (node.children && node.children.length > 0) {
366
+ const childPrefix = prefix + (isLast ? ' ' : '│ ');
367
+ node.children.forEach((child, i) => {
368
+ displayTree(child, childPrefix, i === node.children.length - 1);
369
+ });
370
+ }
371
+ }
372
+ //# sourceMappingURL=vfs.js.map