/**
 * The project registry: `~/.indusk/projects.json` (or `$INDUSK_HOME/projects.json`
 * if INDUSK_HOME is set — used by tests to redirect away from the real home).
 *
 * Mutations only happen via this module's exports. Reads are also funneled here
 * so the version bump path is single-sourced if the schema ever evolves.
 */
export interface ProjectEntry {
    name: string;
    path: string;
    registeredAt: string;
    lastSeenAt: string;
}
export interface Registry {
    version: 1;
    projects: ProjectEntry[];
}
/**
 * Read the registry. Returns a fresh empty registry if the file doesn't exist.
 *
 * When the file exists but is malformed (unparseable JSON, or parseable but
 * wrong-shape), we QUARANTINE it: rename to `projects.json.corrupt.{ISO}.bak`
 * before returning `emptyRegistry()`. Any subsequent `writeRegistry` creates
 * a fresh `projects.json` without silently overwriting the damaged bytes.
 * The ISO timestamp in the filename prevents repeated corruption events from
 * overwriting each other's backups. A stderr warning names the quarantined
 * file so the user can recover (hand-fix the JSON, mv back).
 */
export declare function readRegistry(): Registry;
/**
 * Append a new project to the registry. Returns the entry that was created.
 *
 * Name resolution: basename of the path, with a numeric suffix (`-2`, `-3`, ...)
 * if the basename collides with an already-registered project. The path itself
 * is the deduplication key — registering the same path twice is a no-op
 * (returns the existing entry without modifying lastSeenAt).
 */
export declare function addProject(projectPath: string): ProjectEntry;
/**
 * Look up a project by name. Returns the entry plus a fresh `pathExists` check —
 * the registry isn't auto-pruned, so a registered name may point at a deleted
 * directory. Caller decides what to do with that signal (the admin UI shows
 * a "needs reconfiguration" failure page in that case).
 *
 * Throws if the name isn't in the registry at all (missing entries are a
 * different failure mode from stale-but-registered entries).
 */
export declare function validateProject(name: string): {
    entry: ProjectEntry;
    pathExists: boolean;
};
/**
 * Update a project's `lastSeenAt` to now. Idempotent — calling it on a
 * non-existent name is a no-op (no throw, just nothing happens).
 */
export declare function touchProject(name: string): void;
