/**
 * Shared parser/rewriter for workspace asset URLs embedded in an artifact
 * bundle. One implementation behind every surface that has to reason about
 * `/api/assets/...` references, so they can't drift:
 *   - mint  → enumerate the exact asset keys an artifact references (allowlist)
 *   - in-app srcdoc + headless PNG/PDF render → append the `?at=` capability token
 *   - public share page → rewrite to `/api/share/<token>/asset/...` paths
 *   - HTML export → rewrite to relative `./assets/...` paths (placeholders for
 *     anything not bundled)
 * Which rewrite applies is decided once per render by the `AssetResolution`
 * contract (artifact-asset-resolution.ts), which derives the CSP from the
 * same value.
 *
 * Matches BOTH forms that appear in bundles:
 *   - root-relative   `/api/assets/<assetId>/<filename>`
 *   - absolute        `https://host/api/assets/<assetId>/<filename>`
 * in any textual context — `<img src>`, `srcset` descriptors, CSS `url(...)`,
 * inline `style=`, and (acceptably) JS string literals. assetId is a UUID and
 * the filename segment is percent-encoded by `publicUrlFor`/`publicUrlForAssetId`
 * (`encodeAssetFilename`) to `[A-Za-z0-9._-]` + `%XX`, so the path never holds a
 * quote/space/paren even when the stored filename does (e.g. a screenshot named
 * `page(Desktop 1920x1080) (1).png`) — we can match the URL token directly
 * without parsing HTML/CSS. (Raw special chars would truncate the match at the
 * first delimiter, splicing `?at=` into a partial URL → broken sandbox images.)
 *
 * Only the IMMUTABLE two-segment scheme is handled. The negative lookahead
 * after the filename means a legacy three-segment `/api/assets/<type>/<id>/<file>`
 * URL is left untouched rather than mis-parsed (legacy is out of scope).
 */
export interface ArtifactAssetRef {
    /** The two-segment immutable key: `<assetId>/<filename>`. */
    key: string;
    assetId: string;
    filename: string;
}
/**
 * Decode a URL filename segment back to the RAW stored filename — the canonical
 * IDENTITY used to match the asset index (`row.filename`), the capability-token
 * allowlist (`artifactAssetKey`), and the decoded serve-route path param. The URL
 * segment itself is percent-encoded by `encodeAssetFilename` (e.g. a screenshot
 * `page(1).png` → `page%281%29.png`); everything that reasons about asset identity
 * must use this decoded form, or it won't match the raw name the index/serve speak
 * (which is exactly the encoded-vs-raw mismatch that left special-char images 404).
 * URL emitters below keep the encoded segment. Falls back to the raw input on a
 * malformed `%` sequence (never throws).
 */
export declare function decodeAssetFilenameSegment(segment: string): string;
/**
 * Percent-encode a RAW stored filename into the URL segment form — the single
 * inverse of {@link decodeAssetFilenameSegment} (encode on emit, decode on
 * parse). `encodeURIComponent` alone is not enough: it leaves `!~*'()`
 * unescaped, and `()` are exactly the delimiters `ASSET_URL_RE` rejects — so
 * encode those too. Result chars ∈ `[A-Za-z0-9._-]` + `%XX`, which the
 * matcher's filename class accepts; the serve route decodes the path param
 * back to the raw stored filename, so the round-trip is exact.
 */
export declare function encodeAssetFilename(filename: string): string;
/** Every distinct asset referenced in the text, in first-seen order. `filename`
 *  and `key` are the DECODED (raw) identity — matchable against the asset index
 *  and token allowlist — not the percent-encoded URL segment. */
export declare function findArtifactAssetRefs(text: string): ArtifactAssetRef[];
/**
 * Set the `at=<token>` capability param on every asset URL. Preserves any other
 * existing query params and **replaces** a pre-existing `at` with the fresh
 * token (so a stale or embedded `?at=` in artifact HTML can't shadow a
 * freshly-minted render/preview token). Idempotent: re-applying the same token
 * yields the same string.
 */
export declare function appendAssetToken(text: string, token: string): string;
/**
 * Rewrite asset URLs to the public-share scheme:
 * `/api/share/<shareToken>/asset/<assetId>/<filename>`. Used by the share-mode
 * asset resolution so the document's URLs and its CSP allowlist come from the
 * same token. The filename segment stays in its encoded URL form. Idempotent:
 * the output no longer matches the `/api/assets/` grammar, and the server-side
 * share read may have already rewritten the body — re-applying is a no-op.
 * Legacy 3-segment URLs aren't matched and pass through unchanged.
 */
export declare function rewriteAssetsToShare(text: string, shareToken: string): string;
/**
 * A labeled inline placeholder for an asset the export could not bundle
 * (exporter lacks access / blob missing): a neutral framed box carrying the
 * filename, as a `data:image/svg+xml` URI so it renders wherever the original
 * URL appeared (`<img src>`, `srcset`, CSS `url(...)`) under the export's
 * no-network CSP. Every output char is `%XX`-escaped past encodeURIComponent's
 * leftovers (`!~*'()`), so the URI never carries a quote/paren/comma that
 * would terminate an attribute, CSS `url()`, or srcset candidate.
 */
export declare function assetPlaceholderDataUri(filename: string): string;
/**
 * Rewrite asset URLs for the self-contained HTML export. Refs whose key is in
 * `bundledKeys` (the assets actually written into the zip) become relative
 * `./assets/<id>/<file>` (offline-resolvable); any OTHER `/api/assets/...` ref
 * (exporter lacks access / blob missing — not bundled) becomes an explicit
 * labeled placeholder. NEVER absolutized back to the workspace: an exported
 * file must not phone home, and its no-network CSP would block the load anyway
 * (D11b). With no `bundledKeys` every ref is relativized (caller bundles all
 * of them). Legacy 3-segment URLs aren't matched and pass through unchanged.
 */
export declare function rewriteAssetsToRelative(text: string, baseDir?: string, opts?: {
    bundledKeys?: Set<string>;
}): string;
