UNPKG

@essentialai/cogent-bridge

Version:

Cogent Bridge — cross-agent comms for Claude Code, OpenAI Codex and Slack. Codex users: install with `curl -fsSL https://cogent.tools/install.sh | sh`, then start with `cogent-codex` for real-time peer wake.

76 lines • 3.81 kB
/** * Authenticated HTTP client for cloud relay server communication. * Uses Node built-in fetch() (Node 18+) with Bearer token auth. * Maps HTTP error responses to BridgeError for consistent error handling. */ export declare class HttpClient { private readonly baseUrl; private token; constructor(baseUrl: string, token: string); private headers; /** * fetch() with an AbortController timeout. Node's fetch has NO default * timeout, so a stalled relay connection would otherwise block forever and * stall the WS poll fallback. An abort maps to a NETWORK_TIMEOUT BridgeError; * every other rejection (DNS, connection refused, etc.) propagates unchanged. */ private fetchWithTimeout; /** * Parse a SUCCESS body, turning an unparseable one into a BridgeError. * * 🔴 WHY THIS EXISTS. `throwMappedError` has always guarded the NON-2xx path, so an nginx 502 or * 413 HTML page arrives as a clean BridgeError. The 2xx path did not: `return resp.json()` let a * truncated or empty success body escape as a raw `SyntaxError` carrying no code, no suggestion, * and nothing in the signature to warn a caller it could happen — callers at * http-backend.ts (list peers / get history / health check) simply propagated it. * * That is the worst corner of the trade-off the vault describes (how much information a failure * carries vs how strictly consumers must handle it — * memory/typescript-master-vault/concepts/Error_Handling.md), in a codebase whose own * BridgeError(code, message, suggestion) is the answer to it. * * A 2xx with an unreadable body is REAL: @hono/node-server can answer with a null body or append * `Error: …` to an already-streaming response (handleResponseError), and any proxy may truncate a * long /poll body. STARTUP_FAILED is deliberately the same code throwMappedError falls back to * for a non-JSON error body, so both directions of "the relay said something we cannot read" * report identically rather than inventing a second vocabulary. */ private parseJson; /** * Perform an authenticated GET request. * Appends query parameters to the URL if provided. */ get<T>(path: string, query?: Record<string, string>): Promise<T>; /** * Perform an authenticated POST request with a JSON body. */ post<T>(path: string, body: unknown): Promise<T>; /** * Perform an authenticated PATCH request with a JSON body. * Used to update existing resources (e.g., message response fields). */ patch<T>(path: string, body: unknown): Promise<T>; /** * Perform an authenticated DELETE request. * Returns the RESPONSE HEADERS (a 204 carries no body, but the relay conveys * out-of-band signals — e.g. Cogent Mail F3's `X-Cogent-Mailbox-Deprovisioned` — * via headers, so callers that need them can read them without a body). * * When no body is provided, Content-Type is omitted so servers don't try * to parse an empty payload as JSON. This was the root cause of a * "Malformed JSON in request body" 400 from cogent-server <=3.1.2 when * any client (including third-party tools) DELETEd a peer without a body. */ delete(path: string, body?: unknown): Promise<Headers>; /** * Update the Bearer token (e.g., after join-session returns a new token). */ updateToken(newToken: string): void; /** * Parse an error response from the server and throw a BridgeError. * If the server returns a cogent ErrorCode, it is passed through. * For non-JSON error responses, STARTUP_FAILED is used as a fallback code. */ private throwMappedError; } //# sourceMappingURL=http-client.d.ts.map