UNPKG

agentcrumbs

Version:
152 lines 4.78 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CrumbStore = void 0; const node_fs_1 = __importDefault(require("node:fs")); const node_path_1 = __importDefault(require("node:path")); const node_os_1 = __importDefault(require("node:os")); const DEFAULT_BASE = node_path_1.default.join(node_os_1.default.homedir(), ".agentcrumbs"); const DEFAULT_FILE = "crumbs.jsonl"; const MAX_FILE_SIZE = 50 * 1024 * 1024; // 50MB before rotation class CrumbStore { filePath; fd; constructor(dir) { const storeDir = dir ?? DEFAULT_BASE; if (!node_fs_1.default.existsSync(storeDir)) { node_fs_1.default.mkdirSync(storeDir, { recursive: true }); } this.filePath = node_path_1.default.join(storeDir, DEFAULT_FILE); } static forApp(app, baseDir) { const base = baseDir ?? DEFAULT_BASE; return new CrumbStore(node_path_1.default.join(base, app)); } static listApps(baseDir) { const base = baseDir ?? DEFAULT_BASE; try { const entries = node_fs_1.default.readdirSync(base, { withFileTypes: true }); return entries .filter((e) => e.isDirectory()) .map((e) => e.name) .sort(); } catch { return []; } } static readAllApps(baseDir) { const apps = CrumbStore.listApps(baseDir); const allCrumbs = []; for (const app of apps) { const store = CrumbStore.forApp(app, baseDir); allCrumbs.push(...store.readAll()); } // Also read legacy flat file if it exists const base = baseDir ?? DEFAULT_BASE; const legacyPath = node_path_1.default.join(base, DEFAULT_FILE); try { if (node_fs_1.default.existsSync(legacyPath)) { const legacy = new CrumbStore(base); const legacyCrumbs = legacy.readAll(); // Tag legacy crumbs missing app field for (const crumb of legacyCrumbs) { if (!crumb.app) crumb.app = "unknown"; allCrumbs.push(crumb); } } } catch { // ignore } allCrumbs.sort((a, b) => a.ts.localeCompare(b.ts)); return allCrumbs; } ensureFd() { if (this.fd === undefined) { this.fd = node_fs_1.default.openSync(this.filePath, "a"); } return this.fd; } append(crumb) { const line = JSON.stringify(crumb) + "\n"; node_fs_1.default.writeSync(this.ensureFd(), line); this.maybeRotate(); } appendRaw(line) { node_fs_1.default.writeSync(this.ensureFd(), line.endsWith("\n") ? line : line + "\n"); this.maybeRotate(); } maybeRotate() { try { const stat = node_fs_1.default.fstatSync(this.ensureFd()); if (stat.size > MAX_FILE_SIZE) { this.rotate(); } } catch { // ignore } } rotate() { if (this.fd !== undefined) { node_fs_1.default.closeSync(this.fd); this.fd = undefined; } const rotated = this.filePath + ".1"; try { if (node_fs_1.default.existsSync(rotated)) node_fs_1.default.unlinkSync(rotated); node_fs_1.default.renameSync(this.filePath, rotated); } catch { // ignore rotation errors } } getFilePath() { return this.filePath; } readAll() { try { const content = node_fs_1.default.readFileSync(this.filePath, "utf-8"); return content .split("\n") .filter(Boolean) .map((line) => { try { return JSON.parse(line); } catch { return null; } }) .filter((c) => c !== null); } catch { return []; } } clear() { if (this.fd !== undefined) { node_fs_1.default.closeSync(this.fd); this.fd = undefined; } try { node_fs_1.default.writeFileSync(this.filePath, ""); } catch { // ignore } } close() { if (this.fd !== undefined) { node_fs_1.default.closeSync(this.fd); this.fd = undefined; } } } exports.CrumbStore = CrumbStore; //# sourceMappingURL=store.js.map