/**
 * Format Registry — the single source of truth for how Studiograph ingests
 * every file type.
 *
 * Framework-free and dependency-free (sits alongside `validation.ts` /
 * `schema-registry.ts`), so it can be imported by server routes, services,
 * the MCP layer, the CLI, and serialized to the web client over
 * `GET /api/formats`. Every ingestion surface reads from here instead of
 * maintaining its own parallel extension / MIME / accept list — that
 * divergence (a stale `.xlsx`, a half-supported `.svg`, a PDF that becomes
 * an asset on one path and a note on another) is exactly what this registry
 * exists to kill.
 *
 * Each `FormatEntry` declares the full disposition of a format: how it's
 * handled, whether the original is retained, what (if anything) it derives
 * to, how it's indexed for search, and which extractor feeds that index.
 * The fields are consumed incrementally across the phased refactor — P0 wires
 * the routing (`handler`, `category`, `extractor`, `sanitize`) and the
 * searchability contract (`indexAs`); later phases consume `deriveTo` /
 * `derive` (conversions, P2), `extractor` for sidecars/captions (indexing,
 * P3), `mimeTypes` (MCP presign, P4), and the serialized shape (client, P5).
 *
 * "Dependency-free" here means no npm packages / no framework — the Node
 * `path` builtin is fine and shared with the rest of `src/core`.
 */
/** How a format is dispatched + what it ultimately becomes. */
export type FormatCategory = 'direct-note' | 'direct-dataset' | 'asset-convertible' | 'asset' | 'bookmarks';
/** Which server handler ingests the bytes. */
export type FormatHandler = 'importDirect' | 'uploadAsset' | 'importBookmarks';
/** The entity a convertible format derives to (entry-primary, D1). */
export type FormatDeriveTo = 'note' | 'dataset' | 'reference' | null;
/** When the derivation happens. */
export type FormatDerive = 'inline' | 'deferred' | 'none';
/**
 * How the format feeds the search index.
 * - `body`    — the entity body itself is the index text (notes, datasets).
 * - `sidecar` — extracted text written to a `.studiograph/assets-text/` sidecar.
 * - `caption` — vision caption + OCR text written to a sidecar.
 * - `none`    — opaque; filename + frontmatter only (`indexable: false`).
 */
export type FormatIndexAs = 'body' | 'sidecar' | 'caption' | 'none';
/** The extractor that produces index text for this format (null = none). */
export type FormatExtractor = 'pdf' | 'docx' | 'xlsx' | 'image-caption' | null;
export interface FormatEntry {
    /** Lowercased, dot-prefixed extensions (`['.md']`). */
    extensions: string[];
    /** MIME types — drives the MCP presign allowlist (P4) + client hints. */
    mimeTypes: string[];
    category: FormatCategory;
    /** Entry-primary: keep the original binary after deriving (D1). */
    retainSource: boolean;
    deriveTo: FormatDeriveTo;
    derive: FormatDerive;
    /** `'none'` ⇒ `indexable: false` in frontmatter. */
    indexAs: FormatIndexAs;
    handler: FormatHandler;
    extractor: FormatExtractor;
    /** Declarative upper bound (bytes). Not enforced in P0; wired later. */
    maxBytes: number;
    /** Bytes need sanitizing before they're stored/served (SVG XSS, D7). */
    sanitize?: 'svg';
    /**
     * P0 transitional marker: this format's target `handler` isn't wired yet,
     * so it temporarily routes through the legacy agent-extraction path and is
     * excluded from `assetUploadExtensions()` (preserving today's behavior).
     * Remove it when the real handler lands — docx when the deterministic
     * markdown convert ships (P2); svg when `sanitize-html` is wired (P3) — at
     * which point the format flows to `uploadAsset` like every other asset.
     */
    transitional?: 'agent-extract';
}
/**
 * The disposition for any file the registry doesn't recognize: a generic
 * opaque asset, never content-indexed. `resolveFormat` returns this exact
 * (frozen) reference for unknown types so callers can identity-check it —
 * the P0 dispatcher rejects on `entry === FALLBACK_ASSET_ENTRY` to preserve
 * today's reject behavior; P0b removes that guard to accept unknowns
 * leniently (the only behavior change between the two phases).
 */
