- File-based memory under .boocode/memory/ (project/user/reference topics) - Hierarchical 4-scope scan: global → home → project → session - Keyword/tag relevance matching for query-based recall - Injected as <boocode-memory> block in system prompt at assembly - v1 recall-only (extract/dream deferred to v2)
55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
export interface MemoryEntry {
|
|
id: string;
|
|
topic: string;
|
|
title: string;
|
|
content: string;
|
|
tags: string[];
|
|
}
|
|
|
|
export function parseMemoryEntries(fileName: string, markdown: string): MemoryEntry[] {
|
|
const entries: MemoryEntry[] = [];
|
|
const lines = markdown.split('\n');
|
|
let currentEntry: Partial<MemoryEntry> | null = null;
|
|
let currentContent: string[] = [];
|
|
|
|
for (const line of lines) {
|
|
const headingMatch = line.match(/^##\s+(.+):\s+(.+)$/);
|
|
if (headingMatch && headingMatch[1] && headingMatch[2]) {
|
|
if (currentEntry && currentEntry.title) {
|
|
entries.push({
|
|
id: `${fileName}-${entries.length}`,
|
|
topic: currentEntry.topic ?? '',
|
|
title: currentEntry.title,
|
|
content: currentContent.join('\n').trim(),
|
|
tags: currentEntry.tags ?? [],
|
|
});
|
|
}
|
|
currentEntry = { topic: headingMatch[1].trim(), title: headingMatch[2].trim(), tags: [] };
|
|
currentContent = [];
|
|
continue;
|
|
}
|
|
|
|
const tagsMatch = line.match(/^>\s*tags:\s*(.+)$/i);
|
|
if (tagsMatch && tagsMatch[1] && currentEntry) {
|
|
currentEntry.tags = tagsMatch[1].split(',').map((t) => t.trim());
|
|
continue;
|
|
}
|
|
|
|
if (currentEntry) {
|
|
currentContent.push(line);
|
|
}
|
|
}
|
|
|
|
if (currentEntry && currentEntry.title) {
|
|
entries.push({
|
|
id: `${fileName}-${entries.length}`,
|
|
topic: currentEntry.topic ?? '',
|
|
title: currentEntry.title,
|
|
content: currentContent.join('\n').trim(),
|
|
tags: currentEntry.tags ?? [],
|
|
});
|
|
}
|
|
|
|
return entries;
|
|
}
|