/**
 * pooledClient — one client INCARNATION: the conversation it serves, the plan it
 * was opened from, its leases, its own tool list, and where it is in its life.
 *
 * Pattern: a plain record the pool owns; no behaviour beyond its own counters.
 * Role:    § 5 of the design. A client is OPENING until its open settles, OPEN
 *          while it can serve, ENDING from the decision to end it until that
 *          ending's work has settled, then ENDED. It is BUSY while any lease is
 *          open — the library's, one per operation, or the app's — while an
 *          operation that waited for its open has not yet taken its lease (a
 *          RESERVATION), and while it opens; IDLE otherwise. A busy client is
 *          never evicted, closed for idleness or ended. "Used" is the last lease
 *          taken or released.
 *
 * Its `clientId` is the pool's own random id; its `generation` counts the key's
 * incarnations (1 = the key's first client). A replacement is a new record with
 * a new id, a new list and a count of its own: nothing of an old incarnation
 * can match it.
 */
import type { McpClient, McpTerminateOutcome } from '../types.js';
import type { ClientPort } from '../clientPort.js';
import type { RequestGuard } from '../requestGuard.js';
import { DefinitionList } from './definitions.js';
import type { PoolKey } from './identityKey.js';
import type { ClientPlan } from './plan.js';
import type { Work } from './work.js';
/** Where a client is in its life. */
export type ClientState = 'opening' | 'open' | 'ending' | 'ended';
/** Why a client ended — the record's `reason`. */
export type EndReason = 'idle' | 'evicted' | 'terminated' | 'closed' | 'expired' | 'handle-lost' | 'abandoned-open';
/** One client incarnation. */
export declare class PooledClient {
    readonly key: PoolKey;
    readonly plan: ClientPlan;
    /** 1 = the key's first client, 2 = its first replacement, … */
    readonly generation: number;
    readonly clientId: string;
    state: ClientState;
    /** The ordinary `McpClient`, once opened. */
    client: McpClient | undefined;
    /** The port back (`clientPort.ts`), once opened. */
    port: ClientPort | undefined;
    /** Open leases: one per library operation, one per app lease. */
    leases: number;
    /**
     * Operations waiting for its open, each holding it until it takes its lease —
     * so between the open settling and that lease nothing can evict or end it.
     */
    reserved: number;
    /** The last lease taken or released, on the pool's clock. */
    usedAt: number;
    /** No new lease: `terminate` named it, its session expired, or its handle was lost. */
    closedToNew: boolean;
    /** Its open ran past `initTimeoutMs`: refused to every waiter, still counted until it settles. */
    abandoned: boolean;
    /** Waiting for an ending slot and an operation slot, and why. */
    deferredEnd: EndReason | undefined;
    /** This incarnation's own tool list. */
    readonly list: DefinitionList;
    /**
     * The guard of the open, listing or ending in progress on this client — what
     * a request that is not a pooled tool call is checked against and counted by.
     */
    phase: RequestGuard | undefined;
    /** The open in flight, with the work it owns. */
    opening: {
        readonly ready: Promise<void>;
        readonly work: Work;
        readonly startedAt: number;
    } | undefined;
    /** How long the open took, once it settled within its deadline. */
    initMs: number | undefined;
    /** Why it left its key without an ordinary ending: its session expired, or its handle was lost. */
    lost: 'expired' | 'handle-lost' | undefined;
    /** The outcome of its ending, once one started. */
    endingOutcome: Promise<McpTerminateOutcome> | undefined;
    /**
     * The definitions context its tools are served under now. It starts as its
     * plan's; the app's `share` is asked again at every use, and a changed answer
     * moves it here — its connection, the plan's transport, never changes.
     */
    definitions: {
        readonly context: string;
        readonly shared: boolean;
    };
    constructor(key: PoolKey, plan: ClientPlan, 
    /** 1 = the key's first client, 2 = its first replacement, … */
    generation: number, now: number);
    /** Busy: a lease is open, an operation holds it between its open and its lease, or it is still opening. */
    get busy(): boolean;
    /** Can it serve a new lease right now? */
    get serving(): boolean;
}
