/** * `DomainError` — the ONE composer of a Plane-2 error's wire text (ggui#880). * * SPEC §7.9 Plane 2. The MCP SDK converts every error a tool handler throws * into `{content: [{type: 'text', text: error.message}], isError: true}` — * no `structuredContent`, no `_meta`, no field for a code. So `message` IS * the wire, and this base is the only place that composes it: * * ": " * * with `code` a member of {@link DOMAIN_ERROR_CODES}. A reader branches on * `text.startsWith(code + ': ')` for a REGISTERED code and on nothing else * — a tool-name prefix inside the detail (`ggui_render: …`) is prose. The * one thing the base refuses at construction is a detail that itself * begins with a registered domain or refusal code followed by `': '`: the * leading slug would then lie to the reader, and the emitter's own suite * sees the `TypeError` instead of the wire. * * Parties (the contract): the EMITTER is any data-plane handler that throws * for a caller-fixable, nothing-committed condition; the TRANSPORT is the * server's `tools/call` dispatch and the SDK's catch it hands to; the * CONSUMER is a raw MCP agent reading the result text. Observable violation: * the conformance kit's `domain-error` catalog grades the raw result. */ import { type DomainErrorCode } from '../types/domain-error-codes.js'; /** * Marks a {@link DomainError} across bundle copies and realms: an instance * from another copy of `@ggui-ai/protocol` is still a domain error to * {@link isDomainError}, which never uses `instanceof`. */ export declare const DOMAIN_ERROR_MARKER: unique symbol; /** * Thrown at construction when a detail begins with a registered code — * an emitter bug, surfaced in the emitter's own suite, never on the wire. */ export declare class DomainErrorDetailCollisionError extends TypeError { readonly code: DomainErrorCode; readonly collidingCode: string; readonly detail: string; constructor(code: DomainErrorCode, collidingCode: string, detail: string); } /** * Base of every Plane-2 error. Subclass it per state; the subclass owns the * detail text and any typed fields, the base owns the wire grammar. */ export declare class DomainError extends Error { readonly [DOMAIN_ERROR_MARKER]: true; readonly code: C; readonly detail: string; constructor(code: C, detail: string, options?: ErrorOptions); } /** * Whether `err` is a domain error — by marker and shape, never by * `instanceof` (not even `instanceof Error`, which is realm-bound), so an * instance from another bundle copy or realm still qualifies and a plain * `Error` that merely carries a `code` does not. */ export declare function isDomainError(err: unknown): err is DomainError; /** A parsed Plane-2 wire text. */ export interface ParsedDomainErrorText { readonly code: DomainErrorCode; readonly detail: string; } /** * The reader side of the grammar: `: ` for a REGISTERED code, * else `null` — a Plane-1 text (`MCP error -32602: …`), a tool-name prefix * (`ggui_render: …`) or an unregistered slug is not a domain error. */ export declare function parseDomainErrorText(text: string): ParsedDomainErrorText | null; //# sourceMappingURL=domain-error.d.ts.map