/** * Gateway session manager: orchestrates attach/detach for live dsh sessions, * enforces the persistent 1:1 binding (Q4), restores bindings across restarts * (C3), and restores normal mode on detach (Q1). * * @module dsh-subagent-codex-plus/gateway/manager */ import type { Context } from '@deepseek-ai/cordis'; import type { SessionId } from '@deepseek-ai/dsh-session'; import { type AttachedGateway } from './attach.ts'; import type { GatewayEventForwarderOptions } from './events.ts'; import { GatewayBindingStore } from './binding.ts'; export interface GatewayManagerOptions { /** App-server argv for every gateway (defaults to the package-local codex bin). */ readonly argv?: readonly string[]; /** Optional per-thread model override. */ readonly model?: string; /** Optional approval policy for gateway turns. */ readonly approvalPolicy?: string; /** Extra environment for the app-server child. */ readonly env?: Record; /** Per-agent model options carried on registered gateway agents. */ readonly agentOptions?: Record; /** Codex → dsh session event forwarding policy (R1-A1/A2). */ readonly eventForwarder?: GatewayEventForwarderOptions; } /** Owns one live attachment per session plus its durable binding. */ export declare class GatewayManager { private readonly ctx; readonly store: GatewayBindingStore; private readonly options; private readonly attached; private readonly reattachRetries; constructor(ctx: Context, store: GatewayBindingStore, options?: GatewayManagerOptions); /** Whether a session is currently attached (live gateway). */ isAttached(sessionId: SessionId): boolean; /** The live attachment for a session, if any. */ get(sessionId: SessionId): AttachedGateway | undefined; /** * Attach a live session to a Codex thread and record the durable binding. * @param sessionId - live session to take over. * @param threadId - optional existing Codex thread to resume; absent creates one. * @returns the attachment. */ attach(sessionId: SessionId, threadId?: string): Promise; /** * Detach a session: stop the gateway, drop the binding, and leave the * session cold so the host's ordinary resume path restores normal mode (Q1). */ detach(sessionId: SessionId): Promise; /** Attach count (diagnostics/UI). */ get size(): number; /** * Restore bindings after a dsh restart: whenever the host publishes a fresh * agent for a bound session, replace it with a gateway resumed on the same * durable Codex thread (C3). Skips our own agents. Resume failures caused * by a still-held thread writer lock are retried with backoff. */ installAutoReattach(): void; private restore; /** * Schedule a backoff retry of a failed auto-reattach. At most one in-flight * retry per session; the retry drops itself when the binding or session goes * away meanwhile. */ private scheduleReattachRetry; private runReattachRetry; }