/**
 * Runtime decoders for server-boundary payloads.
 *
 * Every ingress boundary (HTTP body, WebSocket message) validates payload shape
 * before dispatching. These decoders return typed `{ ok: false, error, path }`
 * failures so routes can report the exact rejected field instead of letting
 * arbitrary shapes fail later in terminal or quality logic.
 *
 * Deliberately pure TS with no new runtime deps (zod, valibot, etc.) per
 * goat-flow's zero-new-dep policy. Narrow shapes are easy enough to validate
 * by hand.
 */
import type { AgentId } from "../types.js";
import type { ClientMessage, Runner } from "./types.js";
type DecodeResult<T> = {
    ok: true;
    value: T;
} | {
    ok: false;
    error: string;
    path: string;
};
/** Terminal-create payload after optional text fields and runner selection are normalised. */
interface TerminalCreateBody {
    prompt: string;
    projectPath: string;
    targetPath: string;
    runner: Runner;
}
/** Dashboard project-list state after omitted optional collections use their state-file fallbacks. */
interface ProjectsListBody {
    paths: string[];
    favorites: string[];
    projectTitles: Record<string, string>;
}
/** Dashboard project-path payload for single-project write actions. */
interface ProjectPathBody {
    path: string;
}
/** Base64 upload item after structural validation; file safety checks run in the upload handler. */
interface TerminalUploadFile {
    name: string;
    data: string;
}
/** Terminal upload payload grouped by request so count limits can be enforced before decoding files. */
interface TerminalUploadBody {
    files: TerminalUploadFile[];
}
/** Quality-evaluate payload, accepting one pasted document or one bounded file bundle. */
export interface EvaluateBody {
    /** Either a single content string (paste / textarea) OR an array of named
     *  files (multi-file drop). Exactly one must be set. */
    content?: string;
    files?: {
        name: string;
        content: string;
    }[];
    /** Optional filename or display name; used as the analyzed artifact name. */
    suggestedName?: string | undefined;
    /** Optional explicit kind override; otherwise inferred from frontmatter. */
    kind?: "skill" | "shared-reference" | undefined;
}
/** Hook-toggle payload accepted by POST /api/hooks/:hookId/toggle. */
type HookToggleBody = Record<"enabled", boolean>;
/**
 * Decode POST /api/terminal/create without defaulting invalid runner names.
 *
 * @param body Raw request body.
 * @param options Runner allow-list plus the fallback used only when `runner` is absent.
 * @returns Typed terminal-create payload or a path-specific decoder error.
 */
export declare function decodeTerminalCreateBody(body: string, options: {
    validRunners: ReadonlySet<string>;
    defaultRunner: AgentId;
}): DecodeResult<TerminalCreateBody>;
/**
 * Decode POST /api/projects/list while preserving dashboard state-file fallbacks.
 *
 * @param body Raw request body.
 * @returns Typed project-list payload or a path-specific decoder error.
 */
export declare function decodeProjectsListBody(body: string): DecodeResult<ProjectsListBody>;
/**
 * Decode a body carrying the target project path for a dashboard write action.
 *
 * @param body Raw request body.
 * @returns Typed project-path payload or a path-specific decoder error.
 */
export declare function decodeProjectPathBody(body: string): DecodeResult<ProjectPathBody>;
/**
 * Decode POST /api/hooks/:hookId/toggle.
 *
 * @param body - raw JSON request body from the dashboard route
 * @returns decoded hook toggle payload or a field-specific validation error
 */
export declare function decodeHookToggleBody(body: string): DecodeResult<HookToggleBody>;
/**
 * Decode POST /api/terminal/:id/upload-image before content safety checks.
 *
 * The handler enforces MIME and byte limits after this structural pass; this
 * decoder only proves the request has named base64 entries and a valid count.
 *
 * @param body Raw request body.
 * @param options Request-level upload limits from the route.
 * @returns Typed upload payload or a path-specific decoder error.
 */
export declare function decodeTerminalUploadBody(body: string, options: {
    maxFiles: number;
}): DecodeResult<TerminalUploadBody>;
/**
 * Decode a terminal WebSocket frame with one branch per supported message type.
 *
 * The socket handler sends these errors back to the client, so the explicit
 * input and resize branches intentionally preserve the exact rejected field.
 *
 * @param raw Raw WebSocket frame text.
 * @returns Typed client message or a path-specific decoder error.
 */
export declare function decodeClientMessage(raw: string): DecodeResult<ClientMessage>;
export declare const MAX_EVALUATE_CONTENT_BYTES: number;
/**
 * Decode and validate a `POST /api/quality/evaluate` request body.
 *
 * This stays explicit because the route accepts the current multi-file uploader
 * and the older single-text form; ambiguous bodies are rejected before quality
 * scoring. The deprecated `/api/quality/analyse` alias reuses the same shape.
 *
 * @param body Raw request body.
 * @returns Typed evaluate payload or a path-specific decoder error.
 */
export declare function decodeEvaluateBody(body: string): DecodeResult<EvaluateBody>;
export {};
//# sourceMappingURL=decoders.d.ts.map