import { type Socket } from "socket.io-client"; import { type Attachment, type BridgeOptions } from "@mulmobridge/protocol"; export interface MessageAck { ok: boolean; reply?: string; error?: string; status?: number; } export interface PushEvent { chatId: string; message: string; } export interface BridgeClientOptions { /** Required. Identifier for this bridge in the handshake. * Matches `handshake.auth.transportId` server-side. */ transportId: string; /** Defaults to `$MULMOCLAUDE_API_URL`, then the port the server * published to `/.server-port`, then * `http://localhost:3001` (#3078). */ apiUrl?: string; /** Flat primitive bag forwarded to the host app's startChat * callback via the handshake (`BridgeOptions` from the * protocol). Values must be string / number / boolean — nested * objects are rejected server-side by the chat-service. If * omitted, the client auto-scrapes `_BRIDGE_*` / * `BRIDGE_*` env vars (producing string values). Pass `{}` * explicitly to opt out of the scrape. */ options?: BridgeOptions; } export interface BridgeClient { /** Send a user turn to MulmoClaude, wait for the assistant reply. */ send(externalChatId: string, text: string, attachments?: Attachment[]): Promise; /** Subscribe to server → bridge async pushes (Phase B of #268). */ onPush(handler: (event: PushEvent) => void): void; /** Subscribe to streaming text chunks during a relay (Phase C of * #268). Each chunk is a fragment of the assistant's response, * emitted in real time as the agent generates text. The final * ack from `send()` still carries the full response. */ onTextChunk(handler: (chunk: string) => void): void; /** Called each time the socket (re-)establishes a connection. */ onConnect(handler: () => void): void; /** Called when the socket disconnects. */ onDisconnect(handler: (reason: string) => void): void; /** Explicit shutdown. */ close(): void; /** Escape hatch — the socket in use NOW. Read it per use rather than * caching it: the client replaces the socket when the server comes back * as a different generation (#3078). */ readonly socket: Socket; } /** * Resolve the bearer token from the workspace / env var, exit with * a clear error if absent. Kept separate so bridges that want to * surface the error differently (e.g. print to a platform channel) * can call `readBridgeToken()` directly. */ export declare function requireBearerToken(): string; export declare function createBridgeClient(opts: BridgeClientOptions): BridgeClient;