@soulcraft/brainy 6.3.1 → 6.3.2

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 CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [6.3.2](https://github.com/soulcraftlabs/brainy/compare/v6.3.1...v6.3.2) (2025-12-09)
6
+
7
+
8
+ ### 🐛 Bug Fixes
9
+
10
+ * **versioning:** VFS file versions now capture actual blob content ([3e0f235](https://github.com/soulcraftlabs/brainy/commit/3e0f235f8b2cfcc6f0792a457879a02e4b93897a))
11
+
5
12
  ### [6.3.1](https://github.com/soulcraftlabs/brainy/compare/v6.3.0...v6.3.1) (2025-12-09)
6
13
 
7
14
  - fix(versioning): clean architecture with index pollution prevention (f145fa1)
@@ -99,6 +99,20 @@ export declare class VersionManager {
99
99
  private versionIndex;
100
100
  private initialized;
101
101
  constructor(brain: any);
102
+ /**
103
+ * Check if an entity is a VFS file
104
+ * VFS files store content in BlobStorage, not in entity.data
105
+ *
106
+ * @param entity Entity metadata object
107
+ * @returns True if entity is a VFS file
108
+ */
109
+ private isVFSFile;
110
+ /**
111
+ * Check if content is text-based for encoding decisions
112
+ * @param mimeType MIME type of the content
113
+ * @returns True if content should be stored as UTF-8 string
114
+ */
115
+ private isTextContent;
102
116
  /**
103
117
  * Initialize versioning system (lazy)
104
118
  */
@@ -35,6 +35,34 @@ export class VersionManager {
35
35
  this.versionStorage = new VersionStorage(brain);
36
36
  this.versionIndex = new VersionIndex(brain);
37
37
  }
38
+ /**
39
+ * Check if an entity is a VFS file
40
+ * VFS files store content in BlobStorage, not in entity.data
41
+ *
42
+ * @param entity Entity metadata object
43
+ * @returns True if entity is a VFS file
44
+ */
45
+ isVFSFile(entity) {
46
+ return (entity?.isVFS === true &&
47
+ entity?.vfsType === 'file' &&
48
+ typeof entity?.path === 'string');
49
+ }
50
+ /**
51
+ * Check if content is text-based for encoding decisions
52
+ * @param mimeType MIME type of the content
53
+ * @returns True if content should be stored as UTF-8 string
54
+ */
55
+ isTextContent(mimeType) {
56
+ if (!mimeType)
57
+ return false;
58
+ return (mimeType.startsWith('text/') ||
59
+ mimeType === 'application/json' ||
60
+ mimeType === 'application/javascript' ||
61
+ mimeType === 'application/typescript' ||
62
+ mimeType === 'application/xml' ||
63
+ mimeType.includes('+xml') ||
64
+ mimeType.includes('+json'));
65
+ }
38
66
  /**
39
67
  * Initialize versioning system (lazy)
40
68
  */
@@ -62,6 +90,27 @@ export class VersionManager {
62
90
  if (!entity) {
63
91
  throw new Error(`Entity ${entityId} not found`);
64
92
  }
93
+ // v6.3.2 FIX: For VFS file entities, fetch current content from blob storage
94
+ // The entity.data field contains stale embedding text, not actual file content
95
+ // VFS files store their real content in BlobStorage (content-addressable)
96
+ if (this.isVFSFile(entity)) {
97
+ if (!this.brain.vfs) {
98
+ throw new Error(`Cannot version VFS file ${entityId}: VFS not initialized. ` +
99
+ `Ensure brain.vfs is available before versioning VFS files.`);
100
+ }
101
+ // Read fresh content from blob storage via VFS
102
+ const freshContent = await this.brain.vfs.readFile(entity.path);
103
+ // Store content with appropriate encoding
104
+ // Text files as UTF-8 string (readable, smaller)
105
+ // Binary files as base64 (safe for JSON serialization)
106
+ if (this.isTextContent(entity.mimeType)) {
107
+ entity.data = freshContent.toString('utf-8');
108
+ }
109
+ else {
110
+ entity.data = freshContent.toString('base64');
111
+ entity._vfsEncoding = 'base64'; // Flag for restore to decode
112
+ }
113
+ }
65
114
  // Get current branch
66
115
  const currentBranch = this.brain.currentBranch;
67
116
  // Get next version number
@@ -207,6 +256,32 @@ export class VersionManager {
207
256
  if (!versionedEntity) {
208
257
  throw new Error(`Version data not found for entity ${entityId} version ${version}`);
209
258
  }
259
+ // v6.3.2 FIX: For VFS file entities, write content back to blob storage
260
+ // The versioned data contains the actual file content (not stale embedding text)
261
+ // Using vfs.writeFile() ensures proper blob creation and metadata update
262
+ if (this.isVFSFile(versionedEntity)) {
263
+ if (!this.brain.vfs) {
264
+ throw new Error(`Cannot restore VFS file ${entityId}: VFS not initialized. ` +
265
+ `Ensure brain.vfs is available before restoring VFS files.`);
266
+ }
267
+ // Decode content based on how it was stored
268
+ let content;
269
+ if (versionedEntity._vfsEncoding === 'base64') {
270
+ // Binary file stored as base64
271
+ content = Buffer.from(versionedEntity.data, 'base64');
272
+ }
273
+ else {
274
+ // Text file stored as UTF-8 string
275
+ content = Buffer.from(versionedEntity.data, 'utf-8');
276
+ }
277
+ // Write content back to VFS - this handles:
278
+ // - BlobStorage write (new hash)
279
+ // - Entity metadata update
280
+ // - Path resolver cache update
281
+ await this.brain.vfs.writeFile(versionedEntity.path, content);
282
+ return targetVersion;
283
+ }
284
+ // For non-VFS entities, use existing brain.update() logic
210
285
  // Extract standard fields vs custom metadata
211
286
  // NounMetadata has: noun, data, createdAt, updatedAt, createdBy, service, confidence, weight
212
287
  const { noun, data, createdAt, updatedAt, createdBy, service, confidence, weight, ...customMetadata } = versionedEntity;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soulcraft/brainy",
3
- "version": "6.3.1",
3
+ "version": "6.3.2",
4
4
  "description": "Universal Knowledge Protocol™ - World's first Triple Intelligence database unifying vector, graph, and document search in one API. Stage 3 CANONICAL: 42 nouns × 127 verbs covering 96-97% of all human knowledge.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",