@evomap/evolver 1.76.0 → 1.78.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.
@@ -0,0 +1,96 @@
1
+ // Portable .gepx archive export (CommonJS).
2
+ // Mirrors @evomap/gep-sdk exportGepx semantics: gzip-tar the local GEP assets
3
+ // (genes / capsules / events / memory graph) plus a manifest and sha256
4
+ // checksums so the archive is self-describing.
5
+ //
6
+ // Kept intentionally minimal (no import path): evolver sync uses this to bundle
7
+ // "everything locally known about this agent" so a user can hand the single
8
+ // file to another machine or keep a point-in-time snapshot.
9
+ const { execFileSync } = require('child_process');
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const crypto = require('crypto');
13
+
14
+ function countJsonlLines(filePath) {
15
+ if (!fs.existsSync(filePath)) return 0;
16
+ return fs.readFileSync(filePath, 'utf8').split('\n').filter((l) => l.trim()).length;
17
+ }
18
+
19
+ function countJsonItems(filePath, key) {
20
+ if (!fs.existsSync(filePath)) return 0;
21
+ try {
22
+ const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
23
+ return Array.isArray(data[key]) ? data[key].length : 0;
24
+ } catch {
25
+ return 0;
26
+ }
27
+ }
28
+
29
+ function exportGepx({ assetsDir, memoryGraphPath, outputPath, agentId, agentName }) {
30
+ if (!assetsDir) throw new Error('exportGepx: assetsDir required');
31
+ if (!outputPath) throw new Error('exportGepx: outputPath required');
32
+
33
+ const outDir = path.dirname(path.resolve(outputPath));
34
+ if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });
35
+
36
+ const tmpDir = `${outputPath}.tmp`;
37
+ if (fs.existsSync(tmpDir)) fs.rmSync(tmpDir, { recursive: true, force: true });
38
+ fs.mkdirSync(path.join(tmpDir, 'genes'), { recursive: true });
39
+ fs.mkdirSync(path.join(tmpDir, 'capsules'), { recursive: true });
40
+ fs.mkdirSync(path.join(tmpDir, 'events'), { recursive: true });
41
+ fs.mkdirSync(path.join(tmpDir, 'memory'), { recursive: true });
42
+
43
+ const filesToCopy = [
44
+ { src: path.join(assetsDir, 'genes.json'), dest: path.join(tmpDir, 'genes', 'genes.json') },
45
+ { src: path.join(assetsDir, 'genes.jsonl'), dest: path.join(tmpDir, 'genes', 'genes.jsonl') },
46
+ { src: path.join(assetsDir, 'capsules.json'), dest: path.join(tmpDir, 'capsules', 'capsules.json') },
47
+ { src: path.join(assetsDir, 'capsules.jsonl'), dest: path.join(tmpDir, 'capsules', 'capsules.jsonl') },
48
+ { src: path.join(assetsDir, 'events.jsonl'), dest: path.join(tmpDir, 'events', 'events.jsonl') },
49
+ ];
50
+ if (memoryGraphPath) {
51
+ filesToCopy.push({ src: memoryGraphPath, dest: path.join(tmpDir, 'memory', 'memory_graph.jsonl') });
52
+ }
53
+
54
+ const checksums = [];
55
+ for (const f of filesToCopy) {
56
+ if (!fs.existsSync(f.src)) continue;
57
+ const content = fs.readFileSync(f.src);
58
+ fs.mkdirSync(path.dirname(f.dest), { recursive: true });
59
+ fs.writeFileSync(f.dest, content);
60
+ const hash = crypto.createHash('sha256').update(content).digest('hex');
61
+ checksums.push(`${hash} ${path.relative(tmpDir, f.dest)}`);
62
+ }
63
+
64
+ const stats = {
65
+ total_events: countJsonlLines(path.join(tmpDir, 'events', 'events.jsonl')),
66
+ total_genes: countJsonItems(path.join(tmpDir, 'genes', 'genes.json'), 'genes'),
67
+ total_capsules: countJsonItems(path.join(tmpDir, 'capsules', 'capsules.json'), 'capsules'),
68
+ memory_graph_entries: memoryGraphPath
69
+ ? countJsonlLines(path.join(tmpDir, 'memory', 'memory_graph.jsonl'))
70
+ : 0,
71
+ };
72
+
73
+ const manifest = {
74
+ gep_version: '1.0.0',
75
+ created_at: new Date().toISOString(),
76
+ agent_id: agentId || null,
77
+ agent_name: agentName || 'unknown',
78
+ statistics: stats,
79
+ source: { platform: 'evolver', component: 'sync' },
80
+ };
81
+
82
+ fs.writeFileSync(path.join(tmpDir, 'manifest.json'), JSON.stringify(manifest, null, 2) + '\n');
83
+ fs.writeFileSync(path.join(tmpDir, 'checksum.sha256'), checksums.join('\n') + '\n');
84
+
85
+ try {
86
+ execFileSync('tar', ['-czf', outputPath, '-C', tmpDir, '.'], { timeout: 60000 });
87
+ } catch (err) {
88
+ fs.rmSync(tmpDir, { recursive: true, force: true });
89
+ throw new Error(`tar failed: ${err.message}. Ensure tar is available on your system.`);
90
+ }
91
+ fs.rmSync(tmpDir, { recursive: true, force: true });
92
+
93
+ return { outputPath, manifest };
94
+ }
95
+
96
+ module.exports = { exportGepx };