From ae6fbd8c4c5842c00b7d02ed5181d9496fc4b8e8 Mon Sep 17 00:00:00 2001 From: David Snelling Date: Fri, 24 Oct 2025 15:59:41 -0700 Subject: [PATCH] fix: add includeVFS parameter to getRelations() - VFS now visible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CRITICAL BUG FIX - VFS Files Were Completely Invisible Workshop Team Issue: - Import created 569 VFS files - vfs.readdir('/') returned 0 items - VFS was 100% unusable Root Cause: v4.4.0 added includeVFS to brain.find() but FORGOT brain.getRelations(). PathResolver.getChildren() calls getRelations() to find VFS relationships, but those were being excluded by default - making ALL VFS files invisible! Fix: 1. Add includeVFS parameter to GetRelationsParams interface 2. Wire includeVFS filtering in brain.getRelations() - Excludes VFS relationships by default (metadata.isVFS != true) - Include them when includeVFS: true 3. Update VFS to mark all relationships with metadata: { isVFS: true } - 7 relate() calls updated in VirtualFileSystem.ts 4. Update PathResolver to use includeVFS: true - resolveChild() line 200 - getChildren() line 229 Impact: - VFS is now fully functional again - Consistent with v4.4.0 architecture (VFS separate from knowledge graph) - All APIs now have includeVFS where needed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/brainy.ts | 8 ++++++++ src/types/brainy.types.ts | 11 +++++++++++ src/vfs/PathResolver.ts | 6 ++++-- src/vfs/VirtualFileSystem.ts | 29 ++++++++++++++++++++++------- 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/brainy.ts b/src/brainy.ts index ef2de0ae..b15aa919 100644 --- a/src/brainy.ts +++ b/src/brainy.ts @@ -1016,6 +1016,14 @@ export class Brainy implements BrainyInterface { filter.service = params.service } + // v4.5.1: Exclude VFS relationships by default (same pattern as brain.find()) + // VFS relationships have metadata.isVFS = true + // Only include VFS relationships if explicitly requested + if (params.includeVFS !== true) { + filter.metadata = filter.metadata || {} + filter.metadata.isVFS = { notEquals: true } + } + // Fetch from storage with pagination at storage layer (efficient!) const result = await this.storage.getVerbs({ pagination: { diff --git a/src/types/brainy.types.ts b/src/types/brainy.types.ts index 8bea452f..ec80630c 100644 --- a/src/types/brainy.types.ts +++ b/src/types/brainy.types.ts @@ -324,6 +324,17 @@ export interface GetRelationsParams { * Only return relationships belonging to this service. */ service?: string + + /** + * Include VFS relationships (v4.5.1) + * + * By default, getRelations() excludes VFS relationships (since v4.4.0). + * Set this to true when you need to traverse VFS structure. + * + * @default false + * @since v4.5.1 + */ + includeVFS?: boolean } // ============= Batch Operations ============= diff --git a/src/vfs/PathResolver.ts b/src/vfs/PathResolver.ts index 6eb63c0e..3b49b1f1 100644 --- a/src/vfs/PathResolver.ts +++ b/src/vfs/PathResolver.ts @@ -199,7 +199,8 @@ export class PathResolver { // Get all relationships where parentId contains other entities const relations = await this.brain.getRelations({ from: parentId, - type: VerbType.Contains + type: VerbType.Contains, + includeVFS: true // v4.5.1: Required to see VFS relationships }) // Find the child with matching name @@ -227,7 +228,8 @@ export class PathResolver { // Production-ready: Use graph relationships (VFS creates these in mkdir/writeFile) const relations = await this.brain.getRelations({ from: dirId, - type: VerbType.Contains + type: VerbType.Contains, + includeVFS: true // v4.5.1: Required to see VFS relationships }) const validChildren: VFSEntity[] = [] diff --git a/src/vfs/VirtualFileSystem.ts b/src/vfs/VirtualFileSystem.ts index ef1b95d6..4069b94f 100644 --- a/src/vfs/VirtualFileSystem.ts +++ b/src/vfs/VirtualFileSystem.ts @@ -422,7 +422,8 @@ export class VirtualFileSystem implements IVirtualFileSystem { await this.brain.relate({ from: parentId, to: existingId, - type: VerbType.Contains + type: VerbType.Contains, + metadata: { isVFS: true } // v4.5.1: Mark as VFS relationship }) } } else { @@ -440,7 +441,8 @@ export class VirtualFileSystem implements IVirtualFileSystem { await this.brain.relate({ from: parentId, to: entity, - type: VerbType.Contains + type: VerbType.Contains, + metadata: { isVFS: true } // v4.5.1: Mark as VFS relationship }) // Update path resolver cache @@ -762,7 +764,8 @@ export class VirtualFileSystem implements IVirtualFileSystem { await this.brain.relate({ from: parentId, to: entity, - type: VerbType.Contains + type: VerbType.Contains, + metadata: { isVFS: true } // v4.5.1: Mark as VFS relationship }) } @@ -1674,7 +1677,12 @@ export class VirtualFileSystem implements IVirtualFileSystem { // Add to new parent if (newParentPath && newParentPath !== '/') { const newParentId = await this.pathResolver.resolve(newParentPath) - await this.brain.relate({ from: newParentId, to: entityId, type: VerbType.Contains }) + await this.brain.relate({ + from: newParentId, + to: entityId, + type: VerbType.Contains, + metadata: { isVFS: true } // v4.5.1: Mark as VFS relationship + }) } } @@ -1747,7 +1755,12 @@ export class VirtualFileSystem implements IVirtualFileSystem { const parentPath = this.getParentPath(destPath) if (parentPath && parentPath !== '/') { const parentId = await this.pathResolver.resolve(parentPath) - await this.brain.relate({ from: parentId, to: newEntity, type: VerbType.Contains }) + await this.brain.relate({ + from: parentId, + to: newEntity, + type: VerbType.Contains, + metadata: { isVFS: true } // v4.5.1: Mark as VFS relationship + }) } // Update path cache @@ -1847,7 +1860,8 @@ export class VirtualFileSystem implements IVirtualFileSystem { await this.brain.relate({ from: parentId, to: entity, - type: VerbType.Contains + type: VerbType.Contains, + metadata: { isVFS: true } // v4.5.1: Mark as VFS relationship }) // Update path resolver cache @@ -2056,7 +2070,8 @@ export class VirtualFileSystem implements IVirtualFileSystem { await this.brain.relate({ from: fromEntityId, to: toEntityId, - type: type as any // Convert string to VerbType + type: type as any, // Convert string to VerbType + metadata: { isVFS: true } // v4.5.1: Mark as VFS relationship }) // Invalidate caches for both paths