/** * Persistent per-target-org id-map shared across seed runs. * * One file per (sourceAlias, targetAlias) pair under * `~/.sandbox-seed/id-maps/__.json`. JSON-shaped * identically to the per-session `id-map.json` used by `IdMap`: * * { ":": "", ... } * * A sibling `.meta.json` records the target org's identity and * `LastRefreshDate`. If either changes (org swapped behind the alias, * or the sandbox was refreshed) the persisted map is treated as stale, * archived to `.stale-.json`, and `load()` returns * an empty map. * * AI-boundary: the contents are source/target Salesforce IDs. Tool * responses must reference the file paths only, never the entries. */ export type ProjectIdMapMeta = { targetOrgId: string; /** ISO timestamp; null when the org has never been refreshed (rare). */ targetLastRefreshDate: string | null; lastWrittenAt: string; }; export type TargetIdentity = { orgId: string; lastRefreshDate: string | null; }; export type ProjectIdMapOptions = { /** Defaults to `~/.sandbox-seed`. */ rootDir?: string; sourceAlias: string; targetAlias: string; }; export type LoadResult = { /** Map entries keyed `:`. Empty when no map exists or it was invalidated. */ entries: Record; /** Populated when the persisted map was archived rather than loaded. */ invalidated: { reason: "org-refresh" | "org-mismatch" | "meta-corrupt"; archivedTo: string; } | null; }; export declare class ProjectIdMap { private readonly mapPath; private readonly metaPath; constructor(opts: ProjectIdMapOptions); paths(): { mapPath: string; metaPath: string; }; /** * Load the persisted map. If the meta indicates the target org has * been refreshed (or replaced) since the map was last written, the * stale files are renamed aside and an empty result is returned. * * Missing files are not an error — a fresh map starts empty. */ load(currentTarget: TargetIdentity): Promise; /** * Persist the merged set of entries plus a refreshed meta record. * Atomic: writes to a `.tmp` sibling then renames into place. */ save(entries: Record, currentTarget: TargetIdentity): Promise; /** * Merge `incoming` on top of the persisted map and write back. * Last-write-wins on key collisions (per BACKLOG decision, acceptable * because the more-recent target id is the authoritative one for a * given source row — a re-seed replaces the prior insert). */ merge(incoming: Record, currentTarget: TargetIdentity): Promise<{ sizeBefore: number; sizeAfter: number; invalidated: LoadResult["invalidated"]; }>; /** * Move both `.json` and `.meta.json` aside with a timestamped suffix. * Returns the archived map path. Best-effort: if rename fails (file * was already gone, e.g. raced with another process) the failure is * swallowed so callers can proceed with an empty map. */ private archive; }