import type { NewWritePlan, WritePlan } from "../domain/write.js"; export type WritePlanStoreOptions = { /** Injected by tests so expiry does not depend on wall-clock timing. */ now?: () => Date; /** Injected by tests so no suite writes into the real `~/.jam`. */ root?: string; }; export declare class WritePlanStore { private readonly now; private readonly root; constructor(options?: WritePlanStoreOptions | (() => Date)); create(plan: NewWritePlan): WritePlan; /** * Resolve a plan for applying, and claim it in the same step. * * The claim is a rename, because two processes can now reach the same plan * and `rename` is the only thing here that is atomic. Whoever renames it owns * the apply; everyone else sees the file already gone and is told there is no * such plan - which is the truth, for them. * * Reading and then deleting would leave a window between the two, and for * `comment.add` that window is a second comment. * * An expired plan is reported as expired rather than as missing: those are * different situations, and telling them apart is the difference between * "re-plan" and "you are calling this wrong". */ take(planId: string): WritePlan; /** * Retire a plan once it has been applied. * * Single use, so a receipt cannot be turned into a second mutation by * calling apply again with the same id - which for `comment.add` would mean * two comments. `take` already made that true by claiming the file; this * removes the claim so it does not sit until expiry. */ consume(planId: string): void; private notFound; /** ``, with the id checked so it can only name a file here. */ private pathFor; private ensureRoot; /** * Drop what has aged out, including claims abandoned by a process that died * mid-apply. Not retrying such a claim is deliberate: apply may already have * reached Jira, and that is `JAM_WRITE_UNCERTAIN`'s whole posture. */ private evictExpired; }