/** Injectable command execution seam. */ export interface TailscaleCommandRunner { run(command: string, args: readonly string[]): { readonly status: number | null; readonly stdout: string; readonly stderr: string; }; } /** Real runner: spawnSync with a hard timeout, never a shell. */ export declare function defaultTailscaleRunner(): TailscaleCommandRunner; /** Read-only detection result, what a surface needs to offer (or not offer) the affordance. */ export interface TailscaleDetection { /** The tailscale binary exists and answered. */ readonly available: boolean; /** The node is logged in and running. */ readonly loggedIn: boolean; /** The node's MagicDNS name (trailing dot stripped), when logged in. */ readonly magicDnsName?: string | undefined; /** The https URL `tailscale serve` would yield, when a MagicDNS name exists. */ readonly httpsUrl?: string | undefined; /** Plain-language state, honest about what was (not) found. */ readonly detail: string; } /** * Detect a usable tailscale environment. READ-ONLY: `tailscale status --json` * only, never up/login/serve/set. Absence is a quiet, honest result, not an * error and never a nag. */ export declare function detectTailscale(runner?: TailscaleCommandRunner): TailscaleDetection; /** The honest record of one serve attempt, persisted either way. */ export interface TailscaleServeReceipt { readonly at: number; readonly command: string; readonly ok: boolean; /** The https MagicDNS URL now fronting the daemon, on success. */ readonly url?: string | undefined; readonly detail: string; } /** * Run `tailscale serve --bg `, the ONE state-changing tailscale action, * invoked only from the explicit user-initiated verb. Returns an honest receipt * either way; the caller persists it and updates web.publicBaseUrl on success. */ export declare function enableTailscaleServe(port: number, runner?: TailscaleCommandRunner): TailscaleServeReceipt; /** Bounded on-disk receipt log for serve attempts (newest last). */ export declare class TailscaleServeReceiptStore { private readonly filePath; constructor(filePath: string); list(): TailscaleServeReceipt[]; append(receipt: TailscaleServeReceipt): void; latest(): TailscaleServeReceipt | null; } //# sourceMappingURL=tailscale.d.ts.map