/** Going live — the pure half. See go-live.js for why each rule is what it is. */ /** The Pages project a site's live deployment belongs in, or a refusal (never a truncated name). */ export function liveProjectFor(site: { key?: string; prodProject?: string; }): { project: string; derived: boolean } | { refuse: string }; /** The DNS record the owner has to create, and the sentence that goes with it. */ export function dnsInstruction(at: { host?: string; project?: string; onCloudflareDns?: boolean; }): { record: { type: string; name: string; value: string }; note: string; /** Threaded straight through from the argument — which of the two note branches this is. */ onCloudflareDns: boolean; }; /** The `next` sentence on a hosted build_preview result: go_live when the site has no live deployment, else publish_site. */ export function buildPreviewNext(canPublish?: boolean): string; /** Which step of the go-live sequence a given state is at. */ export function goLiveStep(state?: { prodProject?: string; published?: boolean; domainStatus?: string; bound?: boolean; }): "recorded" | "ready-to-publish" | "awaiting-dns" | "verified" | "live"; /** * Where a site can be found, as one object, for `list_sites`. `live` appears only when a visitor * arrives — which, since W209 P1-2, includes what the last observation of that host actually saw: * the two probe fields below are read through `liveDomainState` (live-state.js), so `stage` and * this object cannot disagree in one payload. */ export type SiteAddressInput = { key?: string; domain?: string; intendedDomain?: string; previewProject?: string; prodProject?: string; canPublish?: boolean; liveProbeAt?: string; liveProbeServedByUs?: boolean; /** The allowlist write landed — the ONLY thing that makes the owned host real. */ previewRegistered?: boolean; /** RSP `sites.preview_registered_at`; a non-empty stamp means the same as the boolean above. */ previewRegisteredAt?: string; }; /** The zone the owned preview address lives in — INJECTED, never inlined. */ export type PreviewAddressOptions = { previewHostSuffix?: string }; export type PreviewAddress = { /** The address to hand a person: the owned host when it is real, the raw alias otherwise. */ reachableAt?: string; /** False ⇒ `reachableAt` IS the raw Cloudflare alias, and `previewNote` says so in plain words. */ previewOwned?: boolean; /** Technical Cloudflare Pages alias; never the owner-facing address when an owned one exists. */ previewRaw?: string; /** Owner-facing sentence, present only when `previewOwned` is false. */ previewNote?: string; /** Owner-facing sentence for `reachableAt`, present only when `previewOwned` is true. */ previewUrlNote?: string; /** ISO instant a minted share token (see `applyPreviewShareToken`) expires — present only once one * was actually minted onto `reachableAt`. */ previewUrlExpiresAt?: string; }; /** * The `deploymentUrl` → `snapshotUrl` reshaping (deprecated `deploymentUrl` alias kept for one * release), gated on the SAME `previewOwned` a caller just read off `previewAddressFor`. On an * owned site, `snapshotUrl` is the owned `/_v//` form (built from `ownedPreviewUrl`, i.e. * `previewAddressFor`'s `reachableAt`) and the raw `*.pages.dev` hash address moves to * `snapshotRaw`. See go-live.js's own header for the incident this exists for, and the * 2026-09-04 owner ruling for why the owned form replaced the raw one as `snapshotUrl`. */ export function snapshotUrlFields( deploymentUrl: string | null | undefined, previewOwned: boolean, ownedPreviewUrl?: string, /** 「the link is the key」 (owner ruling 2026-09-05). A token freshly minted for THIS site, * stamped onto the OWNED `/_v//` form after it is built. Omit when unowned, or a mint was * never attempted, or one was attempted and failed — every case leaves the owned form bare. */ shareToken?: string | null, /** reef #881 — an R2-only build's own minted id, for when there is no Cloudflare hash URL to * build the `/_v//` form from (`deploymentUrl` is `null`). Ignored, safely, whenever * `deploymentUrl` already parses (see `buildIdOfReport`, src/freshness.js). */ knownBuildId?: string | null, ): | { deploymentUrl: string | null } | { snapshotUrl: string | null; snapshotUrlNote: string; snapshotRaw?: string | null; deploymentUrl: string | null; }; /** The zone suffix, trimmed/lowercased/de-dotted — the one normalization every door shares. */ export function normalizePreviewHostSuffix(suffix?: string | null): string; /** * 「the link is the key」 (owner ruling 2026-09-05). Append `?k=` (or `&k=` when `url` * already carries a query) to an owned preview-host address. `null`/empty token or no url ⇒ `url` * unchanged (or `null` when `url` itself was nullish). */ export function withPreviewToken( url: string | null | undefined, token: string | null | undefined, ): string | null; /** Mirrors `apps/preview-host/src/index.ts`'s `PREVIEW_COOKIE` — see go-live.js's header. */ export const PREVIEW_COOKIE_NAME: string; /** #885 P1-3 — a tool's own short-lived preview token TTL, in seconds. See go-live.js. */ export const PREVIEW_TOOL_TOKEN_TTL_SECONDS: number; /** The `Cookie:` header value for a server-side fetch against an owned preview-host address, or * `null` with no token — see go-live.js's header for why this exists alongside `withPreviewToken`. */ export function previewCookieHeader(token: string | null | undefined): string | null; /** * Stamp a minted share token onto a `previewAddressFor`/`siteAddress`-shaped object's * `reachableAt`, adding `previewUrlExpiresAt` and extending `previewUrlNote` — the ONE place * `build_preview`, `list_sites` and `create_site` do this. A no-op on anything not owned, or with * no `reachableAt`. `minted: null` reports a failed mint (bare address, a note saying so); it is * the CALLER's job to decide whether to attempt a mint at all (gate on `previewOwned`). */ export function applyPreviewShareToken( addr: T, minted: { token: string; expiresAt: string } | null, ): T; /** Whether the allowlist write for this site has landed. Fails closed on anything but true/stamp. */ export function previewRegisteredFrom(site?: SiteAddressInput): boolean; /** THE ONE PLACE the owned preview address is derived. Never throws — read paths call it. */ export function previewAddressFor( site?: SiteAddressInput, options?: PreviewAddressOptions, ): PreviewAddress; export function siteAddress( site?: SiteAddressInput, options?: PreviewAddressOptions, ): PreviewAddress & { state: | "preview-only" | "named" | "awaiting-dns" | "recorded-not-served" | "bound-unreachable" | "live"; intended?: string; /** The bound host, NAMED but not linked — `bound-unreachable` only. A live url would be a lie. */ host?: string; live?: string; note?: string; }; /** The door's flat `note` + `previewUrlNote`/`previewNote` cut to one line — see `compactSiteRow`'s * own header. `address.note` is NOT cut to it (🩸 R9): this limit is what severed its verb. */ export const LIST_SITES_NOTE_LIMIT: number; /** * `list_sites`' lean default (AX-442) — collapses a site row's duplicated facts (the preview URL * repeated as `preview`/`previewUrl`/`address.reachableAt`, `previewUrlNote` repeated at the top * level and inside `address`, …) into one occurrence apiece, and merges the flat `note` + * `previewUrlNote`/`previewNote` into a single `note` cut to `noteLimit` characters. `address` * keeps `state`/`intended`/`note` — the facts no flat field states, `address.note` uncut (🩸 R9). * Pure post-processing over a row the caller already built — see go-live.js's own header for * exactly what it drops. It also drops the owner's own `display_name`/`agent_guidance` and no * longer derives `name`: those leave every row for the top-level maps `siteOwnerText` builds (#47). */ export function compactSiteRow( row: Record, options?: { noteLimit?: number }, ): Record; /** * The owner's own words for these rows, keyed by each row's `key` — one top-level map per field the * calling door can produce, emitted even when empty. `derivedName` adds the lean shape's `name` * map (`display_name ?? domain ?? key`). See go-live.js for why the shape moved. */ export function siteOwnerText( rows: Record[], options?: { fields?: readonly string[]; derivedName?: boolean }, ): Record>; /** Hoist identical complete notes once; preserve per-site notes when they differ. Also lifts the * owner's own text out of every row into the top-level maps above (#47) — `ownerTextFields` names * the ones THIS door can produce. */ export function compactSiteList( rows: Record[], options?: { verbose?: boolean; ownerTextFields?: readonly string[] }, ): { sites: Record[]; name?: Record; display_name?: Record; agent_guidance?: Record; _notes?: { previewUrl: string }; }; /** #1300 P2-1 — RSP goLive refusals that undo the Cloudflare attach. */ export const REGISTRY_BIND_REFUSALS: readonly string[]; export function registryRefusalCode(error: unknown): string | null; export function bindOrDetach(args: { bind: () => Promise; detach: () => Promise; host?: string; project?: string; log?: (message: string) => void; }): Promise;