import { constants } from "node:fs"; import { mkdir, open, readFile, rename, rm } from "node:fs/promises"; import path from "node:path"; import { accountProfileSchema, type AccountProfile } from "@agent-studio/shared"; export class PersistentAccountProfileStore { private profile: AccountProfile | undefined; constructor(private readonly persistentPath?: string) {} async load(): Promise { if (!this.persistentPath) return; let raw: string; try { raw = await readFile(this.persistentPath, "utf8"); } catch (error) { if ((error as NodeJS.ErrnoException).code === "ENOENT") return; throw error; } this.profile = accountProfileSchema.parse(JSON.parse(raw)); } get(): AccountProfile | undefined { return this.profile; } async save(input: AccountProfile): Promise { const profile = accountProfileSchema.parse(input); if (this.persistentPath) { await mkdir(path.dirname(this.persistentPath), { recursive: true, mode: 0o700 }); const temp = `${this.persistentPath}.${crypto.randomUUID()}.tmp`; try { const handle = await open(temp, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW, 0o600); try { await handle.writeFile(`${JSON.stringify(profile, null, 2)}\n`, "utf8"); await handle.sync(); } finally { await handle.close(); } await rename(temp, this.persistentPath); } catch (error) { await rm(temp, { force: true }); throw error; } } this.profile = profile; return profile; } }