@soulcraft/brainy 3.9.0 → 3.10.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.
Files changed (43) hide show
  1. package/README.md +89 -33
  2. package/dist/augmentations/KnowledgeAugmentation.d.ts +40 -0
  3. package/dist/augmentations/KnowledgeAugmentation.js +251 -0
  4. package/dist/augmentations/defaultAugmentations.d.ts +1 -0
  5. package/dist/augmentations/defaultAugmentations.js +5 -0
  6. package/dist/brainy.d.ts +11 -0
  7. package/dist/brainy.js +87 -1
  8. package/dist/embeddings/EmbeddingManager.js +14 -2
  9. package/dist/utils/mutex.d.ts +2 -0
  10. package/dist/utils/mutex.js +14 -3
  11. package/dist/vfs/ConceptSystem.d.ts +202 -0
  12. package/dist/vfs/ConceptSystem.js +598 -0
  13. package/dist/vfs/EntityManager.d.ts +75 -0
  14. package/dist/vfs/EntityManager.js +216 -0
  15. package/dist/vfs/EventRecorder.d.ts +83 -0
  16. package/dist/vfs/EventRecorder.js +292 -0
  17. package/dist/vfs/FSCompat.d.ts +85 -0
  18. package/dist/vfs/FSCompat.js +257 -0
  19. package/dist/vfs/GitBridge.d.ts +167 -0
  20. package/dist/vfs/GitBridge.js +537 -0
  21. package/dist/vfs/KnowledgeAugmentation.d.ts +104 -0
  22. package/dist/vfs/KnowledgeAugmentation.js +146 -0
  23. package/dist/vfs/KnowledgeLayer.d.ts +35 -0
  24. package/dist/vfs/KnowledgeLayer.js +443 -0
  25. package/dist/vfs/PathResolver.d.ts +96 -0
  26. package/dist/vfs/PathResolver.js +362 -0
  27. package/dist/vfs/PersistentEntitySystem.d.ts +163 -0
  28. package/dist/vfs/PersistentEntitySystem.js +525 -0
  29. package/dist/vfs/SemanticVersioning.d.ts +105 -0
  30. package/dist/vfs/SemanticVersioning.js +318 -0
  31. package/dist/vfs/VirtualFileSystem.d.ts +246 -0
  32. package/dist/vfs/VirtualFileSystem.js +1927 -0
  33. package/dist/vfs/importers/DirectoryImporter.d.ts +86 -0
  34. package/dist/vfs/importers/DirectoryImporter.js +298 -0
  35. package/dist/vfs/index.d.ts +19 -0
  36. package/dist/vfs/index.js +26 -0
  37. package/dist/vfs/streams/VFSReadStream.d.ts +19 -0
  38. package/dist/vfs/streams/VFSReadStream.js +54 -0
  39. package/dist/vfs/streams/VFSWriteStream.d.ts +21 -0
  40. package/dist/vfs/streams/VFSWriteStream.js +70 -0
  41. package/dist/vfs/types.d.ts +330 -0
  42. package/dist/vfs/types.js +46 -0
  43. package/package.json +1 -1
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Knowledge Augmentation
3
+ *
4
+ * Main orchestrator for the Knowledge Layer that coordinates all knowledge systems
5
+ * and enhances the VFS with intelligent capabilities
6
+ */
7
+ import crypto from 'crypto';
8
+ import { EventRecorder } from './EventRecorder.js';
9
+ import { SemanticVersioning } from './SemanticVersioning.js';
10
+ import { PersistentEntitySystem } from './PersistentEntitySystem.js';
11
+ import { ConceptSystem } from './ConceptSystem.js';
12
+ import { GitBridge } from './GitBridge.js';
13
+ export class KnowledgeAugmentation {
14
+ constructor(config) {
15
+ this.enabled = false;
16
+ this.config = config;
17
+ }
18
+ /**
19
+ * Initialize the Knowledge Augmentation with Brainy instance
20
+ */
21
+ async init(brain, vfs) {
22
+ this.brain = brain;
23
+ this.vfs = vfs;
24
+ if (!this.config.enabled) {
25
+ return;
26
+ }
27
+ // Initialize sub-systems
28
+ if (this.config.eventRecording?.enabled) {
29
+ this.eventRecorder = new EventRecorder(this.brain);
30
+ }
31
+ if (this.config.semanticVersioning?.enabled !== false) {
32
+ this.semanticVersioning = new SemanticVersioning(this.brain);
33
+ }
34
+ if (this.config.entitySystem?.enabled !== false) {
35
+ this.entitySystem = new PersistentEntitySystem(this.brain);
36
+ }
37
+ if (this.config.conceptSystem?.enabled !== false) {
38
+ this.conceptSystem = new ConceptSystem(this.brain);
39
+ }
40
+ if (this.config.gitBridge?.enabled !== false) {
41
+ this.gitBridge = new GitBridge(this.brain, this.vfs);
42
+ }
43
+ this.enabled = true;
44
+ }
45
+ /**
46
+ * Enable the Knowledge Augmentation
47
+ */
48
+ async enable() {
49
+ if (!this.brain || !this.vfs) {
50
+ throw new Error('Knowledge augmentation not initialized. Call init() first.');
51
+ }
52
+ this.enabled = true;
53
+ // Enhance VFS with knowledge methods
54
+ this.enhanceVFS();
55
+ }
56
+ /**
57
+ * Disable the Knowledge Augmentation
58
+ */
59
+ async disable() {
60
+ this.enabled = false;
61
+ // Remove VFS enhancements if any were added
62
+ // For now, just mark as disabled
63
+ }
64
+ /**
65
+ * Check if the knowledge augmentation is enabled
66
+ */
67
+ isEnabled() {
68
+ return this.enabled;
69
+ }
70
+ /**
71
+ * Get the EventRecorder instance
72
+ */
73
+ getEventRecorder() {
74
+ return this.eventRecorder;
75
+ }
76
+ /**
77
+ * Get the SemanticVersioning instance
78
+ */
79
+ getSemanticVersioning() {
80
+ return this.semanticVersioning;
81
+ }
82
+ /**
83
+ * Get the PersistentEntitySystem instance
84
+ */
85
+ getEntitySystem() {
86
+ return this.entitySystem;
87
+ }
88
+ /**
89
+ * Get the ConceptSystem instance
90
+ */
91
+ getConceptSystem() {
92
+ return this.conceptSystem;
93
+ }
94
+ /**
95
+ * Get the GitBridge instance
96
+ */
97
+ getGitBridge() {
98
+ return this.gitBridge;
99
+ }
100
+ /**
101
+ * Record a file event (called by VFS)
102
+ */
103
+ async recordEvent(type, path, metadata) {
104
+ if (!this.enabled || !this.eventRecorder)
105
+ return;
106
+ await this.eventRecorder.recordEvent({
107
+ id: crypto.randomUUID(),
108
+ timestamp: Date.now(),
109
+ type,
110
+ path,
111
+ metadata
112
+ });
113
+ }
114
+ /**
115
+ * Create a semantic version (called by VFS)
116
+ */
117
+ async createVersion(path, content) {
118
+ if (!this.enabled || !this.semanticVersioning)
119
+ return;
120
+ await this.semanticVersioning.createVersion(path, content);
121
+ }
122
+ /**
123
+ * Extract entities from content (called by VFS)
124
+ */
125
+ async extractEntities(path, content) {
126
+ if (!this.enabled || !this.entitySystem)
127
+ return;
128
+ await this.entitySystem.extractEntities(content, { sourcePath: path });
129
+ }
130
+ /**
131
+ * Extract concepts from content (called by VFS)
132
+ */
133
+ async extractConcepts(path, content) {
134
+ if (!this.enabled || !this.conceptSystem)
135
+ return;
136
+ await this.conceptSystem.extractConcepts(content, { sourcePath: path });
137
+ }
138
+ /**
139
+ * Enhance the VFS with knowledge methods
140
+ */
141
+ enhanceVFS() {
142
+ // For now, the VFS calls the knowledge methods directly
143
+ // In the future, we could add methods to the VFS prototype
144
+ }
145
+ }
146
+ //# sourceMappingURL=KnowledgeAugmentation.js.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Knowledge Layer for VFS
3
+ *
4
+ * This is the REAL integration that makes VFS intelligent.
5
+ * It wraps VFS operations and adds Knowledge Layer processing.
6
+ */
7
+ import { VirtualFileSystem } from './VirtualFileSystem.js';
8
+ import { Brainy } from '../brainy.js';
9
+ export declare class KnowledgeLayer {
10
+ private vfs;
11
+ private brain;
12
+ private eventRecorder;
13
+ private semanticVersioning;
14
+ private entitySystem;
15
+ private conceptSystem;
16
+ private gitBridge;
17
+ private enabled;
18
+ constructor(vfs: VirtualFileSystem, brain: Brainy);
19
+ /**
20
+ * Enable Knowledge Layer by wrapping VFS methods
21
+ */
22
+ enable(): Promise<void>;
23
+ /**
24
+ * Add Knowledge Layer query methods to VFS
25
+ */
26
+ private addKnowledgeMethods;
27
+ /**
28
+ * Disable Knowledge Layer
29
+ */
30
+ disable(): Promise<void>;
31
+ }
32
+ /**
33
+ * Enable Knowledge Layer on a VFS instance
34
+ */
35
+ export declare function enableKnowledgeLayer(vfs: VirtualFileSystem, brain: Brainy): Promise<KnowledgeLayer>;
@@ -0,0 +1,443 @@
1
+ /**
2
+ * Knowledge Layer for VFS
3
+ *
4
+ * This is the REAL integration that makes VFS intelligent.
5
+ * It wraps VFS operations and adds Knowledge Layer processing.
6
+ */
7
+ import { EventRecorder } from './EventRecorder.js';
8
+ import { SemanticVersioning } from './SemanticVersioning.js';
9
+ import { PersistentEntitySystem } from './PersistentEntitySystem.js';
10
+ import { ConceptSystem } from './ConceptSystem.js';
11
+ import { GitBridge } from './GitBridge.js';
12
+ export class KnowledgeLayer {
13
+ constructor(vfs, brain) {
14
+ this.vfs = vfs;
15
+ this.brain = brain;
16
+ this.enabled = false;
17
+ // Initialize all Knowledge Layer components
18
+ this.eventRecorder = new EventRecorder(brain);
19
+ this.semanticVersioning = new SemanticVersioning(brain);
20
+ this.entitySystem = new PersistentEntitySystem(brain);
21
+ this.conceptSystem = new ConceptSystem(brain);
22
+ this.gitBridge = new GitBridge(vfs, brain);
23
+ }
24
+ /**
25
+ * Enable Knowledge Layer by wrapping VFS methods
26
+ */
27
+ async enable() {
28
+ if (this.enabled)
29
+ return;
30
+ this.enabled = true;
31
+ // Save original methods
32
+ const originalWriteFile = this.vfs.writeFile.bind(this.vfs);
33
+ const originalUnlink = this.vfs.unlink.bind(this.vfs);
34
+ const originalRename = this.vfs.rename.bind(this.vfs);
35
+ const originalMkdir = this.vfs.mkdir.bind(this.vfs);
36
+ const originalRmdir = this.vfs.rmdir.bind(this.vfs);
37
+ // Wrap writeFile to add intelligence
38
+ this.vfs.writeFile = async (path, data, options) => {
39
+ // Call original VFS method first
40
+ const result = await originalWriteFile(path, data, options);
41
+ // Process in background (non-blocking)
42
+ setImmediate(async () => {
43
+ try {
44
+ const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
45
+ // 1. Record the event
46
+ await this.eventRecorder.recordEvent({
47
+ type: 'write',
48
+ path,
49
+ content: buffer,
50
+ size: buffer.length,
51
+ author: options?.author || 'system'
52
+ });
53
+ // 2. Check for semantic versioning
54
+ try {
55
+ const existingContent = await this.vfs.readFile(path).catch(() => null);
56
+ if (existingContent) {
57
+ const shouldVersion = await this.semanticVersioning.shouldVersion(existingContent, buffer);
58
+ if (shouldVersion) {
59
+ await this.semanticVersioning.createVersion(path, buffer, {
60
+ message: options?.message || 'Automatic semantic version'
61
+ });
62
+ }
63
+ }
64
+ }
65
+ catch (err) {
66
+ console.debug('Versioning check failed:', err);
67
+ }
68
+ // 3. Extract entities
69
+ if (options?.extractEntities !== false) {
70
+ await this.entitySystem.extractEntities(path, buffer);
71
+ }
72
+ // 4. Extract concepts
73
+ if (options?.extractConcepts !== false) {
74
+ await this.conceptSystem.extractAndLinkConcepts(path, buffer);
75
+ }
76
+ }
77
+ catch (error) {
78
+ console.debug('Knowledge Layer processing error:', error);
79
+ }
80
+ });
81
+ return result;
82
+ };
83
+ // Wrap unlink to record deletion
84
+ this.vfs.unlink = async (path) => {
85
+ const result = await originalUnlink(path);
86
+ setImmediate(async () => {
87
+ await this.eventRecorder.recordEvent({
88
+ type: 'delete',
89
+ path,
90
+ author: 'system'
91
+ });
92
+ });
93
+ return result;
94
+ };
95
+ // Wrap rename to track moves
96
+ this.vfs.rename = async (oldPath, newPath) => {
97
+ const result = await originalRename(oldPath, newPath);
98
+ setImmediate(async () => {
99
+ await this.eventRecorder.recordEvent({
100
+ type: 'rename',
101
+ path: oldPath,
102
+ metadata: { newPath },
103
+ author: 'system'
104
+ });
105
+ });
106
+ return result;
107
+ };
108
+ // Wrap mkdir to track directory creation
109
+ this.vfs.mkdir = async (path, options) => {
110
+ const result = await originalMkdir(path, options);
111
+ setImmediate(async () => {
112
+ await this.eventRecorder.recordEvent({
113
+ type: 'mkdir',
114
+ path,
115
+ author: 'system'
116
+ });
117
+ });
118
+ return result;
119
+ };
120
+ // Wrap rmdir to track directory deletion
121
+ this.vfs.rmdir = async (path, options) => {
122
+ const result = await originalRmdir(path, options);
123
+ setImmediate(async () => {
124
+ await this.eventRecorder.recordEvent({
125
+ type: 'rmdir',
126
+ path,
127
+ author: 'system'
128
+ });
129
+ });
130
+ return result;
131
+ };
132
+ // Add Knowledge Layer methods to VFS
133
+ this.addKnowledgeMethods();
134
+ console.log('✨ Knowledge Layer enabled on VFS');
135
+ }
136
+ /**
137
+ * Add Knowledge Layer query methods to VFS
138
+ */
139
+ addKnowledgeMethods() {
140
+ // Event history
141
+ this.vfs.getHistory = async (path, options) => {
142
+ return await this.eventRecorder.getHistory(path, options);
143
+ };
144
+ this.vfs.reconstructAtTime = async (path, timestamp) => {
145
+ return await this.eventRecorder.reconstructFileAtTime(path, timestamp);
146
+ };
147
+ // Semantic versioning
148
+ this.vfs.getVersions = async (path) => {
149
+ return await this.semanticVersioning.getVersions(path);
150
+ };
151
+ this.vfs.getVersion = async (path, versionId) => {
152
+ return await this.semanticVersioning.getVersion(path, versionId);
153
+ };
154
+ this.vfs.restoreVersion = async (path, versionId) => {
155
+ const content = await this.semanticVersioning.getVersion(path, versionId);
156
+ if (content) {
157
+ await this.vfs.writeFile(path, content);
158
+ }
159
+ };
160
+ // Entity system
161
+ this.vfs.createEntity = async (config) => {
162
+ return await this.entitySystem.createEntity(config);
163
+ };
164
+ this.vfs.findEntity = async (query) => {
165
+ return await this.entitySystem.findEntity(query);
166
+ };
167
+ this.vfs.getEntityEvolution = async (entityId) => {
168
+ return await this.entitySystem.getEvolution(entityId);
169
+ };
170
+ // Concept system
171
+ this.vfs.createConcept = async (config) => {
172
+ return await this.conceptSystem.createConcept(config);
173
+ };
174
+ this.vfs.findConcepts = async (query) => {
175
+ return await this.conceptSystem.findConcepts(query);
176
+ };
177
+ this.vfs.getConceptGraph = async (options) => {
178
+ return await this.conceptSystem.getConceptGraph(options);
179
+ };
180
+ // Git bridge
181
+ this.vfs.exportToGit = async (vfsPath, gitPath) => {
182
+ return await this.gitBridge.exportToGit(vfsPath, gitPath);
183
+ };
184
+ this.vfs.importFromGit = async (gitPath, vfsPath) => {
185
+ return await this.gitBridge.importFromGit(gitPath, vfsPath);
186
+ };
187
+ // Temporal coupling
188
+ this.vfs.findTemporalCoupling = async (path, windowMs) => {
189
+ return await this.eventRecorder.findTemporalCoupling(path, windowMs);
190
+ };
191
+ // Entity convenience methods that wrap Brainy's core API
192
+ this.vfs.linkEntities = async (fromEntity, toEntity, relationship) => {
193
+ // Handle both entity IDs and entity objects
194
+ const fromId = typeof fromEntity === 'string' ? fromEntity : fromEntity.id;
195
+ const toId = typeof toEntity === 'string' ? toEntity : toEntity.id;
196
+ // Use brain.relate to create the relationship
197
+ return await this.brain.relate({
198
+ from: fromId,
199
+ to: toId,
200
+ type: relationship // VerbType or string
201
+ });
202
+ };
203
+ // Find where an entity appears across files
204
+ this.vfs.findEntityOccurrences = async (entityId) => {
205
+ const occurrences = [];
206
+ // Search for files that contain references to this entity
207
+ // First, get all relationships where this entity is involved
208
+ const relations = await this.brain.getRelations({ from: entityId });
209
+ const toRelations = await this.brain.getRelations({ to: entityId });
210
+ // Find file entities that relate to this entity
211
+ for (const rel of [...relations, ...toRelations]) {
212
+ try {
213
+ // Check if the related entity is a file
214
+ const relatedId = rel.from === entityId ? rel.to : rel.from;
215
+ const entity = await this.brain.get(relatedId);
216
+ if (entity?.metadata?.vfsType === 'file' && entity?.metadata?.path) {
217
+ occurrences.push({
218
+ path: entity.metadata.path,
219
+ context: entity.data ? entity.data.toString().substring(0, 200) : undefined
220
+ });
221
+ }
222
+ }
223
+ catch (error) {
224
+ // Entity might not exist, continue
225
+ }
226
+ }
227
+ // Also search for files that mention the entity name in their content
228
+ const entityData = await this.brain.get(entityId);
229
+ if (entityData?.metadata?.name) {
230
+ const searchResults = await this.brain.find({
231
+ query: entityData.metadata.name,
232
+ where: { vfsType: 'file' },
233
+ limit: 20
234
+ });
235
+ for (const result of searchResults) {
236
+ if (result.entity?.metadata?.path && !occurrences.some(o => o.path === result.entity.metadata.path)) {
237
+ occurrences.push({
238
+ path: result.entity.metadata.path,
239
+ context: result.entity.data ? result.entity.data.toString().substring(0, 200) : undefined
240
+ });
241
+ }
242
+ }
243
+ }
244
+ return occurrences;
245
+ };
246
+ // Update an entity (convenience wrapper)
247
+ this.vfs.updateEntity = async (entityId, updates) => {
248
+ // Get current entity from brain
249
+ const currentEntity = await this.brain.get(entityId);
250
+ if (!currentEntity) {
251
+ throw new Error(`Entity ${entityId} not found`);
252
+ }
253
+ // Merge updates
254
+ const updatedMetadata = {
255
+ ...currentEntity.metadata,
256
+ ...updates,
257
+ lastUpdated: Date.now(),
258
+ version: (currentEntity.metadata?.version || 0) + 1
259
+ };
260
+ // Update via brain
261
+ await this.brain.update({
262
+ id: entityId,
263
+ data: JSON.stringify(updatedMetadata),
264
+ metadata: updatedMetadata
265
+ });
266
+ return entityId;
267
+ };
268
+ // Get entity graph (convenience wrapper)
269
+ this.vfs.getEntityGraph = async (entityId, options) => {
270
+ const depth = options?.depth || 2;
271
+ const graph = { nodes: new Map(), edges: [] };
272
+ const visited = new Set();
273
+ const traverse = async (id, currentDepth) => {
274
+ if (visited.has(id) || currentDepth > depth)
275
+ return;
276
+ visited.add(id);
277
+ // Add node
278
+ const entity = await this.brain.get(id);
279
+ if (entity) {
280
+ graph.nodes.set(id, entity);
281
+ }
282
+ // Get relationships
283
+ const relations = await this.brain.getRelations({ from: id });
284
+ const toRelations = await this.brain.getRelations({ to: id });
285
+ for (const rel of [...relations, ...toRelations]) {
286
+ graph.edges.push(rel);
287
+ // Traverse connected nodes
288
+ if (currentDepth < depth) {
289
+ const nextId = rel.from === id ? rel.to : rel.from;
290
+ await traverse(nextId, currentDepth + 1);
291
+ }
292
+ }
293
+ };
294
+ await traverse(entityId, 0);
295
+ return {
296
+ nodes: Array.from(graph.nodes.values()),
297
+ edges: graph.edges
298
+ };
299
+ };
300
+ // List all entities of a specific type
301
+ this.vfs.listEntities = async (query) => {
302
+ return await this.entitySystem.findEntity(query || {});
303
+ };
304
+ // Find files by concept
305
+ this.vfs.findByConcept = async (conceptName) => {
306
+ const paths = [];
307
+ // First find the concept
308
+ const concepts = await this.conceptSystem.findConcepts({ name: conceptName });
309
+ if (concepts.length === 0) {
310
+ return paths;
311
+ }
312
+ const concept = concepts[0];
313
+ // Search for files that contain concept keywords
314
+ const searchTerms = [conceptName, ...(concept.keywords || [])].join(' ');
315
+ const searchResults = await this.brain.find({
316
+ query: searchTerms,
317
+ where: { vfsType: 'file' },
318
+ limit: 50
319
+ });
320
+ // Get unique paths
321
+ const pathSet = new Set();
322
+ for (const result of searchResults) {
323
+ if (result.entity?.metadata?.path) {
324
+ pathSet.add(result.entity.metadata.path);
325
+ }
326
+ }
327
+ // Also check concept manifestations if stored
328
+ if (concept.manifestations) {
329
+ for (const manifestation of concept.manifestations) {
330
+ if (manifestation.filePath) {
331
+ pathSet.add(manifestation.filePath);
332
+ }
333
+ }
334
+ }
335
+ return Array.from(pathSet);
336
+ };
337
+ // Get timeline of events
338
+ this.vfs.getTimeline = async (options) => {
339
+ const fromTime = options?.from ? new Date(options.from).getTime() : Date.now() - 30 * 24 * 60 * 60 * 1000; // 30 days ago
340
+ const toTime = options?.to ? new Date(options.to).getTime() : Date.now();
341
+ const limit = options?.limit || 100;
342
+ // Get events from event recorder
343
+ const events = await this.eventRecorder.getEvents({
344
+ since: fromTime,
345
+ until: toTime,
346
+ types: options?.types,
347
+ limit
348
+ });
349
+ // Transform to timeline format
350
+ return events.map(event => ({
351
+ timestamp: new Date(event.timestamp),
352
+ type: event.type,
353
+ path: event.path,
354
+ user: event.author,
355
+ description: `${event.type} ${event.path}${event.oldPath ? ` (from ${event.oldPath})` : ''}`
356
+ }));
357
+ };
358
+ // Get collaboration history for a file
359
+ this.vfs.getCollaborationHistory = async (path) => {
360
+ // Get all events for this path
361
+ const history = await this.eventRecorder.getHistory(path, { limit: 100 });
362
+ return history.map(event => ({
363
+ user: event.author || 'system',
364
+ timestamp: new Date(event.timestamp),
365
+ action: event.type,
366
+ size: event.size
367
+ }));
368
+ };
369
+ // Export to markdown format
370
+ this.vfs.exportToMarkdown = async (path) => {
371
+ const markdown = [];
372
+ const traverse = async (currentPath, depth = 0) => {
373
+ const indent = ' '.repeat(depth);
374
+ try {
375
+ const stats = await this.vfs.stat(currentPath);
376
+ if (stats.isDirectory()) {
377
+ // Add directory header
378
+ const name = currentPath.split('/').pop() || currentPath;
379
+ markdown.push(`${indent}## ${name}/`);
380
+ markdown.push('');
381
+ // List and traverse children
382
+ const children = await this.vfs.readdir(currentPath);
383
+ for (const child of children.sort()) {
384
+ const childPath = currentPath === '/' ? `/${child}` : `${currentPath}/${child}`;
385
+ await traverse(childPath, depth + 1);
386
+ }
387
+ }
388
+ else {
389
+ // Add file content
390
+ const name = currentPath.split('/').pop() || currentPath;
391
+ const extension = name.split('.').pop() || 'txt';
392
+ try {
393
+ const content = await this.vfs.readFile(currentPath);
394
+ const textContent = content.toString('utf8');
395
+ markdown.push(`${indent}### ${name}`);
396
+ markdown.push('');
397
+ // Add code block for code files
398
+ if (['js', 'ts', 'jsx', 'tsx', 'py', 'java', 'cpp', 'go', 'rs', 'json'].includes(extension)) {
399
+ markdown.push(`${indent}\`\`\`${extension}`);
400
+ markdown.push(textContent.split('\n').map(line => `${indent}${line}`).join('\n'));
401
+ markdown.push(`${indent}\`\`\``);
402
+ }
403
+ else if (extension === 'md') {
404
+ // Include markdown directly
405
+ markdown.push(textContent);
406
+ }
407
+ else {
408
+ // Plain text in quotes
409
+ markdown.push(`${indent}> ${textContent.split('\n').join(`\n${indent}> `)}`);
410
+ }
411
+ markdown.push('');
412
+ }
413
+ catch (error) {
414
+ markdown.push(`${indent}*Binary or unreadable file*`);
415
+ markdown.push('');
416
+ }
417
+ }
418
+ }
419
+ catch (error) {
420
+ // Skip inaccessible paths
421
+ }
422
+ };
423
+ await traverse(path);
424
+ return markdown.join('\n');
425
+ };
426
+ }
427
+ /**
428
+ * Disable Knowledge Layer
429
+ */
430
+ async disable() {
431
+ // Would restore original methods here
432
+ this.enabled = false;
433
+ }
434
+ }
435
+ /**
436
+ * Enable Knowledge Layer on a VFS instance
437
+ */
438
+ export async function enableKnowledgeLayer(vfs, brain) {
439
+ const knowledgeLayer = new KnowledgeLayer(vfs, brain);
440
+ await knowledgeLayer.enable();
441
+ return knowledgeLayer;
442
+ }
443
+ //# sourceMappingURL=KnowledgeLayer.js.map