fivocell 6.0.2 → 6.1.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 (67) hide show
  1. package/dist/__tests__/archive-versioning.test.d.ts +2 -0
  2. package/dist/__tests__/archive-versioning.test.d.ts.map +1 -0
  3. package/dist/__tests__/archive-versioning.test.js +131 -0
  4. package/dist/__tests__/archive-versioning.test.js.map +1 -0
  5. package/dist/__tests__/blob-vault.test.d.ts +2 -0
  6. package/dist/__tests__/blob-vault.test.d.ts.map +1 -0
  7. package/dist/__tests__/blob-vault.test.js +125 -0
  8. package/dist/__tests__/blob-vault.test.js.map +1 -0
  9. package/dist/__tests__/cell-mirror.test.d.ts +2 -0
  10. package/dist/__tests__/cell-mirror.test.d.ts.map +1 -0
  11. package/dist/__tests__/cell-mirror.test.js +122 -0
  12. package/dist/__tests__/cell-mirror.test.js.map +1 -0
  13. package/dist/__tests__/context-pipeline.test.d.ts +2 -0
  14. package/dist/__tests__/context-pipeline.test.d.ts.map +1 -0
  15. package/dist/__tests__/context-pipeline.test.js +119 -0
  16. package/dist/__tests__/context-pipeline.test.js.map +1 -0
  17. package/dist/__tests__/key-provider.test.d.ts +2 -0
  18. package/dist/__tests__/key-provider.test.d.ts.map +1 -0
  19. package/dist/__tests__/key-provider.test.js +74 -0
  20. package/dist/__tests__/key-provider.test.js.map +1 -0
  21. package/dist/walls/06-memory/archive/archive-versioning.d.ts +33 -0
  22. package/dist/walls/06-memory/archive/archive-versioning.d.ts.map +1 -0
  23. package/dist/walls/06-memory/archive/archive-versioning.js +201 -0
  24. package/dist/walls/06-memory/archive/archive-versioning.js.map +1 -0
  25. package/dist/walls/06-memory/archive/blob-vault.d.ts +47 -0
  26. package/dist/walls/06-memory/archive/blob-vault.d.ts.map +1 -0
  27. package/dist/walls/06-memory/archive/blob-vault.js +272 -0
  28. package/dist/walls/06-memory/archive/blob-vault.js.map +1 -0
  29. package/dist/walls/06-memory/archive/memory-archive.d.ts.map +1 -1
  30. package/dist/walls/06-memory/archive/memory-archive.js +19 -5
  31. package/dist/walls/06-memory/archive/memory-archive.js.map +1 -1
  32. package/dist/walls/06-memory/database/database.d.ts.map +1 -1
  33. package/dist/walls/06-memory/database/database.js +63 -22
  34. package/dist/walls/06-memory/database/database.js.map +1 -1
  35. package/dist/walls/06-memory/mirror/cell-mirror.d.ts +30 -0
  36. package/dist/walls/06-memory/mirror/cell-mirror.d.ts.map +1 -0
  37. package/dist/walls/06-memory/mirror/cell-mirror.js +297 -0
  38. package/dist/walls/06-memory/mirror/cell-mirror.js.map +1 -0
  39. package/dist/walls/06-memory/privacy/key-migration.d.ts +14 -0
  40. package/dist/walls/06-memory/privacy/key-migration.d.ts.map +1 -0
  41. package/dist/walls/06-memory/privacy/key-migration.js +124 -0
  42. package/dist/walls/06-memory/privacy/key-migration.js.map +1 -0
  43. package/dist/walls/06-memory/privacy/key-provider-file.d.ts +9 -0
  44. package/dist/walls/06-memory/privacy/key-provider-file.d.ts.map +1 -0
  45. package/dist/walls/06-memory/privacy/key-provider-file.js +129 -0
  46. package/dist/walls/06-memory/privacy/key-provider-file.js.map +1 -0
  47. package/dist/walls/06-memory/privacy/key-provider-os.d.ts +22 -0
  48. package/dist/walls/06-memory/privacy/key-provider-os.d.ts.map +1 -0
  49. package/dist/walls/06-memory/privacy/key-provider-os.js +201 -0
  50. package/dist/walls/06-memory/privacy/key-provider-os.js.map +1 -0
  51. package/dist/walls/06-memory/privacy/key-provider.d.ts +21 -0
  52. package/dist/walls/06-memory/privacy/key-provider.d.ts.map +1 -0
  53. package/dist/walls/06-memory/privacy/key-provider.js +123 -0
  54. package/dist/walls/06-memory/privacy/key-provider.js.map +1 -0
  55. package/dist/walls/06-memory/retrieval/context-pipeline.d.ts +36 -0
  56. package/dist/walls/06-memory/retrieval/context-pipeline.d.ts.map +1 -0
  57. package/dist/walls/06-memory/retrieval/context-pipeline.js +266 -0
  58. package/dist/walls/06-memory/retrieval/context-pipeline.js.map +1 -0
  59. package/dist/walls/06-memory/stores/memory-search.d.ts.map +1 -1
  60. package/dist/walls/06-memory/stores/memory-search.js +18 -4
  61. package/dist/walls/06-memory/stores/memory-search.js.map +1 -1
  62. package/dist/walls/06-memory/stores/sync-engine.d.ts.map +1 -1
  63. package/dist/walls/06-memory/stores/sync-engine.js +15 -0
  64. package/dist/walls/06-memory/stores/sync-engine.js.map +1 -1
  65. package/dist/walls/07-runtime/cli/cli.js +121 -0
  66. package/dist/walls/07-runtime/cli/cli.js.map +1 -1
  67. package/package.json +1 -1
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const key_provider_1 = require("../walls/06-memory/privacy/key-provider");
4
+ const key_provider_file_1 = require("../walls/06-memory/privacy/key-provider-file");
5
+ const key_migration_1 = require("../walls/06-memory/privacy/key-migration");
6
+ describe('Key Provider', () => {
7
+ it('detectOS returns a valid OS type', () => {
8
+ const os = (0, key_provider_1.detectOS)();
9
+ expect(['windows', 'macos', 'linux', 'unknown']).toContain(os);
10
+ });
11
+ it('deriveMachineKey returns 32-byte buffer', () => {
12
+ const key = (0, key_provider_1.deriveMachineKey)();
13
+ expect(key).toBeInstanceOf(Buffer);
14
+ expect(key.length).toBe(32);
15
+ });
16
+ it('deriveMachineKey is deterministic', () => {
17
+ const key1 = (0, key_provider_1.deriveMachineKey)();
18
+ const key2 = (0, key_provider_1.deriveMachineKey)();
19
+ expect(key1.equals(key2)).toBe(true);
20
+ });
21
+ it('getKeyProviderInfo returns provider info', () => {
22
+ const info = (0, key_provider_1.getKeyProviderInfo)();
23
+ expect(info.os).toBeDefined();
24
+ expect(typeof info.name).toBe('string');
25
+ expect(typeof info.available).toBe('boolean');
26
+ });
27
+ it('FileKeyProvider can set and get keys', () => {
28
+ const provider = new key_provider_file_1.FileKeyProvider();
29
+ if (!provider.isAvailable())
30
+ return;
31
+ const testKey = Buffer.alloc(32, 0xab);
32
+ const testId = 'test-file-provider-' + Date.now();
33
+ const setResult = provider.setKey(testId, testKey);
34
+ expect(setResult).toBe(true);
35
+ const retrieved = provider.getKey(testId);
36
+ expect(retrieved).not.toBeNull();
37
+ expect(retrieved.equals(testKey)).toBe(true);
38
+ // Cleanup
39
+ provider.deleteKey(testId);
40
+ });
41
+ it('FileKeyProvider returns null for missing key', () => {
42
+ const provider = new key_provider_file_1.FileKeyProvider();
43
+ if (!provider.isAvailable())
44
+ return;
45
+ const result = provider.getKey('nonexistent-key-' + Date.now());
46
+ expect(result).toBeNull();
47
+ });
48
+ it('FileKeyProvider delete removes key', () => {
49
+ const provider = new key_provider_file_1.FileKeyProvider();
50
+ if (!provider.isAvailable())
51
+ return;
52
+ const testId = 'test-delete-' + Date.now();
53
+ provider.setKey(testId, Buffer.alloc(32, 0xcc));
54
+ expect(provider.getKey(testId)).not.toBeNull();
55
+ const deleted = provider.deleteKey(testId);
56
+ expect(deleted).toBe(true);
57
+ expect(provider.getKey(testId)).toBeNull();
58
+ });
59
+ });
60
+ describe('Key Migration', () => {
61
+ it('migrateKey returns a result', () => {
62
+ const result = (0, key_migration_1.migrateKey)(process.cwd());
63
+ expect(result).toBeDefined();
64
+ expect(result.provider).toBeDefined();
65
+ expect(result.message).toBeDefined();
66
+ });
67
+ it('getMigrationStatus returns status', () => {
68
+ const status = (0, key_migration_1.getMigrationStatus)();
69
+ expect(typeof status.newProviderHas).toBe('boolean');
70
+ expect(typeof status.oldGlobalExists).toBe('boolean');
71
+ expect(typeof status.needsMigration).toBe('boolean');
72
+ });
73
+ });
74
+ //# sourceMappingURL=key-provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-provider.test.js","sourceRoot":"","sources":["../../src/__tests__/key-provider.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export declare const ARCHIVE_FORMAT_VERSION = 2;
2
+ export interface ArchiveChunkMeta {
3
+ format_version: number;
4
+ compression: 'gzip' | 'zstd';
5
+ encryption: 'aes-256-gcm';
6
+ chunk_type: 'events' | 'sessions' | 'decisions' | 'mixed';
7
+ project: string;
8
+ date: string;
9
+ event_count: number;
10
+ created_at: string;
11
+ checksum?: string;
12
+ }
13
+ export interface ArchiveChunk {
14
+ meta: ArchiveChunkMeta;
15
+ data: Buffer;
16
+ }
17
+ export declare function readArchiveChunkMeta(projectDir: string, chunkType: string, date: Date): ArchiveChunkMeta | null;
18
+ export declare function listArchiveChunks(projectDir: string): Array<{
19
+ path: string;
20
+ meta: ArchiveChunkMeta | null;
21
+ }>;
22
+ export declare function writeArchiveChunk(projectDir: string, project: string, chunkType: string, events: unknown[], _key: Buffer, date?: Date): {
23
+ chunkPath: string;
24
+ metaPath: string;
25
+ };
26
+ export declare function verifyArchiveIntegrity(projectDir: string): {
27
+ totalChunks: number;
28
+ versionedChunks: number;
29
+ unversionedChunks: number;
30
+ totalEvents: number;
31
+ issues: string[];
32
+ };
33
+ //# sourceMappingURL=archive-versioning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive-versioning.d.ts","sourceRoot":"","sources":["../../../../src/walls/06-memory/archive/archive-versioning.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,UAAU,EAAE,aAAa,CAAC;IAC1B,UAAU,EAAE,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAyBD,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,gBAAgB,GAAG,IAAI,CAqB/G;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAAE,CAAC,CAyB5G;AAMD,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EAAE,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,IAAI,GACV;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAiCzC;AAMD,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CA2BA"}
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ARCHIVE_FORMAT_VERSION = void 0;
37
+ exports.readArchiveChunkMeta = readArchiveChunkMeta;
38
+ exports.listArchiveChunks = listArchiveChunks;
39
+ exports.writeArchiveChunk = writeArchiveChunk;
40
+ exports.verifyArchiveIntegrity = verifyArchiveIntegrity;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ // ============================================================
44
+ // archive-versioning.ts — Archive format versioning + metadata
45
+ //
46
+ // Current format: gzip + AES-256-GCM (.jsonl.gz.enc)
47
+ // New format adds: versioned metadata header
48
+ //
49
+ // Archive chunk structure:
50
+ // .cell/memory/archive/YYYY/MM/events-YYYY-MM-DD.jsonl.gz.enc
51
+ // .cell/memory/archive/YYYY/MM/sessions-YYYY-MM-DD.jsonl.gz.enc
52
+ // .cell/memory/archive/YYYY/MM/decisions-YYYY-MM-DD.jsonl.gz.enc
53
+ //
54
+ // Metadata (inside each chunk or as sidecar):
55
+ // format_version: 2
56
+ // compression: 'gzip' | 'zstd'
57
+ // encryption: 'aes-256-gcm'
58
+ // chunk_type: 'events' | 'sessions' | 'decisions'
59
+ // project: string
60
+ // date: string
61
+ // event_count: number
62
+ // ============================================================
63
+ exports.ARCHIVE_FORMAT_VERSION = 2;
64
+ function getArchiveDir(projectDir, date) {
65
+ const d = date || new Date();
66
+ const year = d.getFullYear().toString();
67
+ const month = (d.getMonth() + 1).toString().padStart(2, '0');
68
+ const dir = path.join(projectDir, '.cell', 'memory', 'archive', year, month);
69
+ if (!fs.existsSync(dir))
70
+ fs.mkdirSync(dir, { recursive: true });
71
+ return dir;
72
+ }
73
+ function getChunkFileName(chunkType, date) {
74
+ const dateStr = date.toISOString().slice(0, 10);
75
+ return `${chunkType}-${dateStr}.jsonl.gz.enc`;
76
+ }
77
+ function getChunkMetaFileName(chunkType, date) {
78
+ const dateStr = date.toISOString().slice(0, 10);
79
+ return `${chunkType}-${dateStr}.meta.json`;
80
+ }
81
+ // ============================================================
82
+ // Read — dual format support (v1 and v2)
83
+ // ============================================================
84
+ function readArchiveChunkMeta(projectDir, chunkType, date) {
85
+ const dir = getArchiveDir(projectDir, date);
86
+ const metaPath = path.join(dir, getChunkMetaFileName(chunkType, date));
87
+ if (!fs.existsSync(metaPath))
88
+ return null;
89
+ try {
90
+ const raw = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
91
+ // Backward compatible: if format_version missing, treat as v1
92
+ return {
93
+ format_version: raw.format_version || 1,
94
+ compression: raw.compression || 'gzip',
95
+ encryption: raw.encryption || 'aes-256-gcm',
96
+ chunk_type: raw.chunk_type || chunkType,
97
+ project: raw.project || '',
98
+ date: raw.date || date.toISOString().slice(0, 10),
99
+ event_count: raw.event_count || 0,
100
+ created_at: raw.created_at || new Date().toISOString(),
101
+ checksum: raw.checksum,
102
+ };
103
+ }
104
+ catch {
105
+ return null;
106
+ }
107
+ }
108
+ function listArchiveChunks(projectDir) {
109
+ const archiveRoot = path.join(projectDir, '.cell', 'memory', 'archive');
110
+ if (!fs.existsSync(archiveRoot))
111
+ return [];
112
+ const results = [];
113
+ const walk = (dir) => {
114
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
115
+ const fullPath = path.join(dir, entry.name);
116
+ if (entry.isDirectory()) {
117
+ walk(fullPath);
118
+ }
119
+ else if (entry.name.endsWith('.enc')) {
120
+ const baseName = entry.name.slice(0, -4); // remove .enc
121
+ const metaPath = path.join(dir, `${baseName}.meta.json`);
122
+ let meta = null;
123
+ if (fs.existsSync(metaPath)) {
124
+ try {
125
+ meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
126
+ }
127
+ catch { /* ignore */ }
128
+ }
129
+ results.push({ path: fullPath, meta });
130
+ }
131
+ }
132
+ };
133
+ try {
134
+ walk(archiveRoot);
135
+ }
136
+ catch { /* ignore */ }
137
+ return results;
138
+ }
139
+ // ============================================================
140
+ // Write — create chunk with metadata sidecar
141
+ // ============================================================
142
+ function writeArchiveChunk(projectDir, project, chunkType, events, _key, date) {
143
+ const d = date || new Date();
144
+ const dir = getArchiveDir(projectDir, d);
145
+ const chunkFileName = getChunkFileName(chunkType, d);
146
+ const metaFileName = getChunkMetaFileName(chunkType, d);
147
+ const chunkPath = path.join(dir, chunkFileName);
148
+ const metaPath = path.join(dir, metaFileName);
149
+ // Create metadata
150
+ const meta = {
151
+ format_version: exports.ARCHIVE_FORMAT_VERSION,
152
+ compression: 'gzip',
153
+ encryption: 'aes-256-gcm',
154
+ chunk_type: chunkType,
155
+ project,
156
+ date: d.toISOString().slice(0, 10),
157
+ event_count: events.length,
158
+ created_at: new Date().toISOString(),
159
+ };
160
+ // Write metadata sidecar
161
+ fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
162
+ // Write chunk placeholder (actual encryption done by memory-archive.ts)
163
+ // This module only handles versioning and metadata
164
+ if (!fs.existsSync(chunkPath) && events.length > 0) {
165
+ const lineData = events.map(e => JSON.stringify(e)).join('\n');
166
+ const compressed = require('zlib').gzipSync(Buffer.from(lineData, 'utf-8'));
167
+ fs.writeFileSync(chunkPath, compressed);
168
+ }
169
+ return { chunkPath, metaPath };
170
+ }
171
+ // ============================================================
172
+ // Integrity check
173
+ // ============================================================
174
+ function verifyArchiveIntegrity(projectDir) {
175
+ const chunks = listArchiveChunks(projectDir);
176
+ const issues = [];
177
+ let versioned = 0;
178
+ let unversioned = 0;
179
+ let totalEvents = 0;
180
+ for (const chunk of chunks) {
181
+ if (chunk.meta) {
182
+ versioned++;
183
+ totalEvents += chunk.meta.event_count;
184
+ if (chunk.meta.format_version < exports.ARCHIVE_FORMAT_VERSION) {
185
+ issues.push(`Old format v${chunk.meta.format_version}: ${chunk.path}`);
186
+ }
187
+ }
188
+ else {
189
+ unversioned++;
190
+ issues.push(`No metadata: ${chunk.path}`);
191
+ }
192
+ }
193
+ return {
194
+ totalChunks: chunks.length,
195
+ versionedChunks: versioned,
196
+ unversionedChunks: unversioned,
197
+ totalEvents,
198
+ issues,
199
+ };
200
+ }
201
+ //# sourceMappingURL=archive-versioning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive-versioning.js","sourceRoot":"","sources":["../../../../src/walls/06-memory/archive/archive-versioning.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ export interface BlobMeta {
2
+ hash: string;
3
+ original_size: number;
4
+ compressed_size: number;
5
+ encrypted_size: number;
6
+ content_type: string;
7
+ created_at: string;
8
+ ref_count: number;
9
+ }
10
+ export interface BlobStats {
11
+ totalBlobs: number;
12
+ totalOriginalBytes: number;
13
+ totalEncryptedBytes: number;
14
+ dedupSavingsPercent: number;
15
+ avgRefCount: number;
16
+ contentTypes: Record<string, number>;
17
+ }
18
+ /**
19
+ * Write content to blob vault (dedup by hash)
20
+ * Returns hash if written, null if error
21
+ */
22
+ export declare function writeBlob(projectDir: string, content: Buffer, contentType?: string): string | null;
23
+ /**
24
+ * Read content from blob vault by hash
25
+ */
26
+ export declare function readBlob(projectDir: string, hash: string): Buffer | null;
27
+ /**
28
+ * Check if blob exists
29
+ */
30
+ export declare function blobExists(projectDir: string, hash: string): boolean;
31
+ /**
32
+ * Get blob metadata
33
+ */
34
+ export declare function getBlobMeta(projectDir: string, hash: string): BlobMeta | null;
35
+ /**
36
+ * Delete blob (only if ref_count <= 1)
37
+ */
38
+ export declare function deleteBlob(projectDir: string, hash: string): boolean;
39
+ /**
40
+ * Get vault statistics
41
+ */
42
+ export declare function getBlobStats(projectDir: string): BlobStats;
43
+ /**
44
+ * List all blobs
45
+ */
46
+ export declare function listBlobs(projectDir: string): BlobMeta[];
47
+ //# sourceMappingURL=blob-vault.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob-vault.d.ts","sourceRoot":"","sources":["../../../../src/walls/06-memory/archive/blob-vault.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAwDD;;;GAGG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,MAAgB,GAC5B,MAAM,GAAG,IAAI,CA0Cf;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUxE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAI7E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAapE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CA2C1D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,EAAE,CAYxD"}
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.writeBlob = writeBlob;
37
+ exports.readBlob = readBlob;
38
+ exports.blobExists = blobExists;
39
+ exports.getBlobMeta = getBlobMeta;
40
+ exports.deleteBlob = deleteBlob;
41
+ exports.getBlobStats = getBlobStats;
42
+ exports.listBlobs = listBlobs;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const crypto = __importStar(require("crypto"));
46
+ const zlib = __importStar(require("zlib"));
47
+ // ============================================================
48
+ // blob-vault.ts — Content-addressed dedup storage
49
+ //
50
+ // Stores large content as SHA-256 hashed blobs
51
+ // Same content → 1 blob, N references
52
+ //
53
+ // Structure:
54
+ // .cell/memory/blobs/sha256-xxxx.enc
55
+ // .cell/memory/blobs/sha256-xxxx.meta.json
56
+ //
57
+ // Format: gzip compress → AES-256-GCM encrypt
58
+ // ============================================================
59
+ const ALGORITHM = 'aes-256-gcm';
60
+ const IV_LENGTH = 16;
61
+ const TAG_LENGTH = 16;
62
+ const KEY_LENGTH = 32;
63
+ // ============================================================
64
+ // Internal helpers
65
+ // ============================================================
66
+ function getBlobsDir(projectDir) {
67
+ const dir = path.join(projectDir, '.cell', 'memory', 'blobs');
68
+ if (!fs.existsSync(dir))
69
+ fs.mkdirSync(dir, { recursive: true });
70
+ return dir;
71
+ }
72
+ function getBlobPath(projectDir, hash) {
73
+ return path.join(getBlobsDir(projectDir), `sha256-${hash}.enc`);
74
+ }
75
+ function getMetaPath(projectDir, hash) {
76
+ return path.join(getBlobsDir(projectDir), `sha256-${hash}.meta.json`);
77
+ }
78
+ function deriveKey() {
79
+ // Machine-bound key for blob encryption
80
+ const hostname = require('os').hostname();
81
+ const username = require('os').userInfo().username;
82
+ return crypto.scryptSync(`${hostname}:${username}:fivocell-blob-vault`, 'fivocell-blob-key', KEY_LENGTH);
83
+ }
84
+ function encrypt(data, key) {
85
+ const iv = crypto.randomBytes(IV_LENGTH);
86
+ const cipher = crypto.createCipheriv(ALGORITHM, key, iv, { authTagLength: TAG_LENGTH });
87
+ const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
88
+ const authTag = cipher.getAuthTag();
89
+ return Buffer.concat([iv, authTag, encrypted]);
90
+ }
91
+ function decrypt(data, key) {
92
+ const iv = data.subarray(0, IV_LENGTH);
93
+ const authTag = data.subarray(IV_LENGTH, IV_LENGTH + TAG_LENGTH);
94
+ const encrypted = data.subarray(IV_LENGTH + TAG_LENGTH);
95
+ const decipher = crypto.createDecipheriv(ALGORITHM, key, iv, { authTagLength: TAG_LENGTH });
96
+ decipher.setAuthTag(authTag);
97
+ return Buffer.concat([decipher.update(encrypted), decipher.final()]);
98
+ }
99
+ function computeHash(data) {
100
+ return crypto.createHash('sha256').update(data).digest('hex');
101
+ }
102
+ // ============================================================
103
+ // Public API
104
+ // ============================================================
105
+ /**
106
+ * Write content to blob vault (dedup by hash)
107
+ * Returns hash if written, null if error
108
+ */
109
+ function writeBlob(projectDir, content, contentType = 'event') {
110
+ try {
111
+ const hash = computeHash(content);
112
+ // Dedup: check if blob already exists
113
+ if (blobExists(projectDir, hash)) {
114
+ // Increment ref_count
115
+ const metaPath = getMetaPath(projectDir, hash);
116
+ if (fs.existsSync(metaPath)) {
117
+ try {
118
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
119
+ meta.ref_count++;
120
+ fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
121
+ }
122
+ catch { /* non-critical */ }
123
+ }
124
+ return hash;
125
+ }
126
+ // Compress
127
+ const compressed = zlib.gzipSync(content, { level: 6 });
128
+ // Encrypt
129
+ const key = deriveKey();
130
+ const encrypted = encrypt(compressed, key);
131
+ // Write encrypted blob
132
+ fs.writeFileSync(getBlobPath(projectDir, hash), encrypted);
133
+ // Write metadata sidecar
134
+ const meta = {
135
+ hash,
136
+ original_size: content.length,
137
+ compressed_size: compressed.length,
138
+ encrypted_size: encrypted.length,
139
+ content_type: contentType,
140
+ created_at: new Date().toISOString(),
141
+ ref_count: 1,
142
+ };
143
+ fs.writeFileSync(getMetaPath(projectDir, hash), JSON.stringify(meta, null, 2));
144
+ return hash;
145
+ }
146
+ catch {
147
+ return null;
148
+ }
149
+ }
150
+ /**
151
+ * Read content from blob vault by hash
152
+ */
153
+ function readBlob(projectDir, hash) {
154
+ const blobPath = getBlobPath(projectDir, hash);
155
+ if (!fs.existsSync(blobPath))
156
+ return null;
157
+ try {
158
+ const encrypted = fs.readFileSync(blobPath);
159
+ const key = deriveKey();
160
+ const compressed = decrypt(encrypted, key);
161
+ return zlib.gunzipSync(compressed);
162
+ }
163
+ catch {
164
+ return null;
165
+ }
166
+ }
167
+ /**
168
+ * Check if blob exists
169
+ */
170
+ function blobExists(projectDir, hash) {
171
+ return fs.existsSync(getBlobPath(projectDir, hash));
172
+ }
173
+ /**
174
+ * Get blob metadata
175
+ */
176
+ function getBlobMeta(projectDir, hash) {
177
+ const metaPath = getMetaPath(projectDir, hash);
178
+ if (!fs.existsSync(metaPath))
179
+ return null;
180
+ try {
181
+ return JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
182
+ }
183
+ catch {
184
+ return null;
185
+ }
186
+ }
187
+ /**
188
+ * Delete blob (only if ref_count <= 1)
189
+ */
190
+ function deleteBlob(projectDir, hash) {
191
+ const meta = getBlobMeta(projectDir, hash);
192
+ if (!meta)
193
+ return false;
194
+ if (meta.ref_count > 1) {
195
+ meta.ref_count--;
196
+ fs.writeFileSync(getMetaPath(projectDir, hash), JSON.stringify(meta, null, 2));
197
+ return true;
198
+ }
199
+ try {
200
+ fs.unlinkSync(getBlobPath(projectDir, hash));
201
+ fs.unlinkSync(getMetaPath(projectDir, hash));
202
+ return true;
203
+ }
204
+ catch {
205
+ return false;
206
+ }
207
+ }
208
+ /**
209
+ * Get vault statistics
210
+ */
211
+ function getBlobStats(projectDir) {
212
+ const blobsDir = path.join(projectDir, '.cell', 'memory', 'blobs');
213
+ if (!fs.existsSync(blobsDir)) {
214
+ return {
215
+ totalBlobs: 0,
216
+ totalOriginalBytes: 0,
217
+ totalEncryptedBytes: 0,
218
+ dedupSavingsPercent: 0,
219
+ avgRefCount: 0,
220
+ contentTypes: {},
221
+ };
222
+ }
223
+ let totalBlobs = 0;
224
+ let totalOriginal = 0;
225
+ let totalEncrypted = 0;
226
+ let totalRefCount = 0;
227
+ const contentTypes = {};
228
+ for (const file of fs.readdirSync(blobsDir)) {
229
+ if (!file.endsWith('.meta.json'))
230
+ continue;
231
+ try {
232
+ const meta = JSON.parse(fs.readFileSync(path.join(blobsDir, file), 'utf-8'));
233
+ totalBlobs++;
234
+ totalOriginal += meta.original_size;
235
+ totalEncrypted += meta.encrypted_size;
236
+ totalRefCount += meta.ref_count;
237
+ contentTypes[meta.content_type] = (contentTypes[meta.content_type] || 0) + 1;
238
+ }
239
+ catch { /* skip corrupt */ }
240
+ }
241
+ return {
242
+ totalBlobs,
243
+ totalOriginalBytes: totalOriginal,
244
+ totalEncryptedBytes: totalEncrypted,
245
+ dedupSavingsPercent: totalOriginal > 0
246
+ ? Math.round((1 - totalEncrypted / totalOriginal) * 100)
247
+ : 0,
248
+ avgRefCount: totalBlobs > 0
249
+ ? Math.round(totalRefCount / totalBlobs * 10) / 10
250
+ : 0,
251
+ contentTypes,
252
+ };
253
+ }
254
+ /**
255
+ * List all blobs
256
+ */
257
+ function listBlobs(projectDir) {
258
+ const blobsDir = path.join(projectDir, '.cell', 'memory', 'blobs');
259
+ if (!fs.existsSync(blobsDir))
260
+ return [];
261
+ const results = [];
262
+ for (const file of fs.readdirSync(blobsDir)) {
263
+ if (!file.endsWith('.meta.json'))
264
+ continue;
265
+ try {
266
+ results.push(JSON.parse(fs.readFileSync(path.join(blobsDir, file), 'utf-8')));
267
+ }
268
+ catch { /* skip */ }
269
+ }
270
+ return results;
271
+ }
272
+ //# sourceMappingURL=blob-vault.js.map