/**
 * File-based workspace ownership.
 *
 * Why a handle and not loose helpers: lock file + pid file are coupled —
 * the pid file is meaningful only while the lock is held, and close-order
 * is load-bearing (pid file must be cleaned before lock release so a
 * concurrent startup sees the workspace as busy until both Chrome is dead
 * and its pid record is gone). Bundling them as a handle keeps callers
 * from accidentally splitting the cleanup.
 */
export interface WorkspaceLockHandle {
    /** Record Chrome's pid so the next startup can clean it up if we crash. */
    writePid(pid: number): void;
    /** Clear pid record after Chrome has exited cleanly. */
    clearPid(): void;
    /**
     * Best-effort kill of any orphan Chrome whose pid was recorded by a
     * previous owner of this workspace. Run after acquire(), before spawning
     * a new Chrome. Safe to call when no pid file exists.
     */
    killOrphanChrome(userDataDir: string): Promise<void>;
    /**
     * Release workspace ownership: clear pid file then unlink lock file.
     * Order matters — a concurrent dipclaw startup must see "busy" until
     * both are gone. Safe to call more than once.
     */
    release(): void;
}
/**
 * Claim the workspace (or take over a stale lock) and return a handle.
 *
 * Throws if another live dipclaw owns this workspace, or if contention is
 * pathological and 20 attempts fail. On any internal failure between
 * claim and return, the lock is released before throwing so we don't
 * orphan our own lock file.
 */
export declare function acquireWorkspaceLock(userDataDir: string): Promise<WorkspaceLockHandle>;
