{"version":3,"file":"cli.cjs","names":[],"sources":["../../src/router/route-scanner.ts","../../src/island/scan.ts","../../src/island/generate-entry.ts","../../src/render/ssr-flag.ts","../../src/render/render-to-string.ts","../../src/build/document-shell.ts","../../src/action/error-store.ts","../../src/cache/policy.ts","../../src/ssr/render.ts","../../src/action/scan.ts","../../src/image/service.ts","../../src/integrations/index.ts","../../src/build/build.ts","../../src/vite/interpolation-plugin.ts","../../src/build/transform-source.ts","../../src/errors.ts","../../src/action/origin.ts","../../src/action/server.ts","../../src/cache.ts","../../src/ssr/match.ts","../../src/ssr/stream.ts","../../src/middleware/index.ts","../../src/runtime/node-http.ts","../../src/runtime/static.ts","../../src/ssr/server.ts","../../src/config/index.ts","../../src/manifest/index.ts","../../src/runtime/capabilities.ts","../../src/build/vite-build.ts","../../src/runtime/context.ts","../../src/runtime/security-headers.ts","../../src/runtime/handler.ts","../../src/adapters/shared.ts","../../src/adapters/vercel.ts","../../src/adapters/netlify.ts","../../src/adapters/bun.ts","../../src/adapters/node.ts","../../src/cli/commands.ts","../../src/cli.ts"],"sourcesContent":["import { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\n// --- Route scanner ---\n//\n// Walks src/app/ and maps file conventions to URL paths.\n//\n// Supported conventions:\n//   - page.ts          -> URL path\n//   - page.data.ts     -> loader for that page\n//   - layout.ts        -> layout wrapping pages in the same segment\n//   - route.ts         -> API endpoint (collected separately)\n//\n// Dynamic segments:\n//   - [slug]           -> :slug\n//   - [...slug]        -> catch-all (rendered as :slug*)\n//   - [[...slug]]      -> optional catch-all (rendered as :slug* but matches\n//                         the base path too)\n//\n// Route conflicts (two routes with the same path pattern) cause an error\n// during scanRoutes (plan §11.1).\n\n/** A page route discovered by the scanner. */\nexport interface PageRoute {\n  /** URL path, e.g. \"/blog/:slug\". */\n  path: string;\n  /** File system path to the page.ts module. */\n  pagePath: string;\n  /** File system path to the page.data.ts module, if any. */\n  dataPath?: string;\n  /** File system path to the page.action.ts module, if any. */\n  actionPath?: string;\n  /** Ordered list of layout.ts modules from root to leaf. */\n  layouts: string[];\n  /** File system path to the loading.ts module, if any. */\n  loadingPath?: string;\n  /** Dynamic parameter names extracted from the path. */\n  params: string[];\n  /** Whether the route has an optional catch-all segment. */\n  optionalCatchAll?: boolean;\n  /**\n   * Named slot modules discovered in the same directory as the page.\n   * Keyed by slot name (filename without `.slot.ts` suffix).\n   * (v2.1 — Fix #2: Layout Slots)\n   */\n  slots?: Record<string, string>;\n}\n\n/** An API route discovered by the scanner. */\nexport interface ApiRoute {\n  /** URL path, e.g. \"/api/posts\". */\n  path: string;\n  /** File system path to the route.ts module. */\n  routePath: string;\n  /** Dynamic parameter names extracted from the path. */\n  params: string[];\n}\n\n/** Result of scanning the app directory. */\nexport interface ScannedRoutes {\n  pages: PageRoute[];\n  api: ApiRoute[];\n  /** Optional 404 error page. */\n  error404?: PageRoute;\n  /** Optional 500 error page. */\n  error500?: PageRoute;\n}\n\nfunction isRouteGroup(segment: string): boolean {\n  return segment.startsWith(\"(\") && segment.endsWith(\")\");\n}\n\nfunction segmentToUrl(segment: string): string {\n  // Optional catch-all: [[...slug]] -> :slug* (matches base path too)\n  if (segment.startsWith(\"[[...\") && segment.endsWith(\"]]\")) {\n    return `:${segment.slice(5, -2)}*`;\n  }\n  // Catch-all: [...slug] -> :slug*\n  if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n    return `:${segment.slice(4, -1)}*`;\n  }\n  // Dynamic: [slug] -> :slug\n  if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n    return `:${segment.slice(1, -1)}`;\n  }\n  return segment;\n}\n\nfunction extractParams(segment: string): string[] {\n  if (segment.startsWith(\"[[...\") && segment.endsWith(\"]]\")) {\n    return [segment.slice(5, -2)];\n  }\n  if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n    return [segment.slice(4, -1)];\n  }\n  if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n    return [segment.slice(1, -1)];\n  }\n  return [];\n}\n\nfunction isOptionalCatchAll(segment: string): boolean {\n  return segment.startsWith(\"[[...\") && segment.endsWith(\"]]\");\n}\n\nasync function collectFiles(dir: string): Promise<string[]> {\n  try {\n    const entries = await readdir(dir, { withFileTypes: true });\n    return entries\n      .filter((e) => e.isFile() && e.name.endsWith(\".ts\"))\n      .map((e) => e.name);\n  } catch {\n    return [];\n  }\n}\n\nasync function collectDirs(dir: string): Promise<string[]> {\n  try {\n    const entries = await readdir(dir, { withFileTypes: true });\n    return entries.filter((e) => e.isDirectory()).map((e) => e.name);\n  } catch {\n    return [];\n  }\n}\n\nasync function scanRecursive(\n  appDir: string,\n  currentDir: string,\n  urlSegments: string[],\n  params: string[],\n  layouts: string[],\n  result: ScannedRoutes,\n  hasOptionalCatchAll = false,\n): Promise<void> {\n  const files = await collectFiles(currentDir);\n  const dirs = await collectDirs(currentDir);\n\n  const pagePath = files.includes(\"page.ts\")\n    ? join(currentDir, \"page.ts\")\n    : undefined;\n  const dataPath = files.includes(\"page.data.ts\")\n    ? join(currentDir, \"page.data.ts\")\n    : undefined;\n  const actionPath = files.includes(\"page.action.ts\")\n    ? join(currentDir, \"page.action.ts\")\n    : undefined;\n  const loadingPath = files.includes(\"loading.ts\")\n    ? join(currentDir, \"loading.ts\")\n    : undefined;\n  const layoutPath = files.includes(\"layout.ts\")\n    ? join(currentDir, \"layout.ts\")\n    : undefined;\n  const routePath = files.includes(\"route.ts\")\n    ? join(currentDir, \"route.ts\")\n    : undefined;\n\n  const currentLayouts = layoutPath\n    ? [...layouts, layoutPath]\n    : [...layouts];\n\n  if (routePath) {\n    result.api.push({\n      path: urlSegments.length === 0 ? \"/\" : \"/\" + urlSegments.join(\"/\"),\n      routePath,\n      params: [...params],\n    });\n  }\n\n  if (pagePath) {\n    const path = urlSegments.length === 0 ? \"/\" : \"/\" + urlSegments.join(\"/\");\n    // Detect named slot files: *.slot.ts (v2.1 — Fix #2: Layout Slots)\n    const slots: Record<string, string> = {};\n    for (const file of files) {\n      const slotMatch = file.match(/^(.+)\\.slot\\.ts$/);\n      if (slotMatch) {\n        slots[slotMatch[1]] = join(currentDir, file);\n      }\n    }\n    result.pages.push({\n      path,\n      pagePath,\n      dataPath,\n      actionPath,\n      layouts: currentLayouts,\n      loadingPath,\n      params: [...params],\n      optionalCatchAll: hasOptionalCatchAll,\n      slots: Object.keys(slots).length > 0 ? slots : undefined,\n    });\n  }\n\n  for (const dir of dirs) {\n    if (isRouteGroup(dir)) {\n      // Route groups do not add a URL segment, but they can add a layout.\n      const groupDir = join(currentDir, dir);\n      const groupFiles = await collectFiles(groupDir);\n      const groupLayout = groupFiles.includes(\"layout.ts\")\n        ? join(groupDir, \"layout.ts\")\n        : undefined;\n      await scanRecursive(\n        appDir,\n        groupDir,\n        urlSegments,\n        params,\n        groupLayout ? [...currentLayouts, groupLayout] : currentLayouts,\n        result,\n      );\n      continue;\n    }\n\n    const optional = isOptionalCatchAll(dir);\n    await scanRecursive(\n      appDir,\n      join(currentDir, dir),\n      [...urlSegments, segmentToUrl(dir)],\n      [...params, ...extractParams(dir)],\n      currentLayouts,\n      result,\n      optional,\n    );\n  }\n}\n\n/**\n * Scans an app directory for Nix.js Kit file-based routes.\n *\n * @param appDir Absolute path to the app directory (e.g. \"src/app\").\n * @returns Discovered page and API routes.\n */\nexport async function scanRoutes(appDir: string): Promise<ScannedRoutes> {\n  const result: ScannedRoutes = { pages: [], api: [] };\n  const rootFiles = await collectFiles(appDir);\n  const rootLayout = rootFiles.includes(\"layout.ts\")\n    ? join(appDir, \"layout.ts\")\n    : undefined;\n\n  if (rootFiles.includes(\"404.page.ts\")) {\n    result.error404 = {\n      path: \"/404\",\n      pagePath: join(appDir, \"404.page.ts\"),\n      dataPath: rootFiles.includes(\"404.page.data.ts\")\n        ? join(appDir, \"404.page.data.ts\")\n        : undefined,\n      layouts: rootLayout ? [rootLayout] : [],\n      params: [],\n    };\n  }\n\n  if (rootFiles.includes(\"500.page.ts\")) {\n    result.error500 = {\n      path: \"/500\",\n      pagePath: join(appDir, \"500.page.ts\"),\n      dataPath: rootFiles.includes(\"500.page.data.ts\")\n        ? join(appDir, \"500.page.data.ts\")\n        : undefined,\n      layouts: rootLayout ? [rootLayout] : [],\n      params: [],\n    };\n  }\n\n  await scanRecursive(appDir, appDir, [], [], [], result);\n\n  // Detect route conflicts (plan §11.1): two routes with the same path\n  // pattern is an error during manifest generation.\n  detectRouteConflicts(result);\n\n  return result;\n}\n\n/**\n * Detects and throws on route conflicts (plan §11.1, runtime-security §10).\n * Two routes with the same path pattern cause an error.\n */\nfunction detectRouteConflicts(routes: ScannedRoutes): void {\n  const pagePaths = new Map<string, string>();\n  for (const page of routes.pages) {\n    const existing = pagePaths.get(page.path);\n    if (existing) {\n      throw new Error(\n        `[nix-js-kit] Route conflict: \"${page.path}\" is defined by both ` +\n        `\"${existing}\" and \"${page.pagePath}\". ` +\n        `Remove one of the conflicting page.ts files.`,\n      );\n    }\n    pagePaths.set(page.path, page.pagePath);\n  }\n\n  // Also check API route conflicts.\n  const apiPaths = new Map<string, string>();\n  for (const api of routes.api) {\n    const existing = apiPaths.get(api.path);\n    if (existing) {\n      throw new Error(\n        `[nix-js-kit] API route conflict: \"${api.path}\" is defined by both ` +\n        `\"${existing}\" and \"${api.routePath}\".`,\n      );\n    }\n    apiPaths.set(api.path, api.routePath);\n  }\n}\n","import { readdir } from \"node:fs/promises\";\nimport type { Dirent } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\n\n// --- Island scanner ---\n//\n// Walks `src/islands/` and lists every island component module. Each `.ts`\n// file (recursively) is treated as one island whose name is derived from its\n// path relative to the islands root:\n//\n//   src/islands/LikeButton.ts        -> \"LikeButton\"\n//   src/islands/nav/MobileMenu.ts    -> \"nav/MobileMenu\"\n//\n// The name must match the first argument passed to `island(name, ...)` on the\n// server so the client registry can look the component up during hydration.\n\n/** A single island component discovered by the scanner. */\nexport interface IslandModule {\n  /** Registry name, derived from the path relative to the islands dir. */\n  name: string;\n  /** Absolute file system path to the island module. */\n  filePath: string;\n}\n\nasync function walk(dir: string): Promise<string[]> {\n  let entries: Dirent<string>[];\n  try {\n    entries = (await readdir(dir, {\n      withFileTypes: true,\n      encoding: \"utf8\",\n    })) as Dirent<string>[];\n  } catch {\n    return [];\n  }\n\n  const files: string[] = [];\n  for (const entry of entries) {\n    const full = join(dir, entry.name);\n    if (entry.isDirectory()) {\n      files.push(...(await walk(full)));\n    } else if (\n      entry.isFile() &&\n      entry.name.endsWith(\".ts\") &&\n      !entry.name.endsWith(\".d.ts\") &&\n      !entry.name.endsWith(\".test.ts\")\n    ) {\n      files.push(full);\n    }\n  }\n  return files;\n}\n\nfunction toIslandName(islandsDir: string, filePath: string): string {\n  return relative(islandsDir, filePath)\n    .replace(/\\.ts$/, \"\")\n    .split(sep)\n    .join(\"/\");\n}\n\n/**\n * Scans an islands directory for island component modules.\n *\n * @param islandsDir Absolute path to the islands directory (e.g. \"src/islands\").\n * @returns Discovered island modules, sorted by name.\n */\nexport async function scanIslands(islandsDir: string): Promise<IslandModule[]> {\n  const files = await walk(islandsDir);\n  return files\n    .map((filePath) => ({ name: toIslandName(islandsDir, filePath), filePath }))\n    .sort((a, b) => a.name.localeCompare(b.name));\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, relative, sep } from \"node:path\";\nimport type { IslandModule } from \"./scan.js\";\n\n// --- Client entry generator ---\n//\n// Turns a list of scanned islands into a client entry module that imports each\n// island and registers it with `hydrateIslands`. This removes the need to hand-\n// maintain `entry-client.ts` as islands are added or removed.\n//\n// The generated file imports island default exports and passes them to\n// `hydrateIslands` keyed by their registry name.\n\n/** Options for generating the client entry module. */\nexport interface GenerateEntryOptions {\n  /** Islands to register, from `scanIslands`. */\n  islands: IslandModule[];\n  /** Absolute path of the entry file to write (e.g. \".nix-js/entry-client.ts\"). */\n  outFile: string;\n  /**\n   * Import specifier for the kit's client island helpers.\n   * Defaults to the published subpath `@deijose/nix-js-kit/island`.\n   */\n  hydrateImport?: string;\n  /**\n   * Import specifier for the kit's client router.\n   * Defaults to the published subpath `@deijose/nix-js-kit/router`.\n   */\n  routerImport?: string;\n}\n\n/** Turns a registry name into a safe JS identifier for the import binding. */\nfunction toIdentifier(name: string, index: number): string {\n  const cleaned = name.replace(/[^a-zA-Z0-9_$]/g, \"_\");\n  return /^[a-zA-Z_$]/.test(cleaned) ? `${cleaned}_${index}` : `_${cleaned}_${index}`;\n}\n\n/** Builds the source code of the client entry module. */\nexport function buildEntrySource(\n  islands: IslandModule[],\n  outFile: string,\n  hydrateImport = \"@deijose/nix-js-kit/island\",\n  routerImport = \"@deijose/nix-js-kit/router\",\n): string {\n  const bindings = islands.map((island, i) => ({\n    ident: toIdentifier(island.name, i),\n    name: island.name,\n    // Relative import specifier from the entry file to the island module.\n    spec: toImportSpecifier(outFile, island.filePath),\n  }));\n\n  // Lazy registry: each island is loaded on-demand via dynamic import().\n  // This enables code-splitting — islands not on the current page (or not yet\n  // triggered by their directive) stay out of the initial bundle.\n  //\n  // The registry maps island name → discriminated lazy loader `{ load }`.\n  // hydrateIslands() awaits `entry.load()` before hydrating, so the first\n  // paint only needs the small entry chunk + the islands on the page. The\n  // discriminated form lets the hydrator tell eager components from lazy\n  // loaders without executing a probe.\n  const registryLines = bindings\n    .map((b) => `  ${JSON.stringify(b.name)}: { load: () => import(${JSON.stringify(b.spec)}).then(m => m.default) },`)\n    .join(\"\\n\");\n\n  const islandHydration = registryLines\n    ? `const registry = {\n${registryLines}\n};\nhydrateIslands(registry);\ndocument.addEventListener(\"nix-js:rendered\", () => {\n  cleanupHydratedIslands();\n  hydrateIslands(registry);\n});\n\n// Vite HMR: when an island module (or the entry itself) updates, dispose the\n// current islands and re-hydrate from the updated modules — the registry's\n// dynamic import() resolves to the fresh modules, so no full page reload is\n// needed (progressive enhancement, audit §10.2 / §12.2).\nif (import.meta.hot) {\n  import.meta.hot.accept((newModule) => {\n    cleanupHydratedIslands();\n    hydrateIslands(registry);\n    if (newModule) {\n      // Re-run the module so its side effects (router, listeners) apply.\n    }\n  });\n}`\n    : \"\";\n\n  return `// AUTO-GENERATED by @deijose/nix-js-kit. Do not edit.\nimport { startClientRouter } from ${JSON.stringify(routerImport)};\nimport { hydrateIslands, cleanupHydratedIslands } from ${JSON.stringify(hydrateImport)};\n\nstartClientRouter();\n${islandHydration}\n`;\n}\n\n/** Computes a POSIX-style relative import specifier between two files. */\nfunction toImportSpecifier(fromFile: string, toFile: string): string {\n  let spec = relative(dirname(fromFile), toFile).split(sep).join(\"/\");\n  if (!spec.startsWith(\".\")) spec = `./${spec}`;\n  return spec;\n}\n\n/**\n * Generates and writes the client entry module for the given islands.\n *\n * @param options Generation options.\n * @returns The absolute path of the written entry file.\n */\nexport async function generateClientEntry(\n  options: GenerateEntryOptions,\n): Promise<string> {\n  const source = buildEntrySource(\n    options.islands,\n    options.outFile,\n    options.hydrateImport,\n    options.routerImport,\n  );\n  await mkdir(dirname(options.outFile), { recursive: true });\n  await writeFile(options.outFile, source, \"utf8\");\n  return options.outFile;\n}\n","// --- SSR flag utility ---\n//\n// Nix.js 2.6.0 (published on npm) does not export `_setSSR`/`_isSSR`. The\n// reactivity state lives on `globalThis[Symbol.for(\"@deijose/nix-js/reactivity-state\")]`\n// and exposes an `ssr` boolean that, when true, makes effects run a single\n// pass without subscribing — exactly what we need during server rendering.\n//\n// This module manipulates that flag directly so the kit does not depend on\n// private exports that may or may not be present in a given nix-js release.\n\nconst STATE_KEY = Symbol.for(\"@deijose/nix-js/reactivity-state\");\n\ntype ReactivityState = { ssr: boolean };\n\nfunction getState(): ReactivityState | undefined {\n  return (globalThis as Record<symbol, unknown>)[STATE_KEY] as\n    | ReactivityState\n    | undefined;\n}\n\n/** Sets the SSR flag on the Nix.js reactivity state. No-op if state is absent. */\nexport function setSSR(value: boolean): void {\n  const state = getState();\n  if (state) state.ssr = value;\n}\n\n/** Reads the SSR flag from the Nix.js reactivity state. Defaults to false. */\nexport function isSSR(): boolean {\n  return getState()?.ssr ?? false;\n}\n","import type { NixTemplate } from \"@deijose/nix-js\";\nimport { renderToString as renderCoreTemplate } from \"@deijose/nix-js/server\";\nimport { setSSR } from \"./ssr-flag\";\n\n// --- Build-time / server rendering ---\n//\n// The Nix.js core ships a DOM-free `renderToString` (`@deijose/nix-js/server`)\n// that streams template output without ever touching a `document`. The kit used\n// to inject a Node-side DOM (happy-dom) as a fallback for legacy compatibility;\n// that fallback has been removed together with the happy-dom dependency.\n\n/**\n * Renders a Nix.js template to an HTML string in Node.\n *\n * Accepts a *factory* (not a template) because `html`` evaluates at call time.\n *\n * @param factory Thunk that builds the template, e.g. `() => Page({ data })`.\n * @returns Serialized HTML of the rendered template.\n */\nexport async function renderToString(\n  factory: () => NixTemplate,\n  options: { markers?: \"none\" | \"hydration\" } = {},\n): Promise<string> {\n  setSSR(true);\n  try {\n    return await renderCoreTemplate(factory(), {\n      markers: options.markers ?? \"hydration\",\n    });\n  } finally {\n    setSSR(false);\n  }\n}\n","//\n// The <!DOCTYPE>, <head> and <body> wrapper — plus the serialized loader data\n// and the client entry — are injected here at build time.\n\nimport type { PageMetadata } from \"../types.js\";\nexport interface ShellOptions {\n  /** Rendered inner HTML that goes inside `#app`. */\n  body: string;\n  /** `<title>` text. */\n  title?: string;\n  /** `<html lang>` attribute. */\n  lang?: string;\n  /** Additional attributes for the `<html>` element, e.g. `{ \"data-theme\": \"dark\" }`. */\n  htmlAttributes?: Record<string, string>;\n  /**\n   * Inline scripts injected into `<head>`. They run synchronously while the\n   * document parses — before the first paint and before the (deferred) client\n   * bundle — so they are the right place for no-flash bootstrapping (e.g.\n   * applying a stored theme before the page becomes visible).\n   */\n  headScripts?: string[];\n  /**\n   * Raw HTML strings injected into `<head>` — e.g. `<link rel=\"icon\">`,\n   * `<link rel=\"manifest\">`, `<meta name=\"theme-color\">`. Each string is\n   * rendered as-is inside `<head>`.\n   */\n  headLinks?: string[];\n  /** Loader data serialized into `<script id=\"nix-js-data\">`. */\n  data?: unknown;\n  /** Per-page action names serialized into `<script id=\"nix-js-actions\">`. */\n  actions?: Record<string, string[]>;\n  /** Path to the client entry module, e.g. `/_nix-js/entry-client.js`. */\n  clientEntry?: string;\n  /** Page metadata emitted as `<meta>`, `<link>` and OG/Twitter tags in `<head>`. */\n  metadata?: PageMetadata;\n  /**\n   * Whether the SSR render endpoint (`/__nix-js/render`) is available at\n   * runtime. Defaults to `true`. When `false` (static deployments), the shell\n   * emits `<meta name=\"nix-js:render-endpoint\" content=\"off\" />` so the client\n   * router skips probing the endpoint entirely — preventing a storm of 404\n   * requests on fully static sites.\n   */\n  renderEndpoint?: boolean;\n}\n\nconst HTML_ESCAPES: Record<string, string> = {\n  \"&\": \"&amp;\",\n  \"<\": \"&lt;\",\n  \">\": \"&gt;\",\n  '\"': \"&quot;\",\n  \"'\": \"&#39;\",\n};\n\nfunction escapeHtml(value: string): string {\n  return value.replace(/[&<>\"']/g, (c) => HTML_ESCAPES[c]);\n}\n\n/**\n * Serializes data for embedding inside a `<script>` tag. Escapes `<` so a\n * `</script>` sequence in the data cannot break out of the tag.\n */\nfunction serializeData(data: unknown): string {\n  return JSON.stringify(data ?? null).replace(/</g, \"\\\\u003c\");\n}\n\n/**\n * Builds the `<head>` tags for a `PageMetadata` object. Every tag is marked with\n * `data-nix-js-head` so the client-side router can replace them on navigation\n * without touching charset/viewport or user-supplied `headScripts`.\n */\nexport function buildHeadTags(metadata: PageMetadata, fallbackTitle: string): string {\n  const tags: string[] = [];\n  const title = metadata.title ?? fallbackTitle;\n  if (metadata.title) {\n    tags.push(`<title data-nix-js-head>${escapeHtml(title)}</title>`);\n  }\n\n  if (metadata.description) {\n    tags.push(`<meta data-nix-js-head name=\"description\" content=\"${escapeHtml(metadata.description)}\" />`);\n  }\n\n  if (metadata.canonical) {\n    tags.push(`<link data-nix-js-head rel=\"canonical\" href=\"${escapeHtml(metadata.canonical)}\" />`);\n  }\n\n  if (metadata.robots) {\n    tags.push(`<meta data-nix-js-head name=\"robots\" content=\"${escapeHtml(metadata.robots)}\" />`);\n  }\n\n  const og = metadata.openGraph;\n  if (og) {\n    if (og.type) tags.push(`<meta data-nix-js-head property=\"og:type\" content=\"${escapeHtml(og.type)}\" />`);\n    tags.push(`<meta data-nix-js-head property=\"og:title\" content=\"${escapeHtml(og.title ?? title)}\" />`);\n    if (og.description ?? metadata.description) {\n      tags.push(`<meta data-nix-js-head property=\"og:description\" content=\"${escapeHtml(og.description ?? metadata.description!)}\" />`);\n    }\n    if (og.url ?? metadata.canonical) {\n      tags.push(`<meta data-nix-js-head property=\"og:url\" content=\"${escapeHtml(og.url ?? metadata.canonical!)}\" />`);\n    }\n    if (og.image) tags.push(`<meta data-nix-js-head property=\"og:image\" content=\"${escapeHtml(og.image)}\" />`);\n    if (og.image && og.imageAlt) tags.push(`<meta data-nix-js-head property=\"og:image:alt\" content=\"${escapeHtml(og.imageAlt)}\" />`);\n    if (og.image && og.imageWidth) tags.push(`<meta data-nix-js-head property=\"og:image:width\" content=\"${String(og.imageWidth)}\" />`);\n    if (og.image && og.imageHeight) tags.push(`<meta data-nix-js-head property=\"og:image:height\" content=\"${String(og.imageHeight)}\" />`);\n    if (og.image && og.imageType) tags.push(`<meta data-nix-js-head property=\"og:image:type\" content=\"${escapeHtml(og.imageType)}\" />`);\n    if (og.siteName) tags.push(`<meta data-nix-js-head property=\"og:site_name\" content=\"${escapeHtml(og.siteName)}\" />`);\n    if (og.locale) tags.push(`<meta data-nix-js-head property=\"og:locale\" content=\"${escapeHtml(og.locale)}\" />`);\n  }\n\n  const tw = metadata.twitter;\n  if (tw) {\n    if (tw.card) tags.push(`<meta data-nix-js-head name=\"twitter:card\" content=\"${escapeHtml(tw.card)}\" />`);\n    if (tw.title ?? title) tags.push(`<meta data-nix-js-head name=\"twitter:title\" content=\"${escapeHtml(tw.title ?? title)}\" />`);\n    if (tw.description ?? metadata.description) {\n      tags.push(`<meta data-nix-js-head name=\"twitter:description\" content=\"${escapeHtml(tw.description ?? metadata.description!)}\" />`);\n    }\n    if (tw.image) tags.push(`<meta data-nix-js-head name=\"twitter:image\" content=\"${escapeHtml(tw.image)}\" />`);\n    if (tw.image && tw.imageAlt) tags.push(`<meta data-nix-js-head name=\"twitter:image:alt\" content=\"${escapeHtml(tw.imageAlt)}\" />`);\n  }\n\n  if (metadata.other) {\n    for (const [name, content] of Object.entries(metadata.other)) {\n      tags.push(`<meta data-nix-js-head name=\"${escapeHtml(name)}\" content=\"${escapeHtml(content)}\" />`);\n    }\n  }\n\n  return tags.map((t) => `\\n    ${t}`).join(\"\");\n}\n\n/** Wraps rendered body HTML into a full HTML document. */\nexport function documentShell(opts: ShellOptions): string {\n  const { body, title = \"Nix.js Kit App\", lang = \"es\", data, actions, clientEntry, htmlAttributes, headScripts, headLinks, metadata } = opts;\n\n  const dataScript =\n    data !== undefined\n      ? `\\n    <script type=\"application/json\" id=\"nix-js-data\">${serializeData(data)}</script>`\n      : \"\";\n\n  const actionsScript = actions && Object.keys(actions).length > 0\n    ? `\\n    <script type=\"application/json\" id=\"nix-js-actions\">${serializeData(actions)}</script>`\n    : \"\";\n\n  const entryScript = clientEntry\n    ? `\\n    <script type=\"module\" src=\"${escapeHtml(clientEntry)}\"></script>`\n    : \"\";\n\n  const htmlAttrs = htmlAttributes\n    ? Object.entries(htmlAttributes)\n      .filter(([, value]) => value !== undefined && value !== null && value !== \"\")\n      .map(([key, value]) => ` ${escapeHtml(key)}=\"${escapeHtml(String(value))}\"`)\n      .join(\"\")\n    : \"\";\n\n  const headScriptsHtml = headScripts\n    ? headScripts\n      .filter((script) => typeof script === \"string\" && script.trim().length > 0)\n      .map((script) => {\n        // If the script is already a complete <script> tag (e.g. JSON-LD),\n        // render it as-is without wrapping.\n        if (script.trimStart().startsWith(\"<script\")) {\n          return `\\n    ${script}`;\n        }\n        return `\\n    <script>${script.replace(/<\\/script>/gi, \"<\\\\/script>\")}</script>`;\n      })\n      .join(\"\")\n    : \"\";\n\n  const headTags = metadata ? buildHeadTags(metadata, title) : \"\";\n  const titleTag = metadata?.title\n    ? \"\" // already emitted by buildHeadTags\n    : `\\n    <title>${escapeHtml(title)}</title>`;\n\n  const headLinksHtml = headLinks\n    ? headLinks\n      .filter((link) => typeof link === \"string\" && link.trim().length > 0)\n      .map((link) => `\\n    ${link}`)\n      .join(\"\")\n    : \"\";\n\n  const renderEndpointMeta =\n    opts.renderEndpoint === false\n      ? '\\n    <meta name=\"nix-js:render-endpoint\" content=\"off\" />'\n      : \"\";\n\n  return `<!DOCTYPE html>\n<html lang=\"${escapeHtml(lang)}\"${htmlAttrs}>\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />${renderEndpointMeta}${titleTag}${headTags}${headLinksHtml}${headScriptsHtml}\n  </head>\n  <body>\n    <div id=\"app\">${body}</div>${dataScript}${actionsScript}${entryScript}\n  </body>\n</html>\n`;\n}\n","// --- Ephemeral action error store ---\n//\n// Action failures submitted via plain HTML forms (progressive enhancement)\n// need to be relayed back to the page so the user sees validation errors.\n//\n// Previously the failure data was serialized into a `?__nix_js_action_error=`\n// query param on the redirect. That leaks errors into browser history,\n// server logs and third-party Referer headers.\n//\n// Now we stash the failure in a short-lived in-memory store keyed by a random\n// id, set a small cookie `__nix_js_action_error=<id>` (Max-Age=15s, SameSite=Lax),\n// and the next render reads the cookie, fetches the payload, exposes it as\n// `props.form`, and clears the entry.\n//\n// The store is process-local, which is fine for the single-process SSR server\n// and the dev server. For multi-instance deployments the cookie carries the\n// payload directly when it fits (see `encodeActionErrorCookie`); the store is\n// only the overflow path for large payloads.\n\nimport { createHmac, randomBytes, timingSafeEqual } from \"node:crypto\";\n\nconst COOKIE_NAME = \"__nix_js_action_error\";\nconst MAX_COOKIE_SIZE = 3500; // bytes; leaves headroom under the 4KB cookie limit\nconst TTL_MS = 15_000;\n\n// HMAC key for signing action error cookies. In production this should be\n// set via NIX_JS_ACTION_SECRET env var; otherwise we derive a per-process\n// key (sufficient for single-process dev/preview, but NOT for multi-instance).\nconst ACTION_SECRET =\n  process.env.NIX_JS_ACTION_SECRET ?? randomBytes(32).toString(\"hex\");\n\ninterface StoredError {\n  data: unknown;\n  status: number;\n  expiresAt: number;\n}\n\nconst store = new Map<string, StoredError>();\n\n// Periodically purge expired entries so the map does not grow unbounded.\nlet sweepScheduled = false;\nfunction scheduleSweep(): void {\n  if (sweepScheduled) return;\n  sweepScheduled = true;\n  setTimeout(() => {\n    sweepScheduled = false;\n    const now = Date.now();\n    for (const [key, entry] of store) {\n      if (entry.expiresAt <= now) store.delete(key);\n    }\n  }, TTL_MS).unref?.();\n}\n\n/**\n * Signs a payload with HMAC-SHA256 using the action secret.\n * Returns `signature.payload` (both hex/base64url).\n */\nfunction sign(payload: string): string {\n  const sig = createHmac(\"sha256\", ACTION_SECRET).update(payload).digest(\"hex\");\n  return `${sig}.${payload}`;\n}\n\n/**\n * Verifies a signed value and returns the payload if valid, or undefined.\n * Uses timingSafeEqual to prevent timing attacks.\n */\nfunction verify(value: string): string | undefined {\n  const dotIndex = value.indexOf(\".\");\n  if (dotIndex === -1) return undefined;\n  const sig = value.slice(0, dotIndex);\n  const payload = value.slice(dotIndex + 1);\n  const expectedSig = createHmac(\"sha256\", ACTION_SECRET).update(payload).digest(\"hex\");\n  if (sig.length !== expectedSig.length) return undefined;\n  try {\n    if (timingSafeEqual(Buffer.from(sig), Buffer.from(expectedSig))) {\n      return payload;\n    }\n  } catch {\n    // Length mismatch — invalid.\n  }\n  return undefined;\n}\n\n/**\n * Encodes an action failure for the redirect cookie. When the payload fits\n * inside the cookie limit, it is embedded directly as a signed base64url JSON\n * value. When it is too large, it is stored in memory and only a short signed\n * id is written to the cookie.\n *\n * The cookie is signed with HMAC-SHA256 to prevent forgery (A-20).\n *\n * @returns The cookie value to set on the redirect response.\n */\nexport function encodeActionErrorCookie(\n  data: unknown,\n  status: number,\n): { value: string; storeId?: string } {\n  const payload = JSON.stringify({ d: data, s: status });\n  const encoded = Buffer.from(payload, \"utf8\").toString(\"base64url\");\n  const signed = sign(encoded);\n  if (signed.length <= MAX_COOKIE_SIZE) {\n    return { value: signed };\n  }\n\n  // Overflow: stash in memory and reference by signed id.\n  const id = randomBytes(12).toString(\"hex\");\n  store.set(id, { data, status, expiresAt: Date.now() + TTL_MS });\n  scheduleSweep();\n  return { value: sign(`id:${id}`), storeId: id };\n}\n\n/**\n * Decodes a cookie value (previously produced by `encodeActionErrorCookie`)\n * into the failure payload. Verifies the HMAC signature first, then resolves\n * in-memory overflow entries and deletes them after reading.\n */\nexport function decodeActionErrorCookie(value: string | undefined | null):\n  | { data: unknown; status: number }\n  | undefined {\n  if (!value) return undefined;\n\n  // Verify signature first.\n  const verifiedPayload = verify(value);\n  if (verifiedPayload === undefined) return undefined;\n\n  // Check if it's an in-memory store reference.\n  if (verifiedPayload.startsWith(\"id:\")) {\n    const id = verifiedPayload.slice(3);\n    const entry = store.get(id);\n    if (!entry) return undefined;\n    store.delete(id);\n    if (entry.expiresAt <= Date.now()) return undefined;\n    return { data: entry.data, status: entry.status };\n  }\n\n  try {\n    const json = Buffer.from(verifiedPayload, \"base64url\").toString(\"utf8\");\n    const parsed = JSON.parse(json) as { d: unknown; s: number };\n    return { data: parsed.d, status: parsed.s };\n  } catch {\n    return undefined;\n  }\n}\n\n/** Name of the cookie used to relay action errors. */\nexport const ACTION_ERROR_COOKIE = COOKIE_NAME;\n\n/** Builds the Set-Cookie header value that clears the error cookie. */\nexport function clearActionErrorCookieHeader(): string {\n  return `${COOKIE_NAME}=; Path=/; Max-Age=0; SameSite=Lax`;\n}\n\n/** Builds the Set-Cookie header value that sets the error cookie. */\nexport function setActionErrorCookieHeader(value: string): string {\n  return `${COOKIE_NAME}=${value}; Path=/; Max-Age=15; SameSite=Lax; HttpOnly`;\n}\n","// --- Cache policy per route (runtime-security §9.1) ---\n//\n// Authors can declare a cache policy in their page.data.ts:\n//\n//   export const cache = {\n//     mode: \"public\",        // \"public\" | \"private\" | \"dynamic\"\n//     revalidate: 60,        // seconds\n//     tags: [\"products\"],    // for tag-based invalidation\n//   };\n//\n// Default policy: \"dynamic\" (no public ISR caching).\n// Requests with Cookie/Authorization are never cached publicly.\n// Responses with Set-Cookie/private/no-store are never cached publicly.\n\n/** Cache mode for a route. */\nexport type CacheMode = \"public\" | \"private\" | \"dynamic\";\n\n/** Cache policy declared by the route's data module. */\nexport interface CachePolicy {\n  mode: CacheMode;\n  revalidate: number;\n  tags?: string[];\n}\n\n/** Default cache policy when none is declared. */\nexport const DEFAULT_CACHE_POLICY: CachePolicy = {\n  mode: \"dynamic\",\n  revalidate: 0,\n};\n\n/**\n * Normalizes a raw cache export from a data module into a CachePolicy.\n * Returns the default policy if the input is invalid or missing.\n */\nexport function normalizeCachePolicy(raw: unknown): CachePolicy {\n  if (!raw || typeof raw !== \"object\") return DEFAULT_CACHE_POLICY;\n  const obj = raw as Record<string, unknown>;\n  const mode = obj.mode;\n  if (mode !== \"public\" && mode !== \"private\" && mode !== \"dynamic\") {\n    return DEFAULT_CACHE_POLICY;\n  }\n  const revalidate = typeof obj.revalidate === \"number\" ? obj.revalidate : 0;\n  const tags = Array.isArray(obj.tags) ? obj.tags.filter((t) => typeof t === \"string\") : undefined;\n  return { mode, revalidate, tags };\n}\n\n/**\n * Determines whether a route's cache policy allows public caching for the\n * given request.\n *\n * Per §9.1:\n * - \"dynamic\" → never cache\n * - \"private\" → never cache publicly (requires private adapter)\n * - \"public\" → cache only if request has no Cookie/Authorization\n */\nexport function shouldCachePublic(\n  policy: CachePolicy,\n  request: Request,\n): boolean {\n  if (policy.mode !== \"public\") return false;\n  if (policy.revalidate <= 0) return false;\n  if (request.headers.get(\"Cookie\")) return false;\n  if (request.headers.get(\"Authorization\")) return false;\n  return true;\n}\n","import type { NixTemplate } from \"@deijose/nix-js\";\nimport { renderToString } from \"../render/render-to-string.js\";\nimport { documentShell, buildHeadTags } from \"../build/document-shell.js\";\nimport type { PageRoute, ScannedRoutes } from \"../router/route-scanner.js\";\nimport type { BuildConfig } from \"../build/build.js\";\nimport type { PageDataLoad, PageProps, RouteParams, PageMetadata, GenerateMetadata } from \"../types.js\";\nimport { existsSync } from \"node:fs\";\nimport { decodeActionErrorCookie, ACTION_ERROR_COOKIE } from \"../action/error-store.js\";\nimport { normalizeCachePolicy, type CachePolicy } from \"../cache/policy.js\";\n\nexport interface RenderPageOptions {\n  route: PageRoute;\n  params?: RouteParams;\n  searchParams?: URLSearchParams;\n  config: Pick<BuildConfig, \"lang\" | \"clientEntry\" | \"renderEndpoint\">;\n  /** Custom module loader. Defaults to native dynamic import. */\n  importer?: (path: string) => Promise<unknown>;\n  /** Per-page action names exposed in the HTML shell. */\n  actions?: Record<string, string[]>;\n  /** Current request, used to hydrate data loaders that need cookies/headers. */\n  request?: Request;\n}\n\nexport interface RenderPageResult {\n  html: string;\n  revalidate?: number;\n  /**\n   * `Set-Cookie` header value that clears the action error cookie, when the\n   * page consumed a relayed action failure. The SSR server should append it to\n   * the outgoing response so the cookie does not persist.\n   */\n  clearActionErrorCookie?: string;\n  /** `<head>` tags (title, meta, OG, twitter) for the SPA router to merge. */\n  head?: string;\n  /** Resolved page title (from metadata or fallback). */\n  resolvedTitle?: string;\n  /**\n   * When a loader or layout throws a `Response` (e.g. `throw new Response(...,\n   * { status: 404 })`), it is captured here as a first-class response instead\n   * of being treated as an internal error (A-22).\n   */\n  response?: Response;\n  /** HTTP status code for the rendered page (e.g. 404 for not-found pages). */\n  status?: number;\n  /** Cache policy declared by the route (§9.1). */\n  cachePolicy?: CachePolicy;\n}\n\nconst defaultImport = (path: string) => import(path);\n\n/**\n * Collects `<html>` attributes and head scripts declared by data loaders\n * (page and layouts) via top-level `htmlAttributes` / `headScripts` fields.\n */\nexport function collectShellExtras(\n  pageData: unknown,\n  layoutDataList: unknown[],\n): { htmlAttributes: Record<string, string>; headScripts: string[]; headLinks: string[] } {\n  const htmlAttributes: Record<string, string> = {};\n  const headScripts: string[] = [];\n  const headLinks: string[] = [];\n  const merge = (value: unknown) => {\n    if (!value || typeof value !== \"object\") return;\n    const attrs = (value as { htmlAttributes?: Record<string, string> }).htmlAttributes;\n    if (attrs) Object.assign(htmlAttributes, attrs);\n    const scripts = (value as { headScripts?: string[] }).headScripts;\n    if (Array.isArray(scripts)) headScripts.push(...scripts);\n    const links = (value as { headLinks?: string[] }).headLinks;\n    if (Array.isArray(links)) headLinks.push(...links);\n  };\n  for (const layoutData of layoutDataList) merge(layoutData);\n  merge(pageData);\n  // Deduplicate headScripts and headLinks (e.g. from both layout and page data)\n  const uniqueScripts = [...new Set(headScripts)];\n  const uniqueLinks = [...new Set(headLinks)];\n  return { htmlAttributes, headScripts: uniqueScripts, headLinks: uniqueLinks };\n}\n\nexport async function renderPage(options: RenderPageOptions): Promise<RenderPageResult> {\n  const { route, params = {}, searchParams = new URLSearchParams(), config, importer = defaultImport, actions, request } = options;\n\n  const pageModule = await importer(route.pagePath) as {\n    default: (props: PageProps<unknown>) => NixTemplate;\n    generateMetadata?: GenerateMetadata;\n  };\n  const { default: PageComponent, generateMetadata } = pageModule;\n\n  let data: unknown;\n  let revalidate: number | undefined;\n  let cachePolicy: import(\"../cache/policy.js\").CachePolicy | undefined;\n  // Use a mutable container so TypeScript doesn't narrow the type after\n  // the first `if (thrownResponse)` check.\n  const thrown: { response: Response | undefined } = { response: undefined };\n  if (route.dataPath) {\n    const mod = await importer(route.dataPath) as {\n      load?: PageDataLoad;\n      revalidate?: number;\n      cache?: unknown;\n    };\n    if (mod.load) {\n      try {\n        data = await mod.load({ params, searchParams, request });\n      } catch (err) {\n        if (err instanceof Response) {\n          thrown.response = err;\n        } else {\n          throw err;\n        }\n      }\n    }\n    if (typeof mod.revalidate === \"number\") {\n      revalidate = mod.revalidate;\n    }\n    // Read cache policy from the data module (§9.1).\n    if (mod.cache) {\n      cachePolicy = normalizeCachePolicy(mod.cache);\n      if (cachePolicy.revalidate > 0) {\n        revalidate = cachePolicy.revalidate;\n      }\n    }\n  }\n\n  // If a loader threw a Response (redirect, 404, etc.), return it as a\n  // first-class response instead of rendering the page (A-22).\n  if (thrown.response) {\n    return { html: \"\", response: thrown.response, status: thrown.response.status };\n  }\n\n  // Relay an action failure previously stored in the ephemeral cookie so the\n  // page can render validation errors via `props.form`. The cookie is cleared\n  // on the outgoing response (see `clearActionErrorCookie` in the result).\n  let form: unknown;\n  let clearActionErrorCookie: string | undefined;\n  if (request) {\n    const cookieHeader = request.headers.get(\"Cookie\") ?? \"\";\n    const match = cookieHeader.match(new RegExp(`(?:^|;\\\\s*)${ACTION_ERROR_COOKIE}=([^;]+)`));\n    if (match) {\n      const decoded = decodeActionErrorCookie(match[1]);\n      if (decoded) {\n        form = { __nix_js_action_error: true, status: decoded.status, data: decoded.data };\n        clearActionErrorCookie = `${ACTION_ERROR_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax`;\n      }\n    }\n  }\n\n  const props: PageProps<unknown> = {\n    data: data ?? {},\n    params,\n    searchParams,\n    form,\n  };\n\n  const layoutModules = await Promise.all(\n    route.layouts.map(async (layoutPath) => importer(layoutPath)),\n  );\n  const layoutDataList = await Promise.all(\n    route.layouts.map(async (layoutPath) => {\n      const dataPath = layoutPath.replace(/layout\\.ts$/, \"layout.data.ts\");\n      if (!existsSync(dataPath)) return undefined;\n      const mod = (await importer(dataPath)) as { load?: PageDataLoad };\n      if (mod.load) {\n        try {\n          return await mod.load({ params, searchParams, request });\n        } catch (err) {\n          if (err instanceof Response) {\n            thrown.response = err;\n            return undefined;\n          }\n          throw err;\n        }\n      }\n      return undefined;\n    }),\n  );\n\n  // If a layout loader threw a Response, return it as first-class (A-22).\n  const layoutThrown = thrown.response as Response | undefined;\n  if (layoutThrown) {\n    return { html: \"\", response: layoutThrown, status: layoutThrown.status };\n  }\n\n  // Load slot modules if the route has them (v2.1 — Fix #2: Layout Slots).\n  let slotTemplates: Record<string, NixTemplate> | undefined;\n  if (route.slots) {\n    slotTemplates = {};\n    for (const [slotName, slotPath] of Object.entries(route.slots)) {\n      const slotMod = await importer(slotPath) as { default: (props: PageProps<unknown>) => NixTemplate };\n      slotTemplates[slotName] = slotMod.default(props);\n    }\n  }\n\n  const body = await renderToString(() => {\n    let template = PageComponent(props);\n    for (let i = layoutModules.length - 1; i >= 0; i--) {\n      const { default: Layout } = layoutModules[i] as {\n        default: (props: { children: NixTemplate; data?: unknown; slots?: Record<string, NixTemplate> }) => NixTemplate;\n      };\n      template = Layout({ children: template, data: layoutDataList[i], slots: slotTemplates });\n    }\n    return template;\n  });\n\n  const title = typeof data === \"object\" && data && \"title\" in data\n    ? String((data as { title?: unknown }).title ?? \"Nix.js Kit\")\n    : \"Nix.js Kit\";\n\n  const { htmlAttributes, headScripts, headLinks } = collectShellExtras(data, layoutDataList);\n\n  // Resolve page metadata. Priority: `generateMetadata` from page.ts > `metadata`\n  // field in the page loader data > `metadata` field in layout loader data.\n  let metadata: PageMetadata | undefined;\n  if (typeof generateMetadata === \"function\") {\n    metadata = await generateMetadata({ params, searchParams, request, data });\n  }\n  if (!metadata) {\n    metadata = extractMetadata(data) ?? extractMetadataFromList(layoutDataList);\n  }\n  // The title from metadata takes precedence over the data.title fallback.\n  const resolvedTitle = metadata?.title ?? title;\n\n  const html = documentShell({\n    title: resolvedTitle,\n    lang: config.lang,\n    body,\n    data,\n    actions,\n    htmlAttributes,\n    headScripts,\n    headLinks,\n    metadata,\n    clientEntry: config.clientEntry,\n    renderEndpoint: config.renderEndpoint,\n  });\n\n  const head = metadata ? buildHeadTags(metadata, resolvedTitle) : \"\";\n  return { html, revalidate, clearActionErrorCookie, head, resolvedTitle, cachePolicy };\n}\n\n/** Extracts a `metadata` field from a loader data object, if present. */\nfunction extractMetadata(value: unknown): PageMetadata | undefined {\n  if (value && typeof value === \"object\" && \"metadata\" in value) {\n    const meta = (value as { metadata?: unknown }).metadata;\n    if (meta && typeof meta === \"object\") return meta as PageMetadata;\n  }\n  return undefined;\n}\n\n/** Extracts metadata from the first layout data object that has one. */\nfunction extractMetadataFromList(list: unknown[]): PageMetadata | undefined {\n  for (const item of list) {\n    const meta = extractMetadata(item);\n    if (meta) return meta;\n  }\n  return undefined;\n}\n\nexport interface RenderErrorPageOptions {\n  routes: ScannedRoutes;\n  status: 404 | 500;\n  error?: unknown;\n  config: Pick<BuildConfig, \"lang\" | \"clientEntry\" | \"renderEndpoint\">;\n  actions?: Record<string, string[]>;\n  importer?: (path: string) => Promise<unknown>;\n}\n\nexport async function renderErrorPage(\n  options: RenderErrorPageOptions,\n): Promise<{ html: string; status: number } | undefined> {\n  const route = options.status === 404 ? options.routes.error404 : options.routes.error500;\n  if (!route) return undefined;\n\n  try {\n    const { html } = await renderPage({\n      route,\n      params: {},\n      searchParams: new URLSearchParams(),\n      config: options.config,\n      actions: options.actions,\n      importer: options.importer,\n    });\n    return { html, status: options.status };\n  } catch (err) {\n    console.error(`[render] error ${options.status} page failed`, err);\n    return undefined;\n  }\n}\n","import { resolve, relative } from \"node:path\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\n\n/**\n * Registry of server actions grouped by page path.\n *\n * The outer key is the page URL path (e.g. \"/contact\"). The inner object maps\n * each exported action name to the absolute file path of the `page.action.ts`\n * module that defines it.\n */\nexport type ActionRegistry = Record<string, Record<string, string>>;\n\n/**\n * Scans `page.action.ts` modules and returns a per-page registry of server actions.\n *\n * Only named function exports are collected; default exports are ignored. The\n * registry is keyed by page URL path so the client can resolve actions scoped\n * to a specific page and avoid name collisions between different routes.\n */\nexport async function scanActions(appDir: string): Promise<ActionRegistry> {\n  const routes = await scanRoutes(appDir);\n  const actions: ActionRegistry = {};\n\n  for (const page of routes.pages) {\n    if (!page.actionPath) continue;\n    const actionPath = resolve(page.actionPath);\n    const mod = (await import(actionPath)) as Record<string, unknown>;\n    const pageActions: Record<string, string> = {};\n    for (const [name, value] of Object.entries(mod)) {\n      if (name === \"default\") continue;\n      if (typeof value === \"function\") {\n        pageActions[name] = actionPath;\n      }\n    }\n    if (Object.keys(pageActions).length > 0) {\n      actions[page.path] = pageActions;\n    }\n  }\n\n  return actions;\n}\n\n/**\n * Return a copy of the action registry where every file path is made relative to\n * the given project root. Useful for serializing actions into the HTML shell\n * without exposing absolute server paths.\n */\nexport function relativeActions(actions: ActionRegistry, root: string): ActionRegistry {\n  const result: ActionRegistry = {};\n  for (const [page, pageActions] of Object.entries(actions)) {\n    const entries: Record<string, string> = {};\n    for (const [name, actionPath] of Object.entries(pageActions)) {\n      entries[name] = relative(root, actionPath);\n    }\n    result[page] = entries;\n  }\n  return result;\n}\n\n/**\n * Return only the names of available actions per page, without file paths.\n * This is the safe format to serialize into the HTML shell: the client only\n * needs to know which actions exist, never where they are implemented.\n */\nexport function actionNames(actions: ActionRegistry): Record<string, string[]> {\n  const result: Record<string, string[]> = {};\n  for (const [page, pageActions] of Object.entries(actions)) {\n    result[page] = Object.keys(pageActions);\n  }\n  return result;\n}\n","import { readFile, mkdir, writeFile, rename, rm, stat } from \"node:fs/promises\";\nimport { join, dirname, extname, basename, resolve, sep } from \"node:path\";\nimport { createHash, randomBytes } from \"node:crypto\";\nimport type { ImageFormat } from \"./index.js\";\n\n// --- ImageService: metadata-driven image processing and manifest ---\n//\n//   * Reads real image dimensions from the source file (sharp metadata).\n//   * Generates hashed variant filenames from a SHA-256 transform key that\n//     incorporates: content digest + normalized transform options +\n//     encoder/service version + output naming version (§4.2).\n//   * Applies path containment for sources and outputs (no traversal, no NUL,\n//     no symlink escape, no Unicode/separator tricks).\n//   * Writes outputs atomically (temp + rename) with single-flight per\n//     transform key and a bounded concurrency pool.\n//   * Supports `strict` mode: fails the build on missing sources or failed\n//     transforms instead of emitting a partially-written variant.\n//   * Falls back gracefully when sharp is not installed.\n\nconst ENCODER_VERSION = \"sharp-1\";\nconst NAMING_VERSION = \"v1\";\nconst HASH_LENGTH = 12;\nconst DEFAULT_QUALITY = 80;\nconst DEFAULT_CONCURRENCY = 4;\n\nexport interface ImageVariant {\n  /** URL path relative to the site root, e.g. \"/images/hero.abc123def456.800w.webp\". */\n  url: string;\n  /** Width in pixels. */\n  width: number;\n  /** Height in pixels (preserves aspect ratio). */\n  height: number;\n  /** Format of the variant. */\n  format: ImageFormat;\n  /** File size in bytes. */\n  size: number;\n}\n\nexport interface ImageEntry {\n  /** Original source URL, e.g. \"/images/hero.jpg\". */\n  src: string;\n  /** Intrinsic width of the source. */\n  width: number;\n  /** Intrinsic height of the source. */\n  height: number;\n  /** All generated variants. */\n  variants: ImageVariant[];\n  /** Content hash of the source file. */\n  hash: string;\n}\n\nexport interface ImageManifest {\n  version: 1;\n  entries: Record<string, ImageEntry>;\n}\n\nexport interface ProcessOptions {\n  /** Absolute path to the public directory (source images). */\n  publicDir: string;\n  /** Absolute path to the output directory. */\n  outDir: string;\n  /** Formats to generate. Defaults to [\"webp\", \"avif\"]. */\n  formats?: ImageFormat[];\n  /** Quality (1-100). Defaults to 80. */\n  quality?: number;\n  /** Path to write the manifest JSON. */\n  manifestPath?: string;\n  /** When true, missing sources or failed transforms fail the build. */\n  strict?: boolean;\n  /** Max concurrent sharp transforms. Defaults to 4. */\n  concurrency?: number;\n  /** Optional URL base prefix applied to variant URLs. */\n  base?: string;\n}\n\nexport interface ProcessResult {\n  manifest: ImageManifest;\n  /** Number of variants generated. */\n  count: number;\n  /** Whether sharp was available. */\n  optimized: boolean;\n}\n\nlet sharpLoader: (() => Promise<any>) | null | undefined;\n\nasync function loadSharp(): Promise<any | null> {\n  if (sharpLoader === null) return null;\n  if (sharpLoader) return sharpLoader();\n  try {\n    // @ts-ignore — `sharp` is an optional peer dependency.\n    const mod = await import(\"sharp\");\n    const sharp = mod.default;\n    if (typeof sharp !== \"function\") {\n      sharpLoader = null;\n      return null;\n    }\n    sharpLoader = async () => sharp;\n    return sharp;\n  } catch {\n    sharpLoader = null;\n    return null;\n  }\n}\n\nexport async function isSharpAvailable(): Promise<boolean> {\n  const sharp = await loadSharp();\n  return sharp !== null;\n}\n\n// --- Transform identity (§4.2) ---\n\n/**\n * SHA-256 transform key. Stable for identical content+options and invalidated\n * whenever the source bytes, the effective transform options, the encoder\n * version or the naming scheme change.\n */\nexport function transformHash(sourceBuffer: Buffer, width: number, format: ImageFormat, quality: number): string {\n  const contentDigest = createHash(\"sha256\").update(sourceBuffer).digest(\"hex\");\n  const normalizedOptions = JSON.stringify({\n    width,\n    format,\n    quality,\n    withoutEnlargement: true,\n  });\n  return createHash(\"sha256\")\n    .update(`${contentDigest}|${normalizedOptions}|${ENCODER_VERSION}|${NAMING_VERSION}`)\n    .digest(\"hex\")\n    .slice(0, HASH_LENGTH);\n}\n\n// --- Path containment (§9.5) ---\n\nfunction isSafeRelativePath(value: string): boolean {\n  if (value.includes(\"\\0\") || value.includes(\"\\\\\")) return false;\n  if (/%[0-9a-f]{2}/i.test(value)) return false;\n  const segments = value.replace(/^\\/+/, \"\").split(\"/\");\n  return !segments.some((segment) => segment === \"..\" || segment === \".\" || segment === \"\");\n}\n\nfunction isInside(root: string, candidate: string): boolean {\n  return candidate === root || candidate.startsWith(`${root}${sep}`);\n}\n\nfunction assertInside(root: string, candidate: string, label: string): void {\n  const resolvedRoot = resolve(root);\n  const resolvedCandidate = resolve(candidate);\n  if (!isInside(resolvedRoot, resolvedCandidate)) {\n    throw new Error(`[nix-js-kit] Image ${label} escapes its allowed root (${resolvedCandidate}).`);\n  }\n}\n\n// --- Concurrency: bounded pool + single-flight ---\n\nfunction createPool(limit: number) {\n  let active = 0;\n  const waiters: Array<() => void> = [];\n  const acquire = () =>\n    new Promise<void>((resolve) => {\n      if (active < limit) {\n        active++;\n        resolve();\n      } else {\n        waiters.push(() => {\n          active++;\n          resolve();\n        });\n      }\n    });\n  const release = () => {\n    active--;\n    const next = waiters.shift();\n    if (next) next();\n    else if (active < 0) active = 0;\n  };\n  return {\n    async run<T>(fn: () => Promise<T>): Promise<T> {\n      await acquire();\n      try {\n        return await fn();\n      } finally {\n        release();\n      }\n    },\n  };\n}\n\n// --- Atomic writes (§9.6) ---\n\nasync function atomicWriteFile(path: string, data: Buffer | string): Promise<void> {\n  const temp = `${path}.${process.pid}.${randomBytes(6).toString(\"hex\")}.tmp`;\n  try {\n    await writeFile(temp, data);\n    await rename(temp, path);\n  } catch (error) {\n    await rm(temp, { force: true }).catch(() => { });\n    throw error;\n  }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n  try {\n    await stat(path);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n// --- Public programmatic API (§3.1 / §3.3) ---\n\nexport interface ImageRequest {\n  src: string;\n  alt: string;\n  widths?: readonly number[];\n  formats?: readonly ImageFormat[];\n  sizes?: string;\n  width?: number;\n  height?: number;\n  priority?: boolean;\n  loading?: \"lazy\" | \"eager\";\n  decoding?: \"async\" | \"sync\" | \"auto\";\n  quality?: number;\n  fit?: string;\n  class?: string;\n  attributes?: Record<string, unknown>;\n}\n\nexport interface GeneratedImage {\n  url: string;\n  width: number;\n  height: number;\n  format: ImageFormat;\n  size: number;\n}\n\nexport interface ImageMetadata {\n  src: string;\n  width?: number;\n  height?: number;\n  sources: Array<{ type: string; srcset: string }>;\n  attributes: Record<string, string | number | boolean | undefined>;\n  generated: readonly GeneratedImage[];\n}\n\nexport interface ImageServiceContext {\n  publicDir: string;\n  outDir: string;\n  manifest: ImageManifest;\n}\n\nexport interface ImageServiceCapabilities {\n  /** Whether the encoder (sharp) is available. */\n  encoding: boolean;\n  /** Whether remote images can be fetched. */\n  remote: boolean;\n  /** Whether a runtime image endpoint exists. */\n  runtimeEndpoint: boolean;\n  /** Whether the host exposes a writable filesystem. */\n  filesystem: boolean;\n}\n\nexport interface ImageService {\n  resolve(request: ImageRequest, context: ImageServiceContext): Promise<ImageMetadata>;\n  capabilities: ImageServiceCapabilities;\n}\n\n/**\n * Creates a build-time ImageService bound to a public/output directory pair.\n */\nexport function createImageService(options: ProcessOptions): ImageService {\n  return {\n    capabilities: {\n      encoding: false,\n      remote: false,\n      runtimeEndpoint: false,\n      filesystem: true,\n    },\n    async resolve(request, context) {\n      return getImage(request, { ...options, publicDir: context.publicDir, outDir: context.outDir });\n    },\n  };\n}\n\n/**\n * Programmatic async image API (§3.1). Ensures the requested variants exist on\n * disk (build-time), then returns deterministic metadata (not opaque markup).\n */\nexport async function getImage(\n  request: ImageRequest,\n  options: ProcessOptions,\n): Promise<ImageMetadata> {\n  const { src, alt, widths, formats, quality, priority, loading, decoding, class: className, attributes = {} } = request;\n  const targetWidths = widths?.length ? [...widths] : [request.width ?? 0];\n  const targetFormats = formats?.length ? [...formats] : options.formats ?? [\"webp\", \"avif\"];\n  const result = await processImageBatch(\n    [{ src, widths: targetWidths, formats: targetFormats }],\n    { ...options, quality: quality ?? options.quality },\n  );\n  const entry = result.manifest.entries[src];\n  const generated: GeneratedImage[] = entry\n    ? entry.variants.map((v) => ({ url: v.url, width: v.width, height: v.height, format: v.format, size: v.size }))\n    : [];\n\n  const sources: ImageMetadata[\"sources\"] = [];\n  for (const format of targetFormats) {\n    const srcset = entry ? buildSrcset(entry, format) : \"\";\n    if (srcset) sources.push({ type: format === \"jpeg\" ? \"image/jpeg\" : `image/${format}`, srcset });\n  }\n\n  return {\n    src,\n    width: entry?.width,\n    height: entry?.height,\n    sources,\n    attributes: {\n      alt,\n      width: entry?.width ?? request.width,\n      height: entry?.height ?? request.height,\n      loading: priority ? \"eager\" : (loading ?? \"lazy\"),\n      decoding: decoding ?? \"async\",\n      ...(priority ? { fetchpriority: \"high\" } : {}),\n      ...(className ? { class: className } : {}),\n      ...attributes,\n    },\n    generated,\n  };\n}\n\n// --- Batch processing ---\n\nexport async function processImageBatch(\n  images: { src: string; widths: number[]; formats?: ImageFormat[] }[],\n  options: ProcessOptions,\n): Promise<ProcessResult> {\n  const sharp = await loadSharp();\n  const {\n    publicDir,\n    outDir,\n    formats = [\"webp\", \"avif\"],\n    quality = DEFAULT_QUALITY,\n    strict = false,\n    concurrency = DEFAULT_CONCURRENCY,\n    base = \"\",\n  } = options;\n  const entries: Record<string, ImageEntry> = {};\n  let count = 0;\n  const pool = createPool(concurrency);\n  const inFlight = new Map<string, Promise<void>>();\n\n  const warned = new Set<string>();\n  const warnOnce = (key: string, message: string): void => {\n    if (warned.has(key)) return;\n    warned.add(key);\n    console.warn(`[nix-js-kit] ${message}`);\n  };\n\n  if (!sharp) {\n    // Without sharp, build a manifest with only the original source entries.\n    for (const { src } of images) {\n      if (entries[src]) continue;\n      if (!isSafeRelativePath(src)) {\n        if (strict) throw new Error(`[nix-js-kit] Invalid image source path: ${src}`);\n        warnOnce(`path:${src}`, `Skipping invalid image source path: ${src}`);\n        continue;\n      }\n      const sourcePath = join(publicDir, src.replace(/^\\//, \"\"));\n      assertInside(publicDir, sourcePath, `source \"${src}\"`);\n      try {\n        const buffer = await readFile(sourcePath);\n        entries[src] = {\n          src,\n          width: 0,\n          height: 0,\n          variants: [],\n          hash: createHash(\"sha256\").update(buffer).digest(\"hex\").slice(0, 8),\n        };\n      } catch (error) {\n        if (strict) throw new Error(`[nix-js-kit] Image source not found: ${src}`);\n        warnOnce(`missing:${src}`, `Image source not found: ${src}. Skipping.`);\n      }\n    }\n    const manifest: ImageManifest = { version: 1, entries };\n    if (options.manifestPath) await writeManifest(options.manifestPath, manifest);\n    return { manifest, count: 0, optimized: false };\n  }\n\n  for (const { src, widths, formats: imgFormats } of images) {\n    if (entries[src]) continue;\n\n    if (!isSafeRelativePath(src)) {\n      if (strict) throw new Error(`[nix-js-kit] Invalid image source path: ${src}`);\n      warnOnce(`path:${src}`, `Skipping invalid image source path: ${src}`);\n      continue;\n    }\n\n    const sourcePath = join(publicDir, src.replace(/^\\//, \"\"));\n    assertInside(publicDir, sourcePath, `source \"${src}\"`);\n\n    let sourceBuffer: Buffer;\n    try {\n      sourceBuffer = await readFile(sourcePath);\n    } catch (error) {\n      if (strict) throw new Error(`[nix-js-kit] Image source not found: ${src}`);\n      warnOnce(`missing:${src}`, `Image not found: ${src}. Skipping.`);\n      continue;\n    }\n\n    const ext = extname(src);\n    const safeBase = basename(src, ext).replace(/[^a-zA-Z0-9._-]+/g, \"-\");\n    const dir = dirname(src);\n    const targetFormats = imgFormats?.length ? imgFormats : formats;\n\n    // Read real metadata from the source.\n    let sourceWidth = 0;\n    let sourceHeight = 0;\n    try {\n      const meta = await sharp(sourceBuffer).metadata();\n      sourceWidth = meta.width ?? 0;\n      sourceHeight = meta.height ?? 0;\n    } catch {\n      // Fallback: no metadata.\n    }\n\n    const variants: ImageVariant[] = [];\n\n    const processVariant = async (width: number, format: ImageFormat): Promise<void> => {\n      // Never upscale: skip widths larger than the source.\n      if (sourceWidth > 0 && width > sourceWidth) return;\n\n      const hash = transformHash(sourceBuffer, width, format, quality);\n      const variantName = `${safeBase}.${hash}.${width}w.${format}`;\n      const variantRelPath = join(dir, variantName);\n      const variantAbsPath = join(outDir, variantRelPath.replace(/^\\//, \"\"));\n      assertInside(outDir, variantAbsPath, `variant \"${variantRelPath}\"`);\n      const variantUrl = `${base.replace(/\\/$/, \"\")}/${variantRelPath.replace(/\\\\/g, \"/\").replace(/^\\//, \"\")}`;\n\n      // Reuse an existing, valid output file (validated, not guessed).\n      if (await fileExists(variantAbsPath)) {\n        try {\n          const info = await sharp(variantAbsPath).metadata();\n          variants.push({\n            url: variantUrl,\n            width: info.width ?? width,\n            height: info.height ?? Math.round((info.height ?? 0) || (sourceHeight && sourceWidth ? (width * sourceHeight) / sourceWidth : 0)),\n            format,\n            size: (await stat(variantAbsPath)).size,\n          });\n          count++;\n          return;\n        } catch {\n          // Existing file invalid — regenerate below.\n        }\n      }\n\n      const key = variantAbsPath;\n      if (inFlight.has(key)) {\n        await inFlight.get(key);\n        variants.push({\n          url: variantUrl,\n          width,\n          height: Math.round(sourceHeight && sourceWidth ? (width * sourceHeight) / sourceWidth : 0),\n          format,\n          size: (await stat(variantAbsPath)).size,\n        });\n        count++;\n        return;\n      }\n\n      const task = (async () => {\n        try {\n          const buffer = await sharp(sourceBuffer)\n            .resize({ width, withoutEnlargement: true })\n            .toFormat(format, { quality })\n            .toBuffer();\n          await mkdir(dirname(variantAbsPath), { recursive: true });\n          await atomicWriteFile(variantAbsPath, buffer);\n        } catch (error) {\n          if (strict) throw new Error(`[nix-js-kit] Failed to generate ${variantName}: ${error instanceof Error ? error.message : String(error)}`);\n          warnOnce(`fail:${variantName}`, `Failed to generate ${variantName}.`);\n          return;\n        }\n        variants.push({\n          url: variantUrl,\n          width,\n          height: Math.round(sourceHeight && sourceWidth ? (width * sourceHeight) / sourceWidth : 0),\n          format,\n          size: (await stat(variantAbsPath)).size,\n        });\n        count++;\n      })().finally(() => inFlight.delete(key));\n\n      inFlight.set(key, task);\n      await pool.run(() => task);\n    };\n\n    const tasks: Promise<void>[] = [];\n    for (const width of widths) {\n      for (const format of targetFormats) {\n        tasks.push(processVariant(width, format));\n      }\n    }\n    await Promise.all(tasks);\n\n    entries[src] = {\n      src,\n      width: sourceWidth,\n      height: sourceHeight,\n      variants,\n      hash: createHash(\"sha256\").update(sourceBuffer).digest(\"hex\").slice(0, 8),\n    };\n  }\n\n  const manifest: ImageManifest = { version: 1, entries };\n  if (options.manifestPath) await writeManifest(options.manifestPath, manifest);\n  return { manifest, count, optimized: true };\n}\n\n/**\n * Read a manifest from disk, or return an empty one if it doesn't exist.\n */\nexport async function readManifest(path: string): Promise<ImageManifest> {\n  try {\n    const data = await readFile(path, \"utf8\");\n    return JSON.parse(data) as ImageManifest;\n  } catch {\n    return { version: 1, entries: {} };\n  }\n}\n\n/**\n * Write a manifest to disk atomically.\n */\nexport async function writeManifest(path: string, manifest: ImageManifest): Promise<void> {\n  await mkdir(dirname(path), { recursive: true });\n  await atomicWriteFile(path, JSON.stringify(manifest, null, 2));\n}\n\n/**\n * Look up an image entry in the manifest by its source URL.\n */\nexport function getManifestEntry(manifest: ImageManifest, src: string): ImageEntry | undefined {\n  return manifest.entries[src];\n}\n\n/**\n * Build a srcset string from manifest variants of a given format.\n * Returns e.g. \"/images/hero.abc.400w.webp 400w, /images/hero.abc.800w.webp 800w\".\n */\nexport function buildSrcset(entry: ImageEntry, format: ImageFormat): string {\n  return entry.variants\n    .filter((v) => v.format === format)\n    .map((v) => `${v.url} ${v.width}w`)\n    .join(\", \");\n}\n\n/**\n * Build the full <picture> markup for an image entry, with <source> per format\n * and a fallback <img>.\n */\nexport function buildPictureMarkup(entry: ImageEntry, opts: {\n  alt: string;\n  sizes?: string;\n  priority?: boolean;\n  class?: string;\n  attributes?: Record<string, string>;\n  fallbackSrc?: string;\n  fallbackWidth?: number;\n  fallbackHeight?: number;\n}): string {\n  const {\n    alt,\n    sizes,\n    priority = false,\n    class: className,\n    attributes = {},\n    fallbackSrc = entry.src,\n    fallbackWidth = entry.width,\n    fallbackHeight = entry.height,\n  } = opts;\n\n  const formats = [...new Set(entry.variants.map((v) => v.format))];\n  const loadingAttr = priority ? \"\" : ' loading=\"lazy\"';\n  const fetchPriorityAttr = priority ? ' fetchpriority=\"high\"' : \"\";\n  const sizesAttr = sizes ? ` sizes=\"${escapeAttr(sizes)}\"` : \"\";\n  const classAttr = className ? ` class=\"${escapeAttr(className)}\"` : \"\";\n  const extraAttrs = Object.entries(attributes)\n    .map(([key, value]) => ` ${escapeAttr(key)}=\"${escapeAttr(String(value))}\"`)\n    .join(\"\");\n\n  const sources = formats\n    .map((format) => {\n      const srcset = buildSrcset(entry, format);\n      if (!srcset) return \"\";\n      const type = format === \"jpeg\" ? \"image/jpeg\" : `image/${format}`;\n      return `<source srcset=\"${srcset}\"${sizesAttr} type=\"${type}\" />`;\n    })\n    .filter(Boolean)\n    .join(\"\");\n\n  const img = `<img src=\"${escapeAttr(fallbackSrc)}\" alt=\"${escapeAttr(alt)}\" width=\"${fallbackWidth}\" height=\"${fallbackHeight}\"${loadingAttr} decoding=\"async\"${fetchPriorityAttr}${classAttr}${extraAttrs} />`;\n\n  return sources ? `<picture>${sources}${img}</picture>` : img;\n}\n\n/**\n * Validate that every variant URL in the manifest corresponds to a real file\n * in the output directory. Returns a list of missing URLs.\n */\nexport async function validateManifestUrls(\n  manifest: ImageManifest,\n  outDir: string,\n): Promise<string[]> {\n  const missing: string[] = [];\n  for (const entry of Object.values(manifest.entries)) {\n    for (const variant of entry.variants) {\n      const relative = variant.url.replace(/^\\/+/, \"\");\n      const resolved = resolve(outDir, relative);\n      if (!isInside(resolve(outDir), resolved)) {\n        missing.push(variant.url);\n        continue;\n      }\n      try {\n        await stat(resolved);\n      } catch {\n        missing.push(variant.url);\n      }\n    }\n  }\n  return missing;\n}\n\nfunction escapeAttr(value: string): string {\n  return value\n    .replace(/&/g, \"&amp;\")\n    .replace(/\"/g, \"&quot;\")\n    .replace(/</g, \"&lt;\")\n    .replace(/>/g, \"&gt;\");\n}\n","export interface NixKitIntegrationContext {\n  root: string;\n  command: \"dev\" | \"build\" | \"preview\" | \"start\" | \"check\" | \"routes\" | \"doctor\";\n}\n\nexport interface NixKitIntegration {\n  name: string;\n  config?(config: Record<string, unknown>, context: NixKitIntegrationContext): void | Promise<void>;\n  routes?(manifest: unknown, context: NixKitIntegrationContext): void | Promise<void>;\n  request?(request: Request, context: NixKitIntegrationContext): void | Response | Promise<void | Response>;\n  render?(result: { html: string }, context: NixKitIntegrationContext): void | Promise<void>;\n  build?(result: unknown, context: NixKitIntegrationContext): void | Promise<void>;\n  clientEntry?(source: string, context: NixKitIntegrationContext): string | void | Promise<string | void>;\n  error?(error: unknown, context: NixKitIntegrationContext): void | Promise<void>;\n}\n\nexport async function runIntegrationHook<K extends keyof Omit<NixKitIntegration, \"name\">>(\n  integrations: readonly NixKitIntegration[],\n  hook: K,\n  args: Parameters<NonNullable<NixKitIntegration[K]>>,\n): Promise<void> {\n  for (const integration of integrations) {\n    const handler = integration[hook];\n    if (typeof handler === \"function\") await (handler as (...values: unknown[]) => unknown)(...args);\n  }\n}\n\n// Typed integration hooks for optional packages (plan §11.6).\nexport {\n  type I18nIntegration,\n  type AuthIntegration,\n  type QueryIntegration,\n  type TestingIntegration,\n  registerIntegration,\n  getI18nIntegration,\n  getAuthIntegration,\n  getQueryIntegration,\n  getTestingIntegration,\n  getCustomIntegrations,\n  clearIntegrations,\n} from \"./hooks.js\";\n","import { cp, mkdir, stat, writeFile } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { scanRoutes, type PageRoute, type ScannedRoutes } from \"../router/route-scanner.js\";\nimport { scanIslands, type IslandModule } from \"../island/scan.js\";\nimport { generateClientEntry } from \"../island/generate-entry.js\";\nimport { renderPage, renderErrorPage } from \"../ssr/render.js\";\nimport { scanActions, actionNames } from \"../action/scan.js\";\nimport { consumeImageRegistry, setImageManifest, type ImageFormat } from \"../image/index.js\";\nimport { processImageBatch, type ImageManifest } from \"../image/service.js\";\nimport { runIntegrationHook, type NixKitIntegration } from \"../integrations/index.js\";\nimport type { RouteParams, GenerateStaticParams } from \"../types.js\";\n\nexport interface BuildConfig {\n  /** Absolute path to the app directory (e.g. /project/src/app). */\n  appDir: string;\n  /** Absolute path to the output directory (e.g. /project/dist). */\n  outDir: string;\n  /** Absolute path to the project root (e.g. /project). When provided, action\n   * paths in the serialized HTML shell are made relative to this root. */\n  root?: string;\n  /** Base path for the client entry module, e.g. \"/_nix-js/entry-client.js\". */\n  clientEntry?: string;\n  /** Default language for the HTML shell. */\n  lang?: string;\n  /**\n   * Absolute path to the islands directory (e.g. /project/src/islands).\n   * When set, `build` scans it and generates a client entry module listing\n   * every island so you don't have to maintain `entry-client.ts` by hand.\n   */\n  islandsDir?: string;\n  /**\n   * Absolute path where the generated client entry module is written\n   * (e.g. /project/.nix-js/entry-client.ts). Required when `islandsDir` is set.\n   */\n  generatedEntry?: string;\n  /**\n   * Import specifier the generated entry uses for `hydrateIslands`.\n   * Defaults to the published subpath `@deijose/nix-js-kit/island`.\n   */\n  hydrateImport?: string;\n  /**\n   * Import specifier the generated entry uses for `startClientRouter`.\n   * Defaults to the published subpath `@deijose/nix-js-kit/router`.\n   */\n  routerImport?: string;\n  /** Absolute path to the public directory for static assets (optional). */\n  publicDir?: string;\n  /** Image formats to generate when sharp is available. Defaults to [\"webp\", \"avif\"]. */\n  imageFormats?: ImageFormat[];\n  /**\n   * Whether the SSR render endpoint (`/__nix-js/render`) exists at runtime.\n   * Defaults to `true` (dev, preview and SSR deployments). Set to `false` for\n   * fully static outputs so the emitted HTML tells the client router to skip\n   * the endpoint (no 404 storms on static hosts like Vercel).\n   */\n  renderEndpoint?: boolean;\n  /**\n   * Integrations to invoke during the build lifecycle. When provided, the\n   * `build` hook fires after all pages and image variants are generated,\n   * giving integrations a chance to write post-build artifacts (sitemaps,\n   * robots.txt, search indexes, etc.) into the output directory.\n   */\n  integrations?: NixKitIntegration[];\n}\n\nexport interface BuildResult {\n  /** Number of static HTML pages generated. */\n  pages: number;\n  /** Paths that were skipped because they are dynamic without a static param list. */\n  skipped: string[];\n  /** Absolute paths to the generated HTML files. */\n  files: string[];\n  /** Islands discovered when `islandsDir` is set. */\n  islands: IslandModule[];\n  /** Absolute path to the generated client entry, if one was written. */\n  generatedEntry?: string;\n  /** Number of image variants generated (0 if sharp is not installed). */\n  imagesProcessed: number;\n  /** Absolute path to the output directory where build artifacts were written.\n   * When called via the CLI, this is the atomic staging directory (not the\n   * final `dist/`). Integration `build` hooks should write post-build\n   * artifacts here so they survive the atomic swap. */\n  outDir: string;\n}\n\nfunction urlToFilePath(outDir: string, urlPath: string): string {\n  if (urlPath === \"/\") {\n    return join(outDir, \"index.html\");\n  }\n\n  const segments = urlPath.slice(1).split(\"/\");\n  return join(outDir, ...segments, \"index.html\");\n}\n\nfunction isDynamic(path: string): boolean {\n  return path.includes(\":\");\n}\n\nfunction buildConcreteUrl(path: string, params: RouteParams): string {\n  return path.replace(/:([a-zA-Z0-9_]+)(\\*)?/g, (_, name, catchAll) => {\n    const value = params[name];\n    if (value === undefined || value === null) {\n      throw new Error(\n        `Missing value for dynamic segment \"${name}\" in path \"${path}\"`,\n      );\n    }\n    if (catchAll) {\n      return Array.isArray(value) ? value.join(\"/\") : String(value);\n    }\n    return String(value);\n  });\n}\n\n/**\n * Builds a static site from a scanned route tree.\n *\n * @param config Build configuration.\n * @returns Summary of generated files.\n */\nexport async function build(config: BuildConfig): Promise<BuildResult> {\n  if (config.publicDir) {\n    try {\n      if ((await stat(config.publicDir)).isDirectory()) {\n        await mkdir(config.outDir, { recursive: true });\n        await cp(config.publicDir, config.outDir, { recursive: true, force: true });\n      }\n    } catch (error) {\n      if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n    }\n  }\n\n  const routes = await scanRoutes(config.appDir);\n  const actions = await scanActions(config.appDir);\n  // Only action names are serialized into the HTML shell; full paths stay on the server.\n  const publicActions = actionNames(actions);\n  const result: BuildResult = { pages: 0, skipped: [], files: [], islands: [], imagesProcessed: 0, outDir: config.outDir };\n\n  // Scan islands and generate the client entry before rendering pages, so the\n  // hydration bundle stays in sync with what the app actually uses.\n  if (config.islandsDir) {\n    result.islands = await scanIslands(config.islandsDir);\n  }\n\n  if (config.generatedEntry) {\n    result.generatedEntry = await generateClientEntry({\n      islands: result.islands,\n      outFile: config.generatedEntry,\n      hydrateImport: config.hydrateImport,\n      routerImport: config.routerImport,\n    });\n  }\n\n  for (const route of routes.pages) {\n    if (!isDynamic(route.path)) {\n      const filePath = await buildPage(config, route, publicActions);\n      result.pages++;\n      result.files.push(filePath);\n      continue;\n    }\n\n    const dynamicFiles = await buildDynamicPages(config, route, publicActions);\n    if (dynamicFiles.length === 0) {\n      result.skipped.push(route.path);\n    } else {\n      result.pages += dynamicFiles.length;\n      result.files.push(...dynamicFiles);\n    }\n  }\n\n  // Generate static 404 and 500 error pages when they exist.\n  const errorConfig = { lang: config.lang, clientEntry: config.clientEntry, renderEndpoint: false };\n  if (routes.error404) {\n    const result404 = await renderErrorPage({\n      routes,\n      status: 404,\n      config: errorConfig,\n      actions: publicActions,\n    });\n    if (result404) {\n      const filePath = join(config.outDir, \"404.html\");\n      await mkdir(dirname(filePath), { recursive: true });\n      await writeFile(filePath, result404.html, \"utf8\");\n      result.files.push(filePath);\n    }\n  }\n\n  if (routes.error500) {\n    const result500 = await renderErrorPage({\n      routes,\n      status: 500,\n      config: errorConfig,\n      actions: publicActions,\n    });\n    if (result500) {\n      const filePath = join(config.outDir, \"500.html\");\n      await mkdir(dirname(filePath), { recursive: true });\n      await writeFile(filePath, result500.html, \"utf8\");\n      result.files.push(filePath);\n    }\n  }\n\n  // Process registered images with the ImageService (if sharp is installed).\n  // This is a two-pass process:\n  //   1. First render pass registers all images (already done above).\n  //   2. Process registered images → produce manifest.\n  //   3. If variants were generated, set the manifest and re-render pages\n  //      so the markup uses real <picture>/<source> with hashed URLs.\n  const registeredImages = consumeImageRegistry();\n  let manifest: ImageManifest | null = null;\n  if (registeredImages.length > 0 && config.publicDir) {\n    const manifestPath = join(config.outDir, \".nix-js\", \"image-manifest.json\");\n    const processResult = await processImageBatch(registeredImages, {\n      publicDir: config.publicDir,\n      outDir: config.outDir,\n      formats: config.imageFormats,\n      manifestPath,\n    });\n    result.imagesProcessed = processResult.count;\n\n    if (processResult.optimized && processResult.count > 0) {\n      manifest = processResult.manifest;\n      setImageManifest(manifest);\n\n      // Re-render all pages with the manifest so image() emits <picture>.\n      result.pages = 0;\n      result.files = [];\n      for (const route of routes.pages) {\n        if (!isDynamic(route.path)) {\n          const filePath = await buildPage(config, route, publicActions);\n          result.pages++;\n          result.files.push(filePath);\n          continue;\n        }\n        const dynamicFiles = await buildDynamicPages(config, route, publicActions);\n        if (dynamicFiles.length === 0) {\n          result.skipped.push(route.path);\n        } else {\n          result.pages += dynamicFiles.length;\n          result.files.push(...dynamicFiles);\n        }\n      }\n\n      // Re-render error pages too.\n      if (routes.error404) {\n        const result404 = await renderErrorPage({\n          routes,\n          status: 404,\n          config: errorConfig,\n          actions: publicActions,\n        });\n        if (result404) {\n          const filePath = join(config.outDir, \"404.html\");\n          await mkdir(dirname(filePath), { recursive: true });\n          await writeFile(filePath, result404.html, \"utf8\");\n          result.files.push(filePath);\n        }\n      }\n      if (routes.error500) {\n        const result500 = await renderErrorPage({\n          routes,\n          status: 500,\n          config: errorConfig,\n          actions: publicActions,\n        });\n        if (result500) {\n          const filePath = join(config.outDir, \"500.html\");\n          await mkdir(dirname(filePath), { recursive: true });\n          await writeFile(filePath, result500.html, \"utf8\");\n          result.files.push(filePath);\n        }\n      }\n    }\n  }\n\n  // Clear the manifest so subsequent builds start fresh.\n  setImageManifest(null);\n\n  // Fire the `build` integration hook so integrations can write\n  // post-build artifacts (sitemaps, robots.txt, search indexes, etc.)\n  // into the output directory. This runs after all pages, image variants,\n  // and the manifest are written, but before the atomic staging commit\n  // (when called via the CLI), so integration artifacts survive the swap.\n  if (config.integrations && config.integrations.length > 0) {\n    await runIntegrationHook(config.integrations, \"build\", [\n      result,\n      { root: config.root ?? config.outDir, command: \"build\" },\n    ]);\n  }\n\n  return result;\n}\n\nasync function buildPage(\n  config: BuildConfig,\n  route: PageRoute,\n  actions: Record<string, string[]>,\n): Promise<string> {\n  return buildConcretePage(config, route, {}, actions);\n}\n\nasync function buildDynamicPages(\n  config: BuildConfig,\n  route: PageRoute,\n  actions: Record<string, string[]>,\n): Promise<string[]> {\n  const { generateStaticParams } = (await import(\n    route.pagePath\n  )) as { generateStaticParams?: GenerateStaticParams };\n\n  if (!generateStaticParams) {\n    return [];\n  }\n\n  const paramList = await generateStaticParams();\n  if (!Array.isArray(paramList) || paramList.length === 0) {\n    return [];\n  }\n\n  const files: string[] = [];\n  for (const params of paramList) {\n    files.push(await buildConcretePage(config, route, params, actions));\n  }\n  return files;\n}\n\nasync function buildConcretePage(\n  config: BuildConfig,\n  route: PageRoute,\n  params: RouteParams,\n  actions: Record<string, string[]>,\n): Promise<string> {\n  const { html: htmlOut } = await renderPage({\n    route,\n    params,\n    searchParams: new URLSearchParams(),\n    config: { lang: config.lang, clientEntry: config.clientEntry, renderEndpoint: false },\n    actions,\n  });\n\n  const urlPath = isDynamic(route.path) ? buildConcreteUrl(route.path, params) : route.path;\n  const filePath = urlToFilePath(config.outDir, urlPath);\n  await mkdir(dirname(filePath), { recursive: true });\n  await writeFile(filePath, htmlOut, \"utf8\");\n\n  return filePath;\n}\n\nexport { scanRoutes, type PageRoute, type ScannedRoutes };\n","import { createRequire } from \"node:module\";\nimport type { Plugin } from \"vite\";\n\n/**\n * How the legacy interpolation transform is handled relative to the installed\n * Nix.js core and Vite plugin:\n *\n * - `\"auto\"` (default): the kit's legacy transform is only applied when the\n *   Vite plugin (`@deijose/vite-plugin-nix-js` >= 1.1.0) is NOT installed.\n *   The plugin has a more powerful state-machine lexer and takes precedence.\n * - `\"legacy\"`: always apply the kit's transform (for migrations), with a\n *   one-time deprecation warning.\n * - `\"off\"`: never apply the kit's transform. Recommended when the Vite\n *   plugin is installed.\n */\nexport type InterpolationMode = \"auto\" | \"legacy\" | \"off\";\n\nconst require = createRequire(import.meta.url);\n\nlet _warnedLegacy = false;\n\nfunction warnLegacyOnce(): void {\n  if (_warnedLegacy) return;\n  _warnedLegacy = true;\n  console.warn(\n    \"[nix-js-kit] The legacy interpolation transform is deprecated. \" +\n    \"Install @deijose/vite-plugin-nix-js >= 1.1.0 for compile-time \" +\n    \"partial attribute interpolation. Remove `interpolation: \\\"legacy\\\"` \" +\n    \"once migration is complete.\",\n  );\n}\n\n/**\n * Detects whether the Vite plugin (`@deijose/vite-plugin-nix-js`) is\n * installed and provides compile-time partial attribute interpolation.\n */\nexport function pluginSupportsPartialInterpolation(): boolean {\n  try {\n    const pkg = require(\"@deijose/vite-plugin-nix-js/package.json\") as {\n      version?: string;\n    };\n    // >= 1.1.0 has the interpolation lexer\n    const [major, minor] = (pkg.version ?? \"0.0.0\").split(\".\").map(Number);\n    return major > 1 || (major === 1 && minor >= 1);\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Detects whether the installed Nix.js core supports partial attribute\n * interpolation natively (via the public `templateFeatures` capability).\n * Note: as of core v3.4.0, this is always false — the lexer moved to the\n * Vite plugin.\n */\nexport function coreSupportsPartialInterpolation(): boolean {\n  try {\n    const core = require(\"@deijose/nix-js\") as {\n      templateFeatures?: { partialAttributeInterpolation?: boolean };\n    };\n    return core?.templateFeatures?.partialAttributeInterpolation === true;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Resolves whether the kit's legacy transform should be applied.\n *\n * In `\"auto\"` mode, the kit's transform runs only when neither the Vite\n * plugin nor the core provides partial interpolation. When the Vite plugin\n * is installed (>= 1.1.0), it takes precedence and the kit's transform is\n * skipped to avoid double-processing.\n */\nexport function shouldUseLegacyInterpolation(mode: InterpolationMode): boolean {\n  if (mode === \"off\") return false;\n  if (mode === \"legacy\") {\n    warnLegacyOnce();\n    return true;\n  }\n  // auto: skip if the Vite plugin handles it\n  if (pluginSupportsPartialInterpolation()) return false;\n  // fallback: use legacy if core doesn't support it natively\n  return !coreSupportsPartialInterpolation();\n}\n\n/**\n * Transforms Nix.js `html\\`\\`` templates so that attributes with partial\n * interpolation become a single interpolation expression.\n *\n * Nix.js requires every dynamic attribute to be a single interpolation covering\n * the whole value. This plugin rewrites patterns such as:\n *\n *   html\\`<a href=\"/blog/${slug}\">...</a>\\`\n *\n * into:\n *\n *   html\\`<a href=${\"/blog/\" + slug}>...</a>\\`\n *\n * Only files inside the app and islands directories are processed.\n *\n * @deprecated Nix.js core supports partial attribute interpolation natively.\n *   Keep this transform only for migrations against older cores\n *   (`interpolation: \"legacy\"`).\n */\nexport interface InterpolationPluginOptions {\n  appDir?: string;\n  islandsDir?: string;\n}\n\nconst HTML_TAG = \"html\";\nconst TEMPLATE_START = \"`\";\n\n/**\n * Scans a `${...}` interpolation starting at `start` (where content[start] is\n * `$` and content[start + 1] is `{`), honoring nested braces, strings and\n * escape sequences. Returns the index just past the closing `}`.\n */\nfunction scanInterpolation(content: string, start: number): number {\n  let depth = 1;\n  let i = start + 2;\n  while (i < content.length && depth > 0) {\n    const c = content[i];\n    if (c === \"\\\\\") {\n      i += 2;\n      continue;\n    }\n    if (c === '\"' || c === \"'\" || c === \"`\") {\n      const q = c;\n      i++;\n      while (i < content.length) {\n        if (content[i] === \"\\\\\") {\n          i += 2;\n          continue;\n        }\n        if (content[i] === q) break;\n        i++;\n      }\n      i++;\n      continue;\n    }\n    if (c === \"{\") depth++;\n    else if (c === \"}\") depth--;\n    i++;\n  }\n  return i;\n}\n\n/**\n * Scans a quoted attribute value starting at `start` (where content[start] is\n * the quote character). Handles escapes, `${...}` interpolations with nested\n * braces, and nested quotes. Returns the index just past the closing quote,\n * the raw inner text (escapes preserved as in the source) and whether the\n * value contains at least one interpolation.\n */\nfunction scanQuotedValue(\n  content: string,\n  start: number,\n  quote: string,\n): { end: number; inside: string; hasInterp: boolean } {\n  let i = start + 1;\n  let inside = \"\";\n  let hasInterp = false;\n  while (i < content.length) {\n    const c = content[i];\n    if (c === \"\\\\\") {\n      inside += c + (content[i + 1] ?? \"\");\n      i += 2;\n      continue;\n    }\n    if (c === quote) {\n      i++;\n      break;\n    }\n    if (c === \"$\" && content[i + 1] === \"{\") {\n      const end = scanInterpolation(content, i);\n      inside += content.slice(i, end);\n      i = end;\n      hasInterp = true;\n      continue;\n    }\n    inside += c;\n    i++;\n  }\n  return { end: i, inside, hasInterp };\n}\n\n/**\n * Converts the inner text of a quoted attribute value (which may contain\n * `${...}` interpolations) into a JS expression. Literal parts are JSON\n * encoded; interpolations keep their raw expression text.\n *\n * Examples:\n *   /blog/${slug}     -> \"/blog/\" + (slug)\n *   ${slug}           -> (slug)\n *   tag ${cls({a:1})} -> \"tag \" + (cls({a:1}))\n */\nfunction valueToExpression(value: string): string {\n  const parts: string[] = [];\n  let i = 0;\n  let literal = \"\";\n  const flush = () => {\n    if (literal) {\n      parts.push(JSON.stringify(unescapeAttributeLiteral(literal)));\n      literal = \"\";\n    }\n  };\n\n  while (i < value.length) {\n    if (value[i] === \"\\\\\") {\n      literal += value[i] + (value[i + 1] ?? \"\");\n      i += 2;\n      continue;\n    }\n    if (value[i] === \"$\" && value[i + 1] === \"{\") {\n      flush();\n      const end = scanInterpolation(value, i);\n      const expr = value.slice(i + 2, end - 1).trim();\n      if (expr) parts.push(`(${expr})`);\n      i = end;\n      continue;\n    }\n    literal += value[i];\n    i++;\n  }\n  flush();\n\n  if (parts.length === 0) return '\"\"';\n  if (parts.length === 1) return parts[0] as string;\n  return parts.join(\" + \");\n}\n\n/**\n * Unescapes escape sequences that appear inside a JS template literal so the\n * JSON.stringify output matches the runtime string value.\n */\nfunction unescapeAttributeLiteral(literal: string): string {\n  const escapes: Record<string, string> = {\n    n: \"\\n\",\n    t: \"\\t\",\n    r: \"\\r\",\n  };\n  let out = \"\";\n  let i = 0;\n  while (i < literal.length) {\n    const c = literal[i];\n    if (c === \"\\\\\" && i + 1 < literal.length) {\n      const next = literal[i + 1];\n      if (next in escapes) {\n        out += escapes[next];\n        i += 2;\n        continue;\n      }\n      out += next;\n      i += 2;\n      continue;\n    }\n    out += c;\n    i++;\n  }\n  return out;\n}\n\n/**\n * Rewrites quoted attribute values that contain interpolations inside html``\n * templates, leaving everything else untouched.\n */\nfunction transformTemplateContent(content: string): string {\n  let out = \"\";\n  let i = 0;\n  const n = content.length;\n\n  while (i < n) {\n    const lt = content.indexOf(\"<\", i);\n    if (lt === -1) {\n      out += content.slice(i);\n      break;\n    }\n    out += content.slice(i, lt);\n    i = lt;\n\n    // HTML comments: copy verbatim.\n    if (content.startsWith(\"<!--\", i)) {\n      const end = content.indexOf(\"-->\", i + 4);\n      if (end === -1) {\n        out += content.slice(i);\n        break;\n      }\n      out += content.slice(i, end + 3);\n      i = end + 3;\n      continue;\n    }\n\n    // Closing tags, doctype, CDATA, processing instructions: copy verbatim.\n    if (content[i + 1] === \"/\" || content[i + 1] === \"!\" || content[i + 1] === \"?\") {\n      const gt = content.indexOf(\">\", i + 1);\n      if (gt === -1) {\n        out += content.slice(i);\n        break;\n      }\n      out += content.slice(i, gt + 1);\n      i = gt + 1;\n      continue;\n    }\n\n    // Opening tag. Copy the tag name, then walk its attributes.\n    let j = i + 1;\n    while (j < n && /[a-zA-Z0-9-]/.test(content[j])) j++;\n    out += content.slice(i, j);\n    i = j;\n\n    while (i < n) {\n      let ws = \"\";\n      while (i < n && /\\s/.test(content[i])) {\n        ws += content[i];\n        i++;\n      }\n      if (i >= n) {\n        out += ws;\n        break;\n      }\n      if (content[i] === \">\") {\n        out += ws + \">\";\n        i++;\n        break;\n      }\n      if (content[i] === \"/\" && content[i + 1] === \">\") {\n        out += ws + \"/>\";\n        i += 2;\n        break;\n      }\n      // Interpolation in the tag body (dynamic attrs/spread): copy verbatim.\n      if (content[i] === \"$\" && content[i + 1] === \"{\") {\n        const end = scanInterpolation(content, i);\n        out += ws + content.slice(i, end);\n        i = end;\n        continue;\n      }\n\n      // Attribute name.\n      let nameStart = i;\n      while (i < n && !/[\\s=/>\"'$]/.test(content[i])) i++;\n      const name = content.slice(nameStart, i);\n      if (!name) {\n        out += ws + content[i];\n        i++;\n        continue;\n      }\n\n      let eqWs = \"\";\n      while (i < n && /\\s/.test(content[i])) {\n        eqWs += content[i];\n        i++;\n      }\n\n      if (content[i] !== \"=\") {\n        out += ws + name + eqWs;\n        continue;\n      }\n\n      i++; // consume \"=\"\n      let valWs = \"\";\n      while (i < n && /\\s/.test(content[i])) {\n        valWs += content[i];\n        i++;\n      }\n\n      const quote = content[i];\n      if (quote === '\"' || quote === \"'\") {\n        const { end, inside, hasInterp } = scanQuotedValue(content, i, quote);\n        if (hasInterp) {\n          // Skip values that are a single full interpolation: Nix.js handles\n          // `attr=\"${expr}\"` natively, so only partial interpolations need the\n          // rewrite.\n          const first = scanInterpolation(inside, 0);\n          const fullValue =\n            inside.startsWith(\"${\") &&\n            first === inside.length &&\n            !inside.slice(2, first - 1).includes(\"${\");\n          if (!fullValue) {\n            // Nix.js needs the interpolation to start right after \"=\" (no space),\n            // so the whitespace before the original value is dropped.\n            out += ws + name + eqWs + \"=\" + \"${\" + valueToExpression(inside) + \"}\";\n            i = end;\n            continue;\n          }\n          out += ws + name + eqWs + \"=\" + valWs + content.slice(i, end);\n        } else {\n          out += ws + name + eqWs + \"=\" + valWs + content.slice(i, end);\n        }\n        i = end;\n        continue;\n      }\n\n      // Unquoted value: copy up to whitespace, \">\" or \"/>\".\n      let v = \"\";\n      while (\n        i < n &&\n        !/\\s/.test(content[i]) &&\n        content[i] !== \">\" &&\n        !(content[i] === \"/\" && content[i + 1] === \">\")\n      ) {\n        v += content[i];\n        i++;\n      }\n      out += ws + name + eqWs + \"=\" + valWs + v;\n    }\n  }\n\n  return out;\n}\n\n/**\n * @deprecated Use the native partial attribute interpolation of Nix.js core\n *   (core >= 3.3). Kept for legacy migrations and direct consumers.\n */\nexport function transformPartialInterpolations(source: string): string {\n  let result = \"\";\n  let i = 0;\n  while (i < source.length) {\n    // Find the next html` sequence.\n    const htmlIndex = source.indexOf(HTML_TAG, i);\n    if (htmlIndex === -1) {\n      result += source.slice(i);\n      break;\n    }\n    result += source.slice(i, htmlIndex + HTML_TAG.length);\n    i = htmlIndex + HTML_TAG.length;\n\n    // Skip whitespace before the backtick.\n    while (i < source.length && /\\s/.test(source[i])) {\n      result += source[i];\n      i++;\n    }\n    if (i >= source.length || source[i] !== TEMPLATE_START) {\n      continue;\n    }\n    result += source[i];\n    i++;\n\n    // Parse the template literal until the matching backtick.\n    let depth = 1;\n    let templateContent = \"\";\n    while (i < source.length && depth > 0) {\n      const char = source[i];\n      if (char === \"\\\\\") {\n        templateContent += char + source[i + 1];\n        i += 2;\n        continue;\n      }\n      if (char === TEMPLATE_START) {\n        depth--;\n        if (depth === 0) {\n          i++;\n          break;\n        }\n      }\n      if (char === \"$\") {\n        // Look ahead for ${...}\n        if (source[i + 1] === \"{\") {\n          const end = scanInterpolation(source, i);\n          templateContent += source.slice(i, end);\n          i = end;\n          continue;\n        }\n      }\n      templateContent += char;\n      i++;\n    }\n\n    const transformed = transformTemplateContent(templateContent);\n    result += transformed;\n    result += TEMPLATE_START;\n  }\n  return result;\n}\n\nexport function nixJsInterpolationPlugin(options: InterpolationPluginOptions = {}): Plugin {\n  const appDir = options.appDir ?? \"src/app\";\n  const islandsDir = options.islandsDir ?? \"src/islands\";\n  return {\n    name: \"nix-js-kit-interpolation\",\n    enforce: \"pre\",\n    transform(code, id) {\n      if (!id.endsWith(\".ts\") && !id.endsWith(\".js\")) return;\n      if (!id.includes(appDir) && !id.includes(islandsDir)) return;\n      if (!code.includes(\"html`\")) return;\n      const transformed = transformPartialInterpolations(code);\n      if (transformed === code) return;\n      return { code: transformed, map: null };\n    },\n  };\n}\n","import { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { dirname, extname, relative, resolve, sep } from \"node:path\";\nimport { shouldUseLegacyInterpolation, transformPartialInterpolations, type InterpolationMode } from \"../vite/interpolation-plugin.js\";\n\nexport interface TransformProjectOptions {\n  root: string;\n  appDir: string;\n  islandsDir?: string;\n  /**\n   * Absolute path to the transformed tree root. The tree mirrors the project\n   * layout relative to the common ancestor of `appDir`/`islandsDir`, so\n   * relative imports between app and islands keep resolving. Relative imports\n   * that escape that ancestor are compensated for the added directory depth.\n   */\n  outDir: string;\n  /**\n   * How the legacy interpolation transform is handled (default: \"auto\").\n   * With a Nix.js core that supports partial attribute interpolation natively\n   * the transform is not applied; use \"legacy\" for migrations against older\n   * cores and \"off\" to never transform.\n   */\n  interpolation?: InterpolationMode;\n}\n\n/**\n * Copy app (and optionally islands) source files to a transformed directory,\n * rewriting partial Nix.js attribute interpolations so they can be imported\n * by the SSG/SSR build without requiring manual syntax changes.\n */\nasync function collectTsFiles(dir: string): Promise<string[]> {\n  try {\n    const entries = await readdir(dir, { withFileTypes: true });\n    const files: string[] = [];\n    for (const entry of entries) {\n      const path = resolve(dir, entry.name);\n      if (entry.isDirectory()) {\n        files.push(...(await collectTsFiles(path)));\n      } else if (entry.isFile() && extname(path) === \".ts\") {\n        files.push(path);\n      }\n    }\n    return files;\n  } catch (err) {\n    const code = (err as NodeJS.ErrnoException).code;\n    if (code === \"ENOENT\") return [];\n    throw err;\n  }\n}\n\nfunction segments(rel: string): string[] {\n  return rel.split(/[\\\\/]+/).filter(Boolean);\n}\n\n/** Number of path segments in `rel`. */\nfunction depth(rel: string): number {\n  return segments(rel).length;\n}\n\n/** Common ancestor directory of two paths (both absolute). */\nfunction commonBase(a: string, b: string): string {\n  const sa = segments(a);\n  const sb = segments(b);\n  const prefix: string[] = [];\n  for (let i = 0; i < Math.min(sa.length, sb.length); i++) {\n    if (sa[i] === sb[i]) prefix.push(sa[i]);\n    else break;\n  }\n  return resolve(\"/\" + prefix.join(sep));\n}\n\n/**\n * Absolute path of the transformed app directory inside the mirror tree,\n * matching where `transformProjectFiles` copies the app files.\n */\nexport function transformedAppDir(\n  root: string,\n  appDir: string,\n  islandsDir: string | undefined,\n  outDir: string,\n): string {\n  const absAppDir = resolve(root, appDir);\n  const absIslandsDir = islandsDir ? resolve(root, islandsDir) : absAppDir;\n  return resolve(outDir, relative(commonBase(absAppDir, absIslandsDir), absAppDir));\n}\n\n/**\n * Rewrites relative import specifiers in non-template regions so they resolve\n * to the same targets from the transformed location.\n *\n * Imports that stay inside the mirrored subtree need no changes. Imports that\n * escape it are moved `delta` levels: a positive delta prepends that many\n * `../`, a negative one strips leading `../` segments.\n */\nfunction compensateRelativeImports(source: string, delta: number, maxUps: number): string {\n  if (delta === 0) return source;\n  const prepend = \"..\".repeat(delta) + \"/\";\n  const strip = -delta;\n  return source.replace(\n    /(?:(\\bfrom\\s*)|(\\bimport\\s*\\()|(\\bimport\\s+)|(\\bexport\\s*\\*\\s*from\\s*))([\"'])(\\.[^\"']*)\\5/g,\n    (_match, fromKw, importCall, importKw, exportStar, quote, specifier) => {\n      let ups = 0;\n      let idx = 0;\n      while (specifier.startsWith(\"../\", idx)) {\n        ups++;\n        idx += 3;\n      }\n      // Imports crossing the mirrored subtree boundary (more `..` than the\n      // file's depth below the mirror base) point outside the tree.\n      const crosses = ups > maxUps;\n      let spec = specifier;\n      if (crosses && delta > 0) {\n        spec = prepend + spec;\n      } else if (crosses && delta < 0) {\n        let removed = 0;\n        while (removed < strip && spec.startsWith(\"../\")) {\n          spec = spec.slice(3);\n          removed++;\n        }\n        if (removed < strip && spec === \"..\") {\n          spec = spec.slice(0, -2);\n          removed++;\n        }\n        if (!spec.startsWith(\".\")) spec = \"./\" + spec;\n      }\n      return (fromKw || importCall || importKw || exportStar) + quote + spec + quote;\n    },\n  );\n}\n\n/**\n * Applies import compensation to every region of `source` that is not inside\n * an `html` template literal, so attribute strings like `from \"./x.js\"` are\n * never rewritten.\n */\nfunction rewriteImportsOutsideTemplates(source: string, delta: number, maxUps: number): string {\n  if (delta === 0) return source;\n  let result = \"\";\n  let i = 0;\n  while (i < source.length) {\n    const htmlIndex = source.indexOf(\"html\", i);\n    if (htmlIndex === -1) {\n      result += compensateRelativeImports(source.slice(i), delta, maxUps);\n      break;\n    }\n    let j = htmlIndex + 4;\n    while (j < source.length && /\\s/.test(source[j])) j++;\n    if (source[j] !== \"`\") {\n      result += compensateRelativeImports(source.slice(i, htmlIndex + 4), delta, maxUps);\n      i = htmlIndex + 4;\n      continue;\n    }\n    result += compensateRelativeImports(source.slice(i, htmlIndex + 4), delta, maxUps);\n    // Copy the template literal verbatim (interpolations included).\n    let depth = 1;\n    let k = j + 1;\n    while (k < source.length && depth > 0) {\n      const c = source[k];\n      if (c === \"\\\\\") {\n        k += 2;\n        continue;\n      }\n      if (c === \"`\") {\n        depth--;\n        if (depth === 0) break;\n      }\n      if (c === \"$\" && source[k + 1] === \"{\") {\n        // Jump over the interpolation, honoring nested braces.\n        let braceDepth = 1;\n        let l = k + 2;\n        while (l < source.length && braceDepth > 0) {\n          if (source[l] === \"{\") braceDepth++;\n          else if (source[l] === \"}\") braceDepth--;\n          l++;\n        }\n        k = l;\n        continue;\n      }\n      k++;\n    }\n    if (k >= source.length) {\n      result += source.slice(j);\n      break;\n    }\n    result += source.slice(j, k + 1);\n    i = k + 1;\n  }\n  return result;\n}\n\nexport async function transformProjectFiles(options: TransformProjectOptions): Promise<void> {\n  const { root, appDir, islandsDir, outDir } = options;\n  const dirs = islandsDir ? [appDir, islandsDir] : [appDir];\n  const files: string[] = [];\n  for (const dir of dirs) {\n    files.push(...(await collectTsFiles(resolve(root, dir))));\n  }\n\n  const absAppDir = resolve(root, appDir);\n  const absIslandsDir = islandsDir ? resolve(root, islandsDir) : absAppDir;\n  const base = commonBase(absAppDir, absIslandsDir);\n\n  // Transformed files sit `delta` levels further from root than originals.\n  const delta = depth(relative(root, outDir)) - depth(relative(root, base));\n\n  for (const file of files) {\n    const source = await readFile(file, \"utf8\");\n    let output = source;\n    if (source.includes(\"html`\") && shouldUseLegacyInterpolation(options.interpolation ?? \"auto\")) {\n      const transformed = transformPartialInterpolations(source);\n      if (transformed !== source) {\n        output = transformed;\n      }\n    }\n    const rel = relative(root, file);\n    if (rel.startsWith(\"..\")) {\n      continue;\n    }\n    const baseDepth = depth(relative(base, dirname(file)));\n    output = rewriteImportsOutsideTemplates(output, delta, baseDepth);\n    const outFile = resolve(outDir, relative(base, file));\n    await mkdir(dirname(outFile), { recursive: true });\n    await writeFile(outFile, output, \"utf8\");\n  }\n}\n","/**\n * Represents a failed action result. Returned by `fail()` from server actions.\n *\n * The `__nix_js_action_failure` marker is set on the instance so the server can\n * detect it even when the value crosses a bundling boundary (e.g. the CLI is\n * bundled separately from the user's action modules).\n */\nexport class ActionFailure<TData = unknown> {\n  readonly __nix_js_action_failure = true;\n  constructor(\n    public status: number,\n    public data: TData,\n  ) {}\n}\n\n/**\n * Represents a redirect returned by a server action. Returned by `redirect()`.\n */\nexport class RedirectResponse {\n  readonly __nix_js_action_redirect = true;\n  constructor(\n    public status: number,\n    public location: string,\n  ) {}\n}\n\n/**\n * Helper to return a validation/error response from a server action.\n *\n * Both argument orders are accepted:\n *\n * ```ts\n * return fail(400, { email: \"Invalid email\" });\n * return fail({ email: \"Invalid email\" }, 400);\n * return fail({ email: \"Invalid email\" }); // defaults to status 400\n * ```\n */\nexport function fail<TData>(\n  statusOrData: number | TData,\n  dataOrStatus?: TData | number,\n): ActionFailure<unknown> {\n  if (typeof statusOrData === \"number\") {\n    return new ActionFailure(statusOrData, dataOrStatus as TData);\n  }\n  return new ActionFailure((dataOrStatus as number) ?? 400, statusOrData);\n}\n\n/**\n * Helper to return a redirect from a server action.\n *\n * Both argument orders are accepted:\n *\n * ```ts\n * return redirect(303, \"/login\");\n * return redirect(\"/login\"); // defaults to status 303\n * ```\n */\nexport function redirect(\n  statusOrLocation: number | string,\n  locationOrStatus?: string | number,\n): RedirectResponse {\n  if (typeof statusOrLocation === \"number\") {\n    return new RedirectResponse(statusOrLocation, locationOrStatus as string);\n  }\n  return new RedirectResponse((locationOrStatus as number) ?? 303, statusOrLocation);\n}\n\n/**\n * Type guard for action failures. Uses the marker field so it works across\n * bundling boundaries where `instanceof` fails.\n */\nexport function isActionFailure(value: unknown): value is ActionFailure {\n  return (\n    typeof value === \"object\" &&\n    value !== null &&\n    (value as { __nix_js_action_failure?: unknown }).__nix_js_action_failure === true\n  );\n}\n\n/**\n * Type guard for redirects. Uses the marker field so it works across bundling\n * boundaries where `instanceof` fails.\n */\nexport function isRedirectResponse(value: unknown): value is RedirectResponse {\n  return (\n    typeof value === \"object\" &&\n    value !== null &&\n    (value as { __nix_js_action_redirect?: unknown }).__nix_js_action_redirect === true\n  );\n}\n\n// --- Public error sanitization (production-safe 500 responses) ---\n\n/**\n * A stable, publicly safe error description. Never includes stacks, internal\n * paths or messages that could leak secrets or filesystem details.\n */\nexport interface PublicErrorInfo {\n  /** Stable machine-readable code for the response body. */\n  code: string;\n  /** Stable public message. In non-production this may include the raw message. */\n  message: string;\n  status: number;\n}\n\n/**\n * Maps an arbitrary thrown value to a public-safe error info. By default the\n * public message is generic; `includeDetail` (dev/verbose mode) appends the\n * original `Error.message` for local debugging.\n */\nexport function toPublicErrorInfo(error: unknown, options: { includeDetail?: boolean } = {}): PublicErrorInfo {\n  const code = \"INTERNAL_SERVER_ERROR\";\n  const status = 500;\n  if (options.includeDetail && error instanceof Error && error.message) {\n    return { code, status, message: error.message };\n  }\n  return { code, status, message: \"Internal Server Error\" };\n}\n\n/**\n * Builds a production-safe JSON error Response. Logs the raw error separately\n * (never reflected in the response body) and keeps the request id header.\n */\nexport function publicErrorResponse(\n  error: unknown,\n  options: { includeDetail?: boolean; requestId?: string } = {},\n): Response {\n  const info = toPublicErrorInfo(error, options);\n  const headers: Record<string, string> = {\n    \"Content-Type\": \"application/json; charset=utf-8\",\n    \"Cache-Control\": \"no-store\",\n  };\n  if (options.requestId) headers[\"X-Request-Id\"] = options.requestId;\n  return new Response(JSON.stringify({ error: info }), {\n    status: info.status,\n    headers,\n  });\n}\n\n/** True when the error should be re-thrown as control flow instead of a 500. */\nexport function isFirstClassResponse(error: unknown): error is Response {\n  return typeof Response !== \"undefined\" && error instanceof Response;\n}\n","// --- Origin verification (CSRF protection for server actions) ---\n//\n// Server actions accept POST requests from the browser. Without origin\n// verification, any third-party site could submit forged requests to\n// `/__nix-js/actions` on behalf of a logged-in user (CSRF).\n//\n// Strategy: compare the request's `Origin` (or `Referer` fallback) host against\n// the target `Host` header. Same-origin requests pass; cross-origin requests\n// are rejected with 403 unless the origin is explicitly allow-listed.\n//\n// Requests without `Origin` AND without `Referer` (e.g. curl, server-to-server)\n// are accepted by default for DX, unless `strictOrigin: true` is configured.\n\nexport interface OriginCheckOptions {\n  /** Extra origins allowed to call actions (e.g. preview deployments). */\n  allowedOrigins?: string[];\n  /**\n   * When true, requests missing both `Origin` and `Referer` are rejected.\n   * Defaults to false so curl/server-to-server calls keep working.\n   */\n  strictOrigin?: boolean;\n}\n\n/**\n * Returns the host:port of a URL string, or undefined if it cannot be parsed.\n */\nfunction originOf(urlString: string | null | undefined): string | undefined {\n  if (!urlString) return undefined;\n  try {\n    const url = new URL(urlString);\n    if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return undefined;\n    return url.origin;\n  } catch {\n    return undefined;\n  }\n}\n\n/**\n * Verifies that a request originates from the same host (or an allow-listed\n * origin). Returns an error message when the request must be rejected, or\n * undefined when it is allowed.\n *\n * @param request The incoming Request to actions.\n * @param options Origin check configuration.\n */\nexport function verifyOrigin(\n  request: Request,\n  options: OriginCheckOptions = {},\n): string | undefined {\n  const targetOrigin = originOf(request.url);\n  if (!targetOrigin) return \"Invalid target URL\";\n\n  const origin = request.headers.get(\"Origin\");\n  const referer = request.headers.get(\"Referer\");\n  if (!origin && !referer) {\n    return options.strictOrigin\n      ? \"Missing Origin and Referer headers\"\n      : undefined;\n  }\n\n  const sourceOrigin = origin ? originOf(origin) : originOf(referer);\n  if (!sourceOrigin) return origin ? \"Invalid Origin header\" : \"Invalid Referer header\";\n  if (sourceOrigin === targetOrigin) return undefined;\n\n  if (options.allowedOrigins?.some((allowed) => originOf(allowed) === sourceOrigin)) return undefined;\n\n  return `Cross-origin request blocked: source \"${sourceOrigin}\" != target \"${targetOrigin}\"`;\n}\n\n/** Builds a 403 Response for a rejected origin. */\nexport function originForbidden(message: string): Response {\n  return new Response(message, {\n    status: 403,\n    headers: { \"Content-Type\": \"text/plain; charset=utf-8\" },\n  });\n}\n","import type { ActionRequest } from \"./index.js\";\nimport { isActionFailure, isRedirectResponse, publicErrorResponse } from \"../errors.js\";\nimport { verifyOrigin, originForbidden, type OriginCheckOptions } from \"./origin.js\";\nimport {\n  encodeActionErrorCookie,\n  setActionErrorCookieHeader,\n} from \"./error-store.js\";\n\n/**\n * Resolves a server action by name and optional page scope.\n */\nexport type ActionResolver = (\n  name: string,\n  page?: string,\n) => Promise<((...args: unknown[]) => unknown) | undefined>;\n\n/** Options shared by `handleActionRequest` callers for CSRF protection. */\nexport interface ActionSecurityOptions extends OriginCheckOptions {\n  /** Maximum body size in bytes. Defaults to 1MB (1_048_576). */\n  bodyLimit?: number;\n}\n\n/** Default body size limit: 1MB. */\nconst DEFAULT_BODY_LIMIT = 1_048_576;\n\n/**\n * Reads the request body as text, enforcing a maximum size.\n * Returns a 413 response if the body exceeds the limit.\n */\nasync function readBodyWithLimit(\n  request: Request,\n  limit: number,\n): Promise<{ ok: true; text: string } | { ok: false; response: Response }> {\n  const contentLength = request.headers.get(\"Content-Length\");\n  if (contentLength && parseInt(contentLength, 10) > limit) {\n    return {\n      ok: false,\n      response: new Response(\"Request body too large\", {\n        status: 413,\n        headers: { \"Content-Type\": \"text/plain\" },\n      }),\n    };\n  }\n  // Read the body as a stream with a size cap to prevent memory exhaustion\n  // from chunked transfer encoding without Content-Length.\n  const reader = request.body?.getReader();\n  if (!reader) {\n    return { ok: true, text: \"\" };\n  }\n  const chunks: Uint8Array[] = [];\n  let totalSize = 0;\n  try {\n    for (; ;) {\n      const { done, value } = await reader.read();\n      if (done) break;\n      totalSize += value.byteLength;\n      if (totalSize > limit) {\n        try { reader.cancel(); } catch { /* ignore */ }\n        return {\n          ok: false,\n          response: new Response(\"Request body too large\", {\n            status: 413,\n            headers: { \"Content-Type\": \"text/plain\" },\n          }),\n        };\n      }\n      chunks.push(value);\n    }\n  } finally {\n    try { reader.releaseLock(); } catch { /* ignore */ }\n  }\n  const total = new Uint8Array(totalSize);\n  let offset = 0;\n  for (const chunk of chunks) {\n    total.set(chunk, offset);\n    offset += chunk.byteLength;\n  }\n  return { ok: true, text: new TextDecoder().decode(total) };\n}\n\nfunction parseFormBody(body: string): Record<string, unknown> {\n  const params = new URLSearchParams(body);\n  const result: Record<string, unknown> = {};\n  for (const [key, value] of params) {\n    if (result[key] === undefined) {\n      result[key] = value;\n    } else if (Array.isArray(result[key])) {\n      (result[key] as unknown[]).push(value);\n    } else {\n      result[key] = [result[key], value];\n    }\n  }\n  return result;\n}\n\nasync function parseActionRequest(\n  request: Request,\n  bodyLimit: number = DEFAULT_BODY_LIMIT,\n): Promise<\n  | { ok: true; name: string; page?: string; args: unknown[]; wantsJson: boolean }\n  | { ok: false; response: Response }\n> {\n  if (request.method !== \"POST\") {\n    return {\n      ok: false,\n      response: new Response(\"Method not allowed\", {\n        status: 405,\n        headers: { \"Content-Type\": \"text/plain\" },\n      }),\n    };\n  }\n\n  const contentType = request.headers.get(\"Content-Type\") ?? \"\";\n  const wantsJson = (request.headers.get(\"Accept\") ?? \"\").includes(\"application/json\");\n\n  let name: string | undefined;\n  let page: string | undefined;\n  let args: unknown[] = [];\n\n  if (contentType.includes(\"application/json\")) {\n    const bodyResult = await readBodyWithLimit(request, bodyLimit);\n    if (!bodyResult.ok) return { ok: false, response: bodyResult.response };\n    let body: ActionRequest;\n    try {\n      body = JSON.parse(bodyResult.text) as ActionRequest;\n    } catch {\n      return {\n        ok: false,\n        response: new Response(\"Invalid JSON body\", {\n          status: 400,\n          headers: { \"Content-Type\": \"text/plain\" },\n        }),\n      };\n    }\n    name = body.name;\n    page = body.page;\n    args = Array.isArray(body.args) ? body.args : [];\n  } else if (\n    contentType.includes(\"application/x-www-form-urlencoded\") ||\n    contentType.includes(\"multipart/form-data\")\n  ) {\n    // For multipart, use the native formData() parser after checking\n    // Content-Length against the limit. For urlencoded, use our size-capped\n    // reader to handle chunked encoding without Content-Length.\n    if (contentType.includes(\"multipart/form-data\")) {\n      const contentLength = request.headers.get(\"Content-Length\");\n      if (contentLength && parseInt(contentLength, 10) > bodyLimit) {\n        return {\n          ok: false,\n          response: new Response(\"Request body too large\", {\n            status: 413,\n            headers: { \"Content-Type\": \"text/plain\" },\n          }),\n        };\n      }\n      let form: FormData;\n      try {\n        form = await request.formData();\n      } catch {\n        return {\n          ok: false,\n          response: new Response(\"Invalid form body\", {\n            status: 400,\n            headers: { \"Content-Type\": \"text/plain\" },\n          }),\n        };\n      }\n      name = form.get(\"__nix_js_action_name\") as string | null ?? undefined;\n      page = form.get(\"__nix_js_action_page\") as string | null ?? undefined;\n      const input: Record<string, unknown> = {};\n      for (const [key, value] of form) {\n        if (key === \"__nix_js_action_name\" || key === \"__nix_js_action_page\") continue;\n        input[key] = value;\n      }\n      args = [input];\n    } else {\n      const bodyResult = await readBodyWithLimit(request, bodyLimit);\n      if (!bodyResult.ok) return { ok: false, response: bodyResult.response };\n      const form = parseFormBody(bodyResult.text);\n      name = form.__nix_js_action_name as string | undefined;\n      page = form.__nix_js_action_page as string | undefined;\n      const input: Record<string, unknown> = {};\n      for (const [key, value] of Object.entries(form)) {\n        if (key === \"__nix_js_action_name\" || key === \"__nix_js_action_page\") continue;\n        input[key] = value;\n      }\n      args = [input];\n    }\n  } else {\n    // Try to parse a plain form body as a fallback for progressive enhancement.\n    const bodyResult = await readBodyWithLimit(request, bodyLimit);\n    if (!bodyResult.ok) return { ok: false, response: bodyResult.response };\n    const form = parseFormBody(bodyResult.text);\n    name = form.__nix_js_action_name as string | undefined;\n    page = form.__nix_js_action_page as string | undefined;\n    const input: Record<string, unknown> = {};\n    for (const [key, value] of Object.entries(form)) {\n      if (key === \"__nix_js_action_name\" || key === \"__nix_js_action_page\") continue;\n      input[key] = value;\n    }\n    args = [input];\n  }\n\n  if (!name || typeof name !== \"string\") {\n    return {\n      ok: false,\n      response: new Response(\"Missing action name\", {\n        status: 400,\n        headers: { \"Content-Type\": \"text/plain\" },\n      }),\n    };\n  }\n\n  return { ok: true, name, page, args, wantsJson };\n}\n\n/**\n * Handles a POST request to the server action endpoint.\n *\n * Accepts both JSON requests (`{ name, page?, args }`) and HTML form submissions\n * for progressive enhancement. The provided resolver looks up the action\n * implementation, invokes it with the supplied arguments and returns the result\n * as JSON or redirects back to the request origin for form submissions.\n *\n * Origin verification (CSRF protection) runs before parsing the body: any\n * cross-origin POST is rejected with 403 unless its origin is allow-listed via\n * `security.allowedOrigins`.\n *\n * For progressive-enhancement form submissions that fail, the failure payload\n * is relayed back via a short-lived `__nix_js_action_error` cookie (SameSite=Lax,\n * Max-Age=15s) instead of a query param, so errors do not leak into browser\n * history, server logs or third-party Referer headers.\n */\nexport async function handleActionRequest(\n  request: Request,\n  resolveAction: ActionResolver,\n  security: ActionSecurityOptions = {},\n): Promise<Response> {\n  // CSRF: verify same-origin (or allow-listed) before doing any work.\n  const originError = verifyOrigin(request, security);\n  if (originError) return originForbidden(originError);\n\n  const parsed = await parseActionRequest(request, security.bodyLimit ?? DEFAULT_BODY_LIMIT);\n  if (!parsed.ok) return parsed.response;\n\n  const { name, page, args, wantsJson } = parsed;\n\n  try {\n    const action = await resolveAction(name, page);\n    if (!action) {\n      const message = page ? `Action not found: ${name} (page: ${page})` : `Action not found: ${name}`;\n      return new Response(message, {\n        status: 404,\n        headers: { \"Content-Type\": \"text/plain\" },\n      });\n    }\n\n    const result = await action(...args);\n\n    if (isActionFailure(result)) {\n      if (wantsJson) {\n        return new Response(JSON.stringify({ __nix_js_action_failure: true, status: result.status, data: result.data }), {\n          status: result.status,\n          headers: { \"Content-Type\": \"application/json\" },\n        });\n      }\n      // Progressive enhancement: redirect back with the failure in a cookie.\n      const referer = request.headers.get(\"Referer\") ?? \"/\";\n      const url = new URL(referer, \"http://localhost\");\n      const { value } = encodeActionErrorCookie(result.data, result.status);\n      return new Response(null, {\n        status: 303,\n        headers: {\n          Location: url.pathname + url.search,\n          \"Content-Type\": \"text/plain\",\n          \"Set-Cookie\": setActionErrorCookieHeader(value),\n        },\n      });\n    }\n\n    if (isRedirectResponse(result)) {\n      if (wantsJson) {\n        return new Response(\n          JSON.stringify({ __nix_js_action_redirect: true, status: result.status, location: result.location }),\n          {\n            status: 200,\n            headers: { \"Content-Type\": \"application/json\" },\n          },\n        );\n      }\n      return new Response(null, {\n        status: result.status,\n        headers: { Location: result.location, \"Content-Type\": \"text/plain\" },\n      });\n    }\n\n    if (wantsJson) {\n      return new Response(JSON.stringify(result ?? null), {\n        status: 200,\n        headers: { \"Content-Type\": \"application/json\" },\n      });\n    }\n\n    // For progressive enhancement (plain form POST), redirect back.\n    const referer = request.headers.get(\"Referer\") ?? \"/\";\n    return new Response(null, {\n      status: 303,\n      headers: {\n        Location: typeof result === \"string\" ? result : referer,\n        \"Content-Type\": \"text/plain\",\n      },\n    });\n  } catch (err) {\n    console.error(\"[nix-js-kit] Action error:\", err);\n    return publicErrorResponse(err, { includeDetail: false });\n  }\n}\n\nexport { verifyOrigin, originForbidden, type OriginCheckOptions } from \"./origin.js\";\nexport {\n  decodeActionErrorCookie,\n  clearActionErrorCookieHeader,\n  setActionErrorCookieHeader,\n  ACTION_ERROR_COOKIE,\n} from \"./error-store.js\";\n","import { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\n\nexport interface CacheEntry {\n  html: string;\n  generatedAt: number;\n  revalidate: number;\n}\n\nexport interface CacheOptions {\n  cacheDir: string;\n  defaultRevalidate?: number;\n}\n\nfunction cachePath(cacheDir: string, pathname: string): string {\n  const key = createHash(\"sha256\").update(pathname).digest(\"hex\");\n  return join(cacheDir, `${key}.html.json`);\n}\n\nexport async function getCachedHtml(\n  cacheDir: string,\n  pathname: string,\n): Promise<CacheEntry | undefined> {\n  const path = cachePath(cacheDir, pathname);\n  try {\n    const raw = await readFile(path, \"utf8\");\n    const entry = JSON.parse(raw) as CacheEntry;\n    if (Date.now() - entry.generatedAt < entry.revalidate * 1000) {\n      return entry;\n    }\n  } catch {\n    // cache miss or invalid\n  }\n  return undefined;\n}\n\nexport async function setCachedHtml(\n  cacheDir: string,\n  pathname: string,\n  html: string,\n  revalidate: number,\n): Promise<void> {\n  const path = cachePath(cacheDir, pathname);\n  await mkdir(dirname(path), { recursive: true });\n  const entry: CacheEntry = { html, generatedAt: Date.now(), revalidate };\n  const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n  try {\n    await writeFile(temporaryPath, JSON.stringify(entry), \"utf8\");\n    await rename(temporaryPath, path);\n  } finally {\n    await rm(temporaryPath, { force: true });\n  }\n}\n\nexport async function isStale(cacheDir: string, pathname: string): Promise<boolean> {\n  const path = cachePath(cacheDir, pathname);\n  try {\n    const raw = await readFile(path, \"utf8\");\n    const entry = JSON.parse(raw) as CacheEntry;\n    return Date.now() - entry.generatedAt >= entry.revalidate * 1000;\n  } catch {\n    return true;\n  }\n}\n\nexport async function clearCache(cacheDir: string): Promise<void> {\n  try {\n    await rm(cacheDir, { recursive: true, force: true });\n  } catch {\n    // ignore\n  }\n}\n","import type { ApiRoute, PageRoute } from \"../router/route-scanner.js\";\n\nexport interface MatchResult {\n  route: PageRoute;\n  params: Record<string, string | string[]>;\n  searchParams: URLSearchParams;\n}\n\n/**\n * Match a request pathname against a list of page routes.\n *\n * Routes are sorted by specificity (static > dynamic > catch-all) before\n * matching, so `/about` wins over `/:slug` even if the catch-all appears first.\n *\n * URL segments are safely decoded (plan §11.1, runtime-security §10).\n */\nexport function matchRoute(\n  pathname: string,\n  routes: PageRoute[],\n): MatchResult | undefined {\n  const cleanPath = pathname.split(\"?\")[0];\n  const requestSegments = cleanPath.split(\"/\").filter(Boolean).map(safeDecodeURIComponent);\n\n  const sorted = [...routes].sort((a, b) => specificity(b.path) - specificity(a.path));\n\n  for (const route of sorted) {\n    const routeSegments = route.path.split(\"/\").filter(Boolean);\n    const match = tryMatch(requestSegments, routeSegments, route.optionalCatchAll);\n    if (match) {\n      return { route, params: match, searchParams: new URLSearchParams() };\n    }\n  }\n\n  return undefined;\n}\n\nexport interface ApiMatchResult<T = ApiRoute> {\n  route: T;\n  params: Record<string, string | string[]>;\n}\n\n/**\n * Match a request pathname against a list of API routes.\n */\nexport function matchApiRoute<T extends { path: string }>(pathname: string, routes: T[]): ApiMatchResult<T> | undefined {\n  const cleanPath = pathname.split(\"?\")[0];\n  const requestSegments = cleanPath.split(\"/\").filter(Boolean).map(safeDecodeURIComponent);\n\n  const sorted = [...routes].sort((a, b) => specificity(b.path) - specificity(a.path));\n\n  for (const route of sorted) {\n    const routeSegments = route.path.split(\"/\").filter(Boolean);\n    const match = tryMatch(requestSegments, routeSegments);\n    if (match) {\n      return { route, params: match };\n    }\n  }\n\n  return undefined;\n}\n\n/**\n * Safely decodes a URI component. If decoding fails (malformed % sequences),\n * returns the original string rather than throwing (runtime-security §10).\n */\nfunction safeDecodeURIComponent(segment: string): string {\n  try {\n    return decodeURIComponent(segment);\n  } catch {\n    return segment;\n  }\n}\n\nfunction specificity(path: string): number {\n  return path.split(\"/\").filter(Boolean).reduce((score, segment) => {\n    if (segment.endsWith(\"*\")) return score;\n    if (segment.startsWith(\":\")) return score + 1;\n    return score + 2;\n  }, 0);\n}\n\nfunction tryMatch(\n  requestSegments: string[],\n  routeSegments: string[],\n  optionalCatchAll = false,\n): Record<string, string | string[]> | undefined {\n  const params: Record<string, string | string[]> = {};\n\n  let i = 0;\n  for (let r = 0; r < routeSegments.length; r++) {\n    const routeSeg = routeSegments[r];\n\n    if (routeSeg.endsWith(\"*\")) {\n      // Catch-all consumes the rest of the request segments.\n      const name = routeSeg.slice(1, -1);\n      const rest = requestSegments.slice(i);\n      // For optional catch-all, empty rest is OK.\n      if (rest.length === 0 && !optionalCatchAll) return undefined;\n      params[name] = rest.length > 0 ? rest : [];\n      return params;\n    }\n\n    if (routeSeg.startsWith(\":\")) {\n      const requestSeg = requestSegments[i];\n      if (requestSeg === undefined) return undefined;\n      params[routeSeg.slice(1)] = requestSeg;\n      i++;\n      continue;\n    }\n\n    if (routeSeg !== requestSegments[i]) {\n      return undefined;\n    }\n    i++;\n  }\n\n  if (i !== requestSegments.length) return undefined;\n  return params;\n}\n","import type { NixTemplate } from \"@deijose/nix-js\";\nimport { renderToString } from \"../render/render-to-string.js\";\nimport { documentShell } from \"../build/document-shell.js\";\nimport type { PageRoute, ScannedRoutes } from \"../router/route-scanner.js\";\nimport type { BuildConfig } from \"../build/build.js\";\nimport type { PageDataLoad } from \"../types.js\";\nimport { matchRoute } from \"./match.js\";\nimport { renderPage } from \"./render.js\";\n\nexport interface StreamingPageOptions {\n  route: PageRoute;\n  params: Record<string, string | string[]>;\n  searchParams: URLSearchParams;\n  config: Pick<BuildConfig, \"lang\" | \"clientEntry\">;\n  importer?: (path: string) => Promise<unknown>;\n  actions?: Record<string, string[]>;\n  request?: Request;\n}\n\nconst defaultImport = (path: string) => import(path);\n\n/** Builds the concrete URL path for a route pattern given matched params. */\nfunction buildConcretePath(\n  routePath: string,\n  params: Record<string, string | string[]>,\n): string {\n  return routePath.replace(/:([a-zA-Z0-9_]+)(\\*)?/g, (_m, name: string, catchAll?: string) => {\n    const value = params[name];\n    if (value === undefined || value === null) return \"\";\n    return catchAll ? (Array.isArray(value) ? value.join(\"/\") : String(value)) : String(value);\n  });\n}\n\nfunction streamingScript(page: string, search: string): string {\n  const src = `\n    async function __nixJsStreamRender() {\n      try {\n        const url = \"/__nix-js/render?page=\" + encodeURIComponent(${JSON.stringify(page)}) + \"&search=\" + encodeURIComponent(${JSON.stringify(search)});\n        const res = await fetch(url);\n        if (!res.ok) throw new Error(\"Streaming render failed: \" + res.status);\n        const html = await res.text();\n        const app = document.getElementById(\"app\");\n        if (app) app.innerHTML = html;\n        document.dispatchEvent(new CustomEvent(\"nix-js:rendered\"));\n      } catch (err) {\n        console.error(\"[nix-js-kit] streaming render failed\", err);\n      }\n    }\n    __nixJsStreamRender();\n  `;\n  return `<script type=\"module\">${src}</script>`;\n}\n\n/**\n * Render a page shell that shows the loading boundary while the real content\n * is fetched and injected by the client.\n */\nexport async function renderStreamingPage(options: StreamingPageOptions): Promise<string> {\n  const { route, params, searchParams, config, importer = defaultImport, actions } = options;\n  if (!route.loadingPath) {\n    throw new Error(\"Cannot stream a page without a loading.ts boundary\");\n  }\n\n  const { default: Loading } = (await importer(route.loadingPath)) as {\n    default: () => NixTemplate;\n  };\n\n  const loadingBody = await renderToString(() => Loading());\n  const concretePath = buildConcretePath(route.path, params);\n  const body = `<div id=\"nix-js-loading\">${loadingBody}</div>${streamingScript(concretePath, searchParams.toString())}`;\n\n  // Apply <html> attributes and head scripts (e.g. data-theme and the no-flash\n  // theme script) from the root layout loader so the shell paints correctly\n  // before the real content arrives.\n  const htmlAttributes: Record<string, string> = {};\n  const headScripts: string[] = [];\n  const headLinks: string[] = [];\n  if (route.layouts.length > 0) {\n    const rootLayout = route.layouts[0];\n    const dataPath = rootLayout.replace(/layout\\.ts$/, \"layout.data.ts\");\n    if (dataPath !== rootLayout) {\n      try {\n        const mod = (await importer(dataPath)) as { load?: PageDataLoad };\n        const layoutData = mod.load ? await mod.load({ params, searchParams, request: options.request }) : undefined;\n        if (layoutData && typeof layoutData === \"object\") {\n          const attrs = (layoutData as { htmlAttributes?: Record<string, string> }).htmlAttributes;\n          if (attrs) Object.assign(htmlAttributes, attrs);\n          const scripts = (layoutData as { headScripts?: string[] }).headScripts;\n          if (Array.isArray(scripts)) headScripts.push(...scripts);\n          const links = (layoutData as { headLinks?: string[] }).headLinks;\n          if (Array.isArray(links)) headLinks.push(...links);\n        }\n      } catch {\n        // The root layout loader is optional; ignore failures here.\n      }\n    }\n  }\n\n  return documentShell({\n    title: \"Loading...\",\n    lang: config.lang,\n    body,\n    data: { __nix_js_streaming: true, page: route.path },\n    actions,\n    htmlAttributes,\n    headScripts,\n    headLinks,\n    clientEntry: config.clientEntry,\n  });\n}\n\nexport interface RenderPageBodyOptions {\n  routes: ScannedRoutes;\n  pathname: string;\n  searchParams: URLSearchParams;\n  config: Pick<BuildConfig, \"lang\" | \"clientEntry\">;\n  actions?: Record<string, string[]>;\n  importer?: (path: string) => Promise<unknown>;\n  request?: Request;\n}\n\nexport interface RenderPageBodyResult {\n  /** Inner HTML body for the page (without the document shell). */\n  body: string;\n  /** Page title extracted from the rendered shell. */\n  title: string;\n  /** Full rendered document shell (used for ISR caching). */\n  fullHtml?: string;\n  /** `Set-Cookie` value that clears a consumed action error cookie. */\n  clearActionErrorCookie?: string;\n  /** `<head>` tags (title, meta, OG, twitter) for the SPA router to merge. */\n  head?: string;\n  /** First-class Response when a loader threw one (A-22). */\n  response?: Response;\n}\n\n/** Thrown by `renderPageBody` when the requested path has no matching route. */\nexport class RouteNotFoundError extends Error {\n  constructor(pathname: string) {\n    super(`No route found for ${pathname}`);\n    this.name = \"RouteNotFoundError\";\n  }\n}\n\n/**\n * Render only the inner HTML body for a page. Used by the streaming endpoint\n * to inject the real content into the shell.\n */\nexport async function renderPageBody(options: RenderPageBodyOptions): Promise<RenderPageBodyResult> {\n  const { routes, pathname, searchParams, config, actions, importer = defaultImport, request } = options;\n  const match = matchRoute(pathname, routes.pages);\n  if (!match) {\n    throw new RouteNotFoundError(pathname);\n  }\n\n  const result = await renderPage({\n    route: match.route,\n    params: match.params,\n    searchParams,\n    config,\n    actions,\n    importer,\n    request,\n  });\n\n  // If a loader threw a Response (redirect, 404, etc.), propagate it (A-22).\n  if (result.response) {\n    return {\n      body: \"\",\n      title: \"\",\n      response: result.response,\n    };\n  }\n\n  const bodyMatch = result.html.match(/<div id=\"app\">([\\s\\S]*)<\\/div>\\s*(<script|$)/);\n  const body = bodyMatch ? bodyMatch[1].trim() : result.html;\n  const titleMatch = result.html.match(/<title[^>]*>([^<]*)<\\/title>/);\n  return {\n    body,\n    title: titleMatch ? titleMatch[1] : result.resolvedTitle ?? \"\",\n    fullHtml: result.html,\n    clearActionErrorCookie: result.clearActionErrorCookie,\n    head: result.head,\n  };\n}\n","// --- Middleware ---\n//\n// Convention: `src/middleware.ts` in the project root exports a default\n// function and an optional `config` with a `matcher` array.\n//\n//   import type { Middleware } from \"@deijose/nix-js-kit\";\n//\n//   export default function middleware(request: Request) {\n//     if (!request.headers.get(\"Cookie\")?.includes(\"session=\")) {\n//       return Response.redirect(new URL(\"/login\", request.url), 307);\n//     }\n//   }\n//\n//   export const config = { matcher: [\"/dashboard/:path*\", \"/admin/:path*\"] };\n//\n// The middleware runs before routing. Return a `Response` to short-circuit\n// (redirect, rewrite, 401, etc.). Return `undefined` or nothing to continue.\n// Use `next()` to pass headers to the loader.\n\nimport { matchRoute } from \"../ssr/match.js\";\nimport type { PageRoute } from \"../router/route-scanner.js\";\n\n/** The middleware function signature. */\nexport type Middleware = (request: Request, context: MiddlewareContext) =>\n  | Response\n  | void\n  | Promise<Response | void>;\n\n/** Context passed to the middleware function. */\nexport interface MiddlewareContext {\n  /** Helper to continue to the next handler. Can attach headers, params, and locals. */\n  next(options?: {\n    headers?: Record<string, string>;\n    params?: Record<string, string | string[]>;\n    locals?: Record<string, unknown>;\n  }): void;\n  /** Matched route params (only available if the path matches a page route). */\n  params?: Record<string, string | string[]>;\n  /** Per-request locals (populated by middleware, available to loaders/actions). */\n  locals?: Record<string, unknown>;\n}\n\n/** Configuration for the middleware module. */\nexport interface MiddlewareConfig {\n  /** Path patterns that trigger the middleware. Supports `:param` and `:param*`. */\n  matcher?: string[];\n}\n\nexport interface LoadedMiddleware {\n  handler: Middleware;\n  config: MiddlewareConfig;\n}\n\n/** Result of running middleware: either a response to short-circuit with, or continue. */\nexport type MiddlewareResult =\n  | { kind: \"response\"; response: Response }\n  | {\n    kind: \"continue\";\n    headers?: Record<string, string>;\n    params?: Record<string, string | string[]>;\n    locals?: Record<string, unknown>;\n  };\n\n/**\n * Loads the user's `src/middleware.ts` module. Returns `null` if no middleware\n * file exists. Distinguishes \"file not found\" from \"file has errors\" (§6):\n * an import error is not silently treated as \"no middleware\".\n */\nexport async function loadMiddleware(root: string): Promise<LoadedMiddleware | null> {\n  const candidates = [\n    `${root}/src/middleware.ts`,\n    `${root}/middleware.ts`,\n  ];\n\n  for (const path of candidates) {\n    try {\n      const mod = await import(path);\n      const handler = (mod.default ?? mod.middleware) as Middleware | undefined;\n      if (typeof handler !== \"function\") continue;\n      const config = (mod.config ?? {}) as MiddlewareConfig;\n      return { handler, config };\n    } catch (err) {\n      // Distinguish \"module not found\" from actual errors.\n      // If the error is a module resolution error for this specific file,\n      // it means the file doesn't exist — try the next candidate.\n      // If it's a syntax/runtime error, rethrow so the user sees it.\n      // Note: Bun's ResolveMessage is not `instanceof Error`, so match on the\n      // message property instead of relying on the class hierarchy.\n      const msg =\n        typeof err === \"object\" && err !== null && \"message\" in err\n          ? String((err as { message: unknown }).message)\n          : String(err);\n      if (\n        msg.includes(\"Cannot find module\") ||\n        msg.includes(\"Cannot find package\") ||\n        msg.includes(\"ENOENT\") ||\n        msg.includes(\"Module not found\")\n      ) {\n        // File doesn't exist — try next candidate.\n        continue;\n      }\n      // Actual error in the middleware file — rethrow (§6).\n      throw new Error(`[nix-js-kit] Error loading middleware: ${msg}`, { cause: err });\n    }\n  }\n\n  return null;\n}\n\n/**\n * Checks if a pathname matches any of the middleware's matcher patterns.\n * If no matcher is configured, the middleware runs for every request.\n *\n * Catch-all patterns (`:param*`) match both the base path and any sub-paths,\n * e.g. `/dashboard/:path*` matches `/dashboard` and `/dashboard/settings/users`.\n */\nexport function matchesMiddleware(pathname: string, config: MiddlewareConfig): boolean {\n  if (!config.matcher || config.matcher.length === 0) return true;\n\n  const cleanPath = pathname.split(\"?\")[0];\n\n  for (const pattern of config.matcher) {\n    // Exact match.\n    if (pattern === cleanPath) return true;\n\n    // Check for catch-all: `/foo/:bar*` should also match `/foo`.\n    const catchAllMatch = pattern.match(/^(.*)\\/:[\\w]+\\*$/);\n    if (catchAllMatch) {\n      const base = catchAllMatch[1];\n      if (cleanPath === base) return true;\n    }\n\n    // Use matchRoute for param matching.\n    const pseudoRoutes: PageRoute[] = [{\n      path: pattern,\n      pagePath: \"\",\n      params: [],\n      layouts: [],\n    }];\n    if (matchRoute(cleanPath, pseudoRoutes)) return true;\n  }\n\n  return false;\n}\n\n/**\n * Runs the middleware for a request. Returns the result indicating whether to\n * short-circuit with a response or continue with propagated headers/params/locals.\n *\n * Per §6: cleanup runs in `finally`, response short-circuits the pipeline,\n * headers/params/locals are propagated to downstream handlers.\n */\nexport async function runMiddleware(\n  middleware: LoadedMiddleware,\n  request: Request,\n  params?: Record<string, string | string[]>,\n): Promise<MiddlewareResult> {\n  let nextHeaders: Record<string, string> | undefined;\n  let nextParams: Record<string, string | string[]> | undefined;\n  let nextLocals: Record<string, unknown> | undefined;\n  const cleanups: Array<() => void | Promise<void>> = [];\n\n  const context: MiddlewareContext = {\n    next(options) {\n      if (options?.headers) nextHeaders = options.headers;\n      if (options?.params) nextParams = options.params;\n      if (options?.locals) nextLocals = options.locals;\n    },\n    params,\n    locals: {},\n  };\n\n  try {\n    const result = await middleware.handler(request, context);\n\n    if (result instanceof Response) {\n      return { kind: \"response\", response: result };\n    }\n\n    return {\n      kind: \"continue\",\n      headers: nextHeaders,\n      params: nextParams ?? params,\n      locals: nextLocals,\n    };\n  } finally {\n    // Run any cleanup functions (§6). Errors in cleanup are logged but\n    // do not propagate to the caller.\n    for (const cleanup of cleanups) {\n      try {\n        await cleanup();\n      } catch (err) {\n        console.error(\"[nix-js-kit] middleware cleanup error:\", err);\n      }\n    }\n  }\n}\n","import type { IncomingMessage } from \"node:http\";\n\n// Capture the global AbortController at module load time so it's immune to\n// test frameworks that replace or delete globalThis.AbortController.\nconst GlobalAbortController =\n  (globalThis as { AbortController?: typeof AbortController }).AbortController ?? AbortController;\n\nexport function incomingMessageToRequest(req: IncomingMessage, body?: BodyInit | null): Request {\n  const headers = new Headers();\n  for (let index = 0; index < req.rawHeaders.length; index += 2) {\n    headers.append(req.rawHeaders[index], req.rawHeaders[index + 1]);\n  }\n\n  const controller = new GlobalAbortController();\n  req.once(\"aborted\", () => controller.abort());\n  req.once(\"close\", () => {\n    if (!req.complete) controller.abort();\n  });\n\n  const protocol = (req.socket as typeof req.socket & { encrypted?: boolean }).encrypted ? \"https\" : \"http\";\n  const init: RequestInit = {\n    method: req.method ?? \"GET\",\n    headers,\n    signal: controller.signal,\n  };\n  if (body !== undefined && body !== null && init.method !== \"GET\" && init.method !== \"HEAD\") init.body = body;\n\n  return new Request(`${protocol}://${headers.get(\"host\") ?? \"localhost\"}${req.url ?? \"/\"}`, init);\n}\n","import { realpath, stat } from \"node:fs/promises\";\nimport { extname, resolve, sep } from \"node:path\";\n\nfunction isInside(root: string, candidate: string): boolean {\n  return candidate === root || candidate.startsWith(`${root}${sep}`);\n}\n\nfunction decodePathname(pathname: string): string | null {\n  try {\n    const decoded = decodeURIComponent(pathname);\n    if (decoded.includes(\"\\0\") || decoded.includes(\"\\\\\") || /%(?:00|2e|2f|5c)/i.test(decoded)) return null;\n    if (decoded.split(\"/\").some((segment) => segment === \"..\")) return null;\n    return decoded;\n  } catch {\n    return null;\n  }\n}\n\nexport async function resolveStaticFile(root: string, pathname: string): Promise<string | null> {\n  const decoded = decodePathname(pathname);\n  if (decoded === null) return null;\n\n  const resolvedRoot = resolve(root);\n  const relativePath = decoded.replace(/^\\/+/, \"\");\n  let candidate = resolve(resolvedRoot, relativePath);\n  if (!isInside(resolvedRoot, candidate)) return null;\n\n  try {\n    const candidateStat = await stat(candidate);\n    if (candidateStat.isDirectory()) candidate = resolve(candidate, \"index.html\");\n  } catch {\n    if (decoded.endsWith(\"/\") || extname(decoded) === \"\") candidate = resolve(candidate, \"index.html\");\n  }\n\n  if (!isInside(resolvedRoot, candidate)) return null;\n\n  try {\n    const [canonicalRoot, canonicalCandidate, candidateStat] = await Promise.all([\n      realpath(resolvedRoot),\n      realpath(candidate),\n      stat(candidate),\n    ]);\n    if (!candidateStat.isFile() || !isInside(canonicalRoot, canonicalCandidate)) return null;\n    return canonicalCandidate;\n  } catch {\n    return null;\n  }\n}\n","import { createServer, type IncomingMessage, type Server } from \"node:http\";\nimport { readFile } from \"node:fs/promises\";\nimport { extname } from \"node:path\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\nimport { scanActions, actionNames } from \"../action/scan.js\";\nimport { handleActionRequest, type ActionSecurityOptions } from \"../action/server.js\";\nimport { getCachedHtml, setCachedHtml } from \"../cache.js\";\nimport { matchApiRoute, matchRoute } from \"./match.js\";\nimport { renderPage, renderErrorPage } from \"./render.js\";\nimport { renderPageBody, renderStreamingPage, RouteNotFoundError } from \"./stream.js\";\nimport { loadMiddleware, matchesMiddleware, runMiddleware } from \"../middleware/index.js\";\nimport { incomingMessageToRequest } from \"../runtime/node-http.js\";\nimport { resolveStaticFile } from \"../runtime/static.js\";\nimport { toPublicErrorInfo } from \"../errors.js\";\n\nexport interface SsrServerOptions {\n  /** Absolute path to the app directory (e.g. /project/src/app). */\n  appDir: string;\n  /** Absolute path to the project root. When provided, action paths in the\n   * serialized HTML shell are made relative to this root. */\n  root?: string;\n  /** Absolute path to the public directory for static files (optional). */\n  publicDir?: string;\n  /** Base path for the client entry module, e.g. \"/_nix-js/entry-client.js\". */\n  clientEntry?: string;\n  /** Default language for the HTML shell. */\n  lang?: string;\n  port?: number;\n  host?: string;\n  /** Absolute path to the ISR cache directory (optional). */\n  cacheDir?: string;\n  /** Default revalidate interval in seconds when a page does not export one. */\n  defaultRevalidate?: number;\n  /** If true, render pages with loading.ts boundaries using streaming. */\n  streaming?: boolean;\n  /** CSRF / origin policy applied to the server actions endpoint. */\n  actionSecurity?: ActionSecurityOptions;\n}\n\nexport interface SsrServer {\n  server: Server;\n  listen(): Promise<void>;\n  close(): Promise<void>;\n}\n\n/**\n * Create an SSR server that renders pages on demand and serves static files.\n */\nexport async function createSsrServer(options: SsrServerOptions): Promise<SsrServer> {\n  const routes = await scanRoutes(options.appDir);\n  const actions = await scanActions(options.appDir);\n  const publicActions = actionNames(actions);\n\n  // Load user middleware (src/middleware.ts) if it exists.\n  const middleware = options.root ? await loadMiddleware(options.root) : null;\n\n  const resolveAction = async (name: string, page?: string) => {\n    const pageKey = resolveActionPageKey(page, routes);\n    const pageActions = pageKey ? actions[pageKey] : Object.values(actions).find((p) => p[name]) ?? undefined;\n    const actionPath = pageActions ? pageActions[name] : undefined;\n    if (!actionPath) return undefined;\n    const mod = (await import(actionPath)) as Record<string, unknown>;\n    const action = mod[name];\n    if (typeof action === \"function\") {\n      return action as (...args: unknown[]) => unknown;\n    }\n    return undefined;\n  };\n\n  const server = createServer(async (req, res) => {\n    let urlPath = req.url ?? \"/\";\n    if (urlPath.includes(\"?\")) urlPath = urlPath.split(\"?\")[0];\n\n    // Server actions endpoint.\n    if (urlPath === \"/__nix-js/actions\" && req.method === \"POST\") {\n      try {\n        const body = await readRequestBody(req);\n        const request = incomingMessageToRequest(req, body);\n        const response = await handleActionRequest(request, resolveAction, options.actionSecurity);\n        res.writeHead(response.status, Object.fromEntries(response.headers.entries()));\n        res.end(await response.text());\n      } catch (err) {\n        console.error(\"[action] error handling\", err);\n        res.writeHead(500, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n        res.end(toPublicErrorInfo(err).message);\n      }\n      return;\n    }\n\n    if (urlPath === \"/__nix-js/render\") {\n      const renderUrl = new URL(req.url ?? \"/\", \"http://localhost\");\n      const page = renderUrl.searchParams.get(\"page\") ?? \"/\";\n      const search = renderUrl.searchParams.get(\"search\") ?? \"\";\n      const wantsJson = (req.headers[\"accept\"] ?? \"\").includes(\"application/json\");\n      try {\n        const request = incomingMessageToRequest(req);\n\n        // ISR: cache the real content served by this endpoint when a cache\n        // directory is configured, so streamed pages regenerate on a TTL.\n        let body: string;\n        let title: string;\n        let lastRenderedCookie: string | undefined;\n        let lastRenderedHead: string | undefined;\n        const ttl = await resolveTtl(options, page, routes);\n        const cacheKey = `/__nix-js/render${page}?${search}`;\n        if (options.cacheDir && typeof ttl === \"number\" && canUsePublicCache(request)) {\n          const cached = await getCachedHtml(options.cacheDir, cacheKey);\n          if (cached) {\n            body = extractBody(cached.html);\n            title = extractTitle(cached.html);\n          } else {\n            const rendered = await renderPageBody({\n              routes,\n              pathname: page,\n              searchParams: new URLSearchParams(search),\n              config: { lang: options.lang ?? \"es\", clientEntry: options.clientEntry },\n              actions: publicActions,\n              request,\n            });\n            body = rendered.body;\n            title = rendered.title;\n            lastRenderedCookie = rendered.clearActionErrorCookie;\n            lastRenderedHead = rendered.head;\n            await setCachedHtml(options.cacheDir, cacheKey, rendered.fullHtml ?? \"\", ttl);\n          }\n        } else {\n          const rendered = await renderPageBody({\n            routes,\n            pathname: page,\n            searchParams: new URLSearchParams(search),\n            config: { lang: options.lang ?? \"es\", clientEntry: options.clientEntry },\n            actions: publicActions,\n            request,\n          });\n          body = rendered.body;\n          title = rendered.title;\n          lastRenderedCookie = rendered.clearActionErrorCookie;\n          lastRenderedHead = rendered.head;\n        }\n\n        if (wantsJson) {\n          const headers: Record<string, string> = { \"Content-Type\": \"application/json; charset=utf-8\" };\n          // The SPA router applies the cookie via document.cookie so the next\n          // full reload does not re-feed stale errors to the page.\n          const setCookie = lastRenderedCookie;\n          if (setCookie) headers[\"X-Nix-Action-Clear-Cookie\"] = setCookie;\n          res.writeHead(200, headers);\n          res.end(JSON.stringify({ title, body, head: lastRenderedHead, clearActionErrorCookie: setCookie }));\n        } else {\n          const headers: Record<string, string> = { \"Content-Type\": \"text/html; charset=utf-8\" };\n          if (lastRenderedCookie) headers[\"Set-Cookie\"] = lastRenderedCookie;\n          res.writeHead(200, headers);\n          res.end(body);\n        }\n      } catch (err) {\n        if (err instanceof RouteNotFoundError) {\n          console.log(`[ssr] render endpoint: no route for ${page}`);\n          res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n          res.end(\"Not Found\");\n          return;\n        }\n        console.error(\"[ssr] streaming render error\", err);\n        res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n        res.end(\"Internal Server Error\");\n      }\n      return;\n    }\n\n    // Run middleware before routing (skip for internal endpoints handled above).\n    let middlewareHeaders: Record<string, string> | undefined;\n    if (middleware && matchesMiddleware(urlPath, middleware.config)) {\n      const mwResult = await runMiddleware(middleware, incomingMessageToRequest(req));\n      if (mwResult.kind === \"response\") {\n        res.writeHead(mwResult.response.status, Object.fromEntries(mwResult.response.headers.entries()));\n        res.end(Buffer.from(await mwResult.response.arrayBuffer()));\n        return;\n      }\n      middlewareHeaders = mwResult.headers;\n    }\n\n    // Try API routes first.\n    const apiMatch = matchApiRoute(urlPath, routes.api);\n    if (apiMatch) {\n      try {\n        const mod = (await import(apiMatch.route.routePath)) as Record<\n          string,\n          (request: Request, context?: { params: Record<string, string | string[]> }) => unknown\n        >;\n        const handler = mod[req.method ?? \"GET\"];\n        if (typeof handler !== \"function\") {\n          res.writeHead(405, { \"Content-Type\": \"text/plain\" });\n          res.end(`Method not allowed: ${req.method}`);\n          return;\n        }\n        const body = req.method && req.method !== \"GET\" && req.method !== \"HEAD\" ? await readRequestBody(req) : undefined;\n        const request = incomingMessageToRequest(req, body);\n        applyHeaders(request.headers, middlewareHeaders);\n        const response = (await handler(request, { params: apiMatch.params })) as Response;\n        res.writeHead(response.status, Object.fromEntries(response.headers.entries()));\n        res.end(Buffer.from(await response.arrayBuffer()));\n      } catch (err) {\n        console.error(\"[api] error handling\", urlPath, err);\n        res.writeHead(500, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n        res.end(toPublicErrorInfo(err).message);\n      }\n      return;\n    }\n\n    // Try static files first.\n    if (options.publicDir) {\n      try {\n        const served = await tryServeStatic(res, options.publicDir, urlPath);\n        if (served) return;\n      } catch (err) {\n        console.error(\"[static] error serving\", urlPath, err);\n      }\n    }\n\n    // Try SSR page rendering.\n    const match = matchRoute(urlPath, routes.pages);\n    const config = { lang: options.lang ?? \"es\", clientEntry: options.clientEntry };\n    if (match) {\n      try {\n        const request = incomingMessageToRequest(req);\n        applyHeaders(request.headers, middlewareHeaders);\n\n        let html: string;\n        let clearActionErrorCookie: string | undefined;\n        const revalidate = match.route.dataPath\n          ? ((await import(match.route.dataPath)) as { revalidate?: number }).revalidate\n          : undefined;\n        const ttl = revalidate ?? options.defaultRevalidate;\n        const useStreaming = options.streaming !== false && match.route.loadingPath;\n        if (useStreaming) {\n          html = await renderStreamingPage({\n            route: match.route,\n            params: match.params,\n            searchParams: new URLSearchParams(req.url?.split(\"?\")[1] ?? \"\"),\n            config,\n            actions: publicActions,\n            request,\n          });\n        } else if (options.cacheDir && typeof ttl === \"number\" && canUsePublicCache(request)) {\n          const cacheKey = new URL(request.url).pathname + new URL(request.url).search;\n          const cached = await getCachedHtml(options.cacheDir, cacheKey);\n          if (cached) {\n            html = cached.html;\n          } else {\n            const result = await renderPage({\n              route: match.route,\n              params: match.params,\n              searchParams: new URLSearchParams(req.url?.split(\"?\")[1] ?? \"\"),\n              config,\n              actions: publicActions,\n              request,\n            });\n            html = result.html;\n            clearActionErrorCookie = result.clearActionErrorCookie;\n            await setCachedHtml(options.cacheDir, cacheKey, html, ttl);\n          }\n        } else {\n          const result = await renderPage({\n            route: match.route,\n            params: match.params,\n            searchParams: new URLSearchParams(req.url?.split(\"?\")[1] ?? \"\"),\n            config,\n            actions: publicActions,\n            request,\n          });\n          html = result.html;\n          clearActionErrorCookie = result.clearActionErrorCookie;\n        }\n        const responseHeaders: Record<string, string> = { \"Content-Type\": \"text/html; charset=utf-8\" };\n        if (clearActionErrorCookie) responseHeaders[\"Set-Cookie\"] = clearActionErrorCookie;\n        res.writeHead(200, responseHeaders);\n        res.end(html);\n        return;\n      } catch (err) {\n        console.error(\"[ssr] error rendering\", urlPath, err);\n        const errorResult = await renderErrorPage({\n          routes,\n          status: 500,\n          error: err,\n          config,\n          actions: publicActions,\n        });\n        if (errorResult) {\n          res.writeHead(errorResult.status, { \"Content-Type\": \"text/html; charset=utf-8\" });\n          res.end(errorResult.html);\n        } else {\n          res.writeHead(500, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n          res.end(toPublicErrorInfo(err).message);\n        }\n        return;\n      }\n    }\n\n    const errorResult = await renderErrorPage({\n      routes,\n      status: 404,\n      config,\n      actions: publicActions,\n    });\n    if (errorResult) {\n      res.writeHead(errorResult.status, { \"Content-Type\": \"text/html; charset=utf-8\" });\n      res.end(errorResult.html);\n      return;\n    }\n\n    res.writeHead(404, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n    res.end(`Not found: ${req.url}`);\n  });\n\n  return {\n    server,\n    listen() {\n      return new Promise((resolve) => {\n        server.listen(options.port ?? 3000, options.host ?? \"127.0.0.1\", () => {\n          console.log(\n            `\\n  → SSR server http://${options.host ?? \"127.0.0.1\"}:${options.port ?? 3000}`,\n          );\n          resolve();\n        });\n      });\n    },\n    close() {\n      return new Promise((resolve, reject) => {\n        server.close((err) => (err ? reject(err) : resolve()));\n      });\n    },\n  };\n}\n\nasync function tryServeStatic(\n  res: import(\"node:http\").ServerResponse,\n  publicDir: string,\n  urlPath: string,\n): Promise<boolean> {\n  const filePath = await resolveStaticFile(publicDir, urlPath);\n  if (!filePath) return false;\n  const contentType = guessContentType(filePath);\n  let data: Buffer | string = await readFile(filePath);\n  if (contentType.includes(\"text/html\")) {\n    // The SSG build bakes `render-endpoint content=\"off\"` into the static\n    // HTML so purely static deployments never probe the endpoint. This server\n    // (SSR `start`) DOES expose /__nix-js/render, so advertise it: SPA\n    // navigations then fetch live server-rendered content instead of the\n    // stale static file (e.g. after a mutating server action).\n    data = data\n      .toString(\"utf8\")\n      .replace(\n        '<meta name=\"nix-js:render-endpoint\" content=\"off\" />',\n        '<meta name=\"nix-js:render-endpoint\" content=\"on\" />',\n      );\n  }\n  res.writeHead(200, { \"Content-Type\": contentType, \"Content-Length\": Buffer.byteLength(data) });\n  res.end(data);\n  return true;\n}\n\nfunction canUsePublicCache(request: Request): boolean {\n  return !request.headers.has(\"cookie\") && !request.headers.has(\"authorization\");\n}\n\nfunction applyHeaders(headers: Headers, values: Record<string, string> | undefined): void {\n  if (!values) return;\n  for (const [name, value] of Object.entries(values)) headers.set(name, value);\n}\n\nfunction readRequestBody(req: IncomingMessage): Promise<string> {\n  return new Promise((resolve, reject) => {\n    let body = \"\";\n    req.setEncoding(\"utf8\");\n    req.on(\"data\", (chunk) => {\n      body += chunk;\n    });\n    req.on(\"end\", () => resolve(body));\n    req.on(\"error\", reject);\n  });\n}\n\nfunction guessContentType(filePath: string): string {\n  switch (extname(filePath)) {\n    case \".html\":\n      return \"text/html; charset=utf-8\";\n    case \".js\":\n    case \".mjs\":\n      return \"application/javascript; charset=utf-8\";\n    case \".css\":\n      return \"text/css; charset=utf-8\";\n    case \".json\":\n      return \"application/json; charset=utf-8\";\n    case \".svg\":\n      return \"image/svg+xml\";\n    case \".png\":\n      return \"image/png\";\n    case \".jpg\":\n    case \".jpeg\":\n      return \"image/jpeg\";\n    case \".webp\":\n      return \"image/webp\";\n    case \".avif\":\n      return \"image/avif\";\n    case \".ico\":\n      return \"image/x-icon\";\n    case \".woff\":\n      return \"font/woff\";\n    case \".woff2\":\n      return \"font/woff2\";\n    case \".wasm\":\n      return \"application/wasm\";\n    default:\n      return \"application/octet-stream\";\n  }\n}\n\n/**\n * Maps a concrete page path (e.g. `/movies/inception`) to the route pattern\n * key used by the action registry (e.g. `/movies/:slug`). Falls back to the\n * path itself when it matches an exact registry key.\n */\nexport function resolveActionPageKey(\n  page: string | undefined,\n  routes: Awaited<ReturnType<typeof scanRoutes>>,\n): string | undefined {\n  if (!page) return undefined;\n  if (routes.pages.some((route) => route.path === page)) return page;\n  const match = matchRoute(page, routes.pages);\n  return match ? match.route.path : page;\n}\n\n/** Resolves the ISR TTL for a page: route `revalidate` or the default. */\nasync function resolveTtl(\n  options: SsrServerOptions,\n  pathname: string,\n  routes: Awaited<ReturnType<typeof scanRoutes>>,\n): Promise<number | undefined> {\n  const match = matchRoute(pathname, routes.pages);\n  if (!match) return undefined;\n  const revalidate = match.route.dataPath\n    ? ((await import(match.route.dataPath)) as { revalidate?: number }).revalidate\n    : undefined;\n  return revalidate ?? options.defaultRevalidate;\n}\n\nfunction extractBody(fullHtml: string): string {\n  const match = fullHtml.match(/<div id=\"app\">([\\s\\S]*)<\\/div>\\s*(<script|$)/);\n  return match ? match[1].trim() : fullHtml;\n}\n\nfunction extractTitle(fullHtml: string): string {\n  const match = fullHtml.match(/<title>([^<]*)<\\/title>/);\n  return match ? match[1] : \"\";\n}\n","import { access } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport { loadConfigFromFile } from \"vite\";\nimport type { Adapter } from \"../adapters/index.js\";\nimport type { ImageFormat } from \"../image/index.js\";\nimport type { NixKitIntegration } from \"../integrations/index.js\";\nimport { runIntegrationHook } from \"../integrations/index.js\";\n\nexport type NixOutputMode = \"static\" | \"server\" | \"hybrid\";\nexport type TrailingSlashMode = \"always\" | \"never\" | \"ignore\";\n\nexport interface NixConfig {\n  root?: string;\n  appDir?: string;\n  islandsDir?: string;\n  contentDir?: string;\n  publicDir?: string;\n  outDir?: string;\n  site?: string;\n  base?: string;\n  trailingSlash?: TrailingSlashMode;\n  output?: NixOutputMode;\n  adapter?: Adapter;\n  images?: {\n    formats?: ImageFormat[];\n    quality?: number;\n    strict?: boolean;\n  };\n  cache?: {\n    dir?: string;\n    defaultRevalidate?: number;\n  };\n  security?: {\n    allowedOrigins?: string[];\n    strictOrigin?: boolean;\n    bodyLimit?: number;\n    /** Security response headers. Set to `false` to disable defaults. */\n    headers?: SecurityHeadersConfig | false;\n  };\n  router?: {\n    enabled?: boolean;\n    prefetch?: boolean;\n  };\n  integrations?: NixKitIntegration[];\n}\n\n/** Security headers configuration (runtime-security §14). */\nexport interface SecurityHeadersConfig {\n  /** X-Content-Type-Options: nosniff. Default: true. */\n  noSniff?: boolean;\n  /** Referrer-Policy. Default: \"strict-origin-when-cross-origin\". */\n  referrerPolicy?: string;\n  /**\n   * Content-Security-Policy. Set to a string to enable.\n   * Use \"nonce\" placeholder to inject per-request nonces.\n   */\n  contentSecurityPolicy?: string;\n  /** Strict-Transport-Security. Only applied under HTTPS. Default: unset. */\n  hsts?: string | true;\n  /** X-Frame-Options or CSP frame-ancestors. Default: \"SAMEORIGIN\". */\n  frameAncestors?: string;\n  /** Permissions-Policy. Default: unset. */\n  permissionsPolicy?: string;\n}\n\nexport interface ResolvedNixConfig {\n  root: string;\n  appDir: string;\n  islandsDir: string;\n  contentDir: string;\n  publicDir: string;\n  outDir: string;\n  site?: string;\n  base: string;\n  trailingSlash: TrailingSlashMode;\n  output: NixOutputMode;\n  adapter?: Adapter;\n  images: {\n    formats: ImageFormat[];\n    quality: number;\n    strict: boolean;\n  };\n  cache: {\n    dir: string;\n    defaultRevalidate?: number;\n  };\n  security: {\n    allowedOrigins: string[];\n    strictOrigin: boolean;\n    bodyLimit: number;\n    headers: SecurityHeadersConfig | false;\n  };\n  router: {\n    enabled: boolean;\n    prefetch: boolean;\n  };\n  integrations: NixKitIntegration[];\n  configFile?: string;\n}\n\nexport interface LoadNixConfigOptions {\n  root?: string;\n  configFile?: string;\n  command?: \"dev\" | \"build\" | \"preview\" | \"start\" | \"check\" | \"routes\" | \"doctor\";\n  mode?: string;\n  overrides?: NixConfig;\n}\n\nexport function defineConfig(config: NixConfig): NixConfig {\n  return config;\n}\n\nexport async function loadNixConfig(options: LoadNixConfigOptions = {}): Promise<ResolvedNixConfig> {\n  const initialRoot = resolve(options.root ?? process.cwd());\n  const configFile = options.configFile\n    ? resolve(initialRoot, options.configFile)\n    : await findConfigFile(initialRoot);\n  let loaded: NixConfig = {};\n\n  if (configFile) {\n    const result = await loadConfigFromFile(\n      { command: options.command === \"build\" ? \"build\" : \"serve\", mode: options.mode ?? \"development\" },\n      configFile,\n      initialRoot,\n    );\n    if (!result) throw new Error(`[nix-js-kit] Could not load config: ${configFile}`);\n    loaded = result.config as NixConfig;\n  }\n\n  const merged = mergeConfig(loaded, options.overrides ?? {});\n  const root = resolve(initialRoot, merged.root ?? \".\");\n  const resolved = resolveConfig(root, merged, configFile);\n  await runIntegrationHook(resolved.integrations, \"config\", [\n    resolved as unknown as Record<string, unknown>,\n    { root, command: options.command ?? \"dev\" },\n  ]);\n  return resolved;\n}\n\nfunction resolveConfig(root: string, config: NixConfig, configFile?: string): ResolvedNixConfig {\n  if (config.site) new URL(config.site);\n  const base = normalizeBase(config.base ?? \"/\");\n  const imageQuality = config.images?.quality ?? 80;\n  if (!Number.isFinite(imageQuality) || imageQuality < 1 || imageQuality > 100) {\n    throw new Error(\"[nix-js-kit] images.quality must be between 1 and 100\");\n  }\n\n  return {\n    root,\n    appDir: resolveInside(root, config.appDir ?? \"src/app\", \"appDir\"),\n    islandsDir: resolveInside(root, config.islandsDir ?? \"src/islands\", \"islandsDir\"),\n    contentDir: resolveInside(root, config.contentDir ?? \"src/content\", \"contentDir\"),\n    publicDir: resolveInside(root, config.publicDir ?? \"public\", \"publicDir\"),\n    outDir: resolveInside(root, config.outDir ?? \"dist\", \"outDir\"),\n    site: config.site,\n    base,\n    trailingSlash: config.trailingSlash ?? \"ignore\",\n    output: config.output ?? \"static\",\n    adapter: config.adapter,\n    images: {\n      formats: config.images?.formats ?? [\"webp\", \"avif\"],\n      quality: imageQuality,\n      strict: config.images?.strict ?? false,\n    },\n    cache: {\n      dir: resolveInside(root, config.cache?.dir ?? \".nix-js/cache\", \"cache.dir\"),\n      defaultRevalidate: config.cache?.defaultRevalidate,\n    },\n    security: {\n      allowedOrigins: config.security?.allowedOrigins ?? [],\n      strictOrigin: config.security?.strictOrigin ?? false,\n      bodyLimit: config.security?.bodyLimit ?? 1_048_576,\n      headers: config.security?.headers === false\n        ? false\n        : config.security?.headers ?? {},\n    },\n    router: {\n      enabled: config.router?.enabled ?? true,\n      prefetch: config.router?.prefetch ?? true,\n    },\n    integrations: config.integrations ?? [],\n    configFile,\n  };\n}\n\nfunction mergeConfig(base: NixConfig, override: NixConfig): NixConfig {\n  return {\n    ...base,\n    ...override,\n    images: { ...base.images, ...override.images },\n    cache: { ...base.cache, ...override.cache },\n    security: { ...base.security, ...override.security },\n    router: { ...base.router, ...override.router },\n    integrations: override.integrations ?? base.integrations,\n  };\n}\n\nfunction resolveInside(root: string, path: string, name: string): string {\n  const resolved = isAbsolute(path) ? resolve(path) : resolve(root, path);\n  const rel = relative(root, resolved);\n  if (rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {\n    throw new Error(`[nix-js-kit] ${name} must stay inside root: ${resolved}`);\n  }\n  return resolved;\n}\n\nfunction normalizeBase(base: string): string {\n  if (!base.startsWith(\"/\")) throw new Error(\"[nix-js-kit] base must start with /\");\n  return base === \"/\" ? base : `${base.replace(/\\/+$/, \"\")}/`;\n}\n\nconst PREFERRED_CONFIG_FILES = [\"nix-js.config.ts\", \"nix-js.config.js\", \"nix-js.config.mjs\"];\n// Legacy names kept for backward compatibility. Emit a deprecation warning\n// when a project still uses them so authors migrate to `nix-js.config.*`.\nconst LEGACY_CONFIG_FILES = [\"nix.config.ts\", \"nix.config.js\", \"nix.config.mjs\"];\n\nasync function findConfigFile(root: string): Promise<string | undefined> {\n  for (const name of PREFERRED_CONFIG_FILES) {\n    const path = resolve(root, name);\n    try {\n      await access(path);\n      return path;\n    } catch {\n    }\n  }\n  for (const name of LEGACY_CONFIG_FILES) {\n    const path = resolve(root, name);\n    try {\n      await access(path);\n      console.warn(\n        `[nix-js-kit] \"${name}\" is deprecated and will be removed in a future release. ` +\n        `Rename it to \"nix-js.config.${name.split(\".\").slice(1).join(\".\")}\" to keep your config working.`,\n      );\n      return path;\n    } catch {\n    }\n  }\n  return undefined;\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, relative } from \"node:path\";\nimport { scanActions, type ActionRegistry } from \"../action/scan.js\";\nimport type { ResolvedNixConfig } from \"../config/index.js\";\nimport { runIntegrationHook } from \"../integrations/index.js\";\nimport { scanIslands, type IslandModule } from \"../island/scan.js\";\nimport { scanRoutes, type ScannedRoutes } from \"../router/route-scanner.js\";\n\nexport interface AppManifest {\n  version: 1;\n  root: string;\n  routes: ScannedRoutes;\n  actions: ActionRegistry;\n  islands: IslandModule[];\n  base: string;\n  output: ResolvedNixConfig[\"output\"];\n}\n\nexport async function createAppManifest(config: ResolvedNixConfig): Promise<AppManifest> {\n  const [routes, actions, islands] = await Promise.all([\n    scanRoutes(config.appDir),\n    scanActions(config.appDir),\n    scanIslands(config.islandsDir),\n  ]);\n  validateManifestRoutes(routes);\n  validateIslands(islands);\n  const manifest: AppManifest = {\n    version: 1,\n    root: config.root,\n    routes,\n    actions,\n    islands,\n    base: config.base,\n    output: config.output,\n  };\n  await runIntegrationHook(config.integrations, \"routes\", [\n    manifest,\n    { root: config.root, command: \"build\" },\n  ]);\n  return manifest;\n}\n\nexport async function writeAppManifest(manifest: AppManifest, path: string): Promise<void> {\n  await mkdir(dirname(path), { recursive: true });\n  await writeFile(path, JSON.stringify(toPortableManifest(manifest), null, 2), \"utf8\");\n}\n\nexport async function writeRouteTypes(manifest: AppManifest, path: string): Promise<void> {\n  const routePaths = manifest.routes.pages.map((route) => JSON.stringify(route.path));\n  const actionNames = Object.values(manifest.actions)\n    .flatMap((actions) => Object.keys(actions))\n    .filter((name, index, names) => names.indexOf(name) === index)\n    .map((name) => JSON.stringify(name));\n  const source = [\n    `export type NixRoutePath = ${routePaths.length ? routePaths.join(\" | \") : \"never\"};`,\n    `export type NixActionName = ${actionNames.length ? actionNames.join(\" | \") : \"never\"};`,\n    \"export interface NixRouteParams { [name: string]: string | string[] | undefined }\",\n    \"\",\n  ].join(\"\\n\");\n  await mkdir(dirname(path), { recursive: true });\n  await writeFile(path, source, \"utf8\");\n}\n\nexport function validateManifestRoutes(routes: ScannedRoutes): void {\n  const seen = new Map<string, string>();\n  for (const route of routes.pages) {\n    registerRoute(seen, route.path, route.pagePath, \"page\");\n    assertNotReserved(route.path, route.pagePath);\n  }\n  for (const route of routes.api) {\n    registerRoute(seen, route.path, route.routePath, \"API\");\n    assertNotReserved(route.path, route.routePath);\n  }\n}\n\nexport function assertClientImportAllowed(id: string, importer?: string): void {\n  if (/\\.server\\.[cm]?[jt]sx?$/.test(id)) {\n    throw new Error(`[nix-js-kit] Server-only module imported by client${importer ? ` from ${importer}` : \"\"}: ${id}`);\n  }\n}\n\nfunction registerRoute(seen: Map<string, string>, path: string, file: string, kind: string): void {\n  const existing = seen.get(path);\n  if (existing) {\n    throw new Error(`[nix-js-kit] Duplicate ${kind} route \"${path}\": ${existing} and ${file}`);\n  }\n  seen.set(path, file);\n}\n\nfunction assertNotReserved(path: string, file: string): void {\n  if (path === \"/__nix-js\" || path.startsWith(\"/__nix-js/\") || path === \"/_nix-js\" || path.startsWith(\"/_nix-js/\")) {\n    throw new Error(`[nix-js-kit] Reserved route \"${path}\" declared by ${file}`);\n  }\n}\n\nfunction validateIslands(islands: readonly IslandModule[]): void {\n  const names = new Set<string>();\n  for (const island of islands) {\n    if (names.has(island.name)) throw new Error(`[nix-js-kit] Duplicate island name: ${island.name}`);\n    names.add(island.name);\n  }\n}\n\nfunction toPortableManifest(manifest: AppManifest): AppManifest {\n  const relativePath = (path: string | undefined) => path ? relative(manifest.root, path).split(\"\\\\\").join(\"/\") : undefined;\n  const routes: ScannedRoutes = {\n    pages: manifest.routes.pages.map((route) => ({\n      ...route,\n      pagePath: relativePath(route.pagePath)!,\n      dataPath: relativePath(route.dataPath),\n      actionPath: relativePath(route.actionPath),\n      loadingPath: relativePath(route.loadingPath),\n      layouts: route.layouts.map((layout) => relativePath(layout)!),\n    })),\n    api: manifest.routes.api.map((route) => ({ ...route, routePath: relativePath(route.routePath)! })),\n    error404: manifest.routes.error404 ? {\n      ...manifest.routes.error404,\n      pagePath: relativePath(manifest.routes.error404.pagePath)!,\n      dataPath: relativePath(manifest.routes.error404.dataPath),\n      actionPath: relativePath(manifest.routes.error404.actionPath),\n      loadingPath: relativePath(manifest.routes.error404.loadingPath),\n      layouts: manifest.routes.error404.layouts.map((layout) => relativePath(layout)!),\n    } : undefined,\n    error500: manifest.routes.error500 ? {\n      ...manifest.routes.error500,\n      pagePath: relativePath(manifest.routes.error500.pagePath)!,\n      dataPath: relativePath(manifest.routes.error500.dataPath),\n      actionPath: relativePath(manifest.routes.error500.actionPath),\n      loadingPath: relativePath(manifest.routes.error500.loadingPath),\n      layouts: manifest.routes.error500.layouts.map((layout) => relativePath(layout)!),\n    } : undefined,\n  };\n  const actions: ActionRegistry = {};\n  for (const [page, pageActions] of Object.entries(manifest.actions)) {\n    actions[page] = Object.fromEntries(\n      Object.entries(pageActions).map(([name, path]) => [name, relativePath(path)!]),\n    );\n  }\n  return {\n    ...manifest,\n    root: \".\",\n    routes,\n    actions,\n    islands: manifest.islands.map((island) => ({ ...island, filePath: relativePath(island.filePath)! })),\n  };\n}\n","// --- Adapter capabilities contract (§8.5) ---\n//\n// Every runtime host (Node CLI, Vite dev, Node/Bun adapters, Vercel, Netlify)\n// declares an explicit `AdapterCapabilities` object. The framework uses it to\n// decide which features are safe to enable: streaming, filesystem access,\n// runtime image transforms, background work, body size limits, ISR persistence.\n//\n// Invalid or incompatible capability combinations fail fast during build.\n\nexport type FilesystemCapability = \"none\" | \"readonly\" | \"persistent\" | \"ephemeral\";\n\nexport interface AdapterCapabilities {\n  /** Whether the host supports streaming responses (ReadableStream bodies). */\n  streaming: boolean;\n  /** Filesystem access model of the host. */\n  filesystem: FilesystemCapability;\n  /** Whether the host can run image transforms at request time. */\n  imageRuntime: boolean;\n  /** Whether the host allows background work after the response completes. */\n  backgroundWork: boolean;\n  /** Maximum request body size in bytes accepted by the host (if any). */\n  maxBodySize?: number;\n}\n\nexport interface CapabilityOptions {\n  streaming?: boolean;\n  filesystem?: FilesystemCapability;\n  imageRuntime?: boolean;\n  backgroundWork?: boolean;\n  maxBodySize?: number;\n}\n\n/** Default capabilities for a full-featured long-lived Node/Bun process. */\nexport const DEFAULT_CAPABILITIES: AdapterCapabilities = {\n  streaming: true,\n  filesystem: \"persistent\",\n  imageRuntime: true,\n  backgroundWork: true,\n};\n\n/** Default capabilities for a stateless serverless function (Vercel/Netlify). */\nexport const SERVERLESS_CAPABILITIES: AdapterCapabilities = {\n  streaming: true,\n  filesystem: \"ephemeral\",\n  imageRuntime: false,\n  backgroundWork: false,\n  maxBodySize: 1_048_576,\n};\n\n/** Default capabilities for an edge runtime (read-only filesystem). */\nexport const EDGE_CAPABILITIES: AdapterCapabilities = {\n  streaming: true,\n  filesystem: \"readonly\",\n  imageRuntime: false,\n  backgroundWork: false,\n  maxBodySize: 1_048_576,\n};\n\nexport function createCapabilities(options: CapabilityOptions = {}): AdapterCapabilities {\n  return {\n    ...DEFAULT_CAPABILITIES,\n    ...options,\n  };\n}\n\n/** True when the host supports streaming responses (streaming !== false). */\nexport function supportsStreaming(capabilities: Pick<AdapterCapabilities, \"streaming\"> = { streaming: true }): boolean {\n  return capabilities.streaming !== false;\n}\n\n/** True when the host can write to persistent storage (for ISR/cache/image writes). */\nexport function supportsPersistentStorage(capabilities: Pick<AdapterCapabilities, \"filesystem\">): boolean {\n  return capabilities.filesystem === \"persistent\";\n}\n\n/** True when the host exposes a writable filesystem at build/runtime. */\nexport function supportsWritableFilesystem(capabilities: Pick<AdapterCapabilities, \"filesystem\">): boolean {\n  return capabilities.filesystem === \"persistent\" || capabilities.filesystem === \"ephemeral\";\n}\n\nexport interface CapabilityDiagnostics {\n  ok: boolean;\n  problems: string[];\n}\n\n/**\n * Validates a capability declaration and reports incompatible combinations.\n * Used by the build pipeline so invalid hosts fail at build time instead of\n * producing a broken runtime.\n */\nexport function validateCapabilities(\n  capabilities: AdapterCapabilities,\n  features: { isr?: boolean; images?: boolean; streaming?: boolean } = {},\n): CapabilityDiagnostics {\n  const problems: string[] = [];\n\n  if (features.isr && !supportsPersistentStorage(capabilities)) {\n    problems.push(\n      `ISR requires a persistent filesystem; the host declares filesystem=\"${capabilities.filesystem}\".`,\n    );\n  }\n  if (features.images && capabilities.imageRuntime === false && capabilities.filesystem === \"none\") {\n    problems.push(\n      \"On-demand image transforms require either imageRuntime=true or a readable filesystem; the host has neither.\",\n    );\n  }\n  if (features.streaming && capabilities.streaming === false) {\n    problems.push(\"Streaming was requested but the host declares streaming=false.\");\n  }\n\n  return { ok: problems.length === 0, problems };\n}\n","import { mkdir, rm, rename, stat, cp, access } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve, dirname, relative } from \"node:path\";\nimport { build as viteBuild, type InlineConfig, type PluginOption } from \"vite\";\nimport { nixJsInterpolationPlugin, shouldUseLegacyInterpolation, type InterpolationMode } from \"../vite/interpolation-plugin.js\";\n\n// --- Programmatic Vite build orchestration ---\n//\n// Replaces the previous `spawnSync(\"npx\", [\"vite\", \"build\", ...])` approach\n// with direct use of the Vite JavaScript API. Benefits:\n//\n//   * No child-process overhead or `npx` resolution latency.\n//   * Shared module cache across build phases (faster large builds).\n//   * Structured errors instead of exit-code parsing.\n//   * Atomic output staging: build into a temp directory, then rename to the\n//     final destination so a crashed build never leaves a half-written dist.\n\nexport interface ClientBuildOptions {\n  /** Project root (absolute). */\n  root: string;\n  /** Absolute path to the user's Vite client config (e.g. vite.client.config.ts). */\n  userConfigPath: string;\n  /** Absolute path to the app directory (used by the interpolation plugin). */\n  appDir: string;\n  /** Absolute path to the islands directory (used by the interpolation plugin). */\n  islandsDir: string;\n  /** Output directory for the client bundle (absolute). */\n  outDir: string;\n  /** Optional base path. */\n  base?: string;\n  /** Optional log prefix. */\n  logPrefix?: string;\n  /**\n   * How the legacy interpolation transform is handled (default: \"auto\").\n   * With a Nix.js core that supports partial attribute interpolation natively\n   * the transform is not applied; use \"legacy\" for migrations against older\n   * cores and \"off\" to never transform.\n   */\n  interpolation?: InterpolationMode;\n}\n\nexport interface ClientBuildResult {\n  /** Output directory (same as `outDir` input). */\n  outDir: string;\n  /** Number of chunks/assets emitted, if reported by Vite. */\n  outputCount: number;\n}\n\n/**\n * Build the client hydration bundle using the Vite JavaScript API.\n *\n * The user's config is loaded programmatically and the nix-js interpolation\n * plugin is injected so partial attribute interpolations inside islands are\n * transformed before reaching the browser.\n */\nexport async function buildClientBundle(options: ClientBuildOptions): Promise<ClientBuildResult> {\n  const log = options.logPrefix ?? \"[client]\";\n  console.log(`${log} Building hydration bundle...`);\n\n  const userConfig = await loadUserConfig(options.userConfigPath, options.root);\n  const pluginOptions: PluginOption = shouldUseLegacyInterpolation(options.interpolation ?? \"auto\")\n    ? nixJsInterpolationPlugin({\n        appDir: options.appDir,\n        islandsDir: options.islandsDir,\n      })\n    : [];\n\n  const config: InlineConfig = {\n    ...userConfig,\n    root: options.root,\n    base: options.base ?? userConfig.base ?? \"/\",\n    build: {\n      ...(userConfig.build ?? {}),\n      outDir: options.outDir,\n      emptyOutDir: true,\n    },\n    plugins: [...(userConfig.plugins ?? []), pluginOptions],\n    configFile: false,\n  };\n\n  const result = await viteBuild(config);\n  const outputs = Array.isArray(result) ? result : [result];\n  const outputCount = outputs.reduce(\n    (n, r) => n + (\"output\" in r ? (r.output?.length ?? 0) : 0),\n    0,\n  );\n  console.log(`${log} ✓ ${outputCount} asset(s) emitted → ${relative(options.root, options.outDir)}`);\n  return { outDir: options.outDir, outputCount };\n}\n\nasync function loadUserConfig(path: string, _root: string): Promise<InlineConfig> {\n  const mod = await import(path);\n  const raw = mod.default ?? mod;\n  const resolved = typeof raw === \"function\" ? await raw({ command: \"build\", mode: \"production\" }) : raw;\n  return (resolved && typeof resolved.then === \"function\" ? await resolved : resolved) ?? {};\n}\n\n// --- Atomic output staging ---\n\nexport interface AtomicStageOptions {\n  /** Final destination directory (absolute). */\n  outDir: string;\n  /** Build into this temp directory first, then rename to `outDir`. */\n  tempDir?: string;\n  /** Whether to preserve existing content in `outDir` during the swap. */\n  keepExisting?: boolean;\n}\n\nexport interface AtomicStage {\n  tempDir: string;\n  /** Call after the build succeeds to atomically swap temp → outDir. */\n  commit: () => Promise<void>;\n  /** Call on failure to clean up the temp directory. */\n  rollback: () => Promise<void>;\n}\n\n/**\n * Prepare an atomic staging directory for build output.\n *\n * Usage:\n *   const stage = await beginAtomicStage({ outDir });\n *   try {\n *     await buildInto(stage.tempDir);\n *     await stage.commit();\n *   } catch (err) {\n *     await stage.rollback();\n *     throw err;\n *   }\n */\nexport async function beginAtomicStage(options: AtomicStageOptions): Promise<AtomicStage> {\n  const outDir = resolve(options.outDir);\n  const tempDir = resolve(options.tempDir ?? join(dirname(outDir), `.${basename(outDir)}.tmp-${process.pid}`));\n\n  // Start from a clean temp directory.\n  await rm(tempDir, { recursive: true, force: true });\n  await mkdir(tempDir, { recursive: true });\n\n  const commit = async () => {\n    // Backup the existing output if requested, then swap.\n    const backup = options.keepExisting && existsSync(outDir) ? `${outDir}.bak-${process.pid}` : undefined;\n    if (backup) {\n      await rm(backup, { recursive: true, force: true });\n      await safeRename(outDir, backup);\n    }\n    try {\n      await safeRename(tempDir, outDir);\n    } catch (err) {\n      // On some platforms, renaming across mount points fails. Fall back to a\n      // recursive copy + clean, which is not atomic but still correct.\n      if (isCrossDevice(err)) {\n        await cp(tempDir, outDir, { recursive: true, force: true });\n        await rm(tempDir, { recursive: true, force: true });\n      } else {\n        if (backup) await safeRename(backup, outDir);\n        throw err;\n      }\n    }\n    if (backup) await rm(backup, { recursive: true, force: true });\n  };\n\n  const rollback = async () => {\n    await rm(tempDir, { recursive: true, force: true });\n  };\n\n  return { tempDir, commit, rollback };\n}\n\nfunction basename(path: string): string {\n  const parts = path.split(/[\\\\/]+/).filter(Boolean);\n  return parts[parts.length - 1] ?? \"output\";\n}\n\nasync function safeRename(src: string, dest: string): Promise<void> {\n  await rm(dest, { recursive: true, force: true });\n  try {\n    await rename(src, dest);\n  } catch (err) {\n    if (isCrossDevice(err)) {\n      await cp(src, dest, { recursive: true, force: true });\n      await rm(src, { recursive: true, force: true });\n    } else {\n      throw err;\n    }\n  }\n}\n\nfunction isCrossDevice(err: unknown): boolean {\n  const code = (err as NodeJS.ErrnoException)?.code;\n  return code === \"EXDEV\";\n}\n\n// --- Public asset copy ---\n\nexport interface CopyPublicAssetsOptions {\n  /** Absolute path to the public directory. */\n  publicDir: string;\n  /** Absolute path to the output directory. */\n  outDir: string;\n}\n\n/**\n * Copy the public directory into the output directory.\n * Returns the number of files copied.\n */\nexport async function copyPublicAssets(options: CopyPublicAssetsOptions): Promise<number> {\n  try {\n    await access(options.publicDir);\n    const s = await stat(options.publicDir);\n    if (!s.isDirectory()) return 0;\n  } catch {\n    return 0;\n  }\n  await mkdir(options.outDir, { recursive: true });\n  await cp(options.publicDir, options.outDir, { recursive: true, force: true });\n  return countFiles(options.outDir);\n}\n\nasync function countFiles(dir: string): Promise<number> {\n  const { readdir } = await import(\"node:fs/promises\");\n  let count = 0;\n  async function walk(d: string): Promise<void> {\n    const entries = await readdir(d, { withFileTypes: true });\n    for (const entry of entries) {\n      const path = join(d, entry.name);\n      if (entry.isDirectory()) await walk(path);\n      else count++;\n    }\n  }\n  await walk(dir);\n  return count;\n}\n","import type { ResolvedNixConfig } from \"../config/index.js\";\nimport { randomUUID } from \"node:crypto\";\n\n// --- RequestContext: unified per-request runtime context ---\n//\n// Every runtime path (SSR server, CLI preview/dev, adapters, Vite plugin)\n// eventually funnels through a single Web handler that receives a Web Request\n// and returns a Web Response. RequestContext carries the resolved config,\n// route tables, action registry and request-scoped state so handlers do not\n// re-derive this information on every request.\n//\n// Design goals (runtime-security §4):\n//   * One type used by every runtime entry point.\n//   * No Node-specific APIs on the type — only Web standards.\n//   * Carries per-request state: params, locals, cookies, signal, requestId.\n//   * response.headers supports multiple Set-Cookie without collapsing them.\n//   * signal aborts when the host disconnects (when the platform allows it).\n//   * Middleware/loaders/actions share the same context or readonly views.\n\nexport interface RouteTable {\n  pages: import(\"../router/route-scanner.js\").PageRoute[];\n  api: import(\"../router/route-scanner.js\").ApiRoute[];\n  error404?: import(\"../router/route-scanner.js\").PageRoute;\n  error500?: import(\"../router/route-scanner.js\").PageRoute;\n}\n\n// --- CookieJar: read cookies from request, write to response ---\n\n/** Read-only access to request cookies. */\nexport interface CookieJar {\n  /** Gets a cookie value by name, or undefined if not present. */\n  get(name: string): string | undefined;\n  /** Returns all cookie name-value pairs. */\n  getAll(): Record<string, string>;\n  /** Checks if a cookie exists. */\n  has(name: string): boolean;\n}\n\n/** Write access to response cookies (Set-Cookie headers). */\nexport interface ResponseCookieJar {\n  /** Sets a Set-Cookie header. */\n  set(name: string, value: string, options?: CookieOptions): void;\n  /** Removes a cookie by setting it expired. */\n  clear(name: string, options?: CookieOptions): void;\n  /** Returns all Set-Cookie header values accumulated so far. */\n  getAll(): string[];\n}\n\nexport interface CookieOptions {\n  httpOnly?: boolean;\n  secure?: boolean;\n  sameSite?: \"strict\" | \"lax\" | \"none\";\n  maxAge?: number;\n  expires?: Date;\n  path?: string;\n  domain?: string;\n}\n\n/** Mutable response state accumulated during the request lifecycle. */\nexport interface ResponseState {\n  status?: number;\n  headers: Headers;\n  cookies: ResponseCookieJar;\n}\n\n// --- Cookie implementation ---\n\nclass RequestCookieJar implements CookieJar {\n  private cookies: Record<string, string>;\n\n  constructor(request: Request) {\n    this.cookies = parseCookies(request.headers.get(\"Cookie\") ?? \"\");\n  }\n\n  get(name: string): string | undefined {\n    return this.cookies[name];\n  }\n\n  getAll(): Record<string, string> {\n    return { ...this.cookies };\n  }\n\n  has(name: string): boolean {\n    return name in this.cookies;\n  }\n}\n\nclass MutableResponseCookieJar implements ResponseCookieJar {\n  private entries: string[] = [];\n\n  set(name: string, value: string, options: CookieOptions = {}): void {\n    this.entries.push(serializeCookie(name, value, options));\n  }\n\n  clear(name: string, options: CookieOptions = {}): void {\n    this.entries.push(serializeCookie(name, \"\", { ...options, maxAge: 0, expires: new Date(0) }));\n  }\n\n  getAll(): string[] {\n    return [...this.entries];\n  }\n}\n\nfunction parseCookies(header: string): Record<string, string> {\n  const result: Record<string, string> = {};\n  if (!header) return result;\n  for (const pair of header.split(\";\")) {\n    const idx = pair.indexOf(\"=\");\n    if (idx === -1) continue;\n    const name = pair.slice(0, idx).trim();\n    const value = pair.slice(idx + 1).trim();\n    result[name] = value;\n  }\n  return result;\n}\n\nfunction serializeCookie(name: string, value: string, options: CookieOptions): string {\n  const parts = [`${name}=${value}`];\n  if (options.httpOnly) parts.push(\"HttpOnly\");\n  if (options.secure) parts.push(\"Secure\");\n  if (options.sameSite) parts.push(`SameSite=${options.sameSite}`);\n  if (options.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);\n  if (options.expires) parts.push(`Expires=${options.expires.toUTCString()}`);\n  if (options.path) parts.push(`Path=${options.path}`);\n  if (options.domain) parts.push(`Domain=${options.domain}`);\n  return parts.join(\"; \");\n}\n\nexport interface RequestContextOptions {\n  request: Request;\n  config: ResolvedNixConfig;\n  routes: RouteTable;\n  actions: import(\"../action/scan.js\").ActionRegistry;\n  /** Public action names serialized into the HTML shell. */\n  publicActions: Record<string, string[]>;\n  /** Optional module loader for adapter-bundled entries. */\n  importer?: (path: string) => unknown | Promise<unknown>;\n  /** Whether the render endpoint (/__nix-js/render) is available. */\n  renderEndpoint?: boolean;\n  /** Whether to bypass the ISR cache (dev mode). */\n  noCache?: boolean;\n  /** ISR cache directory (absolute). */\n  cacheDir?: string;\n  /** Default ISR revalidate interval in seconds. */\n  defaultRevalidate?: number;\n  /** Route params (populated after route matching). */\n  params?: Record<string, string | string[] | undefined>;\n  /** Per-request locals (populated by middleware). */\n  locals?: Record<string, unknown>;\n  /** Abort signal for the request (from host disconnect). */\n  signal?: AbortSignal;\n  /** Request ID (auto-generated if not provided). */\n  requestId?: string;\n  /** Platform-specific context (e.g. Vercel, Netlify). */\n  platform?: unknown;\n  /** Matched route (populated after route matching). */\n  route?: import(\"../router/route-scanner.js\").PageRoute | import(\"../router/route-scanner.js\").ApiRoute;\n}\n\nexport class RequestContext {\n  readonly request: Request;\n  readonly url: URL;\n  readonly config: ResolvedNixConfig;\n  readonly routes: RouteTable;\n  readonly actions: import(\"../action/scan.js\").ActionRegistry;\n  readonly publicActions: Record<string, string[]>;\n  readonly importer?: (path: string) => unknown | Promise<unknown>;\n  readonly renderEndpoint: boolean;\n  readonly noCache: boolean;\n  readonly cacheDir?: string;\n  readonly defaultRevalidate?: number;\n\n  // Per-request state (runtime-security §4)\n  /** Route params derived from the matched route. */\n  params: Readonly<Record<string, string | string[] | undefined>>;\n  /** Per-request locals, populated by middleware. Not global. */\n  locals: Record<string, unknown>;\n  /** Read-only access to request cookies. */\n  readonly cookies: CookieJar;\n  /** Abort signal (from host disconnect when platform allows). */\n  readonly signal: AbortSignal;\n  /** Unique request ID for logging/correlation. */\n  readonly requestId: string;\n  /** Platform-specific context (Vercel, Netlify, etc.). */\n  readonly platform: unknown;\n  /** Matched route after route matching. */\n  route?: import(\"../router/route-scanner.js\").PageRoute | import(\"../router/route-scanner.js\").ApiRoute;\n  /** Mutable response state accumulated during the request. */\n  readonly response: ResponseState;\n\n  constructor(options: RequestContextOptions) {\n    this.request = options.request;\n    this.url = new URL(options.request.url);\n    this.config = options.config;\n    this.routes = options.routes;\n    this.actions = options.actions;\n    this.publicActions = options.publicActions;\n    this.importer = options.importer;\n    this.renderEndpoint = options.renderEndpoint ?? true;\n    this.noCache = options.noCache ?? false;\n    this.cacheDir = options.cacheDir;\n    this.defaultRevalidate = options.defaultRevalidate;\n\n    // Per-request state\n    this.params = options.params ?? {};\n    this.locals = options.locals ?? {};\n    this.cookies = new RequestCookieJar(options.request);\n    this.signal = options.signal ?? new AbortController().signal;\n    this.requestId = options.requestId ?? randomUUID();\n    this.platform = options.platform;\n    this.route = options.route;\n    this.response = {\n      status: undefined,\n      headers: new Headers(),\n      cookies: new MutableResponseCookieJar(),\n    };\n  }\n\n  /** The pathname without a query string. */\n  get pathname(): string {\n    return this.url.pathname;\n  }\n\n  /** The HTTP method, uppercased. */\n  get method(): string {\n    return (this.request.method ?? \"GET\").toUpperCase();\n  }\n\n  /** Whether the request accepts JSON. */\n  get wantsJson(): boolean {\n    return (this.request.headers.get(\"Accept\") ?? \"\").includes(\"application/json\");\n  }\n\n  /** Search params from the request URL. */\n  get searchParams(): URLSearchParams {\n    return this.url.searchParams;\n  }\n\n  /** Render config passed to renderPage/renderErrorPage. */\n  get renderConfig(): { lang?: string; clientEntry?: string; renderEndpoint?: boolean } {\n    return {\n      lang: undefined,\n      clientEntry: undefined,\n      renderEndpoint: this.renderEndpoint,\n    };\n  }\n\n  /** Applies accumulated response state (headers, cookies, status) to a Response. */\n  applyToResponse(response: Response): Response {\n    const headers = new Headers(response.headers);\n    // Merge accumulated headers\n    for (const [key, value] of this.response.headers.entries()) {\n      headers.set(key, value);\n    }\n    // Append Set-Cookie values (multiple allowed)\n    for (const cookie of this.response.cookies.getAll()) {\n      headers.append(\"Set-Cookie\", cookie);\n    }\n    const status = this.response.status ?? response.status;\n    return new Response(response.body, {\n      status,\n      statusText: response.statusText,\n      headers,\n    });\n  }\n}\n\n// --- ResponseBuilder: small helpers for consistent Web Responses ---\n\nexport function htmlResponse(body: string, status = 200, headers?: HeadersInit): Response {\n  return new Response(body, {\n    status,\n    headers: { \"Content-Type\": \"text/html; charset=utf-8\", ...headers as Record<string, string> },\n  });\n}\n\nexport function jsonResponse(data: unknown, status = 200, headers?: HeadersInit): Response {\n  return new Response(JSON.stringify(data), {\n    status,\n    headers: { \"Content-Type\": \"application/json; charset=utf-8\", ...headers as Record<string, string> },\n  });\n}\n\nexport function textResponse(body: string, status = 200, headers?: HeadersInit): Response {\n  return new Response(body, {\n    status,\n    headers: { \"Content-Type\": \"text/plain; charset=utf-8\", ...headers as Record<string, string> },\n  });\n}\n\nexport function notFound(body = \"Not Found\"): Response {\n  return textResponse(body, 404);\n}\n\nexport function methodNotAllowed(method: string): Response {\n  return textResponse(`Method not allowed: ${method}`, 405);\n}\n\nexport function serverError(body: string): Response {\n  return textResponse(body, 500);\n}\n\n// --- Content-type guessing (shared by all static-serving paths) ---\n\nexport function guessContentType(filePath: string): string {\n  switch (filePath.slice(filePath.lastIndexOf(\".\") + 1).toLowerCase()) {\n    case \"html\": return \"text/html; charset=utf-8\";\n    case \"js\": return \"application/javascript; charset=utf-8\";\n    case \"mjs\": return \"application/javascript; charset=utf-8\";\n    case \"css\": return \"text/css; charset=utf-8\";\n    case \"json\": return \"application/json; charset=utf-8\";\n    case \"svg\": return \"image/svg+xml\";\n    case \"png\": return \"image/png\";\n    case \"jpg\":\n    case \"jpeg\": return \"image/jpeg\";\n    case \"webp\": return \"image/webp\";\n    case \"avif\": return \"image/avif\";\n    case \"ico\": return \"image/x-icon\";\n    case \"woff\": return \"font/woff\";\n    case \"woff2\": return \"font/woff2\";\n    case \"wasm\": return \"application/wasm\";\n    case \"txt\": return \"text/plain; charset=utf-8\";\n    default: return \"application/octet-stream\";\n  }\n}\n\n// --- Static file serving as a Web handler (reuses resolveStaticFile) ---\n\nimport { readFile, stat } from \"node:fs/promises\";\nimport { createHash } from \"node:crypto\";\nimport { resolveStaticFile } from \"./static.js\";\n\n/**\n * Serves a static file from the root directory with full conditional and\n * range support:\n *\n * - ETag / Last-Modified with If-None-Match / If-Modified-Since → 304.\n * - `Range` with `If-Range` (ETag or date) → 206 with `Content-Range`.\n * - HEAD → same headers as GET without a body.\n * - Invalid/unsatisfiable ranges → 416 with a `Content-Range: bytes (asterisk)/size` header.\n *\n * Files with content hashes in their names (e.g. `app-abc123.js`) get\n * `Cache-Control: public, max-age=31536000, immutable`.\n *\n * @param root Static file root (absolute path).\n * @param pathname Request pathname.\n * @param request Optional request for conditional/range/HEAD handling.\n */\nexport async function serveStaticFile(\n  root: string,\n  pathname: string,\n  request?: Request,\n): Promise<Response | null> {\n  const filePath = await resolveStaticFile(root, pathname);\n  if (!filePath) return null;\n  try {\n    const [data, stats] = await Promise.all([\n      readFile(filePath),\n      stat(filePath),\n    ]);\n\n    const contentType = guessContentType(filePath);\n    const etag = `\"${createHash(\"sha1\").update(data).digest(\"hex\").slice(0, 16)}\"`;\n    const lastModified = stats.mtime.toUTCString();\n    const isHead = request?.method === \"HEAD\";\n    const size = data.byteLength;\n\n    const baseHeaders: Record<string, string> = {\n      \"Content-Type\": contentType,\n      \"Content-Length\": String(size),\n      ETag: etag,\n      \"Last-Modified\": lastModified,\n      \"Accept-Ranges\": \"bytes\",\n    };\n\n    // Determine Cache-Control: hashed assets get immutable, others get a\n    // short revalidation window.\n    const baseName = filePath.split(\"/\").pop() ?? \"\";\n    const isHashed = /[a-f0-9]{8,}\\.(js|css|woff2?|wasm|png|jpg|jpeg|webp|avif|svg)$/i.test(baseName);\n    baseHeaders[\"Cache-Control\"] = isHashed\n      ? \"public, max-age=31536000, immutable\"\n      : \"public, max-age=0, must-revalidate\";\n\n    // Conditional requests (If-None-Match takes precedence).\n    const ifNoneMatch = request?.headers.get(\"If-None-Match\");\n    if (ifNoneMatch && etagListMatches(ifNoneMatch, etag)) {\n      return new Response(null, { status: 304, headers: baseHeaders });\n    }\n    const ifModifiedSince = request?.headers.get(\"If-Modified-Since\");\n    if (ifModifiedSince) {\n      const since = Date.parse(ifModifiedSince);\n      if (!isNaN(since) && Math.floor(stats.mtime.getTime() / 1000) <= Math.floor(since / 1000)) {\n        return new Response(null, { status: 304, headers: baseHeaders });\n      }\n    }\n\n    // Range support with If-Range validation.\n    const rangeHeader = request?.headers.get(\"Range\");\n    const ifRange = request?.headers.get(\"If-Range\");\n    if (rangeHeader && (!ifRange || ifRangeMatches(ifRange, etag, stats.mtime))) {\n      const range = parseRange(rangeHeader, size);\n      if (range === null) {\n        return new Response(null, {\n          status: 416,\n          headers: { ...baseHeaders, \"Content-Range\": `bytes */${size}` },\n        });\n      }\n      if (range) {\n        const [start, end] = range;\n        const chunk = data.subarray(start, end + 1);\n        const headers: Record<string, string> = {\n          ...baseHeaders,\n          \"Content-Length\": String(chunk.byteLength),\n          \"Content-Range\": `bytes ${start}-${end}/${size}`,\n        };\n        if (isHead) return new Response(null, { status: 206, headers });\n        return new Response(chunk, { status: 206, headers });\n      }\n    }\n\n    if (isHead) return new Response(null, { status: 200, headers: baseHeaders });\n    return new Response(data, { status: 200, headers: baseHeaders });\n  } catch {\n    return null;\n  }\n}\n\nfunction etagListMatches(ifNoneMatch: string, etag: string): boolean {\n  return ifNoneMatch\n    .split(\",\")\n    .map((value) => value.trim())\n    .some((value) => value === \"*\" || value === etag);\n}\n\nfunction ifRangeMatches(ifRange: string, etag: string, mtime: Date): boolean {\n  if (ifRange.startsWith('\"') || ifRange.startsWith(\"W/\")) return ifRange === etag;\n  const date = Date.parse(ifRange);\n  return !isNaN(date) && Math.floor(mtime.getTime() / 1000) <= Math.floor(date / 1000);\n}\n\n/**\n * Parses a single `Range: bytes=...` header. Returns:\n * - `[start, end]` for a satisfiable range.\n * - `null` when the header is malformed or unsatisfiable (→ 416).\n * - `undefined` when the header is valid but the whole resource is requested\n *   (e.g. `bytes=0-` for an empty file) — serve the full body.\n */\nfunction parseRange(rangeHeader: string, size: number): [number, number] | null | undefined {\n  const match = /^bytes=(\\d*)-(\\d*)$/.exec(rangeHeader.trim());\n  if (!match) return null;\n  const startText = match[1];\n  const endText = match[2];\n\n  if (startText === \"\" && endText === \"\") return null;\n  if (startText === \"\") {\n    // Suffix range: last N bytes.\n    const suffix = Number(endText);\n    if (!Number.isSafeInteger(suffix) || suffix <= 0) return null;\n    const start = Math.max(0, size - suffix);\n    if (size === 0) return undefined;\n    return [start, size - 1];\n  }\n\n  const start = Number(startText);\n  if (!Number.isSafeInteger(start) || start < 0 || start >= size) return null;\n  const end = endText === \"\" ? size - 1 : Number(endText);\n  if (!Number.isSafeInteger(end) || end < start) return null;\n  return [start, Math.min(end, size - 1)];\n}\n","// --- Security response headers (runtime-security §14) ---\n//\n// Applies configurable security headers to responses. Defaults are safe and\n// compatible: X-Content-Type-Options, Referrer-Policy, frame-ancestors.\n// HSTS is only applied under HTTPS or when explicitly configured.\n// CSP supports a \"nonce\" placeholder replaced per-request.\n// User-set headers on the response are never overwritten without explicit\n// merge rules.\n\nimport type { SecurityHeadersConfig } from \"../config/index.js\";\n\n/** Default security headers applied when `security.headers` is not `false`. */\nexport const DEFAULT_SECURITY_HEADERS: Required<\n  Omit<SecurityHeadersConfig, \"contentSecurityPolicy\" | \"hsts\" | \"permissionsPolicy\">\n> = {\n  noSniff: true,\n  referrerPolicy: \"strict-origin-when-cross-origin\",\n  frameAncestors: \"SAMEORIGIN\",\n};\n\n/**\n * Builds the security headers map from the resolved config.\n * Returns an empty map if headers are disabled.\n */\nexport function buildSecurityHeaders(\n  config: SecurityHeadersConfig | false,\n  isHttps: boolean,\n  nonce?: string,\n): Record<string, string> {\n  if (config === false) return {};\n\n  const headers: Record<string, string> = {};\n  const merged = { ...DEFAULT_SECURITY_HEADERS, ...config };\n\n  if (merged.noSniff) {\n    headers[\"X-Content-Type-Options\"] = \"nosniff\";\n  }\n\n  if (merged.referrerPolicy) {\n    headers[\"Referrer-Policy\"] = merged.referrerPolicy;\n  }\n\n  // Frame policy: prefer CSP frame-ancestors if CSP is set, otherwise\n  // X-Frame-Options for broader compatibility.\n  if (merged.contentSecurityPolicy) {\n    let csp = merged.contentSecurityPolicy;\n    if (nonce) {\n      csp = csp.replace(/\\bnonce\\b/g, `'nonce-${nonce}'`);\n    }\n    headers[\"Content-Security-Policy\"] = csp;\n  } else if (merged.frameAncestors) {\n    // Without CSP, use X-Frame-Options for frame protection.\n    const fa = merged.frameAncestors;\n    if (fa === \"NONE\") {\n      headers[\"X-Frame-Options\"] = \"DENY\";\n    } else if (fa === \"SAMEORIGIN\") {\n      headers[\"X-Frame-Options\"] = \"SAMEORIGIN\";\n    } else {\n      headers[\"X-Frame-Options\"] = fa;\n    }\n  }\n\n  // HSTS: only under HTTPS or when explicitly set as a string.\n  if (merged.hsts === true && isHttps) {\n    headers[\"Strict-Transport-Security\"] = \"max-age=15552000; includeSubDomains\";\n  } else if (typeof merged.hsts === \"string\") {\n    headers[\"Strict-Transport-Security\"] = merged.hsts;\n  }\n\n  if (merged.permissionsPolicy) {\n    headers[\"Permissions-Policy\"] = merged.permissionsPolicy;\n  }\n\n  return headers;\n}\n\n/**\n * Applies security headers to an existing Response, preserving any\n * user-set headers unless overridden by security config.\n */\nexport function applySecurityHeaders(\n  response: Response,\n  headers: Record<string, string>,\n): Response {\n  if (Object.keys(headers).length === 0) return response;\n\n  const newHeaders = new Headers(response.headers);\n  for (const [key, value] of Object.entries(headers)) {\n    // Don't overwrite a header the response already set explicitly.\n    if (!newHeaders.has(key)) {\n      newHeaders.set(key, value);\n    }\n  }\n\n  return new Response(response.body, {\n    status: response.status,\n    statusText: response.statusText,\n    headers: newHeaders,\n  });\n}\n","import { matchRoute, matchApiRoute } from \"../ssr/match.js\";\nimport { handleActionRequest, type ActionResolver } from \"../action/server.js\";\nimport { renderPage, renderErrorPage } from \"../ssr/render.js\";\nimport { renderPageBody, RouteNotFoundError } from \"../ssr/stream.js\";\nimport { actionNames } from \"../action/scan.js\";\nimport { serveStaticFile, htmlResponse, jsonResponse, notFound, methodNotAllowed } from \"./context.js\";\nimport { publicErrorResponse } from \"../errors.js\";\nimport { getCachedHtml, setCachedHtml } from \"../cache.js\";\nimport { shouldCachePublic, type CachePolicy } from \"../cache/policy.js\";\nimport { buildSecurityHeaders, applySecurityHeaders } from \"./security-headers.js\";\nimport type { SecurityHeadersConfig } from \"../config/index.js\";\n\n// --- Unified Web handler ---\n//\n// A single function that turns a Web Request into a Web Response. Every\n// runtime entry point (Node CLI, Bun adapter, Vercel, Netlify, Vite dev)\n// eventually calls this handler so behavior is identical across platforms.\n//\n// Responsibilities (in order):\n//   1. Server actions endpoint (/__nix-js/actions).\n//   2. SPA render endpoint (/__nix-js/render).\n//   3. API routes.\n//   4. Static files from the output directory.\n//   5. Dynamic SSR rendering for unmatched paths.\n//   6. 404 / 500 error pages.\n//\n// The handler is pure: it does not import Node HTTP types and can be used in\n// Bun, Deno, Cloudflare Workers, Vercel Edge, etc.\n\nexport interface WebHandlerOptions {\n  /** Static file root (absolute path). Usually the build output directory. */\n  staticRoot: string;\n  /** Whether to bypass the ISR cache (dev mode). */\n  noCache?: boolean;\n  /** ISR cache directory (absolute). */\n  cacheDir?: string;\n  /** Default ISR revalidate interval in seconds. */\n  defaultRevalidate?: number;\n  /** Optional module loader for adapter-bundled entries. */\n  importer?: (path: string) => Promise<unknown>;\n  /** HTML lang attribute. */\n  lang?: string;\n  /** Client entry path. */\n  clientEntry?: string;\n  /** Whether the render endpoint exists. */\n  renderEndpoint?: boolean;\n  /** Security headers config (runtime-security §14). `false` disables. */\n  securityHeaders?: SecurityHeadersConfig | false;\n}\n\nexport interface WebHandlerRouteTable {\n  pages: import(\"../router/route-scanner.js\").PageRoute[];\n  api: import(\"../router/route-scanner.js\").ApiRoute[];\n  error404?: import(\"../router/route-scanner.js\").PageRoute;\n  error500?: import(\"../router/route-scanner.js\").PageRoute;\n}\n\nexport interface WebHandlerActionRegistry {\n  [pagePath: string]: Record<string, string>;\n}\n\nexport interface CreateWebHandlerResult {\n  (request: Request): Promise<Response>;\n}\n\n/**\n * Create a unified Web handler from scanned routes, actions and options.\n *\n * The returned function is the single entry point for all runtimes.\n */\nexport function createWebHandler(\n  routes: WebHandlerRouteTable,\n  actions: WebHandlerActionRegistry,\n  options: WebHandlerOptions,\n): CreateWebHandlerResult {\n  const publicActions = actionNames(actions);\n  const lang = options.lang ?? \"es\";\n  const clientEntry = options.clientEntry;\n  const renderEndpoint = options.renderEndpoint ?? true;\n  const noCache = options.noCache ?? false;\n  const cacheDir = options.cacheDir;\n  const defaultRevalidate = options.defaultRevalidate;\n\n  const renderConfig = { lang, clientEntry, renderEndpoint };\n  const securityHeadersConfig = options.securityHeaders ?? {};\n\n  function createActionResolver(): ActionResolver {\n    return async (name: string, page?: string) => {\n      const pageKey = page\n        ? routes.pages.some((route) => route.path === page)\n          ? page\n          : (matchRoute(page, routes.pages)?.route.path ?? page)\n        : undefined;\n      const pageActions = pageKey ? actions[pageKey] : Object.values(actions).find((p) => p[name]) ?? undefined;\n      const actionPath = pageActions ? pageActions[name] : undefined;\n      if (!actionPath) return undefined;\n      if (options.importer) {\n        const mod = (await options.importer(actionPath)) as Record<string, unknown>;\n        const action = mod[name];\n        if (typeof action === \"function\") return action as (...args: unknown[]) => unknown;\n        return undefined;\n      }\n      const mod = (await import(actionPath)) as Record<string, unknown>;\n      const action = mod[name];\n      if (typeof action === \"function\") return action as (...args: unknown[]) => unknown;\n      return undefined;\n    };\n  }\n\n  const actionResolver = createActionResolver();\n\n  async function handleActions(request: Request): Promise<Response> {\n    try {\n      return await handleActionRequest(request, actionResolver);\n    } catch (err) {\n      console.error(\"[nix-js-kit] action error:\", err);\n      return publicErrorResponse(err, { includeDetail: noCache });\n    }\n  }\n\n  async function handleRenderEndpoint(request: Request, url: URL): Promise<Response> {\n    const page = url.searchParams.get(\"page\") ?? \"/\";\n    const search = url.searchParams.get(\"search\") ?? \"\";\n    const wantsJson = (request.headers.get(\"Accept\") ?? \"\").includes(\"application/json\");\n    try {\n      const { body, title } = await renderPageBody({\n        routes,\n        pathname: page,\n        searchParams: new URLSearchParams(search),\n        config: renderConfig,\n        actions: publicActions,\n        request,\n        importer: options.importer,\n      });\n      if (wantsJson) return jsonResponse({ title, body });\n      return htmlResponse(body);\n    } catch (err) {\n      if (err instanceof RouteNotFoundError) return notFound(\"Not Found\");\n      // A thrown Response from a loader is a first-class response (A-22).\n      if (err instanceof Response) return err;\n      console.error(\"[nix-js-kit] render endpoint error:\", err);\n      return publicErrorResponse(err, { includeDetail: noCache });\n    }\n  }\n\n  async function handleApiRoute(\n    request: Request,\n    pathname: string,\n  ): Promise<Response | null> {\n    const apiMatch = matchApiRoute(pathname, routes.api);\n    if (!apiMatch) return null;\n    try {\n      let mod: Record<string, unknown>;\n      if (options.importer) {\n        mod = (await options.importer(apiMatch.route.routePath as unknown as string)) as Record<string, unknown>;\n      } else {\n        mod = (await import(apiMatch.route.routePath)) as Record<string, unknown>;\n      }\n      const handler = mod[request.method ?? \"GET\"];\n      if (typeof handler !== \"function\") return methodNotAllowed(request.method ?? \"GET\");\n      // Pass params and a writable locals object to the API handler\n      // (runtime-security §4: params derived from the effective route).\n      const ctx = { params: apiMatch.params, locals: {} as Record<string, unknown> };\n      const response = (await (handler as (req: Request, ctx?: { params: Record<string, string | string[]>; locals: Record<string, unknown> }) => unknown)(request, ctx)) as Response;\n      return response;\n    } catch (err) {\n      console.error(\"[nix-js-kit] API route error:\", err);\n      return publicErrorResponse(err, { includeDetail: noCache });\n    }\n  }\n\n  async function handleStatic(pathname: string, request: Request): Promise<Response | null> {\n    const response = await serveStaticFile(options.staticRoot, pathname, request);\n    if (response && noCache) {\n      const ct = response.headers.get(\"Content-Type\") ?? \"\";\n      if (ct.includes(\"text/html\")) {\n        // Dev mode: strip the render-endpoint marker so the client router uses\n        // the live /__nix-js/render endpoint for fast SPA navigation.\n        const stripped = (await response.text())\n          .replace('<meta name=\"nix-js:render-endpoint\" content=\"off\" />', \"\");\n        return new Response(stripped, {\n          status: response.status,\n          headers: { \"Content-Type\": ct, \"Cache-Control\": \"no-store, must-revalidate\" },\n        });\n      }\n      return new Response(response.body, {\n        status: response.status,\n        headers: { ...Object.fromEntries(response.headers.entries()), \"Cache-Control\": \"no-store, must-revalidate\" },\n      });\n    }\n    if (response && renderEndpoint) {\n      const ct = response.headers.get(\"Content-Type\") ?? \"\";\n      if (ct.includes(\"text/html\")) {\n        const headers = Object.fromEntries(response.headers.entries());\n        delete headers[\"content-length\"];\n        const body = await response.text();\n        if (body.includes('nix-js:render-endpoint\" content=\"off\"')) {\n          // The SSG build baked `render-endpoint content=\"off\"` so static\n          // deployments never probe the endpoint. This server exposes\n          // /__nix-js/render, so advertise it: SPA navigations fetch live\n          // server-rendered content instead of the stale static file.\n          const rewritten = body.replace(\n            '<meta name=\"nix-js:render-endpoint\" content=\"off\" />',\n            '<meta name=\"nix-js:render-endpoint\" content=\"on\" />',\n          );\n          return new Response(rewritten, { status: response.status, headers });\n        }\n        return new Response(body, { status: response.status, headers });\n      }\n    }\n    return response;\n  }\n\n  async function handleDynamicRender(request: Request, pathname: string): Promise<Response> {\n    const match = matchRoute(pathname, routes.pages);\n    if (!match) {\n      const errorResult = await renderErrorPage({\n        routes,\n        status: 404,\n        config: renderConfig,\n        actions: publicActions,\n        importer: options.importer,\n      });\n      if (errorResult) return htmlResponse(errorResult.html, errorResult.status);\n      return notFound(`Not found: ${pathname}`);\n    }\n\n    // ISR cache check (only when caching is enabled and the request is\n    // cacheable — no cookies, no authorization header).\n    const cacheable = !noCache && cacheDir && isCacheable(request);\n    if (cacheable && cacheDir) {\n      const cached = await getCachedHtml(cacheDir, pathname);\n      if (cached) return htmlResponse(cached.html);\n    }\n\n    try {\n      const result = await renderPage({\n        route: match.route,\n        params: match.params,\n        searchParams: new URLSearchParams(request.url.split(\"?\")[1] ?? \"\"),\n        config: renderConfig,\n        actions: publicActions,\n        request,\n        importer: options.importer,\n      });\n\n      // If a loader threw a Response (redirect, 404, etc.), return it\n      // as a first-class response (A-22).\n      if (result.response) {\n        return result.response;\n      }\n\n      if (cacheable && cacheDir && isResultCacheable(result, request)) {\n        const revalidateSeconds = result.revalidate ?? defaultRevalidate ?? 0;\n        if (revalidateSeconds > 0) {\n          await setCachedHtml(cacheDir, pathname, result.html, revalidateSeconds);\n        }\n      }\n\n      return htmlResponse(result.html);\n    } catch (err) {\n      // A thrown Response from a loader is a first-class response (A-22).\n      if (err instanceof Response) return err;\n      console.error(\"[nix-js-kit] SSR render error:\", err);\n      const errorResult = await renderErrorPage({\n        routes,\n        status: 500,\n        error: err,\n        config: renderConfig,\n        actions: publicActions,\n        importer: options.importer,\n      }).catch(() => undefined);\n      if (errorResult) return htmlResponse(errorResult.html, errorResult.status);\n      return publicErrorResponse(err, { includeDetail: noCache });\n    }\n  }\n\n  return async function handler(request: Request): Promise<Response> {\n    const url = new URL(request.url);\n    const pathname = url.pathname;\n    const isHttps = url.protocol === \"https:\";\n\n    // Determine security headers (rebuild if nonce is needed).\n    // HSTS is only applied under HTTPS; other headers apply always.\n    const secHeaders = securityHeadersConfig === false\n      ? {}\n      : buildSecurityHeaders(securityHeadersConfig, isHttps);\n\n    // 1. Server actions endpoint.\n    if (pathname === \"/__nix-js/actions\" && request.method === \"POST\") {\n      const response = await handleActions(request);\n      return applySecurityHeaders(response, secHeaders);\n    }\n\n    // 2. SPA render endpoint.\n    if (pathname === \"/__nix-js/render\" && renderEndpoint) {\n      const response = await handleRenderEndpoint(request, url);\n      return applySecurityHeaders(response, secHeaders);\n    }\n\n    // 3. API routes.\n    const apiResponse = await handleApiRoute(request, pathname);\n    if (apiResponse) return applySecurityHeaders(apiResponse, secHeaders);\n\n    // 4. Static files.\n    const staticResponse = await handleStatic(pathname, request);\n    if (staticResponse) return applySecurityHeaders(staticResponse, secHeaders);\n\n    // 5. Dynamic SSR rendering.\n    const dynamicResponse = await handleDynamicRender(request, pathname);\n    return applySecurityHeaders(dynamicResponse, secHeaders);\n  };\n}\n\nfunction isCacheable(request: Request): boolean {\n  if (request.method !== \"GET\" && request.method !== \"HEAD\") return false;\n  if (request.headers.get(\"Cookie\")) return false;\n  if (request.headers.get(\"Authorization\")) return false;\n  return true;\n}\n\n/**\n * Checks whether a rendered page result is cacheable as public ISR.\n * Per runtime-security §9.1: uses the route's cache policy and checks\n * for personalized content markers.\n */\nfunction isResultCacheable(\n  result: { revalidate?: number; html: string; cachePolicy?: CachePolicy },\n  request: Request,\n): boolean {\n  // If the HTML contains action error markers, it's personalized.\n  if (result.html.includes(\"__nix_js_action_error\")) return false;\n  // Use the route's cache policy if declared.\n  if (result.cachePolicy) {\n    return shouldCachePublic(result.cachePolicy, request);\n  }\n  // Fallback: cacheable only if revalidate > 0 and request is clean.\n  if (!result.revalidate || result.revalidate <= 0) return false;\n  if (request.headers.get(\"Cookie\")) return false;\n  if (request.headers.get(\"Authorization\")) return false;\n  return true;\n}\n","import { existsSync } from \"node:fs\";\nimport { mkdir, readdir, copyFile, writeFile } from \"node:fs/promises\";\nimport { dirname, join, relative } from \"node:path\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\nimport type { AdapterOptions } from \"./index.js\";\nimport type { PageRoute } from \"../router/route-scanner.js\";\n\n/**\n * Shared helper: copy a directory recursively.\n */\nexport async function copyStatic(from: string, to: string): Promise<void> {\n  await mkdir(to, { recursive: true });\n  const entries = await readdir(from, { withFileTypes: true });\n  for (const entry of entries) {\n    const src = join(from, entry.name);\n    const dest = join(to, entry.name);\n    if (entry.isDirectory()) {\n      await copyStatic(src, dest);\n    } else {\n      await copyFile(src, dest);\n    }\n  }\n}\n\n/** Adds every module the SSR runtime may import for a page to the registry. */\nfunction collectPageModules(\n  page: PageRoute,\n  moduleSet: Set<string>,\n  actionPathsByPage: Map<string, Set<string>>,\n): void {\n  moduleSet.add(page.pagePath);\n  if (page.dataPath) moduleSet.add(page.dataPath);\n  if (page.loadingPath) moduleSet.add(page.loadingPath);\n  for (const layout of page.layouts) {\n    moduleSet.add(layout);\n    const layoutDataPath = layout.replace(/layout\\.ts$/, \"layout.data.ts\");\n    if (layoutDataPath !== layout && existsSync(layoutDataPath)) {\n      moduleSet.add(layoutDataPath);\n    }\n  }\n  if (page.actionPath) {\n    moduleSet.add(page.actionPath);\n    let set = actionPathsByPage.get(page.path);\n    if (!set) {\n      set = new Set<string>();\n      actionPathsByPage.set(page.path, set);\n    }\n    set.add(page.actionPath);\n  }\n}\n\n/**\n * Build a self-contained SSR entry file for a platform adapter.\n * The generated module exports a default `handler(request: Request): Response`\n * and embeds the full route table plus a registry of all page/layout/data/\n * action modules so the runtime never touches the file system.\n */\nexport async function buildSsrEntry(\n  routes: Awaited<ReturnType<typeof scanRoutes>>,\n  options: AdapterOptions,\n  entryDir: string,\n): Promise<string> {\n  // Collect all module paths that the SSR runtime may need to import.\n  const moduleSet = new Set<string>();\n  const actionPathsByPage = new Map<string, Set<string>>();\n  for (const page of routes.pages) {\n    collectPageModules(page, moduleSet, actionPathsByPage);\n  }\n  if (routes.error404) collectPageModules(routes.error404, moduleSet, actionPathsByPage);\n  if (routes.error500) collectPageModules(routes.error500, moduleSet, actionPathsByPage);\n  for (const api of routes.api) {\n    moduleSet.add(api.routePath);\n  }\n  const modules = Array.from(moduleSet);\n  const moduleIndex = new Map(modules.map((path, index) => [path, index]));\n\n  const imports = modules\n    .map((path, index) => {\n      const rel = relativeToPosix(entryDir, path);\n      return `import * as m_${index} from ${JSON.stringify(rel)};`;\n    })\n    .join(\"\\n\");\n\n  const renderPageRecord = (page: PageRoute): string => `{\n    path: ${JSON.stringify(page.path)},\n    pagePath: ${JSON.stringify(page.pagePath)},\n    dataPath: ${JSON.stringify(page.dataPath ?? null)},\n    actionPath: ${JSON.stringify(page.actionPath ?? null)},\n    loadingPath: ${JSON.stringify(page.loadingPath ?? null)},\n    layouts: ${JSON.stringify(page.layouts)},\n    params: ${JSON.stringify(page.params)},\n  }`;\n\n  const pages = routes.pages.map(renderPageRecord).join(\",\\n\");\n\n  const apiRoutes = routes.api\n    .map((api) => {\n      const index = moduleIndex.get(api.routePath);\n      return `  { path: ${JSON.stringify(api.path)}, routePath: m_${index} },`;\n    })\n    .join(\"\\n\");\n\n  const actionModules = Array.from(actionPathsByPage.entries())\n    .map(([pagePath, paths]) => {\n      const entries = Array.from(paths)\n        .map((path) => {\n          const index = moduleIndex.get(path);\n          return `      [${JSON.stringify(path)}, m_${index}],`;\n        })\n        .join(\"\\n\");\n      return `  [${JSON.stringify(pagePath)}, new Map([\\n${entries}\\n    ])],`;\n    })\n    .join(\"\\n\");\n\n  const actionsRegistry: Record<string, string[]> = {};\n  for (const page of routes.pages) {\n    if (!page.actionPath) continue;\n    const mod = (await import(page.actionPath)) as Record<string, unknown>;\n    const names: string[] = [];\n    for (const [name, value] of Object.entries(mod)) {\n      if (name === \"default\") continue;\n      if (typeof value === \"function\") {\n        names.push(name);\n      }\n    }\n    if (names.length > 0) {\n      actionsRegistry[page.path] = names;\n    }\n  }\n\n  return `// AUTO-GENERATED by @deijose/nix-js-kit. Do not edit.\nimport { handleActionRequest, matchApiRoute, matchRoute, renderPage, renderErrorPage } from \"@deijose/nix-js-kit\";\n${imports}\n\nconst registry = new Map<string, unknown>([\n${modules.map((path, index) => `  [${JSON.stringify(path)}, m_${index}],`).join(\"\\n\")}\n]);\n\nconst pages = [\n${pages},\n];\n\nconst apiRoutes = [\n${apiRoutes}\n];\n\nconst actionModules = new Map<string, Map<string, unknown>>([\n${actionModules}\n]);\n\nconst actions = ${JSON.stringify(actionsRegistry)};\n\nconst routes = {\n  pages,\n  api: apiRoutes,\n  error404: ${routes.error404 ? renderPageRecord(routes.error404) : \"undefined\"},\n  error500: ${routes.error500 ? renderPageRecord(routes.error500) : \"undefined\"},\n};\n\nconst clientEntry = ${JSON.stringify(options.clientEntry)};\nconst lang = ${JSON.stringify(options.lang)};\n\nfunction loadModule(path: string) {\n  const mod = registry.get(path);\n  if (mod) return mod;\n  throw new Error(\\`Module not found in registry: \\${path}\\`);\n}\n\nasync function resolveAction(name: string, page?: string) {\n  // Match concrete page paths (e.g. /movies/inception) to their route pattern\n  // (/movies/:slug) so actions on dynamic routes resolve by scope.\n  let pageKey: string | undefined;\n  if (page) {\n    pageKey = routes.pages.some((route) => route.path === page)\n      ? page\n      : (matchRoute(page, routes.pages)?.route.path ?? page);\n  }\n  const pageModules = pageKey ? actionModules.get(pageKey) : undefined;\n  const candidates = pageModules ? [...pageModules.values()] : [];\n  if (!pageModules) {\n    for (const mods of actionModules.values()) {\n      for (const mod of mods.values()) {\n        const action = (mod as Record<string, unknown>)[name];\n        if (typeof action === \"function\") return action;\n      }\n    }\n  }\n  for (const mod of candidates) {\n    const action = (mod as Record<string, unknown>)[name];\n    if (typeof action === \"function\") {\n      return action as (...args: unknown[]) => unknown;\n    }\n  }\n  return undefined;\n}\n\nexport default async function handler(request: Request): Promise<Response> {\n  const url = new URL(request.url);\n\n  if (url.pathname === \"/__nix-js/actions\") {\n    return handleActionRequest(request, resolveAction);\n  }\n\n  // Render endpoint used by the SPA router and streaming boundaries.\n  if (url.pathname === \"/__nix-js/render\") {\n    const page = url.searchParams.get(\"page\") ?? \"/\";\n    const search = url.searchParams.get(\"search\") ?? \"\";\n    const wantsJson = (request.headers.get(\"Accept\") ?? \"\").includes(\"application/json\");\n    try {\n      const match = matchRoute(page, routes.pages);\n      if (!match) throw new Error(\\`No route found for \\${page}\\`);\n      const { html } = await renderPage({\n        route: match.route,\n        params: match.params,\n        searchParams: new URLSearchParams(search),\n        config: { lang, clientEntry },\n        importer: loadModule,\n        actions,\n        request,\n      });\n      const bodyStart = html.indexOf('<div id=\"app\">');\n      const bodyEnd = html.lastIndexOf(\"</div>\");\n      const body = bodyStart >= 0 && bodyEnd > bodyStart\n        ? html.slice(bodyStart + 13, bodyEnd).trim()\n        : html;\n      const titleStart = html.indexOf(\"<title>\");\n      const titleEnd = html.indexOf(\"</title>\");\n      const title = titleStart >= 0 && titleEnd > titleStart\n        ? html.slice(titleStart + 7, titleEnd)\n        : \"\";\n      if (wantsJson) {\n        return new Response(JSON.stringify({ title, body }), {\n          status: 200,\n          headers: { \"Content-Type\": \"application/json; charset=utf-8\" },\n        });\n      }\n      return new Response(body, {\n        status: 200,\n        headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n      });\n    } catch (err) {\n      if ((err as { name?: string }).name === \"RouteNotFoundError\") {\n        return new Response(\"Not Found\", {\n          status: 404,\n          headers: { \"Content-Type\": \"text/plain\" },\n        });\n      }\n      console.error(\"[nix-js-kit] render endpoint error:\", err);\n      return new Response(\"Internal Server Error\", {\n        status: 500,\n        headers: { \"Content-Type\": \"text/plain\" },\n      });\n    }\n  }\n\n  const apiMatch = matchApiRoute(url.pathname, apiRoutes);\n  if (apiMatch) {\n    const mod = apiMatch.route.routePath as Record<\n      string,\n      (request: Request, context?: { params: Record<string, string | string[]> }) => unknown\n    >;\n    const handler = mod[request.method ?? \"GET\"];\n    if (typeof handler !== \"function\") {\n      return new Response(\"Method not allowed: \" + request.method, { status: 405, headers: { \"Content-Type\": \"text/plain\" } });\n    }\n    return (await handler(request, { params: apiMatch.params })) as Response;\n  }\n\n  const match = matchRoute(url.pathname, routes.pages);\n  if (!match) {\n    const errorResult = await renderErrorPage({ routes, status: 404, config: { lang, clientEntry }, actions, importer: loadModule });\n    if (errorResult) {\n      return new Response(errorResult.html, { status: errorResult.status, headers: { \"Content-Type\": \"text/html; charset=utf-8\" } });\n    }\n    return new Response(\"Not Found\", { status: 404, headers: { \"Content-Type\": \"text/plain\" } });\n  }\n\n  try {\n    const { html } = await renderPage({\n      route: match.route,\n      params: match.params,\n      searchParams: new URLSearchParams(url.search),\n      config: { lang, clientEntry },\n      importer: loadModule,\n      actions,\n      request,\n    });\n    return new Response(html, { status: 200, headers: { \"Content-Type\": \"text/html; charset=utf-8\" } });\n  } catch (err) {\n    console.error(\"[nix-js-kit] SSR render error:\", err);\n    const errorResult = await renderErrorPage({ routes, status: 500, error: err, config: { lang, clientEntry }, actions, importer: loadModule });\n    if (errorResult) {\n      return new Response(errorResult.html, { status: errorResult.status, headers: { \"Content-Type\": \"text/html; charset=utf-8\" } });\n    }\n    return new Response(\"Internal Server Error\", { status: 500, headers: { \"Content-Type\": \"text/plain; charset=utf-8\" } });\n  }\n}\n`;\n}\n\nfunction relativeToPosix(from: string, to: string): string {\n  return relative(from, to).split(\"\\\\\").join(\"/\");\n}\n\n/**\n * Write a generated SSR entry file for an adapter.\n */\nexport async function writeSsrEntry(\n  entryPath: string,\n  routes: Awaited<ReturnType<typeof scanRoutes>>,\n  options: AdapterOptions,\n): Promise<void> {\n  await writeFile(\n    entryPath,\n    await buildSsrEntry(routes, options, dirname(entryPath)),\n    \"utf8\",\n  );\n}\n","import { mkdir, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { build } from \"vite\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\nimport type { Adapter } from \"./index.js\";\nimport { copyStatic, writeSsrEntry } from \"./shared.js\";\nimport { SERVERLESS_CAPABILITIES } from \"../runtime/capabilities.js\";\n\n/**\n * Vercel adapter for nix-js-kit.\n *\n * Produces a `.vercel/output` directory compatible with the Vercel Build Output\n * API (v3). Static files are served from `dist/` and unmatched routes fall back\n * to the SSR function.\n */\nexport const vercelAdapter: Adapter = {\n  name: \"vercel\",\n  capabilities: SERVERLESS_CAPABILITIES,\n\n  async build(options) {\n    const root = resolve(options.root);\n    const outDir = resolve(root, options.outDir);\n    const vercelOut = resolve(root, \".vercel/output\");\n    const functionsDir = join(vercelOut, \"functions\", \"__nix-js-kit.func\");\n    const generatedDir = resolve(root, \".nix-js\");\n\n    // Verify the production build exists.\n    try {\n      await stat(outDir);\n    } catch {\n      throw new Error(\n        `Output directory not found: ${outDir}. Run \"nix-js-kit build\" first.`,\n      );\n    }\n\n    // Clean previous adapter output.\n    await rm(vercelOut, { recursive: true, force: true });\n    await mkdir(vercelOut, { recursive: true });\n    await mkdir(functionsDir, { recursive: true });\n    await mkdir(generatedDir, { recursive: true });\n\n    // Copy static files.\n    await copyStatic(outDir, join(vercelOut, \"static\"));\n\n    // Scan routes and generate a self-contained function entry.\n    const appDir = resolve(root, options.appDir);\n    const routes = await scanRoutes(appDir);\n\n    const entryPath = resolve(generatedDir, \"vercel-index.ts\");\n    await writeSsrEntry(entryPath, routes, options);\n\n    // Bundle the function entry.\n    await build({\n      configFile: false,\n      root,\n      build: {\n        outDir: functionsDir,\n        emptyOutDir: true,\n        ssr: true,\n        lib: {\n          entry: entryPath,\n          formats: [\"es\"],\n          fileName: () => \"index.js\",\n        },\n        rollupOptions: {\n          external: [],\n          output: {\n            inlineDynamicImports: true,\n          },\n        },\n      },\n    });\n\n    // Vite SSR lib builds may use the entry file name, so force the expected handler name.\n    const generatedHandler = join(functionsDir, \"vercel-index.js\");\n    const targetHandler = join(functionsDir, \"index.js\");\n    try {\n      await stat(generatedHandler);\n      await rename(generatedHandler, targetHandler);\n    } catch {\n      // If the file is already named index.js, nothing to do.\n    }\n\n    // Write Vercel function config.\n    await writeFile(\n      join(functionsDir, \".vc-config.json\"),\n      JSON.stringify(\n        {\n          runtime: \"nodejs20.x\",\n          handler: \"index.js\",\n          launcherType: \"Nodejs\",\n          shouldAddHelpers: true,\n        },\n        null,\n        2,\n      ),\n      \"utf8\",\n    );\n\n    // Write Vercel root config.\n    await writeFile(\n      join(vercelOut, \"config.json\"),\n      JSON.stringify(\n        {\n          version: 3,\n          routes: [\n            { handle: \"filesystem\" },\n            { src: \"/(.*)\", \"dest\": \"/__nix-js-kit\" },\n          ],\n        },\n        null,\n        2,\n      ),\n      \"utf8\",\n    );\n  },\n};\n","import { mkdir, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { build } from \"vite\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\nimport type { Adapter } from \"./index.js\";\nimport { writeSsrEntry } from \"./shared.js\";\nimport { SERVERLESS_CAPABILITIES } from \"../runtime/capabilities.js\";\n\n/**\n * Netlify adapter for nix-js-kit.\n *\n * Produces the files expected by Netlify Functions v2:\n *   - `netlify/functions/__nix-js-kit.mjs` — bundled SSR function.\n *   - `netlify.toml` — redirects unmatched routes to the function.\n *\n * Run this after `nix-js-kit build`. The static files are left in `dist/` and\n * served directly by Netlify; the function only handles routes that have no\n * matching static file.\n */\nexport const netlifyAdapter: Adapter = {\n  name: \"netlify\",\n  capabilities: SERVERLESS_CAPABILITIES,\n\n  async build(options) {\n    const root = resolve(options.root);\n    const outDir = resolve(root, options.outDir);\n    const netlifyDir = resolve(root, \"netlify\");\n    const functionsDir = join(netlifyDir, \"functions\");\n    const generatedDir = resolve(root, \".nix-js\");\n\n    // Verify the production build exists.\n    try {\n      await stat(outDir);\n    } catch {\n      throw new Error(\n        `Output directory not found: ${outDir}. Run \"nix-js-kit build\" first.`,\n      );\n    }\n\n    // Clean previous adapter output.\n    await rm(functionsDir, { recursive: true, force: true });\n    await mkdir(functionsDir, { recursive: true });\n    await mkdir(generatedDir, { recursive: true });\n\n    // Scan routes and generate a self-contained function entry.\n    const appDir = resolve(root, options.appDir);\n    const routes = await scanRoutes(appDir);\n\n    const entryPath = resolve(generatedDir, \"netlify-index.ts\");\n    await writeSsrEntry(entryPath, routes, options);\n\n    // Bundle the function entry.\n    await build({\n      configFile: false,\n      root,\n      build: {\n        outDir: functionsDir,\n        emptyOutDir: true,\n        ssr: true,\n        lib: {\n          entry: entryPath,\n          formats: [\"es\"],\n          fileName: () => \"__nix-js-kit.mjs\",\n        },\n        rollupOptions: {\n          external: [],\n          output: {\n            inlineDynamicImports: true,\n          },\n        },\n      },\n    });\n\n    // Vite SSR lib builds may use the entry file name, so force the expected handler name.\n    const generatedHandler = join(functionsDir, \"netlify-index.js\");\n    const targetHandler = join(functionsDir, \"__nix-js-kit.mjs\");\n    try {\n      await stat(generatedHandler);\n      await rename(generatedHandler, targetHandler);\n    } catch {\n      // If the file is already named __nix-js-kit.mjs, nothing to do.\n    }\n\n    // Write Netlify redirects config.\n    await writeFile(\n      join(root, \"netlify.toml\"),\n      `[build]\n  command = \"nix-js-kit build\"\n  publish = \"dist\"\n\n[[redirects]]\n  from = \"/*\"\n  to = \"/.netlify/functions/__nix-js-kit\"\n  status = 200\n`,\n      \"utf8\",\n    );\n  },\n};\n","import { mkdir, rm, stat, writeFile } from \"node:fs/promises\";\nimport { relative, resolve } from \"node:path\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\nimport type { Adapter } from \"./index.js\";\nimport { writeSsrEntry } from \"./shared.js\";\nimport { DEFAULT_CAPABILITIES } from \"../runtime/capabilities.js\";\n\n/**\n * Bun adapter for nix-js-kit.\n *\n * Produces a self-contained Bun server entry at `.nix-js/bun-server.ts`.\n * Run it with:\n *\n *   bun run .nix-js/bun-server.ts\n *\n * The server serves static files from `dist/` and renders pages on demand for\n * unmatched routes.\n */\nexport const bunAdapter: Adapter = {\n  name: \"bun\",\n  capabilities: DEFAULT_CAPABILITIES,\n\n  async build(options) {\n    const root = resolve(options.root);\n    const outDir = resolve(root, options.outDir);\n    const generatedDir = resolve(root, \".nix-js\");\n\n    // Verify the production build exists.\n    try {\n      await stat(outDir);\n    } catch {\n      throw new Error(\n        `Output directory not found: ${outDir}. Run \"nix-js-kit build\" first.`,\n      );\n    }\n\n    // Clean previous adapter output.\n    await rm(generatedDir, { recursive: true, force: true });\n    await mkdir(generatedDir, { recursive: true });\n\n    // Scan routes and generate a self-contained SSR handler entry.\n    const appDir = resolve(root, options.appDir);\n    const routes = await scanRoutes(appDir);\n\n    const entryPath = resolve(generatedDir, \"bun-index.ts\");\n    await writeSsrEntry(entryPath, routes, options);\n\n    // Write the Bun server entry.\n    const serverPath = resolve(generatedDir, \"bun-server.ts\");\n    await writeFile(\n      serverPath,\n      buildBunServerSource(relativeToUrlPath(generatedDir, outDir), options),\n      \"utf8\",\n    );\n  },\n};\n\nfunction buildBunServerSource(\n  outDirUrl: string,\n  options: {\n    clientEntry: string;\n    lang: string;\n    port?: number;\n  },\n): string {\n  return `// AUTO-GENERATED by @deijose/nix-js-kit. Do not edit.\nimport { fileURLToPath } from \"node:url\";\nimport { createWebHandler } from \"@deijose/nix-js-kit/runtime\";\nimport handler from \"./bun-index.ts\";\n\nconst outDir = fileURLToPath(new URL(${JSON.stringify(outDirUrl)}, import.meta.url));\nconst port = Number(process.env.PORT) || ${options.port ?? 3000};\n\nconst webHandler = createWebHandler(\n  { pages: [], api: [], error404: undefined, error500: undefined },\n  {},\n  { staticRoot: outDir, lang: ${JSON.stringify(options.lang)}, clientEntry: ${JSON.stringify(options.clientEntry)} },\n);\n\nBun.serve({\n  port,\n  async fetch(request) {\n    // Try static files first via the unified handler, then fall back to the\n    // bundled SSR handler for dynamic routes.\n    let response = await webHandler(request);\n    if (response.status === 404) {\n      response = await handler(request);\n    }\n    return response;\n  },\n});\n\nconsole.log(\\`Bun server running at http://localhost:\\${port}\\`);\n`;\n}\n\nfunction relativeToUrlPath(from: string, to: string): string {\n  const path = relative(from, to).split(\"\\\\\").join(\"/\");\n  return `${path.startsWith(\".\") ? path : `./${path}`}/`;\n}\n","import { mkdir, rm, stat, writeFile } from \"node:fs/promises\";\nimport { relative, resolve } from \"node:path\";\nimport { build } from \"vite\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\nimport type { Adapter } from \"./index.js\";\nimport { writeSsrEntry } from \"./shared.js\";\nimport { DEFAULT_CAPABILITIES } from \"../runtime/capabilities.js\";\n\n/**\n * Node adapter for nix-js-kit.\n *\n * Produces a self-contained Node server entry at `.nix-js/node-server.mjs`.\n * Run it with:\n *\n *   node .nix-js/node-server.mjs\n *\n * The server serves static files from `dist/` and renders pages on demand for\n * unmatched routes.\n */\nexport const nodeAdapter: Adapter = {\n  name: \"node\",\n  capabilities: DEFAULT_CAPABILITIES,\n\n  async build(options) {\n    const root = resolve(options.root);\n    const outDir = resolve(root, options.outDir);\n    const generatedDir = resolve(root, \".nix-js\");\n\n    try {\n      await stat(outDir);\n    } catch {\n      throw new Error(\n        `Output directory not found: ${outDir}. Run \"nix-js-kit build\" first.`,\n      );\n    }\n\n    await rm(generatedDir, { recursive: true, force: true });\n    await mkdir(generatedDir, { recursive: true });\n\n    const appDir = resolve(root, options.appDir);\n    const routes = await scanRoutes(appDir);\n\n    const entryPath = resolve(generatedDir, \"node-index.ts\");\n    await writeSsrEntry(entryPath, routes, options);\n\n    const serverPath = resolve(generatedDir, \"node-server.ts\");\n    await writeFile(\n      serverPath,\n      buildNodeServerSource(relativeToUrlPath(generatedDir, outDir), options),\n      \"utf8\",\n    );\n\n    await build({\n      configFile: false,\n      root,\n      build: {\n        outDir: generatedDir,\n        emptyOutDir: false,\n        ssr: true,\n        lib: {\n          entry: serverPath,\n          formats: [\"es\"],\n        },\n        rollupOptions: {\n          external: [/^@deijose\\/nix-js-kit(?:\\/.*)?$/, /^@deijose\\/nix-js(?:\\/.*)?$/, /^node:/],\n          output: {\n            entryFileNames: \"node-server.mjs\",\n            inlineDynamicImports: true,\n          },\n        },\n      },\n    });\n  },\n};\n\nfunction buildNodeServerSource(\n  outDirUrl: string,\n  options: {\n    clientEntry: string;\n    lang: string;\n    port?: number;\n  },\n): string {\n  return `// AUTO-GENERATED by @deijose/nix-js-kit. Do not edit.\nimport { createServer } from \"node:http\";\nimport { fileURLToPath } from \"node:url\";\nimport { createWebHandler } from \"@deijose/nix-js-kit/runtime\";\nimport { incomingMessageToRequest } from \"@deijose/nix-js-kit/runtime\";\nimport handler from \"./node-index.ts\";\n\nconst outDir = fileURLToPath(new URL(${JSON.stringify(outDirUrl)}, import.meta.url));\nconst port = Number(process.env.PORT) || ${options.port ?? 3000};\n\n// The adapter-bundled handler already handles actions, API routes, render\n// endpoint and dynamic SSR. We only need to add static file serving from\n// the output directory, then fall through to the bundled handler.\nconst webHandler = createWebHandler(\n  { pages: [], api: [], error404: undefined, error500: undefined },\n  {},\n  { staticRoot: outDir, lang: ${JSON.stringify(options.lang)}, clientEntry: ${JSON.stringify(options.clientEntry)} },\n);\n\ncreateServer(async (req, res) => {\n  const body = req.method !== \"GET\" && req.method !== \"HEAD\"\n    ? await readBody(req)\n    : undefined;\n  const request = incomingMessageToRequest(req, body);\n  // Try static files first via the unified handler, then fall back to the\n  // bundled SSR handler for dynamic routes.\n  let response = await webHandler(request);\n  if (response.status === 404) {\n    response = await handler(request);\n  }\n  res.writeHead(response.status, Object.fromEntries(response.headers.entries()));\n  res.end(Buffer.from(await response.arrayBuffer()));\n}).listen(port, () => {\n  console.log(\\`Node server running at http://localhost:\\${port}\\`);\n});\n\nfunction readBody(req: import(\"node:http\").IncomingMessage): Promise<Buffer> {\n  return new Promise((resolve, reject) => {\n    const chunks: Buffer[] = [];\n    req.on(\"data\", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));\n    req.on(\"end\", () => resolve(Buffer.concat(chunks)));\n    req.on(\"error\", reject);\n  });\n}\n`;\n}\n\nfunction relativeToUrlPath(from: string, to: string): string {\n  const path = relative(from, to).split(\"\\\\\").join(\"/\");\n  return `${path.startsWith(\".\") ? path : `./${path}`}/`;\n}\n","// --- CLI commands: check, routes, doctor (plan §12.1) ---\n//\n// `check`  — typechecks the project and validates route/config integrity.\n// `routes` — lists all discovered routes and their metadata.\n// `doctor` — diagnoses common configuration and environment issues.\n//\n// All commands produce actionable error messages with cause/path/suggestion\n// and reliable exit codes.\n\nimport { stat, access } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\nimport { scanActions } from \"../action/scan.js\";\nimport type { CliOptions } from \"../cli.js\";\n\n/** Exit codes used by all CLI commands. */\nexport const ExitCode = {\n  Success: 0,\n  GenericError: 1,\n  ConfigError: 2,\n  TypeError: 3,\n  RouteConflict: 4,\n  MissingDependency: 5,\n} as const;\n\n/** Formats an error with cause, path, and suggestion. */\nexport function formatError(\n  cause: string,\n  path?: string,\n  suggestion?: string,\n): string {\n  const parts = [cause];\n  if (path) parts.push(`  at: ${path}`);\n  if (suggestion) parts.push(`  fix: ${suggestion}`);\n  return parts.join(\"\\n\");\n}\n\n// check — typecheck + route/config integrity\n\nexport async function doCheck(options: CliOptions): Promise<number> {\n  console.log(\"Running typecheck...\");\n  const typecheckResult = await runTypecheck(options.root);\n  if (typecheckResult !== 0) {\n    console.error(formatError(\n      \"Typecheck failed.\",\n      undefined,\n      \"Fix TypeScript errors above before building.\",\n    ));\n    return ExitCode.TypeError;\n  }\n  console.log(\"✓ Typecheck passed\");\n\n  console.log(\"\\nValidating routes...\");\n  try {\n    const routes = await scanRoutes(options.appDir);\n    console.log(`✓ ${routes.pages.length} page route(s), ${routes.api.length} API route(s)`);\n    if (routes.error404) console.log(\"  - 404 page: configured\");\n    if (routes.error500) console.log(\"  - 500 page: configured\");\n  } catch (err) {\n    const message = err instanceof Error ? err.message : String(err);\n    console.error(formatError(\n      \"Route validation failed.\",\n      options.appDir,\n      message,\n    ));\n    return ExitCode.RouteConflict;\n  }\n\n  console.log(\"\\nValidating actions...\");\n  try {\n    const actions = await scanActions(options.appDir);\n    console.log(`✓ ${actions.size} action(s) discovered`);\n  } catch (err) {\n    const message = err instanceof Error ? err.message : String(err);\n    console.error(formatError(\n      \"Action validation failed.\",\n      options.appDir,\n      message,\n    ));\n    return ExitCode.GenericError;\n  }\n\n  console.log(\"\\n✓ All checks passed\");\n  return ExitCode.Success;\n}\n\n// routes — list all discovered routes\n\nexport async function doRoutes(options: CliOptions): Promise<number> {\n  try {\n    const routes = await scanRoutes(options.appDir);\n\n    console.log(\"\\nPage routes:\");\n    if (routes.pages.length === 0) {\n      console.log(\"  (none)\");\n    } else {\n      for (const page of routes.pages) {\n        const params = page.params.length > 0 ? ` [${page.params.join(\", \")}]` : \"\";\n        const loading = page.loadingPath ? \" +loading\" : \"\";\n        const action = page.actionPath ? \" +action\" : \"\";\n        const data = page.dataPath ? \" +data\" : \"\";\n        const optional = page.optionalCatchAll ? \" (optional)\" : \"\";\n        console.log(`  ${page.path}${params}${data}${loading}${action}${optional}`);\n        console.log(`    page: ${relative(options.root, page.pagePath)}`);\n        if (page.layouts.length > 0) {\n          console.log(`    layouts: ${page.layouts.map((l) => relative(options.root, l)).join(\" → \")}`);\n        }\n      }\n    }\n\n    console.log(\"\\nAPI routes:\");\n    if (routes.api.length === 0) {\n      console.log(\"  (none)\");\n    } else {\n      for (const api of routes.api) {\n        const params = api.params.length > 0 ? ` [${api.params.join(\", \")}]` : \"\";\n        console.log(`  ${api.path}${params}`);\n        console.log(`    route: ${relative(options.root, api.routePath)}`);\n      }\n    }\n\n    if (routes.error404) {\n      console.log(`\\n404 page: ${relative(options.root, routes.error404.pagePath)}`);\n    } else {\n      console.log(\"\\n404 page: (not configured)\");\n    }\n    if (routes.error500) {\n      console.log(`500 page: ${relative(options.root, routes.error500.pagePath)}`);\n    } else {\n      console.log(\"500 page: (not configured)\");\n    }\n\n    return ExitCode.Success;\n  } catch (err) {\n    const message = err instanceof Error ? err.message : String(err);\n    console.error(formatError(\"Failed to scan routes.\", options.appDir, message));\n    return ExitCode.RouteConflict;\n  }\n}\n\n// doctor — diagnose common issues\n\ninterface DiagnosticResult {\n  name: string;\n  status: \"ok\" | \"warn\" | \"error\";\n  message: string;\n  suggestion?: string;\n}\n\nexport async function doDoctor(options: CliOptions): Promise<number> {\n  const results: DiagnosticResult[] = [];\n\n  // Check 1: app directory exists\n  results.push(await checkExists(\"App directory\", options.appDir, \"Create src/app/ with at least a page.ts\"));\n\n  // Check 2: islands directory exists (optional)\n  if (options.islandsDir) {\n    results.push(await checkExists(\"Islands directory\", options.islandsDir, \"Create src/islands/ for client-side islands\", \"warn\"));\n  }\n\n  // Check 3: public directory exists (optional)\n  if (options.publicDir) {\n    results.push(await checkExists(\"Public directory\", options.publicDir, \"Create public/ for static assets\", \"warn\"));\n  }\n\n  // Check 4: nix-js.config.ts exists (optional)\n  const preferredPaths = [\"nix-js.config.ts\", \"nix-js.config.js\", \"nix-js.config.mjs\"];\n  const legacyPaths = [\"nix.config.ts\", \"nix.config.js\", \"nix.config.mjs\"];\n  let configFound = false;\n  let foundName: string | undefined;\n  let isLegacy = false;\n  for (const p of preferredPaths) {\n    try {\n      await access(join(options.root, p));\n      configFound = true;\n      foundName = p;\n      break;\n    } catch {\n      // continue\n    }\n  }\n  if (!configFound) {\n    for (const p of legacyPaths) {\n      try {\n        await access(join(options.root, p));\n        configFound = true;\n        foundName = p;\n        isLegacy = true;\n        break;\n      } catch {\n        // continue\n      }\n    }\n  }\n  if (configFound && foundName) {\n    results.push({\n      name: \"Config file\",\n      status: isLegacy ? \"warn\" : \"ok\",\n      message: `Found ${foundName}${isLegacy ? \" (legacy, rename to nix-js.config.* )\" : \"\"}`,\n      suggestion: isLegacy\n        ? `Rename ${foundName} to nix-js.config.${foundName.split(\".\").slice(1).join(\".\")} (deprecated name)`\n        : undefined,\n    });\n  } else {\n    results.push({\n      name: \"Config file\",\n      status: \"warn\",\n      message: \"No nix-js.config.ts/js/mjs found\",\n      suggestion: \"Create nix-js.config.ts for custom configuration (optional, defaults work)\",\n    });\n  }\n\n  // Check 5: TypeScript config exists\n  results.push(await checkExists(\"tsconfig.json\", join(options.root, \"tsconfig.json\"), \"Create a tsconfig.json for TypeScript support\", \"warn\"));\n\n  // Check 6: Node.js version\n  const nodeVersion = process.versions.node;\n  const major = parseInt(nodeVersion.split(\".\")[0]!, 10);\n  if (major >= 18) {\n    results.push({ name: \"Node.js version\", status: \"ok\", message: `v${nodeVersion}` });\n  } else {\n    results.push({\n      name: \"Node.js version\",\n      status: \"error\",\n      message: `v${nodeVersion} (requires >= 18)`,\n      suggestion: \"Upgrade Node.js to v18 or later\",\n    });\n  }\n\n  // Check 7: routes scan\n  try {\n    const routes = await scanRoutes(options.appDir);\n    results.push({\n      name: \"Route scan\",\n      status: routes.pages.length > 0 ? \"ok\" : \"warn\",\n      message: `${routes.pages.length} page(s), ${routes.api.length} API route(s)`,\n    });\n  } catch (err) {\n    const message = err instanceof Error ? err.message : String(err);\n    results.push({\n      name: \"Route scan\",\n      status: \"error\",\n      message: message,\n      suggestion: \"Fix route conflicts or file structure issues\",\n    });\n  }\n\n  // Check 8: optional peer dependencies\n  const peers = [\n    { name: \"marked\", import: \"marked\", purpose: \"Markdown rendering\" },\n    { name: \"zod\", import: \"zod\", purpose: \"Schema validation\" },\n    { name: \"sharp\", import: \"sharp\", purpose: \"Image optimization\" },\n  ];\n  for (const peer of peers) {\n    try {\n      await import(peer.import);\n      results.push({ name: `Peer dep: ${peer.name}`, status: \"ok\", message: `available (${peer.purpose})` });\n    } catch {\n      results.push({\n        name: `Peer dep: ${peer.name}`,\n        status: \"warn\",\n        message: `not installed (${peer.purpose})`,\n        suggestion: `Install with: bun add ${peer.name}`,\n      });\n    }\n  }\n\n  // Print results\n  console.log(\"\\nNix.js Kit doctor\\n\");\n  let hasErrors = false;\n  let hasWarnings = false;\n  for (const result of results) {\n    const icon = result.status === \"ok\" ? \"✓\" : result.status === \"warn\" ? \"⚠\" : \"✗\";\n    const color = result.status === \"ok\" ? \"\" : result.status === \"warn\" ? \"\" : \"\";\n    console.log(`${icon} ${result.name}: ${color}${result.message}`);\n    if (result.suggestion) console.log(`    → ${result.suggestion}`);\n    if (result.status === \"error\") hasErrors = true;\n    if (result.status === \"warn\") hasWarnings = true;\n  }\n\n  console.log(\"\");\n  if (hasErrors) {\n    console.log(\"✗ Issues found. Fix errors before building.\");\n    return ExitCode.GenericError;\n  } else if (hasWarnings) {\n    console.log(\"⚠ Warnings found. Project may work but consider fixing them.\");\n    return ExitCode.Success;\n  } else {\n    console.log(\"✓ All checks passed. Project is healthy.\");\n    return ExitCode.Success;\n  }\n}\n\n// Helpers\n\nasync function checkExists(\n  name: string,\n  path: string,\n  suggestion: string,\n  level: \"error\" | \"warn\" = \"error\",\n): Promise<DiagnosticResult> {\n  try {\n    await stat(path);\n    return { name, status: \"ok\", message: path };\n  } catch {\n    return {\n      name,\n      status: level,\n      message: `not found at ${path}`,\n      suggestion,\n    };\n  }\n}\n\nasync function runTypecheck(root: string): Promise<number> {\n  return new Promise((resolve) => {\n    const child = spawn(\"npx\", [\"tsc\", \"--noEmit\"], {\n      cwd: root,\n      stdio: \"inherit\",\n      shell: true,\n    });\n    child.on(\"close\", (code) => resolve(code ?? 1));\n    child.on(\"error\", () => resolve(1));\n  });\n}\n","import { stat } from \"node:fs/promises\";\nimport { createServer } from \"node:http\";\nimport { join, resolve, relative } from \"node:path\";\nimport { existsSync, watch } from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\nimport { build, type BuildConfig } from \"./build/build.js\";\nimport { transformProjectFiles, transformedAppDir as transformedAppDirOf } from \"./build/transform-source.js\";\nimport { createSsrServer } from \"./ssr/server.js\";\nimport { scanActions } from \"./action/scan.js\";\nimport { scanRoutes } from \"./router/route-scanner.js\";\nimport { incomingMessageToRequest } from \"./runtime/node-http.js\";\nimport { loadNixConfig, type ResolvedNixConfig } from \"./config/index.js\";\nimport { createAppManifest, writeAppManifest, writeRouteTypes } from \"./manifest/index.js\";\nimport { validateCapabilities } from \"./runtime/capabilities.js\";\n\n// --- CLI ---\n//\n// Minimal command-line interface for Nix.js Kit. Supports:\n//   nix-js-kit build   — run a production static build\n//   nix-js-kit dev     — run a dev server that rebuilds on file changes\n//   nix-js-kit preview — serve the static build in production mode\n//   nix-js-kit start   — run an SSR server that renders pages on demand\n//\n// This is intentionally small: no generators, no config file parsing, just\n// convention-based defaults overridable via CLI flags.\n\nexport interface CliOptions {\n  command: \"build\" | \"dev\" | \"preview\" | \"start\" | \"adapter\" | \"check\" | \"routes\" | \"doctor\";\n  adapterName?: \"vercel\" | \"netlify\" | \"bun\" | \"node\";\n  root: string;\n  appDir: string;\n  islandsDir?: string;\n  outDir: string;\n  publicDir?: string;\n  generatedEntry: string;\n  clientEntry: string;\n  port: number;\n  host: string;\n  lang: string;\n  hydrateImport?: string;\n  routerImport?: string;\n  /**\n   * Path to a Vite config used to build the client hydration bundle.\n   * In dev mode it is rebuilt whenever source files change.\n   */\n  clientConfig?: string;\n  /** Absolute path to the ISR cache directory. */\n  cacheDir?: string;\n  /** Default revalidate interval in seconds for ISR. */\n  defaultRevalidate?: number;\n  configFile?: string;\n  resolvedConfig?: ResolvedNixConfig;\n}\n\nfunction parseArgs(argv: string[]): CliOptions {\n  const args = argv.slice(2);\n  if (args.includes(\"--help\") || args.includes(\"-?\")) {\n    printHelp();\n    process.exit(0);\n  }\n  const command = args[0];\n  if (\n    command !== \"build\" &&\n    command !== \"dev\" &&\n    command !== \"preview\" &&\n    command !== \"start\" &&\n    command !== \"adapter\" &&\n    command !== \"check\" &&\n    command !== \"routes\" &&\n    command !== \"doctor\"\n  ) {\n    throw new Error(`Usage: nix-js-kit <build|dev|preview|start|adapter|check|routes|doctor> [options]`);\n  }\n  const adapterName = command === \"adapter\" ? args[1] : undefined;\n  if (\n    command === \"adapter\" &&\n    adapterName !== \"vercel\" &&\n    adapterName !== \"netlify\" &&\n    adapterName !== \"bun\" &&\n    adapterName !== \"node\"\n  ) {\n    throw new Error(`Usage: nix-js-kit adapter <vercel|netlify|bun|node> [options]`);\n  }\n  const optionStart = command === \"adapter\" ? 2 : 1;\n\n  let root = process.cwd();\n  let appDir = \"src/app\";\n  let islandsDir = \"src/islands\";\n  let outDir = \"dist\";\n  let publicDir = \"public\";\n  let generatedEntry = \".nix-js/entry-client.ts\";\n  let clientEntry = \"/_nix-js/entry-client.js\";\n  let port = 3000;\n  let host = \"127.0.0.1\";\n  let lang = \"es\";\n  let hydrateImport: string | undefined;\n  let routerImport: string | undefined;\n  let clientConfig: string | undefined;\n  let cacheDir: string | undefined;\n  let defaultRevalidate: number | undefined;\n  let configFile: string | undefined;\n\n  for (let i = optionStart; i < args.length; i++) {\n    const arg = args[i];\n    const next = args[i + 1];\n    switch (arg) {\n      case \"--root\":\n      case \"-r\":\n        root = next;\n        i++;\n        break;\n      case \"--app\":\n      case \"-a\":\n        appDir = next;\n        i++;\n        break;\n      case \"--islands\":\n      case \"-i\":\n        islandsDir = next;\n        i++;\n        break;\n      case \"--out\":\n      case \"-o\":\n        outDir = next;\n        i++;\n        break;\n      case \"--public\":\n        publicDir = next;\n        i++;\n        break;\n      case \"--port\":\n      case \"-p\":\n        port = Number(next);\n        i++;\n        break;\n      case \"--host\":\n      case \"-h\":\n        host = next;\n        i++;\n        break;\n      case \"--lang\":\n      case \"-l\":\n        lang = next;\n        i++;\n        break;\n      case \"--hydrate-import\":\n        hydrateImport = next;\n        i++;\n        break;\n      case \"--router-import\":\n        routerImport = next;\n        i++;\n        break;\n      case \"--client-config\":\n        clientConfig = next;\n        i++;\n        break;\n      case \"--config\":\n        configFile = next;\n        i++;\n        break;\n      case \"--cache-dir\":\n        cacheDir = next;\n        i++;\n        break;\n      case \"--default-revalidate\":\n        defaultRevalidate = Number(next);\n        i++;\n        break;\n      case \"--help\":\n      case \"-?\":\n        printHelp();\n        process.exit(0);\n      default:\n        throw new Error(`Unknown option: ${arg}`);\n    }\n  }\n\n  return {\n    command,\n    adapterName: adapterName as CliOptions[\"adapterName\"],\n    root: resolve(root),\n    appDir: resolve(root, appDir),\n    islandsDir: resolve(root, islandsDir),\n    outDir: resolve(root, outDir),\n    publicDir: resolve(root, publicDir),\n    generatedEntry: resolve(root, generatedEntry),\n    clientEntry,\n    port,\n    host,\n    lang,\n    hydrateImport,\n    routerImport,\n    clientConfig: clientConfig ? resolve(root, clientConfig) : undefined,\n    cacheDir: cacheDir ? resolve(root, cacheDir) : undefined,\n    defaultRevalidate,\n    configFile: configFile ? resolve(root, configFile) : undefined,\n  };\n}\n\nfunction printHelp(): void {\n  console.log(`\nnix-js-kit <command> [options]\n\nCommands:\n  build            Run a static site build\n  dev              Run a development server with rebuild-on-change\n  preview          Serve the static build in production mode\n  start            Run an SSR server that renders pages on demand\n  adapter <name>   Generate deployment output for a platform (vercel|netlify|bun|node)\n  check            Typecheck the project and validate route/config integrity\n  routes           List all discovered routes and their metadata\n  doctor           Diagnose common configuration and environment issues\n\nOptions:\n  -r, --root <dir>          Project root (default: cwd)\n  -a, --app <dir>           App directory relative to root (default: src/app)\n  -i, --islands <dir>       Islands directory relative to root (default: src/islands)\n  -o, --out <dir>           Output directory relative to root (default: dist)\n  --public <dir>            Public directory relative to root (default: public)\n  -p, --port <number>       Server port (default: 3000)\n  -h, --host <address>      Server host (default: 127.0.0.1)\n  -l, --lang <lang>         HTML lang attribute (default: es)\n  --hydrate-import <spec>   Import specifier for hydrateIslands in generated entry\n  --router-import <spec>    Import specifier for startClientRouter in generated entry\n  --client-config <path>    Vite config used to build the client hydration bundle\n  --config <path>           Nix config file (default: nix-js.config.ts/js/mjs)\n  --cache-dir <dir>         Directory for ISR cache (only used by start)\n  --default-revalidate <s>  Default ISR revalidate interval in seconds\n`);\n}\n\nfunction toBuildConfig(options: CliOptions): BuildConfig {\n  return {\n    root: options.root,\n    appDir: options.appDir,\n    outDir: options.outDir,\n    publicDir: options.publicDir,\n    clientEntry: options.clientEntry,\n    lang: options.lang,\n    islandsDir: options.islandsDir,\n    generatedEntry: options.generatedEntry,\n    hydrateImport: options.hydrateImport,\n    routerImport: options.routerImport,\n    imageFormats: options.resolvedConfig?.images.formats,\n    integrations: options.resolvedConfig?.integrations,\n  };\n}\n\nasync function doBuild(options: CliOptions): Promise<void> {\n  const transformedRoot = join(options.root, \".nix-js\", \"transformed\");\n  const transformedAppDir = transformedAppDirOf(options.root, options.appDir, options.islandsDir, transformedRoot);\n  await transformProjectFiles({\n    root: options.root,\n    appDir: options.appDir,\n    islandsDir: options.islandsDir,\n    outDir: transformedRoot,\n  });\n\n  // Atomic output staging: build into a temp directory, then swap to the final\n  // outDir so a crashed build never leaves a half-written dist.\n  const { beginAtomicStage } = await import(\"./build/vite-build.js\");\n  const stage = await beginAtomicStage({ outDir: options.outDir });\n  const tempOutDir = stage.tempDir;\n\n  try {\n    const buildConfig = toBuildConfig(options);\n    buildConfig.appDir = transformedAppDir;\n    buildConfig.outDir = tempOutDir;\n    const result = await build(buildConfig);\n\n    // Emit the portable application manifest and route types when a resolved\n    // config is available. The manifest is the source of truth for adapters,\n    // the client island registry and runtime route metadata.\n    if (options.resolvedConfig) {\n      try {\n        const manifest = await createAppManifest(options.resolvedConfig);\n        const manifestPath = join(tempOutDir, \".nix-js\", \"manifest.json\");\n        await writeAppManifest(manifest, manifestPath);\n        const typesPath = join(options.root, \".nix-js\", \"routes.d.ts\");\n        await writeRouteTypes(manifest, typesPath);\n        console.log(`  - manifest: ${relative(options.root, join(options.outDir, \".nix-js\", \"manifest.json\"))}`);\n      } catch (err) {\n        console.warn(\"[nix-js-kit] manifest generation failed:\", err);\n      }\n    }\n\n    if (options.islandsDir && !options.clientConfig) {\n      const autoConfig = await findClientConfig(options.root);\n      if (autoConfig) {\n        options.clientConfig = autoConfig;\n      }\n    }\n    if (options.clientConfig) {\n      // Temporarily redirect the client build to the staging directory.\n      const originalOutDir = options.outDir;\n      options.outDir = tempOutDir;\n      try {\n        await buildClient(options);\n      } finally {\n        options.outDir = originalOutDir;\n      }\n    }\n\n    // Atomically swap the staged output into the final destination.\n    await stage.commit();\n\n    console.log(`✓ Build completo: ${result.pages} páginas generadas`);\n    for (const file of result.files) {\n      console.log(\"  -\", relative(options.root, file));\n    }\n    if (result.islands.length > 0) {\n      console.log(`\\n✓ ${result.islands.length} island(s) detectada(s):`);\n      for (const island of result.islands) {\n        console.log(\"  -\", island.name);\n      }\n      if (result.generatedEntry) {\n        console.log(\"  entry:\", relative(options.root, result.generatedEntry));\n      }\n    }\n    if (result.skipped.length > 0) {\n      console.log(\"\\nRutas dinámicas omitidas (necesitan generateStaticParams):\");\n      for (const path of result.skipped) {\n        console.log(\"  -\", path);\n      }\n    }\n  } catch (err) {\n    await stage.rollback();\n    throw err;\n  }\n}\n\nconst DEV_WORKER_ENV = \"NIX_JS_KIT_DEV_WORKER\";\n\nasync function doDev(options: CliOptions): Promise<void> {\n  await doBuild(options);\n\n  const transformedRoot = join(options.root, \".nix-js\", \"transformed\");\n  const transformedAppDir = transformedAppDirOf(options.root, options.appDir, options.islandsDir, transformedRoot);\n  await transformProjectFiles({\n    root: options.root,\n    appDir: options.appDir,\n    islandsDir: options.islandsDir,\n    outDir: transformedRoot,\n  });\n\n  const actions = await scanActions(transformedAppDir);\n  const routes = await scanRoutes(transformedAppDir);\n  const server = createServer((req, res) => handleRequest(req, res, options, actions, routes, true));\n\n  const shutdown = () => {\n    server.close(() => process.exit(0));\n    setTimeout(() => process.exit(0), 2000).unref();\n  };\n  process.on(\"SIGTERM\", shutdown);\n  process.on(\"SIGINT\", shutdown);\n\n  server.listen(options.port, options.host, () => {\n    console.log(`\\n  → Dev server http://${options.host}:${options.port}`);\n  });\n}\n\n/**\n * Dev supervisor: runs the actual dev server in a child process and restarts\n * it whenever app/islands source files change. A fresh process means a fresh\n * module registry, so edits to pages, loaders, layouts and islands are always\n * picked up (no stale ESM cache).\n */\nasync function doDevSupervisor(options: CliOptions): Promise<void> {\n  // Re-invoke this bin with the same flags; the worker branch (env var set)\n  // runs the actual server in a fresh process.\n  const binPath = process.argv[1];\n  const spawnPath = binPath && existsSync(binPath)\n    ? binPath\n    : fileURLToPath(import.meta.url);\n  const args = process.argv.slice(2);\n\n  let child: import(\"node:child_process\").ChildProcess | null = null;\n  let stopping = false;\n  let intentional = false;\n  let respawnTimer: ReturnType<typeof setTimeout> | null = null;\n\n  const startWorker = () => {\n    intentional = false;\n    console.log(\"\\n[dev] Starting dev server...\");\n    child = spawn(process.execPath, [spawnPath, ...args], {\n      env: { ...process.env, [DEV_WORKER_ENV]: \"1\" },\n      stdio: \"inherit\",\n    });\n    child.on(\"exit\", (code) => {\n      child = null;\n      if (stopping) return;\n      if (intentional) {\n        // Restart after a source change.\n        respawnTimer = setTimeout(startWorker, 400);\n        return;\n      }\n      if (code !== 0) {\n        console.error(`[dev] Dev server exited with code ${code}; restarting...`);\n        respawnTimer = setTimeout(startWorker, 600);\n      }\n    });\n  };\n\n  const restart = () => {\n    if (!child) return;\n    intentional = true;\n    child.kill(\"SIGTERM\");\n  };\n\n  const watchedDirs = [options.appDir, options.islandsDir].filter(Boolean) as string[];\n  if (watchedDirs.length > 0) {\n    let timer: ReturnType<typeof setTimeout> | null = null;\n    const scheduleRestart = () => {\n      console.log(\"\\n[change] Restarting dev server...\");\n      if (timer) clearTimeout(timer);\n      timer = setTimeout(() => restart(), 150);\n    };\n    for (const dir of watchedDirs) {\n      try {\n        watch(dir, { recursive: true }, (event, filename) => {\n          // Editors and sed replace files via atomic rename, which reports the\n          // temporary name (e.g. \"blog/sed1234\") instead of the .ts file, so\n          // treat every rename as a potential source change. \"change\" events\n          // only restart when the reported name looks like a source file.\n          if (event === \"rename\") {\n            scheduleRestart();\n          } else if (filename && /\\.ts$/.test(filename)) {\n            scheduleRestart();\n          }\n        });\n      } catch (err) {\n        console.error(`[dev] failed to watch ${dir}:`, err);\n      }\n    }\n  }\n\n  const cleanup = () => {\n    stopping = true;\n    if (respawnTimer) clearTimeout(respawnTimer);\n    if (child) child.kill(\"SIGTERM\");\n    // Exit after the worker has gone, so a new supervisor can take over the port.\n    const deadline = setTimeout(() => process.exit(0), 3000);\n    deadline.unref();\n    if (!child) process.exit(0);\n  };\n  process.on(\"SIGINT\", cleanup);\n  process.on(\"SIGTERM\", cleanup);\n\n  startWorker();\n}\n\nexport async function doPreview(options: CliOptions): Promise<import(\"node:http\").Server> {\n  try {\n    const s = await stat(options.outDir);\n    if (!s.isDirectory()) {\n      throw new Error(`Output path is not a directory: ${options.outDir}`);\n    }\n  } catch (err) {\n    const code = (err as NodeJS.ErrnoException).code;\n    if (code === \"ENOENT\") {\n      throw new Error(\n        `No build output found at ${options.outDir}. Run \\`nix-js-kit build\\` first.`,\n      );\n    }\n    throw err;\n  }\n\n  const transformedRoot = join(options.root, \".nix-js\", \"preview-transformed\");\n  const transformedAppDir = transformedAppDirOf(options.root, options.appDir, options.islandsDir, transformedRoot);\n  await transformProjectFiles({\n    root: options.root,\n    appDir: options.appDir,\n    islandsDir: options.islandsDir,\n    outDir: transformedRoot,\n  });\n\n  const actions = await scanActions(transformedAppDir);\n  const routes = await scanRoutes(transformedAppDir);\n  const server = createServer((req, res) => handleRequest(req, res, options, actions, routes));\n  server.listen(options.port, options.host, () => {\n    console.log(`\\n  → Preview server http://${options.host}:${options.port}`);\n  });\n  return server;\n}\n\nasync function doStart(options: CliOptions): Promise<void> {\n  const transformedRoot = join(options.root, \".nix-js\", \"transformed\");\n  const transformedAppDir = transformedAppDirOf(options.root, options.appDir, options.islandsDir, transformedRoot);\n  await transformProjectFiles({\n    root: options.root,\n    appDir: options.appDir,\n    islandsDir: options.islandsDir,\n    outDir: transformedRoot,\n  });\n\n  const ssr = await createSsrServer({\n    root: options.root,\n    appDir: transformedAppDir,\n    publicDir: options.outDir,\n    clientEntry: options.clientEntry,\n    lang: options.lang,\n    port: options.port,\n    host: options.host,\n    cacheDir: options.cacheDir,\n    defaultRevalidate: options.defaultRevalidate,\n  });\n  await ssr.listen();\n}\n\nasync function findClientConfig(root: string): Promise<string | undefined> {\n  const candidates = [\"vite.client.config.ts\", \"vite.client.config.js\", \"vite.client.config.mjs\"];\n  for (const name of candidates) {\n    const path = resolve(root, name);\n    try {\n      if ((await stat(path)).isFile()) return path;\n    } catch {\n      // ignore\n    }\n  }\n  return undefined;\n}\n\nasync function buildClient(options: CliOptions): Promise<void> {\n  if (!options.clientConfig) return;\n\n  // Use the programmatic Vite build API instead of spawnSync(\"npx\", [\"vite\", ...]).\n  // This avoids child-process overhead, shares the module cache, and gives us\n  // structured errors instead of exit-code parsing.\n  const { buildClientBundle } = await import(\"./build/vite-build.js\");\n  const clientOutDir = join(options.outDir, \"_nix-js\");\n  // The client bundle is always served from /_nix-js/ regardless of the\n  // project's deployment base. The deployment base is applied to page HTML,\n  // not to the internal hydration bundle path.\n  const clientBase = \"/_nix-js/\";\n  await buildClientBundle({\n    root: options.root,\n    userConfigPath: resolve(options.clientConfig),\n    appDir: join(options.root, \"src\", \"app\"),\n    islandsDir: join(options.root, \"src\", \"islands\"),\n    outDir: clientOutDir,\n    base: clientBase,\n    logPrefix: \"[client]\",\n  });\n}\n\nasync function handleRequest(\n  req: import(\"node:http\").IncomingMessage,\n  res: import(\"node:http\").ServerResponse,\n  options: CliOptions,\n  actions: import(\"./action/scan.js\").ActionRegistry,\n  routes: import(\"./router/route-scanner.js\").ScannedRoutes,\n  noCache = false,\n): Promise<void> {\n  // Unified pipeline: actions, render endpoint, API routes, static files and\n  // dynamic SSR all run through `createWebHandler`, the same code used by the\n  // Node/Bun/Vercel/Netlify adapters. This eliminates the duplicated request\n  // handling that previously diverged between dev/preview/start and adapters\n  // (audit §8.1, Risk 1).\n  const { createWebHandler } = await import(\"./runtime/handler.js\");\n  const securityHeaders = (options.resolvedConfig as { security?: { headers?: unknown } } | undefined)?.security?.headers;\n  const webHandler = createWebHandler(\n    routes,\n    actions,\n    {\n      staticRoot: options.outDir,\n      noCache,\n      cacheDir: options.cacheDir,\n      defaultRevalidate: options.defaultRevalidate,\n      lang: options.lang,\n      clientEntry: options.clientEntry,\n      renderEndpoint: true,\n      securityHeaders: securityHeaders === undefined ? false : (securityHeaders as never),\n    },\n  );\n\n  const body = req.method && req.method !== \"GET\" && req.method !== \"HEAD\"\n    ? await readRequestBody(req)\n    : undefined;\n  const request = incomingMessageToRequest(req, body);\n  let response: Response;\n  try {\n    response = await webHandler(request);\n  } catch (err) {\n    console.error(\"[nix-js-kit] request error:\", err);\n    res.writeHead(500, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n    res.end(\"Internal Server Error\");\n    return;\n  }\n  res.writeHead(response.status, Object.fromEntries(response.headers.entries()));\n  res.end(Buffer.from(await response.arrayBuffer()));\n}\n\nfunction readRequestBody(req: import(\"node:http\").IncomingMessage): Promise<string> {\n  return new Promise((resolve, reject) => {\n    let body = \"\";\n    req.setEncoding(\"utf8\");\n    req.on(\"data\", (chunk) => {\n      body += chunk;\n    });\n    req.on(\"end\", () => resolve(body));\n    req.on(\"error\", reject);\n  });\n}\n\nasync function doAdapter(options: CliOptions): Promise<void> {\n  const adapterOptions = {\n    root: options.root,\n    appDir: options.appDir,\n    islandsDir: options.islandsDir ?? resolve(options.root, \"src/islands\"),\n    outDir: options.outDir,\n    publicDir: options.publicDir,\n    clientEntry: options.clientEntry,\n    lang: options.lang,\n    hydrateImport: options.hydrateImport,\n  };\n  const resolvedConfig = options.resolvedConfig as { images?: { strict?: boolean }; cache?: { defaultRevalidate?: number } } | undefined;\n  const features = {\n    isr: typeof resolvedConfig?.cache?.defaultRevalidate === \"number\" && resolvedConfig.cache.defaultRevalidate > 0,\n    images: resolvedConfig?.images?.strict === true,\n  };\n  let adapterName = options.adapterName;\n  if (adapterName === \"vercel\") {\n    const { vercelAdapter } = await import(\"./adapters/vercel.js\");\n    assertCapabilities(vercelAdapter, features, adapterName);\n    await vercelAdapter.build(adapterOptions);\n    console.log(\"\\n  → Vercel output generated at .vercel/output\");\n  } else if (adapterName === \"netlify\") {\n    const { netlifyAdapter } = await import(\"./adapters/netlify.js\");\n    assertCapabilities(netlifyAdapter, features, adapterName);\n    await netlifyAdapter.build(adapterOptions);\n    console.log(\"\\n  → Netlify output generated at netlify/functions/__nix-js-kit.mjs\");\n  } else if (adapterName === \"bun\") {\n    const { bunAdapter } = await import(\"./adapters/bun.js\");\n    assertCapabilities(bunAdapter, features, adapterName);\n    await bunAdapter.build(adapterOptions);\n    console.log(\"\\n  → Bun server generated at .nix-js/bun-server.ts\");\n  } else if (adapterName === \"node\") {\n    const { nodeAdapter } = await import(\"./adapters/node.js\");\n    assertCapabilities(nodeAdapter, features, adapterName);\n    await nodeAdapter.build(adapterOptions);\n    console.log(\"\\n  → Node server generated at .nix-js/node-server.mjs\");\n  }\n}\n\nfunction assertCapabilities(\n  adapter: { capabilities?: import(\"./runtime/capabilities.js\").AdapterCapabilities },\n  features: { isr: boolean; images: boolean },\n  adapterName: string,\n): void {\n  if (!adapter.capabilities) return;\n  const diagnostics = validateCapabilities(adapter.capabilities, features);\n  if (!diagnostics.ok) {\n    throw new Error(\n      `[nix-js-kit] Adapter \"${adapterName}\" cannot satisfy the requested features:\\n  - ${diagnostics.problems.join(\"\\n  - \")}`,\n    );\n  }\n}\n\nasync function applyProjectConfig(options: CliOptions, argv: string[]): Promise<void> {\n  // Map non-build commands to \"build\" or \"serve\" for config resolution.\n  const command = (options.command === \"adapter\" || options.command === \"routes\" || options.command === \"doctor\")\n    ? \"build\"\n    : options.command;\n  const config = await loadNixConfig({\n    root: options.root,\n    configFile: options.configFile,\n    command,\n  });\n  const args = argv.slice(2);\n  const has = (...names: string[]) => names.some((name) => args.includes(name));\n  options.root = config.root;\n  if (!has(\"--app\", \"-a\")) options.appDir = config.appDir;\n  if (!has(\"--islands\", \"-i\")) options.islandsDir = config.islandsDir;\n  if (!has(\"--out\", \"-o\")) options.outDir = config.outDir;\n  if (!has(\"--public\")) options.publicDir = config.publicDir;\n  if (!has(\"--cache-dir\")) options.cacheDir = config.cache.dir;\n  if (!has(\"--default-revalidate\")) options.defaultRevalidate = config.cache.defaultRevalidate;\n  options.generatedEntry = resolve(config.root, \".nix-js/entry-client.ts\");\n  options.resolvedConfig = config;\n}\n\nexport async function run(argv: string[]): Promise<void> {\n  const options = parseArgs(argv);\n\n  // Commands that don't need project config resolution.\n  if (options.command === \"doctor\") {\n    const { doDoctor } = await import(\"./cli/commands.js\");\n    const code = await doDoctor(options);\n    process.exit(code);\n  }\n\n  await applyProjectConfig(options, argv);\n\n  if (options.command === \"build\") {\n    await doBuild(options);\n  } else if (options.command === \"preview\") {\n    await doPreview(options);\n  } else if (options.command === \"start\") {\n    await doStart(options);\n  } else if (options.command === \"adapter\") {\n    await doAdapter(options);\n  } else if (options.command === \"check\") {\n    const { doCheck } = await import(\"./cli/commands.js\");\n    const code = await doCheck(options);\n    process.exit(code);\n  } else if (options.command === \"routes\") {\n    const { doRoutes } = await import(\"./cli/commands.js\");\n    const code = await doRoutes(options);\n    process.exit(code);\n  } else if (process.env[DEV_WORKER_ENV] === \"1\") {\n    await doDev(options);\n  } else {\n    await doDevSupervisor(options);\n  }\n}\n"],"mappings":"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"}