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; /** * 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; export declare function registerCleanup(port: number): void;