@zitadel/cli 0.1.0-alpha.8 → 1.0.0-alpha.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +250 -62
  2. package/SKILLS.md +227 -38
  3. package/dist/branding-cygSBPkV.mjs +79 -0
  4. package/dist/branding-cygSBPkV.mjs.map +1 -0
  5. package/dist/claim-state-DlfD6Res.mjs +66 -0
  6. package/dist/claim-state-DlfD6Res.mjs.map +1 -0
  7. package/dist/commands/apply.mjs +27 -8
  8. package/dist/commands/apply.mjs.map +1 -1
  9. package/dist/commands/branding/eject.mjs +104 -0
  10. package/dist/commands/branding/eject.mjs.map +1 -0
  11. package/dist/commands/claim.mjs +402 -0
  12. package/dist/commands/claim.mjs.map +1 -0
  13. package/dist/commands/doctor.mjs +687 -55
  14. package/dist/commands/doctor.mjs.map +1 -1
  15. package/dist/commands/eject.mjs +18 -6
  16. package/dist/commands/eject.mjs.map +1 -1
  17. package/dist/commands/logs.mjs +2 -2
  18. package/dist/commands/plan.mjs +19 -6
  19. package/dist/commands/plan.mjs.map +1 -1
  20. package/dist/commands/reset.mjs +12 -4
  21. package/dist/commands/reset.mjs.map +1 -1
  22. package/dist/commands/schemas/list.mjs +146 -0
  23. package/dist/commands/schemas/list.mjs.map +1 -0
  24. package/dist/commands/setup.mjs +642 -287
  25. package/dist/commands/setup.mjs.map +1 -1
  26. package/dist/commands/start.mjs +73 -6
  27. package/dist/commands/start.mjs.map +1 -1
  28. package/dist/commands/status.mjs +52 -13
  29. package/dist/commands/status.mjs.map +1 -1
  30. package/dist/commands/stop.mjs +59 -6
  31. package/dist/commands/stop.mjs.map +1 -1
  32. package/dist/designs-Ckz18Dpo.mjs +38 -0
  33. package/dist/designs-Ckz18Dpo.mjs.map +1 -0
  34. package/dist/{docker-BA78SdC2.mjs → docker-DcRGTOJa.mjs} +61 -11
  35. package/dist/docker-DcRGTOJa.mjs.map +1 -0
  36. package/dist/environment-rjRVkJjW.mjs +17 -0
  37. package/dist/environment-rjRVkJjW.mjs.map +1 -0
  38. package/dist/journey-guidance-BGrOX_gT.mjs +40 -0
  39. package/dist/journey-guidance-BGrOX_gT.mjs.map +1 -0
  40. package/dist/oclif-CanO3zdt.mjs +1769 -0
  41. package/dist/oclif-CanO3zdt.mjs.map +1 -0
  42. package/dist/{orca-CfKDQRop.mjs → orca-BzQIQqzt.mjs} +1663 -303
  43. package/dist/orca-BzQIQqzt.mjs.map +1 -0
  44. package/dist/package-manager-DFdLcDx1.mjs +194 -0
  45. package/dist/package-manager-DFdLcDx1.mjs.map +1 -0
  46. package/dist/ports-BM20XIZb.mjs +116 -0
  47. package/dist/ports-BM20XIZb.mjs.map +1 -0
  48. package/dist/processes-DKHPkU8O.mjs +120 -0
  49. package/dist/processes-DKHPkU8O.mjs.map +1 -0
  50. package/dist/{project-CKAHtHML.mjs → project-CHhot85s.mjs} +57 -4
  51. package/dist/project-CHhot85s.mjs.map +1 -0
  52. package/dist/sync-BBlACKzT.mjs +1633 -0
  53. package/dist/sync-BBlACKzT.mjs.map +1 -0
  54. package/dist/user-schema-DTuOsdKE.mjs +91 -0
  55. package/dist/user-schema-DTuOsdKE.mjs.map +1 -0
  56. package/oclif.manifest.json +412 -5
  57. package/package.json +10 -5
  58. package/dist/docker-BA78SdC2.mjs.map +0 -1
  59. package/dist/docker-guidance-BvfpmsDj.mjs +0 -21
  60. package/dist/docker-guidance-BvfpmsDj.mjs.map +0 -1
  61. package/dist/oclif-VkCTGIEk.mjs +0 -818
  62. package/dist/oclif-VkCTGIEk.mjs.map +0 -1
  63. package/dist/orca-CfKDQRop.mjs.map +0 -1
  64. package/dist/project-CKAHtHML.mjs.map +0 -1
  65. package/dist/sync-B5lqgQO3.mjs +0 -733
  66. package/dist/sync-B5lqgQO3.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orca-BzQIQqzt.mjs","names":["dirExists","SDK_DEPENDENCY","SDK_DEPENDENCY","appTemplate","SDK_DEPENDENCY","appTemplate","appTemplate","SDK_DEPENDENCY","appTemplate","appTemplate","SDK_DEPENDENCY","appTemplate","appTemplate","SDK_DEPENDENCY","appTemplate"],"sources":["../src/lib/orca/detectors/package-json.ts","../src/lib/orca/detectors/port.ts","../src/lib/orca/detectors/angular.ts","../src/lib/orca/detectors/next.ts","../src/lib/orca/detectors/nuxt.ts","../src/lib/orca/detectors/qwik.ts","../src/lib/orca/detectors/react.ts","../src/lib/orca/detectors/solid.ts","../src/lib/orca/detectors/svelte.ts","../src/lib/orca/detectors/vue.ts","../src/lib/orca/detectors/index.ts","../src/lib/orca/patchers/rule/file-writer/index.ts","../src/lib/orca/patchers/rule/guidance.ts","../src/lib/orca/patchers/rule/reclaim.ts","../src/lib/orca/patchers/rule/base.ts","../src/lib/orca/patchers/rule/angular/angular-json.ts","../src/lib/orca/patchers/rule/utils/magicast.ts","../src/lib/orca/patchers/rule/angular/angular-routes.ts","../src/lib/orca/patchers/rule/proxy.ts","../src/lib/orca/patchers/rule/proxy-credential-policy.ts","../src/lib/orca/patchers/rule/angular/templates.ts","../src/lib/orca/patchers/rule/angular/index.ts","../src/lib/orca/patchers/rule/dev-script-port.ts","../src/lib/orca/patchers/rule/next/renderers/lit/index.ts","../src/lib/orca/patchers/rule/next/renderers/react/index.ts","../src/lib/orca/patchers/rule/next/renderers/registry.ts","../src/lib/orca/patchers/rule/next/index.ts","../src/lib/orca/patchers/rule/config-paths.ts","../src/lib/orca/patchers/rule/nuxt/nuxt-config.ts","../src/lib/orca/patchers/rule/nuxt/templates.ts","../src/lib/orca/patchers/rule/nuxt/index.ts","../src/lib/orca/patchers/rule/vite-support.ts","../src/lib/orca/patchers/rule/qwik/templates.ts","../src/lib/orca/patchers/rule/qwik/index.ts","../src/lib/orca/patchers/rule/react/templates.ts","../src/lib/orca/patchers/rule/react/index.ts","../src/lib/orca/patchers/rule/solid/templates.ts","../src/lib/orca/patchers/rule/solid/index.ts","../src/lib/orca/patchers/rule/svelte/templates.ts","../src/lib/orca/patchers/rule/svelte/index.ts","../src/lib/orca/patchers/rule/vue/templates.ts","../src/lib/orca/patchers/rule/vue/index.ts","../src/lib/orca/patchers/index.ts","../src/lib/orca/scaffolders/cli.ts","../src/lib/orca/scaffolders/angular.ts","../src/lib/orca/scaffolders/next.ts","../src/lib/orca/scaffolders/nuxt.ts","../src/lib/orca/scaffolders/qwik.ts","../src/lib/orca/scaffolders/react.ts","../src/lib/orca/scaffolders/solid.ts","../src/lib/orca/scaffolders/svelte.ts","../src/lib/orca/scaffolders/vue.ts","../src/lib/orca/scaffolders/index.ts","../src/lib/orca/index.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport semver from \"semver\";\n\n/**\n * Minimal shape of the `package.json` fields detectors read. Intentionally\n * partial: only the keys detection logic depends on are modeled, all optional\n * since a project may omit any of them.\n */\nexport type PackageJson = {\n name?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n};\n\n/**\n * Reads and parses the `package.json` at `cwd`. Rejects if the file is absent\n * or malformed; callers that treat those as \"not a project\" are expected to\n * catch and fall back rather than have detection swallow the error here.\n */\nexport async function readPackageJson(cwd: string): Promise<PackageJson> {\n const contents = await readFile(join(cwd, \"package.json\"), \"utf8\");\n return JSON.parse(contents) as PackageJson;\n}\n\n/**\n * Reports whether `name` appears in either `dependencies` or `devDependencies`.\n * Both are checked because framework packages may legitimately live in either.\n */\nexport function hasDependency(pkg: PackageJson, name: string): boolean {\n return Boolean(pkg.dependencies?.[name] ?? pkg.devDependencies?.[name]);\n}\n\n/**\n * Best-effort major version of a declared dependency: the first number in the\n * spec. A heuristic for scaffold decisions (e.g. which Next request-boundary\n * convention to emit), NOT for support gating — range semantics like `<16`\n * are beyond it. Floors use {@link dependencySpecProvablyBelowMajor}.\n */\nexport function dependencyVersionMajor(pkg: PackageJson, name: string): number | undefined {\n const spec = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name];\n if (!spec) {\n return undefined;\n }\n const match = spec.match(/\\d+/);\n return match ? Number(match[0]) : undefined;\n}\n\n/**\n * Returns the declared spec for `name` when that spec provably cannot resolve\n * to `floorMajor` or newer: a valid semver range with no overlap with\n * `>=floorMajor.0.0-0`. Everything unprovable returns `undefined` — protocol\n * specs (`file:`, `link:`, `workspace:`, git URLs), dist-tags (`latest`,\n * `canary`), absent deps, and ranges that also admit a compliant version\n * (`>=14`, `14 || 16`). The floor comparator includes prereleases so a\n * `15.0.0-rc` user is not rejected by the 15 floor.\n */\nexport function dependencySpecProvablyBelowMajor(\n pkg: PackageJson,\n name: string,\n floorMajor: number,\n): string | undefined {\n const spec = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name];\n if (!spec || semver.validRange(spec) === null) {\n return undefined;\n }\n const atOrAboveFloor = `>=${String(floorMajor)}.0.0-0`;\n return semver.intersects(spec, atOrAboveFloor, { includePrerelease: true }) ? undefined : spec;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport type { PackageJson } from \"./package-json\";\n\n/**\n * Port assumed when no explicit dev port can be discovered. Matches Next.js's\n * own default so the inferred issuer URL lines up with `next dev`.\n */\nexport const DEFAULT_DEV_PORT = 3000;\n\n/**\n * Determines the local dev-server port for `cwd`. The `dev` script is the most\n * authoritative source, then a `PORT` declaration in an env file, falling back\n * to {@link DEFAULT_DEV_PORT}. Used to derive the local issuer URL.\n */\nexport async function detectDevPort(cwd: string, pkg: PackageJson): Promise<number> {\n const dev = pkg.scripts?.dev;\n const fromScript = typeof dev === \"string\" ? extractPort(dev) : undefined;\n if (fromScript) {\n return fromScript;\n }\n\n const fromEnvFile = await portFromEnvFile(cwd);\n if (fromEnvFile) {\n return fromEnvFile;\n }\n\n return DEFAULT_DEV_PORT;\n}\n\nasync function portFromEnvFile(cwd: string): Promise<number | undefined> {\n for (const candidate of [\".env.local\", \".env\"]) {\n try {\n const contents = await readFile(join(cwd, candidate), \"utf8\");\n const match = contents.match(/^\\s*PORT\\s*=\\s*(\\d+)/m);\n const rawPort = match?.[1];\n if (rawPort) {\n return Number.parseInt(rawPort, 10);\n }\n } catch {\n continue;\n }\n }\n return undefined;\n}\n\n/**\n * Parses a dev port out of an npm `dev` script string, recognizing both flag\n * forms (`-p`/`--port`) and a leading `PORT=` env assignment. Returns\n * `undefined` when no valid positive port is present so callers can fall back.\n */\nexport function extractPort(script: string): number | undefined {\n const inline = script.match(/-p\\s+(\\d+)|--port[=\\s]+(\\d+)/);\n if (inline) {\n const raw = inline[1] ?? inline[2];\n if (!raw) {\n return undefined;\n }\n const value = Number.parseInt(raw, 10);\n if (Number.isFinite(value) && value > 0) {\n return value;\n }\n }\n const env = script.match(/(?:^|\\s)PORT=(\\d+)/);\n const rawEnvPort = env?.[1];\n if (rawEnvPort) {\n return Number.parseInt(rawEnvPort, 10);\n }\n return undefined;\n}\n\n/**\n * Rewrites a `dev` script so it explicitly runs on `port`.\n *\n * Setup registers `http://localhost:<port>` as the project's only allowed\n * origin, so the dev server has to land on exactly that port — a bare\n * `next dev` does not: it defaults to 3000 and, when 3000 is taken, silently\n * falls back to 3001. Either way the flow API then rejects the app's origin\n * mid-login. An explicit `--port` removes both failure modes: the port\n * matches what setup registered, and a busy port fails loudly with\n * `EADDRINUSE` instead of drifting to one the project does not allow.\n *\n * `--port <n>` is the one spelling every framework this CLI scaffolds\n * accepts (`next dev`, `nuxt dev`, `vite`, `vinxi dev`, `ng serve`), so an\n * appended declaration stays framework-agnostic. An existing declaration is\n * rewritten in its own form instead — a `PORT=` env assignment keeps the\n * `PORT=` form — so the script keeps whichever mechanism its author chose and\n * only the number changes.\n */\nexport function withDevPort(script: string, port: number): string {\n // Test for a declaration rather than comparing before/after: a script that\n // already names the target port rewrites to itself, and treating that\n // \"unchanged\" as \"no port found\" would append a second, duplicate flag on\n // every re-run of setup.\n const flagPattern = /(-p\\s+|--port[=\\s]+)\\d+/;\n if (flagPattern.test(script)) {\n return script.replace(flagPattern, (_match, prefix: string) => `${prefix}${String(port)}`);\n }\n const envPattern = /((?:^|\\s)PORT=)\\d+/;\n if (envPattern.test(script)) {\n return script.replace(envPattern, (_match, prefix: string) => `${prefix}${String(port)}`);\n }\n return `${script.trimEnd()} --port ${String(port)}`;\n}\n\n/**\n * Builds the local OIDC issuer URL for a given dev port. Centralized so the\n * `localhost` origin convention is defined in exactly one place.\n */\nexport function issuerFromPort(port: number): string {\n return `http://localhost:${port}`;\n}\n\n/**\n * The port an issuer URL names, or `undefined` when it names none.\n *\n * The inverse of {@link issuerFromPort}, and the authoritative way to learn\n * which port a project *registered* — as opposed to {@link detectDevPort},\n * which reports the port the app would start on right now. The two agree\n * during setup and diverge afterwards, which is exactly when it matters: a\n * dev script edited to another port must be read as a mismatch against the\n * registered origin, not as the new truth.\n */\nexport function portFromIssuer(issuer: string): number | undefined {\n try {\n // Validity gate only. `.port` cannot be read off this: WHATWG drops a\n // port matching the scheme's default, so `http://localhost:80` — a port\n // `--dev-port` accepts — would come back portless and silently disable\n // the dev-script pinning, reintroducing the very mismatch it prevents.\n new URL(issuer);\n } catch {\n return undefined;\n }\n // Re-parse under a scheme the URL standard treats as non-special. Those\n // have no default port, so an explicitly written 80/443 survives, while\n // host parsing (IPv6 brackets, userinfo) stays the standard's job.\n let probe: URL;\n try {\n probe = new URL(issuer.replace(/^[a-zA-Z][a-zA-Z0-9+.-]*:/, \"zl-issuer-probe:\"));\n } catch {\n return undefined;\n }\n const port = Number.parseInt(probe.port, 10);\n return Number.isFinite(port) && port > 0 ? port : undefined;\n}\n","import { ZitadelError } from \"../../errors\";\nimport { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/** The lowest Angular major the generated templates compile on. */\nconst MIN_ANGULAR_MAJOR = 17;\n\n/** Best-effort major version from a dependency range (`^17.3.0` → 17). */\nfunction angularMajor(spec: string): number | undefined {\n const match = spec.match(/\\d+/);\n return match ? Number.parseInt(match[0], 10) : undefined;\n}\n\n/**\n * Detects an Angular project by its `@angular/core` dependency. The app dir is\n * `src/app` (where the patcher writes `app.ts`/`app.html`), the dev port comes\n * from the project (else the default), and the issuer is derived from it.\n * Angular's dev server (`@angular/build:dev-server`)\n * is Vite-based but configured via `angular.json` + a `proxy.conf.cjs`, not a\n * `vite.config.ts` — handled by the Angular patcher.\n *\n * The managed templates use Angular 17+ control flow (`@if`), so a clearly\n * older project fails fast with `E_VALIDATION` instead of scaffolding files\n * that won't compile.\n */\nexport class AngularDetector implements Detector {\n readonly framework = \"angular\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, \"@angular/core\")) {\n return null;\n }\n\n const spec = pkg.dependencies?.[\"@angular/core\"] ?? pkg.devDependencies?.[\"@angular/core\"];\n const major = spec ? angularMajor(spec) : undefined;\n if (major !== undefined && major < MIN_ANGULAR_MAJOR) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Angular ${major} is unsupported — the generated auth templates use Angular ${MIN_ANGULAR_MAJOR}+ control flow (@if).`,\n {\n hint: `Upgrade to Angular ${MIN_ANGULAR_MAJOR} or newer before running setup, or add the Zitadel components to your templates manually.`,\n },\n );\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"angular\", appDir: \"src/app\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ZitadelError } from \"../../errors\";\nimport {\n dependencySpecProvablyBelowMajor,\n dependencyVersionMajor,\n hasDependency,\n readPackageJson,\n} from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Next.js App Router project and extracts its facts: the App Router\n * directory (`app` vs `src/app`), the dev-server port (parsed from the `dev`\n * script / env file, else 3000), and the derived local issuer URL. Owns every\n * Next-specific assumption so the orchestrator and commands stay generic.\n */\nexport class NextDetector implements Detector {\n readonly framework = \"next\";\n\n /**\n * Returns `null` when `cwd` is not a Next.js project (no `next` dependency),\n * so the orchestrator can try other detectors. Throws\n * `E_UNSUPPORTED_PROJECT_SHAPE` when it is Next.js but lacks an App Router\n * directory (e.g. a Pages Router project), which is a hard error rather than\n * an empty directory to scaffold.\n */\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, \"next\")) {\n return null;\n }\n\n // Supported floor (ADR 043): the scaffolded templates target Next 15+\n // (current App Router and request-boundary conventions). The floor is\n // enforced here so setup and doctor share one loud gate instead of\n // degrading silently; only a spec that provably cannot resolve to 15+\n // is rejected — protocol specs and dist-tags pass.\n const belowFloor = dependencySpecProvablyBelowMajor(pkg, \"next\", 15);\n if (belowFloor !== undefined) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n `Next.js \"${belowFloor}\" is below the supported floor — the CLI integrates Next.js 15 and newer`,\n { hint: \"Upgrade the app to Next 15+ (e.g. `npx @next/codemod@latest upgrade`) and rerun.\" },\n );\n }\n\n const appDir = (await dirExists(join(cwd, \"app\")))\n ? \"app\"\n : (await dirExists(join(cwd, \"src/app\")))\n ? \"src/app\"\n : undefined;\n if (!appDir) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n \"Next.js Pages Router projects are not supported in v1\",\n { hint: \"Create an App Router project with an app/ or src/app/ directory.\" },\n );\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n const versionMajor = dependencyVersionMajor(pkg, \"next\");\n return {\n id: \"next\",\n appDir,\n devPort,\n url: issuerFromPort(devPort),\n ...(versionMajor === undefined ? {} : { versionMajor }),\n };\n }\n}\n\nasync function dirExists(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isDirectory();\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: string }).code === \"ENOENT\"\n ) {\n return false;\n }\n throw error;\n }\n}\n","import { stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Nuxt project by its `nuxt` dependency. Like Next.js, Nuxt proxies\n * the auth backend through server middleware (`@zitadel/sdk-nuxt`), not a Vite\n * dev-server proxy — so the patcher wires the module + a `nuxt.config.ts` edit.\n * Runs before the Vue detector (which excludes Nuxt) since Nuxt ships Vue.\n *\n * `appDir` tracks the Nuxt srcDir: Nuxt 4 (what `nuxi init` now scaffolds) keeps\n * `app.vue`/`pages/`/`plugins/` under `app/`, while Nuxt 3 keeps them at the\n * root — so the patcher writes its files relative to whichever this project uses.\n */\nexport class NuxtDetector implements Detector {\n readonly framework = \"nuxt\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, \"nuxt\")) {\n return null;\n }\n\n const appDir = (await dirExists(join(cwd, \"app\"))) ? \"app\" : \".\";\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"nuxt\", appDir, devPort, url: issuerFromPort(devPort) };\n }\n}\n\nasync function dirExists(path: string): Promise<boolean> {\n return stat(path).then(\n (s) => s.isDirectory(),\n () => false,\n );\n}\n","import { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Vite + Qwik single-page app: depends on `@builder.io/qwik` and\n * `vite` but NOT `@builder.io/qwik-city` (Qwik City is its own meta-framework\n * and ships Qwik). The source dir is `src`, the dev port comes from the\n * project, and the issuer is derived from it.\n */\nexport class QwikDetector implements Detector {\n readonly framework = \"qwik\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"@builder.io/qwik-city\") ||\n !hasDependency(pkg, \"@builder.io/qwik\") ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"qwik\", appDir: \"src\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { ZitadelError } from \"../../errors\";\nimport {\n dependencySpecProvablyBelowMajor,\n dependencyVersionMajor,\n hasDependency,\n readPackageJson,\n} from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Vite + React single-page app and extracts its facts: the source\n * directory (`src`), the dev-server port (parsed from the `dev` script / env\n * file, else the framework default), and the derived local issuer URL.\n *\n * Recognises a project that depends on both `react` and `vite` but NOT `next`\n * — Next.js ships React too, so the {@link import(\"./next\").NextDetector} must\n * run first (and does, by registry order) and this detector excludes it.\n */\nexport class ReactDetector implements Detector {\n readonly framework = \"react\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"next\") ||\n !hasDependency(pkg, \"react\") ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n // Supported floor (ADR 043): the SDK wrappers and scaffolded templates\n // target React 18+. Enforced here so setup and doctor share one loud\n // gate; only a spec that provably cannot resolve to 18+ is rejected —\n // protocol specs and dist-tags pass.\n const belowFloor = dependencySpecProvablyBelowMajor(pkg, \"react\", 18);\n if (belowFloor !== undefined) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n `React \"${belowFloor}\" is below the supported floor — the CLI integrates React 18 and newer`,\n { hint: \"Upgrade the app to React 18+ and rerun.\" },\n );\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n const versionMajor = dependencyVersionMajor(pkg, \"react\");\n return {\n id: \"react\",\n appDir: \"src\",\n devPort,\n url: issuerFromPort(devPort),\n ...(versionMajor === undefined ? {} : { versionMajor }),\n };\n }\n}\n","import { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Vite + Solid single-page app: depends on `solid-js` and `vite` but\n * NOT `@solidjs/start` (SolidStart is its own meta-framework and ships Solid).\n * The source dir is `src`, the dev port comes from the project, and the issuer\n * is derived from it.\n */\nexport class SolidDetector implements Detector {\n readonly framework = \"solid\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"@solidjs/start\") ||\n !hasDependency(pkg, \"solid-js\") ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"solid\", appDir: \"src\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Vite + Svelte single-page app: depends on `svelte` and `vite` but\n * NOT `@sveltejs/kit` (SvelteKit is its own meta-framework and ships Svelte).\n * The source dir is `src`, the dev port comes from the project, and the issuer\n * is derived from it.\n */\nexport class SvelteDetector implements Detector {\n readonly framework = \"svelte\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"@sveltejs/kit\") ||\n !hasDependency(pkg, \"svelte\") ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"svelte\", appDir: \"src\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Vite + Vue single-page app: depends on `vue` and `vite` but NOT\n * `nuxt` (Nuxt is its own meta-framework and ships Vue) — so the source dir is\n * `src`, the dev port comes from the project, and the issuer is derived from it.\n */\nexport class VueDetector implements Detector {\n readonly framework = \"vue\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"nuxt\") ||\n !hasDependency(pkg, \"vue\") ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"vue\", appDir: \"src\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { AngularDetector } from \"./angular\";\nimport { NextDetector } from \"./next\";\nimport { NuxtDetector } from \"./nuxt\";\nimport { QwikDetector } from \"./qwik\";\nimport { ReactDetector } from \"./react\";\nimport { SolidDetector } from \"./solid\";\nimport { SvelteDetector } from \"./svelte\";\nimport { VueDetector } from \"./vue\";\nimport type { Detector } from \"./types\";\n\n/**\n * Active detectors, in probe order. The orchestrator tries each until one\n * recognises the project. Add a framework by appending its detector here — no\n * orchestrator changes needed. Meta-frameworks run before their base: Next\n * before React (Next ships React), and the Vue detector excludes Nuxt — so a\n * Next/Nuxt project is never mistaken for a bare React/Vue SPA.\n */\nexport const detectors = [\n new NextDetector(),\n new NuxtDetector(),\n new ReactDetector(),\n new VueDetector(),\n new SolidDetector(),\n new SvelteDetector(),\n new QwikDetector(),\n new AngularDetector(),\n] as const satisfies ReadonlyArray<Detector>;\n","import { chmod, mkdir, readFile, rename, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { ZitadelError } from \"../../../../errors\";\nimport {\n isObject,\n parseJsonObject,\n setTopLevelJsonKey,\n stableStringify,\n} from \"../../../../json\";\nimport type { PatchedFile } from \"../../types\";\nimport type { FileOp, ScaffoldPlan, ScaffoldResult } from \"./types\";\n\n/**\n * The executor's private, mutable accumulator. Handlers record each touched\n * artifact as a typed row; {@link scaffold} derives the readonly\n * {@link ScaffoldResult} from it so the public result stays immutable.\n */\ntype ScaffoldAccumulator = {\n dryRun: boolean;\n files: PatchedFile[];\n filesSkipped: string[];\n depsAdded: string[];\n};\n\n/**\n * Records one touched artifact, deduplicating by path: several plan ops can\n * legitimately hit the same file (the base and framework op lists both merge\n * into `.env.local`, for example), but the report should carry it once, with\n * the first action as the net one — a file created and then extended in the\n * same run was created by the run.\n */\nfunction record(\n result: ScaffoldAccumulator,\n path: string,\n kind: PatchedFile[\"kind\"],\n action: PatchedFile[\"action\"],\n): void {\n if (result.files.some((file) => file.path === path)) {\n return;\n }\n result.files.push({ path, kind, action });\n}\n\n/**\n * Applies a {@link ScaffoldPlan} to disk, executing its operations in order.\n *\n * Operations are idempotent: writes whose target already matches the desired\n * contents are recorded as skipped rather than rewritten, so re-running setup\n * is safe. With `dryRun` no filesystem changes are made but the result still\n * reflects what would have been written. Existing files are only overwritten\n * when `force` is set; otherwise an `E_CONFLICT` is thrown to protect\n * user-authored content. Paths in the plan are resolved relative to `cwd`.\n */\nexport async function scaffold(\n plan: ScaffoldPlan,\n opts: { cwd: string; dryRun: boolean; force: boolean },\n): Promise<ScaffoldResult> {\n const result: ScaffoldAccumulator = {\n dryRun: opts.dryRun,\n files: [],\n filesSkipped: [],\n depsAdded: [],\n };\n\n for (const op of plan.ops) {\n await applyOp(op, opts, result);\n }\n\n const written = new Set(result.files.map((file) => file.path));\n return {\n dryRun: result.dryRun,\n files: result.files,\n // Legacy flat list: deduplicated file paths only. Directories stay in\n // `files` rows (kind \"dir\"); a path both written and later skipped as\n // already-matching reports as written.\n filesWritten: result.files.filter((file) => file.kind === \"file\").map((file) => file.path),\n filesSkipped: [...new Set(result.filesSkipped)].filter((path) => !written.has(path)),\n depsAdded: result.depsAdded,\n };\n}\n\nasync function applyOp(\n op: FileOp,\n opts: { cwd: string; dryRun: boolean; force: boolean },\n result: ScaffoldAccumulator,\n): Promise<void> {\n switch (op.kind) {\n case \"mkdir\":\n await ensureDir(abs(opts.cwd, op.path), op.mode, opts.dryRun, result);\n break;\n case \"write\":\n await writeText(\n abs(opts.cwd, op.path),\n op.contents,\n { mode: op.mode, force: opts.force, dryRun: opts.dryRun },\n result,\n );\n break;\n case \"append\":\n await appendText(abs(opts.cwd, op.path), op.contents, op.ifMissing, opts.dryRun, result);\n break;\n case \"merge-env\":\n await mergeEnv(abs(opts.cwd, op.path), op.entries, opts.dryRun, result);\n break;\n case \"merge-json\":\n await mergeJson(abs(opts.cwd, op.path), op.patch, opts.dryRun, result);\n break;\n case \"append-gitignore\":\n await appendGitignore(abs(opts.cwd, \".gitignore\"), op.entries, opts.dryRun, result);\n break;\n case \"add-dep\":\n await addDependency(abs(opts.cwd, \"package.json\"), op, opts.dryRun, result);\n break;\n case \"edit\":\n await editFile(opts.cwd, op.path, op.edit, opts.dryRun, result);\n break;\n }\n}\n\n/**\n * Generic content edit: read the file, run the patcher-supplied transform, write\n * the result. Framework knowledge lives entirely in `edit` (next to its\n * patcher); this executor only owns candidate resolution, idempotency, dry-run,\n * and the atomic write. `pathOrPaths` may be a single path or a priority list of\n * candidates — the first that exists wins, else the first candidate.\n */\nasync function editFile(\n cwd: string,\n pathOrPaths: string | ReadonlyArray<string>,\n edit: (source: string | undefined) => string,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const candidates = (typeof pathOrPaths === \"string\" ? [pathOrPaths] : pathOrPaths).map((p) =>\n abs(cwd, p),\n );\n if (candidates.length === 0) {\n throw new ZitadelError(\"E_VALIDATION\", \"An edit op needs at least one candidate path\", {\n hint: \"This is an internal patcher error — please report it if you hit it.\",\n });\n }\n let path = candidates[0];\n let source: string | undefined;\n let mode: number | undefined;\n for (const candidate of candidates) {\n const contents = await readIfExists(candidate);\n if (contents !== undefined) {\n path = candidate;\n source = contents;\n // Preserve the existing file's permission bits across the temp-file swap\n // (mask off the file-type bits `stat` includes so `chmod` gets only perms).\n mode = (await stat(candidate)).mode & 0o777;\n break;\n }\n }\n const next = edit(source);\n if (next === source) {\n result.filesSkipped.push(path);\n return;\n }\n const action = source === undefined ? \"create\" : \"update\";\n if (dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n await mkdir(dirname(path), { recursive: true });\n const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;\n await writeFile(tmp, next);\n if (mode !== undefined) {\n await chmod(tmp, mode).catch(() => undefined);\n }\n await rename(tmp, path);\n record(result, path, \"file\", action);\n}\n\nasync function ensureDir(\n path: string,\n mode: number | undefined,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n // An already-existing directory is a skip — unless its permissions drifted\n // from the requested mode, in which case the chmod below repairs them and\n // the report says so (an \"update\" row, not a silent skip). Windows does not\n // implement POSIX permission classes (only the write bit is changeable), so\n // there the mode comparison is meaningless and healing is never reported —\n // otherwise every rerun would flag `.zitadel` as an update forever.\n const pre = await stat(path).catch(() => undefined);\n const existed = pre?.isDirectory() ?? false;\n const healsMode =\n existed &&\n mode !== undefined &&\n process.platform !== \"win32\" &&\n (pre!.mode & 0o777) !== mode;\n if (dryRun) {\n if (!existed) {\n record(result, path, \"dir\", \"create\");\n } else if (healsMode) {\n record(result, path, \"dir\", \"update\");\n } else {\n result.filesSkipped.push(path);\n }\n return;\n }\n await mkdir(path, { recursive: true, mode });\n if (mode) {\n await chmod(path, mode).catch(() => undefined);\n }\n if (!existed) {\n record(result, path, \"dir\", \"create\");\n } else if (healsMode) {\n record(result, path, \"dir\", \"update\");\n } else {\n result.filesSkipped.push(path);\n }\n}\n\nasync function writeText(\n path: string,\n contents: string,\n opts: { mode?: number; force: boolean; dryRun: boolean },\n result: ScaffoldAccumulator,\n): Promise<void> {\n const existing = await readIfExists(path);\n if (existing === contents) {\n result.filesSkipped.push(path);\n return;\n }\n\n if (existing !== undefined && !opts.force) {\n throw new ZitadelError(\"E_CONFLICT\", `Refusing to overwrite ${path}`, {\n hint: \"Re-run with --force if you want the CLI to replace this file.\",\n details: { path },\n });\n }\n\n const action = existing === undefined ? \"create\" : \"update\";\n if (opts.dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n\n await mkdir(dirname(path), { recursive: true });\n const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;\n await writeFile(tmp, contents, { mode: opts.mode });\n if (opts.mode) {\n await chmod(tmp, opts.mode).catch(() => undefined);\n }\n await rename(tmp, path);\n record(result, path, \"file\", action);\n}\n\nasync function appendText(\n path: string,\n contents: string,\n ifMissing: string | undefined,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const raw = await readIfExists(path);\n const existing = raw ?? \"\";\n if (ifMissing && existing.includes(ifMissing)) {\n result.filesSkipped.push(path);\n return;\n }\n\n const next = `${existing}${existing && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\"}${contents}`;\n if (next === existing) {\n result.filesSkipped.push(path);\n return;\n }\n\n const action = raw === undefined ? \"create\" : \"update\";\n if (dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, next);\n record(result, path, \"file\", action);\n}\n\nasync function mergeEnv(\n path: string,\n entries: Readonly<Record<string, string>>,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const raw = await readIfExists(path);\n const existing = raw ?? \"\";\n const present = new Set(\n existing\n .split(/\\r?\\n/g)\n .map((line) => line.match(/^\\s*([A-Za-z_][A-Za-z0-9_]*)=/)?.[1])\n .filter((value): value is string => Boolean(value)),\n );\n const additions = Object.entries(entries).filter(([key]) => !present.has(key));\n if (additions.length === 0) {\n result.filesSkipped.push(path);\n return;\n }\n\n const block = additions.map(([key, value]) => `${key}=${value}`).join(\"\\n\");\n const next = `${existing}${existing && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\"}${block}\\n`;\n const action = raw === undefined ? \"create\" : \"update\";\n if (dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, next);\n record(result, path, \"file\", action);\n}\n\nasync function mergeJson(\n path: string,\n patch: Readonly<Record<string, unknown>>,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const existing = await readIfExists(path);\n const current = existing ? parseJsonObject(existing, path) : {};\n const next = deepMerge(current, patch);\n const contents = `${stableStringify(next)}\\n`;\n if (existing === contents) {\n result.filesSkipped.push(path);\n return;\n }\n const action = existing === undefined ? \"create\" : \"update\";\n if (dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, contents);\n record(result, path, \"file\", action);\n}\n\nasync function appendGitignore(\n path: string,\n entries: ReadonlyArray<string>,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const raw = await readIfExists(path);\n const existing = raw ?? \"\";\n const lines = new Set(existing.split(/\\r?\\n/g).map((line) => line.trim()));\n const missing = entries.filter((entry) => !lines.has(entry));\n if (missing.length === 0) {\n result.filesSkipped.push(path);\n return;\n }\n const next = `${existing}${existing && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\"}${missing.join(\"\\n\")}\\n`;\n const action = raw === undefined ? \"create\" : \"update\";\n if (dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n await writeFile(path, next);\n record(result, path, \"file\", action);\n}\n\nasync function addDependency(\n path: string,\n op: { name: string; version: string; dev?: boolean },\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const existing = await readIfExists(path);\n if (!existing) {\n throw new ZitadelError(\"E_VALIDATION\", \"package.json is required to add Zitadel dependencies\");\n }\n const current = parseJsonObject(existing, path);\n const key = op.dev ? \"devDependencies\" : \"dependencies\";\n const deps = isObject(current[key]) ? (current[key] as Record<string, unknown>) : {};\n if (deps[op.name] === op.version) {\n result.filesSkipped.push(path);\n return;\n }\n // package.json is user-owned: splice only the dependency map's value into\n // the document. Every byte outside it — key order, blank lines, inline\n // objects, line endings — stays untouched; the touched map itself is\n // name-sorted, matching what a package manager writes.\n const contents = setTopLevelJsonKey(\n existing,\n path,\n key,\n sortByKey({ ...deps, [op.name]: op.version }),\n );\n if (dryRun) {\n record(result, path, \"file\", \"update\");\n result.depsAdded.push(op.name);\n return;\n }\n await writeFile(path, contents);\n record(result, path, \"file\", \"update\");\n result.depsAdded.push(op.name);\n}\n\n/** Rebuilds an object with lexicographically sorted keys (dependency maps). */\nfunction sortByKey(value: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(value).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)),\n );\n}\n\nasync function readIfExists(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if (typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction abs(cwd: string, path: string): string {\n return join(cwd, path);\n}\n\nfunction deepMerge(\n target: Record<string, unknown>,\n patch: Readonly<Record<string, unknown>>,\n): Record<string, unknown> {\n const out = { ...target };\n for (const [key, value] of Object.entries(patch)) {\n if (isObject(value) && isObject(out[key])) {\n out[key] = deepMerge(out[key] as Record<string, unknown>, value);\n } else {\n out[key] = value;\n }\n }\n return out;\n}\n","/**\n * Scaffolded guidance for humans (`README.md`) and agents (`AGENTS.md`):\n * the golden journey from a fresh scaffold to a customized, published\n * login — so the project explains its own next step without the docs\n * site. Both files are edited via a marker-fenced managed section, so\n * setup never clobbers what a developer (or another tool) wrote and a\n * rerun replaces only its own section.\n */\nimport { publicCliCommand } from \"../../../public-cli\";\nimport type { PatchContext } from \"../types\";\n\nconst MARKER_BEGIN = \"<!-- zitadel:guidance:begin -->\";\nconst MARKER_END = \"<!-- zitadel:guidance:end -->\";\n\n/**\n * Insert or replace the managed guidance section in `source`. A missing\n * file becomes `header` + section; an existing section (marker pair) is\n * replaced in place; anything else gets the section appended. Pure and\n * idempotent — the file-writer skips the write when output equals input.\n */\nexport function upsertGuidanceSection(\n source: string | undefined,\n section: string,\n header: string,\n): string {\n const block = `${MARKER_BEGIN}\\n${section}\\n${MARKER_END}\\n`;\n if (source === undefined || source.trim() === \"\") {\n return `${header}${block}`;\n }\n const begin = source.indexOf(MARKER_BEGIN);\n const end = source.indexOf(MARKER_END);\n if (begin !== -1 && end > begin) {\n return `${source.slice(0, begin)}${block}${source.slice(end + MARKER_END.length).replace(/^\\n/, \"\")}`;\n }\n return `${source.replace(/\\n*$/, \"\\n\\n\")}${block}`;\n}\n\n/**\n * Remove the managed guidance section (markers inclusive) from `source` —\n * the inverse of {@link upsertGuidanceSection}, for `eject`. Content outside\n * the markers is preserved byte-for-byte; a missing or malformed marker pair\n * returns `source` unchanged.\n */\nexport function removeGuidanceSection(source: string): string {\n const begin = source.indexOf(MARKER_BEGIN);\n const end = source.indexOf(MARKER_END);\n if (begin === -1 || end <= begin) {\n return source;\n }\n return `${source.slice(0, begin)}${source.slice(end + MARKER_END.length).replace(/^\\n/, \"\")}`;\n}\n\n/** The agent-facing golden path, written into `AGENTS.md`. */\nexport function agentsGuidanceSection(ctx: PatchContext): string {\n const plan = publicCliCommand(\"plan\", ctx.cliVersion);\n const apply = publicCliCommand(\"apply\", ctx.cliVersion);\n // WebAuthn ceremonies need an OS-level authenticator, so an agent driving\n // an automated browser stalls on the primary action of a passkey-first\n // flow unless told how to verify around it.\n const passkeyVerifyNote =\n ctx.preset === \"passkey-first\"\n ? \" Agents: automated browsers can't complete passkey ceremonies — verify the loop via the email/password fallback actions, or attach a CDP WebAuthn virtual authenticator.\"\n : \"\";\n // JSX typing is a Next/React concern; other frameworks type the elements\n // through their own SDK wrappers, so the pointer would be misleading there.\n const jsxTypesNote =\n ctx.framework.id === \"next\"\n ? \" React JSX types for the `<zitadel-*>` elements ship with the SDK — `custom-elements.d.ts` references `@zitadel/sdk-next/jsx`.\"\n : \"\";\n // Describe the posture the pages were actually emitted with (ADR 044), so\n // the guidance never claims full-page chrome an embedded card doesn't have.\n const presentationParagraph =\n ctx.posture === \"widget\"\n ? 'Presentation, by contrast, is edited in the generated pages: this app pre-dates setup, so they embed the sign-in widgets as `variant=\"widget\"` cards (with `theme=\"auto\"`) inside your existing layout; switch to `variant=\"page\"` for the widget\\'s own full-page chrome, and set `theme` (`light` | `dark` | `auto`) to pick the color scheme — `auto` follows the OS `prefers-color-scheme`, not this app\\'s own theme, so pin `light` or `dark` when the app fixes its scheme.'\n : 'Presentation, by contrast, is edited in the generated pages: they pin the sign-in widgets to `variant=\"page\"` (full-page chrome); switch to `variant=\"widget\"` to embed a card inside your own layout, and set `theme` (`light` | `dark` | `auto`) to pick the color scheme — `auto` follows the OS `prefers-color-scheme`, not this app\\'s own theme, so pin `light` or `dark` when the app fixes its scheme.';\n // The token bridge is the highest-leverage embedding lever and lives\n // nowhere an integrator would otherwise look (component source). Keep the\n // knob list here in sync with the documented public tokens.\n const themingParagraph =\n \"Theming the widgets from your app: `--zl-*` design-token custom properties set on the element in your own stylesheet pierce the widgets' shadow DOM. The bridge covers your fonts (`--zl-font-family-heading`, `--zl-font-family-sans`), radii (`--zl-radius-md`/`-lg`/`-xl`), the primary CTA pair (`--zl-primary` / `--zl-primary-foreground`), and the link color (`--zl-link`). When your page already carries the heading, set the `suppress-header` attribute on `<zitadel-login>` / `<zitadel-session>` (SDK wrappers: `suppressHeader`) to visually hide the widget's own heading block — it stays in the accessibility tree. Starter designs from `.zitadel/branding/` collapse their brand pane by container width, not viewport: an embedded card usually renders the compact brand mark instead (`logo_url`, else `hero_url`, from `branding.json`; the `hero` design falls back to editable text).\";\n // The app's own chrome (header nav, account menus) needs a session read of\n // its own — the widgets render their surfaces but never tell the host page\n // whether someone is signed in. Name the framework's supported read path;\n // the contract details live with each helper's own docs.\n const sessionStateParagraph =\n ctx.framework.id === \"next\"\n ? \"Your app's own chrome (header navigation, account menus) reads session state with `getSession()` from `@zitadel/sdk-next/session` — a no-store client read of the same-origin `/__nextgen/sessions/me` that the session card itself uses. It returns identity only for 200 with a non-empty `user_id`, and signed-out only for the backend's canonical `401/auth.unauthorized` or `404/sess.not_found`; any other response is unknown/error, never signed-out. In Server Components on routes covered by the request-boundary `matcher`, `auth()` from `@zitadel/sdk-next/server` works too — extend the `matcher` in the request boundary to cover your public routes when you want server-rendered, flash-free session state in shared chrome (the trade: the middleware then runs on those routes). Sign-in and sign-out navigate (`post-sign-in-url` / `post-sign-out-url`), so chrome re-reads on the next page load without extra wiring.\"\n : ctx.framework.id === \"nuxt\"\n ? \"Your app's own chrome (header navigation, account menus) reads session state with the auto-imported `useAuth()` composable — seeded from the server on every render by the scaffolded auth plugin. Sign-in and sign-out navigate (`post-sign-in-url` / `post-sign-out-url`), so the state is fresh on every page load.\"\n : 'Your app\\'s own chrome (header navigation, account menus) can read session state from the same-origin `/__nextgen/sessions/me` — the same server-answered read the session card performs. Fetch with `credentials: \"include\"`, `cache: \"no-store\"`, and `Accept: application/json`; treat 200 as signed-in only with a non-empty `user_id`, and signed-out only for the canonical error envelope `401/auth.unauthorized` or `404/sess.not_found`. Any other response is unknown/error, never signed-out. Sign-in and sign-out navigate (`post-sign-in-url` / `post-sign-out-url`), so chrome re-reads on the next page load.';\n return `## Authentication (Zitadel)\n\nThis app's login is managed by Zitadel. Local config is the source of truth; never change auth behavior by editing generated route files.\n\nThe golden path:\n\n1. Start the dev server and open ${ctx.issuer}/login — **exactly this origin, not 127.0.0.1**. Passkeys and the origin allowlist are bound to it. (Freshly scaffolded apps also redirect / there; pre-existing apps keep their homepage.)\n2. Prove the loop in a real browser: register a user → sign out → sign in → /profile shows signed in.${passkeyVerifyNote}\n3. Customize by editing local config:\n - \\`.zitadel/schemas/*.json\\` — what a user is (fields, required, auth methods). See \\`.zitadel/schemas/README.md\\`.\n - \\`.zitadel/flows/*.json\\` — which screen collects which field/credential and how steps transition. See \\`.zitadel/flows/README.md\\`.\n4. Preview, then publish:\n - \\`${plan}\\`\n - \\`${apply}\\`\n - Agents: append \\`--non-interactive --json\\` to both. \\`plan\\` validates flow invariants with the server's own rules **before** anything uploads — fix what it reports and re-run.\n\n${presentationParagraph}${jsxTypesNote}\n\n${themingParagraph}\n\n${sessionStateParagraph}\n\nMachine-readable dialect (read these before authoring flow or schema edits):\n\n- Flow files carry \\`\"$schema\": \"../meta/flow-definition.json\"\\` — the flow dialect spec (steps, actions and their kinds, transitions, reserved outcomes like \\`user_not_found\\`). Editors validate against it.\n- \\`.zitadel/meta/user-schema.json\\` (with its companions \\`user-property.json\\`, \\`auth-methods.json\\`, \\`auth-method.json\\`) specifies the user-schema dialect (\\`x-auth-methods\\`, \\`x-unique\\`, property constraints).\n- Worked flow examples: https://github.com/zitadel/nextgen/tree/main/api/openapi/endpoints/flow_definitions/examples\n\nNever edit \\`.zitadel/state.json\\` (sync bookkeeping) or \\`.zitadel/secret\\` (credentials, git-ignored). Keep \\`.zitadel/local/\\` out of source control.`;\n}\n\n/** The human-facing summary appended to the app `README.md`. */\nexport function readmeGuidanceSection(ctx: PatchContext): string {\n const plan = publicCliCommand(\"plan\", ctx.cliVersion);\n const apply = publicCliCommand(\"apply\", ctx.cliVersion);\n return `## Authentication (Zitadel)\n\nLogin for this app is managed by [Zitadel](https://zitadel.com). Try it: start the dev server, open ${ctx.issuer}/login (use this exact origin — passkeys are bound to it), register a user, sign out, and sign in again.\n\nTo change what the login collects or how sign-in works, edit the files under \\`.zitadel/schemas/\\` and \\`.zitadel/flows/\\` (each folder has a README), then:\n\n\\`\\`\\`sh\n${plan}\n${apply}\n\\`\\`\\``;\n}\n\n/** Full-file header used when `AGENTS.md` does not exist yet. */\nexport const AGENTS_HEADER = `# AGENTS.md\n\nGuidance for AI agents working in this repository.\n\n`;\n\n/** Full-file header used when `README.md` does not exist yet. */\nexport const README_HEADER = \"\";\n","import { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { isObject } from \"../../../json\";\nimport { MANAGED_MARKER } from \"../../../paths\";\nimport type { FileOp, ScaffoldPlan } from \"./file-writer/types\";\n\n/**\n * The subset of a patcher plan's operations that `doctor --fix` re-applies:\n * env merges, gitignore entries, dependency additions, marker-bearing managed\n * files (framework routes/middleware), and the `edit` transforms — the\n * `/__nextgen` dev proxy merged into `vite.config`/`nuxt.config`/`angular.json`\n * and the Angular `dev` script added to `package.json`. Every `edit` transform\n * is idempotent and only adds what is missing (an existing value is left as-is,\n * the transform returning the source unchanged), so replaying one restores a\n * removed managed block without clobbering the user's own edits. Deliberately\n * excludes the unmarked `.zitadel/` resource writes and `zitadel.json` — those\n * are user-editable and synced by `apply`, so `--fix` must not clobber them.\n *\n * Pure: filters a freshly-allocated list; the input plan is not mutated.\n */\nexport function reclaimableOps(plan: ScaffoldPlan): FileOp[] {\n return plan.ops.filter(\n (op) =>\n op.kind === \"merge-env\" ||\n op.kind === \"append-gitignore\" ||\n op.kind === \"add-dep\" ||\n op.kind === \"edit\" ||\n (op.kind === \"write\" && op.contents.includes(MANAGED_MARKER)),\n );\n}\n\n/**\n * Narrow a reclaimable op list to what a missing-only repair may replay:\n * content ops (`write`, and `edit` marked `overwrites`) survive only when\n * their target file does not exist, so the repair can restore a deleted\n * managed file but can never touch an edited or user-adopted one. Merging\n * `edit` transforms and the additive kinds (`merge-env`, `append-gitignore`)\n * pass through — they are idempotent and only add what is missing. `add-dep`\n * is additive only while the dependency is absent: `addDependency` replaces\n * a differing existing version, so under missing-only semantics the op is\n * dropped whenever the dependency is already declared at *any* version —\n * repairing an unrelated missing file must never rewrite a user-pinned\n * range. Reads the filesystem; paths resolve against `cwd` like the\n * file-writer's.\n */\nexport async function withoutExistingTargets(\n ops: ReadonlyArray<FileOp>,\n cwd: string,\n): Promise<FileOp[]> {\n const kept: FileOp[] = [];\n for (const op of ops) {\n if (op.kind === \"write\") {\n if (!(await exists(join(cwd, op.path)))) {\n kept.push(op);\n }\n continue;\n }\n if (op.kind === \"edit\" && op.overwrites) {\n const candidates = typeof op.path === \"string\" ? [op.path] : op.path;\n const present = await Promise.all(\n candidates.map((candidate) => exists(join(cwd, candidate))),\n );\n if (!present.includes(true)) {\n kept.push(op);\n }\n continue;\n }\n if (op.kind === \"add-dep\") {\n if (!(await dependencyDeclared(cwd, op.name))) {\n kept.push(op);\n }\n continue;\n }\n kept.push(op);\n }\n return kept;\n}\n\n/**\n * Whether `package.json` already declares `name` in dependencies or\n * devDependencies, at any version. A missing or unparsable `package.json`\n * counts as \"not declared\" so the op is kept and the file-writer's own\n * error handling reports the real problem.\n */\nasync function dependencyDeclared(cwd: string, name: string): Promise<boolean> {\n let contents: string;\n try {\n contents = await readFile(join(cwd, \"package.json\"), \"utf8\");\n } catch {\n return false;\n }\n try {\n const pkg = JSON.parse(contents) as unknown;\n if (!isObject(pkg)) {\n return false;\n }\n const declared = (key: string): boolean => isObject(pkg[key]) && name in (pkg[key] as object);\n return declared(\"dependencies\") || declared(\"devDependencies\");\n } catch {\n return false;\n }\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { metaSchemaFiles, META_SCHEMA_DIR } from \"@zitadel/config/meta-schemas\";\n\nimport { stableStringify } from \"../../../json\";\nimport { normalizePublicCliJson } from \"../../../public-cli\";\nimport { DEFAULT_SERVER } from \"../../../server\";\nimport { scaffold } from \"./file-writer\";\nimport type { FileOp, ScaffoldPlan } from \"./file-writer/types\";\nimport {\n AGENTS_HEADER,\n agentsGuidanceSection,\n README_HEADER,\n readmeGuidanceSection,\n upsertGuidanceSection,\n} from \"./guidance\";\nimport type {\n ConfigWiringStatus,\n EjectActions,\n Patcher,\n PatchContext,\n PatchExecOptions,\n PatchResult,\n PatchView,\n} from \"../types\";\nimport { reclaimableOps, withoutExistingTargets } from \"./reclaim\";\n\n/**\n * Base for rule-based (deterministic, template-driven) patchers, as opposed to\n * a future LLM-driven family. It applies the integration by building a\n * file-operation plan and running the file-writer — that strategy stays\n * entirely inside this family, so callers only ever see the family-neutral\n * {@link Patcher} surface. Owns the framework-agnostic `.zitadel/` base files\n * and the shared eject classification; subclasses contribute only their\n * framework-specific routes/middleware.\n */\nexport abstract class AbstractRulePatcher implements Patcher {\n abstract canPatch(framework: string): boolean;\n\n /** Apply the full plan (base `.zitadel/` files + framework routes). */\n async patch(ctx: PatchContext, opts: PatchExecOptions): Promise<PatchResult> {\n return scaffold(this.plan(ctx), opts);\n }\n\n /**\n * Re-apply only the reclaimable subset — env files, gitignore, the SDK\n * dependency, and marker-bearing routes — leaving the user-editable\n * `.zitadel/` resources untouched. Backs `doctor --fix`. With\n * `opts.missingOnly` the content ops are further narrowed to files that do\n * not exist (see {@link withoutExistingTargets}) and the writer runs without\n * `force`, so the repair restores deleted managed files and can never\n * overwrite an edited or user-adopted one.\n */\n async repair(ctx: PatchContext, opts: PatchExecOptions): Promise<PatchResult> {\n const plan = this.plan(ctx);\n let ops = opts.missingOnly\n ? await withoutExistingTargets(reclaimableOps(plan), opts.cwd)\n : reclaimableOps(plan);\n const excluded = new Set(opts.excludePaths ?? []);\n if (excluded.size > 0) {\n ops = ops.filter((op) => {\n if (op.kind === \"write\") {\n return !excluded.has(op.path);\n }\n if (op.kind === \"edit\" && op.overwrites) {\n const candidates = typeof op.path === \"string\" ? [op.path] : op.path;\n return !candidates.some((candidate) => excluded.has(candidate));\n }\n return true;\n });\n }\n const execOpts = opts.missingOnly ? { ...opts, force: false } : opts;\n return scaffold({ ops, summary: plan.summary }, execOpts);\n }\n\n /**\n * Probe whether the labelled config wirings are still applied, using each\n * merge transform's own idempotency: the transforms only add what is\n * missing and return the source unchanged when everything they manage is\n * present, so a changed output means the wiring is absent from the user's\n * config. Every labelled wiring gets a verdict: a missing host file is\n * `detached` (the wiring cannot be applied in a file that does not exist),\n * and a transform that throws on restructured content yields `unknown` —\n * surfaced rather than silently dropped, so a deleted `angular.json` can\n * never read as healthy. Read-only.\n */\n async verify(\n ctx: PatchContext,\n opts: { cwd: string },\n ): Promise<ReadonlyArray<ConfigWiringStatus>> {\n const statuses: ConfigWiringStatus[] = [];\n for (const op of this.plan(ctx).ops) {\n if (op.kind !== \"edit\" || !op.wiring) {\n continue;\n }\n const candidates = typeof op.path === \"string\" ? [op.path] : op.path;\n let path = candidates[0]!;\n let source: string | undefined;\n for (const candidate of candidates) {\n const contents = await readTextIfExists(join(opts.cwd, candidate));\n if (contents !== undefined) {\n path = candidate;\n source = contents;\n break;\n }\n }\n if (source === undefined) {\n statuses.push({ path, wiring: op.wiring, state: \"detached\" });\n continue;\n }\n try {\n statuses.push({\n path,\n wiring: op.wiring,\n state: op.edit(source) === source ? \"applied\" : \"detached\",\n });\n } catch (error) {\n statuses.push({\n path,\n wiring: op.wiring,\n state: \"unknown\",\n reason: error instanceof Error ? error.message : \"verification failed\",\n });\n }\n }\n return statuses;\n }\n\n /** Shared base artifacts plus the subclass's marker-bearing route files. */\n artifacts(view: PatchView): EjectActions {\n const infrastructure = new Set(this.infrastructureFiles(view));\n const markedFiles = this.routeFiles(view);\n return {\n markedFiles,\n rootConfigFiles: [\"zitadel.json\"],\n directories: [\".zitadel\"],\n envBackups: [\".env.local\"],\n dependencies: this.routeDeps(view),\n configEdits: this.routeConfigEdits(view),\n guidanceFiles: [\"AGENTS.md\", \"README.md\"],\n fileClasses: Object.fromEntries(\n markedFiles.map((path) => [path, infrastructure.has(path) ? \"infrastructure\" : \"presentation\"]),\n ),\n conditionalFiles: this.conditionallyScaffoldedFiles(view),\n retiredAlternates: this.retiredAlternateFiles(view),\n };\n }\n\n /**\n * Current marked files mapped to sibling paths that older templates wrote\n * in their place and the framework rejects alongside them. Drives the\n * managed-files boundary migration. Defaults to none; Next overrides it\n * for the `middleware.ts`/`proxy.ts` pair.\n */\n protected retiredAlternateFiles(\n _view: PatchView,\n ): Readonly<Record<string, ReadonlyArray<string>>> {\n return {};\n }\n\n /**\n * The subset of {@link routeFiles} that is load-bearing for the integration\n * (request boundary, proxies, plugins, type declarations). The `doctor`\n * managed-files check fails when one is missing; everything else is a\n * presentation starting point and only warns. Every patcher whose marked\n * files include plumbing must override this — Next (boundary/provider/dts),\n * Angular (proxy.conf.cjs), and Nuxt (plugins) do. The Vite SPAs' only\n * marked file is the root component (presentation); their plumbing lives in\n * `vite.config.*`, which is a config-edit merge into a user file and out of\n * the file check's reach. Defaults to none.\n */\n protected infrastructureFiles(_view: PatchView): ReadonlyArray<string> {\n return [];\n }\n\n /**\n * Marked files only written on some scaffolds (e.g. a framework home page\n * that setup replaces only when it created the app skeleton itself). The\n * managed-files check excludes them when no scaffold manifest recorded what\n * was actually written. Defaults to none.\n */\n protected conditionallyScaffoldedFiles(_view: PatchView): ReadonlyArray<string> {\n return [];\n }\n\n /**\n * User config files this patcher merges into via an `edit` op (e.g.\n * `vite.config.ts`). `eject` can't reverse an in-place merge, so it lists\n * these as manual cleanup steps. Defaults to none; patchers that edit a config\n * (React/Vue/Angular/Nuxt) override it. Next writes whole marker-bearing files\n * instead, so it has none.\n */\n protected routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [];\n }\n\n /**\n * The full file-operation plan this patcher would apply. Public so rule-family\n * unit tests can assert the planned ops directly; the generic {@link Patcher}\n * interface deliberately does not expose it (an LLM patcher has no such plan).\n */\n plan(ctx: PatchContext): ScaffoldPlan {\n return {\n ops: [...this.baseOps(ctx), ...this.routeOps(ctx)],\n summary: [this.summary(ctx)],\n };\n }\n\n /**\n * The framework-agnostic `.zitadel/` base files every rule patcher writes:\n * the project secret, `zitadel.json`, env templates, and an empty sync\n * state. The `schemas/` and `flows/` directories are created empty here;\n * setup fills them from versioned local defaults after patching.\n * Pure: no filesystem or network.\n */\n private baseOps(ctx: PatchContext): ReadonlyArray<FileOp> {\n return [\n { kind: \"mkdir\", path: \".zitadel\", mode: 0o700 },\n { kind: \"mkdir\", path: \".zitadel/flows\" },\n { kind: \"mkdir\", path: \".zitadel/schemas\" },\n { kind: \"append-gitignore\", entries: [\".zitadel/secret\", \".env*\", \"!.env.example\"] },\n {\n kind: \"write\",\n path: \".zitadel/secret\",\n mode: 0o600,\n contents: `${stableStringify({\n project_id: ctx.project.id,\n project_secret: ctx.project.project_secret,\n preview_secret: ctx.project.preview_secret,\n preview_origins: ctx.project.preview_origins,\n created_at: ctx.project.created_at,\n })}\\n`,\n },\n { kind: \"write\", path: \"zitadel.json\", contents: `${stableStringify(projectConfig(ctx))}\\n` },\n {\n kind: \"merge-env\",\n path: \".env.example\",\n entries: {\n ZITADEL_PROJECT_ID: \"\",\n ZITADEL_PROJECT_SECRET: \"\",\n ZITADEL_ENVIRONMENT: \"\",\n ZITADEL_ISSUER: \"\",\n ZITADEL_URL: \"\",\n },\n },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: {\n ZITADEL_PROJECT_ID: ctx.project.id,\n ZITADEL_PROJECT_SECRET: ctx.project.project_secret,\n ZITADEL_ENVIRONMENT: \"development\",\n ZITADEL_ISSUER: ctx.issuer,\n ZITADEL_URL: ctx.server,\n },\n },\n {\n kind: \"write\",\n path: \".zitadel/state.json\",\n contents: `${stableStringify({ framework: ctx.framework.id, resources: {} })}\\n`,\n },\n // The dialect meta-schemas, committed with the project so flow files'\n // relative `$schema` pointers resolve offline (editor validation) and\n // agents can read the flow/schema dialect without the docs site. Their\n // descriptions become editor tooltips inside the generated app, so the\n // `zitadel …` mentions are rewritten to the runnable public form on the\n // way out — the shared source keeps the bare spelling the server wants.\n { kind: \"mkdir\", path: META_SCHEMA_DIR },\n ...metaSchemaFiles().map(\n (file): FileOp => ({\n kind: \"write\",\n path: `${META_SCHEMA_DIR}/${file.name}`,\n contents: `${JSON.stringify(normalizePublicCliJson(file.body, ctx.cliVersion), null, 2)}\\n`,\n }),\n ),\n // Guidance for humans (README) and agents (AGENTS.md): the golden\n // journey and the customize→plan→apply loop. Marker-fenced managed\n // sections — existing content is never clobbered.\n {\n kind: \"edit\",\n path: \"AGENTS.md\",\n edit: (source) => upsertGuidanceSection(source, agentsGuidanceSection(ctx), AGENTS_HEADER),\n },\n {\n kind: \"edit\",\n path: \"README.md\",\n edit: (source) => upsertGuidanceSection(source, readmeGuidanceSection(ctx), README_HEADER),\n },\n ];\n }\n\n /** Framework-specific route/middleware write ops plus the SDK dependency. */\n protected abstract routeOps(ctx: PatchContext): ReadonlyArray<FileOp>;\n /** Framework-specific managed (marker-bearing) file paths, for ejection. */\n protected abstract routeFiles(view: PatchView): ReadonlyArray<string>;\n /**\n * The package-manager dependencies the integration added, surfaced in\n * `eject`'s `next_commands` so the user can uninstall them themselves.\n */\n protected abstract routeDeps(view: PatchView): ReadonlyArray<string>;\n /** One-line summary of what the integration scaffolded. */\n protected abstract summary(ctx: PatchContext): { title: string; detail: string };\n}\n\n/** Reads a text file, mapping every failure to `undefined`. */\nasync function readTextIfExists(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return undefined;\n }\n}\n\n/** Builds the `zitadel.json` body persisted at the project root. */\nfunction projectConfig(ctx: PatchContext): Record<string, unknown> {\n const environments: Record<string, unknown> = { development: { issuer: ctx.issuer } };\n if (ctx.project.preview_origins.length > 0) {\n // preview_origins are already full origins (scheme://host[:port]); don't\n // prepend a scheme or it doubles up (https://http://localhost:3000).\n environments.preview = {\n issuer_pattern: [...ctx.project.preview_origins],\n };\n }\n return {\n $schema: \"https://schemas.zitadel.com/v2/project.schema.json\",\n project: ctx.project.id,\n server: resolveServerOrigin(ctx.server),\n framework: { id: ctx.framework.id },\n branding: { renderer: ctx.rendererId, attribution: \"visible\" },\n environments,\n ...(ctx.preset === undefined ? {} : { preset: ctx.preset }),\n ...(ctx.useCase === undefined ? {} : { useCase: ctx.useCase }),\n };\n}\n\n/** Normalizes a server URL to its origin, falling back to {@link DEFAULT_SERVER}. */\nfunction resolveServerOrigin(source: string): string {\n try {\n return new URL(source).origin;\n } catch {\n return DEFAULT_SERVER;\n }\n}\n","import { ZitadelError } from \"../../../../errors\";\nimport { isObject, parseJsonObject } from \"../../../../json\";\n\n/**\n * Builds the pure `edit` transform the file-writer applies to `angular.json`:\n * wires a dev-server `proxyConfig` (and optional `port`) into the project's\n * `serve` target. The project name is discovered from the file (`defaultProject`,\n * else the sole project) rather than hardcoded, since it varies per app.\n * Idempotent — already-set values are left as-is. Throws `E_VALIDATION` when the\n * file is absent, the project/serve target cannot be located, or the workspace\n * has several projects with no `defaultProject` to disambiguate (rather than\n * guessing and wiring the proxy into an arbitrary one).\n */\nexport function angularProxyEdit(opts: {\n proxyConfig: string;\n port?: number;\n}): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"Cannot wire Angular proxy: angular.json not found\", {\n hint: \"Run setup from an Angular project.\",\n });\n }\n const root = parseJsonObject(source, \"angular.json\");\n const projects = isObject(root.projects)\n ? (root.projects as Record<string, unknown>)\n : undefined;\n const projectNames = Object.keys(projects ?? {});\n let projectName: string | undefined;\n if (typeof root.defaultProject === \"string\") {\n projectName = root.defaultProject;\n } else if (projectNames.length === 1) {\n projectName = projectNames[0];\n } else if (projectNames.length > 1) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"angular.json has multiple projects and no defaultProject to choose from\",\n {\n hint: `Set \"defaultProject\" in angular.json, or add \"proxyConfig\" to the right project's serve target manually. Projects: ${projectNames.join(\", \")}.`,\n },\n );\n }\n const project = projects && projectName ? projects[projectName] : undefined;\n if (!isObject(project)) {\n throw new ZitadelError(\"E_VALIDATION\", \"No project found in angular.json\", {\n hint: 'Add \"proxyConfig\" to your serve target manually.',\n });\n }\n // Angular CLI has used both \"architect\" and \"targets\" for the target map.\n const targets = isObject(project.architect)\n ? (project.architect as Record<string, unknown>)\n : isObject(project.targets)\n ? (project.targets as Record<string, unknown>)\n : undefined;\n const serve =\n targets && isObject(targets.serve) ? (targets.serve as Record<string, unknown>) : undefined;\n if (!serve) {\n throw new ZitadelError(\"E_VALIDATION\", \"No serve target in angular.json\", {\n hint: 'Add \"proxyConfig\" to your serve options manually.',\n });\n }\n const options = isObject(serve.options) ? (serve.options as Record<string, unknown>) : {};\n let changed = false;\n if (options.proxyConfig === undefined) {\n options.proxyConfig = opts.proxyConfig;\n changed = true;\n }\n if (opts.port !== undefined && options.port === undefined) {\n options.port = opts.port;\n changed = true;\n }\n // Nothing to add — return the source untouched so the edit op skips it\n // instead of reformatting (re-indenting) the user's angular.json.\n if (!changed) {\n return source;\n }\n serve.options = options;\n // Preserve the user's key order (JSON, no comments) instead of sorting.\n return `${JSON.stringify(root, null, 2)}\\n`;\n };\n}\n","import { parseModule } from \"magicast\";\n\nimport { ZitadelError } from \"../../../../errors\";\n\n/**\n * Generic magicast helpers shared by the config-editing patchers (Vite, Nuxt).\n * They navigate a module's default export — they carry no framework knowledge\n * beyond \"find the config object literal\" and \"is this import present\".\n */\n\n/**\n * Parses a config file with magicast, throwing a clean `E_VALIDATION` (instead\n * of a raw parse error) when the source is missing or unparseable. `filename` is\n * only used in the error message, so each patcher can name its own config file.\n */\nexport function parseConfigModule(\n source: string | undefined,\n filename: string,\n): ReturnType<typeof parseModule> {\n if (source === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", `Cannot edit ${filename}: file not found`, {\n hint: `Run setup from a project that has ${filename}.`,\n });\n }\n let mod: ReturnType<typeof parseModule>;\n try {\n mod = parseModule(source);\n } catch (error) {\n throw new ZitadelError(\"E_VALIDATION\", `Could not parse ${filename}`, {\n hint: `Ensure ${filename} is valid, or apply the Zitadel changes manually.`,\n details: { cause: error instanceof Error ? error.message : String(error) },\n });\n }\n // A CommonJS config (e.g. a `*.cjs` file or a `*.js` with `module.exports`)\n // can't evaluate the ESM `import`/`import.meta.url` these edits inject, so\n // reject it with a clear message instead of producing a broken config. Check\n // the parsed AST for a real `module.exports`/`exports.x` assignment — scanning\n // raw text would false-positive on the same string in a comment or literal.\n if (hasCommonJsExport(mod)) {\n throw new ZitadelError(\"E_VALIDATION\", `${filename} is a CommonJS module, which can't be edited`, {\n hint: `The Zitadel edits use ESM imports. Convert the config to ESM (a .ts/.mts file, or set \"type\": \"module\"), or add the Zitadel block manually.`,\n });\n }\n return mod;\n}\n\n/**\n * Whether the module has a top-level CommonJS export assignment —\n * `module.exports = …`, `module.exports.x = …`, or `exports.x = …` — read from\n * the parsed AST so comments and string literals can't trigger a false match.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction hasCommonJsExport(mod: any): boolean {\n // magicast's `$ast` may be a babel `File` (with `.program.body`) or the\n // `Program` node itself (`.body`) — handle both.\n const program = mod?.$ast?.program ?? mod?.$ast;\n const body = program?.body ?? [];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return body.some((node: any) => {\n if (node?.type !== \"ExpressionStatement\" || node.expression?.type !== \"AssignmentExpression\") {\n return false;\n }\n const left = node.expression.left;\n if (left?.type !== \"MemberExpression\") {\n return false;\n }\n const object = left.object;\n // `exports.x = …`\n if (object?.type === \"Identifier\" && object.name === \"exports\") {\n return true;\n }\n // `module.exports = …`\n if (object?.type === \"Identifier\" && object.name === \"module\" && left.property?.name === \"exports\") {\n return true;\n }\n // `module.exports.x = …`\n return (\n object?.type === \"MemberExpression\" &&\n object.object?.name === \"module\" &&\n object.property?.name === \"exports\"\n );\n });\n}\n\n/**\n * Reaches the object literal of a module's default export — the argument of\n * `export default <call>({...})` (e.g. `defineConfig`/`defineNuxtConfig`) or a\n * bare `export default {...}`. Throws `E_VALIDATION` for shapes magicast cannot\n * safely edit (function-form, configs built elsewhere) so the caller can fall\n * back to manual steps.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function resolveDefaultExportObject(mod: any, filename: string): any {\n const def = mod.exports?.default;\n const unreachable = () =>\n new ZitadelError(\"E_VALIDATION\", `Could not locate the config object in ${filename}`, {\n hint: `Add the Zitadel configuration to ${filename} manually (see the SDK README).`,\n });\n if (!def) {\n throw unreachable();\n }\n if (def.$type === \"function-call\") {\n const arg = def.$args?.[0];\n if (!arg || arg.$type !== \"object\") {\n throw unreachable();\n }\n return arg;\n }\n if (def.$type === \"object\") {\n return def;\n }\n throw unreachable();\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function importIsPresent(mod: any, local: string, from?: string): boolean {\n try {\n const items: ReadonlyArray<{ local?: string; from?: string }> = mod.imports?.$items ?? [];\n // Match the source module too when given, so a same-named local imported\n // from a different module isn't mistaken for the one we need.\n return items.some((item) => item.local === local && (from === undefined || item.from === from));\n } catch {\n return false;\n }\n}\n\n/**\n * Appends `item` to a string array at `parent[key]`, creating the array when\n * absent and skipping it when already present. Reads the proxified array by\n * index so primitive elements compare as plain values. Returns `true` when it\n * actually added the item, so callers can tell whether the edit changed\n * anything (and skip rewriting an already-complete config).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function ensureArrayItem(parent: any, key: string, item: string): boolean {\n if (parent[key] === undefined) {\n parent[key] = [item];\n return true;\n }\n const arr = parent[key];\n // The existing value is something other than an array literal (e.g. an\n // identifier or spread), which magicast cannot safely append to. Surface a\n // clean E_VALIDATION instead of letting `arr.push` throw a raw TypeError.\n if (typeof arr?.push !== \"function\" || typeof arr?.length !== \"number\") {\n throw new ZitadelError(\"E_VALIDATION\", `Could not add \"${item}\" to \"${key}\"`, {\n hint: `Add \"${item}\" to \"${key}\" in your config manually.`,\n });\n }\n const present = Array.from({ length: arr.length as number }, (_unused, i) => arr[i]).includes(\n item,\n );\n if (!present) {\n arr.push(item);\n return true;\n }\n return false;\n}\n\n/**\n * Returns the object literal at `parent[key]`, creating an empty one when\n * absent, so callers can safely descend into it. Throws `E_VALIDATION` when the\n * key already holds something that is not an inline object literal (an\n * identifier, spread, or function call) — magicast cannot edit those, and\n * assigning into them otherwise throws a raw proxy `TypeError`. The object\n * sibling of {@link ensureArrayItem}.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function ensureEditableObject(parent: any, key: string): any {\n if (parent[key] === undefined) {\n parent[key] = {};\n }\n const value = parent[key];\n if (value?.$type !== \"object\") {\n throw new ZitadelError(\"E_VALIDATION\", `Could not edit \"${key}\" in the config`, {\n hint: `Set \"${key}\" to an inline object literal, or add the Zitadel settings manually.`,\n });\n }\n return value;\n}\n","import { builders, generateCode } from \"magicast\";\n\nimport { ZitadelError } from \"../../../../errors\";\nimport { parseConfigModule } from \"../utils/magicast\";\n\nconst AUTH_ROUTE_PATHS = [\"login\", \"register\", \"profile\"] as const;\n\n/**\n * Angular's default `ng new` app enables the router with an empty route table.\n * That router rejects direct `/login` and `/profile` navigations, then rewrites\n * the URL back to `/`. Add componentless routes for the auth paths so the root\n * component can keep rendering based on `window.location.pathname` without\n * requiring a router outlet.\n */\nexport function angularRoutesEdit(): (source: string | undefined) => string {\n return (source) => {\n const label = \"src/app/app.routes.ts\";\n const mod = parseConfigModule(source, label);\n const routes = mod.exports?.routes;\n if (routes?.$type !== \"array\" || typeof routes.push !== \"function\") {\n throw new ZitadelError(\"E_VALIDATION\", \"Cannot wire Angular auth routes\", {\n hint: `Set \"routes\" in ${label} to an inline Routes array, or add /login, /register, and /profile manually.`,\n });\n }\n\n const present = new Set(\n Array.from({ length: routes.length as number }, (_unused, index) => routes[index]?.path).filter(\n (path): path is string => typeof path === \"string\",\n ),\n );\n let changed = false;\n for (const path of AUTH_ROUTE_PATHS) {\n if (present.has(path)) {\n continue;\n }\n routes.push(builders.raw(`{ path: ${JSON.stringify(path)}, children: [] }`));\n changed = true;\n }\n\n if (!changed && source !== undefined) {\n return source;\n }\n const code = generateCode(mod).code;\n return code.endsWith(\"\\n\") ? code : `${code}\\n`;\n };\n}\n","/**\n * The same-origin path the SDK widgets call (`configureZitadel({ proxyPath })`),\n * which every framework's dev proxy forwards to the backend. Framework-agnostic:\n * Vite (React/Vue), Angular's dev-server proxy, and Nuxt's server middleware all\n * key off the same prefix, so it lives here rather than in any one framework's\n * patcher.\n */\nexport const PROXY_PATH = \"/__nextgen\";\n","import { ZitadelError } from \"../../../errors\";\nimport { PROXY_PATH } from \"./proxy\";\n\n/** Marker emitted after the exchange-only credential policy was introduced. */\nexport const PROXY_CREDENTIAL_POLICY_MARKER = \"zitadel:proxy:v2\";\n\n/**\n * Rejects a browser-reachable proxy that still appears to attach the project\n * secret without the complete exchange-only guard. Known generated legacy\n * bytes are migrated before this runs; anything else stays user-owned and is\n * surfaced for manual review instead of being silently counted as healthy by\n * `zitadel doctor`.\n */\nexport function assertNoUnreviewedProjectSecretProxy(source: string, label: string): void {\n if (\n !source.includes(PROXY_PATH) ||\n !source.includes(\"ZITADEL_PROJECT_SECRET\") ||\n !/authorization/i.test(source) ||\n hasExchangeOnlyGuard(source)\n ) {\n return;\n }\n\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${label} may forward ZITADEL_PROJECT_SECRET outside POST /sessions/exchange`,\n {\n hint: \"Review the proxy manually: restrict the bearer to the exact POST /sessions/exchange pathname and preserve caller-provided authorization.\",\n },\n );\n}\n\nfunction hasExchangeOnlyGuard(source: string): boolean {\n const authorizationSetter = /proxyReq\\s*\\.\\s*setHeader\\s*\\(\\s*[\"']authorization[\"']\\s*,/gi;\n const setterOffsets = [...source.matchAll(authorizationSetter)].map((match) => match.index);\n if (setterOffsets.length === 0) {\n return false;\n }\n\n const safeBodyRanges: Array<Readonly<{ start: number; end: number }>> = [];\n const ifBlock = /if\\s*\\(([\\s\\S]*?)\\)\\s*\\{([\\s\\S]*?)\\}/g;\n for (const match of source.matchAll(ifBlock)) {\n const condition = match[1];\n const body = match[2];\n if (\n !/proxyReq\\s*\\.\\s*method\\s*===\\s*[\"']POST[\"']/i.test(condition) ||\n !/pathname\\s*===\\s*[\"']\\/sessions\\/exchange[\"']/i.test(condition) ||\n !/!\\s*proxyReq\\s*\\.\\s*getHeader\\s*\\(\\s*[\"']authorization[\"']\\s*\\)/i.test(condition) ||\n !/proxyReq\\s*\\.\\s*setHeader\\s*\\(\\s*[\"']authorization[\"']\\s*,/i.test(body)\n ) {\n continue;\n }\n\n const bodyOffset = match[0].lastIndexOf(body);\n const start = match.index + bodyOffset;\n safeBodyRanges.push({ start, end: start + body.length });\n }\n\n // Every project-secret authorization write must live inside the same exact\n // method/path/no-overwrite guard. A decoy guard next to an unconditional\n // write must not make doctor report the file as healthy.\n return setterOffsets.every((offset) =>\n safeBodyRanges.some(({ start, end }) => offset >= start && offset < end),\n );\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\nimport {\n assertNoUnreviewedProjectSecretProxy,\n PROXY_CREDENTIAL_POLICY_MARKER,\n} from \"../proxy-credential-policy\";\n\n/**\n * The managed root component `src/app/app.ts`: a standalone component that\n * renders the `@zitadel/sdk-angular` widgets based on the current path. The\n * project id (public, not secret) is inlined; the dev proxy in `proxy.conf.cjs`\n * attaches the project service-key secret as the bearer server-side only to\n * `POST /sessions/exchange` (read from `.env.local`), and no secret reaches\n * the browser.\n *\n * Projects set up with the business use case additionally expose the SDK's\n * `businessLocales` overlay as a class property, which `app.html` binds to the\n * login widgets via `[locales]` — restoring work-email copy on top of the\n * widget's neutral built-in dictionaries.\n */\nexport function appComponentTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? `\n ZitadelLoginComponent,\n ZitadelSessionComponent,\n businessLocales,\n configureZitadel,\n`\n : `\n ZitadelLoginComponent,\n ZitadelSessionComponent,\n configureZitadel,\n`;\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesProperty = business\n ? `\n // Set up for a business audience: businessLocales overlays work-email copy\n // on the login widget's neutral built-in dictionaries. Remove it (and the\n // [locales] binding in app.html) to fall back to the neutral wording.\n protected readonly locales = businessLocales;`\n : \"\";\n return `${MANAGED_MARKER}\nimport { Component, OnInit } from \"@angular/core\";\nimport {${importNames}} from \"@zitadel/sdk-angular\";\n\n@Component({\n selector: \"app-root\",\n standalone: true,\n imports: [ZitadelLoginComponent, ZitadelSessionComponent],\n templateUrl: \"./app.html\",\n})\nexport class App implements OnInit {\n protected readonly project = configureZitadel({\n projectId: ${JSON.stringify(ctx.project.id)},\n proxyPath: \"${PROXY_PATH}\",\n });\n protected readonly path = window.location.pathname;${localesProperty}\n\n ngOnInit(): void {\n if (this.path === \"/\") {\n window.location.replace(\"/login\");\n }\n }\n}\n`;\n}\n\n/**\n * The managed `src/app/app.html`. The marker lives in an HTML comment that still\n * contains the literal managed-marker text, so eject/doctor stay marker-aware.\n * Business-use-case scaffolds bind the component's `locales` overlay property\n * onto the login widgets.\n */\nexport function appTemplateHtml(ctx: PatchContext): string {\n const localesBinding = ctx.useCase === \"business\" ? `\\n [locales]=\"locales\"` : \"\";\n return `<!-- ${MANAGED_MARKER} -->\n@if (path.startsWith('/profile')) {\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <zitadel-auth-session\n [project]=\"project\"\n [postSignOutUrl]=\"'/login'\"\n ></zitadel-auth-session>\n </div>\n} @else if (path.startsWith('/register')) {\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <zitadel-auth-login\n [project]=\"project\"${localesBinding}\n purpose=\"register\"\n [postSignInUrl]=\"'/profile'\"\n ></zitadel-auth-login>\n </div>\n} @else {\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <zitadel-auth-login\n [project]=\"project\"${localesBinding}\n purpose=\"login\"\n [postSignInUrl]=\"'/profile'\"\n ></zitadel-auth-login>\n </div>\n}\n`;\n}\n\n/**\n * The managed `proxy.conf.cjs` for `ng serve`: forwards `/__nextgen/*` to the\n * backend and attaches the project's service-key secret only to the current\n * app-plane `POST /sessions/exchange` request. Both the backend URL\n * (`ZITADEL_URL`) and the secret\n * (`ZITADEL_PROJECT_SECRET`) are read from `.env.local`, which `zitadel setup`\n * writes and `.gitignore` excludes — Angular's CLI does not auto-load env files\n * into the dev-server process, so this file does it itself with a small inline\n * parser. The prefix strip and the bearer are each provided in both the\n * http-proxy-middleware form (`pathRewrite`/`onProxyReq`) and the Vite form\n * (`rewrite`/`configure`), so both fire whichever proxy layer Angular's\n * dev server uses.\n */\nexport function proxyConfTemplate(): string {\n return `${MANAGED_MARKER}\nconst { readFileSync, existsSync } = require(\"node:fs\");\n\nfunction loadEnvLocal() {\n if (!existsSync(\".env.local\")) return {};\n const out = {};\n for (const line of readFileSync(\".env.local\", \"utf8\").split(/\\\\r?\\\\n/)) {\n const m = line.match(/^\\\\s*(?:export\\\\s+)?([A-Z_][A-Z0-9_]*)\\\\s*=\\\\s*(.*)$/);\n if (m) {\n const raw = m[2].trim();\n const quoted = raw.match(/^(['\"])(.*)\\\\1\\\\s*(?:#.*)?$/);\n out[m[1]] = quoted ? quoted[2] : raw.replace(/\\\\s+#.*$/, \"\").trim();\n }\n }\n return out;\n}\n\nconst env = loadEnvLocal();\nconst server = process.env.ZITADEL_URL ?? env.ZITADEL_URL;\nconst secret = process.env.ZITADEL_PROJECT_SECRET ?? env.ZITADEL_PROJECT_SECRET;\nif (!server) {\n throw new Error(\"ZITADEL_URL is not set; add it to .env.local (zitadel setup writes it).\");\n}\nif (!secret) {\n throw new Error(\"ZITADEL_PROJECT_SECRET is not set; add it to .env.local (zitadel setup writes it).\");\n}\nconst bearer = \\`Bearer \\${secret}\\`;\n\n${EXCHANGE_ONLY_BEARER}\n\nfunction stripPrefix(path) {\n return path.replace(/^\\\\${PROXY_PATH}/, \"\").replace(/^(?!\\\\/)/, \"/\");\n}\n\nmodule.exports = {\n \"${PROXY_PATH}\": {\n target: server,\n changeOrigin: false,\n pathRewrite: stripPrefix,\n rewrite: stripPrefix,\n onProxyReq: setBearer,\n configure: (proxy) => proxy.on(\"proxyReq\", setBearer),\n },\n};\n`;\n}\n\nconst LEGACY_UNCONDITIONAL_BEARER = `function setBearer(proxyReq) {\n proxyReq.setHeader(\"authorization\", bearer);\n}`;\n\nconst EXCHANGE_ONLY_BEARER = `/* ${PROXY_CREDENTIAL_POLICY_MARKER} */\nfunction setBearer(proxyReq) {\n const pathname = new URL(proxyReq.path, \"http://zitadel.local\").pathname;\n if (\n proxyReq.method === \"POST\" &&\n pathname === \"/sessions/exchange\" &&\n !proxyReq.getHeader(\"authorization\")\n ) {\n proxyReq.setHeader(\"authorization\", bearer);\n }\n}`;\n\n/**\n * Creates the managed Angular proxy and upgrades the exact insecure hook the\n * CLI emitted before the exchange-only policy. Other edits are preserved; a\n * safe custom proxy is left untouched, while an unrecognized proxy that may\n * still over-forward the project secret is surfaced for manual review.\n */\nexport function proxyConfEdit(): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n return proxyConfTemplate();\n }\n if (source.includes(MANAGED_MARKER) && source.includes(LEGACY_UNCONDITIONAL_BEARER)) {\n return source.replace(LEGACY_UNCONDITIONAL_BEARER, EXCHANGE_ONLY_BEARER);\n }\n assertNoUnreviewedProjectSecretProxy(source, \"proxy.conf.cjs\");\n return source;\n };\n}\n","import { ZitadelError } from \"../../../../errors\";\nimport { isObject, parseJsonObject, setTopLevelJsonKey } from \"../../../../json\";\nimport { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { angularProxyEdit } from \"./angular-json\";\nimport { angularRoutesEdit } from \"./angular-routes\";\nimport { appComponentTemplate, appTemplateHtml, proxyConfEdit } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-angular\";\n\n/**\n * Adds a `dev: \"ng serve\"` script only when the project does not already define\n * one. `ng new` ships only a `start` script, but the CLI tells every framework\n * to run `npm run dev` (and `ng serve` reads the proxy + port from\n * `angular.json`). Non-destructive: an existing `dev` script is preserved, so\n * patching a project that already wires its own `dev` leaves it untouched.\n */\nfunction ensureDevScript(source: string | undefined): string {\n if (source === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"package.json is required to add the dev script\", {\n hint: \"Run setup from a project that has a package.json.\",\n });\n }\n const pkg = parseJsonObject(source, \"package.json\");\n const scripts = isObject(pkg.scripts) ? pkg.scripts : undefined;\n // Leave an existing dev script untouched, returning the source unchanged so\n // the edit op skips the file instead of reformatting the user's package.json.\n if (scripts?.dev !== undefined) {\n return source;\n }\n // package.json is user-owned: splice only the scripts value; every byte\n // outside it stays untouched.\n return setTopLevelJsonKey(source, \"package.json\", \"scripts\", {\n ...(scripts ?? {}),\n dev: \"ng serve\",\n });\n}\n\n/**\n * Rule-based patcher for an Angular app. Inherits the shared `.zitadel/` base\n * files from {@link AbstractRulePatcher} and contributes the managed root\n * component (`app.ts`/`app.html`) that renders the `@zitadel/sdk-angular`\n * widgets, a `proxy.conf.cjs` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`) wired into `angular.json`,\n * and the SDK dep.\n *\n * Unlike React/Vue (whose dev proxy lives in `vite.config.ts`), Angular owns its\n * Vite config, so the proxy is a separate `proxy.conf.cjs` referenced from the\n * `serve` target. In production the same-origin path comes from a platform\n * rewrite or minimal worker (ADR 036); CLI scaffolding for it is tracked in\n * issue #560.\n */\nexport class AngularPatcher extends AbstractRulePatcher {\n canPatch(framework: string): boolean {\n return framework === \"angular\";\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n {\n kind: \"write\",\n path: \"src/app/app.ts\",\n contents: appComponentTemplate(ctx),\n },\n { kind: \"write\", path: \"src/app/app.html\", contents: appTemplateHtml(ctx) },\n {\n kind: \"edit\",\n path: \"src/app/app.routes.ts\",\n edit: angularRoutesEdit(),\n // Without the auth routes the router bounces /login back to /.\n wiring: \"infrastructure\",\n },\n {\n kind: \"edit\",\n path: \"proxy.conf.cjs\",\n edit: proxyConfEdit(),\n // The transform creates the managed proxy when absent and safely\n // migrates the exact unconditional bearer hook emitted by older CLIs.\n wiring: \"infrastructure\",\n },\n {\n kind: \"edit\",\n path: \"angular.json\",\n edit: angularProxyEdit({ proxyConfig: \"proxy.conf.cjs\", port: ctx.framework.devPort }),\n // The serve target's proxyConfig is what attaches proxy.conf.cjs —\n // without it the proxy file is inert and auth requests fail.\n wiring: \"infrastructure\",\n },\n {\n kind: \"edit\",\n path: \"package.json\",\n edit: ensureDevScript,\n // Golden-path convenience (`npm run dev`); its absence only warns.\n wiring: \"convenience\",\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/app/app.ts\", \"src/app/app.html\", \"proxy.conf.cjs\"];\n }\n\n protected override infrastructureFiles(_view: PatchView): ReadonlyArray<string> {\n // The dev proxy is the auth request path (it also attaches the project\n // secret); the root component pair is the user's customization surface.\n return [\"proxy.conf.cjs\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n // These files are touched via `edit` ops eject can't auto-revert: the proxy\n // wired into angular.json, auth paths added to app.routes.ts, and the `dev`\n // script added to package.json.\n return [\"angular.json\", \"src/app/app.routes.ts\", \"package.json\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Angular integration\",\n detail:\n \"Wrote the app root component + proxy.conf.cjs, added auth routes, and wired the /__nextgen dev proxy into angular.json.\",\n };\n }\n}\n","import { ZitadelError } from \"../../../errors\";\nimport { isObject, parseJsonObject, setTopLevelJsonKey } from \"../../../json\";\nimport { extractPort, portFromIssuer, withDevPort } from \"../../detectors/port\";\nimport type { FileOp } from \"./file-writer/types\";\n\n/**\n * Pins the `dev` script to the port setup registered as the project's origin.\n *\n * Setup allows exactly one origin, `http://localhost:<devPort>`, so the dev\n * server has to land on that port or the flow API rejects the app mid-login\n * (the first step renders, the first submit 400s with `origin ... is not\n * allowed for this project`). Every other framework this CLI patches already\n * guarantees that in its own dev-server config — Vite gets `server.port` plus\n * `strictPort`, Angular gets `serve.options.port` — but `next dev` and\n * `nuxt dev` take their port from the command line, so nothing held them to\n * it: they default to 3000 regardless of the port setup registered.\n *\n * For Next the flag also restores the guarantee `strictPort` gives Vite: bare\n * `next dev` silently serves 3001 when 3000 is taken (measured), while\n * `next dev --port N` exits with `EADDRINUSE` instead of drifting onto a port\n * the project does not allow.\n *\n * Non-destructive: a script already on the right port is returned unchanged\n * (so the op skips the file rather than reformatting a user's package.json),\n * and a project without a `dev` script is left alone because there is no\n * command to pin.\n *\n * Takes the project's registered `issuer` rather than a port, because the\n * expected value has to survive the app drifting away from it. `doctor`\n * rebuilds this plan from `loadPatchContext`, whose `framework.devPort` is\n * freshly *detected* from the current script — deriving the target from that\n * would make any edited script verify against itself (always \"applied\") and\n * would make `doctor --fix` write back the detected fallback instead of the\n * port the project actually allows. The issuer comes from `zitadel.json`\n * (falling back to the scaffold manifest), so it still says 3456 after\n * someone edits the script to 4000. An issuer that names no port yields no\n * expectation and the op becomes a no-op.\n */\nexport function devScriptPortEdit(issuer: string): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"package.json is required to pin the dev port\", {\n hint: \"Run setup from a project that has a package.json.\",\n });\n }\n const devPort = portFromIssuer(issuer);\n if (devPort === undefined) {\n return source;\n }\n const pkg = parseJsonObject(source, \"package.json\");\n const scripts = isObject(pkg.scripts) ? pkg.scripts : undefined;\n const dev = scripts?.dev;\n if (typeof dev !== \"string\" || dev.trim() === \"\") {\n return source;\n }\n if (extractPort(dev) === devPort) {\n return source;\n }\n // package.json is user-owned: splice only the scripts value; every byte\n // outside it stays untouched.\n return setTopLevelJsonKey(source, \"package.json\", \"scripts\", {\n ...scripts,\n dev: withDevPort(dev, devPort),\n });\n };\n}\n\n/**\n * The `package.json` op pinning the dev script's port. Marked as managed\n * wiring so `doctor` reports a dev script that drifted off the registered\n * origin — `convenience` (warn, not fail) because the script is only one of\n * the ways a dev server picks its port: `npm run dev -- --port 4000` still\n * moves it without touching the file, so a hard failure here would promise a\n * guarantee the check cannot make.\n */\nexport function devScriptPortOp(issuer: string): FileOp {\n return {\n kind: \"edit\",\n path: \"package.json\",\n edit: devScriptPortEdit(issuer),\n wiring: \"convenience\",\n };\n}\n","import { MANAGED_MARKER } from \"../../../../../../paths\";\nimport type { RendererSpec } from \"../types\";\n\n/**\n * Placeholder renderer for the `<zitadel-flow>` Lit web component. Declared\n * so the `web-component` renderer id resolves and surfaces a clear\n * \"not yet published\" error, while reserving the integration shape for when\n * `@zitadel/ui-lit` ships. The `authPage` template emits an illustrative\n * page only; this renderer is never selected for real scaffolding because\n * `getRenderer` rejects any `status: \"not-implemented\"` spec.\n */\nexport const litRenderer: RendererSpec = {\n id: \"web-component\",\n displayName: \"Web component (<zitadel-flow>)\",\n status: \"not-implemented\",\n frameworks: [\"next\", \"astro\", \"remix\", \"sveltekit\", \"nuxt\", \"vanilla\"],\n dependency: { name: \"@zitadel/ui-lit\", version: \"workspace:*\" },\n templates: {\n authPage(mode) {\n const purpose = mode === \"login\" ? \"login\" : \"register\";\n return {\n mode,\n contents: `${MANAGED_MARKER}\n// The web component renderer ships a <zitadel-flow> element. Until\n// @zitadel/ui-lit is published, this template only declares the\n// intended integration point. See docs/design/cli/bdui-renderer.md.\nimport \"@zitadel/ui-lit\";\n\nconst environment =\n process.env.ZITADEL_ENVIRONMENT ??\n (process.env.NODE_ENV === \"production\" ? \"production\" : \"development\");\n\nexport default function ${mode === \"login\" ? \"LoginPage\" : \"RegisterPage\"}() {\n return (\n <zitadel-flow\n purpose=\"${purpose}\"\n project-id={process.env.ZITADEL_PROJECT_ID}\n issuer={process.env.ZITADEL_ISSUER}\n environment={environment}\n />\n );\n}\n`,\n };\n },\n },\n};\n","import { MANAGED_MARKER } from \"../../../../../../paths\";\nimport type { RendererSpec } from \"../types\";\n\n/**\n * The Next.js App Router renderer scaffolds `/login`, `/register`, and\n * `/profile` pages that drive the `<zitadel-login>` and `<zitadel-session>`\n * Lit web components. `/profile` is the post-sign-in \"signed in as\" card.\n *\n * Each page is a single client component (`\"use client\"`) that, inside a\n * `next/dynamic({ ssr: false })` loader, builds the SDK project handle with\n * `configureZitadel({ projectId, proxyPath: \"/__nextgen\" })` and passes it to\n * the widget via `project={...}`. It also imports\n * `@zitadel/sdk-next/client` for its `customElements.define`\n * side-effect — importing `@zitadel/components` directly would fail on\n * strict-resolution package managers (pnpm, yarn PnP) because the app only\n * declares `sdk-next` as a direct dep. SSR is disabled because Lit's element\n * registration needs a browser.\n *\n * The handle is passed as the `project` DOM property, which relies on React\n * 19's custom-element property binding (the scaffold targets the latest Next /\n * React). The backend URL never reaches the browser: the client talks to the\n * same-origin `/__nextgen` proxy path, and the scaffolded Next request boundary\n * forwards it to `ZITADEL_URL` server-side. `NEXT_PUBLIC_ZITADEL_PROJECT_ID` is\n * public — the project id is not sensitive and the widget needs it to start a\n * flow.\n *\n * Projects set up with the business use case additionally wire the SDK's\n * `businessLocales` overlay onto the auth pages, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. The overlay is assigned\n * via a ref callback, not a JSX prop: sdk-next supports React >=18, and only\n * React 19 binds non-primitive custom-element props as properties — on 18 a\n * `locales={...}` prop would decay to a useless attribute and silently keep\n * the neutral copy (the `project` prop tolerates this because\n * `configureZitadel()` registers a global fallback; `locales` has none).\n */\nexport const reactRenderer: RendererSpec = {\n id: \"react\",\n displayName: \"React (Next.js App Router)\",\n status: \"available\",\n frameworks: [\"next\"],\n dependency: { name: \"@zitadel/sdk-next\", version: \"latest\" },\n templates: {\n authPage(mode, context) {\n const componentName = mode === \"login\" ? \"LoginPage\" : \"RegisterPage\";\n const elementName = mode === \"login\" ? \"ZitadelLogin\" : \"ZitadelRegister\";\n // The business use case restores the work-email framing the widget's\n // neutral built-in copy dropped; the overlay ships with the SDK, so the\n // generated page only wires it up (and stays plain otherwise).\n const business = context.useCase === \"business\";\n const importNames = business ? \"businessLocales, configureZitadel\" : \"configureZitadel\";\n const localesComment = business\n ? `\n // Set up for a business audience: businessLocales overlays work-email\n // copy on the widget's neutral built-in dictionaries. It is assigned\n // through the ref because React binds non-primitive custom-element\n // props as properties only from v19 — the ref works on React 18 too.\n // Remove the assignment to fall back to the neutral wording.`\n : \"\";\n const localesAttr = business\n ? `\n ref={(element) => {\n if (element) {\n element.locales = businessLocales;\n }\n }}`\n : \"\";\n // Pre-existing apps embed the card in their own layout (ADR 044); a\n // fresh scaffold keeps the widget's full-page chrome.\n const widget = context.posture === \"widget\";\n const variantAttrs = widget ? `variant=\"widget\"\\n theme=\"auto\"` : `variant=\"page\"`;\n const postureComment = widget\n ? ` // variant=\"widget\" embeds the sign-in card in this app's existing layout.\n // theme=\"auto\" follows the OS light/dark preference (prefers-color-scheme),\n // not this app's own theme — set theme=\"light\" or theme=\"dark\" to match an\n // app that pins its scheme. The wrapper below only centers the card —\n // restyle or replace it freely. Switch to variant=\"page\" for the widget's\n // own full-page chrome (viewport height, surface background from design\n // tokens).\n // If this page already carries its own heading, add suppress-header to the\n // element to visually hide the widget's heading block — it stays in the\n // accessibility tree, and the card keeps no blank header band.`\n : ` // variant=\"page\" makes the widget paint the full-page chrome itself\n // (viewport height, surface background) from design tokens; switch to\n // variant=\"widget\" to embed the sign-in card inside a layout you own.`;\n const wrapperOpen = widget\n ? `<div style={{ display: \"flex\", justifyContent: \"center\", padding: \"4rem 1rem\" }}>`\n : `<main style={{ colorScheme: \"dark\" }}>`;\n const wrapperClose = widget ? `</div>` : `</main>`;\n return {\n mode,\n contents: `${MANAGED_MARKER}\n\"use client\";\n\nimport dynamic from \"next/dynamic\";\n\nconst ${elementName} = dynamic(\n async () => {\n const { ${importNames} } = await import(\"@zitadel/sdk-next/client\");\n // Build the SDK project handle and pass it to the component via the\n // \\`project\\` prop. The component reads config from this prop directly, so\n // it works regardless of how the SDK packages are bundled. The backend URL\n // stays server-side: requests go through the proxy path \"/__nextgen\",\n // which the scaffolded request boundary forwards to the Zitadel server.\n const project = configureZitadel({\n projectId: process.env.NEXT_PUBLIC_ZITADEL_PROJECT_ID ?? \"\",\n proxyPath: \"/__nextgen\",\n });\n return function ${elementName}Element() {${localesComment}\n return (\n <zitadel-login\n ${variantAttrs}${localesAttr}\n project={project}\n purpose=\"${mode}\"\n post-sign-in-url=\"/profile\"\n />\n );\n };\n },\n { ssr: false },\n);\n\nexport default function ${componentName}() {\n${postureComment}\n return (\n ${wrapperOpen}\n <${elementName} />\n ${wrapperClose}\n );\n}\n`,\n };\n },\n profilePage(context) {\n // Same posture hinge as the auth pages (ADR 044): a pre-existing app\n // gets the session card embedded in its own layout.\n const widget = context.posture === \"widget\";\n const variantAttrs = widget ? `variant=\"widget\"\\n theme=\"auto\"` : `variant=\"page\"`;\n const postureComment = widget\n ? ` // variant=\"widget\" embeds the session card in this app's existing layout.\n // theme=\"auto\" follows the OS light/dark preference (prefers-color-scheme),\n // not this app's own theme — set theme=\"light\" or theme=\"dark\" to match an\n // app that pins its scheme. The wrapper below only centers the card —\n // restyle or replace it freely. Switch to variant=\"page\" for the card's\n // own full-page chrome (viewport height, surface background from design\n // tokens).\n // If this page already carries its own heading, add suppress-header to the\n // element to visually hide the widget's heading block — it stays in the\n // accessibility tree, and the card keeps no blank header band.`\n : ` // variant=\"page\" makes the session card paint the full-page chrome itself\n // (viewport height, surface background) from design tokens; switch to\n // variant=\"widget\" to embed the card inside a layout you own.`;\n const wrapperOpen = widget\n ? `<div style={{ display: \"flex\", justifyContent: \"center\", padding: \"4rem 1rem\" }}>`\n : `<main style={{ colorScheme: \"dark\" }}>`;\n const wrapperClose = widget ? `</div>` : `</main>`;\n return {\n contents: `${MANAGED_MARKER}\n\"use client\";\n\nimport dynamic from \"next/dynamic\";\n\nconst ZitadelSession = dynamic(\n async () => {\n const { configureZitadel } = await import(\"@zitadel/sdk-next/client\");\n // Build the SDK project handle and pass it to the session card via the\n // \\`project\\` prop. The card reads identity from \"/__nextgen/sessions/me\"\n // and exposes a Sign out action. Your own components (a header, an\n // account menu) can make the same read with getSession() from\n // \"@zitadel/sdk-next/session\" to swap sign-in CTAs for account chrome.\n const project = configureZitadel({\n projectId: process.env.NEXT_PUBLIC_ZITADEL_PROJECT_ID ?? \"\",\n proxyPath: \"/__nextgen\",\n });\n return function ZitadelSessionElement() {\n return (\n <zitadel-session\n ${variantAttrs}\n project={project}\n post-sign-out-url=\"/login\"\n />\n );\n };\n },\n { ssr: false },\n);\n\nexport default function ProfilePage() {\n${postureComment}\n return (\n ${wrapperOpen}\n <ZitadelSession />\n ${wrapperClose}\n );\n}\n`,\n };\n },\n customElementsDts() {\n return {\n contents: `${MANAGED_MARKER}\n// React JSX declarations for the <zitadel-*> custom elements ship with the\n// SDK, so the scaffold stays aligned with the real element surface instead\n// of carrying a hand-maintained copy that drifts.\n/// <reference types=\"@zitadel/sdk-next/jsx\" />\n`,\n };\n },\n },\n};\n","import { ZitadelError } from \"../../../../../errors\";\nimport { litRenderer } from \"./lit\";\nimport { reactRenderer } from \"./react\";\nimport type { RendererId, RendererSpec } from \"./types\";\n\n/**\n * Runtime mirror of the {@link RendererId} union, used by {@link isRendererId}\n * to validate untrusted strings (a TS union has no runtime presence). Must stay\n * in sync with the {@link RendererId} type.\n */\nexport const RENDERER_IDS: RendererId[] = [\"react\", \"web-component\"];\n\n/**\n * Type guard narrowing an arbitrary value to a {@link RendererId}, used to\n * validate renderer ids read from config before indexing {@link RENDERERS}.\n */\nexport function isRendererId(value: unknown): value is RendererId {\n return typeof value === \"string\" && (RENDERER_IDS as string[]).includes(value);\n}\n\n/**\n * The single source of truth mapping each {@link RendererId} to its spec.\n * Keyed by id so {@link getRenderer} can look up and validate a renderer\n * chosen from persisted config (an arbitrary string) at runtime.\n */\nexport const RENDERERS: Record<RendererId, RendererSpec> = {\n react: reactRenderer,\n \"web-component\": litRenderer,\n};\n\n/**\n * The subset of {@link RENDERER_IDS} that {@link getRenderer} resolves rather\n * than rejects (`status: \"available\"`). Anything advertising renderer choices\n * — flag options, error hints — must derive from this list, not\n * {@link RENDERER_IDS}: a declared-but-unpublished renderer (ADR 006) keeps\n * its registry entry to reserve the id, but must never be offered as a usable\n * value.\n */\nexport const AVAILABLE_RENDERER_IDS: RendererId[] = RENDERER_IDS.filter(\n (id) => RENDERERS[id].status === \"available\",\n);\n\n/**\n * Resolves a renderer id (an untrusted string from config) to its spec,\n * throwing a typed {@link ZitadelError} rather than returning `undefined`\n * so callers get an actionable message. Rejects ids that are unknown\n * (`E_VALIDATION`) or declared-but-unpublished (`E_NOT_IMPLEMENTED`),\n * guaranteeing the returned spec is safe to scaffold from.\n */\nexport function getRenderer(id: string): RendererSpec {\n if (!isRendererId(id)) {\n throw new ZitadelError(\"E_VALIDATION\", `Unknown renderer \"${id}\"`, {\n hint: `Available renderers: ${AVAILABLE_RENDERER_IDS.join(\", \")}`,\n });\n }\n const renderer = RENDERERS[id];\n if (renderer.status === \"not-implemented\") {\n throw new ZitadelError(\n \"E_NOT_IMPLEMENTED\",\n `Renderer \"${id}\" is declared but not yet published`,\n {\n hint: \"Use --renderer react for now; the <zitadel-flow> web component ships in a later package.\",\n },\n );\n }\n return renderer;\n}\n","import { join } from \"node:path\";\n\nimport { MANAGED_MARKER } from \"../../../../paths\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { devScriptPortOp } from \"../dev-script-port\";\nimport { getRenderer } from \"./renderers/registry\";\nimport type { RendererSpec } from \"./renderers/types\";\n\n/**\n * Next.js request-boundary file at the project root. Wires `nextgenMiddleware` so the\n * generated project config's `/__nextgen` proxy path is same-origin proxied\n * to `ZITADEL_URL` and `/profile` is gated. Next 16 renamed this convention to\n * `proxy.ts`; older projects keep `middleware.ts`.\n * Carries the managed marker so `doctor --fix` reclaims it and `eject` removes it.\n */\nfunction requestBoundaryTemplate(functionName: \"middleware\" | \"proxy\"): string {\n return `${MANAGED_MARKER}\nimport { nextgenMiddleware } from \"@zitadel/sdk-next/middleware\";\nimport type { NextRequest } from \"next/server\";\n\nexport function ${functionName}(req: NextRequest) {\n return nextgenMiddleware(req, {\n url: process.env.ZITADEL_URL,\n protectedRoutes: [\"/profile\"],\n loginPath: \"/login\",\n });\n}\n\nexport const config = {\n matcher: [\"/__nextgen/:path*\", \"/profile/:path*\"],\n};\n`;\n}\n\n/**\n * Rule-based patcher for the Next.js App Router. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * Next routes and request boundary whose templates come from the chosen renderer.\n */\nexport class NextPatcher extends AbstractRulePatcher {\n /** Returns true for Next.js projects. */\n canPatch(framework: string): boolean {\n return framework === \"next\";\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return nextCodeOps(ctx, getRenderer(ctx.rendererId));\n }\n\n protected routeFiles(view: PatchView): ReadonlyArray<string> {\n return nextCodeFilePaths(view.framework, getRenderer(view.rendererId));\n }\n\n protected override infrastructureFiles(view: PatchView): ReadonlyArray<string> {\n return nextInfrastructureFilePaths(view.framework, getRenderer(view.rendererId));\n }\n\n protected override conditionallyScaffoldedFiles(view: PatchView): ReadonlyArray<string> {\n // Written only when setup created the app skeleton itself; on a\n // pre-existing app the homepage stays user-owned (see nextCodeOps).\n return [join(view.framework.appDir, \"page.tsx\")];\n }\n\n protected override retiredAlternateFiles(\n view: PatchView,\n ): Readonly<Record<string, ReadonlyArray<string>>> {\n // Next renamed the request boundary in v16 (middleware.ts → proxy.ts)\n // and throws at build time when both exist — but only in the ≥16\n // direction. On Next 15, proxy.ts was not a reserved convention, so a\n // root proxy.ts there is the user's own file, never a conflicting\n // boundary. Declaring the alternate one-way keeps a healthy Next 15 app\n // with an unrelated proxy.ts passing.\n const current = requestBoundaryFile(view.framework).filename;\n if (current !== \"proxy.ts\") {\n return {};\n }\n return {\n [join(view.framework.appDir, \"../proxy.ts\")]: [\n join(view.framework.appDir, \"../middleware.ts\"),\n ],\n };\n }\n\n protected routeDeps(view: PatchView): ReadonlyArray<string> {\n return [getRenderer(view.rendererId).dependency.name];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n // The `dev` script gets the project's dev-server port pinned into it via\n // an `edit` op eject can't auto-revert, so it has to be surfaced as a\n // manual cleanup step like any other in-place config merge.\n return [\"package.json\"];\n }\n\n protected summary(ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Next.js integration\",\n detail: `Scaffolded login/register/profile routes with renderer \"${ctx.rendererId}\".`,\n };\n }\n}\n\n/**\n * Ordered paths of the framework code files the patcher writes. All carry the\n * managed marker. Shared by {@link NextPatcher.routeOps} (which adds contents)\n * and {@link NextPatcher.routeFiles} (which only needs the paths) so the two\n * cannot drift.\n */\nfunction nextCodeFilePaths(\n framework: PatchView[\"framework\"],\n renderer: RendererSpec,\n): ReadonlyArray<string> {\n const appDir = framework.appDir;\n const paths = [\n join(appDir, \"page.tsx\"),\n join(appDir, \"login/page.tsx\"),\n join(appDir, \"register/page.tsx\"),\n ];\n if (renderer.templates.profilePage) {\n paths.push(join(appDir, \"profile/page.tsx\"));\n }\n paths.push(join(appDir, `../${requestBoundaryFile(framework).filename}`));\n if (renderer.templates.provider) {\n paths.push(join(appDir, renderer.templates.provider.filename));\n }\n if (renderer.templates.customElementsDts) {\n paths.push(join(appDir, \"../custom-elements.d.ts\"));\n }\n return paths;\n}\n\n/**\n * The subset of {@link nextCodeFilePaths} that is load-bearing for the auth\n * integration rather than a presentation starting point: the request boundary\n * (proxy/middleware), the provider file, and the custom-elements declarations.\n * Shares path construction with {@link nextCodeFilePaths} so the two cannot\n * drift; the `doctor` managed-files check fails when one of these is missing.\n */\nfunction nextInfrastructureFilePaths(\n framework: PatchView[\"framework\"],\n renderer: RendererSpec,\n): ReadonlyArray<string> {\n const appDir = framework.appDir;\n const paths = [join(appDir, `../${requestBoundaryFile(framework).filename}`)];\n if (renderer.templates.provider) {\n paths.push(join(appDir, renderer.templates.provider.filename));\n }\n if (renderer.templates.customElementsDts) {\n paths.push(join(appDir, \"../custom-elements.d.ts\"));\n }\n return paths;\n}\n\n/** The Next route/request-boundary write ops plus the SDK dependency. */\nfunction nextCodeOps(ctx: PatchContext, renderer: RendererSpec): FileOp[] {\n const appDir = ctx.framework.appDir;\n const pageContext = { useCase: ctx.useCase, posture: ctx.posture };\n const profile = renderer.templates.profilePage?.(pageContext);\n const provider = renderer.templates.provider;\n const dts = renderer.templates.customElementsDts?.();\n const boundary = requestBoundaryFile(ctx.framework);\n return [\n ctx.scaffoldedFramework\n ? {\n kind: \"edit\",\n path: join(appDir, \"page.tsx\"),\n edit: () => homePageTemplate(),\n // Replaces create-next-app's default homepage wholesale; the\n // missing-only repair path must not replay it over user content.\n overwrites: true,\n }\n : undefined,\n {\n kind: \"write\",\n path: join(appDir, \"login/page.tsx\"),\n contents: renderer.templates.authPage(\"login\", pageContext).contents,\n },\n {\n kind: \"write\",\n path: join(appDir, \"register/page.tsx\"),\n contents: renderer.templates.authPage(\"register\", pageContext).contents,\n },\n profile\n ? { kind: \"write\", path: join(appDir, \"profile/page.tsx\"), contents: profile.contents }\n : undefined,\n {\n kind: \"write\",\n path: join(appDir, `../${boundary.filename}`),\n contents: requestBoundaryTemplate(boundary.functionName),\n },\n provider\n ? { kind: \"write\", path: join(appDir, provider.filename), contents: provider.contents }\n : undefined,\n dts\n ? { kind: \"write\", path: join(appDir, \"../custom-elements.d.ts\"), contents: dts.contents }\n : undefined,\n // Next.js exposes NEXT_PUBLIC_-prefixed vars to client code.\n { kind: \"merge-env\", path: \".env.example\", entries: { NEXT_PUBLIC_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { NEXT_PUBLIC_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: renderer.dependency.name,\n version: dependencyVersionForCli(ctx.cliVersion, renderer.dependency.version),\n },\n // `next dev` takes its port from the command line only, so without this\n // the app can serve a port the project does not allow as an origin.\n devScriptPortOp(ctx.issuer),\n ].filter((op): op is FileOp => op !== undefined);\n}\n\nfunction homePageTemplate(): string {\n return `${MANAGED_MARKER}\nimport { redirect } from \"next/navigation\";\n\nexport default function Home() {\n redirect(\"/login\");\n}\n`;\n}\n\nfunction requestBoundaryFile(framework: PatchContext[\"framework\"]): {\n filename: \"middleware.ts\" | \"proxy.ts\";\n functionName: \"middleware\" | \"proxy\";\n} {\n if ((framework.versionMajor ?? 0) >= 16) {\n return { filename: \"proxy.ts\", functionName: \"proxy\" };\n }\n return { filename: \"middleware.ts\", functionName: \"middleware\" };\n}\n\nfunction dependencyVersionForCli(cliVersion: string, fallback: string): string {\n const normalized = cliVersion.trim().replace(/^v/, \"\");\n if (/^\\d+\\.\\d+\\.\\d+-alpha\\.\\d+$/.test(normalized)) {\n return normalized;\n }\n const prerelease = normalized.match(/^\\d+\\.\\d+\\.\\d+-([0-9A-Za-z]+)(?:[.-]|$)/)?.[1];\n return prerelease ?? fallback;\n}\n","/**\n * The module extensions the config edits can actually write, in resolution\n * priority. magicast injects ESM `import`/`import.meta.url`, so only ESM-capable\n * extensions are editable; CommonJS (`cts`/`cjs`) is not.\n */\nconst CONFIG_EXTENSIONS = [\"ts\", \"mts\", \"js\", \"mjs\"] as const;\n\n/**\n * The CommonJS extensions we still *probe* (after the ESM ones) so a project\n * whose only config is `*.cjs`/`*.cts` is found and rejected with a targeted\n * \"CommonJS is unsupported\" error, rather than a misleading \"file not found\".\n * {@link parseConfigModule} surfaces that error when it sees CommonJS source.\n */\nconst COMMONJS_EXTENSIONS = [\"cts\", \"cjs\"] as const;\n\n/**\n * Candidate config filenames for `basename`, ESM extensions first then the\n * CommonJS ones, e.g. `configCandidates(\"vite.config\")` → `[\"vite.config.ts\",\n * \"vite.config.mts\", \"vite.config.js\", \"vite.config.mjs\", \"vite.config.cts\",\n * \"vite.config.cjs\"]`. Handed to the\n * generic `edit` file-op, which patches the first one that exists — an ESM\n * config wins, and a CommonJS-only project is still read so the edit can emit a\n * clear unsupported-format error.\n */\nexport function configCandidates(basename: string): string[] {\n return [...CONFIG_EXTENSIONS, ...COMMONJS_EXTENSIONS].map((ext) => `${basename}.${ext}`);\n}\n","import { builders, generateCode } from \"magicast\";\n\nimport {\n ensureArrayItem,\n ensureEditableObject,\n parseConfigModule,\n resolveDefaultExportObject,\n} from \"../utils/magicast\";\nimport { PROXY_PATH } from \"../proxy\";\n\nconst NUXT_MODULE = \"@zitadel/sdk-nuxt/module\";\n\n/**\n * Builds the pure `edit` transform the file-writer applies to the project's Nuxt\n * config (`nuxt.config.*`): registers the `@zitadel/sdk-nuxt` module (which wires\n * the server-side proxy + session middleware), sets the login path, seeds\n * `runtimeConfig` with the backend URL, the proxy path, and the project id, and\n * marks the `zitadel-*` Lit elements as custom elements for the Vue compiler —\n * preserving the user's existing config via magicast. Idempotent. Throws\n * `E_VALIDATION` when the file is absent or `defineNuxtConfig` cannot be reached.\n */\nexport function nuxtConfigEdit(opts: {\n projectId: string;\n server: string;\n}): (source: string | undefined) => string {\n return (source) => {\n const label = \"the Nuxt config (nuxt.config.*)\";\n const mod = parseConfigModule(source, label);\n const config = resolveDefaultExportObject(mod, label);\n\n let changed = ensureArrayItem(config, \"modules\", NUXT_MODULE);\n\n const nextgen = ensureEditableObject(config, \"nextgen\");\n if (nextgen.url === undefined) {\n nextgen.url = builders.raw(\n `process.env.ZITADEL_URL ?? ${JSON.stringify(opts.server)}`,\n );\n changed = true;\n }\n if (nextgen.loginPath === undefined) {\n nextgen.loginPath = \"/login\";\n changed = true;\n }\n if (nextgen.protectedRoutes === undefined) {\n nextgen.protectedRoutes = [\"/profile\"];\n changed = true;\n }\n\n const runtimeConfig = ensureEditableObject(config, \"runtimeConfig\");\n if (runtimeConfig.zitadelUrl === undefined) {\n runtimeConfig.zitadelUrl = builders.raw(\n `process.env.ZITADEL_URL ?? ${JSON.stringify(opts.server)}`,\n );\n changed = true;\n }\n const publicConfig = ensureEditableObject(runtimeConfig, \"public\");\n if (publicConfig.nextgenProxyPath === undefined) {\n publicConfig.nextgenProxyPath = PROXY_PATH;\n changed = true;\n }\n if (publicConfig.zitadelProjectId === undefined) {\n publicConfig.zitadelProjectId = builders.raw(\n `process.env.NUXT_PUBLIC_ZITADEL_PROJECT_ID ?? ${JSON.stringify(opts.projectId)}`,\n );\n changed = true;\n }\n\n // The Lit components and their style/token deps must be transpiled for SSR\n // (matching the repo's own demo-nuxt config) or the build fails on the\n // untranspiled ESM those transitive packages ship.\n const build = ensureEditableObject(config, \"build\");\n for (const dep of [\n \"@zitadel/api\",\n \"@zitadel/components\",\n \"@zitadel/design-tokens\",\n ]) {\n if (ensureArrayItem(build, \"transpile\", dep)) {\n changed = true;\n }\n }\n\n // Tell Vue's template compiler the `zitadel-*` Lit elements are custom\n // elements, not Vue components, so it renders them as native elements\n // instead of logging \"Failed to resolve component\" and mis-binding props.\n const vue = ensureEditableObject(config, \"vue\");\n const compilerOptions = ensureEditableObject(vue, \"compilerOptions\");\n if (compilerOptions.isCustomElement === undefined) {\n compilerOptions.isCustomElement = builders.raw(`(tag) => tag.startsWith(\"zitadel-\")`);\n changed = true;\n }\n\n // Nothing was missing — return the source untouched so the file-writer skips\n // it instead of letting magicast reformat an already-patched config.\n if (!changed && source !== undefined) {\n return source;\n }\n const code = generateCode(mod).code;\n return code.endsWith(\"\\n\") ? code : `${code}\\n`;\n };\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\nimport type { PatchContext } from \"../../types\";\n\n/** `app.vue` — renders the page router. Marker in an HTML comment. */\nexport function appVueTemplate(): string {\n return `<!-- ${MANAGED_MARKER} -->\n<template>\n <NuxtPage />\n</template>\n\n<style>\n:root {\n color-scheme: dark;\n}\nbody {\n margin: 0;\n background: #0f0f11;\n color: #f4f4f6;\n font-family: sans-serif;\n}\n</style>\n`;\n}\n\n/** `pages/index.vue` — redirects the app root to `/login`. */\nexport function indexPageTemplate(): string {\n return `<script setup lang=\"ts\">\n${MANAGED_MARKER}\nawait navigateTo(\"/login\", { replace: true });\n</script>\n`;\n}\n\n/**\n * A login/register page rendering `<zitadel-login>` inside `<ClientOnly>`.\n * Business-use-case projects additionally bind the SDK's `businessLocales`\n * overlay, restoring work-email copy on top of the widget's neutral built-in\n * dictionaries. A plain `:locales` binding suffices even on the raw custom\n * element: Vue sets bindings whose key exists on the element as DOM\n * properties (unlike React 18, which is why the Next template needs a ref).\n */\nfunction authPage(purpose: \"login\" | \"register\", ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business ? \"businessLocales, useZitadelProject\" : \"useZitadelProject\";\n // The overlay ships with the SDK, so the generated page only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the :locales\n// binding to fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? '\\n :locales=\"businessLocales\"' : \"\";\n const purposeAttr = purpose === \"register\" ? '\\n purpose=\"register\"' : \"\";\n // Posture (ADR 044): page posture paints the widget's full-page chrome and\n // pins the color scheme via the <main> wrapper; widget posture embeds the\n // card in the host app's own layout inside a layout-neutral centered <div>.\n const widget = ctx.posture === \"widget\";\n const variantAttrs = widget ? 'variant=\"widget\"\\n theme=\"auto\"' : 'variant=\"page\"';\n const postureComment = widget\n ? `<!-- variant=\"widget\" embeds the card in this app's own layout.\n theme=\"auto\" follows the OS light/dark preference\n (prefers-color-scheme), not the app's own theme — set\n theme=\"light\" or theme=\"dark\" to match an app that pins its\n scheme. variant=\"page\" would paint the widget's full-page\n chrome instead. -->`\n : `<!-- variant=\"page\" paints the widget's full-page chrome from design\n tokens; variant=\"widget\" embeds the card inside a layout you own. -->`;\n const wrapperOpen = widget\n ? '<div style=\"display: flex; justify-content: center; padding: 4rem 1rem\">'\n : '<main style=\"color-scheme: dark\">';\n const wrapperClose = widget ? \"</div>\" : \"</main>\";\n return `<script setup lang=\"ts\">\n${MANAGED_MARKER}\nimport { ${importNames} } from \"@zitadel/sdk-nuxt\";${localesComment}\n\nconst project = useZitadelProject();\n</script>\n\n<template>\n ${wrapperOpen}\n <ClientOnly>\n ${postureComment}\n <zitadel-login\n ${variantAttrs}\n :project=\"project\"${localesAttr}${purposeAttr}\n post-sign-in-url=\"/profile\"\n />\n </ClientOnly>\n ${wrapperClose}\n</template>\n`;\n}\n\nexport function loginPageTemplate(ctx: PatchContext): string {\n return authPage(\"login\", ctx);\n}\n\nexport function registerPageTemplate(ctx: PatchContext): string {\n return authPage(\"register\", ctx);\n}\n\n/** `pages/profile.vue` — the post-sign-in \"signed in as\" session card. */\nexport function profilePageTemplate(ctx: PatchContext): string {\n // Same posture hinge as the auth pages (ADR 044).\n const widget = ctx.posture === \"widget\";\n const variantAttrs = widget ? 'variant=\"widget\"\\n theme=\"auto\"' : 'variant=\"page\"';\n const postureComment = widget\n ? `<!-- variant=\"widget\" embeds the session card in this app's own layout.\n theme=\"auto\" follows the OS light/dark preference\n (prefers-color-scheme), not the app's own theme — set\n theme=\"light\" or theme=\"dark\" to match an app that pins its\n scheme. variant=\"page\" would paint the card's full-page chrome\n instead. Your own components (a header, an account menu) read\n the same session state with the auto-imported useAuth()\n composable. -->`\n : `<!-- variant=\"page\" paints the session card's full-page chrome from design\n tokens; variant=\"widget\" embeds the card inside a layout you own.\n Your own components (a header, an account menu) read the same session\n state with the auto-imported useAuth() composable. -->`;\n const wrapperOpen = widget\n ? '<div style=\"display: flex; justify-content: center; padding: 4rem 1rem\">'\n : '<main style=\"color-scheme: dark\">';\n const wrapperClose = widget ? \"</div>\" : \"</main>\";\n const element = widget\n ? `<zitadel-session\n ${variantAttrs}\n :project=\"project\"\n post-sign-out-url=\"/login\"\n />`\n : `<zitadel-session variant=\"page\" :project=\"project\" post-sign-out-url=\"/login\" />`;\n return `<script setup lang=\"ts\">\n${MANAGED_MARKER}\nimport { useZitadelProject } from \"@zitadel/sdk-nuxt\";\n\nconst project = useZitadelProject();\n</script>\n\n<template>\n ${wrapperOpen}\n <ClientOnly>\n ${postureComment}\n ${element}\n </ClientOnly>\n ${wrapperClose}\n</template>\n`;\n}\n\n/** `plugins/zitadel-components.client.ts` — register the Lit elements client-side. */\nexport function componentsPluginTemplate(): string {\n return `${MANAGED_MARKER}\n// Register Lit custom elements on the client only. Importing @zitadel/components\n// from a page <script setup> would run during SSR and break the widgets.\nimport \"@zitadel/components\";\n\nexport default defineNuxtPlugin(() => {});\n`;\n}\n\n/** `plugins/auth.server.ts` — seed the client auth state from the server context. */\nexport function authPluginTemplate(): string {\n return `${MANAGED_MARKER}\nimport { defineNuxtPlugin, useRequestEvent, useState } from \"#imports\";\nimport type { ClientAuthResult } from \"@zitadel/sdk-nuxt\";\n\nexport default defineNuxtPlugin(() => {\n const event = useRequestEvent();\n const auth = event?.context.nextgenAuth ?? {\n isAuthenticated: false as const,\n session: null,\n };\n\n // Strip the raw JWT before seeding useState — it must not appear in the SSR\n // payload where client-side scripts could read it.\n const clientAuth: ClientAuthResult = auth.isAuthenticated\n ? {\n isAuthenticated: true,\n session: {\n userId: auth.session.userId,\n email: auth.session.email,\n name: auth.session.name,\n },\n }\n : { isAuthenticated: false, session: null };\n\n useState<ClientAuthResult>(\"nextgen-auth\", () => clientAuth);\n});\n`;\n}\n","import { join } from \"node:path\";\n\nimport { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport { configCandidates } from \"../config-paths\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { devScriptPortOp } from \"../dev-script-port\";\nimport { nuxtConfigEdit } from \"./nuxt-config\";\nimport {\n appVueTemplate,\n authPluginTemplate,\n componentsPluginTemplate,\n indexPageTemplate,\n loginPageTemplate,\n profilePageTemplate,\n registerPageTemplate,\n} from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-nuxt\";\n\nconst NUXT_CONFIG_PATHS = configCandidates(\"nuxt.config\");\n\n/**\n * Rule-based patcher for a Nuxt app. Like Next.js, Nuxt proxies the backend and\n * verifies the session through server middleware — here the `@zitadel/sdk-nuxt`\n * module, registered via a non-destructive `nuxt.config.*` edit. Contributes\n * the login/register/profile pages (the raw `<zitadel-login>`/`<zitadel-logout>`\n * elements), the client/server plugins, the `app.vue` router, and the SDK dep.\n */\nexport class NuxtPatcher extends AbstractRulePatcher {\n canPatch(framework: string): boolean {\n return framework === \"nuxt\";\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n const src = (rel: string) => join(ctx.framework.appDir, rel);\n return [\n // app.vue/pages/plugins live under the Nuxt srcDir (`app/` on Nuxt 4, the\n // root on Nuxt 3); nuxt.config, env, and the dep stay at the project root.\n // The app shell and homepage redirect are written only when setup created\n // the skeleton itself — a pre-existing app keeps its own shell, theme,\n // and landing page (ADR 044), same as the Next homepage.\n ...(ctx.scaffoldedFramework\n ? ([\n { kind: \"write\", path: src(\"app.vue\"), contents: appVueTemplate() },\n { kind: \"write\", path: src(\"pages/index.vue\"), contents: indexPageTemplate() },\n ] satisfies FileOp[])\n : []),\n { kind: \"write\", path: src(\"pages/login.vue\"), contents: loginPageTemplate(ctx) },\n { kind: \"write\", path: src(\"pages/register.vue\"), contents: registerPageTemplate(ctx) },\n { kind: \"write\", path: src(\"pages/profile.vue\"), contents: profilePageTemplate(ctx) },\n {\n kind: \"write\",\n path: src(\"plugins/zitadel-components.client.ts\"),\n contents: componentsPluginTemplate(),\n },\n { kind: \"write\", path: src(\"plugins/auth.server.ts\"), contents: authPluginTemplate() },\n {\n kind: \"edit\",\n path: [...NUXT_CONFIG_PATHS],\n edit: nuxtConfigEdit({ projectId: ctx.project.id, server: ctx.server }),\n // Runtime config + proxy wiring: auth breaks without it.\n wiring: \"infrastructure\",\n },\n { kind: \"merge-env\", path: \".env.example\", entries: { NUXT_PUBLIC_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { NUXT_PUBLIC_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n // `nuxt dev` takes its port from the command line only, so without this\n // the app can serve a port the project does not allow as an origin.\n devScriptPortOp(ctx.issuer),\n ];\n }\n\n protected routeFiles(view: PatchView): ReadonlyArray<string> {\n const src = (rel: string) => join(view.framework.appDir, rel);\n return [\n src(\"app.vue\"),\n src(\"pages/index.vue\"),\n src(\"pages/login.vue\"),\n src(\"pages/register.vue\"),\n src(\"pages/profile.vue\"),\n src(\"plugins/zitadel-components.client.ts\"),\n src(\"plugins/auth.server.ts\"),\n ];\n }\n\n protected override infrastructureFiles(view: PatchView): ReadonlyArray<string> {\n const src = (rel: string) => join(view.framework.appDir, rel);\n // The plugins are the auth plumbing: component registration on the\n // client and the server-side auth/session hook. The pages and app shell\n // are the user's customization surface.\n return [src(\"plugins/zitadel-components.client.ts\"), src(\"plugins/auth.server.ts\")];\n }\n\n protected override conditionallyScaffoldedFiles(view: PatchView): ReadonlyArray<string> {\n // Written only when setup created the app skeleton itself; on a\n // pre-existing app the shell and homepage stay user-owned (see routeOps).\n const src = (rel: string) => join(view.framework.appDir, rel);\n return [src(\"app.vue\"), src(\"pages/index.vue\")];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n // package.json: the `dev` script gets the project's dev-server port\n // pinned into it, another in-place edit eject can't auto-revert.\n return [\"nuxt.config.*\", \"package.json\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Nuxt integration\",\n detail:\n \"Wrote login/register/profile pages + plugins and registered @zitadel/sdk-nuxt in nuxt.config.*.\",\n };\n }\n}\n","import { builders, generateCode } from \"magicast\";\n\nimport { configCandidates } from \"./config-paths\";\nimport type { FileOp } from \"./file-writer/types\";\nimport { PROXY_PATH } from \"./proxy\";\nimport {\n assertNoUnreviewedProjectSecretProxy,\n PROXY_CREDENTIAL_POLICY_MARKER,\n} from \"./proxy-credential-policy\";\nimport {\n ensureEditableObject,\n importIsPresent,\n parseConfigModule,\n resolveDefaultExportObject,\n} from \"./utils/magicast\";\n\n/**\n * Shared Vite dev-server proxy merged into the project's Vite config for the SPA\n * frameworks (React, Vue, Solid, Svelte, Qwik). It forwards same-origin\n * `/__nextgen/*` calls to the\n * backend, strips the prefix, and attaches the project's service-key secret\n * (read from `ZITADEL_PROJECT_SECRET` in `.env.local`) only to the current\n * app-plane `POST /sessions/exchange` operation. The secret stays server-side:\n * Vite only exposes vars with the configured `envPrefix` (default `VITE_`) to\n * client bundles, so this server-only key never leaks into the browser.\n */\nfunction proxyEntryCode(server: string): string {\n return `/* ${PROXY_CREDENTIAL_POLICY_MARKER} */ {\n target: ${JSON.stringify(server)},\n changeOrigin: false,\n rewrite: (path) => path.replace(/^\\\\${PROXY_PATH}/, \"\").replace(/^(?!\\\\/)/, \"/\"),\n configure: (proxy) => {\n const secret = loadEnv(\"development\", process.cwd(), \"ZITADEL_\").ZITADEL_PROJECT_SECRET;\n if (!secret) {\n throw new Error(\"ZITADEL_PROJECT_SECRET is not set; add it to .env.local (zitadel setup writes it).\");\n }\n const bearer = \\`Bearer \\${secret}\\`;\n proxy.on(\"proxyReq\", (proxyReq) => {\n const pathname = new URL(proxyReq.path, \"http://zitadel.local\").pathname;\n if (\n proxyReq.method === \"POST\" &&\n pathname === \"/sessions/exchange\" &&\n !proxyReq.getHeader(\"authorization\")\n ) {\n proxyReq.setHeader(\"authorization\", bearer);\n }\n });\n },\n}`;\n}\n\nconst LEGACY_PROXY_REQUEST_LISTENER =\n /(^[\\t ]*)proxy\\.on\\(\"proxyReq\", \\(proxyReq\\) => \\{\\r?\\n\\1 {2}proxyReq\\.setHeader\\(\"authorization\", bearer\\);\\r?\\n\\1\\}\\);/m;\n\nfunction exchangeOnlyProxyRequestListener(indent: string): string {\n return `${indent}/* ${PROXY_CREDENTIAL_POLICY_MARKER} */\n${indent}proxy.on(\"proxyReq\", (proxyReq) => {\n${indent} const pathname = new URL(proxyReq.path, \"http://zitadel.local\").pathname;\n${indent} if (\n${indent} proxyReq.method === \"POST\" &&\n${indent} pathname === \"/sessions/exchange\" &&\n${indent} !proxyReq.getHeader(\"authorization\")\n${indent} ) {\n${indent} proxyReq.setHeader(\"authorization\", bearer);\n${indent} }\n${indent}});`;\n}\n\n/**\n * Identifies the exact proxy shape emitted before the exchange-only credential\n * policy. Setup may replace that generated listener, but must preserve the\n * surrounding `/__nextgen` proxy and any user changes elsewhere in the entry.\n */\nfunction isLegacyManagedProxy(source: string): boolean {\n if (source.includes(PROXY_CREDENTIAL_POLICY_MARKER)) {\n return false;\n }\n return [\n 'loadEnv(\"development\", process.cwd(), \"ZITADEL_\").ZITADEL_PROJECT_SECRET',\n 'throw new Error(\"ZITADEL_PROJECT_SECRET is not set; add it to .env.local (zitadel setup writes it).\")',\n \"const bearer = `Bearer ${secret}`;\",\n ].every((fingerprint) => source.includes(fingerprint)) && LEGACY_PROXY_REQUEST_LISTENER.test(source);\n}\n\n/** The imports that the injected proxy entry depends on. */\nconst PROXY_IMPORTS = [{ from: \"vite\", imported: \"loadEnv\", local: \"loadEnv\" }] as const;\n\n/**\n * Builds the pure `edit` transform the file-writer applies to the project's Vite\n * config (`vite.config.*`): a non-destructive magicast merge that adds the\n * `/__nextgen` proxy and sets `server.port`/`strictPort` when they are unset,\n * preserving the user's plugins, options, and formatting. Leaves `server.host`\n * alone so the user can still opt into network binding (`--host`/`host: true`);\n * the issuer/origin requirement is about the port, not the bind host. Idempotent\n * — entries already present are left as-is. Throws `E_VALIDATION` when the file\n * is absent or the config object cannot be reached (function-built/exotic\n * configs), with a hint to add the block manually.\n */\nexport function viteProxyEdit(\n devPort: number,\n server: string,\n): (source: string | undefined) => string {\n return (source) => {\n const label = \"the Vite config (vite.config.*)\";\n let workingSource = source;\n if (workingSource !== undefined && isLegacyManagedProxy(workingSource)) {\n // Replace only the generated bearer listener. User changes elsewhere in\n // the proxy entry (target, rewrite, TLS options, comments) remain intact.\n workingSource = workingSource.replace(\n LEGACY_PROXY_REQUEST_LISTENER,\n (_listener, indent: string) => exchangeOnlyProxyRequestListener(indent),\n );\n } else if (workingSource !== undefined) {\n assertNoUnreviewedProjectSecretProxy(workingSource, label);\n }\n\n const mod = parseConfigModule(workingSource, label);\n const config = resolveDefaultExportObject(mod, label);\n let changed = workingSource !== source;\n const serverConfig = ensureEditableObject(config, \"server\");\n if (serverConfig.port === undefined) {\n serverConfig.port = devPort;\n changed = true;\n }\n if (serverConfig.strictPort === undefined) {\n serverConfig.strictPort = true;\n changed = true;\n }\n const proxyConfig = ensureEditableObject(serverConfig, \"proxy\");\n if (proxyConfig[PROXY_PATH] === undefined) {\n proxyConfig[PROXY_PATH] = builders.raw(proxyEntryCode(server));\n changed = true;\n }\n for (const imp of PROXY_IMPORTS) {\n if (!importIsPresent(mod, imp.local, imp.from)) {\n mod.imports.$add({ ...imp });\n changed = true;\n }\n }\n // Nothing was missing — return the source untouched so the file-writer skips\n // it instead of letting magicast reformat an already-patched config.\n if (!changed && source !== undefined) {\n return source;\n }\n const code = generateCode(mod).code;\n return code.endsWith(\"\\n\") ? code : `${code}\\n`;\n };\n}\n\n/**\n * Candidate Vite config filenames, in resolution priority. The patcher hands\n * this list to the generic `edit` file-op, which patches the first one that\n * exists — so any project layout (`vite.config.ts`, `.mts`, `.js`, …) is covered.\n */\nexport const VITE_CONFIG_PATHS = configCandidates(\"vite.config\");\n\n/**\n * Capability shared by every Vite-based patcher (React, Vue, and any future\n * Vite framework): contributes the file-op that non-destructively merges the\n * `/__nextgen` dev proxy into the project's Vite config. A patcher opts in by\n * declaring `implements ViteSupport` and spreading {@link viteProxyOp} into its\n * `routeOps`, so the proxy logic is written once and reused everywhere — no\n * per-framework duplication.\n */\nexport interface ViteSupport {\n /** The `edit` file-op that merges the `/__nextgen` proxy into the Vite config. */\n viteProxyOp(devPort: number, server: string): FileOp;\n}\n\n/** Builds the shared Vite-config proxy {@link FileOp} for a {@link ViteSupport} patcher. */\nexport function buildViteProxyOp(devPort: number, server: string): FileOp {\n return {\n kind: \"edit\",\n path: [...VITE_CONFIG_PATHS],\n edit: viteProxyEdit(devPort, server),\n // The dev proxy is the auth request path — the doctor managed-files\n // check fails when this merge is no longer applied.\n wiring: \"infrastructure\",\n };\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n/**\n * The managed `src/app.tsx`: a minimal path-based router that renders the\n * `@zitadel/sdk-qwik` widgets — login at `/login`, register at `/register`, and\n * the signed-in session card at `/profile`. The root path redirects to `/login`.\n * Exports a named `App` (`component$`) to match the create-vite Qwik entry\n * (`main.tsx` imports `{ App }`). The project id comes from\n * `VITE_ZITADEL_PROJECT_ID`. No secret reaches the browser: the dev proxy in\n * `vite.config.*` attaches the project service-key secret (from\n * `ZITADEL_PROJECT_SECRET`) server-side only to `POST /sessions/exchange`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the login widgets, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. A plain `locales` prop\n * suffices here: the wrapper component assigns it as a DOM property internally.\n */\nexport function appTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, ZitadelSession, businessLocales, configureZitadel\"\n : \"ZitadelLogin, ZitadelSession, configureZitadel\";\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the locales prop to\n// fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? \" locales={businessLocales}\" : \"\";\n return `${MANAGED_MARKER}\nimport { component$, useVisibleTask$ } from \"@builder.io/qwik\";\nimport { ${importNames} } from \"@zitadel/sdk-qwik\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,\n proxyPath: \"${PROXY_PATH}\",\n});\n\nexport const App = component$(() => {\n const path = window.location.pathname;\n\n useVisibleTask$(() => {\n if (path === \"/\") {\n window.location.replace(\"/login\");\n }\n });\n\n if (path === \"/\") {\n return null;\n }\n if (path.startsWith(\"/profile\")) {\n return (\n <div style={{ position: \"fixed\", inset: \"0\", overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelSession project={project} postSignOutUrl=\"/login\" />\n </div>\n );\n }\n if (path.startsWith(\"/register\")) {\n return (\n <div style={{ position: \"fixed\", inset: \"0\", overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelLogin project={project}${localesAttr} purpose=\"register\" postSignInUrl=\"/profile\" />\n </div>\n );\n }\n return (\n <div style={{ position: \"fixed\", inset: \"0\", overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelLogin project={project}${localesAttr} purpose=\"login\" postSignInUrl=\"/profile\" />\n </div>\n );\n});\n`;\n}\n","import { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { type ViteSupport, buildViteProxyOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-qwik\";\n\n/**\n * Rule-based patcher for a Vite + Qwik single-page app. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * managed `src/app.tsx` auth entry, a non-destructive `vite.config.*` merge\n * that adds the `/__nextgen` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`), the `VITE_`-prefixed\n * project id, and the SDK dep.\n *\n * The create-vite Qwik template uses a lowercase `src/app.tsx` exporting a named\n * `App` (mounted by `main.tsx`), so this patcher writes that exact entry. Unlike\n * Next.js — whose middleware runs the proxy server-side — a SPA has no server,\n * so the dev proxy provides the same-origin `/__nextgen` path locally. In\n * production that path comes from a platform rewrite or minimal worker\n * (ADR 036); CLI scaffolding for it is tracked in issue #560.\n */\nexport class QwikPatcher extends AbstractRulePatcher implements ViteSupport {\n canPatch(framework: string): boolean {\n return framework === \"qwik\";\n }\n\n viteProxyOp(devPort: number, server: string): FileOp {\n return buildViteProxyOp(devPort, server);\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: \"src/app.tsx\", contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n { kind: \"merge-env\", path: \".env.example\", entries: { VITE_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/app.tsx\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Qwik (Vite) integration\",\n detail:\n \"Wrote src/app.tsx auth entry and merged the /__nextgen dev proxy into vite.config.*.\",\n };\n }\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n/**\n * The managed `src/App.tsx`: a minimal path-based router that renders the\n * `@zitadel/sdk-react` widgets — login at `/login`, register at `/register`, and\n * the signed-in session card at `/profile`. The root path redirects to `/login`.\n * The project id comes from `VITE_ZITADEL_PROJECT_ID` (Vite only exposes\n * `VITE_`-prefixed env to the client). No secret reaches the browser: the dev\n * proxy in `vite.config.*` attaches the project service-key secret (from\n * `ZITADEL_PROJECT_SECRET`) server-side only to `POST /sessions/exchange`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the login widgets, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. A plain `locales` prop\n * suffices here: the wrapper component assigns it as a DOM property internally,\n * so the React-18 attribute-decay caveat of the raw custom element does not\n * apply.\n */\nexport function appTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, ZitadelSession, businessLocales, configureZitadel\"\n : \"ZitadelLogin, ZitadelSession, configureZitadel\";\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the locales prop to\n// fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? \" locales={businessLocales}\" : \"\";\n return `${MANAGED_MARKER}\nimport { useEffect } from \"react\";\nimport { ${importNames} } from \"@zitadel/sdk-react\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,\n proxyPath: \"${PROXY_PATH}\",\n});\n\nexport default function App() {\n const path = window.location.pathname;\n\n useEffect(() => {\n if (path === \"/\") {\n window.location.replace(\"/login\");\n }\n }, [path]);\n\n if (path === \"/\") {\n return null;\n }\n if (path.startsWith(\"/profile\")) {\n return (\n <div style={{ position: \"fixed\", inset: 0, overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelSession project={project} postSignOutUrl=\"/login\" />\n </div>\n );\n }\n if (path.startsWith(\"/register\")) {\n return (\n <div style={{ position: \"fixed\", inset: 0, overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelLogin project={project}${localesAttr} purpose=\"register\" postSignInUrl=\"/profile\" />\n </div>\n );\n }\n return (\n <div style={{ position: \"fixed\", inset: 0, overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelLogin project={project}${localesAttr} purpose=\"login\" postSignInUrl=\"/profile\" />\n </div>\n );\n}\n`;\n}\n","import { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { type ViteSupport, buildViteProxyOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-react\";\n\n/**\n * Rule-based patcher for a Vite + React single-page app. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * managed `src/App.tsx` auth entry, a non-destructive `vite.config.*` merge\n * that adds the `/__nextgen` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`), the `VITE_`-prefixed\n * project id, and the SDK dep.\n *\n * Unlike Next.js — whose middleware runs the proxy and token exchange\n * server-side — a SPA has no server, so the dev proxy provides the same-origin\n * `/__nextgen` path locally. In production that path comes from a platform\n * rewrite or minimal worker (ADR 036); CLI scaffolding for it is tracked in\n * issue #560.\n */\nexport class ReactPatcher extends AbstractRulePatcher implements ViteSupport {\n canPatch(framework: string): boolean {\n return framework === \"react\";\n }\n\n viteProxyOp(devPort: number, server: string): FileOp {\n return buildViteProxyOp(devPort, server);\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: \"src/App.tsx\", contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n { kind: \"merge-env\", path: \".env.example\", entries: { VITE_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/App.tsx\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"React (Vite) integration\",\n detail:\n \"Wrote src/App.tsx auth entry and merged the /__nextgen dev proxy into vite.config.*.\",\n };\n }\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n/**\n * The managed `src/App.tsx`: a minimal path-based router that renders the\n * `@zitadel/sdk-solid` widgets — login at `/login`, register at `/register`, and\n * the signed-in session card at `/profile`. The root path redirects to `/login`.\n * The project id comes from `VITE_ZITADEL_PROJECT_ID` (Vite only exposes\n * `VITE_`-prefixed env to the client). No secret reaches the browser: the dev\n * proxy in `vite.config.*` attaches the project service-key secret (from\n * `ZITADEL_PROJECT_SECRET`) server-side only to `POST /sessions/exchange`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the login widgets, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. A plain `locales` prop\n * suffices here: the wrapper component assigns it as a DOM property internally.\n */\nexport function appTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, ZitadelSession, businessLocales, configureZitadel\"\n : \"ZitadelLogin, ZitadelSession, configureZitadel\";\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the locales prop to\n// fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? \" locales={businessLocales}\" : \"\";\n return `${MANAGED_MARKER}\nimport { onMount } from \"solid-js\";\nimport { ${importNames} } from \"@zitadel/sdk-solid\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,\n proxyPath: \"${PROXY_PATH}\",\n});\n\nexport default function App() {\n const path = window.location.pathname;\n\n onMount(() => {\n if (path === \"/\") {\n window.location.replace(\"/login\");\n }\n });\n\n if (path === \"/\") {\n return null;\n }\n if (path.startsWith(\"/profile\")) {\n return (\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelSession project={project} postSignOutUrl=\"/login\" />\n </div>\n );\n }\n if (path.startsWith(\"/register\")) {\n return (\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelLogin project={project}${localesAttr} purpose=\"register\" postSignInUrl=\"/profile\" />\n </div>\n );\n }\n return (\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelLogin project={project}${localesAttr} purpose=\"login\" postSignInUrl=\"/profile\" />\n </div>\n );\n}\n`;\n}\n","import { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { type ViteSupport, buildViteProxyOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-solid\";\n\n/**\n * Rule-based patcher for a Vite + Solid single-page app. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * managed `src/App.tsx` auth entry, a non-destructive `vite.config.*` merge\n * that adds the `/__nextgen` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`), the `VITE_`-prefixed\n * project id, and the SDK dep.\n *\n * Unlike Next.js — whose middleware runs the proxy and token exchange\n * server-side — a SPA has no server, so the dev proxy provides the same-origin\n * `/__nextgen` path locally. In production that path comes from a platform\n * rewrite or minimal worker (ADR 036); CLI scaffolding for it is tracked in\n * issue #560.\n */\nexport class SolidPatcher extends AbstractRulePatcher implements ViteSupport {\n canPatch(framework: string): boolean {\n return framework === \"solid\";\n }\n\n viteProxyOp(devPort: number, server: string): FileOp {\n return buildViteProxyOp(devPort, server);\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: \"src/App.tsx\", contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n { kind: \"merge-env\", path: \".env.example\", entries: { VITE_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/App.tsx\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Solid (Vite) integration\",\n detail:\n \"Wrote src/App.tsx auth entry and merged the /__nextgen dev proxy into vite.config.*.\",\n };\n }\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n/**\n * The managed `src/App.svelte`: a minimal path-based router that renders the\n * `@zitadel/sdk-svelte` widgets — login at `/login`, register at `/register`, and\n * the signed-in session card at `/profile`. The root path redirects to `/login`.\n * The managed marker lives in the `<script lang=\"ts\">` block (a JS comment) so\n * eject/doctor stay marker-aware. The project id comes from\n * `VITE_ZITADEL_PROJECT_ID`. No secret reaches the browser: the dev proxy in\n * `vite.config.*` attaches the project service-key secret (from\n * `ZITADEL_PROJECT_SECRET`) server-side only to `POST /sessions/exchange`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the login widgets, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. A plain `locales` prop\n * suffices here: the wrapper component assigns it as a DOM property internally.\n */\nexport function appTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, ZitadelSession, businessLocales, configureZitadel\"\n : \"ZitadelLogin, ZitadelSession, configureZitadel\";\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the locales prop to\n// fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? \" locales={businessLocales}\" : \"\";\n return `<script lang=\"ts\">\n${MANAGED_MARKER}\nimport { onMount } from \"svelte\";\nimport { ${importNames} } from \"@zitadel/sdk-svelte\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,\n proxyPath: \"${PROXY_PATH}\",\n});\n\nconst path = window.location.pathname;\n\nonMount(() => {\n if (path === \"/\") {\n window.location.replace(\"/login\");\n }\n});\n</script>\n\n{#if path.startsWith(\"/profile\")}\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelSession {project} postSignOutUrl=\"/login\" />\n </div>\n{:else if path.startsWith(\"/register\")}\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelLogin {project}${localesAttr} purpose=\"register\" postSignInUrl=\"/profile\" />\n </div>\n{:else if path !== \"/\"}\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelLogin {project}${localesAttr} purpose=\"login\" postSignInUrl=\"/profile\" />\n </div>\n{/if}\n`;\n}\n","import { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { type ViteSupport, buildViteProxyOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-svelte\";\n\n/**\n * Rule-based patcher for a Vite + Svelte single-page app. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * managed `src/App.svelte` auth entry, a non-destructive `vite.config.*` merge\n * that adds the `/__nextgen` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`), the `VITE_`-prefixed\n * project id, and the SDK dep.\n *\n * Unlike Next.js — whose middleware runs the proxy and token exchange\n * server-side — a SPA has no server, so the dev proxy provides the same-origin\n * `/__nextgen` path locally. In production that path comes from a platform\n * rewrite or minimal worker (ADR 036); CLI scaffolding for it is tracked in\n * issue #560.\n */\nexport class SveltePatcher extends AbstractRulePatcher implements ViteSupport {\n canPatch(framework: string): boolean {\n return framework === \"svelte\";\n }\n\n viteProxyOp(devPort: number, server: string): FileOp {\n return buildViteProxyOp(devPort, server);\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: \"src/App.svelte\", contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n { kind: \"merge-env\", path: \".env.example\", entries: { VITE_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/App.svelte\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Svelte (Vite) integration\",\n detail:\n \"Wrote src/App.svelte auth entry and merged the /__nextgen dev proxy into vite.config.*.\",\n };\n }\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n/**\n * The managed `src/App.vue`: a minimal path-based router that renders the\n * `@zitadel/sdk-vue` widgets — login at `/login`, register at `/register`, and\n * the signed-in session card at `/profile`. The root path redirects to `/login`.\n * The managed marker lives in the `<script setup>` block (a JS comment) so\n * eject/doctor stay marker-aware. The project id comes from\n * `VITE_ZITADEL_PROJECT_ID`. No secret reaches the browser: the dev proxy in\n * `vite.config.*` attaches the project service-key secret (from\n * `ZITADEL_PROJECT_SECRET`) server-side only to `POST /sessions/exchange`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the login widgets, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. A plain `:locales` prop\n * suffices here: the wrapper component assigns it as a DOM property internally.\n */\nexport function appTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, ZitadelSession, businessLocales, configureZitadel\"\n : \"ZitadelLogin, ZitadelSession, configureZitadel\";\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the :locales prop\n// to fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? ' :locales=\"businessLocales\"' : \"\";\n return `<script setup lang=\"ts\">\n${MANAGED_MARKER}\nimport { onMounted } from \"vue\";\nimport { ${importNames} } from \"@zitadel/sdk-vue\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,\n proxyPath: \"${PROXY_PATH}\",\n});\n\nconst path = window.location.pathname;\n\nonMounted(() => {\n if (path === \"/\") {\n window.location.replace(\"/login\");\n }\n});\n</script>\n\n<template>\n <div\n v-if=\"path.startsWith('/profile')\"\n style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\"\n >\n <ZitadelSession :project=\"project\" postSignOutUrl=\"/login\" />\n </div>\n <div\n v-else-if=\"path.startsWith('/register')\"\n style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\"\n >\n <ZitadelLogin :project=\"project\"${localesAttr} purpose=\"register\" postSignInUrl=\"/profile\" />\n </div>\n <div v-else-if=\"path !== '/'\" style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelLogin :project=\"project\"${localesAttr} purpose=\"login\" postSignInUrl=\"/profile\" />\n </div>\n</template>\n`;\n}\n","import { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { type ViteSupport, buildViteProxyOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-vue\";\n\n/**\n * Rule-based patcher for a Vite + Vue single-page app. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * managed `src/App.vue` auth entry, a non-destructive `vite.config.*` merge\n * that adds the `/__nextgen` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`), the `VITE_`-prefixed\n * project id, and the SDK dep.\n */\nexport class VuePatcher extends AbstractRulePatcher implements ViteSupport {\n canPatch(framework: string): boolean {\n return framework === \"vue\";\n }\n\n viteProxyOp(devPort: number, server: string): FileOp {\n return buildViteProxyOp(devPort, server);\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: \"src/App.vue\", contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n { kind: \"merge-env\", path: \".env.example\", entries: { VITE_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/App.vue\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Vue (Vite) integration\",\n detail:\n \"Wrote src/App.vue auth entry and merged the /__nextgen dev proxy into vite.config.*.\",\n };\n }\n}\n","import { AngularPatcher } from \"./rule/angular\";\nimport { NextPatcher } from \"./rule/next\";\nimport { NuxtPatcher } from \"./rule/nuxt\";\nimport { QwikPatcher } from \"./rule/qwik\";\nimport { ReactPatcher } from \"./rule/react\";\nimport { SolidPatcher } from \"./rule/solid\";\nimport { SveltePatcher } from \"./rule/svelte\";\nimport { VuePatcher } from \"./rule/vue\";\nimport type { Patcher } from \"./types\";\n\n/**\n * Active patchers, in priority order; the first whose `canPatch` matches wins.\n *\n * Patchers are grouped by family under subdirectories: `rule/` holds the\n * deterministic, template-driven patchers (extending\n * {@link import(\"./rule/base\").AbstractRulePatcher}). A future LLM-driven\n * family lives under `llm/` and registers its concrete patchers here — no\n * orchestrator or command changes needed. Only Next.js is supported today.\n */\nexport const patchers = [\n new NextPatcher(),\n new NuxtPatcher(),\n new ReactPatcher(),\n new VuePatcher(),\n new SolidPatcher(),\n new SveltePatcher(),\n new QwikPatcher(),\n new AngularPatcher(),\n] as const satisfies ReadonlyArray<Patcher>;\n","import { spawnSync } from \"node:child_process\";\n\nimport { ZitadelError } from \"../../errors\";\nimport type { Scaffolder } from \"./types\";\n\n/**\n * Base for scaffolders that delegate to an external CLI (e.g. create-next-app).\n * Subclasses implement {@link scaffold} and call {@link runCommand}.\n */\nexport abstract class AbstractCLIScaffolder implements Scaffolder {\n abstract readonly displayName: string;\n abstract readonly supportedFrameworks: ReadonlyArray<string>;\n\n /** True when the requested framework is in {@link supportedFrameworks}. */\n canScaffold(framework: string): boolean {\n return this.supportedFrameworks.includes(framework);\n }\n\n abstract scaffold(cwd: string, framework: string): Promise<void>;\n\n /**\n * Runs an external command in `cwd`, throwing a typed {@link ZitadelError} on\n * failure so the cause surfaces as a categorized CLI error. Distinguishes\n * \"binary not on PATH\" (`ENOENT` from the spawn itself) from \"binary ran but\n * exited non-zero\" — the former previously got masked as a generic\n * `exited with status 1`, leaving users to guess. Tests stub\n * `node:child_process` to assert the command without spawning.\n */\n protected runCommand(command: string, args: ReadonlyArray<string>, cwd: string): void {\n const result = spawnSync(command, [...args], { cwd, encoding: \"utf8\" });\n if (result.error) {\n const err = result.error as NodeJS.ErrnoException;\n const notFound = err.code === \"ENOENT\";\n throw new ZitadelError(\n \"E_VALIDATION\",\n notFound ? `Command not found: ${command}` : `Failed to spawn \"${command}\": ${err.message}`,\n {\n hint: notFound ? `Ensure '${command}' is installed and on PATH.` : undefined,\n details: { command, args: [...args], code: err.code },\n },\n );\n }\n const status = result.status ?? 1;\n if (status !== 0) {\n const stdout = String(result.stdout ?? \"\");\n const stderr = String(result.stderr ?? \"\");\n const output = truncateCommandOutput([stderr, stdout].filter(Boolean).join(\"\\n\").trim());\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Command \"${command} ${args.join(\" \")}\" exited with status ${String(status)}`,\n {\n hint: output ? `Command output:\\n${output}` : \"Run the command directly for more detail.\",\n details: { command, args: [...args], cwd, stdout, stderr },\n },\n );\n }\n }\n}\n\nfunction truncateCommandOutput(output: string): string {\n const limit = 4000;\n if (output.length <= limit) {\n return output;\n }\n return `${output.slice(0, limit)}\\n... output truncated ...`;\n}\n","import { rm } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Derives a valid Angular project name from the target directory. `ng new`\n * validates the name against `^[a-zA-Z0-9-~][a-zA-Z0-9-._~]*$` and rejects `.`,\n * so we slugify the directory's basename (lowercase, non-alphanumerics → `-`)\n * and guarantee a leading letter by prefixing `app-` when the slug does not\n * start with one (`app-zitadel` when the basename slugifies to nothing).\n */\nfunction angularProjectName(cwd: string): string {\n const slug = basename(cwd)\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return /^[a-z]/.test(slug) ? slug : `app-${slug || \"zitadel\"}`;\n}\n\n/**\n * Scaffolds a new Angular app with the Angular CLI, then removes the starter\n * `app.ts`/`app.html` root component (and its now-unreferenced `app.css`) so the\n * patcher can write the managed ones without colliding with boilerplate. The\n * managed component uses only `templateUrl`, so `app.css` would otherwise be a\n * dangling file eject never cleans up. Unlike `create-vite`/`nuxi`, `ng new`\n * needs a real project name plus `--directory .` to populate the current dir.\n * Requires a Node version Angular supports (^22.22.3 || ^24.15.0 || >=26).\n */\nexport class AngularScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Angular\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"angular\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npx\",\n [\n \"-y\",\n \"@angular/cli@latest\",\n \"new\",\n angularProjectName(cwd),\n \"--directory\",\n \".\",\n \"--defaults\",\n \"--style=css\",\n \"--ssr=false\",\n \"--skip-git\",\n ],\n cwd,\n );\n await rm(join(cwd, \"src/app/app.ts\"), { force: true });\n await rm(join(cwd, \"src/app/app.html\"), { force: true });\n await rm(join(cwd, \"src/app/app.css\"), { force: true });\n }\n}\n","import { AbstractCLIScaffolder } from \"./cli\";\n\nconst CREATE_NEXT_APP_VERSION = \"16.2.4\";\n\n/** Scaffolds a new Next.js App Router project with `create-next-app`. */\nexport class NextScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Next.js\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"next\"];\n\n /**\n * Runs the pinned `create-next-app` version in `cwd`, creating a TypeScript\n * App Router project in place. `--yes` accepts all defaults so the command\n * runs unattended, and `--skip-install` leaves dependency installation to the\n * setup command's explicit next step after Zitadel patches package.json.\n */\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npx\",\n [\n \"--yes\",\n `create-next-app@${CREATE_NEXT_APP_VERSION}`,\n \".\",\n \"--ts\",\n \"--app\",\n \"--use-npm\",\n \"--disable-git\",\n \"--yes\",\n \"--skip-install\",\n ],\n cwd,\n );\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Nuxt app with `nuxi init`, then removes the starter `app.vue`\n * so the patcher can write the managed one without colliding with boilerplate.\n * Nuxt 4 (what `nuxi init` scaffolds today) puts it under `app/`; older Nuxt put\n * it at the root, so both are removed. `nuxt.config.ts` is left in place — the\n * patcher merges into it via an `edit`, which preserves whatever `nuxi` generated.\n */\nexport class NuxtScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Nuxt\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"nuxt\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npx\",\n [\n \"-y\",\n \"nuxi@latest\",\n \"init\",\n \".\",\n \"--template\",\n \"minimal\",\n \"--packageManager\",\n \"npm\",\n \"--no-gitInit\",\n \"--force\",\n ],\n cwd,\n );\n await rm(join(cwd, \"app/app.vue\"), { force: true });\n await rm(join(cwd, \"app.vue\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Vite + Qwik (TypeScript) single-page app with `create-vite`,\n * then removes the starter `app.tsx`/`app.css` demo so the patcher can write the\n * managed `src/app.tsx` without colliding with boilerplate. The create-vite Qwik\n * template uses a lowercase `app.tsx` (named `App` export, mounted by `main.tsx`)\n * — the patched file keeps that same entry.\n */\nexport class QwikScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Qwik (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"qwik\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"qwik-ts\"], cwd);\n await rm(join(cwd, \"src/app.tsx\"), { force: true });\n await rm(join(cwd, \"src/app.css\"), { force: true });\n // create-vite's Qwik template pairs qwik 1.x with vite 8, but qwik 1.x peers\n // vite \">=5 <8\", so a bare `npm install` fails with ERESOLVE. Pin vite to v7\n // (what @zitadel/sdk-qwik builds against) so the generated app installs.\n this.runCommand(\"npm\", [\"pkg\", \"set\", \"devDependencies.vite=^7.3.5\"], cwd);\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Vite + React (TypeScript) single-page app with `create-vite`,\n * then removes the starter `App.tsx`/`App.css` demo so the patcher can write the\n * managed `src/App.tsx` without colliding with boilerplate. `index.css` and\n * `main.tsx` are left in place — the patched `App.tsx` keeps the same entry.\n */\nexport class ReactScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"React (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"react\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"react-ts\"], cwd);\n await rm(join(cwd, \"src/App.tsx\"), { force: true });\n await rm(join(cwd, \"src/App.css\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Vite + Solid (TypeScript) single-page app with `create-vite`,\n * then removes the starter `App.tsx`/`App.css` demo so the patcher can write the\n * managed `src/App.tsx` without colliding with boilerplate. `index.css` and\n * `index.tsx` are left in place — the patched `App.tsx` keeps the same entry.\n */\nexport class SolidScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Solid (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"solid\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"solid-ts\"], cwd);\n await rm(join(cwd, \"src/App.tsx\"), { force: true });\n await rm(join(cwd, \"src/App.css\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Vite + Svelte (TypeScript) single-page app with `create-vite`,\n * then removes the starter `App.svelte`/`lib/Counter.svelte` demo so the patcher\n * can write the managed `src/App.svelte` without colliding with boilerplate.\n * `app.css` and `main.ts` are left in place — the patched `App.svelte` keeps the\n * same entry.\n */\nexport class SvelteScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Svelte (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"svelte\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"svelte-ts\"], cwd);\n await rm(join(cwd, \"src/App.svelte\"), { force: true });\n await rm(join(cwd, \"src/lib/Counter.svelte\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Vite + Vue (TypeScript) single-page app with `create-vite`,\n * then removes the starter `App.vue`/`components/HelloWorld.vue` demo so the\n * patcher can write the managed `src/App.vue` without colliding with boilerplate.\n */\nexport class VueScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Vue (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"vue\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"vue-ts\"], cwd);\n await rm(join(cwd, \"src/App.vue\"), { force: true });\n await rm(join(cwd, \"src/components/HelloWorld.vue\"), { force: true });\n }\n}\n","import { AngularScaffolder } from \"./angular\";\nimport { NextScaffolder } from \"./next\";\nimport { NuxtScaffolder } from \"./nuxt\";\nimport { QwikScaffolder } from \"./qwik\";\nimport { ReactScaffolder } from \"./react\";\nimport { SolidScaffolder } from \"./solid\";\nimport { SvelteScaffolder } from \"./svelte\";\nimport { VueScaffolder } from \"./vue\";\nimport type { Scaffolder } from \"./types\";\n\n/**\n * Active scaffolders, in priority order. The framework picker derives its\n * choices from this list. Add a new framework by appending its scaffolder\n * here — no orchestrator changes needed.\n */\nexport const scaffolders = [\n new NextScaffolder(),\n new NuxtScaffolder(),\n new ReactScaffolder(),\n new VueScaffolder(),\n new SolidScaffolder(),\n new SvelteScaffolder(),\n new QwikScaffolder(),\n new AngularScaffolder(),\n] as const satisfies ReadonlyArray<Scaffolder>;\n","import { mkdir, readdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\n\nimport { ZitadelError } from \"../errors\";\nimport { detectors } from \"./detectors\";\nimport type { Detector, FrameworkFacts } from \"./detectors/types\";\nimport { patchers } from \"./patchers\";\nimport type { Patcher } from \"./patchers/types\";\nimport { scaffolders } from \"./scaffolders\";\nimport type { Scaffolder } from \"./scaffolders/types\";\n\nexport type { Detector, FrameworkFacts } from \"./detectors/types\";\nexport { issuerFromPort } from \"./detectors/port\";\n\n/** One framework the CLI can scaffold from scratch, surfaced to the picker. */\nexport type FrameworkChoice = Readonly<{ id: string; displayName: string }>;\n\nexport type ScaffoldTarget = Readonly<{\n scaffoldable: boolean;\n hasGitignore: boolean;\n hasRuntimeOnlyZitadel: boolean;\n reason?: string;\n entries: ReadonlyArray<string>;\n}>;\n\ntype ScaffoldStash = Readonly<{\n gitignore?: string;\n root: string;\n zitadel?: string;\n}>;\n\n/**\n * Orchestrates the three per-framework strategies — detectors (recognise an\n * existing project and extract its facts), scaffolders (create a project), and\n * patchers (integrate Zitadel) — over their respective registries. It resolves\n * the right strategy for a framework and drives the detect/scaffold lifecycle;\n * how a patcher applies its work (file operations vs an LLM agent) stays\n * internal to that patcher. Registries are injected so tests can supply fakes.\n */\nexport class Orca {\n constructor(\n private readonly detectors: ReadonlyArray<Detector>,\n private readonly scaffolders: ReadonlyArray<Scaffolder>,\n private readonly patchers: ReadonlyArray<Patcher>,\n ) {}\n\n /**\n * Detects the framework in `cwd` and extracts its {@link FrameworkFacts},\n * honouring an explicit `requested` framework. Throws\n * `E_FRAMEWORK_NOT_DETECTED` when nothing matches; a detector's\n * `E_UNSUPPORTED_PROJECT_SHAPE` (recognised but unsupported) propagates.\n */\n async detect(cwd: string, requested?: string): Promise<FrameworkFacts> {\n const candidates = requested\n ? this.detectors.filter((detector) => detector.framework === requested)\n : this.detectors;\n if (requested && candidates.length === 0) {\n throw new ZitadelError(\"E_FRAMEWORK_NOT_DETECTED\", `Unsupported framework \"${requested}\"`, {\n hint: `Supported frameworks: ${this.frameworkIds().join(\", \")}.`,\n });\n }\n for (const detector of candidates) {\n const facts = await detector.detect(cwd);\n if (facts) {\n return facts;\n }\n }\n throw new ZitadelError(\n \"E_FRAMEWORK_NOT_DETECTED\",\n \"Could not detect a supported app framework\",\n {\n hint: \"Run setup from your app project directory, pass --cwd <path-to-app>, or run setup from an empty directory to scaffold a new app.\",\n },\n );\n }\n\n /**\n * Non-throwing detection: returns `undefined` instead of raising for a\n * project that is absent, unrecognised, or recognised-but-unsupported, so\n * callers (e.g. `eject`) can probe and degrade gracefully.\n */\n async tryDetect(cwd: string): Promise<FrameworkFacts | undefined> {\n try {\n return await this.detect(cwd);\n } catch (error) {\n if (\n error instanceof ZitadelError &&\n (error.code === \"E_FRAMEWORK_NOT_DETECTED\" || error.code === \"E_UNSUPPORTED_PROJECT_SHAPE\")\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n /** Whether `cwd` is safe for an in-place framework scaffold. */\n async isFreshScaffoldTarget(cwd: string): Promise<boolean> {\n return (await inspectScaffoldTarget(cwd)).scaffoldable;\n }\n\n /**\n * Creates a new `framework` project in `cwd`, then re-detects it to return\n * the resulting {@link FrameworkFacts}. Throws `E_CONFLICT` when the directory\n * already contains a project (\"already scaffolded\") and `E_VALIDATION` when no\n * scaffolder supports the framework.\n */\n async scaffold(cwd: string, framework: string): Promise<FrameworkFacts> {\n const target = await inspectScaffoldTarget(cwd);\n if (!target.scaffoldable) {\n throw new ZitadelError(\"E_CONFLICT\", `Cannot scaffold: ${cwd} is not empty`, {\n hint:\n target.reason ??\n \"Run setup in an empty directory, or run setup from an existing supported app project.\",\n details: { entries: target.entries },\n });\n }\n assertNpmSafeScaffoldDirectoryName(cwd);\n const stash = await stashFreshScaffoldArtifacts(cwd, target);\n try {\n await this.scaffolderFor(framework).scaffold(cwd, framework);\n } finally {\n await restoreFreshScaffoldArtifacts(cwd, stash);\n }\n return this.detect(cwd, framework);\n }\n\n /**\n * Resolves the scaffolder for a framework, throwing `E_VALIDATION` (with the\n * available list) when none matches.\n */\n scaffolderFor(framework: string): Scaffolder {\n const scaffolder = this.scaffolders.find((candidate) => candidate.canScaffold(framework));\n if (!scaffolder) {\n throw new ZitadelError(\"E_VALIDATION\", `No scaffolder supports \"${framework}\"`, {\n hint: `Available frameworks: ${this.availableFrameworks()\n .map((f) => f.id)\n .join(\", \")}.`,\n });\n }\n return scaffolder;\n }\n\n /**\n * Resolves the patcher for a framework, throwing `E_VALIDATION` when none\n * matches (e.g. a framework that can be scaffolded but not yet integrated).\n */\n patcherFor(framework: string): Patcher {\n const patcher = this.patchers.find((candidate) => candidate.canPatch(framework));\n if (!patcher) {\n throw new ZitadelError(\"E_VALIDATION\", `No patcher supports \"${framework}\"`, {\n hint: \"Zitadel integration currently supports Next.js.\",\n });\n }\n return patcher;\n }\n\n /** The frameworks that can be scaffolded, derived from the scaffolder registry. */\n availableFrameworks(): ReadonlyArray<FrameworkChoice> {\n return this.scaffolders.map((scaffolder) => ({\n id: scaffolder.supportedFrameworks[0] ?? scaffolder.displayName,\n displayName: scaffolder.displayName,\n }));\n }\n\n private frameworkIds(): ReadonlyArray<string> {\n return this.detectors.map((detector) => detector.framework);\n }\n}\n\nfunction assertNpmSafeScaffoldDirectoryName(cwd: string): void {\n const name = basename(cwd);\n const errors = npmPackageNameErrors(name);\n if (errors.length === 0) {\n return;\n }\n\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Fresh app directory name \"${name}\" is not npm-package-safe`,\n {\n hint:\n \"Rename the directory to a lowercase npm-package-safe name, for example `my-zitadel-app`, then rerun setup.\",\n details: { cwd, name, validation_errors: errors },\n },\n );\n}\n\nfunction npmPackageNameErrors(name: string): string[] {\n // This local preflight catches common package-name failures before the\n // scaffolder mutates disk; framework generators still own stricter checks.\n const errors: string[] = [];\n if (name.length === 0) {\n errors.push(\"name is empty\");\n }\n if (name.length > 214) {\n errors.push(\"name is longer than 214 characters\");\n }\n if (name !== name.trim()) {\n errors.push(\"name contains leading or trailing whitespace\");\n }\n if (/[A-Z]/.test(name)) {\n errors.push(\"name can no longer contain capital letters\");\n }\n if (name.startsWith(\".\") || name.startsWith(\"_\")) {\n errors.push(\"name cannot start with a period or underscore\");\n }\n if (!/^[a-z0-9][a-z0-9._~-]*$/.test(name)) {\n errors.push(\"name may only contain lowercase letters, numbers, dots, underscores, tildes, and hyphens\");\n }\n if (name === \"node_modules\" || name === \"favicon.ico\") {\n errors.push(`name \"${name}\" is reserved`);\n }\n return [...new Set(errors)];\n}\n\n/** {@link Orca} wired with the default detector, scaffolder, and patcher registries. */\nexport function createOrca(): Orca {\n return new Orca(detectors, scaffolders, patchers);\n}\n\nexport async function inspectScaffoldTarget(cwd: string): Promise<ScaffoldTarget> {\n const entries = await readdir(cwd, { withFileTypes: true });\n const names = entries.map((entry) => entry.name).sort();\n let hasGitignore = false;\n let hasRuntimeOnlyZitadel = false;\n\n for (const entry of entries) {\n if (entry.name === \".gitignore\") {\n if (!entry.isFile()) {\n return {\n scaffoldable: false,\n hasGitignore: false,\n hasRuntimeOnlyZitadel: false,\n reason: \".gitignore exists but is not a file.\",\n entries: names,\n };\n }\n hasGitignore = true;\n continue;\n }\n\n if (entry.name === \".zitadel\") {\n if (!entry.isDirectory() || !(await isRuntimeOnlyZitadelDir(join(cwd, \".zitadel\")))) {\n return {\n scaffoldable: false,\n hasGitignore,\n hasRuntimeOnlyZitadel: false,\n reason:\n \".zitadel contains project state. Move it aside or run setup from an empty app directory.\",\n entries: names,\n };\n }\n hasRuntimeOnlyZitadel = true;\n continue;\n }\n\n return {\n scaffoldable: false,\n hasGitignore,\n hasRuntimeOnlyZitadel: false,\n reason: `Directory contains ${entry.name}. Run setup from an empty directory to scaffold a new app.`,\n entries: names,\n };\n }\n\n return { scaffoldable: true, hasGitignore, hasRuntimeOnlyZitadel, entries: names };\n}\n\nasync function isRuntimeOnlyZitadelDir(path: string): Promise<boolean> {\n const entries = await readdir(path, { withFileTypes: true });\n if (entries.length !== 1 || entries[0]?.name !== \"local\" || !entries[0].isDirectory()) {\n return false;\n }\n return true;\n}\n\nasync function stashFreshScaffoldArtifacts(\n cwd: string,\n target: ScaffoldTarget,\n): Promise<ScaffoldStash | undefined> {\n if (!target.hasGitignore && !target.hasRuntimeOnlyZitadel) {\n return undefined;\n }\n\n const parent = dirname(cwd);\n const root = join(\n parent,\n `.${basename(cwd)}.fresh-scaffold-stash-${String(process.pid)}-${String(Date.now())}`,\n );\n await mkdir(root, { mode: 0o700 });\n\n const stash: { gitignore?: string; root: string; zitadel?: string } = { root };\n if (target.hasRuntimeOnlyZitadel) {\n stash.zitadel = join(root, \".zitadel\");\n await rename(join(cwd, \".zitadel\"), stash.zitadel);\n }\n if (target.hasGitignore) {\n stash.gitignore = join(root, \".gitignore\");\n await rename(join(cwd, \".gitignore\"), stash.gitignore);\n }\n return stash;\n}\n\nasync function restoreFreshScaffoldArtifacts(\n cwd: string,\n stash: ScaffoldStash | undefined,\n): Promise<void> {\n if (!stash) {\n return;\n }\n\n try {\n await restoreRuntimeOnlyZitadel(cwd, stash.zitadel);\n await restoreGitignore(cwd, stash.gitignore);\n } finally {\n await rm(stash.root, { recursive: true, force: true });\n }\n}\n\nasync function restoreRuntimeOnlyZitadel(cwd: string, stash: string | undefined): Promise<void> {\n if (!stash) {\n return;\n }\n\n const target = join(cwd, \".zitadel\");\n try {\n await rename(stash, target);\n await appendGitignoreEntry(cwd, \".zitadel/local/\");\n return;\n } catch (error) {\n if (!isErrno(error, \"EEXIST\")) {\n throw error;\n }\n }\n\n await mkdir(target, { recursive: true, mode: 0o700 });\n await rename(join(stash, \"local\"), join(target, \"local\"));\n await rm(stash, { recursive: true, force: true });\n await appendGitignoreEntry(cwd, \".zitadel/local/\");\n}\n\nasync function restoreGitignore(cwd: string, stash: string | undefined): Promise<void> {\n if (!stash) {\n return;\n }\n\n const path = join(cwd, \".gitignore\");\n const stashed = await readFile(stash, \"utf8\");\n let current = \"\";\n try {\n current = await readFile(path, \"utf8\");\n } catch (error) {\n if (!isErrno(error, \"ENOENT\")) {\n throw error;\n }\n }\n\n const existingLines = new Set(\n current\n .split(/\\r?\\n/g)\n .map((line) => line.trim())\n .filter(Boolean),\n );\n const missingLines = stashed\n .split(/\\r?\\n/g)\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !existingLines.has(line));\n if (missingLines.length === 0) {\n return;\n }\n\n const prefix = current.length === 0 || current.endsWith(\"\\n\") ? \"\" : \"\\n\";\n await writeFile(path, `${current}${prefix}${missingLines.join(\"\\n\")}\\n`);\n}\n\nasync function appendGitignoreEntry(cwd: string, entry: string): Promise<void> {\n const path = join(cwd, \".gitignore\");\n let existing = \"\";\n try {\n existing = await readFile(path, \"utf8\");\n } catch (error) {\n if (!isErrno(error, \"ENOENT\")) {\n throw error;\n }\n }\n\n const lines = existing.split(/\\r?\\n/g).map((line) => line.trim());\n if (lines.includes(entry)) {\n return;\n }\n const prefix = existing.length === 0 || existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n await writeFile(path, `${existing}${prefix}${entry}\\n`);\n}\n\nfunction isErrno(error: unknown, code: string): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === code\n );\n}\n"],"mappings":"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"}