export type StudioLockSource = "npx-cli" | "node-direct" | "tauri";
export interface StudioLock {
    /** OS PID of the process holding the lock. */
    pid: number;
    /** TCP port the studio runtime is bound to. */
    port: number;
    /** Truncated argv joined into a single line (≤120 chars). */
    cmdline: string;
    /** ISO-8601 UTC timestamp at which the runtime announced its bind. */
    startedAt: string;
    /** Optional source classification — defaults to "npx-cli" when omitted. */
    source?: StudioLockSource;
}
/** Returns `~/.vskill/runtime/`. Honours `$HOME` (Unix) and `$USERPROFILE` (Windows). */
export declare function runtimeDir(): string;
/** Returns the lock-file path for a given port. */
export declare function lockfilePath(port: number): string;
/**
 * Atomically write a studio lock file. Creates `~/.vskill/runtime/` if missing.
 *
 * Mode 0600 on Unix (parent dir 0700). Windows: stock fs perms — Tauri scanner
 * does the cross-platform PID liveness check anyway.
 *
 * 0832 F-007: if the target lock already exists and is owned by a LIVE
 * process (PID alive AND pid != ours), refuse to overwrite. This avoids the
 * TOCTOU race where two CLIs racing for the same port silently clobber each
 * other's lock content. Stale locks (owner dead) are replaced normally.
 */
export declare function writeLock(lock: StudioLock): string;
/** Read a lock file by port. Returns `null` if missing or unparseable. */
export declare function readLock(port: number): StudioLock | null;
/** Remove the lock file for `port`. Swallows ENOENT (idempotent). */
export declare function removeLock(port: number): void;
/** List every `studio-*.lock` in the runtime dir. Returns parsed locks (skips invalid). */
export declare function listLocks(): Array<StudioLock & {
    _path: string;
}>;
/**
 * Check if `pid` is a live process. Uses `process.kill(pid, 0)` which throws
 * `ESRCH` for nonexistent processes and `EPERM` for live-but-not-ours (still
 * counts as alive). Returns `false` only when ESRCH.
 */
export declare function isPidAlive(pid: number): boolean;
/**
 * Prune lock files that no longer correspond to a live process or are >1d old.
 * Returns the list of remaining (live) locks.
 */
export declare function pruneStaleLocks(now?: Date): Array<StudioLock & {
    _path: string;
}>;
export declare function registerCleanup(port: number): void;
