/**
* Memory Manager — persistent /remember and /forget across sessions
*
* Extracted from agent-loop.ts for single-responsibility.
* All consumers should import from agent-loop.ts (re-export facade).
*/
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
import { join } from "path";
import { homedir } from "os";
const MEMORY_DIR = join(homedir(), ".swagmanager", "memory");
const MEMORY_FILE = join(MEMORY_DIR, "MEMORY.md");
function ensureMemoryDir(): void {
if (!existsSync(MEMORY_DIR)) mkdirSync(MEMORY_DIR, { recursive: true });
}
export function loadMemory(): string {
if (!existsSync(MEMORY_FILE)) return "";
try {
return readFileSync(MEMORY_FILE, "utf-8").trim();
} catch { return ""; }
}
export function addMemory(fact: string): { success: boolean; message: string } {
ensureMemoryDir();
const existing = loadMemory();
const entry = `- ${fact}`;
// Check for duplicate
if (existing.includes(fact)) {
return { success: false, message: "Already remembered." };
}
const updated = existing ? existing + "\n" + entry : entry;
writeFileSync(MEMORY_FILE, updated + "\n", "utf-8");
return { success: true, message: `Remembered: ${fact}` };
}
export function removeMemory(pattern: string): { success: boolean; message: string } {
if (!existsSync(MEMORY_FILE)) return { success: false, message: "No memories stored." };
const content = readFileSync(MEMORY_FILE, "utf-8");
const lines = content.split("\n");
const lower = pattern.toLowerCase();
const filtered = lines.filter(line => !line.toLowerCase().includes(lower));
if (filtered.length === lines.length) {
return { success: false, message: `No memory matching "${pattern}" found.` };
}
const removed = lines.length - filtered.length;
writeFileSync(MEMORY_FILE, filtered.join("\n"), "utf-8");
return { success: true, message: `Forgot ${removed} memor${removed === 1 ? "y" : "ies"} matching "${pattern}".` };
}
export function listMemories(): string[] {
const content = loadMemory();
if (!content) return [];
return content.split("\n").filter(l => l.trim().startsWith("- ")).map(l => l.replace(/^- /, "").trim());
}