/** * Daemon State File Management * * Handles reading, writing, and cleanup of .sweetlink/daemon.json. * Uses atomic writes (tmp + rename) and lockfiles to prevent race conditions. */ import type { DaemonState } from './types.js'; /** * Get the .sweetlink directory path for a given project root */ export declare function getStateDir(projectRoot: string): string; /** * Get the daemon.json file path. * If appPort is provided, the state file is scoped per-port to support * multiple daemon instances in the same project (e.g., monorepo with * multiple apps running on different ports). */ export declare function getStateFilePath(projectRoot: string, appPort?: number): string; /** * Get the daemon.lock file path */ export declare function getLockFilePath(projectRoot: string, appPort?: number): string; /** * Extract port number from a URL string. */ export declare function extractPort(url: string): number | undefined; /** * Write daemon state to .sweetlink/daemon.json (or daemon-{port}.json) atomically. * Creates the directory if it doesn't exist. * Sets file permissions to 600 (owner read/write only) for security. * * If the rename fails or the process crashes between the write and the * rename, the stale `.tmp` file is left containing the bearer token. We * unlink any pre-existing tmp before writing so a previous crash can't * leak a token across daemon restarts. */ export declare function writeDaemonState(projectRoot: string, state: DaemonState, appPort?: number): void; /** * Read daemon state from .sweetlink/daemon.json (or daemon-{port}.json). * Returns null if the file doesn't exist or is invalid. */ export declare function readDaemonState(projectRoot: string, appPort?: number): DaemonState | null; /** * Remove daemon state file and lock file (and any leftover tmp). */ export declare function removeDaemonState(projectRoot: string, appPort?: number): void; /** * Check if a daemon is alive by sending an HTTP ping. * Returns true if the daemon responds, false otherwise. */ export declare function isDaemonAlive(state: DaemonState): Promise; /** * Acquire a lockfile to prevent concurrent daemon starts. * Returns true if the lock was acquired, false if another process holds it. * * Lockfile format: `PID:TOKEN` where TOKEN is a 16-byte random hex string * generated for this acquisition attempt. The token defends against PID * reuse — a reincarnated PID can't impersonate the original lock-holder * because it has a different token. * * Stale-lock recovery is made atomic by writing our token and reading it * back: if two processes race on recovery, only the winner's token will * be in the file. */ export declare function acquireLock(projectRoot: string, appPort?: number): boolean; /** * Release the lockfile */ export declare function releaseLock(projectRoot: string, appPort?: number): void; //# sourceMappingURL=stateFile.d.ts.map