import { type H2AAgentVersion, type H2ALaunchContext, type H2ASession, type H2ASessionInterests, type H2ASessionNotificationTopic, type H2ASessionState, type H2AWorkspaceRef } from "@sentropic/h2a"; export interface OpenSessionRequest { /** Identity of the live attachment. Required. */ readonly instance: string; /** Host CLI hint (claude / codex / gemini / ...). Optional. */ readonly host?: string; /** First-class workspace trace for the perennial identity. */ readonly workspace?: H2AWorkspaceRef; /** Mutable display name for the perennial agent. */ readonly name?: string; /** PID of the holding process. Defaults to process.pid. */ readonly pid?: number; /** Scopes / negotiations the session wants to follow. Defaults to empty arrays. */ readonly interests?: Partial; /** Topics the session subscribes to. Defaults to all four canonical topics. */ readonly subscribedTopics?: readonly H2ASessionNotificationTopic[]; /** Deployed-version stamp ({cli, skill}) for drift visibility. */ readonly version?: H2AAgentVersion; /** Launch context (e.g. the tmux pane) so wake/relance drivers can target this agent. */ readonly launchContext?: H2ALaunchContext; /** Optional explicit session id (UUID-ish). Generated if omitted. */ readonly sessionId?: string; } export interface SessionRegistryOptions { /** Heartbeat interval (ms). Defaults to H2A_SESSION_DEFAULT_HEARTBEAT_INTERVAL_MS. */ readonly heartbeatIntervalMs?: number; /** Expiry window (ms). Defaults to H2A_SESSION_DEFAULT_EXPIRY_MS. */ readonly expiryMs?: number; /** * When true, schedule a setInterval that touches each session's heartbeat * on disk. Disabled by default so unit tests can drive the clock manually. */ readonly autoHeartbeat?: boolean; } /** * Per-process registry of MCP sessions. Owns the in-memory map and the * heartbeat timers. Each session corresponds to one client connection * (one mcp-serve subprocess attachment). The registry writes a presence * file under `/.h2a/presence/.json` and keeps it fresh. */ export declare class SessionRegistry { private readonly root; private readonly entries; private readonly heartbeatIntervalMs; private readonly expiryMs; private readonly autoHeartbeat; constructor(root: string, options?: SessionRegistryOptions); open(request: OpenSessionRequest): H2ASession; close(sessionId: string, finalState?: H2ASessionState): H2ASession | undefined; /** * Install (or replace) the host-native display-name resolver for a session. * Spec 2026-07-25-h2a-lane-addressing §D1b. Idempotent on unknown ids. */ setDisplayNameResolver(sessionId: string, resolve: () => string | undefined): void; /** * Re-derive the host-native display name for a session, returning it only * when it is a real CHANGE worth writing. * * Deliberately conservative in three ways (spec §D1b): * - a resolver that throws is swallowed — a naming bug must never break the * heartbeat, which is what liveness is computed from; * - `undefined` (transcript rotated, deleted, or not yet findable) keeps the * name we already have. It must NEVER downgrade a real host-native name back * to the cwd basename — refresh is monotonic in confidence; * - an unchanged value returns undefined so the patch key is omitted entirely * rather than re-writing the same string. */ private nextDisplayName; /** Mark heartbeat on disk for a known session. Idempotent on unknown ids. */ touch(sessionId: string): H2ASession | undefined; /** * WP-F: record that the MCP channel carried an inbound line right now. Cheap * (in-memory only); flushed to the presence file by the next heartbeat * `touch()`. No-op on an unknown session id. */ markActivity(sessionId: string): void; /** Snapshot of in-memory sessions held by this process. */ list(): H2ASession[]; /** Scan all presence files under root (own + peers), filtered by freshness. */ scanFresh(now?: number): H2ASession[]; /** * Close every live session held by this process. Idempotent. Used by * mcp-serve's shutdown hook when stdin reaches EOF or a signal lands. */ closeAll(finalState?: H2ASessionState): void; } //# sourceMappingURL=sessions.d.ts.map