import type { SessionFile } from './native/session.js';
export interface LiveReplClientLease {
    clientId: string;
    clientPid: number;
    daemonPid: number;
    runtimeToken: string;
    host: string;
    port: number;
    routerUrl: string;
    startedAt: string;
    sessionId?: string;
}
export interface LiveReplRegistry {
    version: 2;
    clients: LiveReplClientLease[];
}
export interface LiveReplRuntimeIdentity {
    host: string;
    port: number;
    routerUrl: string;
    runtimeToken?: string;
}
export interface SessionResumeResolution {
    requestedTarget: string;
    resolvedTarget: string | null;
    session: SessionFile | null;
    reason: 'ok' | 'not_found' | 'no_target' | 'no_resumable_session' | 'owned_by_live_client';
    blockedBy?: LiveReplClientLease;
    skippedLiveSessionIds: string[];
}
export interface LiveReplDetachResult {
    ok: boolean;
    reason: 'removed' | 'not_found' | 'active_requires_force';
    client?: LiveReplClientLease;
}
export interface LiveReplDetachManyResult {
    removedClients: LiveReplClientLease[];
    blockedClients: LiveReplClientLease[];
}
export type LiveReplLease = LiveReplClientLease;
export declare function createLiveReplClientId(): string;
export declare function writeLiveReplLease(lease: LiveReplLease): void;
export declare function writeLiveReplRegistry(registry: LiveReplRegistry): void;
export declare function readLiveReplRegistry(): LiveReplRegistry | null;
export declare function readLiveReplLease(): LiveReplLease | null;
export declare function removeLiveReplLease(): void;
export declare function removeLiveReplClient(clientId: string): void;
export declare function removeLiveReplClientIfOwned(clientId: string, clientPid?: number): void;
export declare function removeLiveReplLeaseIfOwned(clientPid: number): void;
export declare function upsertLiveReplClient(lease: LiveReplClientLease): LiveReplRegistry;
export declare function updateLiveReplClientSession(clientId: string, sessionId: string | undefined): boolean;
export declare function detachLiveReplClient(clientId: string, opts?: {
    force?: boolean;
}): LiveReplDetachResult;
export declare function detachLiveReplClientsForRuntime(runtime: LiveReplRuntimeIdentity, opts?: {
    force?: boolean;
}): LiveReplDetachManyResult;
export declare function listActiveLiveReplClients(runtime?: LiveReplRuntimeIdentity): LiveReplClientLease[];
export declare function getActiveLiveReplLease(): LiveReplLease | null;
export declare function getActiveLiveReplClientsForRuntime(runtime: LiveReplRuntimeIdentity): LiveReplClientLease[];
export declare function liveReplLeaseMatchesConfig(lease: Pick<LiveReplClientLease, 'host' | 'port' | 'routerUrl'>, config: {
    host: string;
    port: number;
    routerUrl: string;
}): boolean;
export declare function formatLiveReplLeaseTarget(lease: Pick<LiveReplClientLease, 'host' | 'port'>): string;
export declare function formatLiveReplClientSummary(client: Pick<LiveReplClientLease, 'clientId' | 'clientPid' | 'startedAt' | 'sessionId'>): string;
export declare function formatLiveReplClientAdminSummary(client: Pick<LiveReplClientLease, 'clientId' | 'clientPid' | 'daemonPid' | 'host' | 'port' | 'startedAt' | 'sessionId'>): string;
export declare const LIVE_REPL_CLIENT_ADMIN_SCHEMA_VERSION = 2;
export interface LiveReplClientAdminView extends LiveReplClientLease {
    /** Result of `process.kill(clientPid, 0)` at enrich time. */
    alive: boolean;
    /** "http://host:port" pre-formatted for display/copy. */
    target: string;
    /** Wall-clock seconds since startedAt (>=0). -1 if startedAt is unparseable. */
    ageSeconds: number;
    /** Session title if the session file is readable, undefined otherwise. */
    sessionTitle?: string;
    /** ISO timestamp of the session's last update if readable. */
    sessionUpdatedAt?: string;
}
/**
 * Produce the admin view for a single client. Caller passes `now` to
 * get a stable ageSeconds across a multi-client snapshot (avoids
 * drift from per-client Date.now() calls).
 */
export declare function enrichLiveReplClientForAdmin(client: LiveReplClientLease, now?: number): LiveReplClientAdminView;
/**
 * Human-readable age: "42s", "5m 12s", "2h 18m", "3d". Keeps output
 * compact — reserved callers format their own precision if needed.
 */
export declare function formatLiveReplClientAge(ageSeconds: number): string;
/**
 * Multi-line human detail block for a single client. Used by
 * `owlcoda clients` default text output. Intentionally verbose —
 * the one-line summary (`formatLiveReplClientAdminSummary`) stays
 * for compact contexts (detach messages).
 *
 *   [n] client <clientId>  alive|stale  started <age> ago
 *       PID <clientPid>    daemon <daemonPid>
 *       target <url>       router <routerUrl>
 *       session <id> — "title" (updated <age>)
 */
export declare function formatLiveReplClientDetail(view: LiveReplClientAdminView, index?: number): string;
export declare function resolveLiveReplResumeTarget(requestedTarget: string | undefined, opts?: {
    currentClientId?: string;
    runtime?: LiveReplRuntimeIdentity;
}): SessionResumeResolution;
