@sashabogi/foundation 2.1.0 → 2.3.1
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/dist/cli.js +236 -2
- package/dist/cli.js.map +1 -1
- package/dist/tools/demerzel/engine.d.ts +3 -2
- package/dist/tools/demerzel/engine.d.ts.map +1 -1
- package/dist/tools/demerzel/engine.js +7 -7
- package/dist/tools/demerzel/engine.js.map +1 -1
- package/dist/tools/demerzel/enhanced-snapshot.d.ts +10 -2
- package/dist/tools/demerzel/enhanced-snapshot.d.ts.map +1 -1
- package/dist/tools/demerzel/enhanced-snapshot.js +156 -77
- package/dist/tools/demerzel/enhanced-snapshot.js.map +1 -1
- package/dist/tools/demerzel/index.d.ts +1 -1
- package/dist/tools/demerzel/index.d.ts.map +1 -1
- package/dist/tools/demerzel/index.js +53 -36
- package/dist/tools/demerzel/index.js.map +1 -1
- package/dist/tools/demerzel/semantic-search.d.ts +2 -2
- package/dist/tools/demerzel/semantic-search.d.ts.map +1 -1
- package/dist/tools/demerzel/semantic-search.js +4 -3
- package/dist/tools/demerzel/semantic-search.js.map +1 -1
- package/dist/tools/demerzel/snapshot.d.ts +34 -1
- package/dist/tools/demerzel/snapshot.d.ts.map +1 -1
- package/dist/tools/demerzel/snapshot.js +70 -34
- package/dist/tools/demerzel/snapshot.js.map +1 -1
- package/dist/tools/demerzel/zstd-io.d.ts +40 -0
- package/dist/tools/demerzel/zstd-io.d.ts.map +1 -0
- package/dist/tools/demerzel/zstd-io.js +69 -0
- package/dist/tools/demerzel/zstd-io.js.map +1 -0
- package/dist/tools/gaia/index.d.ts +5 -4
- package/dist/tools/gaia/index.d.ts.map +1 -1
- package/dist/tools/gaia/index.js +155 -8
- package/dist/tools/gaia/index.js.map +1 -1
- package/dist/tools/gaia/storage.d.ts +31 -2
- package/dist/tools/gaia/storage.d.ts.map +1 -1
- package/dist/tools/gaia/storage.js +110 -6
- package/dist/tools/gaia/storage.js.map +1 -1
- package/dist/tools/gaia/transcript-ingester.d.ts +81 -0
- package/dist/tools/gaia/transcript-ingester.d.ts.map +1 -0
- package/dist/tools/gaia/transcript-ingester.js +418 -0
- package/dist/tools/gaia/transcript-ingester.js.map +1 -0
- package/dist/vault/dashboard.d.ts +10 -0
- package/dist/vault/dashboard.d.ts.map +1 -0
- package/dist/vault/dashboard.js +145 -0
- package/dist/vault/dashboard.js.map +1 -0
- package/dist/vault/sync.d.ts +64 -0
- package/dist/vault/sync.d.ts.map +1 -0
- package/dist/vault/sync.js +372 -0
- package/dist/vault/sync.js.map +1 -0
- package/dist/vault/transform.d.ts +25 -0
- package/dist/vault/transform.d.ts.map +1 -0
- package/dist/vault/transform.js +155 -0
- package/dist/vault/transform.js.map +1 -0
- package/package.json +2 -1
- package/packages/ui/dist/assets/index-BCBAHIpG.css +1 -0
- package/packages/ui/dist/assets/index-CxRK0aqp.js +387 -0
- package/packages/ui/dist/index.html +2 -2
- package/docs/foundation +0 -0
- package/packages/ui/dist/assets/index-DVS_pYGH.css +0 -1
- package/packages/ui/dist/assets/index-WNO_oIqP.js +0 -312
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vault Sync Engine
|
|
3
|
+
*
|
|
4
|
+
* Syncs Gaia memories from SQLite to an Obsidian vault as interlinked
|
|
5
|
+
* markdown files. Supports full and incremental sync, Claude Code memory
|
|
6
|
+
* file ingestion, and orphan cleanup.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, unlinkSync, statSync, } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import { createHash } from 'crypto';
|
|
11
|
+
import { parse as parseYaml } from 'yaml';
|
|
12
|
+
import { MemoriaStorage } from '../tools/gaia/storage.js';
|
|
13
|
+
import { transformMemory, memoryToFilename, memoryToFolderPath, } from './transform.js';
|
|
14
|
+
import { generateDashboard } from './dashboard.js';
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Folder Scaffold
|
|
17
|
+
// =============================================================================
|
|
18
|
+
const VAULT_FOLDERS = [
|
|
19
|
+
'Foundation',
|
|
20
|
+
'Foundation/Global',
|
|
21
|
+
'Foundation/Projects',
|
|
22
|
+
'Foundation/Sessions',
|
|
23
|
+
'Foundation/Notes',
|
|
24
|
+
'Foundation/Observations',
|
|
25
|
+
'Knowledge',
|
|
26
|
+
];
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// VaultSync
|
|
29
|
+
// =============================================================================
|
|
30
|
+
export class VaultSync {
|
|
31
|
+
config;
|
|
32
|
+
constructor(config) {
|
|
33
|
+
this.config = config;
|
|
34
|
+
}
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Public API
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
/**
|
|
39
|
+
* Create the required folder structure in the vault and write an initial
|
|
40
|
+
* dashboard index file.
|
|
41
|
+
*/
|
|
42
|
+
async init() {
|
|
43
|
+
for (const folder of VAULT_FOLDERS) {
|
|
44
|
+
const fullPath = join(this.config.vaultPath, folder);
|
|
45
|
+
if (!existsSync(fullPath)) {
|
|
46
|
+
mkdirSync(fullPath, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const dashboardPath = join(this.config.vaultPath, 'Foundation', '_dashboard.md');
|
|
50
|
+
if (!existsSync(dashboardPath)) {
|
|
51
|
+
writeFileSync(dashboardPath, generateDashboard(), 'utf8');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Full sync: reads ALL memories from Gaia DB, transforms and writes every
|
|
56
|
+
* file, updates sync state. Also syncs Claude Code memory files if
|
|
57
|
+
* claudeMemoryPath is configured.
|
|
58
|
+
*/
|
|
59
|
+
async sync() {
|
|
60
|
+
await this.init();
|
|
61
|
+
const gaiaResult = await this.syncGaiaMemories(false);
|
|
62
|
+
let claudeResult = { created: 0, updated: 0, deleted: 0, skipped: 0, errors: [] };
|
|
63
|
+
if (this.config.claudeMemoryPath) {
|
|
64
|
+
claudeResult = await this.syncClaudeMemories();
|
|
65
|
+
}
|
|
66
|
+
return mergeResults(gaiaResult, claudeResult);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Incremental sync: only writes memories whose rendered content has changed
|
|
70
|
+
* since the last sync (detected via MD5 hash comparison).
|
|
71
|
+
*/
|
|
72
|
+
async syncIncremental() {
|
|
73
|
+
await this.init();
|
|
74
|
+
const gaiaResult = await this.syncGaiaMemories(true);
|
|
75
|
+
let claudeResult = { created: 0, updated: 0, deleted: 0, skipped: 0, errors: [] };
|
|
76
|
+
if (this.config.claudeMemoryPath) {
|
|
77
|
+
claudeResult = await this.syncClaudeMemories();
|
|
78
|
+
}
|
|
79
|
+
return mergeResults(gaiaResult, claudeResult);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns the current sync state, or null if no sync has run yet.
|
|
83
|
+
*/
|
|
84
|
+
getStatus() {
|
|
85
|
+
if (!existsSync(this.config.syncStatePath))
|
|
86
|
+
return null;
|
|
87
|
+
try {
|
|
88
|
+
return JSON.parse(readFileSync(this.config.syncStatePath, 'utf8'));
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Private: State Management
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
loadSyncState() {
|
|
98
|
+
const existing = this.getStatus();
|
|
99
|
+
if (existing)
|
|
100
|
+
return existing;
|
|
101
|
+
return {
|
|
102
|
+
vault_path: this.config.vaultPath,
|
|
103
|
+
last_full_sync: new Date(0).toISOString(),
|
|
104
|
+
synced_memories: {},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
saveSyncState(state) {
|
|
108
|
+
const dir = join(this.config.syncStatePath, '..');
|
|
109
|
+
// syncStatePath may point to a file whose parent dir doesn't exist yet
|
|
110
|
+
if (!existsSync(dir)) {
|
|
111
|
+
mkdirSync(dir, { recursive: true });
|
|
112
|
+
}
|
|
113
|
+
writeFileSync(this.config.syncStatePath, JSON.stringify(state, null, 2), 'utf8');
|
|
114
|
+
}
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// Private: Hashing
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
hashContent(content) {
|
|
119
|
+
return createHash('md5').update(content).digest('hex');
|
|
120
|
+
}
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
// Private: Gaia Sync
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
async syncGaiaMemories(incremental) {
|
|
125
|
+
const result = { created: 0, updated: 0, deleted: 0, skipped: 0, errors: [] };
|
|
126
|
+
const state = this.loadSyncState();
|
|
127
|
+
let storage = null;
|
|
128
|
+
try {
|
|
129
|
+
storage = new MemoriaStorage(this.config.gaiaDbPath);
|
|
130
|
+
const memories = storage.getAllMemories();
|
|
131
|
+
const links = storage.getAllLinks();
|
|
132
|
+
// Build lookup maps
|
|
133
|
+
const memoryMap = new Map(memories.map(m => [m.id, m]));
|
|
134
|
+
const linksBySource = new Map();
|
|
135
|
+
for (const link of links) {
|
|
136
|
+
const bucket = linksBySource.get(link.from_memory_id) ?? [];
|
|
137
|
+
bucket.push(link);
|
|
138
|
+
linksBySource.set(link.from_memory_id, bucket);
|
|
139
|
+
}
|
|
140
|
+
const currentIds = new Set();
|
|
141
|
+
for (const memory of memories) {
|
|
142
|
+
currentIds.add(memory.id);
|
|
143
|
+
try {
|
|
144
|
+
const memLinks = linksBySource.get(memory.id) ?? [];
|
|
145
|
+
const markdown = transformMemory(memory, memLinks, memoryMap);
|
|
146
|
+
const hash = this.hashContent(markdown);
|
|
147
|
+
// In incremental mode, skip if content unchanged
|
|
148
|
+
if (incremental && state.synced_memories[memory.id] === hash) {
|
|
149
|
+
result.skipped++;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const folderPath = memoryToFolderPath(memory, this.config.vaultPath);
|
|
153
|
+
const filename = memoryToFilename(memory);
|
|
154
|
+
const filePath = join(folderPath, filename);
|
|
155
|
+
if (!existsSync(folderPath)) {
|
|
156
|
+
mkdirSync(folderPath, { recursive: true });
|
|
157
|
+
}
|
|
158
|
+
const isNew = !state.synced_memories[memory.id];
|
|
159
|
+
writeFileSync(filePath, markdown, 'utf8');
|
|
160
|
+
state.synced_memories[memory.id] = hash;
|
|
161
|
+
if (isNew) {
|
|
162
|
+
result.created++;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
result.updated++;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
170
|
+
result.errors.push(`[${memory.id}] ${msg}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Clean up orphaned vault files for deleted memories
|
|
174
|
+
result.deleted = this.cleanOrphans(currentIds, state);
|
|
175
|
+
// Prune deleted memory ids from state
|
|
176
|
+
for (const id of Object.keys(state.synced_memories)) {
|
|
177
|
+
if (!currentIds.has(id)) {
|
|
178
|
+
delete state.synced_memories[id];
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
state.last_full_sync = new Date().toISOString();
|
|
182
|
+
this.saveSyncState(state);
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
186
|
+
result.errors.push(`[fatal] ${msg}`);
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
storage?.close();
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
// Private: Claude Code Memory Sync
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
async syncClaudeMemories() {
|
|
197
|
+
const result = { created: 0, updated: 0, deleted: 0, skipped: 0, errors: [] };
|
|
198
|
+
const claudeMemoryPath = this.config.claudeMemoryPath;
|
|
199
|
+
if (!claudeMemoryPath || !existsSync(claudeMemoryPath)) {
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
let files;
|
|
203
|
+
try {
|
|
204
|
+
files = readdirSync(claudeMemoryPath).filter(f => f.endsWith('.md'));
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
208
|
+
result.errors.push(`[claude-memory] Failed to read directory: ${msg}`);
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
for (const filename of files) {
|
|
212
|
+
try {
|
|
213
|
+
const sourcePath = join(claudeMemoryPath, filename);
|
|
214
|
+
const rawContent = readFileSync(sourcePath, 'utf8');
|
|
215
|
+
// Parse YAML frontmatter to extract type for folder routing
|
|
216
|
+
const { frontmatter, body } = extractFrontmatter(rawContent);
|
|
217
|
+
let type = 'general';
|
|
218
|
+
if (frontmatter) {
|
|
219
|
+
try {
|
|
220
|
+
const parsed = parseYaml(frontmatter);
|
|
221
|
+
if (typeof parsed['type'] === 'string') {
|
|
222
|
+
type = parsed['type'];
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
// Unparseable frontmatter — fall back to default type
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Build enhanced markdown with source field injected into frontmatter
|
|
230
|
+
const enhanced = injectFrontmatterField(rawContent, 'source', 'claude-code');
|
|
231
|
+
const targetDir = join(this.config.vaultPath, 'Knowledge', type);
|
|
232
|
+
if (!existsSync(targetDir)) {
|
|
233
|
+
mkdirSync(targetDir, { recursive: true });
|
|
234
|
+
}
|
|
235
|
+
const targetPath = join(targetDir, filename);
|
|
236
|
+
const existed = existsSync(targetPath);
|
|
237
|
+
writeFileSync(targetPath, enhanced, 'utf8');
|
|
238
|
+
if (existed) {
|
|
239
|
+
result.updated++;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
result.created++;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
247
|
+
result.errors.push(`[claude-memory/${filename}] ${msg}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return result;
|
|
251
|
+
}
|
|
252
|
+
// ---------------------------------------------------------------------------
|
|
253
|
+
// Private: Orphan Cleanup
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
/**
|
|
256
|
+
* Walk Foundation/ in the vault and remove .md files whose memory id is no
|
|
257
|
+
* longer in currentIds. Returns the number of files deleted.
|
|
258
|
+
*/
|
|
259
|
+
cleanOrphans(currentIds, state) {
|
|
260
|
+
let deleted = 0;
|
|
261
|
+
const foundationRoot = join(this.config.vaultPath, 'Foundation');
|
|
262
|
+
if (!existsSync(foundationRoot))
|
|
263
|
+
return 0;
|
|
264
|
+
const walkAndClean = (dir) => {
|
|
265
|
+
let entries;
|
|
266
|
+
try {
|
|
267
|
+
entries = readdirSync(dir);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
for (const entry of entries) {
|
|
273
|
+
const fullPath = join(dir, entry);
|
|
274
|
+
let isDir = false;
|
|
275
|
+
try {
|
|
276
|
+
isDir = statSync(fullPath).isDirectory();
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
if (isDir) {
|
|
282
|
+
walkAndClean(fullPath);
|
|
283
|
+
}
|
|
284
|
+
else if (entry.endsWith('.md')) {
|
|
285
|
+
// Recover the memory id from the filename.
|
|
286
|
+
//
|
|
287
|
+
// Filename format: ${memory.id}-${slug}.md where memory.id = mem_${nanoid()}.
|
|
288
|
+
// Because nanoid produces hyphens, both the id and the id-to-slug separator
|
|
289
|
+
// use '-', making regex-based extraction ambiguous. Instead, we consult
|
|
290
|
+
// state.synced_memories — the authoritative record of every id vault-sync
|
|
291
|
+
// has ever written — and check whether any of those ids is a prefix of
|
|
292
|
+
// this filename's stem. This is unambiguous and never deletes user files
|
|
293
|
+
// that vault-sync did not create.
|
|
294
|
+
const stem = entry.slice(0, -3); // strip .md
|
|
295
|
+
let matchedId = null;
|
|
296
|
+
for (const id of Object.keys(state.synced_memories)) {
|
|
297
|
+
if (stem === id || stem.startsWith(id + '-')) {
|
|
298
|
+
matchedId = id;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (matchedId && !currentIds.has(matchedId)) {
|
|
303
|
+
try {
|
|
304
|
+
unlinkSync(fullPath);
|
|
305
|
+
deleted++;
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
// File may have already been removed — ignore
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
walkAndClean(foundationRoot);
|
|
315
|
+
return deleted;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
// =============================================================================
|
|
319
|
+
// Utility Functions
|
|
320
|
+
// =============================================================================
|
|
321
|
+
function mergeResults(a, b) {
|
|
322
|
+
return {
|
|
323
|
+
created: a.created + b.created,
|
|
324
|
+
updated: a.updated + b.updated,
|
|
325
|
+
deleted: a.deleted + b.deleted,
|
|
326
|
+
skipped: a.skipped + b.skipped,
|
|
327
|
+
errors: [...a.errors, ...b.errors],
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Split a markdown file into its YAML frontmatter block and body.
|
|
332
|
+
* Returns { frontmatter: string | null, body: string }.
|
|
333
|
+
*/
|
|
334
|
+
function extractFrontmatter(content) {
|
|
335
|
+
if (!content.startsWith('---')) {
|
|
336
|
+
return { frontmatter: null, body: content };
|
|
337
|
+
}
|
|
338
|
+
const end = content.indexOf('\n---', 3);
|
|
339
|
+
if (end === -1) {
|
|
340
|
+
return { frontmatter: null, body: content };
|
|
341
|
+
}
|
|
342
|
+
const frontmatter = content.slice(4, end).trim();
|
|
343
|
+
const body = content.slice(end + 4).trimStart();
|
|
344
|
+
return { frontmatter, body };
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Inject a key: value pair into a markdown file's YAML frontmatter.
|
|
348
|
+
* If no frontmatter exists, one is created. If the key already exists,
|
|
349
|
+
* it is left unchanged.
|
|
350
|
+
*/
|
|
351
|
+
function injectFrontmatterField(content, key, value) {
|
|
352
|
+
if (!content.startsWith('---')) {
|
|
353
|
+
// No frontmatter — prepend one
|
|
354
|
+
return `---\n${key}: ${value}\n---\n\n${content}`;
|
|
355
|
+
}
|
|
356
|
+
const end = content.indexOf('\n---', 3);
|
|
357
|
+
if (end === -1) {
|
|
358
|
+
return `---\n${key}: ${value}\n---\n\n${content}`;
|
|
359
|
+
}
|
|
360
|
+
const frontmatterBlock = content.slice(0, end + 4);
|
|
361
|
+
const rest = content.slice(end + 4);
|
|
362
|
+
// Only inject if key is absent
|
|
363
|
+
if (new RegExp(`^${key}:`, 'm').test(frontmatterBlock)) {
|
|
364
|
+
return content;
|
|
365
|
+
}
|
|
366
|
+
// Insert before closing ---
|
|
367
|
+
const insertionPoint = end;
|
|
368
|
+
return (content.slice(0, insertionPoint) +
|
|
369
|
+
`\n${key}: ${value}` +
|
|
370
|
+
content.slice(insertionPoint));
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/vault/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vault Transform Layer
|
|
3
|
+
*
|
|
4
|
+
* Converts Gaia Memory objects into Obsidian-compatible markdown files
|
|
5
|
+
* with YAML frontmatter and [[wikilink]] cross-references.
|
|
6
|
+
*/
|
|
7
|
+
import type { Memory, MemoryLink } from '../tools/gaia/storage.js';
|
|
8
|
+
/**
|
|
9
|
+
* Returns a filesystem-safe filename for a memory.
|
|
10
|
+
* Format: `<id>-<slug>.md`
|
|
11
|
+
*/
|
|
12
|
+
export declare function memoryToFilename(memory: Memory): string;
|
|
13
|
+
/**
|
|
14
|
+
* Returns the target folder path in the vault for a given memory, based on tier.
|
|
15
|
+
*/
|
|
16
|
+
export declare function memoryToFolderPath(memory: Memory, vaultRoot: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Transforms a Memory and its links into a full Obsidian markdown string.
|
|
19
|
+
*
|
|
20
|
+
* @param memory The memory to transform
|
|
21
|
+
* @param links All MemoryLink rows where from_memory_id === memory.id
|
|
22
|
+
* @param allMemories Map of id → Memory for resolving link targets
|
|
23
|
+
*/
|
|
24
|
+
export declare function transformMemory(memory: Memory, links: MemoryLink[], allMemories: Map<string, Memory>): string;
|
|
25
|
+
//# sourceMappingURL=transform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/vault/transform.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAiDnE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAyB5E;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,EAAE,EACnB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,MAAM,CA4ER"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vault Transform Layer
|
|
3
|
+
*
|
|
4
|
+
* Converts Gaia Memory objects into Obsidian-compatible markdown files
|
|
5
|
+
* with YAML frontmatter and [[wikilink]] cross-references.
|
|
6
|
+
*/
|
|
7
|
+
import { format } from 'date-fns';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Internal Helpers
|
|
11
|
+
// =============================================================================
|
|
12
|
+
function slugify(text) {
|
|
13
|
+
return text
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.replace(/[^a-z0-9\s-]/g, '')
|
|
16
|
+
.trim()
|
|
17
|
+
.replace(/\s+/g, '-')
|
|
18
|
+
.replace(/-+/g, '-')
|
|
19
|
+
.slice(0, 40)
|
|
20
|
+
.replace(/-$/, '');
|
|
21
|
+
}
|
|
22
|
+
function unixMsToIso(ms) {
|
|
23
|
+
return new Date(ms).toISOString();
|
|
24
|
+
}
|
|
25
|
+
function extractFirstLine(content) {
|
|
26
|
+
const firstLine = content.split('\n')[0] ?? '';
|
|
27
|
+
// Strip markdown heading markers
|
|
28
|
+
return firstLine.replace(/^#+\s*/, '').trim();
|
|
29
|
+
}
|
|
30
|
+
function extractProjectName(projectPath) {
|
|
31
|
+
if (!projectPath)
|
|
32
|
+
return 'unscoped';
|
|
33
|
+
// Take the last non-empty path segment as the project name
|
|
34
|
+
const parts = projectPath.replace(/\/$/, '').split('/');
|
|
35
|
+
const name = parts[parts.length - 1] ?? 'unscoped';
|
|
36
|
+
return name || 'unscoped';
|
|
37
|
+
}
|
|
38
|
+
function formatTagsYaml(tags) {
|
|
39
|
+
if (tags.length === 0)
|
|
40
|
+
return '[]';
|
|
41
|
+
return '\n' + tags.map(t => ` - ${t}`).join('\n');
|
|
42
|
+
}
|
|
43
|
+
function formatFilesYaml(files) {
|
|
44
|
+
if (files.length === 0)
|
|
45
|
+
return '[]';
|
|
46
|
+
return '\n' + files.map(f => ` - ${f}`).join('\n');
|
|
47
|
+
}
|
|
48
|
+
// =============================================================================
|
|
49
|
+
// Public API
|
|
50
|
+
// =============================================================================
|
|
51
|
+
/**
|
|
52
|
+
* Returns a filesystem-safe filename for a memory.
|
|
53
|
+
* Format: `<id>-<slug>.md`
|
|
54
|
+
*/
|
|
55
|
+
export function memoryToFilename(memory) {
|
|
56
|
+
const firstLine = extractFirstLine(memory.content);
|
|
57
|
+
const slug = slugify(firstLine);
|
|
58
|
+
if (slug) {
|
|
59
|
+
return `${memory.id}-${slug}.md`;
|
|
60
|
+
}
|
|
61
|
+
return `${memory.id}.md`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns the target folder path in the vault for a given memory, based on tier.
|
|
65
|
+
*/
|
|
66
|
+
export function memoryToFolderPath(memory, vaultRoot) {
|
|
67
|
+
switch (memory.tier) {
|
|
68
|
+
case 'global':
|
|
69
|
+
return join(vaultRoot, 'Foundation', 'Global');
|
|
70
|
+
case 'project': {
|
|
71
|
+
const projectName = extractProjectName(memory.project_path);
|
|
72
|
+
return join(vaultRoot, 'Foundation', 'Projects', projectName);
|
|
73
|
+
}
|
|
74
|
+
case 'session': {
|
|
75
|
+
// Group by YYYY-MM of created_at
|
|
76
|
+
const monthFolder = format(new Date(memory.created_at), 'yyyy-MM');
|
|
77
|
+
return join(vaultRoot, 'Foundation', 'Sessions', monthFolder);
|
|
78
|
+
}
|
|
79
|
+
case 'note':
|
|
80
|
+
return join(vaultRoot, 'Foundation', 'Notes');
|
|
81
|
+
case 'observation':
|
|
82
|
+
return join(vaultRoot, 'Foundation', 'Observations');
|
|
83
|
+
default:
|
|
84
|
+
return join(vaultRoot, 'Foundation', 'Global');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Transforms a Memory and its links into a full Obsidian markdown string.
|
|
89
|
+
*
|
|
90
|
+
* @param memory The memory to transform
|
|
91
|
+
* @param links All MemoryLink rows where from_memory_id === memory.id
|
|
92
|
+
* @param allMemories Map of id → Memory for resolving link targets
|
|
93
|
+
*/
|
|
94
|
+
export function transformMemory(memory, links, allMemories) {
|
|
95
|
+
const title = extractFirstLine(memory.content) || memory.id;
|
|
96
|
+
const projectName = extractProjectName(memory.project_path);
|
|
97
|
+
// -------------------------------------------------------------------------
|
|
98
|
+
// YAML frontmatter
|
|
99
|
+
// -------------------------------------------------------------------------
|
|
100
|
+
const frontmatterLines = [
|
|
101
|
+
'---',
|
|
102
|
+
`id: ${memory.id}`,
|
|
103
|
+
`tier: ${memory.tier}`,
|
|
104
|
+
`tags:${formatTagsYaml(memory.tags)}`,
|
|
105
|
+
`related_files:${formatFilesYaml(memory.related_files)}`,
|
|
106
|
+
];
|
|
107
|
+
if (memory.project_path) {
|
|
108
|
+
frontmatterLines.push(`project: ${projectName}`);
|
|
109
|
+
}
|
|
110
|
+
if (memory.session_id) {
|
|
111
|
+
frontmatterLines.push(`session_id: ${memory.session_id}`);
|
|
112
|
+
}
|
|
113
|
+
frontmatterLines.push(`created: ${unixMsToIso(memory.created_at)}`, `accessed: ${unixMsToIso(memory.accessed_at)}`, `access_count: ${memory.access_count}`, `source: gaia`);
|
|
114
|
+
// Include non-empty metadata fields as individual YAML entries
|
|
115
|
+
if (memory.metadata && Object.keys(memory.metadata).length > 0) {
|
|
116
|
+
for (const [key, value] of Object.entries(memory.metadata)) {
|
|
117
|
+
if (value !== null && value !== undefined) {
|
|
118
|
+
const serialized = typeof value === 'string' ? value : JSON.stringify(value);
|
|
119
|
+
frontmatterLines.push(`${key}: ${serialized}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
frontmatterLines.push('---');
|
|
124
|
+
// -------------------------------------------------------------------------
|
|
125
|
+
// Body
|
|
126
|
+
// -------------------------------------------------------------------------
|
|
127
|
+
const bodyLines = [
|
|
128
|
+
'',
|
|
129
|
+
`# ${title}`,
|
|
130
|
+
'',
|
|
131
|
+
memory.content,
|
|
132
|
+
];
|
|
133
|
+
// -------------------------------------------------------------------------
|
|
134
|
+
// Links section
|
|
135
|
+
// -------------------------------------------------------------------------
|
|
136
|
+
if (links.length > 0) {
|
|
137
|
+
bodyLines.push('', '## Links');
|
|
138
|
+
for (const link of links) {
|
|
139
|
+
const targetMemory = allMemories.get(link.to_memory_id);
|
|
140
|
+
let targetFilename;
|
|
141
|
+
if (targetMemory) {
|
|
142
|
+
// Use filename without .md extension for wikilinks
|
|
143
|
+
const fullFilename = memoryToFilename(targetMemory);
|
|
144
|
+
targetFilename = fullFilename.replace(/\.md$/, '');
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// Target was deleted; link to bare id
|
|
148
|
+
targetFilename = link.to_memory_id;
|
|
149
|
+
}
|
|
150
|
+
bodyLines.push(`- **${link.link_type}** → [[${targetFilename}]]`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return [...frontmatterLines, ...bodyLines].join('\n') + '\n';
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=transform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../src/vault/transform.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sashabogi/foundation",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "Unified MCP server for AI-assisted development: codebase intelligence, multi-agent orchestration, and workflow patterns with advanced memory",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"@anthropic-ai/sdk": "^0.71.0",
|
|
57
57
|
"@clack/prompts": "^1.0.0",
|
|
58
58
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
59
|
+
"@mongodb-js/zstd": "^7.0.0",
|
|
59
60
|
"better-sqlite3": "^12.0.0",
|
|
60
61
|
"chalk": "^5.3.0",
|
|
61
62
|
"commander": "^12.1.0",
|