import { Buffer } from "node:buffer";
//#region src/tools/image-sniff.ts
/**
* Magic-byte sniffer for inline image blocks.
*
* Anthropic's `messages` API validates the declared `media_type` against the
* actual bytes; a mismatch (e.g. an MCP screenshot tagged `image/webp` that
* actually serves JPEG) rejects the whole request with
* `messages.N.content.K.tool_result.content.M.image.source.base64: The image
* was specified using the X media type, but the image appears to be a Y image`.
*
* Three boundaries in the harness emit image blocks where the declared type
* came from a less-than-trustworthy signal:
*
*   1. `read_file` — derives mediaType from the file extension.
*   2. `normalizeMcpBlocks` — forwards `mimeType` declared by the MCP server.
*   3. TUI paste — derives mediaType from the dropped-file extension.
*
* Each calls {@link reconcileImageMediaType} with the declared type and the
* payload (bytes or base64). The sniffer overrides the declared type only
* when the magic bytes positively identify a *different* known format —
* unknown / non-image / too-short payloads pass the declared type through
* unchanged so we never make a worse guess than the source.
*
* The check is cheap (≤16 bytes inspected) and runs once per image block.
*/
/**
* Identify a common raster image format from its leading bytes.
*
* Returns the IANA media type when the magic bytes match a known signature,
* or `undefined` for unknown / too-short payloads. Callers must NOT treat
* `undefined` as "not an image" — it just means "we couldn't tell".
*
* Signatures cover the formats actually accepted by the Anthropic API
* (PNG, JPEG, GIF, WebP) plus BMP (some sources still emit it).
*/
function sniffImageMediaType(bytes) {
	if (bytes.length < 3) return void 0;
	if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) return "image/jpeg";
	if (bytes.length >= 8 && bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71 && bytes[4] === 13 && bytes[5] === 10 && bytes[6] === 26 && bytes[7] === 10) return "image/png";
	if (bytes.length >= 6 && bytes[0] === 71 && bytes[1] === 73 && bytes[2] === 70 && bytes[3] === 56 && (bytes[4] === 55 || bytes[4] === 57) && bytes[5] === 97) return "image/gif";
	if (bytes.length >= 12 && bytes[0] === 82 && bytes[1] === 73 && bytes[2] === 70 && bytes[3] === 70 && bytes[8] === 87 && bytes[9] === 69 && bytes[10] === 66 && bytes[11] === 80) return "image/webp";
	if (bytes.length >= 4 && bytes[0] === 66 && bytes[1] === 77) return "image/bmp";
}
/**
* {@link sniffImageMediaType} but takes a base64 string. Decodes just enough
* of the prefix to cover the longest signature we look for (12 bytes for
* WebP), so the cost is constant regardless of image size.
*
* Tolerates whitespace inside the base64 (line-wrapped output from `base64
* < file` on coreutils) and incomplete trailing groups. Returns `undefined`
* when nothing decodable is in the leading slice — callers should treat
* that as "couldn't tell" and keep the declared type.
*/
function sniffImageMediaTypeFromBase64(b64) {
	const clean = b64.replace(/\s+/g, "");
	if (clean.length < 8) return void 0;
	const usable = clean.length >= 16 ? clean.slice(0, 16) : clean.slice(0, clean.length - clean.length % 4);
	if (usable.length === 0) return void 0;
	try {
		return sniffImageMediaType(Buffer.from(usable, "base64"));
	} catch {
		return;
	}
}
/**
* Reconcile a declared image media type against the actual bytes.
*
* Returns the sniffed type when it positively identifies a *different*
* known format; otherwise returns `declared` unchanged. This is the
* one-call interface for harness boundaries that need to ship a
* `{ type: 'image', mediaType, data }` block to a vision API.
*
* Failure modes are conservative by design:
*   - Sniff unknown      → keep `declared` (we don't know better).
*   - Sniff matches      → keep `declared` (no-op).
*   - Sniff disagrees    → use the sniffed type (the bug-fix path).
*
* Accepts either raw bytes (preferred when you already have them) or a
* base64 string (convenient at the wire boundary).
*/
function reconcileImageMediaType(declared, data) {
	const sniffed = typeof data === "string" ? sniffImageMediaTypeFromBase64(data) : sniffImageMediaType(data);
	if (sniffed && sniffed !== declared) return sniffed;
	return declared;
}
//#endregion
export { sniffImageMediaType as n, reconcileImageMediaType as t };

//# sourceMappingURL=image-sniff-B7uFSNO1.js.map