/**
 * # client/platform-wire — the ONE platform HTTP/SSE transport dialect (kestrel-z473.2).
 *
 * The four HTTP faces of the managed service — the CLI's {@link ../cli/backend/remote.ts
 * RemoteBackend}, the CLI's {@link ../cli/backend/hosted.ts HostedFunnel}, the SDK's
 * {@link ../sdk/remote.ts remoteTransport} (via the 109 client), and the library-safe
 * {@link ./index.ts KestrelClient} — used to each hand-decode the same platform wire:
 * the single {@link DEFAULT_API}, the deterministic Idempotency-Key, the JSON/auth
 * headers, the structured 402/Offer surfaced as DATA, the trial-capability mint, and the
 * Operation SSE stream (framing lives in {@link ./sse-transport.ts}; the OperationEvent
 * decode/accumulate loop was copied verbatim into two faces). This module owns that
 * dialect ONCE so a change is a single edit and no face can silently re-fabricate it.
 *
 * The wire SHAPES + pure decoders stay in {@link ../protocol/wire.ts} (OSS-ADR-0046: the
 * protocol package owns the shapes and ships zero runtime deps). This is the TRANSPORT
 * layer over those shapes: the fetch plumbing, header construction, and stream handling
 * every face shares.
 *
 * ERROR-AGNOSTIC (like {@link ./sse-transport.ts}): the CLI faces fail closed as
 * `CliError`, the library faces as `KestrelClientError`, so every helper that can fail
 * takes the caller's error factory INJECTED (`httpError` for a synchronous status→error,
 * `onHttpError` for a `Response`→error that may read a problem+json body). This module
 * holds no error type of its own and imports NOTHING from `src/cli` — it stays inside the
 * `types:[]` light-build closure the published `./client` / `./sdk` faces depend on
 * (pinned by tests/package.boundary.test.ts).
 *
 * Determinism (ADR-0009): the Idempotency-Key is a pure sha256 of the canonical request,
 * so a replay is effect-once with no wall clock / RNG. node ≥18 + bun + Workers: web
 * `fetch`/`ReadableStream`/`TextDecoder` only.
 */
import type { TrialCapability } from "../protocol/index.ts";
import { type WireOperation, type WireOfferResponse, type SseEventType } from "../protocol/wire.ts";
import type { FetchLike } from "./sse-transport.ts";
export type { FetchLike };
/** The single canonical managed API base. A bare/empty base resolves here. Every face
 *  re-exports THIS constant rather than defining its own copy. */
export declare const DEFAULT_API = "https://api.kestrel.markets";
/** A synchronous status→error factory (fail-closed). The CLI supplies one building
 *  `CliError`; the library faces one building `KestrelClientError`. */
export type HttpErrorFactory = (status: number, message: string) => Error;
/** An async `Response`→error factory: the non-2xx path some faces enrich with the
 *  server's `application/problem+json` diagnostics (the library client) or leave bare
 *  (the CLI). It never throws inside error handling — it returns the error to throw. */
export type ResponseErrorFactory = (res: Response, message: string) => Promise<Error>;
/** A control-plane result that may be gated behind a structured 402/Offer, surfaced as
 *  DATA (ADR-0004) — never a thrown error, never a browser redirect. Structurally the
 *  `Gated<T>` both the CLI backend and the library client define, over the ONE
 *  {@link WireOfferResponse}. */
export type Gated402<T> = {
    readonly gated: false;
    readonly value: T;
} | {
    readonly gated: true;
    readonly payment: WireOfferResponse;
};
/** The JSON request headers every control-plane POST/GET carries. */
export declare function jsonHeaders(): Record<string, string>;
/** The `Authorization` header for a static bearer (a REGISTERED credential, a pre-seeded
 *  capability, or a lazily-minted anon trial). Absent bearer ⇒ `{}` (no header), never a
 *  fabricated token. The keypair-JWT path is a per-face concern (it mints a fresh token
 *  per call) and is layered on top by the caller. */
export declare function bearerHeader(bearer: string | undefined): Record<string, string>;
/**
 * A DETERMINISTIC Idempotency-Key: a sha256 of the canonical request (method, path,
 * body). The identical request yields the identical key → effect-once on replay
 * (ADR-0009), with no wall clock / RNG on the runtime path. ≥8 chars (openapi). This is
 * the ONE definition — the CLI and library faces were byte-identical copies of it, so a
 * cross-face replay is effect-once interchangeable.
 */
