import type { ResolvedConfig } from "../shared/config.js"; import { type AssetRecord, type BatchResponse, type SearchResponse } from "./wire.js"; /** The API said no, with a code we can act on. */ export declare class LibraryError extends Error { readonly status: number; readonly code?: string | undefined; constructor(message: string, status: number, code?: string | undefined); } /** We could not reach the API at all — a transport failure, not an answer. */ export declare class LibraryUnreachableError extends Error { readonly cause?: unknown | undefined; constructor(cause?: unknown | undefined); } export interface SearchParams { q: string; kind?: string; render?: string; palette?: string; limit?: number; } /** * The transport seam. Every f5 command takes one of these, so the whole surface is * testable against a recording stub with no socket — and so the deny fixture in * QA-F5-C3 has exactly one place to observe. */ export interface LibraryClient { search(params: SearchParams): Promise; fetchOne(id: string): Promise; batch(ids: string[]): Promise; /** Download asset BYTES from a URL the SERVER returned. Only `--download` calls this. */ download(url: string): Promise; } /** * The real HTTP client, PAT-authed like every other machine call. * * A thrown TypeError from `fetch` is a transport failure (DNS, refused connection, * a deny fixture) and becomes LibraryUnreachableError → exit 4. An HTTP status is * an ANSWER and becomes LibraryError, which the commands map by code. Collapsing * the two would merge "we did not answer" into "we answered no", and the agent's * correct recovery differs between them (retry later vs re-search). */ export declare function httpLibraryClient(cfg: ResolvedConfig): LibraryClient;