export interface AjvLikeError { readonly instancePath: string; readonly message?: string; } export type WSClientErrorKind = "connect" | "handshake" | "welcome-timeout" | "welcome-invalid" | "protocol-version" | "closed" | "schema" | "outbound-schema" | "unknown-message" | "aborted"; export declare abstract class WSClientError extends Error { abstract readonly kind: WSClientErrorKind; } /** TCP / TLS / DNS layer failure: the WebSocket couldn't even * reach the HTTP upgrade step. Wraps the underlying Node net / * tls / dns error (or whatever the `ws` library surfaced). */ export declare class WSConnectError extends WSClientError { readonly kind: "connect"; readonly cause?: unknown; constructor(message: string, cause?: unknown); } /** HTTP upgrade was attempted and the server replied with an error * status (typically 401 invalid api key, 404 wrong path, 5xx * server fault). `responseBody` is the raw response payload as a * string; callers SHOULD NOT JSON.parse it without checking * Content-Type, since some 5xx pages are HTML. */ export declare class WSHandshakeError extends WSClientError { readonly kind: "handshake"; readonly statusCode: number; readonly responseBody: string; readonly cause?: unknown; constructor(statusCode: number, responseBody: string, message: string, cause?: unknown); } /** Specialization of WSHandshakeError for the 403 the server returns when the * agent's credential is presented from a device other than the one it is bound * to (single-device binding / anti-theft). statusCode is always 403, so the * reconnect layer treats it as terminal (no retry); callers branch on * `instanceof WSDeviceMismatchError` to show the "re-pair from the Dashboard" * recovery rather than retrying forever. */ export declare class WSDeviceMismatchError extends WSHandshakeError { constructor(responseBody: string, message: string, cause?: unknown); } /** Specialization of WSHandshakeError for the 403 the server returns when the * RIGHT machine but the WRONG program presents the credential: the desktop app * where the background service is bound, or the reverse. * * Separate from WSDeviceMismatchError because the two need different words in * front of a user — "this agent runs on another computer" versus "this agent * runs through your background service on this computer" — even though both are * terminal (403, never retried) and both are resolved the same way: take a * pairing code from the Dashboard and give it to the client that should have * the agent. `boundClient` is the kind the server says currently owns it. */ export declare class WSClientMismatchError extends WSHandshakeError { readonly boundClient: string; constructor(responseBody: string, boundClient: string, message: string, cause?: unknown); } /** WS open succeeded but no frame arrived within * `welcomeTimeoutMs` (default 10s). Distinguished from * WSConnectError so callers can differentiate "couldn't reach * server" from "reached server but it's not speaking". */ export declare class WSWelcomeTimeoutError extends WSClientError { readonly kind: "welcome-timeout"; constructor(message: string); } /** First server frame arrived but is not a valid welcome — wrong * type, malformed JSON, or fails ajv against * server_welcome.schema.json. `ajvErrors` is the raw ajv error * array (or empty for non-ajv failures like "wrong type"). */ export declare class WSWelcomeInvalidError extends WSClientError { readonly kind: "welcome-invalid"; readonly ajvErrors: readonly AjvLikeError[]; constructor(ajvErrors: readonly AjvLikeError[], message: string); } /** server_protocol_version's major component does not match the * runtime's compiled-in expectedProtocolVersion. Per plan §5.8 + * server_welcome.schema.json the runtime MUST refuse such * connections (major bumps are breaking). Minor / patch * mismatches do NOT throw this — they are silently accepted. */ export declare class WSProtocolVersionError extends WSClientError { readonly kind: "protocol-version"; readonly clientVersion: string; readonly serverVersion: string; constructor(clientVersion: string, serverVersion: string, message: string); } /** Operation attempted on a WSClient whose state is not * "connected": send() during closing, send() after close, * close() called twice (this is no-op, not an error — but * internal use may distinguish). */ export declare class WSClosedError extends WSClientError { readonly kind: "closed"; constructor(message: string); } /** Inbound frame failed ajv validation against its * per-message schema. Indicates server bug or protocol drift — * surfaced to onError handler; the connection stays open and * the offending message is dropped. `messageType` is the * envelope's `type` field if parseable, else "". */ export declare class WSSchemaError extends WSClientError { readonly kind: "schema"; readonly messageType: string; readonly ajvErrors: readonly AjvLikeError[]; constructor(messageType: string, ajvErrors: readonly AjvLikeError[], message: string); } /** Outbound message passed to send() failed ajv validation * against the matching client_*.schema.json. Indicates LOCAL * code bug (we tried to send something the server would * reject) — thrown synchronously to the calling code, message * never reaches the wire. Kept distinct from WSSchemaError * because callers MUST treat it as a programming error, not a * runtime drift signal. */ export declare class WSOutboundSchemaError extends WSClientError { readonly kind: "outbound-schema"; readonly messageType: string; readonly ajvErrors: readonly AjvLikeError[]; constructor(messageType: string, ajvErrors: readonly AjvLikeError[], message: string); } /** Inbound frame's `type` field is not in the dispatch table * (see protocol/schemas.ts MESSAGE_TYPE_TO_FILE). Server bug * or version skew — surfaced to onError, message dropped, * connection stays open. */ export declare class WSUnknownMessageError extends WSClientError { readonly kind: "unknown-message"; readonly messageType: string; constructor(messageType: string, message: string); } /** The caller-controlled AbortSignal fired during connect() or a * mid-flight operation. `cause` carries the abort reason * (AbortSignal.reason) so callers can distinguish their own * abort categories without parsing message text. */ export declare class WSAbortedError extends WSClientError { readonly kind: "aborted"; readonly cause?: unknown; constructor(message: string, cause?: unknown); }