import { type DeviceInput, type DevicePlatform } from './registry.js';
/** A single node distilled from `tailscale status --json`. */
export interface TailscaleNode {
    name: string;
    platform: DevicePlatform;
    dnsName?: string;
    ip?: string;
    online: boolean;
    direct: boolean;
    relay?: string;
    lastSeen?: string;
    /** True for a node another user shared INTO this tailnet — not the operator's
     * own machine, so discovery must never auto-register or suggest it. */
    sharee: boolean;
}
/**
 * Slugify a raw Tailscale HostName into a valid logical device name (ssh alias
 * charset). Used only as a fallback — when a node has a DNSName we prefer its
 * first label, which is the canonical slug Tailscale itself derived.
 */
export declare function slugifyHostName(hostName: string): string;
/**
 * Parse `tailscale status --json` output into one node per tailnet device,
 * including Self. Throws on malformed JSON. Nodes without a HostName are
 * skipped (they cannot be addressed by a logical name).
 */
export declare function parseTailscaleStatus(json: string): TailscaleNode[];
/** Turn a parsed Tailscale node into the registry fields it can populate. */
export declare function nodeToDeviceInput(node: TailscaleNode): DeviceInput;
/**
 * Run `tailscale status --json` and return its raw stdout. Throws a clear
 * error when the binary is missing or the daemon is not reachable.
 */
export declare function tailscaleStatusJson(): string;