export declare function idemKey(method: string, path: string, body: unknown): string;
/**
 * Decode a structured 402 body → {@link WireOfferResponse}, fail-closed via the injected
 * `httpError`. NEVER opens a browser / follows `human_action.url` — the Offer is returned
 * as DATA (ADR-0004). A body that is not JSON, or is JSON that is not a real OfferResponse,
 * is a loud error, never a silent default.
 */
export declare function decodeOfferResponse(res: Response, httpError: HttpErrorFactory): Promise<WireOfferResponse>;
/**
 * Read the `diagnostics[]` off a 422 validate response into human strings. Fail-safe: a
 * non-JSON / absent body degrades to `["validation_failed"]`, never a throw (a validate
 * failure must surface `ok:false` + diagnostics, never a 200 hiding a silent default).
 */
export declare function parseValidateDiagnostics(res: Response): Promise<string[]>;
/** The decoded result of a trial mint: the OSS {@link TrialCapability} plus the raw
 *  bearer token (`capability`) the caller caches for its `Authorization` header. */
export interface MintedTrial {
    readonly capability: TrialCapability;
    readonly bearer: string;
}
/**
 * `POST /capabilities/trial` — mint an anonymous trial capability (proof-before-account,
 * ADR-0009). Effectful → carries a deterministic Idempotency-Key. The bearer token
 * (openapi `capability`) authorizes every subsequent call. The caller owns caching (it
 * sets `this.cap`/`this.bearer`) and the error type (`onHttpError` builds it). No trial is
 * ever minted here except by an explicit call — a face short-circuits when it already
 * holds a bearer.
 */
export declare function mintTrialCapability(opts: {
    readonly fetch: FetchLike;
    readonly base: string;
    readonly onHttpError: ResponseErrorFactory;
}): Promise<MintedTrial>;
/**
 * An effectful control-plane POST (`/sim`, `/grade`) with the deterministic
 * Idempotency-Key and structured-402 gating. The caller pre-resolves its `authHeaders`
 * (so the jwtSigner / anon-mint timing stays a per-face concern) and injects both error
 * factories: `httpError` for the 402 Offer decode, `onHttpError` for a non-2xx. A 402 is
 * surfaced as DATA on {@link Gated402}; anything else off the happy path is a loud throw.
 */
export declare function postEffectful(opts: {
    readonly fetch: FetchLike;
    readonly base: string;
    readonly path: string;
    readonly body: unknown;
    readonly authHeaders: Record<string, string>;
    readonly httpError: HttpErrorFactory;
    readonly onHttpError: ResponseErrorFactory;
}): Promise<Gated402<WireOperation>>;
/** A single SSE frame surfaced to an {@link ConsumeOperationOptions.onEvent} observer. */
export interface OperationEventView {
    readonly type: SseEventType;
    readonly operationId: string;
    /** The opaque resume cursor at this frame. */
    readonly cursor: string;
    /** The opaque domain payload carried on artifact/receipt frames. */
    readonly data?: Record<string, unknown>;
}
export interface ConsumeOperationOptions {
    readonly fetch: FetchLike;
    /** The API base (trailing slashes already trimmed). */
    readonly base: string;
    /** The Operation whose canonical event stream is read to its terminal event. */
    readonly operationId: string;
    /** The initial opaque cursor (the Operation's `cursor`), handed back verbatim. */
    readonly cursor: string;
    /** Auth (and any other) headers for the events GET. */
    readonly headers?: Record<string, string>;
    readonly httpError: HttpErrorFactory;
    readonly unknownEventError: (type: string) => Error;
    /** Observe each in-vocabulary frame as it arrives (progress/artifact/…). Optional. */
    readonly onEvent?: (event: OperationEventView) => void;
}
/**
 * Read an Operation's canonical event stream (`GET /operations/{id}/events`) to a terminal
 * event, accumulating the domain payload from `operation.artifact` / `operation.receipt`
 * frames. The framing + opaque-cursor resume loop is the shared leaf
 * ({@link consumeSseStream}); this supplies the OperationEvent vocabulary, the per-frame
 * decode/accumulate, and the optional observer. An SSE event whose `type` is outside the
 * OperationEvent enum is a protocol violation → FAIL CLOSED (via `unknownEventError`);
 * `operation.failed`, a non-JSON `data:`, a bad status, or budget exhaustion are loud
 * errors (via `httpError`), never a silent empty payload.
 */
export declare function consumeOperationStream(opts: ConsumeOperationOptions): Promise<{
    payload: Record<string, unknown>;
}>;
//# sourceMappingURL=platform-wire.d.ts.map