import type { CrossProcessLockMetadata, AcquireLockOptions, LockHandle, LockInfo } from '../../types/spec-lock-v2.js';
declare const HEARTBEAT_INTERVAL_MS = 30000;
export { HEARTBEAT_INTERVAL_MS };
/** Thrown by withSpecLock when the lock is held by another live session. */
export declare class LockBusyError extends Error {
    readonly code: "LOCK_BUSY";
    readonly holder: CrossProcessLockMetadata;
    constructor(holder: CrossProcessLockMetadata);
}
/**
 * Try to acquire a cross-process lock for `specId`.
 *
 * Returns a LockHandle on success, or null if the lock is held by another live session.
 * Stale locks (PID dead, heartbeat expired, or TTL expired) are reclaimed automatically.
 *
 * Implementation:
 * - Attempt `fs.open(lockPath, 'wx')` (O_EXCL) — succeeds only when no lockfile exists.
 * - On EEXIST, read the existing lockfile and check staleness.
 * - If stale: overwrite atomically via SPEC-718 writeJsonSafe and return a new handle.
 * - If live: log a structured warning and return null.
 *
 * @remarks
 * NFS / SMB caveat: O_EXCL is not guaranteed atomic on network filesystems.
 * This implementation is reliable on local POSIX filesystems (APFS, HFS+, ext4, tmpfs).
 */
export declare function acquireLock(projectPath: string, specId: string, opts?: AcquireLockOptions): Promise<LockHandle | null>;
/**
 * Release a lock if it is still held by the given handle.
 * Idempotent: calling twice on the same handle is safe.
 * Will NOT unlink a lockfile that is now held by a different session.
 */
export declare function releaseLock(handle: LockHandle): Promise<void>;
/**
 * Read the current lockfile state for a spec.
 * Returns null when no lockfile exists.
 * Enriches the result with computed staleness fields.
 */
export declare function isLocked(projectPath: string, specId: string): Promise<LockInfo | null>;
/**
 * List all cross-process locks for a project, filtering out stale ones.
 * Non-existent `.locks/` directory returns an empty array.
 */
export declare function listActiveCrossProcessLocks(projectPath: string): Promise<LockInfo[]>;
/**
 * High-level wrapper: acquire → run fn → release.
 * Automatically sets up a 30s heartbeat and tears it down on completion.
 * Throws LockBusyError if the lock cannot be acquired.
 *
 * @example
 * ```ts
 * await withSpecLock(projectPath, specId, async (_handle) => {
 *   await mutatSpec();
 * }, { reason: 'update_status(approved)' });
 * ```
 */
export declare function withSpecLock<T>(projectPath: string, specId: string, fn: (handle: LockHandle) => Promise<T>, opts?: AcquireLockOptions): Promise<T>;
//# sourceMappingURL=cross-process-lock.d.ts.map