export declare const FALLBACK_ASSET_ENTRY: FormatEntry;
/** Look up a format by extension (dot-prefixed or bare). */
export declare function lookupByExtension(ext: string): FormatEntry | undefined;
/** Look up a format by MIME type. */
export declare function lookupByMime(mime: string): FormatEntry | undefined;
/**
 * Resolve the disposition for a file. Never returns undefined — unknown
 * types resolve to `FALLBACK_ASSET_ENTRY` (identity-checkable). Extension is
 * the primary key; `mime` is a fallback when the filename carries no usable
 * extension. Bookmark detection is by content (`isNetscapeBookmarkFile`),
 * NOT handled here.
 */
export declare function resolveFormat(filename: string, mime?: string): FormatEntry;
/** A format is searchable when it declares any index extraction. */
export declare function isIndexable(entry: FormatEntry): boolean;
/**
 * Extensions whose bytes are stored as a binary asset (category `asset` or
 * `asset-convertible`), plus `.csv` — which is a direct-dataset on the web
 * import path but has historically been accepted by `uploadAsset` too (the
 * agent `import_file` tool stores a dropped `.csv` as an opaque asset). Kept
 * in the set so `isAssetUploadExtension` preserves that behavior exactly.
 * Returned WITHOUT the leading dot to match the legacy `base.ts` set.
 */
export declare function assetUploadExtensions(): Set<string>;
/**
 * Extensions the `import-service` text path participates in — verbatim
 * direct-write formats, anything with a text/caption extractor, and the
 * sanitized SVG. Used to derive `import-service`'s `isSupportedFile`.
 *
 * This is a (small) superset of the legacy literal — it additionally
 * includes `.xlsx`, `.avif`, `.heic` — but every one of those extra
 * extensions is an asset-upload extension, so it is caught by
 * `isAssetUploadExtension` *before* `isSupportedFile` is ever consulted in
 * the only live caller (the agent `import_file` tool). The observable
 * behavior is therefore identical to the legacy set. Dot-prefixed.
 */
export declare function importServiceExtensions(): Set<string>;
/**
 * Per-ingress capability (P4, Codex drift-guard). Each ingress path has a
 * different trust model, so "which formats may travel this path" is a property
 * of the format + the path, expressed here in the registry rather than as a
 * special-case in the presign/upload code:
 *
 *  - `presign`   — MCP pre-signed PUT straight to R2. The app NEVER holds the
 *    bytes, so it cannot sanitize them. Only formats that are safe as raw bytes
 *    are eligible: image assets with no `sanitize` requirement and font assets.
 *    This is what keeps SVG (sanitize: 'svg') and every doc/video/opaque type
 *    OFF the presign path without a hardcoded list.
 *  - `inline`    — MCP base64 bytes through the app (V3) OR web multipart. The
 *    app holds the bytes, so it CAN sanitize — SVG is allowed here (sanitize
 *    runs before store). Any asset the upload pipeline accepts is inline-able.
 *  - `multipart` — alias of `inline` for the web upload route's perspective.
 *
 * A format is presign-safe iff: it's an image asset or font asset, needs no
 * sanitization, and isn't transitional. Images cover png/jpeg/gif/webp/avif/heic;
 * fonts cover woff2/woff/ttf/otf.
 */
export declare function isPresignSafe(entry: FormatEntry): boolean;
/** A format may travel the inline/multipart path iff the upload pipeline takes
 *  it (any asset, including ones that need sanitizing — the app holds the bytes
 *  and sanitizes before store). Excludes still-transitional formats. */
export declare function isInlineUploadAllowed(entry: FormatEntry): boolean;
/**
 * MIME allowlist for the MCP PRESIGN path (Content-Type gate baked into the PUT
 * signature). Derived from `isPresignSafe` — NOT every asset MIME. The presign
 * service + the MCP tool's mime enum both read this so they can't drift.
 */
export declare function presignMimeAllowlist(): string[];
/**
 * MIME allowlist for the INLINE-bytes / multipart path (V3 — the app holds the
 * bytes and can sanitize). Broader than presign: includes SVG and the
 * convertible docs. Drives the V3 `upload_asset_inline` MCP tool's gate.
 */
export declare function inlineUploadMimeAllowlist(): string[];
/**
 * The HTML `accept` attribute value covering every ingestible format
 * (extensions + MIME types). The single source the client's fragmented
 * accept lists collapse onto (P5).
 */
export declare function acceptAttribute(): string;
/**
 * JSON-safe projection of the registry for `GET /api/formats`. The client
 * builds its accept lists, disposition matrix, and supported-types copy from
 * this — `supported-file-types.ts` becomes a derived view (P5).
 */
export declare function serializeForClient(): {
    formats: FormatEntry[];
    accept: string;
};
/** All registered entries (read-only view). */
export declare function allFormats(): FormatEntry[];
