@zitadel/cli 0.1.0-alpha.9 → 0.2.0

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 (49) hide show
  1. package/README.md +4043 -229
  2. package/bin/run.js +8 -0
  3. package/dist/index.mjs +24173 -0
  4. package/dist/index.mjs.map +1 -0
  5. package/dist/lib/oclif/help.mjs +117 -0
  6. package/dist/lib/oclif/help.mjs.map +1 -0
  7. package/dist/skills-hint-CBoak9HL.mjs +4348 -0
  8. package/dist/skills-hint-CBoak9HL.mjs.map +1 -0
  9. package/oclif.manifest.json +8635 -253
  10. package/package.json +106 -15
  11. package/skills/zitadel-cli/SKILL.md +538 -0
  12. package/skills/zitadel-cli/references/driving-login-ui.md +109 -0
  13. package/SKILLS.md +0 -157
  14. package/dist/commands/apply.mjs +0 -62
  15. package/dist/commands/apply.mjs.map +0 -1
  16. package/dist/commands/doctor.mjs +0 -569
  17. package/dist/commands/doctor.mjs.map +0 -1
  18. package/dist/commands/eject.mjs +0 -145
  19. package/dist/commands/eject.mjs.map +0 -1
  20. package/dist/commands/logs.mjs +0 -58
  21. package/dist/commands/logs.mjs.map +0 -1
  22. package/dist/commands/plan.mjs +0 -52
  23. package/dist/commands/plan.mjs.map +0 -1
  24. package/dist/commands/reset.mjs +0 -79
  25. package/dist/commands/reset.mjs.map +0 -1
  26. package/dist/commands/setup.mjs +0 -856
  27. package/dist/commands/setup.mjs.map +0 -1
  28. package/dist/commands/start.mjs +0 -288
  29. package/dist/commands/start.mjs.map +0 -1
  30. package/dist/commands/status.mjs +0 -112
  31. package/dist/commands/status.mjs.map +0 -1
  32. package/dist/commands/stop.mjs +0 -105
  33. package/dist/commands/stop.mjs.map +0 -1
  34. package/dist/docker-CnGQK3ZK.mjs +0 -432
  35. package/dist/docker-CnGQK3ZK.mjs.map +0 -1
  36. package/dist/docker-guidance-ypN3IM3o.mjs +0 -21
  37. package/dist/docker-guidance-ypN3IM3o.mjs.map +0 -1
  38. package/dist/oclif-B7lBzh3R.mjs +0 -808
  39. package/dist/oclif-B7lBzh3R.mjs.map +0 -1
  40. package/dist/orca-U142Wrau.mjs +0 -2556
  41. package/dist/orca-U142Wrau.mjs.map +0 -1
  42. package/dist/ports-B09RjuHx.mjs +0 -111
  43. package/dist/ports-B09RjuHx.mjs.map +0 -1
  44. package/dist/processes-Cw8TO1SY.mjs +0 -120
  45. package/dist/processes-Cw8TO1SY.mjs.map +0 -1
  46. package/dist/project-Cd0L3PtM.mjs +0 -87
  47. package/dist/project-Cd0L3PtM.mjs.map +0 -1
  48. package/dist/sync-BojoQm2P.mjs +0 -733
  49. package/dist/sync-BojoQm2P.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["request","fetchWithPolicy","REQUEST_TIMEOUT_MS","errorMessage","readEnvFile","isErrno","sleep","isErrno","unique","isErrno","isErrno","delay","DEFAULT_SERVER","consola","DEFAULT_SERVER","text","exists","DEFAULT_SERVER","SECRET_KEYS","isErrno","askInput","isErrno","isErrno","nodeSpawn","sleep","COLUMNS","dirExists","readIfExists","exists","readTextIfExists","DEFAULT_SERVER","isFile","HOST_KEEPING_ENTRY","forwardAppOrigin","SDK_DEPENDENCY","ROOT","indexPageTemplate","authPage","loginPageTemplate","registerPageTemplate","profilePageTemplate","SDK_DEPENDENCY","indexPageTemplate","loginPageTemplate","registerPageTemplate","profilePageTemplate","VITE_CONFIG_PATHS","appTemplate","SDK_DEPENDENCY","ROOT","appTemplate","WIDGET_WRAP","indexPageTemplate","authPage","loginPageTemplate","registerPageTemplate","profilePageTemplate","SDK_DEPENDENCY","COMPONENT_DEPENDENCY","indexPageTemplate","loginPageTemplate","registerPageTemplate","profilePageTemplate","appTemplate","SDK_DEPENDENCY","ROOT","appTemplate","appTemplate","SDK_DEPENDENCY","ROOT","appTemplate","WIDGET_WRAP","indexPageTemplate","authPage","loginPageTemplate","registerPageTemplate","profilePageTemplate","SDK_DEPENDENCY","COMPONENT_DEPENDENCY","indexPageTemplate","loginPageTemplate","registerPageTemplate","profilePageTemplate","appTemplate","SDK_DEPENDENCY","ROOT","appTemplate","SDK_DEPENDENCY","SDK_DEPENDENCY","pathExists","exists","resolveRuntimeBackend","DEFAULT_SERVER","COLUMNS","COLUMNS","COLUMNS","fieldsOf","COLUMNS","DEFAULT_SERVER","relativeDisplay","isErrno","stylePath","styleUrl","styleId","COLUMNS"],"sources":["../src/lib/oclif/crud/zod.ts","../src/lib/oclif/crud/document.ts","../src/lib/oclif/crud/assign.ts","../src/lib/oclif/crud/fields.ts","../src/lib/api/operations.ts","../src/lib/api/request.ts","../src/lib/api/call.ts","../src/lib/api/curl.ts","../src/lib/oclif/flags.ts","../src/lib/local-server/processes.ts","../src/lib/paths.ts","../src/lib/prober/ports.ts","../src/lib/local-server/docker-guidance.ts","../src/lib/local-server/env-vars.ts","../src/lib/local-server/runtime.ts","../src/lib/local-server/internal/clock.ts","../src/lib/local-server/internal/lifecycle.ts","../src/lib/local-server/internal/docker-launcher.ts","../src/lib/local-server/internal/failures.ts","../src/lib/local-server/internal/binary-launcher.ts","../src/lib/local-server/internal/start-lock.ts","../src/lib/local-server/internal/probes.ts","../src/lib/local-server/internal/store.ts","../src/lib/local-server/server-log.ts","../src/lib/local-server/server.ts","../src/lib/server.ts","../src/lib/telemetry/dimensions/ci-flag.ts","../src/lib/telemetry/config.ts","../src/lib/telemetry/util.ts","../src/lib/telemetry/vercel.ts","../src/lib/telemetry/index.ts","../src/lib/telemetry/dimensions/country.ts","../src/lib/telemetry/dimensions/invocation-channel.ts","../src/lib/telemetry/dimensions/operating-system.ts","../src/lib/oclif/server-kind.ts","../src/lib/oclif/command-telemetry.ts","../src/lib/shell.ts","../src/lib/oclif/base.ts","../src/lib/input.ts","../src/lib/fs-safe.ts","../src/lib/project.ts","../src/lib/environment.ts","../src/lib/oclif/credentials.ts","../src/lib/oclif/environment-flags.ts","../src/lib/oclif/environment-command.ts","../src/lib/idp/callback.ts","../src/lib/auth-methods.ts","../src/lib/sync/state.ts","../src/lib/schema-flows.ts","../src/lib/oclif/envelope.ts","../src/lib/oclif/promptable.ts","../src/lib/oclif/auth-method-command.ts","../src/commands/api/index.ts","../src/lib/oclif/crud/table.ts","../src/commands/api/ls.ts","../src/commands/auth-method/passkey/disable.ts","../src/commands/auth-method/passkey/enable.ts","../src/commands/auth-method/password/disable.ts","../src/commands/auth-method/password/enable.ts","../src/commands/auth-method/sso/disable.ts","../src/lib/build-channel.ts","../src/commands/auth-method/sso/enable.ts","../src/lib/branding/designs.ts","../src/lib/meta-schemas.ts","../src/lib/release/release.ts","../src/lib/release/pipeline.ts","../src/lib/release/origins.ts","../src/commands/branding/eject.ts","../src/lib/browser.ts","../src/lib/claim-state.ts","../src/commands/claim.ts","../src/lib/local-server/admin-credential.ts","../src/lib/local-server/sign-in.ts","../src/commands/console.ts","../src/lib/origins.ts","../src/commands/deploy.ts","../src/commands/deployment/create.ts","../src/commands/deployment/get.ts","../src/commands/deployment/list.ts","../src/commands/deployment/rollback.ts","../src/lib/orca/detectors/package-json.ts","../src/lib/orca/detectors/port.ts","../src/lib/orca/detectors/version-floor.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/qwik-router.ts","../src/lib/orca/detectors/react.ts","../src/lib/orca/detectors/solid.ts","../src/lib/orca/detectors/solid-start.ts","../src/lib/orca/detectors/svelte.ts","../src/lib/orca/detectors/sveltekit.ts","../src/lib/orca/detectors/tanstack-start.ts","../src/lib/orca/detectors/vue.ts","../src/lib/orca/detectors/index.ts","../src/lib/orca/patchers/rule/dev-port-move.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/root-component.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/session-cookie.ts","../src/lib/orca/patchers/rule/utils/line-ends.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/public-project-id.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/qwik-router/templates.ts","../src/lib/orca/patchers/rule/qwik-router/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/solid-start/vite-config.ts","../src/lib/orca/patchers/rule/solid-start/templates.ts","../src/lib/orca/patchers/rule/solid-start/index.ts","../src/lib/orca/patchers/rule/svelte/templates.ts","../src/lib/orca/patchers/rule/svelte/index.ts","../src/lib/orca/patchers/rule/sveltekit/env-vars.ts","../src/lib/orca/patchers/rule/sveltekit/templates.ts","../src/lib/orca/patchers/rule/sveltekit/index.ts","../src/lib/orca/patchers/rule/tanstack-start/templates.ts","../src/lib/orca/patchers/rule/tanstack-start/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/node-engines.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/remove-install.ts","../src/lib/orca/scaffolders/qwik-router.ts","../src/lib/orca/scaffolders/react.ts","../src/lib/orca/scaffolders/solid.ts","../src/lib/orca/scaffolders/solid-start.ts","../src/lib/orca/scaffolders/svelte.ts","../src/lib/orca/scaffolders/sveltekit.ts","../src/lib/orca/scaffolders/tanstack-start.ts","../src/lib/orca/scaffolders/vue.ts","../src/lib/orca/scaffolders/index.ts","../src/lib/orca/index.ts","../src/commands/doctor/checks/types.ts","../src/commands/doctor/checks/config.ts","../src/commands/doctor/checks/secret.ts","../src/commands/doctor/checks/secret-permissions.ts","../src/commands/doctor/checks/gitignore.ts","../src/commands/doctor/checks/env-example.ts","../src/commands/doctor/checks/framework.ts","../src/lib/scaffold-manifest.ts","../src/commands/doctor/patch-context.ts","../src/commands/doctor/checks/managed-files.ts","../src/commands/doctor/checks/dependency.ts","../src/lib/package-manager.ts","../src/commands/doctor/checks/dependency-version.ts","../src/commands/doctor/checks/meta-schemas.ts","../src/commands/doctor/checks/project-match.ts","../src/commands/doctor/checks/issuer-origin.ts","../src/commands/doctor/checks/schema.ts","../src/commands/doctor/checks/claim.ts","../src/commands/doctor/checks/index.ts","../src/commands/doctor/index.ts","../src/commands/eject.ts","../src/commands/env/index.ts","../src/commands/env/add.ts","../src/commands/env/list.ts","../src/commands/logs.ts","../src/lib/oclif/crud/secrets.ts","../src/lib/oclif/crud/shared.ts","../src/commands/origin/add.ts","../src/commands/origin/list.ts","../src/commands/origin/rm.ts","../src/lib/preview.ts","../src/lib/ttl.ts","../src/commands/preview/index.ts","../src/commands/preview/list.ts","../src/commands/preview/rm.ts","../src/lib/sync/writeback.ts","../src/commands/pull.ts","../src/commands/release/create.ts","../src/commands/release/revoke.ts","../src/commands/reset.ts","../src/lib/oclif/crud/ops/command.ts","../src/lib/oclif/crud/ops/delete.ts","../src/lib/oclif/crud/wire.ts","../src/lib/oclif/crud/query.ts","../src/lib/oclif/crud/paths.ts","../src/lib/oclif/crud/columns.ts","../src/lib/oclif/crud/ops/list.ts","../src/lib/oclif/crud/ops/read.ts","../src/lib/oclif/crud/body.ts","../src/lib/oclif/crud/ops/write.ts","../src/lib/oclif/crud/describe.ts","../src/lib/oclif/crud/index.ts","../src/commands/resources.ts","../src/commands/resources-list.ts","../src/lib/local-server/claim-as-admin.ts","../src/lib/orca/patchers/posture.ts","../src/lib/setup-resources.ts","../src/commands/setup/install.ts","../src/commands/setup/move-dev-port.ts","../src/commands/setup/prompts/dev-port.ts","../src/commands/setup/prompts/framework-confirm.ts","../src/commands/setup/prompts/password-policy.ts","../src/commands/setup/prompts/server.ts","../src/commands/setup/prompts/sign-in-preset.ts","../src/commands/setup/prompts/social-sign-in.ts","../src/commands/setup/prompts/use-case.ts","../src/commands/setup/prompts/types.ts","../src/commands/setup/prompts/pick-framework.ts","../src/commands/setup/prompts/index.ts","../src/commands/setup/summary.ts","../src/commands/setup/index.ts","../src/commands/start.ts","../src/commands/status.ts","../src/commands/stop.ts","../src/commands/variable/get.ts","../src/commands/variable/list.ts","../src/commands/variable/resolve.ts","../src/commands/variable/rm.ts","../src/commands/variable/set.ts","../src/index.ts"],"sourcesContent":["/**\n * The slice of a generated Zod schema's internals the command factory reads.\n *\n * The generated schemas are values, not types, and the factory needs to walk\n * them to learn a request's fields and a response's shape. Zod's own internal\n * types are not part of its public API, so this is the minimum structural\n * description of what is actually touched — declared once because both the\n * field reader and the path walker need it, and a second copy would drift.\n */\nexport type ZodLike = {\n def?: {\n type?: string;\n /** The wrapped schema of `optional`, `default`, `nullable`, … */\n innerType?: ZodLike;\n /** The element schema of an array. */\n element?: ZodLike;\n /** The members of a union. */\n options?: readonly ZodLike[];\n /** The halves of an intersection. */\n left?: ZodLike;\n right?: ZodLike;\n /** The value schema of a record. */\n valueType?: ZodLike;\n /** What a `default` fills in when the field is left out. */\n defaultValue?: unknown;\n /** The values of a literal. */\n values?: readonly unknown[];\n /** A number's format: `safeint` for an integer. */\n format?: string;\n /** Refinements; an integer written as `number().int()` carries a `number_format` one. */\n checks?: readonly { _zod?: { def?: { check?: string; format?: string } } }[];\n };\n shape?: Record<string, ZodLike>;\n /** The allowed values of an enum. */\n options?: readonly string[];\n description?: string;\n /** Whether a body may leave the value out, as Zod itself decides. */\n isOptional?: () => boolean;\n};\n\n/**\n * Depth limit for peeling wrappers. A generated schema nests a handful at\n * most (`optional` around `default` around `nullable`); the limit exists so a\n * malformed or self-referential schema cannot spin rather than because a real\n * one comes close to it.\n */\nconst MAX_WRAPPER_DEPTH = 10;\n\n/**\n * Peel the wrappers a generated schema puts around a field, so the caller sees\n * the type that decides how the field is rendered rather than the `optional`\n * that happens to enclose it.\n */\nexport const unwrap = (\n schema: ZodLike | undefined,\n depth = MAX_WRAPPER_DEPTH,\n): ZodLike | undefined =>\n schema?.def?.innerType && depth > 0 ? unwrap(schema.def.innerType, depth - 1) : schema;\n\n/** The wrappers around a field, outermost first, the field's own type last. */\nconst layers = (schema: ZodLike | undefined): ZodLike[] => {\n const found: ZodLike[] = [];\n for (let current = schema; current && found.length <= MAX_WRAPPER_DEPTH; ) {\n found.push(current);\n current = current.def?.innerType;\n }\n return found;\n};\n\n/**\n * Whether a body may leave the field out: it is `optional`, or carries a\n * `default` the schema fills in. A `nullable` field is still required; it only\n * accepts `null` as its value.\n */\nexport const isOptionalField = (field: ZodLike | undefined): boolean =>\n typeof field?.isOptional === \"function\"\n ? field.isOptional()\n : layers(field).some((layer) => [\"optional\", \"default\"].includes(layer.def?.type ?? \"\"));\n\n/** The value the schema fills in for a field left out, when it has one. */\nexport const defaultOf = (field: ZodLike | undefined): { value: unknown } | undefined => {\n const layer = layers(field).find((candidate) => candidate.def?.type === \"default\");\n return layer ? { value: layer.def?.defaultValue } : undefined;\n};\n\n/** Whether a number schema only takes integers. */\nexport const isInteger = (schema: ZodLike | undefined): boolean => {\n const type = unwrap(schema);\n return (\n (type?.def?.format ?? \"\").includes(\"int\") ||\n (type?.def?.checks ?? []).some(\n (check) =>\n check._zod?.def?.check === \"number_format\" && (check._zod.def.format ?? \"\").includes(\"int\"),\n )\n );\n};\n\n/**\n * The object a field holds, to walk into: a plain object, or the object of a\n * field that is either that object or `null` (a clearable one, such as a\n * project's `password_hash`). Anything else — a scalar, a record, a union of\n * several objects — has no fixed fields to walk.\n */\nexport const objectOf = (schema: ZodLike | undefined): ZodLike | undefined => {\n const type = unwrap(schema);\n if (type?.def?.type === \"object\" && type.shape) {\n return type;\n }\n if (type?.def?.type !== \"union\") {\n return undefined;\n }\n const members = (type.def.options ?? []).map((member) => unwrap(member));\n const objects = members.filter((member) => member?.def?.type === \"object\" && member.shape);\n const nulls = members.filter((member) => member?.def?.type === \"null\");\n return objects.length === 1 && objects.length + nulls.length === members.length\n ? objects[0]\n : undefined;\n};\n\n/** One field of an object schema, never a property inherited from `Object.prototype`. */\nexport const fieldOf = (schema: ZodLike | undefined, key: string): ZodLike | undefined => {\n const shape = objectOf(schema)?.shape;\n return shape && Object.hasOwn(shape, key) ? shape[key] : undefined;\n};\n\n/**\n * What a schema says about the value at one path into a document. `node` is\n * the schema at the path; `open` says the path runs through an open record (a\n * user's `attributes`), below which the API spec names no keys, so any key is\n * legal and `node` is whatever the record says of its values — often nothing.\n */\nexport type PathNode = Readonly<{ node: ZodLike | undefined; open: boolean }>;\n\n/**\n * Follow a path into a document's schema. Returns `undefined` when the path\n * names a field the schema does not have, or runs on past a value that has no\n * fields of its own.\n */\nexport const nodeAt = (\n schema: ZodLike | undefined,\n path: readonly string[],\n): PathNode | undefined => {\n let node = schema;\n let open = false;\n for (const segment of path) {\n const type = unwrap(node);\n if (objectOf(type)) {\n const field = fieldOf(type, segment);\n if (!field) {\n return undefined;\n }\n node = field;\n } else if (type?.def?.type === \"record\") {\n node = type.def.valueType;\n open = true;\n } else if (open && (!type || type.def?.type === \"any\" || type.def?.type === \"unknown\")) {\n // Below an open record whose values the spec leaves untyped: any key.\n node = undefined;\n } else {\n return undefined;\n }\n }\n return { node, open };\n};\n","import { ZitadelError } from \"../../errors\";\nimport { isObject } from \"../../json\";\nimport type { Json } from \"./types\";\nimport { isInteger, unwrap, type ZodLike } from \"./zod\";\n\n/**\n * The document a write assembles before it sends anything (ADR 071 §1), and\n * the few operations every source of it needs: reading a path, assigning one,\n * laying one source over another, and turning the text a command line carries\n * into the value the schema declares.\n */\n\n/** The value at a path, or `undefined` when a segment on the way is missing. */\nexport const valueAt = (document: unknown, path: readonly string[]): unknown =>\n path.reduce<unknown>(\n (current, segment) =>\n isObject(current) && Object.hasOwn(current, segment) ? current[segment] : undefined,\n document,\n );\n\n/**\n * A copy of `document` holding `value` at `path`. Objects missing on the way\n * are created, and a value in the way (a string, `null`) is replaced: the\n * assignment is the more specific instruction.\n */\nexport const setAt = (document: Json, path: readonly string[], value: unknown): Json => {\n const [head, ...rest] = path;\n if (head === undefined) {\n return document;\n }\n if (rest.length === 0) {\n return { ...document, [head]: value };\n }\n const child = Object.hasOwn(document, head) ? document[head] : undefined;\n return { ...document, [head]: setAt(isObject(child) ? child : {}, rest, value) };\n};\n\n/**\n * `overlay` laid over `base`: objects merge key by key at every depth, and any\n * other value — an array, a scalar, `null` — replaces what was there. That is\n * how one JSON Merge Patch composes with another (RFC 7396), so a flag over\n * `--file` changes the one key it names instead of the object around it, and\n * on an update a `null` still reaches the server, which removes the key.\n */\nexport const mergeDocuments = (base: unknown, overlay: unknown): unknown => {\n if (!isObject(base) || !isObject(overlay)) {\n return overlay;\n }\n const keys = [...new Set([...Object.keys(base), ...Object.keys(overlay)])];\n return Object.fromEntries(\n keys.map((key) => [\n key,\n !Object.hasOwn(overlay, key)\n ? base[key]\n : Object.hasOwn(base, key)\n ? mergeDocuments(base[key], overlay[key])\n : overlay[key],\n ]),\n );\n};\n\n/**\n * A refusal for a path or key that names `__proto__`. That name reads as an\n * object's prototype rather than as one of its keys, and the schema check\n * drops a value set under it without a word, so it is refused where it is\n * typed. `label` is how the caller spelled the entry (`--set attributes.x`).\n */\nexport const refuseProtoKey = (segments: readonly string[], label: string): void => {\n if (segments.includes(\"__proto__\")) {\n throw new ZitadelError(\"E_VALIDATION\", `${label} names __proto__, which no body can carry`, {\n hint: \"__proto__ is read as an object's prototype rather than as a key, so a value set there would be dropped.\",\n });\n }\n};\n\n/**\n * A number as a person writes one: digits, an optional minus and, where the\n * number need not be whole, a fraction (`3`, `-12`, `1.5`). `Number()` alone\n * would also read `0x10` as 16, `1e3` as 1000 and `\" 12 \"` as 12, which a\n * field typed as a number should not get by surprise; `:=` takes any JSON\n * number. The integer rule is the one oclif's own integer flag applies.\n */\nconst INTEGER = /^-?\\d+$/;\nconst DECIMAL = /^-?\\d+(?:\\.\\d+)?$/;\n\n/** The finite number `text` spells in decimal notation, or `undefined` when it spells none. */\nexport const decimalValue = (text: string, integer: boolean): number | undefined => {\n const value = (integer ? INTEGER : DECIMAL).test(text) ? Number(text) : Number.NaN;\n return Number.isFinite(value) ? value : undefined;\n};\n\n/** Whether a schema accepts the text itself, so no reading of it is needed. */\nconst takesText = (schema: ZodLike | undefined): boolean =>\n [\"string\", \"enum\", \"any\", \"unknown\", undefined].includes(unwrap(schema)?.def?.type);\n\n/**\n * A refusal for text that does not fit the schema. `label` is how the caller\n * spelled the value's place (`--set oidc.pkce_enabled`, `--attributes age`),\n * so the error can offer the JSON form of the same entry.\n */\nconst misfit = (label: string, text: string, expected: string): ZitadelError =>\n new ZitadelError(\"E_VALIDATION\", `${label} expects ${expected}, got \"${text}\"`, {\n hint: `Give ${expected}, or a JSON value with ${label}:=<json>.`,\n });\n\n/** The scalar `text` stands for under one schema, or the error saying why it does not fit. */\nconst scalarFrom = (schema: ZodLike | undefined, text: string, label: string): unknown => {\n const type = unwrap(schema);\n switch (type?.def?.type) {\n case \"number\": {\n const integer = isInteger(type);\n return (\n decimalValue(text, integer) ?? misfit(label, text, integer ? \"an integer\" : \"a number\")\n );\n }\n case \"boolean\":\n return text === \"true\"\n ? true\n : text === \"false\"\n ? false\n : misfit(label, text, \"true or false\");\n case \"null\":\n return text === \"null\" ? null : misfit(label, text, \"null\");\n case \"union\": {\n const members = type.def?.options ?? [];\n if (members.some(takesText)) {\n return text;\n }\n const readings = members.map((member) => scalarFrom(member, text, label));\n return readings.find((reading) => !(reading instanceof ZitadelError)) ?? readings[0];\n }\n default:\n return text;\n }\n};\n\n/**\n * The value `text` stands for, at a field the schema declares as `schema`.\n *\n * ADR 064 §6 made `key=value` always a string, because the CLI could not know\n * a field's type, and guessing turns a postal code into a number. Where the\n * schema declares the type, nothing is guessed: a field typed as a number or a\n * boolean reads the text as one (`pkce_enabled=false` is the boolean), and a\n * field that accepts a string, or that the schema says nothing about, keeps\n * the text, so `postcode=02139` survives (ADR 071 §3) and on a `string | null`\n * field `null` is the text \"null\" (`:=null` is the null). A number is read in\n * decimal notation only. A value that does not fit is refused, pointing at the\n * JSON form.\n */\nexport const typedValue = (schema: ZodLike | undefined, text: string, label: string): unknown => {\n const value = scalarFrom(schema, text, label);\n if (value instanceof ZitadelError) {\n throw value;\n }\n return value;\n};\n\n/** `text` read as JSON for the entry `label`, or an error that offers the plain form. */\nexport const jsonValue = (text: string, label: string): unknown => {\n try {\n return JSON.parse(text) as unknown;\n } catch {\n throw new ZitadelError(\"E_VALIDATION\", `${label}:= expects JSON, got \"${text}\"`, {\n hint: `Quote a JSON value, e.g. ${label}:=30, ${label}:=true, or ${label}:='{\"a\":1}'. For a plain string use ${label}=${text}.`,\n });\n }\n};\n","import { ZitadelError } from \"../../errors\";\nimport { jsonValue, refuseProtoKey, setAt, typedValue } from \"./document\";\nimport type { BodyField } from \"./fields\";\nimport type { Json } from \"./types\";\nimport { nodeAt, unwrap, type ZodLike } from \"./zod\";\n\n/**\n * `--set <path>=<value>` and `--set <path>:=<json>` (ADR 071 §3): one field of\n * the document by its dot path, the path language `--fields` already speaks.\n * A field flag is the documented spelling of one path; `--set` is the general\n * one, in the wire's own names, so a key read from `get --json` can be typed\n * back as it is, and a field no flag can carry is still reachable. `zitadel\n * api` reads its `--field` with the same grammar, so the readers take the flag\n * they report errors under.\n */\n\n/** One `--set` entry, read and checked. */\nexport type Assignment = Readonly<{\n /** The path as typed (`oidc.client_id`). */\n name: string;\n path: readonly string[];\n value: unknown;\n /** The entry as it came in, for errors. */\n raw: string;\n}>;\n\nconst usage = (flag: string): string =>\n `Use ${flag} path=value, or ${flag} path:=json for a JSON value (e.g. ${flag} oidc.pkce_enabled=false).`;\n\n/** The fields worth naming to a caller whose path does not exist. */\nconst knownPaths = (fields: readonly BodyField[], first: string): readonly string[] => {\n const all = fields.map((field) => (field.kind === \"record\" ? `${field.name}.<key>` : field.name));\n const near = all.filter((path) => path === first || path.startsWith(`${first}.`));\n return near.length > 0 ? near : all;\n};\n\n/** What an assignment's plain form can hold at a path, or why it cannot. */\nconst plainValue = (\n node: ZodLike | undefined,\n text: string,\n name: string,\n fields: readonly BodyField[],\n label: string,\n): unknown => {\n const type = unwrap(node)?.def?.type;\n const shape =\n type === \"array\" ? \"a list\" : type === \"object\" || type === \"record\" ? \"an object\" : undefined;\n if (shape) {\n const flag = fields.find((field) => field.name === name)?.flag;\n throw new ZitadelError(\"E_VALIDATION\", `${label} ${name} names ${shape}, which takes JSON`, {\n hint: `Set it whole with ${label} '${name}:=<json>'${flag ? `, or give --${flag} once per value` : \"\"}.`,\n });\n }\n return typedValue(node, text, `${label} ${name}`);\n};\n\n/**\n * Read one `--set` entry against the document's schema. With no schema to\n * check against (one the factory cannot introspect), any path is taken and a\n * plain value stays a string. `label` is the flag the entry came with.\n */\nexport const readAssignment = (\n raw: string,\n document: ZodLike | undefined,\n fields: readonly BodyField[],\n label = \"--set\",\n): Assignment => {\n const json = raw.indexOf(\":=\");\n const plain = raw.indexOf(\"=\");\n const isJson = json > 0 && json === plain - 1;\n const at = isJson ? json : plain;\n if (at <= 0) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid ${label} \"${raw}\"`, { hint: usage(label) });\n }\n const name = raw.slice(0, at);\n const text = raw.slice(at + (isJson ? 2 : 1));\n const path = name.split(\".\");\n if (path.some((segment) => segment === \"\")) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid ${label} path \"${name}\"`, {\n hint: usage(label),\n });\n }\n refuseProtoKey(path, `${label} ${name}`);\n const located = document === undefined ? { node: undefined, open: true } : nodeAt(document, path);\n if (!located) {\n const paths = knownPaths(fields, path[0] ?? \"\");\n throw new ZitadelError(\"E_VALIDATION\", `${label} ${name} names no field of this body`, {\n hint: `Fields: ${paths.join(\", \")}.`,\n details: { field: name, fields: paths },\n });\n }\n return {\n name,\n path,\n value: isJson\n ? jsonValue(text, `${label} ${name}`)\n : plainValue(located.node, text, name, fields, label),\n raw,\n };\n};\n\n/** Every `--set` entry of an invocation, in the order given. */\nexport const readAssignments = (\n entries: unknown,\n document: ZodLike | undefined,\n fields: readonly BodyField[],\n): readonly Assignment[] =>\n (Array.isArray(entries) ? entries : entries === undefined ? [] : [entries]).map((entry) =>\n readAssignment(String(entry), document, fields),\n );\n\n/** An assignment as the fragment of a document it describes. */\nexport const fragmentOf = (assignment: Assignment): Json =>\n setAt({}, assignment.path, assignment.value);\n","import { Flags, type Interfaces } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../../errors\";\nimport { decimalValue, jsonValue, refuseProtoKey, setAt, typedValue } from \"./document\";\nimport type { Json, Schema } from \"./types\";\nimport {\n defaultOf,\n fieldOf,\n isInteger,\n isOptionalField,\n objectOf,\n unwrap,\n type ZodLike,\n} from \"./zod\";\n\n/**\n * Body fields as CLI flags. A registry entry already carries the generated\n * request schema, and that schema knows every field's name, type, whether it\n * is required, and its allowed values — so `create` and `update` expose one\n * flag per field instead of only a raw `--data '{…}'` blob.\n *\n * Every leaf gets one, nested ones too (ADR 071 §2): a field's flag is its\n * path with each segment kebab-cased, joined with `-`, so `oidc.client_id` is\n * `--oidc-client-id`. A list of scalars is a repeatable flag, an open record (a\n * user's `attributes`) a repeatable `key=value` one. What no single flag can\n * hold — an array of objects, a union of several shapes — has no flag and is\n * reached through `--set` or the whole document.\n *\n * Introspection is defensive: an unrecognised schema yields no fields, and\n * the command falls back to `--set` and the raw-body flags alone.\n */\n\n/** How a field is given on the command line. `json` has no flag of its own. */\nexport type FieldKind =\n | \"string\"\n | \"number\"\n | \"integer\"\n | \"boolean\"\n | \"enum\"\n | \"list\"\n | \"record\"\n | \"json\";\n\nexport type BodyField = Readonly<{\n /** Dot path of the field in the document (`oidc.client_id`); the wire name at the top level. */\n name: string;\n /** The same path, segment by segment, as the wire spells it. */\n path: readonly string[];\n /** Flag name as typed (`oidc-client-id`); absent when no flag can carry the field. */\n flag?: string;\n kind: FieldKind;\n /** Whether every body carries it: required in its object, and every object around it too. */\n required: boolean;\n /**\n * The optional object that makes this field required once it is given at\n * all: `[\"oidc\"]` for `oidc.issuer`, which only a connection with an `oidc`\n * block must carry.\n */\n requiredWith?: readonly string[];\n /** Closed value set, for an `enum` field or a list of one. */\n options?: readonly string[];\n /** What a `list` holds. */\n item?: \"string\" | \"number\" | \"integer\" | \"enum\";\n /** What the schema fills in when the field is left out. */\n default?: { value: unknown };\n /** One-line summary of the schema's description, used as flag help. */\n summary: string;\n /** The field's own schema, which types the text the command line gives it. */\n node: ZodLike;\n}>;\n\n/**\n * Flags a write command owns, or every command does; a body field whose flag\n * would be one of these gets none, and stays reachable through `--set`.\n */\nconst RESERVED = new Set([\n \"data\",\n \"file\",\n \"set\",\n \"json\",\n \"help\",\n \"version\",\n \"force\",\n \"cwd\",\n \"server\",\n \"env\",\n \"env-file\",\n \"non-interactive\",\n \"dry-run\",\n \"verbose\",\n \"debug\",\n \"color\",\n \"no-color\",\n \"telemetry\",\n \"no-telemetry\",\n]);\n\n/**\n * How deep the walk goes. Generated request schemas nest two or three levels;\n * the limit keeps a self-referential schema from spinning, and anything below\n * it is still reachable through `--set`.\n */\nconst MAX_DEPTH = 6;\n\nconst kebab = (name: string): string => name.replaceAll(\"_\", \"-\");\n\n/**\n * One-line flag help from a schema description: newlines collapsed, the first\n * sentence kept, and long prose trimmed at a word boundary so `--help` stays a\n * table rather than a paragraph.\n */\nconst summarize = (description: string | undefined): string => {\n const text = (description ?? \"\").replaceAll(/\\s+/g, \" \").trim();\n const sentence = /^(.+?\\.)(?:\\s|$)/.exec(text)?.[1] ?? text;\n if (sentence.length <= 110) {\n return sentence;\n }\n const clipped = sentence.slice(0, 110);\n return `${clipped.slice(0, clipped.lastIndexOf(\" \"))}…`;\n};\n\ntype Classified = Pick<BodyField, \"kind\" | \"options\" | \"item\">;\n\n/** How a leaf of a given type is given on the command line. */\nconst classify = (type: ZodLike | undefined): Classified => {\n switch (type?.def?.type) {\n case \"string\":\n return { kind: \"string\" };\n case \"number\":\n return { kind: isInteger(type) ? \"integer\" : \"number\" };\n case \"boolean\":\n return { kind: \"boolean\" };\n case \"enum\":\n return { kind: \"enum\", ...(type.options ? { options: type.options } : {}) };\n case \"record\":\n return { kind: \"record\" };\n case \"array\": {\n const element = classify(unwrap(type.def.element));\n return element.kind === \"string\" ||\n element.kind === \"number\" ||\n element.kind === \"integer\" ||\n element.kind === \"enum\"\n ? {\n kind: \"list\",\n item: element.kind,\n ...(element.options ? { options: element.options } : {}),\n }\n : { kind: \"json\" };\n }\n case \"union\": {\n // A string that may be `null` (a clearable field) reads as a plain string\n // flag; clearing it is `--set <path>:=null`.\n const members = (type.def.options ?? []).map((member) => unwrap(member));\n const values = members.filter((member) => member?.def?.type !== \"null\");\n return values.length === 1 && values[0]?.def?.type === \"string\"\n ? { kind: \"string\" }\n : { kind: \"json\" };\n }\n default:\n return { kind: \"json\" };\n }\n};\n\n/** A leaf before its flag is settled, which needs every other leaf's. */\ntype Leaf = Omit<BodyField, \"flag\">;\n\n/**\n * The leaves below one object. `chainRequired` says whether every object\n * around this one is required; `optionalAncestor` is the innermost one that is\n * not. A leaf required within the objects below it is required exactly when\n * that object is given: the objects around it are then given too, and the ones\n * between it and the leaf are required.\n */\nconst leavesOf = (\n object: ZodLike,\n prefix: readonly string[],\n chainRequired: boolean,\n optionalAncestor: readonly string[] | undefined,\n): Leaf[] =>\n Object.entries(object.shape ?? {}).flatMap(([key, field]): Leaf[] => {\n const path = [...prefix, key];\n const requiredHere = !isOptionalField(field);\n const required = chainRequired && requiredHere;\n const nested = objectOf(field);\n if (nested?.shape && Object.keys(nested.shape).length > 0 && path.length < MAX_DEPTH) {\n return leavesOf(nested, path, required, requiredHere ? optionalAncestor : path);\n }\n const inner = unwrap(field);\n const fallback = defaultOf(field);\n return [\n {\n name: path.join(\".\"),\n path,\n ...classify(inner),\n required,\n ...(requiredHere && !chainRequired && optionalAncestor\n ? { requiredWith: optionalAncestor }\n : {}),\n ...(fallback ? { default: fallback } : {}),\n summary: summarize(field.description ?? inner?.description),\n node: field,\n },\n ];\n });\n\n/** The flag a leaf would get, before collisions are settled. */\nconst candidateFlag = (leaf: Leaf): string | undefined =>\n leaf.kind === \"json\" ? undefined : leaf.path.map(kebab).join(\"-\");\n\n/** The flag names a leaf occupies: its own, and `--no-<flag>` for a boolean. */\nconst occupied = (leaf: Leaf, flag: string): string[] =>\n leaf.kind === \"boolean\" ? [flag, `no-${flag}`] : [flag];\n\n/**\n * Give each leaf its flag. Two leaves that would share a name, or a name the\n * command already owns, both go without, so neither silently shadows the\n * other; they stay reachable through `--set`.\n */\nconst settleFlags = (leaves: readonly Leaf[], reserved: ReadonlySet<string>): BodyField[] => {\n const uses = new Map<string, number>();\n for (const leaf of leaves) {\n const flag = candidateFlag(leaf);\n for (const name of flag ? occupied(leaf, flag) : []) {\n uses.set(name, (uses.get(name) ?? 0) + 1);\n }\n }\n return leaves.map((leaf) => {\n const flag = candidateFlag(leaf);\n const free =\n flag !== undefined &&\n occupied(leaf, flag).every(\n (name) => uses.get(name) === 1 && !RESERVED.has(name) && !reserved.has(name),\n );\n return free ? { ...leaf, flag } : leaf;\n });\n};\n\n/** What a write command's body is described from. */\nexport type DescribeOptions = Readonly<{\n /**\n * Property the document sits under in the request body (`idp`). The fields\n * are then the document's own, which is how every other surface — a file\n * under `.zitadel/`, `get --json` — spells the resource.\n */\n root?: string;\n /** Flags the command declares beyond the factory's own, which a field must not take. */\n reserved?: Iterable<string>;\n}>;\n\n/** The schema of the document a write sends: the body, or the part of it under `root`. */\nexport const documentSchemaOf = (schema: Schema, root?: string): ZodLike | undefined =>\n root === undefined ? (schema as ZodLike) : fieldOf(schema as ZodLike, root);\n\n/**\n * Read the fields of a generated request schema, nested ones included.\n * Returns an empty list for anything that is not an object schema, so the\n * caller degrades to `--set` and `--data` / `--file`.\n */\nexport const describeBody = (\n schema: Schema,\n options: DescribeOptions = {},\n): readonly BodyField[] => {\n const document = objectOf(documentSchemaOf(schema, options.root));\n if (!document) {\n return [];\n }\n return settleFlags(leavesOf(document, [], true, undefined), new Set(options.reserved ?? []));\n};\n\n/**\n * A float flag; oclif's own number flag only takes integers. It reads decimal\n * notation, as `--set` does, so `0x10` is refused rather than read as 16.\n */\nconst numberFlag = Flags.custom<number>({\n parse: async (input) => {\n const value = decimalValue(input, false);\n if (value === undefined) {\n throw new Error(`Expected a number but received: ${input}`);\n }\n return value;\n },\n});\n\n/**\n * The help group a field is listed under. A top-level field is grouped by\n * whether it is required; a nested one by the object it belongs to, so the\n * `oidc` fields of a connection read as one block.\n */\nconst helpGroupOf = (field: BodyField): string => {\n if (field.path.length === 1) {\n return field.required ? \"REQUIRED FIELD\" : \"OPTIONAL FIELD\";\n }\n return `${(field.path[0] ?? \"\").replaceAll(\"_\", \" \").toUpperCase()} FIELD`;\n};\n\n/** The oclif flag for one field. */\nconst flagFor = (field: BodyField): Interfaces.FlagInput[string] => {\n // oclif orders help groups by their first flag alphabetically, so the\n // required marker also rides in the description rather than relying on the\n // group heading coming first.\n const description = [\n field.required\n ? \"(required)\"\n : field.requiredWith\n ? `(required with ${field.requiredWith.join(\".\")}.*)`\n : \"\",\n field.kind === \"record\"\n ? `Repeatable ${field.name} entry: key=value for a string, key:=value for JSON.`\n : \"\",\n field.kind === \"list\" ? \"Repeatable, one value each.\" : \"\",\n field.summary,\n ]\n .filter(Boolean)\n .join(\" \");\n const common = { description, helpGroup: helpGroupOf(field) };\n const options = field.options ? { options: [...field.options] } : {};\n switch (field.kind) {\n case \"boolean\":\n return Flags.boolean({ ...common, allowNo: true });\n case \"integer\":\n return Flags.integer(common);\n case \"number\":\n return numberFlag(common);\n case \"record\":\n return Flags.string({ ...common, multiple: true });\n case \"list\":\n return field.item === \"integer\"\n ? Flags.integer({ ...common, multiple: true })\n : field.item === \"number\"\n ? numberFlag({ ...common, multiple: true })\n : Flags.string({ ...common, ...options, multiple: true });\n default:\n return Flags.string({ ...common, ...options });\n }\n};\n\n/** oclif flags for the given fields; a field without a flag is left to `--set`. */\nexport const bodyFieldFlags = (fields: readonly BodyField[]): Interfaces.FlagInput =>\n Object.fromEntries(\n fields.flatMap((field) => (field.flag === undefined ? [] : [[field.flag, flagFor(field)]])),\n );\n\n/**\n * Build the document fragment the field flags describe, nesting each value at\n * its path. Returns `undefined` when no field flag was given, so the caller\n * can tell \"no body at all\" from \"a body made of flags\".\n */\nexport const bodyFromFlags = (fields: readonly BodyField[], flags: Json): Json | undefined => {\n let body: Json | undefined;\n for (const field of fields) {\n const value = field.flag === undefined ? undefined : flags[field.flag];\n if (value === undefined || field.flag === undefined) {\n continue;\n }\n body = setAt(body ?? {}, field.path, field.kind === \"record\" ? recordOf(field, value) : value);\n }\n return body;\n};\n\n/** The object a repeatable record flag's entries make. */\nconst recordOf = (field: BodyField, value: unknown): Json => {\n const values = unwrap(field.node)?.def?.valueType;\n const entries = (Array.isArray(value) ? value : [value]).map((entry) =>\n parsePair(String(entry), field.flag ?? field.name, values),\n );\n return Object.fromEntries(entries);\n};\n\n/**\n * One entry of a repeatable record flag.\n *\n * `key:=value` parses the value as JSON. `key=value` is the value as the\n * record's schema types it (ADR 071 §3): text where its values may be strings\n * or are untyped — a user's `attributes`, so an identifier that looks numeric\n * (a postal code, a phone number) survives — and a number or a boolean where\n * the schema declares nothing else. The split is HTTPie's, and keeping the two\n * explicit means the CLI never has to guess which one was meant.\n */\nconst parsePair = (\n raw: string,\n flag: string,\n values: ZodLike | undefined,\n): readonly [string, unknown] => {\n const json = raw.indexOf(\":=\");\n const plain = raw.indexOf(\"=\");\n if (json > 0 && json === plain - 1) {\n const key = raw.slice(0, json);\n refuseProtoKey([key], `--${flag} ${key}`);\n return [key, jsonValue(raw.slice(json + 2), `--${flag} ${key}`)];\n }\n if (plain <= 0) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid --${flag} \"${raw}\"`, {\n hint: `Use --${flag} key=value for a string, or key:=value for JSON (e.g. --${flag} age:=30).`,\n });\n }\n const key = raw.slice(0, plain);\n refuseProtoKey([key], `--${flag} ${key}`);\n return [key, typedValue(values, raw.slice(plain + 1), `--${flag} ${key}`)];\n};\n\n/**\n * Whether a run made of required flags alone may still be an incomplete body.\n * A nested object can carry rules the required list cannot — a grant names\n * exactly one of `user` and `team` — and a field without a flag cannot be\n * given that way at all. Such a command offers no generated flags-only\n * example; its registry entry may declare one that is complete.\n */\nexport const flagsAloneMayBeIncomplete = (fields: readonly BodyField[]): boolean =>\n fields.some((field) => field.path.length > 1 || field.flag === undefined);\n\n/** One example invocation using the required fields, for a command's `examples`. */\nexport const fieldExample = (fields: readonly BodyField[]): string | undefined => {\n const required = fields.filter((field) => field.required);\n if (required.length === 0 || required.some((field) => field.flag === undefined)) {\n return undefined;\n }\n return required\n .map((field) =>\n field.kind === \"record\"\n ? `--${field.flag} <key>=<value>`\n : `--${field.flag} ${field.options ? field.options[0] : `<${field.name}>`}`,\n )\n .join(\" \");\n};\n","import { type ApiOperation, operations } from \"@zitadel/api/generated/operations\";\n\nimport { ZitadelError } from \"../errors\";\nimport { unscopedCommand } from \"../suggestion\";\n\nexport type { ApiOperation };\n\n/** Every operation of the API the CLI was built with. */\nexport const OPERATIONS: readonly ApiOperation[] = operations;\n\n/** What `zitadel api` was pointed at, before any value is read. */\nexport type Target = Readonly<{\n operation: ApiOperation;\n /** Path parameters the path form spelled out (`/users/user_01…`), by name. */\n pathValues: Readonly<Record<string, string>>;\n /** The query string the path form carried (`/users?team_id=…`). */\n query: URLSearchParams;\n}>;\n\nconst LIST = unscopedCommand(\"api ls --json\");\n\n/**\n * Why the CLI cannot call an operation, or `undefined` when it can. It holds a\n * project secret and nothing else: an operation only an end user's session\n * cookie authenticates is theirs, and a cookie parameter (the login flow's\n * `_zflow`) is state only a browser carries.\n */\nexport const uncallable = (operation: ApiOperation): string | undefined => {\n if (operation.auth === \"session\") {\n return `${operation.id} is authenticated by an end user's session cookie, and the CLI holds a project secret`;\n }\n const cookie = operation.parameters.find((parameter) => parameter.in === \"cookie\");\n return cookie\n ? `${operation.id} reads the ${cookie.name} cookie, which only a browser carries`\n : undefined;\n};\n\n/**\n * The operations `zitadel api ls` lists: those of one tag, and those whose id,\n * path, summary or tag contains the filter, both in any case.\n */\nexport const findOperations = ({\n filter,\n tag,\n}: Readonly<{ filter?: string; tag?: string }>): readonly ApiOperation[] =>\n OPERATIONS.filter(\n (operation) =>\n (tag === undefined || operation.tag.toLowerCase() === tag.toLowerCase()) &&\n (filter === undefined ||\n [operation.id, operation.path, operation.summary, operation.tag].some((word) =>\n word.toLowerCase().includes(filter.toLowerCase()),\n )),\n );\n\n/** The names of an operation's path parameters, in the order the path has them. */\nexport const pathParameterNames = (operation: ApiOperation): readonly string[] =>\n [...operation.path.matchAll(/\\{([^}]+)\\}/g)].map((match) => match[1] ?? \"\");\n\n/**\n * The operation an argument names: an `operationId` (in any case, as the docs\n * and `@zitadel/api` spell it), or a path starting with `/`, matched against\n * the spec's templates. `method` is `-X`: with a path it picks among the\n * path's methods; with an id it must be the operation's own.\n */\nexport const resolveTarget = (ref: string, method?: string): Target => {\n const wanted = method?.toUpperCase();\n if (!ref.startsWith(\"/\")) {\n const operation = byId(ref);\n if (wanted !== undefined && wanted !== operation.method) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${operation.id} is ${operation.method} ${operation.path}, not ${wanted}`,\n { hint: `Leave out -X, or pass -X ${operation.method}.` },\n );\n }\n return { operation, pathValues: {}, query: new URLSearchParams() };\n }\n return byPath(ref, wanted);\n};\n\nconst byId = (ref: string): ApiOperation => {\n const operation = OPERATIONS.find(\n (candidate) => candidate.id.toLowerCase() === ref.toLowerCase(),\n );\n if (operation) {\n return operation;\n }\n const wanted = ref.toLowerCase();\n const near = OPERATIONS.filter((candidate) => {\n const id = candidate.id.toLowerCase();\n return id.includes(wanted) || distance(id, wanted) <= 2;\n }).map((candidate) => candidate.id);\n throw new ZitadelError(\"E_VALIDATION\", `No operation is called ${ref}`, {\n hint:\n near.length > 0\n ? `Did you mean ${near.slice(0, 5).join(\", \")}? List them all with \\`zitadel api ls\\`.`\n : \"List them with `zitadel api ls`, or give a path such as /users/query.\",\n nextCommands: [LIST],\n });\n};\n\n/** How many single-letter edits turn `a` into `b` (Levenshtein), for a typo's suggestion. */\nconst distance = (a: string, b: string): number => {\n let previous = Array.from({ length: b.length + 1 }, (_, index) => index);\n for (const [i, left] of [...a].entries()) {\n const current = [i + 1];\n for (const [j, right] of [...b].entries()) {\n current.push(\n Math.min(\n (previous[j + 1] ?? 0) + 1,\n (current[j] ?? 0) + 1,\n (previous[j] ?? 0) + (left === right ? 0 : 1),\n ),\n );\n }\n previous = current;\n }\n return previous[b.length] ?? 0;\n};\n\n/** A path's segments, each percent-decoded; `undefined` for a malformed escape. */\nconst segmentsOf = (path: string): readonly string[] | undefined => {\n try {\n return path.split(\"/\").slice(1).map(decodeURIComponent);\n } catch {\n return undefined;\n }\n};\n\n/**\n * How well a template matches a path: `undefined` when it does not, else the\n * positions of its literal segments, so `/users/me` is chosen over\n * `/users/{user_id}` for `/users/me`.\n */\nconst matchOf = (\n template: string,\n segments: readonly string[],\n): { literals: number; values: Record<string, string> } | undefined => {\n const parts = template.split(\"/\").slice(1);\n if (parts.length !== segments.length) {\n return undefined;\n }\n const values: Record<string, string> = {};\n let literals = 0;\n for (const [index, part] of parts.entries()) {\n const segment = segments[index] ?? \"\";\n const parameter = /^\\{([^}]+)\\}$/.exec(part)?.[1];\n if (parameter !== undefined) {\n if (segment === \"\") {\n return undefined;\n }\n values[parameter] = segment;\n } else if (part === segment) {\n literals++;\n } else {\n return undefined;\n }\n }\n return { literals, values };\n};\n\nconst byPath = (ref: string, method: string | undefined): Target => {\n const at = ref.indexOf(\"?\");\n const path = at === -1 ? ref : ref.slice(0, at);\n const query = new URLSearchParams(at === -1 ? \"\" : ref.slice(at + 1));\n const segments = segmentsOf(path.length > 1 ? path.replace(/\\/$/, \"\") : path);\n const matches = (segments ? OPERATIONS : [])\n .map((operation) => ({ operation, match: matchOf(operation.path, segments ?? []) }))\n .filter((candidate) => candidate.match !== undefined);\n const best = Math.max(-1, ...matches.map((candidate) => candidate.match?.literals ?? -1));\n const template = matches.find((candidate) => candidate.match?.literals === best);\n if (!template?.match) {\n throw new ZitadelError(\"E_VALIDATION\", `No operation has the path ${path}`, {\n hint: \"List the paths with `zitadel api ls`.\",\n nextCommands: [LIST],\n });\n }\n const methods = OPERATIONS.filter((operation) => operation.path === template.operation.path);\n const operation =\n method === undefined\n ? methods.length === 1\n ? methods[0]\n : methods.find((candidate) => candidate.method === \"GET\")\n : methods.find((candidate) => candidate.method === method);\n if (!operation) {\n const offered = methods.map((candidate) => candidate.method).join(\", \");\n throw new ZitadelError(\n \"E_VALIDATION\",\n method === undefined\n ? `${template.operation.path} takes ${offered}; say which with -X`\n : `${template.operation.path} takes ${offered}, not ${method}`,\n { hint: `Pass -X with one of ${offered}.` },\n );\n }\n return { operation, pathValues: template.match.values, query };\n};\n","import { readFile } from \"node:fs/promises\";\nimport { text } from \"node:stream/consumers\";\n\nimport * as schemas from \"@zitadel/api/generated/endpoints/zitadelNextGen.zod\";\n\nimport { ZitadelError } from \"../errors\";\nimport { parseJsonObject } from \"../json\";\nimport { fragmentOf, readAssignment } from \"../oclif/crud/assign\";\nimport { mergeDocuments, typedValue } from \"../oclif/crud/document\";\nimport { describeBody } from \"../oclif/crud/fields\";\nimport type { Schema } from \"../oclif/crud/types\";\nimport { nodeAt, unwrap, type ZodLike } from \"../oclif/crud/zod\";\nimport { type ApiOperation, pathParameterNames, type Target } from \"./operations\";\n\n/** The flag a field is given with, which errors name. */\nconst FIELD = \"--field\";\n\n/** One request to the API, before the server and the credential are added. */\nexport type ApiRequest = Readonly<{\n operation: ApiOperation;\n /** The path with its parameters filled in, without the query string. */\n path: string;\n /** The query string's entries, in order; a list parameter repeats its name. */\n query: readonly (readonly [string, string])[];\n /** The JSON body, when the request has one. */\n body?: unknown;\n}>;\n\n/** The URL a request goes to on `server`. */\nexport const urlOf = (server: string, request: ApiRequest): string => {\n const query = new URLSearchParams(\n request.query.map(([name, value]) => [name, value] as [string, string]),\n );\n const search = query.size > 0 ? `?${query}` : \"\";\n return `${server.replace(/\\/+$/, \"\")}${request.path}${search}`;\n};\n\n/**\n * The generated Zod schema for one part of an operation's request:\n * `QueryUsersBody`, `ListEventsQueryParams`. orval names them after the\n * `operationId` with its first letter raised.\n */\nexport const schemaOf = (\n operation: ApiOperation,\n part: \"Body\" | \"QueryParams\",\n): ZodLike | undefined => {\n const name = `${operation.id.charAt(0).toUpperCase()}${operation.id.slice(1)}${part}`;\n return Object.hasOwn(schemas, name)\n ? ((schemas as Record<string, unknown>)[name] as ZodLike)\n : undefined;\n};\n\n/** Path parameter values read so far, and the names still without one. */\nexport type PathValues = Readonly<{\n values: Readonly<Record<string, string>>;\n missing: readonly string[];\n}>;\n\n/**\n * Fill an operation's path parameters: from the path itself when the target\n * was a path, else from the positionals in path order. A `project_id` still\n * missing is the CLI's own project, as the resource commands take it.\n */\nexport const pathValuesOf = (\n target: Target,\n positionals: readonly string[],\n projectId: string | undefined,\n): PathValues => {\n const names = pathParameterNames(target.operation);\n const fromPath = Object.keys(target.pathValues).length > 0;\n if (positionals.length > 0 && (fromPath || names.length === 0)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n names.length === 0\n ? `${target.operation.id} takes no path parameters, but got ${positionals.join(\" \")}`\n : `The path already names ${names.join(\", \")}, so ${positionals.join(\" \")} is one argument too many`,\n { hint: \"Give a path parameter either in the path or as an argument after an operation id.\" },\n );\n }\n if (positionals.length > names.length) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${target.operation.id} takes ${names.length} path parameter${names.length === 1 ? \"\" : \"s\"} (${names.join(\", \")}), but got ${positionals.length}`,\n { hint: `Give them in the path's order: ${target.operation.path}.` },\n );\n }\n const values: Record<string, string> = { ...target.pathValues };\n for (const [index, value] of positionals.entries()) {\n const name = names[index];\n if (name !== undefined) {\n values[name] = value;\n }\n }\n if (values.project_id === undefined && names.includes(\"project_id\") && projectId) {\n values.project_id = projectId;\n }\n return { values, missing: names.filter((name) => values[name] === undefined) };\n};\n\n/** What a request is built from, once every path parameter has a value. */\nexport type RequestInput = Readonly<{\n target: Target;\n pathValues: Readonly<Record<string, string>>;\n /** `--field` entries, in the order given. */\n fields: readonly string[];\n /** The `--input` document, when one was given. */\n input?: Readonly<Record<string, unknown>>;\n /** The CLI's project, for a required `project_id` the caller leaves out. */\n projectId?: string;\n}>;\n\n/** The first segment of a field's name: `idp` for `idp.oidc.issuer=…`. */\nconst headOf = (raw: string): string => {\n const at = raw.indexOf(\"=\");\n const name = at === -1 ? raw : raw.slice(0, raw[at - 1] === \":\" ? at - 1 : at);\n return name.split(\".\")[0] ?? \"\";\n};\n\n/** A query parameter's value as the URL carries it: a list repeats the name. */\nconst queryValues = (name: string, value: unknown): readonly string[] => {\n const values = Array.isArray(value) ? value : [value];\n if (values.some((item) => item === null || typeof item === \"object\")) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${FIELD} ${name} is a query parameter, which takes a value or a list of values`,\n {\n hint: `Give it as ${FIELD} ${name}=value, or a list as ${FIELD} '${name}:=[\"a\",\"b\"]'.`,\n },\n );\n }\n return values.map(String);\n};\n\n/**\n * One query field's values. A list parameter takes one value per field, as a\n * query string repeats its name (`-F category=auth -F category=session`), or\n * the whole list as JSON; any other takes its one value.\n */\nconst queryField = (raw: string, name: string, schema: ZodLike | undefined) => {\n const node = nodeAt(schema, [name])?.node;\n const type = unwrap(node);\n if (type?.def?.type !== \"array\" || raw.startsWith(`${name}:=`)) {\n return { list: false, values: queryValues(name, readAssignment(raw, schema, [], FIELD).value) };\n }\n const text = raw.slice(name.length + 1);\n return {\n list: true,\n values: queryValues(name, typedValue(type.def.element, text, `${FIELD} ${name}`)),\n };\n};\n\n/**\n * Build the request: the path filled in, the query, and the body.\n *\n * A field whose name the operation declares as a query parameter sets that\n * parameter; every other field is a dot path into the body, laid over\n * `--input`. Each is typed by the operation's generated schema, as `--set` is\n * on the resource commands. A body the operation requires but nothing gave is\n * `{}`, the empty document.\n */\nexport const buildRequest = ({\n target,\n pathValues,\n fields,\n input,\n projectId,\n}: RequestInput): ApiRequest => {\n const { operation } = target;\n const query = new Map<string, readonly string[]>();\n for (const [name, value] of target.query) {\n query.set(name, [...(query.get(name) ?? []), value]);\n }\n if (input !== undefined && operation.body === null) {\n throw new ZitadelError(\"E_VALIDATION\", `${operation.id} takes no body, but --input gave one`, {\n hint: \"Leave out --input.\",\n });\n }\n\n let body: unknown = input ?? (operation.body === \"required\" ? {} : undefined);\n const given = new Set<string>();\n const bodySchema = schemaOf(operation, \"Body\");\n for (const raw of fields) {\n const head = headOf(raw);\n const parameter = operation.parameters.find((candidate) => candidate.name === head);\n if (parameter?.in === \"query\") {\n if (!/^[^.]+:?=/.test(raw)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${FIELD} ${head} is a query parameter, which has no fields`,\n {\n hint: `Give it as ${FIELD} ${head}=value.`,\n },\n );\n }\n const { list, values } = queryField(raw, head, schemaOf(operation, \"QueryParams\"));\n // The first field for a name replaces what the path's query string\n // said; a list's further fields add to it.\n query.set(head, list && given.has(head) ? [...(query.get(head) ?? []), ...values] : values);\n given.add(head);\n continue;\n }\n if (parameter) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n parameter.in === \"path\"\n ? `${head} is a path parameter of ${operation.id}; give it as an argument`\n : `${head} is a ${parameter.in} parameter, which the CLI does not send`,\n parameter.in === \"path\"\n ? { hint: `For example: zitadel api ${operation.id} <${head}>` }\n : {},\n );\n }\n if (operation.body === null) {\n const names = operation.parameters\n .filter((candidate) => candidate.in === \"query\")\n .map((candidate) => candidate.name);\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${operation.id} takes no body, and ${head} is none of its query parameters`,\n {\n hint:\n names.length > 0\n ? `Its query parameters: ${names.join(\", \")}.`\n : `${operation.id} takes no fields.`,\n details: { field: head, query_parameters: names },\n },\n );\n }\n const assignment = readAssignment(raw, bodySchema, bodyFields(bodySchema), FIELD);\n body = mergeDocuments(body ?? {}, fragmentOf(assignment));\n }\n\n const projectParameter = operation.parameters.find(\n (candidate) => candidate.in === \"query\" && candidate.name === \"project_id\",\n );\n if (projectParameter?.required && !query.has(\"project_id\") && projectId) {\n query.set(\"project_id\", [projectId]);\n }\n\n return {\n operation,\n path: operation.path.replace(/\\{([^}]+)\\}/g, (_, name: string) =>\n encodeURIComponent(pathValues[name] ?? \"\"),\n ),\n query: [...query].flatMap(([name, values]) => values.map((value) => [name, value] as const)),\n ...(body === undefined ? {} : { body }),\n };\n};\n\n/**\n * The body's fields, for an error that names the ones a path could have\n * meant. Without their flags: those belong to the resource commands.\n */\nconst bodyFields = (schema: ZodLike | undefined) =>\n schema === undefined\n ? []\n : describeBody(schema as Schema).map(({ flag: _flag, ...field }) => field);\n\n/**\n * The `--input` document: a file, or stdin with `-`. Reading a terminal to its\n * end would look like a hang, so `-` with nothing piped in is refused.\n */\nexport const readInput = async (\n source: string | undefined,\n): Promise<Readonly<Record<string, unknown>> | undefined> => {\n if (source === undefined) {\n return undefined;\n }\n if (source === \"-\") {\n if (process.stdin.isTTY) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"--input - reads the body from a pipe, but nothing is piped in\",\n {\n hint: \"Pipe a body in (`cat body.json | zitadel api … --input -`), or pass --input <path>.\",\n },\n );\n }\n return parseJsonObject(await text(process.stdin), \"stdin\");\n }\n return parseJsonObject(await readFile(source, \"utf8\"), source);\n};\n","import { ApiError, request as fetchWithPolicy } from \"@zitadel/api/runtime/fetch\";\n\nimport { REQUEST_TIMEOUT_MS, sanitizeRejection, sanitizeResponse } from \"../api-client\";\nimport { interruptSignal } from \"../interrupt\";\nimport { collectPages } from \"../oclif/crud/paging\";\nimport { type ApiRequest, urlOf } from \"./request\";\n\n/** What the server answered. `body` is `undefined` for a response without one. */\nexport type ApiResponse = Readonly<{ status: number; body: unknown }>;\n\n/** The response body: JSON where the server says so, text otherwise. */\nconst readBody = async (res: Response): Promise<unknown> => {\n if ([204, 205, 304].includes(res.status)) {\n return undefined;\n }\n const raw = await res.text();\n if (raw === \"\") {\n return undefined;\n }\n if (!(res.headers.get(\"content-type\") ?? \"\").includes(\"json\")) {\n return raw;\n }\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return raw;\n }\n};\n\n/**\n * Send one request to `server`, with the project secret as the bearer when\n * there is one. It is bounded and cancelled as every platform call is\n * (`createZitadelClient`), and what the server says is escaped the same way:\n * a non-2xx is the {@link ApiError} `toZitadelError` maps to an exit code.\n */\nexport const send = async (\n server: string,\n token: string | undefined,\n request: ApiRequest,\n): Promise<ApiResponse> => {\n const url = urlOf(server, request);\n const { method } = request.operation;\n const headers = new Headers({ accept: \"application/json\" });\n if (token !== undefined) {\n headers.set(\"authorization\", `Bearer ${token}`);\n }\n if (request.body !== undefined) {\n headers.set(\"content-type\", \"application/json\");\n }\n const { res, rawBody } = await fetchWithPolicy(\n url,\n {\n method,\n headers,\n ...(request.body === undefined ? {} : { body: JSON.stringify(request.body) }),\n },\n { signal: interruptSignal(), timeoutMs: REQUEST_TIMEOUT_MS },\n readBody,\n );\n if (!res.ok) {\n sanitizeRejection(\n new ApiError(res.status, url, rawBody, `${method} ${url} returned ${res.status}`),\n );\n }\n return { status: res.status, body: sanitizeResponse(rawBody) };\n};\n\n/** The request for the page `token` names; `undefined` leaves the request as it is. */\nconst pageOf = (request: ApiRequest, token: string | undefined): ApiRequest => {\n const paging = request.operation.paging;\n if (token === undefined || paging === null) {\n return request;\n }\n if (paging.token === \"query\") {\n return {\n ...request,\n query: [...request.query.filter(([name]) => name !== \"page_token\"), [\"page_token\", token]],\n };\n }\n return { ...request, body: { ...(request.body as Record<string, unknown>), page_token: token } };\n};\n\n/**\n * Send a paged request until the server's `next_page_token` runs out, and\n * answer the last page with the page field holding every page's items. The\n * walk is `collectPages`, the resource lists' `--all`, so a server that\n * repeats a cursor is caught the same way.\n */\nexport const sendAll = async (\n server: string,\n token: string | undefined,\n request: ApiRequest,\n): Promise<ApiResponse> => {\n const paging = request.operation.paging;\n if (paging === null) {\n return send(server, token, request);\n }\n let last: ApiResponse = { status: 200, body: undefined };\n const { items } = await collectPages(\n async (cursor) => {\n last = await send(server, token, pageOf(request, cursor));\n return last.body;\n },\n {\n items: paging.items,\n all: true,\n nextPageToken: \"next_page_token\",\n flags: { all: \"--paginate\", onePage: \"-F limit=<n> and -F page_token=<token>\" },\n },\n );\n return {\n status: last.status,\n body: { ...(last.body as Record<string, unknown>), [paging.items]: items },\n };\n};\n","import { type ApiRequest, urlOf } from \"./request\";\n\n/** A shell word, single-quoted. */\nconst quote = (value: string): string => `'${value.replaceAll(\"'\", `'\\\\''`)}'`;\n\n/**\n * The cURL command that sends a request, as `--dry-run` shows it. The project\n * secret is never written out: an operation that needs it reads it from\n * `$ZITADEL_PROJECT_SECRET`, as the API reference's cURL samples do, in double\n * quotes so the shell expands it.\n */\nexport const curlOf = (server: string, request: ApiRequest): string =>\n [\n `curl -X ${request.operation.method} ${quote(urlOf(server, request))}`,\n ...(request.operation.auth === \"secret\"\n ? ['-H \"Authorization: Bearer $ZITADEL_PROJECT_SECRET\"']\n : []),\n ...(request.body === undefined\n ? []\n : [\"-H 'Content-Type: application/json'\", `-d ${quote(JSON.stringify(request.body))}`]),\n ].join(\" \\\\\\n \");\n","import { Args, Flags } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../errors\";\n\n/**\n * Refuse a value that is present but holds nothing.\n *\n * `required: true` is no help: it asks whether a token arrived in argv, and an\n * empty one satisfies it. The way this happens is the shell, not a typo —\n * `--client-id \"$CLIENT_ID\"` with the variable unset sends exactly that, the\n * expansion dropping the value while the quotes keep the word, so argv carries\n * `[\"--client-id\", \"\"]`. Unquoted, the word vanishes and oclif refuses with\n * \"expects a value\"; quoted, nothing complained and the empty string travelled\n * on as if it were a real answer.\n *\n * Refusing during parse rather than in each command puts it at the same point\n * oclif's own refusal lands, so both spellings of a missing value fail the same\n * way, and the value that reaches `run` is already trimmed.\n */\nfunction refuseBlank(input: string, label: string, message: string): string {\n const value = input.trim();\n if (value === \"\") {\n throw new ZitadelError(\"E_VALIDATION\", message, {\n hint: `Pass a value for ${label}, or omit it entirely.`,\n details: { argument: label },\n });\n }\n return value;\n}\n\n/**\n * A string flag whose value must not be blank. See {@link refuseBlank}.\n *\n * Not for a flag that writes a field value: an empty string is a legitimate\n * thing to store, so the generated resource flags in `crud/fields.ts` keep\n * plain `Flags.string`.\n */\nexport const nonBlankString = Flags.custom<string>({\n // oclif prefixes a flag's parse failure with \"Parsing --<name>\", so the\n // message must not name it again.\n parse: async (input, _command, flag) =>\n refuseBlank(input, `--${flag.name}`, \"the value is empty\"),\n});\n\n/** A positional argument whose value must not be blank. See {@link refuseBlank}. */\nexport const nonBlankArg = Args.custom<string>({\n // An argument's failure carries no such prefix, so this one names itself.\n parse: async (input, _command, arg) =>\n refuseBlank(input, arg.name, `${arg.name} was given an empty value`),\n});\n","import { execFile } from \"node:child_process\";\nimport { basename } from \"node:path\";\n\nexport type ManagedRuntimeProcess = Readonly<{\n command: string;\n data_dir?: string;\n kind: \"server-binary\" | \"server-wrapper\";\n pid: number;\n ppid?: number;\n}>;\n\nexport type ManagedRuntimeDiscovery = Readonly<{\n error?: string;\n processes: ReadonlyArray<ManagedRuntimeProcess>;\n supported: boolean;\n}>;\n\ntype ProcessRow = Readonly<{\n command: string;\n pid: number;\n ppid?: number;\n}>;\n\n/**\n * Which CLI-managed local Zitadel servers are running on the machine, whichever\n * directory started them. Everything that asks goes through this, so a test can\n * answer for the machine instead of reading it.\n */\nexport interface LocalServers {\n current(): Promise<ManagedRuntimeDiscovery>;\n}\n\n/** The real answer: the machine's processes, read with `ps`. */\nexport class PsLocalServers implements LocalServers {\n current(): Promise<ManagedRuntimeDiscovery> {\n return discoverManagedRuntimeProcesses();\n }\n}\n\nexport async function discoverManagedRuntimeProcesses(opts?: {\n readonly timeoutMs?: number;\n}): Promise<ManagedRuntimeDiscovery> {\n if (process.platform === \"win32\") {\n return { supported: false, processes: [], error: \"process sweep is not available on Windows\" };\n }\n\n let rows: ReadonlyArray<ProcessRow>;\n try {\n rows = parsePsRows(await runPs([\"axo\", \"pid=,ppid=,command=\"], opts?.timeoutMs ?? 1000));\n } catch (error) {\n return { supported: false, processes: [], error: errorMessage(error) };\n }\n\n const candidates = rows.filter((row) => isRuntimeCandidate(row.command));\n const hydrated = await Promise.all(\n candidates.map(async (row) => ({\n ...row,\n command: await hydrateCommand(row.pid, row.command, opts?.timeoutMs ?? 1000),\n })),\n );\n const processes = hydrated\n .map(toManagedRuntimeProcess)\n .filter((candidate): candidate is ManagedRuntimeProcess => candidate !== undefined);\n return { supported: true, processes: uniqueByPid(processes) };\n}\n\nfunction runPs(args: string[], timeoutMs: number): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n execFile(\"ps\", args, { timeout: timeoutMs, encoding: \"utf8\" }, (err, stdout) => {\n if (err) {\n reject(err);\n return;\n }\n resolve(stdout);\n });\n });\n}\n\nasync function hydrateCommand(pid: number, fallback: string, timeoutMs: number): Promise<string> {\n try {\n const hydrated = await runPs([\"eww\", \"-p\", String(pid), \"-o\", \"command=\"], timeoutMs);\n return hydrated.trim() || fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction parsePsRows(stdout: string): ReadonlyArray<ProcessRow> {\n const rows: ProcessRow[] = [];\n for (const line of stdout.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed) {\n continue;\n }\n const match = trimmed.match(/^(\\d+)\\s+(\\d+)\\s+(.+)$/);\n if (!match) {\n continue;\n }\n rows.push({\n pid: Number(match[1]),\n ppid: Number(match[2]),\n command: match[3] ?? \"\",\n });\n }\n return rows;\n}\n\nfunction toManagedRuntimeProcess(row: ProcessRow): ManagedRuntimeProcess | undefined {\n const dataDir = extractDataDir(row.command);\n const wrapper = isServerWrapper(row.command);\n const binary = isServerBinary(row.command);\n if (!wrapper && !binary) {\n return undefined;\n }\n if (!wrapper && !isCliLocalDataDir(dataDir)) {\n return undefined;\n }\n return {\n pid: row.pid,\n ppid: row.ppid,\n command: stripEnvironmentNoise(row.command),\n kind: wrapper ? \"server-wrapper\" : \"server-binary\",\n ...(dataDir ? { data_dir: dataDir } : {}),\n };\n}\n\nfunction isRuntimeCandidate(command: string): boolean {\n return (\n isServerWrapper(command) ||\n isServerBinary(command) ||\n command.includes(\"NEXTGEN_SERVER_DATA_DIR=\") ||\n basename(command.split(/\\s+/)[0] ?? \"\") === \"nextgen\"\n );\n}\n\nfunction isServerWrapper(command: string): boolean {\n return command.includes(\"zitadel-server.js\");\n}\n\nfunction isServerBinary(command: string): boolean {\n if (/@zitadel\\/server-[^/\\s]+\\/bin\\/nextgen(?:\\.exe)?(?:\\s|$)/.test(command)) {\n return true;\n }\n return (\n isCliLocalDataDir(extractDataDir(command)) &&\n commandTokens(command).some((token) => basename(token) === \"nextgen\")\n );\n}\n\nfunction extractDataDir(command: string): string | undefined {\n const match = command.match(/NEXTGEN_SERVER_DATA_DIR=(\"[^\"]+\"|'[^']+'|[^\\s]+)/);\n const value = match?.[1];\n if (!value) {\n return undefined;\n }\n return value.replace(/^[\"']|[\"']$/g, \"\");\n}\n\nfunction isCliLocalDataDir(path: string | undefined): boolean {\n return Boolean(path && /(?:^|\\/)\\.zitadel\\/local\\/nextgen-data\\/?$/.test(path));\n}\n\nfunction stripEnvironmentNoise(command: string): string {\n return command\n .replace(/(^|\\s)[A-Z_][A-Z0-9_]*=(?:\"[^\"]+\"|'[^']+'|[^\\s]+)/g, \" \")\n .replace(/\\s{2,}/g, \" \")\n .trim();\n}\n\nfunction commandTokens(command: string): string[] {\n return command.split(/\\s+/).filter((token) => !/^[A-Z_][A-Z0-9_]*=/.test(token));\n}\n\nfunction uniqueByPid(\n processes: ReadonlyArray<ManagedRuntimeProcess>,\n): ReadonlyArray<ManagedRuntimeProcess> {\n const byPid = new Map<number, ManagedRuntimeProcess>();\n for (const processInfo of processes) {\n byPid.set(processInfo.pid, processInfo);\n }\n return [...byPid.values()].sort((a, b) => a.pid - b.pid);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { resolve } from \"node:path\";\n\n/**\n * Resolve the working directory the CLI should operate against, defaulting to\n * the process CWD when no `--cwd` override is given. Always returns an\n * absolute path so downstream `join`/`readFile` calls are unaffected by later\n * `process.chdir` or relative-path ambiguity.\n */\nexport function resolveCwd(cwd?: string): string {\n return resolve(cwd ?? process.cwd());\n}\n\n/**\n * Sentinel comment stamped at the top of every file the CLI generates and\n * owns. Commands like `doctor` and `eject` look for this marker to decide\n * whether a file is safe to touch; the trailing `v1` lets the format evolve\n * without mistaking newer managed files for hand-edited ones.\n */\nexport const MANAGED_MARKER = \"// zitadel-cli: managed-file v1\";\n","import { execFile } from \"node:child_process\";\n\nexport type TcpListener = Readonly<{\n address: string;\n command?: string;\n host: string;\n pid?: number;\n port: number;\n}>;\n\n/**\n * Enumerate TCP LISTEN sockets on loopback/wildcard interfaces (`127.0.0.1`,\n * `::1`, or the wildcard `*`) with enough metadata for CLI diagnostics.\n * Spawns `lsof -iTCP -sTCP:LISTEN -P -n -F pcn` and parses its\n * machine-readable output.\n *\n * Never throws. Returns `[]` whenever lsof is unavailable (e.g. Windows,\n * unusual PATH), the spawn errors, exits non-zero, or the call exceeds\n * `timeoutMs` (default 1000ms). The caller treats an empty list the same as\n * \"no visible listeners.\"\n */\nexport async function listListeningTcpListeners(opts?: {\n readonly timeoutMs?: number;\n}): Promise<ReadonlyArray<TcpListener>> {\n const timeoutMs = opts?.timeoutMs ?? 1000;\n try {\n const stdout = await runLsof(timeoutMs);\n return parseLsofListeners(stdout);\n } catch {\n return [];\n }\n}\n\nexport async function listenersForPort(\n port: number,\n opts?: { readonly timeoutMs?: number },\n): Promise<ReadonlyArray<TcpListener>> {\n return (await listListeningTcpListeners(opts)).filter((listener) => listener.port === port);\n}\n\n/**\n * Spawn `lsof` with the canned argv and resolve to its stdout. Hand-rolled\n * rather than `util.promisify(execFile)` because the latter resolves with a\n * `{stdout, stderr}` object via its custom-promisify symbol — a heavier shape\n * to mock and worse to read at the call site, where we only ever want stdout.\n */\nfunction runLsof(timeoutMs: number): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n execFile(\n \"lsof\",\n [\"-iTCP\", \"-sTCP:LISTEN\", \"-P\", \"-n\", \"-F\", \"pcn\"],\n { timeout: timeoutMs, encoding: \"utf8\" },\n (err, stdout) => {\n if (err) {\n reject(err);\n return;\n }\n resolve(stdout);\n },\n );\n });\n}\n\n/**\n * Parse the pid (`p`), command (`c`), and name/address (`n`) records emitted by\n * `lsof -F pcn`. Address records end in `:<port>` (e.g. `n*:8080`,\n * `n127.0.0.1:3000`, `n[::1]:5050`). Only loopback/wildcard hosts are kept;\n * external interface bindings are ignored.\n */\nfunction parseLsofListeners(stdout: string): ReadonlyArray<TcpListener> {\n const listeners: TcpListener[] = [];\n let pid: number | undefined;\n let command: string | undefined;\n for (const line of stdout.split(/\\r?\\n/)) {\n if (line.startsWith(\"p\")) {\n const parsed = Number.parseInt(line.slice(1), 10);\n pid = Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n command = undefined;\n continue;\n }\n if (line.startsWith(\"c\")) {\n command = line.slice(1) || undefined;\n continue;\n }\n if (!line.startsWith(\"n\")) {\n continue;\n }\n const address = line.slice(1);\n const colon = address.lastIndexOf(\":\");\n if (colon < 0) {\n continue;\n }\n const host = address.slice(0, colon);\n const portStr = address.slice(colon + 1);\n if (!isLoopback(host)) {\n continue;\n }\n const port = Number.parseInt(portStr, 10);\n if (Number.isFinite(port) && port > 0 && port < 65536) {\n listeners.push({ address, command, host, pid, port });\n }\n }\n return listeners.sort((a, b) => a.port - b.port || (a.pid ?? 0) - (b.pid ?? 0));\n}\n\n/** Recognised loopback host strings as emitted by `lsof -F n`. */\nfunction isLoopback(host: string): boolean {\n return host === \"*\" || host === \"127.0.0.1\" || host === \"[::1]\" || host === \"::1\";\n}\n","import { publicCliCommand } from \"../public-cli\";\nimport { shellCommand, type SuggestedCommand, unscopedCommand } from \"../suggestion\";\n\nexport type DockerRuntimeGuidance = {\n hint: string;\n nextActions: string[];\n nextCommands: SuggestedCommand[];\n};\n\nexport function dockerUnavailableMessage(error: unknown): string {\n const detail = error instanceof Error ? error.message : String(error);\n const suffix = detail.trim() ? ` (${detail.trim()})` : \"\";\n return `Docker is not reachable${suffix}; managed local runtime commands need Docker, but remote or cloud setup can continue with --server <url>.`;\n}\n\nexport function dockerRuntimeGuidance(\n retryCommand: \"doctor\" | \"start\",\n cliVersion: string,\n): DockerRuntimeGuidance {\n return {\n hint: \"Docker is required only for the managed local runtime (`zitadel start` and `--server local`). Start Docker, then retry; or target a remote server with `--server <url>`.\",\n nextActions: [\n \"Start Docker Desktop, Docker Engine, or a Docker-compatible runtime such as Colima.\",\n `Run \\`docker version\\`, then rerun \\`${publicCliCommand(retryCommand, cliVersion)}\\`.`,\n \"If you are not using the managed local runtime, run setup with `--server <url>` instead.\",\n ],\n nextCommands: [shellCommand(\"docker version\"), unscopedCommand(retryCommand, cliVersion)],\n };\n}\n","/**\n * Dev-runtime secret join (issue #1049).\n *\n * The developer's env files configure the local server. When `zitadel start`\n * spawns it, the CLI reads `.env.local`, then `.env`, and hands every\n * `NEXTGEN_*` variable to the runtime: that is the server's own configuration\n * namespace (`server.data_dir` is `NEXTGEN_SERVER_DATA_DIR`, and so on). The\n * three keys the CLI sets itself, address, data dir and public base, are not\n * read from the files at all.\n *\n * On top of the files, the CLI adds `LOCAL_DEFAULTS`: settings a server on the\n * developer's machine needs and a deployed one must not have.\n *\n * Only that prefix crosses into the runtime; everything else in the env files\n * stays on disk. Values travel through the child's environment, never argv,\n * so they do not show up in `ps -ef`, and only names are recorded or printed.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parseEnv } from \"node:util\";\n\nimport { ZitadelError } from \"../errors\";\nimport { isObject } from \"../json\";\n\n/** Highest priority first. */\nexport const ENV_FILES = [\".env.local\", \".env\"] as const;\n\n/** Variables handed to the runtime: the server's config prefix, upper-case. */\nexport const ENV_PREFIX = \"NEXTGEN_\";\n\n/** Keys the CLI sets itself at spawn; a file may not set them, so they are not read. */\nconst CLI_OWNED = new Set([\n \"NEXTGEN_SERVER_ADDRESS\",\n \"NEXTGEN_SERVER_DATA_DIR\",\n \"NEXTGEN_SERVER_PUBLIC_BASE\",\n]);\n\n/**\n * Server settings a local runtime gets unless the developer sets them. A key\n * set in an env file or the shell wins, an empty value included, which is how\n * a default is turned off.\n *\n * `httpclient.allow_list` lets the server fetch from this machine's loopback\n * (ADR 061's supported development relaxation), so an identity provider on\n * `http://localhost:<port>` works as an SSO connection's issuer. The deny list\n * still blocks every other internal range.\n */\nexport const LOCAL_DEFAULTS: Readonly<Record<string, string>> = {\n NEXTGEN_HTTPCLIENT_ALLOW_LIST: \"localhost,127.0.0.0/8,::1/128\",\n};\n\n/** What `runtime.json` and the `start`/`status` envelopes record: names only. */\nexport type EnvSummary = Readonly<{ injected: readonly string[] }>;\n\n/** A summary plus the values themselves. Never serialise or log this. */\nexport type ResolvedEnv = EnvSummary & Readonly<{ values: Readonly<Record<string, string>> }>;\n\nexport const EMPTY_SUMMARY: EnvSummary = { injected: [] };\nexport const EMPTY_ENV: ResolvedEnv = { ...EMPTY_SUMMARY, values: {} };\n\n/** True for an `env` block read back from `runtime.json`; names only. */\nexport const isEnvSummary = (value: unknown): value is EnvSummary =>\n isObject(value) &&\n Array.isArray(value.injected) &&\n value.injected.every((item) => typeof item === \"string\");\n\n/** The serialisable half of a resolution: what the metadata file stores. */\nexport const envSummary = ({ injected }: EnvSummary): EnvSummary => ({ injected });\n\n/**\n * Reads the project's env files into one map. Earlier files win, so a key in\n * `.env.local` shadows the same key in `.env`. Missing files are skipped.\n */\nexport const loadEnvFiles = async (\n cwd: string,\n files: readonly string[] = ENV_FILES,\n): Promise<Readonly<Record<string, string>>> => {\n const parsed = await Promise.all(files.map((file) => readEnvFile(join(cwd, file))));\n return parsed.reduceRight<Record<string, string>>(\n (merged, source) => Object.assign(merged, source),\n {},\n );\n};\n\nconst readEnvFile = async (path: string): Promise<Readonly<Record<string, string>>> => {\n let contents: string;\n try {\n contents = await readFile(path, \"utf8\");\n } catch (error: unknown) {\n if (isObject(error) && error.code === \"ENOENT\") {\n return {};\n }\n throw new ZitadelError(\"E_VALIDATION\", `Cannot read ${path}`, {\n hint: \"The file exists but could not be read; fix its permissions or remove it.\",\n details: { path, message: error instanceof Error ? error.message : String(error) },\n });\n }\n // parseEnv types values as possibly-undefined (it never emits them); drop them for the string map.\n return Object.fromEntries(\n Object.entries(parseEnv(contents.replace(/^\\uFEFF/, \"\"))).filter(\n (entry): entry is [string, string] => entry[1] !== undefined,\n ),\n );\n};\n\n/**\n * The `NEXTGEN_*` variables from the project's env files, plus the\n * `LOCAL_DEFAULTS` neither the files nor `shell` set, ready to hand to a\n * runtime. `start` calls this before it stops or spawns anything, so an\n * unreadable file fails fast and leaves a running runtime alone.\n */\nexport const loadProjectEnv = async (\n cwd: string,\n shell: Readonly<Record<string, string | undefined>> = process.env,\n): Promise<ResolvedEnv> => {\n const declared = Object.entries(await loadEnvFiles(cwd)).filter(\n ([name]) => name.startsWith(ENV_PREFIX) && !CLI_OWNED.has(name),\n );\n const defaults = Object.entries(LOCAL_DEFAULTS).filter(\n ([name]) =>\n shell[name] === undefined && !declared.some(([declaredName]) => declaredName === name),\n );\n const values = Object.fromEntries([...defaults, ...declared.filter(([, value]) => value !== \"\")]);\n return { values, injected: Object.keys(values).sort() };\n};\n","import { createHash } from \"node:crypto\";\nimport { access, mkdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\n\nimport { isErrno, ZitadelError } from \"../errors\";\nimport { isPortableShellWord, isTrainVersion } from \"../public-cli\";\nimport { unscopedCommand } from \"../suggestion\";\nimport { parseJsonObject } from \"../json\";\nimport { EMPTY_SUMMARY, type EnvSummary, isEnvSummary, LOCAL_DEFAULTS } from \"./env-vars\";\n\nexport const LOCAL_SERVER_IMAGE_NAME = \"ghcr.io/zitadel/nextgen\";\nexport const DEFAULT_LOCAL_SERVER_IMAGE = `${LOCAL_SERVER_IMAGE_NAME}:latest`;\nexport const DEFAULT_LOCAL_SERVER_PORT = 8080;\nexport const DEFAULT_LOCAL_SERVER_URL = \"http://localhost:8080\";\nexport const LOCAL_RUNTIME_DIR = \".zitadel/local\";\nexport const LOCAL_DATA_DIR = \".zitadel/local/nextgen-data\";\nexport const LOCAL_RUNTIME_FILE = \".zitadel/local/runtime.json\";\nexport const LOCAL_SERVER_LOG_FILE = \".zitadel/local/server.log\";\nexport const LOCAL_CONTAINER_PASSWD_FILE = \".zitadel/local/container-passwd\";\nexport const LOCAL_CONTAINER_GROUP_FILE = \".zitadel/local/container-group\";\nexport const CONTAINER_DATA_DIR = \"/var/lib/zitadel/nextgen-data\";\nexport const CONTAINER_HTTP_PORT = 8080;\n\n/**\n * The well-known id of a deployment's platform project (`domain.PlatformProjectID`,\n * `internal/domain/project.go`). A CLI-managed local server bootstraps it, which\n * is what gives the developer a team to own their projects with.\n */\nexport const PLATFORM_PROJECT_ID = \"proj_platform\";\n\n/**\n * The platform project's browser-safe key, read from the console runtime\n * document, or `undefined` when the server does not host the platform project.\n * The document sits outside the API, so the generated client does not cover\n * it; it publishes the deployment's default project, which the platform\n * bootstrap pins to {@link PLATFORM_PROJECT_ID}. Fail closed: an unreadable,\n * absent or hanging document reads as not hosted.\n */\nexport async function readPlatformRuntime(\n serverUrl: string,\n timeoutMs = 1500,\n): Promise<{ publishable_key: string } | undefined> {\n try {\n const res = await fetch(new URL(\"/console/runtime.json\", serverUrl), {\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) return undefined;\n const doc = (await res.json()) as { console_project_id?: unknown; publishable_key?: unknown };\n return doc.console_project_id === PLATFORM_PROJECT_ID && typeof doc.publishable_key === \"string\"\n ? { publishable_key: doc.publishable_key }\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport type RuntimeBackend = \"binary\" | \"docker\";\n\ntype RuntimeMetadataBase = {\n schema_version: 1;\n backend: RuntimeBackend;\n port: number;\n server_url: string;\n data_dir: string;\n created_at: string;\n cli_version: string;\n /** Absent on runtime files written before the env summary existed. */\n env?: EnvSummary;\n};\n\nexport type BinaryRuntimeMetadata = RuntimeMetadataBase & {\n backend: \"binary\";\n pid: number;\n command: string;\n log_path: string;\n server_package: string;\n server_version: string;\n};\n\nexport type DockerRuntimeMetadata = RuntimeMetadataBase & {\n backend: \"docker\";\n container_name: string;\n container_id: string;\n image: string;\n};\n\nexport type RuntimeMetadata = BinaryRuntimeMetadata | DockerRuntimeMetadata;\n\nexport type LocalRuntimePaths = {\n runtimeDir: string;\n dataDir: string;\n runtimeFile: string;\n logFile: string;\n containerPasswdFile: string;\n containerGroupFile: string;\n};\n\nexport type WritablePathProbe = {\n targetPath: string;\n checkedPath: string;\n};\n\nexport type ContainerIdentity = {\n uid: number;\n gid: number;\n passwdFile: string;\n groupFile: string;\n};\n\nexport function localRuntimePaths(cwd: string): LocalRuntimePaths {\n return {\n runtimeDir: join(cwd, LOCAL_RUNTIME_DIR),\n dataDir: join(cwd, LOCAL_DATA_DIR),\n runtimeFile: join(cwd, LOCAL_RUNTIME_FILE),\n logFile: join(cwd, LOCAL_SERVER_LOG_FILE),\n containerPasswdFile: join(cwd, LOCAL_CONTAINER_PASSWD_FILE),\n containerGroupFile: join(cwd, LOCAL_CONTAINER_GROUP_FILE),\n };\n}\n\nexport function localContainerName(cwd: string): string {\n const hash = createHash(\"sha256\").update(resolve(cwd)).digest(\"hex\").slice(0, 12);\n return `zitadel-server-${hash}`;\n}\n\nexport function localServerUrl(port: number): string {\n return `http://localhost:${port}`;\n}\n\nexport function defaultLocalServerImageForCliVersion(cliVersion: string): string {\n const normalized = cliVersion.trim().replace(/^v/, \"\");\n if (isTrainVersion(normalized)) {\n return `${LOCAL_SERVER_IMAGE_NAME}:${normalized}`;\n }\n return DEFAULT_LOCAL_SERVER_IMAGE;\n}\n\nexport async function ensureLocalState(cwd: string): Promise<LocalRuntimePaths> {\n const paths = localRuntimePaths(cwd);\n await mkdir(paths.dataDir, { recursive: true, mode: 0o700 });\n await appendGitignoreEntry(cwd, `${LOCAL_RUNTIME_DIR}/`);\n return paths;\n}\n\nexport async function assertLocalStateWritable(cwd: string): Promise<WritablePathProbe> {\n const paths = localRuntimePaths(cwd);\n const checkedPath = await nearestExistingDirectory(paths.dataDir);\n await access(checkedPath, constants.W_OK);\n return { targetPath: paths.dataDir, checkedPath };\n}\n\nexport async function ensureContainerIdentity(\n cwd: string,\n user: { uid?: number; gid?: number },\n): Promise<ContainerIdentity | undefined> {\n if (user.uid === undefined || user.uid <= 0) {\n return undefined;\n }\n const gid = user.gid ?? user.uid;\n const paths = localRuntimePaths(cwd);\n await mkdir(paths.runtimeDir, { recursive: true, mode: 0o700 });\n await writeFile(\n paths.containerPasswdFile,\n [\n \"root:x:0:0:root:/root:/bin/sh\",\n \"nonroot:x:65532:65532:nonroot:/nonexistent:/usr/sbin/nologin\",\n `zitadel-local:x:${String(user.uid)}:${String(gid)}:Zitadel local user:/tmp:/usr/sbin/nologin`,\n \"\",\n ].join(\"\\n\"),\n { mode: 0o644 },\n );\n await writeFile(\n paths.containerGroupFile,\n [\"root:x:0:\", \"nonroot:x:65532:\", `zitadel-local:x:${String(gid)}:`, \"\"].join(\"\\n\"),\n { mode: 0o644 },\n );\n return {\n uid: user.uid,\n gid,\n passwdFile: paths.containerPasswdFile,\n groupFile: paths.containerGroupFile,\n };\n}\n\n/**\n * The nearest directory, from `cwd` upward, that holds `file`, or `undefined`\n * when none does. `zitadel start` keeps its state in the directory it ran in,\n * and an app created inside that directory reads it from there. Only readers\n * walk up: commands that write or remove local state act on `cwd` alone.\n *\n * The walk ends at `stopAt`, the home directory by default, and skips a file\n * another user owns: local state names a server to talk to and a credential to\n * sign in with, so it is only taken from somewhere the developer put it.\n */\nexport async function findUpward(\n cwd: string,\n file: string,\n stopAt: string = homedir(),\n): Promise<string | undefined> {\n for (let dir = cwd; ; dir = dirname(dir)) {\n if (await isOwnFile(join(dir, file))) return dir;\n if (dir === stopAt || dirname(dir) === dir) return undefined;\n }\n}\n\nasync function isOwnFile(path: string): Promise<boolean> {\n try {\n const { uid } = await stat(path);\n // Windows reports no uid; existence is all there is to check.\n return process.getuid === undefined || uid === process.getuid();\n } catch (error) {\n // Only a missing path means \"not here\". Local state that exists but\n // cannot be read is still the nearest one, and walking past it would\n // pick a parent's server or credential instead.\n if (isErrno(error, \"ENOENT\") || isErrno(error, \"ENOTDIR\")) return false;\n throw new ZitadelError(\"E_VALIDATION\", `${path} cannot be read`, {\n hint: `Check that ${path} and its directory are readable by you.`,\n details: { cause: error instanceof Error ? error.message : String(error) },\n });\n }\n}\n\n/**\n * Whether two URLs name the same local server. `localhost` and the loopback\n * addresses are one host here: `start` records `localhost`, and a developer\n * may pass `--server http://127.0.0.1:8080` for the same process.\n */\nexport function sameLocalServer(a: string, b: string): boolean {\n const LOOPBACK = new Set([\"localhost\", \"127.0.0.1\", \"[::1]\"]);\n try {\n const [left, right] = [new URL(a), new URL(b)];\n const sameHost =\n left.hostname === right.hostname ||\n (LOOPBACK.has(left.hostname) && LOOPBACK.has(right.hostname));\n return sameHost && left.protocol === right.protocol && left.port === right.port;\n } catch {\n return false;\n }\n}\n\n/**\n * How the server at `serverUrl` reaches this machine's loopback, judged by the\n * nearest runtime record: `allowed` when that record's process server got the\n * loopback allow list, `container` when it runs in Docker (its localhost is\n * the container), `unknown` for any other server or an unreadable record.\n */\nexport async function loopbackReach(\n cwd: string,\n serverUrl: string,\n): Promise<\"allowed\" | \"container\" | \"unknown\"> {\n const nearest = await readNearestRuntimeMetadata(cwd).catch(() => undefined);\n if (!nearest || !sameLocalServer(nearest.runtime.server_url, serverUrl)) {\n return \"unknown\";\n }\n if (nearest.runtime.backend === \"docker\") {\n return \"container\";\n }\n return Object.keys(LOCAL_DEFAULTS).every((name) => nearest.runtime.env?.injected.includes(name))\n ? \"allowed\"\n : \"unknown\";\n}\n\n/** Runtime metadata of the server started in `cwd` or the nearest parent with one. */\nexport async function readNearestRuntimeMetadata(\n cwd: string,\n): Promise<{ dir: string; runtime: RuntimeMetadata } | undefined> {\n const dir = await findUpward(cwd, LOCAL_RUNTIME_FILE);\n if (!dir) {\n return undefined;\n }\n let runtime: RuntimeMetadata | undefined;\n try {\n runtime = await readRuntimeMetadata(dir);\n } catch (error) {\n // A record in a parent is recovered where it is: the bare commands would\n // act on the working directory instead.\n throw dir === cwd ? error : retargetMalformedRuntime(error, dir);\n }\n return runtime ? { dir, runtime } : undefined;\n}\n\n/**\n * The runtime record when it can be read, `undefined` when it is missing or\n * malformed. For commands that only want a hint from it (the port a directory\n * had) before they report a malformed record themselves, with the fix.\n */\nexport async function peekRuntimeMetadata(cwd: string): Promise<RuntimeMetadata | undefined> {\n try {\n return await readRuntimeMetadata(cwd);\n } catch {\n return undefined;\n }\n}\n\nexport async function readRuntimeMetadata(cwd: string): Promise<RuntimeMetadata | undefined> {\n const paths = localRuntimePaths(cwd);\n let raw: string;\n try {\n raw = await readFile(paths.runtimeFile, \"utf8\");\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return undefined;\n }\n throw error;\n }\n\n const parsed = parseJsonObject(raw, LOCAL_RUNTIME_FILE);\n return normalizeRuntimeMetadata(parsed);\n}\n\nexport async function writeRuntimeMetadata(cwd: string, metadata: RuntimeMetadata): Promise<void> {\n const paths = localRuntimePaths(cwd);\n await mkdir(paths.runtimeDir, { recursive: true, mode: 0o700 });\n await writeFile(paths.runtimeFile, `${JSON.stringify(metadata, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport async function removeRuntimeMetadata(cwd: string): Promise<void> {\n await rm(localRuntimePaths(cwd).runtimeFile, { force: true });\n}\n\nexport async function removeLocalData(cwd: string): Promise<void> {\n await rm(localRuntimePaths(cwd).dataDir, { recursive: true, force: true });\n}\n\n/**\n * Whether the server at `serverUrl` is ready: `/readyz` answers once the\n * server's database does, so a server that started but cannot reach its\n * database is not healthy.\n */\nexport async function checkLocalServerHealth(\n serverUrl: string,\n timeoutMs = 1500,\n): Promise<boolean> {\n try {\n const readyUrl = new URL(\"/readyz\", serverUrl);\n const response = await fetch(readyUrl, { signal: AbortSignal.timeout(timeoutMs) });\n return response.ok;\n } catch {\n return false;\n }\n}\n\n/**\n * The error for a directory with no running server of its own. With a\n * `serverUrl` there is a record whose server is not running; without one there\n * is no record in the directory or a parent. The hint offers `--server` for the\n * case where someone really does mean another directory's server, since\n * nothing falls back to one on its own.\n */\nexport function localServerNotRunning(serverUrl?: string): ZitadelError {\n return new ZitadelError(\"E_LOCAL_SERVER_NOT_RUNNING\", \"Local Zitadel server is not running\", {\n hint: serverUrl\n ? `No healthy local server responded at ${serverUrl}.`\n : \"No local server has been started in this directory or a parent. Run `zitadel start`, or name a server another directory started with --server <url>.\",\n nextCommands: [unscopedCommand(\"start\")],\n details: { server_url: serverUrl },\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/).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 normalizeRuntimeMetadata(input: Record<string, unknown>): RuntimeMetadata {\n if (\n input.schema_version !== 1 ||\n typeof input.port !== \"number\" ||\n !isValidPort(input.port) ||\n typeof input.server_url !== \"string\" ||\n !isValidServerUrl(input.server_url, input.port) ||\n typeof input.data_dir !== \"string\" ||\n typeof input.created_at !== \"string\" ||\n typeof input.cli_version !== \"string\"\n ) {\n throw malformedRuntime(input);\n }\n\n const backend = input.backend === undefined ? \"docker\" : input.backend;\n const base = {\n schema_version: 1 as const,\n port: input.port,\n server_url: input.server_url,\n data_dir: input.data_dir,\n created_at: input.created_at,\n cli_version: input.cli_version,\n env: isEnvSummary(input.env) ? input.env : undefined,\n };\n\n if (backend === \"binary\") {\n if (\n typeof input.pid !== \"number\" ||\n !Number.isInteger(input.pid) ||\n input.pid <= 0 ||\n typeof input.command !== \"string\" ||\n typeof input.log_path !== \"string\" ||\n typeof input.server_package !== \"string\" ||\n typeof input.server_version !== \"string\"\n ) {\n throw malformedRuntime(input);\n }\n return {\n ...base,\n backend: \"binary\",\n pid: input.pid,\n command: input.command,\n log_path: input.log_path,\n server_package: input.server_package,\n server_version: input.server_version,\n };\n }\n\n if (\n backend !== \"docker\" ||\n typeof input.container_name !== \"string\" ||\n typeof input.container_id !== \"string\" ||\n typeof input.image !== \"string\"\n ) {\n throw malformedRuntime(input);\n }\n return {\n ...base,\n backend: \"docker\",\n container_name: input.container_name,\n container_id: input.container_id,\n image: input.image,\n };\n}\n\nasync function nearestExistingDirectory(path: string): Promise<string> {\n let current = path;\n while (true) {\n try {\n const info = await stat(current);\n if (!info.isDirectory()) {\n throw new Error(`${current} exists but is not a directory`);\n }\n return current;\n } catch (error) {\n if (!isErrno(error, \"ENOENT\")) {\n throw error;\n }\n const parent = dirname(current);\n if (parent === current) {\n throw error;\n }\n current = parent;\n }\n }\n}\n\nexport function runtimeSummary(metadata: RuntimeMetadata | undefined): Record<string, unknown> {\n if (!metadata) {\n return { configured: false };\n }\n const base = {\n configured: true,\n backend: metadata.backend,\n port: metadata.port,\n server_url: metadata.server_url,\n data_dir: metadata.data_dir,\n created_at: metadata.created_at,\n env: metadata.env ?? EMPTY_SUMMARY,\n };\n if (metadata.backend === \"binary\") {\n return {\n ...base,\n pid: metadata.pid,\n command: metadata.command,\n log_path: metadata.log_path,\n server_package: metadata.server_package,\n server_version: metadata.server_version,\n };\n }\n return {\n ...base,\n container_name: metadata.container_name,\n container_id: metadata.container_id,\n image: metadata.image,\n };\n}\n\nfunction isValidPort(value: number): boolean {\n return Number.isInteger(value) && value >= 1 && value <= 65_535;\n}\n\nfunction isValidServerUrl(value: string, port: number): boolean {\n try {\n const url = new URL(value);\n return (\n (url.protocol === \"http:\" || url.protocol === \"https:\") &&\n url.hostname.length > 0 &&\n explicitUrlPort(value) === port\n );\n } catch {\n return false;\n }\n}\n\nfunction explicitUrlPort(value: string): number | undefined {\n const match = value.match(/^[a-z][a-z\\d+\\-.]*:\\/\\/(?:\\[[^\\]]+\\]|[^/?#:]+):(\\d+)(?:[/?#]|$)/i);\n if (!match) {\n return undefined;\n }\n const port = Number(match[1]);\n return isValidPort(port) ? port : undefined;\n}\n\nfunction malformedRuntime(input: Record<string, unknown>): ZitadelError {\n return new ZitadelError(\"E_VALIDATION\", `${LOCAL_RUNTIME_FILE} is malformed`, {\n hint: \"Run `zitadel reset --force`, then `zitadel start`.\",\n nextCommands: [unscopedCommand(\"reset --force\"), unscopedCommand(\"start\")],\n details: input,\n });\n}\n\n/**\n * The malformed-record error again, with its recovery aimed at `dir`. The\n * commands are written out only when `dir` can sit in them unquoted on every\n * shell (POSIX, PowerShell, cmd.exe quote differently); otherwise the\n * arguments are handed over as `details.suggested_args`, which no shell reads.\n */\nexport function retargetMalformedRuntime(error: unknown, dir: string): unknown {\n if (!(error instanceof ZitadelError) || error.message !== `${LOCAL_RUNTIME_FILE} is malformed`) {\n return error;\n }\n const resetArgs = [\"reset\", \"--force\", \"--cwd\", dir];\n const startArgs = [\"start\", \"--cwd\", dir];\n const suggestedArgs = [resetArgs, startArgs];\n const portable = suggestedArgs.every((args) => args.every(isPortableShellWord));\n const reset = `zitadel ${resetArgs.join(\" \")}`;\n const start = `zitadel ${startArgs.join(\" \")}`;\n return new ZitadelError(error.code, error.message, {\n hint: portable\n ? `Run \\`${reset}\\`, then \\`${start}\\`.`\n : `Run \\`zitadel reset --force\\`, then \\`zitadel start\\`, each with --cwd ${dir} ` +\n \"(details.suggested_args holds the exact arguments).\",\n ...(portable\n ? {\n nextCommands: [\n unscopedCommand(resetArgs.join(\" \")),\n unscopedCommand(startArgs.join(\" \")),\n ],\n }\n : {}),\n details: { ...(error.details as Record<string, unknown>), suggested_args: suggestedArgs },\n });\n}\n","import { setTimeout as sleep } from \"node:timers/promises\";\n\n/**\n * Time, as the code that waits for something sees it. Waiting for a server to\n * answer, or for another start to finish, polls; taking the clock as a\n * dependency lets a test move time by hand instead of waiting for it.\n */\nexport interface Clock {\n now(): number;\n /** Waits `ms`, or until `signal` aborts if that comes first. */\n wait(ms: number, signal?: AbortSignal): Promise<void>;\n}\n\nexport const realClock: Clock = {\n now: () => Date.now(),\n wait: async (ms, signal) => {\n try {\n await sleep(ms, undefined, { signal });\n } catch (error) {\n if (!signal?.aborted) {\n throw error;\n }\n }\n },\n};\n\n/**\n * A signal that aborts when the CLI is interrupted (Ctrl-C) or asked to stop,\n * for what runs until then, such as following a log. `dispose` stops\n * listening.\n */\nexport function stopSignal(): { signal: AbortSignal; dispose: () => void } {\n const controller = new AbortController();\n const abort = () => controller.abort();\n process.once(\"SIGINT\", abort);\n process.once(\"SIGTERM\", abort);\n return {\n signal: controller.signal,\n dispose: () => {\n process.off(\"SIGINT\", abort);\n process.off(\"SIGTERM\", abort);\n },\n };\n}\n","/**\n * The lifecycle of one directory's server, written against interfaces so it\n * can be tested with no processes, sockets, files or real time.\n *\n * This is the layer below `LocalServer` (the public class) and above the\n * launchers (`BinaryLauncher`, `DockerLauncher`). It decides what to do (reuse\n * the running server, restart it, which port to take, when a start has failed);\n * the launchers know how to run and stop a server; the probes and the store\n * know about the machine. Keep it that way: if this file starts to know how a\n * process is spawned or how a port is probed, the tests that make it cheap to\n * change stop being able to cover it.\n */\nimport { DEFAULT_LOCAL_SERVER_PORT } from \"../runtime\";\nimport { type Clock, realClock } from \"./clock\";\n\n/**\n * What the lifecycle needs to know about a running server, whatever started it.\n * Which process or container it is stays in the launcher's own record type.\n */\nexport type ServerRecord = Readonly<{\n port: number;\n server_url: string;\n}>;\n\n/**\n * Where a directory keeps its record of the server it started (in practice\n * `.zitadel/local/runtime.json`). The record is what ties a directory to its own\n * server, so everything that must not reach another directory's server starts\n * from it.\n */\nexport interface ServerStore<R extends ServerRecord> {\n read(): Promise<R | undefined>;\n write(record: R): Promise<void>;\n}\n\n/**\n * What stopping did. `stale` means there was nothing left to stop (the process\n * was already gone, or its pid had become another program and was left alone);\n * it is not a failure, so stopping twice is safe. `failed` means it was still\n * running after being signalled.\n */\nexport type StopOutcome = Readonly<{\n pid?: number;\n status: \"failed\" | \"stale\" | \"stopped\";\n target?: \"process\" | \"process-group\";\n signal?: NodeJS.Signals;\n}>;\n\ndeclare const launchedBrand: unique symbol;\n\n/**\n * A record that `launch` has just returned, as opposed to one read back from\n * disk. The two are asked different questions about whether they are alive (see\n * {@link Launcher.isAlive} and {@link Launcher.isLaunchedAlive}), and the type\n * keeps them apart: only a launcher can make one, so a recorded server can never\n * be passed where a just-launched one is expected.\n */\nexport type Launched<R extends ServerRecord> = R & { readonly [launchedBrand]: true };\n\n/** Marks a record as just launched. Only launchers call this, from `launch`. */\nexport function launched<R extends ServerRecord>(record: R): Launched<R> {\n return record as Launched<R>;\n}\n\n/**\n * Runs the server. The binary and Docker runtimes are two implementations; the\n * lifecycle treats a record as opaque beyond its port and URL, so a new way of\n * running a server needs a launcher and a record type, not changes here.\n */\nexport interface Launcher<R extends ServerRecord> {\n /** Starts a server on the port and returns the record that identifies it. It need not be ready. */\n launch(spec: { port: number; serverUrl: string }): Promise<Launched<R>>;\n /**\n * Whether the server a record read back from disk names still exists,\n * answering or not. This must check identity, not just existence: pids are\n * reused, and after a reboot the recorded one can be any program.\n */\n isAlive(record: R): Promise<boolean>;\n /**\n * Whether a server that `launch` has just returned still exists. It does not\n * check identity, on purpose: there is nothing older it could be confused\n * with, and on Linux the process list still shows a just-spawned process under\n * its parent's name until it has exec'd, so asking would wrongly say \"not ours\"\n * (this took down every journey lane once).\n */\n isLaunchedAlive(server: Launched<R>): Promise<boolean>;\n /**\n * What identifies the server in an error about it (its pid and log file, or its\n * container). The launcher owns this because only it knows what a record holds,\n * which keeps the error mapping from needing to know the backends.\n */\n describe(record: R): Readonly<Record<string, unknown>>;\n /** Stops it, `stale` when there was nothing left to stop. */\n terminate(record: R): Promise<StopOutcome>;\n /** The end of its own log, for explaining a failed start; read before it is cleaned up. */\n logTail?(record: R, lines: number): Promise<string | undefined>;\n}\n\n/**\n * What is known about ports. `isFree` says whether the port can be used right\n * now; `reserve` is what keeps two starts from choosing the same free port.\n */\nexport interface PortProbe {\n /** Whether nothing holds the port: it can neither be connected to nor bound. */\n isFree(port: number): Promise<boolean>;\n /**\n * Claims a port for one start until the returned function releases it, so that\n * two starts that choose at the same moment cannot choose the same port.\n * `undefined` when another start already has it.\n */\n reserve(port: number): Promise<(() => Promise<void>) | undefined>;\n}\n\n/**\n * Whether something answers as a healthy Zitadel at a URL. It cannot tell whose\n * server it is, which is why a launcher's identity check always comes with it.\n */\nexport interface HealthProbe {\n isHealthy(serverUrl: string): Promise<boolean>;\n}\n\n/**\n * `stopped`: no record. `running`: the recorded server is alive and answering.\n * `dead`: a record whose server is gone, or alive but not answering; either way\n * the next start clears it.\n */\nexport type ServerState<R extends ServerRecord> =\n | { kind: \"stopped\" }\n | { kind: \"running\"; record: R }\n | { kind: \"dead\"; record: R };\n\nexport type LifecycleOptions<R extends ServerRecord> = Readonly<{\n /**\n * A port that was asked for. It is taken as asked or refused, never replaced:\n * a server somewhere the caller did not look for it is worse than an error.\n * Absent, the directory keeps the port it had, or takes the first free one.\n */\n port?: number;\n /** The port a directory without a record tries first (8080 by default). */\n firstPort?: number;\n /**\n * The port the directory's server had under the other backend. A backend\n * switch keeps it when it can, because the app's configuration names it.\n */\n previousPort?: number;\n /** A running server is kept only when this holds (right version, right image); otherwise it is restarted. */\n reusable?: (record: R) => boolean;\n /** How long to wait for a new server to answer before giving up on it. */\n startTimeoutMs?: number;\n /** How often to ask whether it answers. Waiting for a server has no event to wait on, so it polls. */\n pollIntervalMs?: number;\n /** Time. Tests pass one they move by hand, so none of them waits in real time. */\n clock?: Clock;\n}>;\n\nexport type LifecycleDeps<R extends ServerRecord> = Readonly<{\n store: ServerStore<R>;\n launcher: Launcher<R>;\n ports: PortProbe;\n health: HealthProbe;\n}>;\n\n/** How many ports above the first are tried before giving up. */\nconst PORT_SEARCH_RANGE = 100;\n/**\n * How many times a server that is alive is asked whether it answers before it is\n * called dead. One slow answer (a busy machine, a migration) must not make a\n * start stop a working server.\n */\nconst HEALTH_ATTEMPTS = 3;\n/** How many times a start that lost a race for its port tries the next one. */\nconst PORT_RACE_RETRIES = 3;\n\n/** Every port in the search range was taken. */\nexport class NoFreePortError extends Error {\n readonly firstPort: number;\n\n constructor(firstPort: number) {\n super(`No free port from ${String(firstPort)} to ${String(firstPort + PORT_SEARCH_RANGE - 1)}`);\n this.firstPort = firstPort;\n }\n}\n\n/** A port that was explicitly asked for is held, so the start is refused rather than moved. */\nexport class PortInUseError extends Error {\n readonly port: number;\n\n constructor(port: number) {\n super(`Port ${String(port)} is already in use`);\n this.port = port;\n }\n}\n\n/**\n * A server was launched but did not become ready. `cleanup` says what stopping\n * it did, `logTail` is what it logged: the lifecycle reads the log before\n * cleaning up because cleaning up a container removes its log, which is the\n * only explanation of why it failed.\n */\nexport class ServerStartError<R extends ServerRecord> extends Error {\n readonly reason: \"exited\" | \"timeout\";\n readonly record: R;\n readonly cleanup: StopOutcome;\n readonly logTail: string | undefined;\n /** What identifies the server, from {@link Launcher.describe}. */\n readonly details: Readonly<Record<string, unknown>>;\n\n constructor(\n reason: \"exited\" | \"timeout\",\n record: R,\n cleanup: StopOutcome,\n details: Readonly<Record<string, unknown>>,\n logTail?: string,\n ) {\n super(\n reason === \"exited\"\n ? \"The server exited before it became healthy\"\n : \"The server did not become healthy in time\",\n );\n this.reason = reason;\n this.record = record;\n this.cleanup = cleanup;\n this.logTail = logTail;\n this.details = details;\n }\n}\n\n/** A server that had to be stopped (to restart or move it) was still running afterwards. */\nexport class ServerStopError<R extends ServerRecord> extends Error {\n readonly record: R;\n readonly outcome: StopOutcome;\n\n constructor(record: R, outcome: StopOutcome) {\n super(\"The server did not stop\");\n this.record = record;\n this.outcome = outcome;\n }\n}\n\n/**\n * One server for one directory: it starts, reports on and stops the server whose\n * record the directory's store holds. Everything it touches arrives through its\n * dependencies, so the lifecycle is testable without processes or sockets.\n *\n * It does not lock. Two starts in one directory are serialised by the caller\n * (see `withStartLock`), because only the caller knows what \"one directory\" is.\n */\nexport class Lifecycle<R extends ServerRecord> {\n private readonly deps: LifecycleDeps<R>;\n private readonly options: LifecycleOptions<R>;\n\n constructor(deps: LifecycleDeps<R>, options: LifecycleOptions<R> = {}) {\n this.deps = deps;\n this.options = options;\n }\n\n /**\n * `running` needs both a live server (by identity, not by pid alone) and a\n * healthy answer at its URL. A healthy answer by itself proves nothing: after\n * a directory's server stops, another directory's can take its port.\n */\n async state(): Promise<ServerState<R>> {\n const record = await this.deps.store.read();\n if (!record) {\n return { kind: \"stopped\" };\n }\n const alive = await this.deps.launcher.isAlive(record);\n return alive && (await this.answers(record.server_url))\n ? { kind: \"running\", record }\n : { kind: \"dead\", record };\n }\n\n /** Whether a server that is alive answers, asking up to {@link HEALTH_ATTEMPTS} times. */\n private async answers(serverUrl: string): Promise<boolean> {\n const clock = this.options.clock ?? realClock;\n for (let attempt = 1; attempt <= HEALTH_ATTEMPTS; attempt++) {\n if (await this.deps.health.isHealthy(serverUrl)) {\n return true;\n }\n if (attempt < HEALTH_ATTEMPTS) {\n await clock.wait(this.options.pollIntervalMs ?? 1000);\n }\n }\n return false;\n }\n\n /**\n * Makes sure the directory has a running server and returns its record.\n *\n * If the recorded server is running and acceptable (`reusable`, and on the\n * requested port if one was), it is kept. Otherwise whatever is recorded is\n * stopped, a port is claimed, and a new server is launched and waited for.\n * The record is written as soon as the server is launched (see {@link save}),\n * so an interrupted start leaves a server that can be found and stopped. A\n * failed start stops its server, so what it leaves reads as `dead`, never as\n * a running server.\n */\n async start(): Promise<{ record: R; alreadyRunning: boolean }> {\n const state = await this.state();\n const requested = this.options.port;\n if (\n state.kind === \"running\" &&\n (requested === undefined || requested === state.record.port) &&\n (this.options.reusable?.(state.record) ?? true)\n ) {\n await this.deps.store.write(state.record);\n return { record: state.record, alreadyRunning: true };\n }\n\n const previous = state.kind === \"stopped\" ? undefined : state.record;\n // A port other than the running server's own is checked before that server\n // is touched, so a refused move leaves it running. Its own port cannot be\n // checked yet: it is held by the server about to be stopped.\n if (requested !== undefined && requested !== previous?.port) {\n await this.assertFree(requested);\n }\n if (previous) {\n await this.terminate(previous);\n }\n let preferred = previous?.port ?? this.options.previousPort;\n for (let attempt = 0; ; attempt++) {\n const claim = await claimFreePort(\n this.deps.ports,\n requested,\n preferred,\n this.options.firstPort,\n );\n try {\n let record: Launched<R>;\n try {\n record = await this.launchAndWait(claim.port);\n } catch (error) {\n // Someone else took the port between claiming it and binding it (a\n // process outside our claims, or a Docker publish that failed). The\n // choice was automatic, so the next port is tried. A server that failed\n // with its port still free crashed, and says so instead of being retried.\n if (\n requested === undefined &&\n attempt < PORT_RACE_RETRIES &&\n !(error instanceof ServerStopError) &&\n (error instanceof ServerStartError ? error.reason === \"exited\" : true) &&\n !(await this.deps.ports.isFree(claim.port))\n ) {\n preferred = claim.port + 1;\n continue;\n }\n throw error;\n }\n return { record, alreadyRunning: false };\n } finally {\n // A claim that cannot be removed is a file whose owner is gone, which\n // the next start takes over; it must not hide how this start ended.\n await claim.release().catch(() => undefined);\n }\n }\n }\n\n /**\n * Records a server the moment it is launched, before it is ready. A server\n * that is launched and not recorded cannot be stopped by anything, and the\n * next start would run a second one over its data: this is what happens when\n * the CLI is interrupted or killed while the server boots. A record of a\n * server that is not ready reads as `dead`, which the next start stops and\n * replaces, and a failed start stops its server (see {@link startFailure}).\n *\n * If the record cannot be written, the server is stopped instead of being left\n * unrecorded. That failure is not retried on another port: the server itself\n * holds this one, so a retry would launch another beside it.\n */\n private async save(record: Launched<R>): Promise<void> {\n try {\n await this.deps.store.write(record);\n } catch (error) {\n const outcome = await this.terminateQuietly(record);\n if (outcome.status === \"failed\") {\n throw new ServerStopError(record, outcome);\n }\n throw error;\n }\n }\n\n /** Stops a server on a path that is already failing, where a second error would hide the first. */\n private async terminateQuietly(record: R): Promise<StopOutcome> {\n try {\n return await this.deps.launcher.terminate(record);\n } catch {\n return { status: \"failed\" };\n }\n }\n\n /** Launches on the port and waits until it is ready; throws {@link ServerStartError} if it does not become so. */\n private async launchAndWait(port: number): Promise<Launched<R>> {\n const record = await this.deps.launcher.launch({ port, serverUrl: serverUrlFor(port) });\n await this.save(record);\n try {\n await this.waitUntilReady(record);\n } catch (error) {\n if (!(error instanceof ServerStartError)) {\n // Something other than the server failing (a probe that threw): the\n // server is still running and must not be left behind.\n await this.terminateQuietly(record);\n }\n throw error;\n }\n return record;\n }\n\n /**\n * Stops the recorded server. `not-running` when nothing was recorded or\n * nothing was left, which is not an error: stopping twice is safe. The record\n * stays, so the directory keeps its port for the next start.\n */\n async stop(): Promise<{ result: \"stopped\" | \"not-running\"; record?: R }> {\n const record = await this.deps.store.read();\n if (!record) {\n return { result: \"not-running\" };\n }\n const outcome = await this.terminate(record);\n return { result: outcome.status === \"stopped\" ? \"stopped\" : \"not-running\", record };\n }\n\n /** Refuses a port that is held. Used before anything is torn down, so a refusal changes nothing. */\n private async assertFree(port: number): Promise<void> {\n if (!(await this.deps.ports.isFree(port))) {\n throw new PortInUseError(port);\n }\n }\n\n /** Stops a server, and treats one that will not stop as an error, because starting over it would fight it for its port and data. */\n private async terminate(record: R): Promise<StopOutcome> {\n const outcome = await this.deps.launcher.terminate(record);\n if (outcome.status === \"failed\") {\n throw new ServerStopError(record, outcome);\n }\n return outcome;\n }\n\n /**\n * Ready means the server is alive and answering, and still alive once it has\n * answered. The second check is for a launch that lost a race for its port: it\n * dies right after failing to bind while the other server holding the port\n * keeps answering, so \"something answered\" is not \"we are ready\". Port claims\n * make this rare; this is the backstop.\n *\n * It polls, because a starting server gives no event to wait on; the clock is\n * injected so that tests do not wait in real time.\n */\n private async waitUntilReady(record: Launched<R>): Promise<void> {\n const timeout = this.options.startTimeoutMs ?? 90_000;\n const interval = this.options.pollIntervalMs ?? 1000;\n const clock = this.options.clock ?? realClock;\n const started = clock.now();\n while (clock.now() - started < timeout) {\n if (!(await this.deps.launcher.isLaunchedAlive(record))) {\n throw await this.startFailure(\"exited\", record);\n }\n if (await this.deps.health.isHealthy(record.server_url)) {\n if (!(await this.deps.launcher.isLaunchedAlive(record))) {\n throw await this.startFailure(\"exited\", record);\n }\n return;\n }\n await clock.wait(interval);\n }\n throw await this.startFailure(\"timeout\", record);\n }\n\n /** Builds the failure for a server that did not become ready, reading its log before cleaning it up. */\n private async startFailure(\n reason: \"exited\" | \"timeout\",\n record: R,\n ): Promise<ServerStartError<R>> {\n // The log goes first: cleaning up may remove it with the server.\n const logTail = await this.deps.launcher.logTail?.(record, 40).catch(() => undefined);\n return new ServerStartError(\n reason,\n record,\n await this.terminateQuietly(record),\n this.deps.launcher.describe(record),\n logTail,\n );\n }\n}\n\nexport type PortClaim = Readonly<{ port: number; release: () => Promise<void> }>;\n\n/**\n * Claims the port a start will use. A port that was asked for is taken as asked\n * or refused. Otherwise the folder's own port, when it is free, so that URLs\n * written into the app's configuration stay valid across restarts, and else the\n * first free port above it: a port someone else holds is skipped, never shared.\n */\nexport async function claimFreePort(\n ports: PortProbe,\n requested?: number,\n preferred?: number,\n firstPort: number = DEFAULT_LOCAL_SERVER_PORT,\n): Promise<PortClaim> {\n // A port is looked at again once it is claimed: another start may have bound\n // it and let go of its claim between the first look and this claim.\n if (requested !== undefined) {\n const release = await ports.reserve(requested);\n if (!release) {\n throw new PortInUseError(requested);\n }\n if (!(await ports.isFree(requested))) {\n await release();\n throw new PortInUseError(requested);\n }\n return { port: requested, release };\n }\n const first = preferred ?? firstPort;\n for (let port = first; port < first + PORT_SEARCH_RANGE; port++) {\n if (!(await ports.isFree(port))) {\n continue;\n }\n const release = await ports.reserve(port);\n if (!release) {\n continue;\n }\n if (await ports.isFree(port)) {\n return { port, release };\n }\n await release();\n }\n throw new NoFreePortError(first);\n}\n\nexport function serverUrlFor(port: number): string {\n return `http://localhost:${String(port)}`;\n}\n","import { spawn } from \"node:child_process\";\n\nimport { ZitadelError, isErrno } from \"../../errors\";\nimport { unscopedCommand } from \"../../suggestion\";\nimport {\n EMPTY_ENV,\n EMPTY_SUMMARY,\n type EnvSummary,\n type ResolvedEnv,\n envSummary,\n} from \"../env-vars\";\nimport {\n CONTAINER_DATA_DIR,\n CONTAINER_HTTP_PORT,\n type ContainerIdentity,\n type DockerRuntimeMetadata,\n} from \"../runtime\";\nimport type { LogSink } from \"../server-log\";\nimport { stopSignal } from \"./clock\";\nimport { type Launched, type Launcher, type StopOutcome, launched } from \"./lifecycle\";\n\nexport type DockerResult = {\n status: number;\n stdout: string;\n stderr: string;\n};\n\n/** Where the local admin's bootstrap user document is mounted in the container. */\nconst CONTAINER_ADMIN_USER_FILE = \"/var/lib/zitadel/bootstrap/admin-user.json\";\n\nexport type DockerLaunchSpec = Readonly<{\n cliVersion: string;\n containerName: string;\n image: string;\n dataDir: string;\n identity?: ContainerIdentity;\n /**\n * Project variables, passed as bare `--env NAME` so Docker copies each\n * value from the docker client's environment; no value appears in argv.\n */\n env?: ResolvedEnv;\n /** Host path of the local admin's bootstrap user document. */\n userFile?: string;\n}>;\n\n/** The arguments of one `docker run`: the launch spec plus the port it is published on. */\nexport type DockerRunSpec = DockerLaunchSpec & Readonly<{ port: number }>;\n\n/**\n * Everything about running the server in a container: the `docker run` it\n * starts, whether the container is alive, how it is stopped and removed, and its\n * logs. The container is named for the directory, so whatever holds that name is\n * this directory's. That is why a container needs no identity check of the kind a\n * pid does: another directory's server cannot be running under this name.\n */\nexport class DockerLauncher implements Launcher<DockerRuntimeMetadata> {\n private readonly spec: DockerLaunchSpec;\n\n constructor(spec: DockerLaunchSpec) {\n this.spec = spec;\n }\n\n /**\n * Starts the container on the chosen port and returns the record that identifies it.\n *\n * The container is named for the directory, so a container with that name is\n * this directory's own leftover (a record that was lost, a container that\n * stopped) and is removed first. If `docker run` fails, whatever it may have\n * created is removed too, so a failed start leaves nothing behind.\n */\n async launch(target: {\n port: number;\n serverUrl: string;\n }): Promise<Launched<DockerRuntimeMetadata>> {\n const { spec } = this;\n // A leftover of an earlier start (a record that was lost, a container that\n // stopped) is removed before the name is taken again.\n await DockerLauncher.remove(spec.containerName);\n await ensureImage(spec.image);\n const env = spec.env ?? EMPTY_ENV;\n let result: DockerResult;\n try {\n result = await requireDocker(\n DockerLauncher.runArgs({ ...spec, port: target.port }, env.injected),\n \"Start local Zitadel container\",\n env.values,\n );\n } catch (error) {\n // A run that failed after the container was created leaves it behind.\n await DockerLauncher.remove(spec.containerName).catch(() => false);\n throw error;\n }\n return launched(\n DockerLauncher.metadata({\n cwdDataDir: spec.dataDir,\n cliVersion: spec.cliVersion,\n containerName: spec.containerName,\n containerId: result.stdout.trim(),\n image: spec.image,\n port: target.port,\n serverUrl: target.serverUrl,\n env: envSummary(env),\n }),\n );\n }\n\n /**\n * Whether the container is running. The container name is per directory, so\n * unlike a pid it cannot have been reused by another directory's server.\n */\n async isAlive(record: DockerRuntimeMetadata): Promise<boolean> {\n return (await DockerLauncher.inspect(record.container_name)).running;\n }\n\n /** A container just started is asked the same question as a recorded one: its name cannot be another's. */\n isLaunchedAlive(server: Launched<DockerRuntimeMetadata>): Promise<boolean> {\n return this.isAlive(server);\n }\n\n /** The container, which is where to look when a start fails. */\n describe(record: DockerRuntimeMetadata): Readonly<Record<string, unknown>> {\n return { runtime: \"docker\", container_name: record.container_name };\n }\n\n /**\n * The end of the container's log, read before a failed start removes the container.\n */\n logTail(record: DockerRuntimeMetadata, lines: number): Promise<string> {\n return DockerLauncher.readLogs(record.container_name, lines);\n }\n\n /**\n * Stops and removes the container; `stale` when it was already gone.\n */\n async terminate(record: DockerRuntimeMetadata): Promise<StopOutcome> {\n return { status: (await DockerLauncher.remove(record.container_name)) ? \"stopped\" : \"stale\" };\n }\n\n /**\n * The `docker run` arguments. The container's port is published on loopback\n * only, so a local server is not reachable from the network. Project variables\n * are passed as bare `--env NAME` so Docker copies them from the client's\n * environment and no value appears in the argument list.\n */\n static runArgs(spec: DockerRunSpec, envNames: readonly string[] = []): string[] {\n const args = [\n \"run\",\n \"--detach\",\n \"--name\",\n spec.containerName,\n \"--publish\",\n `127.0.0.1:${spec.port}:${CONTAINER_HTTP_PORT}`,\n \"--volume\",\n `${spec.dataDir}:${CONTAINER_DATA_DIR}`,\n // Project variables first: Docker takes the last value for a repeated\n // name, so the CLI's own settings below always win.\n ...envNames.flatMap((name) => [\"--env\", name]),\n \"--env\",\n `NEXTGEN_SERVER_ADDRESS=:${CONTAINER_HTTP_PORT}`,\n \"--env\",\n `NEXTGEN_SERVER_DATA_DIR=${CONTAINER_DATA_DIR}`,\n // Browser-facing URLs (claim, dashboard) must use the host-visible port\n // published above, not the cloud default the server config falls back to.\n \"--env\",\n `NEXTGEN_SERVER_PUBLIC_BASE=http://localhost:${spec.port}`,\n ];\n // The platform project and the local admin travel together: the admin is a\n // user of that project. A caller that wants a bare single-project instance\n // (test harnesses) starts without a user file and gets neither.\n if (spec.userFile) {\n args.push(\n \"--env\",\n \"NEXTGEN_PLATFORM_BOOTSTRAP_PROJECT=true\",\n \"--volume\",\n `${spec.userFile}:${CONTAINER_ADMIN_USER_FILE}:ro`,\n );\n }\n\n if (spec.identity) {\n args.push(\n \"--volume\",\n `${spec.identity.passwdFile}:/etc/passwd:ro`,\n \"--volume\",\n `${spec.identity.groupFile}:/etc/group:ro`,\n \"--user\",\n `${spec.identity.uid}:${spec.identity.gid}`,\n );\n }\n\n args.push(spec.image);\n // The image's CMD is `--migrate`; passing arguments replaces it, so keep it.\n if (spec.userFile) {\n args.push(\"--migrate\", \"--user-file\", CONTAINER_ADMIN_USER_FILE);\n }\n return args;\n }\n\n /**\n * Builds the record of a container that was started.\n */\n static metadata(input: {\n cwdDataDir: string;\n cliVersion: string;\n containerName: string;\n containerId: string;\n image: string;\n port: number;\n serverUrl: string;\n env?: EnvSummary;\n }): DockerRuntimeMetadata {\n return {\n schema_version: 1,\n backend: \"docker\",\n container_name: input.containerName,\n container_id: input.containerId,\n image: input.image,\n port: input.port,\n server_url: input.serverUrl,\n data_dir: input.cwdDataDir,\n created_at: new Date().toISOString(),\n cli_version: input.cliVersion,\n env: envSummary(input.env ?? EMPTY_SUMMARY),\n };\n }\n\n /**\n * Whether the Docker daemon answers, as `docker version`'s result.\n */\n static available(): Promise<DockerResult> {\n return runDocker([\"version\", \"--format\", \"{{.Server.Version}}\"]);\n }\n\n /** Where the image can be had from: already here, or at the registry. Throws when neither. */\n static async imageAvailable(image: string): Promise<\"local\" | \"remote\"> {\n if (await imageExists(image)) {\n return \"local\";\n }\n\n const args = [\"manifest\", \"inspect\", image];\n let result: DockerResult;\n try {\n result = await runDocker(args);\n } catch (error) {\n throw dockerError(`Inspect Docker image ${image}`, args, error);\n }\n if (result.status === 0) {\n return \"remote\";\n }\n throw dockerError(`Inspect Docker image ${image}`, args, result);\n }\n\n /**\n * What Docker says about a container: whether it exists, is running, and which\n * image it runs. Absent containers are an answer (`exists: false`), not an error.\n */\n static async inspect(containerName: string): Promise<{\n exists: boolean;\n running: boolean;\n id?: string;\n image?: string;\n }> {\n const result = await runDocker([\n \"inspect\",\n \"--format\",\n \"{{.Id}} {{.State.Running}} {{.Config.Image}}\",\n containerName,\n ]);\n if (result.status !== 0) {\n return { exists: false, running: false };\n }\n const [id, running, ...imageParts] = result.stdout.trim().split(/\\s+/);\n return { exists: true, running: running === \"true\", id, image: imageParts.join(\" \") };\n }\n\n /**\n * Stops and removes the container. `false` when there was none to remove,\n * which is also the answer where Docker is not installed: the default runtime\n * runs without it, so `stop`, `reset` and a `start` that moves a directory off\n * a container must not fail for want of a `docker` to ask.\n */\n static async remove(containerName: string): Promise<boolean> {\n let inspect: Awaited<ReturnType<typeof DockerLauncher.inspect>>;\n try {\n inspect = await DockerLauncher.inspect(containerName);\n } catch (error) {\n // No `docker` on PATH: Docker is not installed, so it runs no container.\n if (isErrno(error, \"ENOENT\")) {\n return false;\n }\n throw error;\n }\n if (!inspect.exists) {\n return false;\n }\n if (inspect.running) {\n await requireDocker([\"stop\", containerName], `Stop ${containerName}`);\n }\n await requireDocker([\"rm\", containerName], `Remove ${containerName}`);\n return true;\n }\n\n /**\n * The last `tail` lines of the container's log, or all of it. `docker logs`\n * replays the container's two streams separately, and the server logs to\n * stderr, so both are returned; reading stdout alone gave an empty log.\n */\n static async readLogs(containerName: string, tail: number | \"all\"): Promise<string> {\n const result = await requireDocker(\n [\"logs\", \"--tail\", String(tail), containerName],\n \"Read logs\",\n );\n // `docker logs` replays each stream on its own: the server logs to stderr.\n return result.stdout + result.stderr;\n }\n\n /**\n * Hands `sink` the container's log until interrupted. With a line count,\n * Docker picks the last lines itself and they arrive as appended, with what\n * follows them. With `\"all\"`, `sink` gets the whole log as it is first, for a\n * caller that picks lines Docker cannot (those at a level). `docker logs\n * --follow` then replays the log before it streams, so the replay is skipped,\n * stream by stream, by the lines read the first time; only whole lines are\n * handed over then, so a line still being written is not handed over twice.\n */\n static async followLogs(\n containerName: string,\n tail: number | \"all\",\n sink: LogSink,\n ): Promise<void> {\n const replayed = { stdout: 0, stderr: 0 };\n if (tail === \"all\") {\n const existing = await requireDocker([\"logs\", \"--tail\", \"all\", containerName], \"Read logs\");\n const stdout = wholeLines(existing.stdout);\n const stderr = wholeLines(existing.stderr);\n sink.existing(stdout + stderr);\n replayed.stdout = lineBreaks(stdout);\n replayed.stderr = lineBreaks(stderr);\n }\n const stop = stopSignal();\n try {\n await streamDocker(\n [\"logs\", \"--tail\", String(tail), \"--follow\", containerName],\n {\n stdout: afterLines(replayed.stdout, sink.appended),\n stderr: afterLines(replayed.stderr, sink.appended),\n },\n stop.signal,\n );\n } finally {\n stop.dispose();\n }\n }\n\n /**\n * The user the container runs as, so files it writes into the mounted data\n * directory belong to the developer and not to root. Empty where there are no\n * user ids (Windows).\n */\n static currentUser(): { uid?: number; gid?: number } {\n const getuid = process.getuid;\n const getgid = process.getgid;\n if (typeof getuid !== \"function\") {\n return {};\n }\n const uid = getuid();\n const gid = typeof getgid === \"function\" ? getgid() : uid;\n return { uid, gid };\n }\n}\n\n/**\n * Runs `docker` and collects its output; the exit status is part of the result, not an exception.\n */\nasync function runDocker(\n args: string[],\n env: Readonly<Record<string, string>> = {},\n): Promise<DockerResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"docker\", args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, ...env },\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout?.setEncoding(\"utf8\");\n child.stderr?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", (chunk: string) => {\n stdout += chunk;\n });\n child.stderr?.on(\"data\", (chunk: string) => {\n stderr += chunk;\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n resolve({ status: code ?? 1, stdout, stderr });\n });\n });\n}\n\n/**\n * Runs `docker` until it ends or `signal` aborts, handing its output over as it\n * comes. Ctrl-C reaches `docker` as well; either way, a stop is not a failure.\n */\nasync function streamDocker(\n args: string[],\n output: { stdout: (text: string) => void; stderr: (text: string) => void },\n signal: AbortSignal,\n): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"docker\", args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: process.env,\n });\n const stop = () => child.kill(\"SIGINT\");\n signal.addEventListener(\"abort\", stop, { once: true });\n child.stdout?.setEncoding(\"utf8\");\n child.stderr?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", output.stdout);\n child.stderr?.on(\"data\", output.stderr);\n child.on(\"error\", (error) => {\n signal.removeEventListener(\"abort\", stop);\n reject(error);\n });\n child.on(\"close\", (code) => {\n signal.removeEventListener(\"abort\", stop);\n if (code === 0 || signal.aborted) {\n resolve();\n } else {\n reject(new Error(`docker ${args.join(\" \")} exited with status ${code ?? 1}`));\n }\n });\n });\n}\n\n/** `text` up to and with its last line break: its whole lines. */\nfunction wholeLines(text: string): string {\n return text.slice(0, text.lastIndexOf(\"\\n\") + 1);\n}\n\nfunction lineBreaks(text: string): number {\n return text.split(\"\\n\").length - 1;\n}\n\n/** Passes a stream's text to `write` once its first `count` lines have gone by. */\nfunction afterLines(count: number, write: (text: string) => void): (text: string) => void {\n let left = count;\n return (text) => {\n let start = 0;\n while (left > 0) {\n const lineBreak = text.indexOf(\"\\n\", start);\n if (lineBreak === -1) {\n return;\n }\n left -= 1;\n start = lineBreak + 1;\n }\n if (start < text.length) {\n write(text.slice(start));\n }\n };\n}\n\n/**\n * Runs `docker` and turns a failure into an error that says what was being done and how to check Docker.\n */\nasync function requireDocker(\n args: string[],\n action: string,\n env: Readonly<Record<string, string>> = {},\n): Promise<DockerResult> {\n let result: DockerResult;\n try {\n result = await runDocker(args, env);\n } catch (error) {\n throw dockerError(action, args, error);\n }\n if (result.status !== 0) {\n throw dockerError(action, args, result);\n }\n return result;\n}\n\n/**\n * Whether the image is already on this machine.\n */\nasync function imageExists(image: string): Promise<boolean> {\n let result: DockerResult;\n const args = [\"image\", \"inspect\", image];\n try {\n result = await runDocker(args);\n } catch (error) {\n throw dockerError(`Inspect Docker image ${image}`, args, error);\n }\n return result.status === 0;\n}\n\n/**\n * Makes sure the image is on this machine, pulling it only if it is not.\n */\nasync function ensureImage(image: string): Promise<\"local\" | \"pulled\"> {\n if (await imageExists(image)) {\n return \"local\";\n }\n await requireDocker([\"pull\", \"--quiet\", image], `Pull Docker image ${image}`);\n return \"pulled\";\n}\n\n/**\n * Wraps a failed `docker` call, keeping its command and stderr for whoever is debugging.\n */\nfunction dockerError(action: string, args: string[], cause: unknown): ZitadelError {\n const details =\n cause && typeof cause === \"object\" && \"stderr\" in cause\n ? { command: [\"docker\", ...args], stderr: String((cause as { stderr?: unknown }).stderr) }\n : { command: [\"docker\", ...args], cause };\n return new ZitadelError(\"E_VALIDATION\", `${action} failed`, {\n hint: \"Check that Docker is installed, running, and reachable from this shell.\",\n nextCommands: [unscopedCommand(\"doctor\")],\n details,\n });\n}\n","import { ZitadelError, toZitadelError } from \"../../errors\";\nimport { unscopedCommand } from \"../../suggestion\";\nimport { listenersForPort, type TcpListener } from \"../../prober/ports\";\nimport { dockerRuntimeGuidance, dockerUnavailableMessage } from \"../docker-guidance\";\nimport { DEFAULT_LOCAL_SERVER_PORT, localServerUrl } from \"../runtime\";\nimport { DockerLauncher } from \"./docker-launcher\";\nimport {\n NoFreePortError,\n PortInUseError,\n ServerStartError,\n ServerStopError,\n type StopOutcome,\n} from \"./lifecycle\";\n\n/**\n * Failures of a start, as the errors the commands report. The lifecycle throws\n * typed errors that know nothing about wording, hints or suggested commands;\n * this is where they become the messages a person or an agent acts on, so a\n * message can be changed without touching the lifecycle.\n */\n\n/**\n * A failed start whose cleanup also failed: the server may still be running\n * with nothing recording it, so the error says how to find and stop it.\n */\nfunction startupCleanupFailedError(\n error: unknown,\n stopResult: StopOutcome,\n cliVersion: string,\n): ZitadelError {\n const startupError = toZitadelError(error);\n return new ZitadelError(\n startupError.code,\n `${startupError.message}; cleanup did not stop the spawned local runtime`,\n {\n hint: \"Inspect the local runtime process and stop it manually, then rerun `zitadel start`.\",\n nextCommands: unique([\n ...(startupError.nextCommands ?? []),\n unscopedCommand(\"stop --all\", cliVersion),\n unscopedCommand(\"logs\", cliVersion),\n unscopedCommand(\"reset --force\", cliVersion),\n ]),\n details: {\n startup_error: {\n code: startupError.code,\n message: startupError.message,\n details: startupError.details,\n },\n stop_result: stopResult,\n },\n },\n );\n}\n\n/**\n * Fails early, with the guidance for starting Docker, when the daemon does not\n * answer: better than a start that fails halfway with a raw `docker` error.\n */\nexport async function assertDockerAvailable(cliVersion: string): Promise<void> {\n let result: Awaited<ReturnType<typeof DockerLauncher.available>>;\n try {\n result = await DockerLauncher.available();\n } catch (error) {\n throw dockerUnavailableError(error, cliVersion);\n }\n if (result.status !== 0) {\n throw dockerUnavailableError(result.stderr || \"docker version failed\", cliVersion);\n }\n}\n\n/** The error for a Docker daemon that is missing or not running. */\nfunction dockerUnavailableError(error: unknown, cliVersion: string): ZitadelError {\n const advice = dockerRuntimeGuidance(\"start\", cliVersion);\n return new ZitadelError(\"E_VALIDATION\", \"Docker is not reachable\", {\n hint: advice.hint,\n nextCommands: advice.nextCommands,\n details: { message: dockerUnavailableMessage(error) },\n });\n}\n\n/**\n * Turns what the lifecycle threw into the error the command reports; anything it\n * does not recognise is returned unchanged for the caller to throw. A start that\n * failed to become ready also carries what cleaning it up did, so a server that\n * could not be stopped is reported as such and not as a plain start failure.\n */\nexport async function startFailure(error: unknown, cliVersion: string): Promise<unknown> {\n if (error instanceof ServerStartError) {\n const { record, details } = error;\n const reported =\n error.reason === \"exited\"\n ? serverExitedError(record.server_url, cliVersion, details, error.logTail)\n : new ZitadelError(\"E_NETWORK\", \"Local Zitadel server did not become healthy\", {\n hint: \"Inspect the local runtime logs, then reset the local runtime if needed.\",\n nextCommands: [\n unscopedCommand(\"logs\", cliVersion),\n unscopedCommand(\"reset --force\", cliVersion),\n ],\n details: {\n ...details,\n server_url: record.server_url,\n ...(error.logTail ? { log_tail: error.logTail } : {}),\n },\n });\n return error.cleanup.status === \"failed\"\n ? startupCleanupFailedError(reported, error.cleanup, cliVersion)\n : reported;\n }\n if (error instanceof ServerStopError) {\n return new ZitadelError(\"E_VALIDATION\", \"Existing local Zitadel server did not stop\", {\n hint: \"Stop the existing local runtime manually, then rerun start.\",\n details: { runtime: error.record, stop_result: error.outcome },\n });\n }\n if (error instanceof PortInUseError) {\n const url = localServerUrl(error.port);\n // Who holds the port is only for the message, so it can afford to wait for `lsof`.\n const listeners = await listenersForPort(error.port, { timeoutMs: 5000 });\n return portInUseError(error.port, url, listeners, cliVersion);\n }\n if (error instanceof NoFreePortError) {\n return new ZitadelError(\"E_PORT_IN_USE\", error.message, {\n hint: \"Free a port, or choose one with --port.\",\n nextCommands: [unscopedCommand(\"start --port 9080\", cliVersion)],\n details: { first_port: error.firstPort },\n });\n }\n return error;\n}\n\n/**\n * A port that was asked for, or every port tried, is held. `listeners` (who\n * holds it, from `lsof`) is only for the message: whether the port is held was\n * decided elsewhere, because a failed `lsof` reads as \"nobody\", and a message\n * may be wrong where a decision must not be.\n */\nfunction portInUseError(\n port: number,\n serverUrl: string,\n listeners: ReadonlyArray<TcpListener>,\n cliVersion: string,\n): ZitadelError {\n const fallbackPort = port === DEFAULT_LOCAL_SERVER_PORT ? port + 1 : DEFAULT_LOCAL_SERVER_PORT;\n return new ZitadelError(\"E_PORT_IN_USE\", `Port ${String(port)} is already in use`, {\n hint: `Stop the process using ${serverUrl}, run \\`zitadel stop --all\\` for managed local runtimes, or choose another port.`,\n nextCommands: [\n unscopedCommand(\"stop --all\", cliVersion),\n unscopedCommand(`start --port ${String(fallbackPort)}`, cliVersion),\n ],\n details: { port, server_url: serverUrl, listeners },\n });\n}\n\n/**\n * A server that started and then exited before answering. `logTail` was read\n * before the failed start was cleaned up, because for a container cleaning up\n * removes the log, which is the only explanation of why it exited.\n */\nfunction serverExitedError(\n serverUrl: string,\n cliVersion: string,\n details: Record<string, unknown>,\n logTail: string | undefined,\n): ZitadelError {\n return new ZitadelError(\n \"E_NETWORK\",\n \"Local Zitadel server process exited before becoming healthy\",\n {\n hint: \"Inspect the local runtime logs, then retry after fixing the startup error.\",\n nextCommands: [\n unscopedCommand(\"logs\", cliVersion),\n unscopedCommand(\"reset --force\", cliVersion),\n ],\n details: { ...details, server_url: serverUrl, ...(logTail ? { log_tail: logTail } : {}) },\n },\n );\n}\n\n/** Removes repeats while keeping order, for suggested commands. */\nfunction unique<T extends string>(values: T[]): T[] {\n return [...new Set(values)];\n}\n","import { execFile, spawn } from \"node:child_process\";\nimport { type FileHandle, mkdir, open, readFile, stat } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { basename, dirname } from \"node:path\";\nimport { StringDecoder } from \"node:string_decoder\";\n\nimport { resolveServerBinary, serverBinaryPath } from \"@zitadel/server/binary\";\n\nimport { ZitadelError, isErrno } from \"../../errors\";\nimport { shellCommand } from \"../../suggestion\";\nimport { EMPTY_ENV, type ResolvedEnv, envSummary } from \"../env-vars\";\nimport type { BinaryRuntimeMetadata } from \"../runtime\";\nimport type { LogSink } from \"../server-log\";\nimport { type Clock, realClock, stopSignal } from \"./clock\";\nimport { type Launched, type Launcher, launched } from \"./lifecycle\";\n\nexport const SERVER_NPM_PACKAGE = \"@zitadel/server\";\nconst COMMAND_ENV = \"ZITADEL_SERVER_BINARY\";\nconst COMMAND_VERSION_ENV = \"ZITADEL_SERVER_BINARY_VERSION\";\nconst STOP_TIMEOUT_MS = 10_000;\nconst STOP_KILL_TIMEOUT_MS = 2_000;\n/** How often a followed log file is checked for new lines. */\nconst LOG_POLL_MS = 1_000;\nconst MIGRATE_FLAG = \"--migrate\";\n/** What the server binary is called, whatever launched it. */\nconst SERVER_PROGRAM = \"nextgen\";\n\nconst require = createRequire(import.meta.url);\n\nexport type BinaryLaunchSpec = Readonly<{\n cliVersion: string;\n dataDir: string;\n logPath: string;\n /** Project variables for the child's environment, never its argv. */\n env?: ResolvedEnv;\n /** Bootstrap user document for the local admin, passed as `--user-file`. */\n userFile?: string;\n}>;\n\nexport type StopBinaryRuntimeResult = Readonly<{\n pid: number;\n signal?: NodeJS.Signals;\n status: \"failed\" | \"stale\" | \"stopped\";\n target: \"process\" | \"process-group\";\n}>;\n\nexport type ServerCommand = Readonly<{\n command: string;\n args: string[];\n serverPackage: string;\n serverVersion: string;\n}>;\n\n/**\n * Everything about running the server as a local process: which binary, how it\n * is started, whether it is alive, how it is stopped and where it logs. The\n * binary comes from `@zitadel/server`, which owns the list of platforms; the CLI\n * starts it directly, not through that package's wrapper script, so the pid it\n * records is the pid that holds the port.\n *\n * The pid in a record is not proof of anything on its own, and most of this\n * class is about that. Pids are reused (after a reboot the recorded one can be\n * any program), every directory's server runs the same program, and a launcher\n * that was killed can leave the server running without the process the record\n * names. So \"is this record's server running\" asks three things: some process\n * in the recorded group is alive, it runs the server program, and it serves\n * *this record's* data directory, which is what tells one directory's server\n * from another's. Stopping applies the same test first, so a stale record can\n * never signal an unrelated program.\n */\nexport class BinaryLauncher implements Launcher<BinaryRuntimeMetadata> {\n private readonly spec: BinaryLaunchSpec;\n\n constructor(spec: BinaryLaunchSpec) {\n this.spec = spec;\n }\n\n /**\n * Starts the server as a detached process and returns the record that identifies it.\n *\n * The binary is started directly, not through `@zitadel/server`'s wrapper script:\n * the pid recorded is then the pid that holds the port, so stopping it stops the\n * server and a wrapper that dies cannot leave the server running unrecorded.\n * It is detached (its own process group and session) so it outlives this CLI\n * invocation, and its output goes to the log file, which is how `zitadel logs`\n * reads a server that is no longer running. Project variables reach it through\n * its environment, never its arguments, so they do not show up in `ps`.\n */\n async launch(target: {\n port: number;\n serverUrl: string;\n }): Promise<Launched<BinaryRuntimeMetadata>> {\n const { spec } = this;\n const command = BinaryLauncher.available(() => BinaryLauncher.command());\n const env = spec.env ?? EMPTY_ENV;\n await mkdir(dirname(spec.logPath), { recursive: true, mode: 0o700 });\n const log = await open(spec.logPath, \"a\", 0o600);\n try {\n const args = withMigrateFlag([\n ...command.args,\n ...(spec.userFile ? [\"--user-file\", spec.userFile] : []),\n ]);\n const child = spawn(command.command, args, {\n detached: true,\n // On Windows a detached process otherwise opens a console window.\n windowsHide: true,\n env: {\n ...process.env,\n // Declared project variables ride the child's environment, never argv.\n ...env.values,\n NEXTGEN_SERVER_ADDRESS: `:${String(target.port)}`,\n NEXTGEN_SERVER_DATA_DIR: spec.dataDir,\n // Browser-facing URLs (claim, dashboard) must point at this local\n // server, not the cloud default the server config falls back to.\n NEXTGEN_SERVER_PUBLIC_BASE: target.serverUrl,\n // The platform project and the local admin travel together: the admin\n // is a user of it. The caller decides by passing a user file, and an\n // opted-out start passes none — leaving whatever the environment says\n // (by default nothing, which the server reads as disabled).\n ...(spec.userFile ? { NEXTGEN_PLATFORM_BOOTSTRAP_PROJECT: \"true\" } : {}),\n },\n stdio: [\"ignore\", log.fd, log.fd],\n });\n const pid = await spawned(child, command.command);\n return launched<BinaryRuntimeMetadata>({\n schema_version: 1,\n backend: \"binary\",\n pid,\n command: [command.command, ...args].join(\" \"),\n log_path: spec.logPath,\n server_package: command.serverPackage,\n server_version: command.serverVersion,\n port: target.port,\n server_url: target.serverUrl,\n data_dir: spec.dataDir,\n created_at: new Date().toISOString(),\n cli_version: spec.cliVersion,\n env: envSummary(env),\n });\n } finally {\n await log.close();\n }\n }\n\n /**\n * Whether the recorded server is alive, checked for identity: see\n * {@link BinaryLauncher.isRecordRunning}.\n */\n isAlive(record: BinaryRuntimeMetadata): Promise<boolean> {\n return BinaryLauncher.isRecordRunning(record);\n }\n\n /**\n * Whether a server that was just launched is alive. Not checked for identity:\n * `ps` shows a just-spawned process under its parent's name until it has\n * exec'd, and would wrongly read it as someone else's.\n */\n async isLaunchedAlive(server: Launched<BinaryRuntimeMetadata>): Promise<boolean> {\n return BinaryLauncher.isRunning(server.pid);\n }\n\n /** The pid and log file, which is where to look when a start fails. */\n describe(record: BinaryRuntimeMetadata): Readonly<Record<string, unknown>> {\n return { runtime: \"binary\", pid: record.pid, log_path: record.log_path };\n }\n\n /**\n * Stops the recorded server, leaving alone a pid that no longer belongs to it.\n */\n terminate(record: BinaryRuntimeMetadata): Promise<StopBinaryRuntimeResult> {\n return BinaryLauncher.stopRecord(record);\n }\n\n /**\n * The end of the server's log file, for explaining a failed start.\n */\n logTail(record: BinaryRuntimeMetadata, lines: number): Promise<string> {\n return BinaryLauncher.readLogs(record.log_path, lines);\n }\n\n /**\n * What `start` runs: the `ZITADEL_SERVER_BINARY` override, else the platform\n * binary of the bundled `@zitadel/server`, which must be built.\n */\n static command(env: NodeJS.ProcessEnv = process.env): ServerCommand {\n const version = BinaryLauncher.version(env);\n return {\n command: env[COMMAND_ENV] || resolveServerBinary(),\n args: [],\n serverPackage: SERVER_NPM_PACKAGE,\n serverVersion: version,\n };\n }\n\n /**\n * The server version `start` runs from this CLI: the bundled `@zitadel/server`,\n * or what `ZITADEL_SERVER_BINARY_VERSION` names for an override.\n */\n static version(env: NodeJS.ProcessEnv = process.env): string {\n if (env[COMMAND_ENV]) {\n return env[COMMAND_VERSION_ENV]?.trim() || \"override\";\n }\n const manifest = require(resolveServerPackageManifest()) as { version?: unknown };\n return typeof manifest.version === \"string\" ? manifest.version : \"unknown\";\n }\n\n /**\n * The bundled server version, to compare with a running server's\n * `server_version`: a server another CLI release started serves that\n * release's API. `undefined` when the package cannot be read: a comparison\n * has nothing to go on then, and `start` reports the broken install itself\n * when it tries to run the server.\n */\n static bundledVersion(env: NodeJS.ProcessEnv = process.env): string | undefined {\n try {\n return BinaryLauncher.version(env);\n } catch {\n return undefined;\n }\n }\n\n /** The bundled server version, or a `ZitadelError` that says how to repair the install. */\n static assertAvailable(): string {\n return BinaryLauncher.available(() => {\n if (!process.env[COMMAND_ENV]) {\n serverBinaryPath();\n }\n return BinaryLauncher.version();\n });\n }\n\n /** Runs `find`, turning any failure to locate the server into the error that says how to repair the install. */\n private static available<T>(find: () => T): T {\n try {\n return find();\n } catch (error) {\n throw new ZitadelError(\"E_VALIDATION\", \"Zitadel server npm package is not available\", {\n hint: \"Reinstall @zitadel/cli so npm can install @zitadel/server and its platform package.\",\n nextCommands: [shellCommand(\"npm install @zitadel/cli@latest\")],\n details: { package: SERVER_NPM_PACKAGE, message: errorMessage(error) },\n });\n }\n }\n\n /**\n * Whether the server a record names is alive. The pid must still belong to it:\n * pids are reused, and after a reboot the recorded one can be any program.\n */\n static async isRecordRunning(record: BinaryRuntimeMetadata): Promise<boolean> {\n return BinaryLauncher.isRunning(record.pid) && (await ownsProcess(record));\n }\n\n /** Stops the server a record names, and leaves alone a pid that has become something else. */\n static async stopRecord(record: BinaryRuntimeMetadata): Promise<StopBinaryRuntimeResult> {\n if (!(await ownsProcess(record))) {\n return { pid: record.pid, status: \"stale\", target: \"process\" };\n }\n return BinaryLauncher.stopPid(record.pid);\n }\n\n /** Whether the process, or any process left in the group it led, is alive. */\n static isRunning(pid: number): boolean {\n if (BinaryLauncher.isPidRunning(pid)) {\n return true;\n }\n if (process.platform === \"win32\") {\n return false;\n }\n try {\n process.kill(-pid, 0);\n return true;\n } catch (error) {\n return isErrno(error, \"EPERM\");\n }\n }\n\n /**\n * Whether a process with this pid exists. It says nothing about whose it is:\n * use {@link BinaryLauncher.isRecordRunning} for a recorded server.\n */\n static isPidRunning(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return isErrno(error, \"EPERM\");\n }\n }\n\n /**\n * Stops a server by the pid it was recorded under. That pid is also the id of\n * the process group the server was started in, and a group outlives its\n * leader: a server whose leader died is still reached by signalling the group,\n * so liveness is the signal's answer, not a check on the leader alone.\n */\n static async stopPid(pid: number): Promise<StopBinaryRuntimeResult> {\n const term = signalRuntime(pid, \"SIGTERM\");\n if (!term.sent) {\n return { pid, status: \"stale\", target: term.target };\n }\n if (await waitForExit(pid, STOP_TIMEOUT_MS)) {\n return { pid, status: \"stopped\", target: term.target, signal: \"SIGTERM\" };\n }\n\n if (BinaryLauncher.isRunning(pid)) {\n const kill = signalRuntime(pid, \"SIGKILL\");\n if (kill.sent && (await waitForExit(pid, STOP_KILL_TIMEOUT_MS))) {\n return { pid, status: \"stopped\", target: kill.target, signal: \"SIGKILL\" };\n }\n }\n return { pid, status: \"failed\", target: term.target, signal: \"SIGKILL\" };\n }\n\n /**\n * A server's whole log file, or an empty string if it has none yet. Read from\n * the file, not the process, so a stopped server's log is still there.\n */\n static async readLog(logPath: string): Promise<string> {\n try {\n return await readFile(logPath, \"utf8\");\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return \"\";\n }\n throw error;\n }\n }\n\n /** The last `tail` lines of a server's log file, or an empty string if it has none yet. */\n static async readLogs(logPath: string, tail: number): Promise<string> {\n const content = await BinaryLauncher.readLog(logPath);\n const lines = content.split(/\\r?\\n/);\n const hasTrailingNewline = lines.at(-1) === \"\";\n const body = hasTrailingNewline ? lines.slice(0, -1) : lines;\n const selected = body.slice(-tail).join(\"\\n\");\n return selected.length === 0 ? \"\" : `${selected}${hasTrailingNewline ? \"\\n\" : \"\"}`;\n }\n\n /**\n * Hands `sink` the log file as it is, then each part appended to it, until\n * `signal` aborts, by default when the CLI is interrupted. The file is\n * polled by size: it is appended to by another process, and there is no\n * event to wait on that works on every platform.\n */\n static async followLogs(\n logPath: string,\n sink: LogSink,\n options: { clock?: Clock; signal?: AbortSignal } = {},\n ): Promise<void> {\n const clock = options.clock ?? realClock;\n const stop = options.signal ? { signal: options.signal, dispose: () => {} } : stopSignal();\n try {\n const log = new AppendedLog(logPath);\n sink.existing(await log.next());\n while (!stop.signal.aborted) {\n await clock.wait(LOG_POLL_MS, stop.signal);\n if (!stop.signal.aborted) {\n sink.appended(await log.next());\n }\n }\n } finally {\n stop.dispose();\n }\n }\n}\n\n/**\n * A log file another process appends to, read a part at a time: each\n * {@link AppendedLog.next} returns what was written since the one before, the\n * first the whole file. Reading by byte offset, rather than by size after a\n * read, loses nothing written in between. A part ends where the file did when\n * it was read, which can be inside a character, so the decoder keeps a\n * character's first bytes until the rest are read.\n */\nexport class AppendedLog {\n private readonly path: string;\n private readonly decoder = new StringDecoder(\"utf8\");\n private offset = 0;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async next(): Promise<string> {\n const size = await fileSize(this.path);\n // A file shorter than what was read of it is another one, as after it was\n // deleted: it is read from the top.\n if (size < this.offset) {\n this.offset = 0;\n }\n if (size === this.offset) {\n return \"\";\n }\n const bytes = await readBytes(this.path, this.offset, size - this.offset);\n this.offset += bytes.length;\n return this.decoder.write(bytes);\n }\n}\n\n/**\n * Whether the recorded pid still belongs to the server that was started. The\n * process, or one left in the group it led, must run the program that was\n * started or the server itself (which is what a launcher that died leaves\n * behind), and must be serving this record's data directory: every directory's\n * server runs the same program, so the data directory in its environment is\n * what tells them apart. Where the process list or a process's environment\n * cannot be read (no `ps`, Windows) the pid is trusted, as it was before.\n */\nasync function ownsProcess(record: BinaryRuntimeMetadata): Promise<boolean> {\n if (process.platform === \"win32\") {\n return true;\n }\n const started = basename(record.command.split(\" \")[0] ?? \"\");\n if (started === \"\") {\n return true;\n }\n const programs = [started, SERVER_PROGRAM];\n let listing: string;\n try {\n // `ww`: without it `ps` cuts the command column to `COLUMNS` (which tools\n // such as pnpm and moon export), and the server's long path is cut before its name.\n listing = await ps([\"axww\", \"-o\", \"pid=,pgid=,command=\"]);\n } catch {\n return true;\n }\n const candidates = listing.split(/\\r?\\n/).flatMap((line) => {\n const match = line.trim().match(/^(\\d+)\\s+(\\d+)\\s+(.*)$/);\n const named = match !== null && programs.some((program) => (match[3] ?? \"\").includes(program));\n const ours =\n match !== null && (Number(match[1]) === record.pid || Number(match[2]) === record.pid);\n return named && ours ? [Number(match[1])] : [];\n });\n for (const pid of candidates) {\n if (await servesDataDir(pid, record.data_dir)) {\n return true;\n }\n }\n return false;\n}\n\nconst DATA_DIR_VARIABLE = \"NEXTGEN_SERVER_DATA_DIR=\";\n\n/** Whether a process serves a data directory, or its environment does not say. */\nasync function servesDataDir(pid: number, dataDir: string): Promise<boolean> {\n let command: string;\n try {\n command = await ps([\"eww\", \"-p\", String(pid), \"-o\", \"command=\"]);\n } catch {\n return true;\n }\n const at = command.indexOf(DATA_DIR_VARIABLE);\n if (at === -1) {\n return true;\n }\n const rest = command.slice(at + DATA_DIR_VARIABLE.length);\n return (\n rest.startsWith(dataDir) &&\n (rest.length === dataDir.length || /\\s/.test(rest[dataDir.length] ?? \"\"))\n );\n}\n\n/**\n * Runs `ps` and returns its output, rejecting where `ps` is missing or fails.\n */\nfunction ps(args: string[]): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n execFile(\n \"ps\",\n args,\n { timeout: 3000, encoding: \"utf8\", maxBuffer: 16 * 1024 * 1024 },\n (error, stdout) => (error ? reject(error) : resolve(stdout)),\n );\n });\n}\n\n/**\n * Waits for a spawned server to exist, and detaches it. A binary that cannot be\n * run (missing, not executable) is reported by an `error` event, not thrown: left\n * unhandled it crashes the CLI with a stack trace, so it is awaited here and\n * turned into an error that says what to do.\n */\nasync function spawned(child: ReturnType<typeof spawn>, command: string): Promise<number> {\n try {\n const pid = await new Promise<number>((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"spawn\", () =>\n child.pid ? resolve(child.pid) : reject(new Error(\"server process did not expose a pid\")),\n );\n });\n // Anything it reports from here on, such as a failed signal, is not the start's to raise.\n child.on(\"error\", () => undefined);\n child.unref();\n return pid;\n } catch (error) {\n throw new ZitadelError(\"E_VALIDATION\", \"The Zitadel server could not be started\", {\n hint: \"Check that the server binary exists and can be run, or reinstall @zitadel/cli.\",\n nextCommands: [shellCommand(\"npm install @zitadel/cli@latest\")],\n details: { command, message: errorMessage(error) },\n });\n }\n}\n\nfunction resolveServerPackageManifest(): string {\n try {\n return require.resolve(`${SERVER_NPM_PACKAGE}/package.json`);\n } catch (error) {\n throw new Error(`Missing ${SERVER_NPM_PACKAGE}. Reinstall @zitadel/cli.`, { cause: error });\n }\n}\n\nasync function fileSize(path: string): Promise<number> {\n try {\n return (await stat(path)).size;\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return 0;\n }\n throw error;\n }\n}\n\n/** Up to `length` bytes of a file from `position` on; none for a file that is gone. */\nasync function readBytes(path: string, position: number, length: number): Promise<Buffer> {\n let file: FileHandle;\n try {\n file = await open(path, \"r\");\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return Buffer.alloc(0);\n }\n throw error;\n }\n try {\n const buffer = Buffer.alloc(length);\n const { bytesRead } = await file.read(buffer, 0, length, position);\n return buffer.subarray(0, bytesRead);\n } finally {\n await file.close();\n }\n}\n\n/**\n * Signals one process. `false` when there is no such process, which is an answer, not an error.\n */\nfunction signalProcess(pid: number, signal: NodeJS.Signals): boolean {\n try {\n process.kill(pid, signal);\n return true;\n } catch (error) {\n if (isErrno(error, \"ESRCH\")) {\n return false;\n }\n throw error;\n }\n}\n\n/**\n * Signals the whole process group the server was started in, falling back to the\n * process itself where there is no such group (Windows). The group, not the pid,\n * is what finds a server whose launcher died: a group lives as long as any\n * member does.\n */\nfunction signalRuntime(\n pid: number,\n signal: NodeJS.Signals,\n): { sent: boolean; target: \"process\" | \"process-group\" } {\n if (process.platform !== \"win32\") {\n try {\n process.kill(-pid, signal);\n return { sent: true, target: \"process-group\" };\n } catch (error) {\n if (!isErrno(error, \"ESRCH\")) {\n throw error;\n }\n }\n }\n return { sent: signalProcess(pid, signal), target: \"process\" };\n}\n\n/**\n * Waits for a stopped server to be gone. It polls: the server is not this\n * process's child, so there is no exit event to wait on.\n */\nasync function waitForExit(pid: number, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (!BinaryLauncher.isRunning(pid)) {\n return true;\n }\n await delay(200);\n }\n return !BinaryLauncher.isRunning(pid);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolveDelay) => setTimeout(resolveDelay, ms));\n}\n\n/**\n * The server applies schema migrations only when asked, and a local server must.\n */\nfunction withMigrateFlag(args: string[]): string[] {\n return args.includes(MIGRATE_FLAG) ? args : [...args, MIGRATE_FLAG];\n}\n","import { mkdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { ZitadelError, isErrno } from \"../../errors\";\nimport { type Clock, realClock } from \"./clock\";\n\ntype LockOptions = Readonly<{\n /** How long to wait for another start to finish. */\n timeoutMs?: number;\n pollMs?: number;\n clock?: Clock;\n}>;\n\n/**\n * Runs `work` as the only start in a directory. Two starts at once would pick\n * the same port and then run two servers over one data directory, so the second\n * waits for the first and then finds its server already running.\n *\n * The lock is a file holding the pid of the start that owns it. A lock whose\n * owner is gone is taken over, so a start that crashed cannot block the next.\n */\nexport async function withStartLock<T>(\n lockFile: string,\n work: () => Promise<T>,\n options: LockOptions = {},\n): Promise<T> {\n const release = await acquireLock(lockFile, options);\n try {\n return await work();\n } finally {\n await release();\n }\n}\n\n/**\n * Takes the lock without waiting. `undefined` when a live start has it.\n *\n * The file is created exclusively, so only one process can create it. If it\n * exists, its owner is asked whether it is still alive: a lock left by a start\n * that crashed must not block every later one, so a dead owner's lock is taken\n * over. The same lock, in a folder shared by the machine, is what claims a port\n * (see `TcpPorts.reserve`).\n */\nexport async function tryLock(lockFile: string): Promise<(() => Promise<void>) | undefined> {\n await mkdir(dirname(lockFile), { recursive: true, mode: 0o700 });\n for (;;) {\n try {\n await createOwned(lockFile);\n return async () => {\n // Only the owner's own lock is removed, so a release that comes after\n // someone else has taken the lock over cannot remove theirs.\n if ((await readOwner(lockFile)) === process.pid) {\n await rm(lockFile, { force: true });\n }\n };\n } catch (error) {\n if (!isErrno(error, \"EEXIST\")) {\n throw error;\n }\n }\n const owner = await readOwner(lockFile);\n const abandoned = owner === undefined ? await isUnwritten(lockFile) : !isAlive(owner);\n if (!abandoned || !(await clearStale(lockFile, owner))) {\n return undefined;\n }\n }\n}\n\n/** Creates the file exclusively and writes the owner into it; a file that could not be written is not left behind empty. */\nasync function createOwned(file: string): Promise<void> {\n try {\n await writeFile(file, String(process.pid), { flag: \"wx\", mode: 0o600 });\n } catch (error) {\n if (!isErrno(error, \"EEXIST\")) {\n await rm(file, { force: true });\n }\n throw error;\n }\n}\n\n/** How long a lock may stay without an owner in it before it is taken to be abandoned: far longer than writing a pid takes. */\nexport const UNWRITTEN_LOCK_MS = 10_000;\n\n/**\n * Whether a lock with no readable owner has been that way for a while. It is\n * normally a start that has created the file and not yet written its pid, and\n * is left alone; one that stays so is a start that died between the two.\n */\nasync function isUnwritten(lockFile: string): Promise<boolean> {\n try {\n return Date.now() - (await stat(lockFile)).mtimeMs > UNWRITTEN_LOCK_MS;\n } catch {\n return false;\n }\n}\n\n/**\n * Removes the lock of a dead owner. Two starts that both saw the same dead owner\n * must not both remove it: the first would then take the lock, and the second,\n * removing it a moment later, would remove the first's live one. So removal\n * itself is exclusive (a second file, created the same way), and the owner is\n * read again once it is held: if the lock has a different owner by then, it is\n * not the stale one and stays. `false` when another start is clearing it.\n */\nexport async function clearStale(\n lockFile: string,\n staleOwner: number | undefined,\n): Promise<boolean> {\n const guardFile = `${lockFile}.clearing`;\n try {\n await createOwned(guardFile);\n } catch (error) {\n if (!isErrno(error, \"EEXIST\")) {\n throw error;\n }\n const clearing = await readOwner(guardFile);\n if (clearing === undefined ? await isUnwritten(guardFile) : !isAlive(clearing)) {\n await rm(guardFile, { force: true });\n }\n return false;\n }\n try {\n if ((await readOwner(lockFile)) === staleOwner) {\n await rm(lockFile, { force: true });\n }\n } finally {\n await rm(guardFile, { force: true });\n }\n return true;\n}\n\nasync function acquireLock(lockFile: string, options: LockOptions): Promise<() => Promise<void>> {\n const clock = options.clock ?? realClock;\n const deadline = clock.now() + (options.timeoutMs ?? 120_000);\n const pollMs = options.pollMs ?? 200;\n for (;;) {\n const release = await tryLock(lockFile);\n if (release) {\n return release;\n }\n if (clock.now() >= deadline) {\n throw new ZitadelError(\n \"E_CONFLICT\",\n \"Another `zitadel start` is still running in this directory\",\n {\n hint: `Wait for it to finish, or delete ${lockFile} if no start is running.`,\n details: { lock_file: lockFile, owner_pid: await readOwner(lockFile) },\n },\n );\n }\n await clock.wait(pollMs);\n }\n}\n\n/**\n * The pid in the lock, or `undefined` while it is being written or when it is\n * unreadable. An unreadable lock counts as held: it is most likely a start that\n * has created the file and not yet written its pid.\n */\nasync function readOwner(lockFile: string): Promise<number | undefined> {\n try {\n const pid = Number.parseInt(await readFile(lockFile, \"utf8\"), 10);\n return Number.isInteger(pid) && pid > 0 ? pid : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return isErrno(error, \"EPERM\");\n }\n}\n","import { createConnection, createServer } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { checkLocalServerHealth } from \"../runtime\";\nimport type { HealthProbe, PortProbe } from \"./lifecycle\";\nimport { tryLock } from \"./start-lock\";\n\n/**\n * The folder port claims are kept in: the user's own, named by uid. The uid is\n * used rather than the account name because the name is looked up in the\n * password database and throws where the uid has no entry (a container run as an\n * arbitrary user), and may hold characters a folder name cannot. Where there is\n * no uid (Windows), the temp directory is already the user's own.\n */\nexport function defaultClaimsDir(): string {\n const uid = process.getuid?.();\n return join(tmpdir(), uid === undefined ? \"zitadel-local-ports\" : `zitadel-local-ports-${uid}`);\n}\n\n/**\n * A port is free when it can be bound and nothing answers on it. Binding alone\n * misses a server bound to one loopback address, which a wildcard bind can sit\n * beside, and connecting alone misses a socket that listens but does not accept\n * yet. `lsof` is not used: a listing that fails or times out reads as an empty\n * one, and an empty one reads as a free port, which is how a start once decided\n * a taken port was free and then accepted another directory's server as its own.\n *\n * Whether a port is free and whether it is *claimed* are separate questions:\n * `isFree` looks at the machine, {@link TcpPorts.reserve} coordinates starts.\n */\nexport class TcpPorts implements PortProbe {\n private readonly claimsDir: string;\n private readonly network: Network;\n\n /**\n * `claimsDir` is where claims are kept; every `zitadel` of the same user on the\n * machine must use the same one. It is the user's own folder because the\n * shared temp directory is shared by accounts, and a folder one account made\n * private would refuse every other. Servers of different users are still told\n * apart by {@link isFree}, which asks the machine; only the coordination of\n * starts at the same instant is per user. `network` is how the machine is asked about a port, and is only\n * replaced in tests, so the logic that combines the answers can be tested\n * without depending on which ports happen to be in use.\n */\n constructor(claimsDir: string = defaultClaimsDir(), network: Network = realNetwork) {\n this.claimsDir = claimsDir;\n this.network = network;\n }\n\n /**\n * Starts that choose a port at the same moment cannot tell it is taken until\n * one of them binds it, and a server takes seconds to bind: the loser used to\n * start, see the winner's server answer on its port, and report itself ready.\n * So a start claims the port first, with a file every `zitadel` on the machine\n * sees, and keeps the claim until its server answers. A claim whose owner is\n * gone is taken over.\n */\n reserve(port: number): Promise<(() => Promise<void>) | undefined> {\n return tryLock(join(this.claimsDir, String(port)));\n }\n\n /** Whether nothing holds the port. Says nothing about another start that has claimed it: see {@link reserve}. */\n async isFree(port: number): Promise<boolean> {\n if (await this.network.answers(port)) {\n return false;\n }\n return this.network.canBind(port);\n }\n}\n\n/** What the machine can be asked about a port. */\nexport interface Network {\n /** Whether something accepts a connection on the port, on either loopback address. */\n answers(port: number): Promise<boolean>;\n /** Whether the port can be bound on every interface. */\n canBind(port: number): Promise<boolean>;\n}\n\n/** The real thing: sockets. */\nconst realNetwork: Network = {\n answers(port) {\n const hosts = [\"127.0.0.1\", \"::1\"];\n return Promise.all(hosts.map((host) => connects(host, port))).then((results) =>\n results.some(Boolean),\n );\n },\n canBind(port) {\n return new Promise((resolve) => {\n const probe = createServer();\n probe.once(\"error\", () => resolve(false));\n probe.listen({ port, exclusive: true }, () => probe.close(() => resolve(true)));\n });\n },\n};\n\n/** Whether something accepts a connection on the port. A refusal, an error or silence is \"no\". */\nfunction connects(host: string, port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ host, port, timeout: 500 });\n socket.once(\"connect\", () => {\n socket.destroy();\n resolve(true);\n });\n socket.once(\"timeout\", () => {\n socket.destroy();\n resolve(false);\n });\n socket.once(\"error\", () => resolve(false));\n });\n}\n\n/**\n * Asks the server's own health endpoint. It only says that *a* Zitadel answers\n * at the URL; which one is the launcher's identity check's job.\n */\nexport class HttpHealth implements HealthProbe {\n isHealthy(serverUrl: string): Promise<boolean> {\n return checkLocalServerHealth(serverUrl, 1000);\n }\n}\n","import {\n type RuntimeBackend,\n type RuntimeMetadata,\n readRuntimeMetadata,\n writeRuntimeMetadata,\n} from \"../runtime\";\nimport type { ServerStore } from \"./lifecycle\";\n\n/** The record type of one backend. */\ntype RecordOf<B extends RuntimeBackend> = Extract<RuntimeMetadata, { backend: B }>;\n\nfunction isRecordOf<B extends RuntimeBackend>(\n runtime: RuntimeMetadata,\n backend: B,\n): runtime is RecordOf<B> {\n return runtime.backend === backend;\n}\n\n/**\n * The directory's `.zitadel/local/runtime.json`, seen as the record of one\n * backend. A record the other backend wrote reads as nothing here: that server\n * is not this launcher's to manage, and `LocalServer` handles a backend switch\n * explicitly instead of by one backend mistaking the other's record for its own.\n */\nexport class RuntimeFileStore<B extends RuntimeBackend> implements ServerStore<RecordOf<B>> {\n private readonly cwd: string;\n private readonly backend: B;\n\n constructor(cwd: string, backend: B) {\n this.cwd = cwd;\n this.backend = backend;\n }\n\n async read(): Promise<RecordOf<B> | undefined> {\n const runtime = await readRuntimeMetadata(this.cwd);\n return runtime && isRecordOf(runtime, this.backend) ? runtime : undefined;\n }\n\n write(record: RecordOf<B>): Promise<void> {\n return writeRuntimeMetadata(this.cwd, record);\n }\n}\n","import pc from \"picocolors\";\n\nimport { escapeControlCharacters } from \"../api-client\";\nimport { isObject } from \"../json\";\n\n/** The levels `zitadel logs --level` takes, lowest first. */\nexport const LOG_LEVELS = [\"debug\", \"info\", \"warn\", \"error\"] as const;\n\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\n/**\n * One line of the server's log and the level of the record it belongs to: its\n * own, or, for a line that is not a record (a panic's stack trace), that of the\n * record above it. `undefined` for a line with no record above it.\n */\nexport type LogLine = Readonly<{ text: string; level: LogLevel | undefined }>;\n\n/**\n * Where a launcher hands the log it reads while following it: first the log as\n * it is, then each part written after it. A part can end inside a line.\n */\nexport type LogSink = Readonly<{\n existing: (text: string) => void;\n appended: (text: string) => void;\n}>;\n\n/**\n * The level names the server writes, in each of its formats. slog writes a\n * level between two named ones as the lower name and an offset (`INFO+2`,\n * `ERROR+4`), which is read as that name; the GCP format writes Cloud\n * Logging's severities.\n */\nconst LEVEL_NAMES: Readonly<Record<string, LogLevel>> = {\n DEBUG: \"debug\",\n INFO: \"info\",\n NOTICE: \"info\",\n WARN: \"warn\",\n WARNING: \"warn\",\n ERROR: \"error\",\n CRITICAL: \"error\",\n ALERT: \"error\",\n EMERGENCY: \"error\",\n};\n\n/** A record in slog's text format, the server's default: `time=… level=WARN …`. */\nconst TEXT_RECORD = /^(?:time=\\S+ )?level=([A-Z]+)(?:[+-]\\d+)?(?: |$)/;\n\n/**\n * A record Go's default logger writes, which the server logs through until it\n * has set up its own: `2026/10/22 07:58:44 WARN …`.\n */\nconst DEFAULT_RECORD = /^\\d{4}\\/\\d{2}\\/\\d{2} \\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)? ([A-Z]+)(?:[+-]\\d+)? /;\n\n/** What the Go runtime prints, outside any logger, when the server crashes. */\nconst CRASH = /^(?:panic|fatal error): /;\n\n/**\n * The level a line of the server's log was written at, or `undefined` for a\n * line that is not a log record. Reads slog's text format, its JSON format\n * (`instrumentation.log.format: json`, and `gcp`, which says `severity`), the\n * lines Go's default logger writes before the server's own is set up, and a\n * crash, which counts as an error.\n */\nexport function levelOf(text: string): LogLevel | undefined {\n const name = TEXT_RECORD.exec(text)?.[1] ?? DEFAULT_RECORD.exec(text)?.[1] ?? jsonLevel(text);\n if (name !== undefined) {\n return LEVEL_NAMES[name];\n }\n return CRASH.test(text) ? \"error\" : undefined;\n}\n\nfunction jsonLevel(text: string): string | undefined {\n if (!text.startsWith(\"{\")) {\n return undefined;\n }\n let record: unknown;\n try {\n record = JSON.parse(text);\n } catch {\n return undefined;\n }\n const level = isObject(record) ? (record.level ?? record.severity) : undefined;\n return typeof level === \"string\" ? level.replace(/[+-]\\d+$/, \"\") : undefined;\n}\n\n/**\n * Splits the server's log into lines as it is read, in parts that need not end\n * at a line break: a line one part starts waits for the part that ends it. A\n * line that is not a record takes the level of the record above it, so a\n * panic's stack trace is shown, colored and filtered with the panic.\n */\nexport class LogLineReader {\n private partial = \"\";\n private level: LogLevel | undefined;\n\n /** The lines `part` completes. */\n read(part: string): LogLine[] {\n const pieces = `${this.partial}${part}`.split(\"\\n\");\n this.partial = pieces.pop() ?? \"\";\n return pieces.map((piece) => this.line(piece));\n }\n\n /** The last line, when the log does not end with a line break. */\n end(): LogLine[] {\n const rest = this.partial;\n this.partial = \"\";\n return rest === \"\" ? [] : [this.line(rest)];\n }\n\n private line(piece: string): LogLine {\n const text = piece.endsWith(\"\\r\") ? piece.slice(0, -1) : piece;\n this.level = levelOf(text) ?? this.level;\n return { text, level: this.level };\n }\n}\n\n/** The lines of a whole log, levelled as {@link LogLineReader} levels them. */\nexport function logLines(text: string): LogLine[] {\n const reader = new LogLineReader();\n return [...reader.read(text), ...reader.end()];\n}\n\n/** The lines at `level` or above; all of them without a level. A line with no level is below every level. */\nexport function atLeast(lines: readonly LogLine[], level: LogLevel | undefined): LogLine[] {\n if (level === undefined) {\n return [...lines];\n }\n const floor = LOG_LEVELS.indexOf(level);\n return lines.filter(\n (line) => line.level !== undefined && LOG_LEVELS.indexOf(line.level) >= floor,\n );\n}\n\n/** The last `tail` lines, counting only those at `level` or above when a level is given. */\nexport function lastLines(\n lines: readonly LogLine[],\n tail: number,\n level: LogLevel | undefined,\n): LogLine[] {\n return atLeast(lines, level).slice(-tail);\n}\n\n/** The lines as the log has them, each ending with a line break. */\nexport function logText(lines: readonly LogLine[]): string {\n return lines.map((line) => `${line.text}\\n`).join(\"\");\n}\n\nconst paint = pc.createColors(true);\n\n/**\n * A line as `zitadel logs` prints it for a person. Characters that could drive\n * the terminal are escaped, as everywhere the CLI prints text it did not write.\n * With `color`, a warning is yellow and an error red, so they stand out from the\n * requests that make up most of the log, and a debug line is dimmed.\n */\nexport function renderLogLine(line: LogLine, color: boolean): string {\n const text = escapeControlCharacters(line.text);\n if (!color) {\n return text;\n }\n switch (line.level) {\n case \"error\":\n return paint.red(text);\n case \"warn\":\n return paint.yellow(text);\n case \"debug\":\n return paint.dim(text);\n default:\n return text;\n }\n}\n","import { join } from \"node:path\";\n\nimport consola from \"consola\";\n\nimport { ZitadelError } from \"../errors\";\nimport { unscopedCommand } from \"../suggestion\";\nimport type { ResolvedEnv } from \"./env-vars\";\nimport { assertDockerAvailable, startFailure } from \"./internal/failures\";\nimport { BinaryLauncher, type StopBinaryRuntimeResult } from \"./internal/binary-launcher\";\nimport { DockerLauncher, type DockerResult } from \"./internal/docker-launcher\";\nimport {\n Lifecycle,\n PortInUseError,\n type Launcher,\n type LifecycleOptions,\n} from \"./internal/lifecycle\";\nimport { HttpHealth, TcpPorts } from \"./internal/probes\";\nimport { withStartLock } from \"./internal/start-lock\";\nimport { RuntimeFileStore } from \"./internal/store\";\nimport type { LocalServers, ManagedRuntimeProcess } from \"./processes\";\nimport {\n type RuntimeBackend,\n type RuntimeMetadata,\n checkLocalServerHealth,\n ensureContainerIdentity,\n localContainerName,\n localRuntimePaths,\n localServerNotRunning,\n readNearestRuntimeMetadata,\n readRuntimeMetadata,\n removeLocalData,\n removeRuntimeMetadata,\n} from \"./runtime\";\nimport {\n type LogLevel,\n type LogLine,\n LogLineReader,\n type LogSink,\n atLeast,\n lastLines,\n logLines,\n} from \"./server-log\";\n\n/** What every backend needs to start: what the directory does not already say. */\ntype CommonRunConfig = Readonly<{\n /** Project variables for the server's environment. */\n env: ResolvedEnv;\n /** Bootstrap user document for the local admin. */\n userFile?: string;\n}>;\n\n/**\n * What to run when starting. A Docker server needs an image and a process does\n * not, so the two are separate shapes: a Docker config without an image cannot\n * be written, instead of failing when it is used.\n */\nexport type RunConfig =\n | (CommonRunConfig & Readonly<{ backend: \"binary\" }>)\n | (CommonRunConfig & Readonly<{ backend: \"docker\"; image: string }>);\n\n/**\n * Where a directory's server stands. `missing`: the directory never started one\n * (no record). `stopped`: there is a record but what it names is not running.\n * `unhealthy`: it is running but does not answer. `running`: both. Whether\n * something answers at the recorded URL is not enough on its own, because\n * another directory's server may have taken the port since; see\n * {@link LocalServer.resolveUrl}.\n */\nexport type ServerStatus = Readonly<{\n lifecycle: \"missing\" | \"running\" | \"unhealthy\" | \"stopped\";\n runtime: RuntimeMetadata | undefined;\n healthy: boolean;\n /** The recorded process, for the binary backend. */\n process?: { pid: number; running: boolean };\n docker: {\n available: boolean;\n error?: string;\n container_exists: boolean;\n container_running: boolean;\n };\n}>;\n\nexport type StopReport = Readonly<{\n runtime: RuntimeMetadata | undefined;\n /** False when there was nothing to stop: no record, or the process was already gone. */\n stopped: boolean;\n /** How the process was stopped, for the binary backend. */\n outcome?: StopBinaryRuntimeResult;\n}>;\n\n/**\n * The outcome of {@link LocalServer.stopAll}. `supported: false` where the\n * process list cannot be read (Windows, or no `ps`), so callers can say so\n * instead of reporting that nothing was running.\n */\nexport type SweepResult = Readonly<\n | { supported: false; error?: string }\n | {\n supported: true;\n results: ReadonlyArray<{\n process: ManagedRuntimeProcess;\n stop_result: StopBinaryRuntimeResult;\n }>;\n }\n>;\n\n/**\n * The local server of one directory, and the only door to it.\n *\n * The rule this class keeps: every directory runs its own server, on its own\n * port, with its own data and its own admin credential, and the CLI only talks\n * to the server that directory's own `.zitadel/local/runtime.json` names. What\n * this replaced (issue #1863) was a second directory silently attaching to the\n * first one's server on port 8080 and signing in with a password that server\n * never imported. So nothing here falls back to a default port, and a recorded\n * URL is never trusted on its own: see {@link LocalServer.resolveUrl}.\n *\n * A directory has at most one server, a process (`binary`) or a container\n * (`docker`), and the record says which. The commands call this class and\n * nothing under `internal/`. How a server is launched, which port it gets, how\n * it is stopped and how it is told apart from another directory's all live\n * there. When behaviour is missing, add it here and to a launcher, not to a\n * command, or the commands drift apart again.\n */\nexport class LocalServer {\n private readonly cwd: string;\n private readonly cliVersion: string;\n\n private constructor(cwd: string, cliVersion: string) {\n this.cwd = cwd;\n this.cliVersion = cliVersion;\n }\n\n /**\n * The server of a directory. `cliVersion` is only used to word the commands\n * that errors suggest, so they name the CLI release the user is running.\n */\n static at(cwd: string, options: { cliVersion: string }): LocalServer {\n return new LocalServer(cwd, options.cliVersion);\n }\n\n /**\n * The server version this CLI ships. A server another CLI release started\n * serves that release's API, so `start` and `setup` compare it with a running\n * server's before reusing it. `undefined` when it cannot be read.\n */\n static bundledVersion(): string | undefined {\n return BinaryLauncher.bundledVersion();\n }\n\n /**\n * The bundled server version, or the error that says how to repair the\n * install. For `doctor`, which must report a broken install, not crash on it.\n */\n static assertBinaryAvailable(): string {\n return BinaryLauncher.assertAvailable();\n }\n\n /** Whether the Docker daemon answers, for `doctor` and for failing a Docker start early. */\n static dockerReachable(): Promise<DockerResult> {\n return DockerLauncher.available();\n }\n\n /** Where an image can be had from, so `doctor` can warn before a start has to pull it. */\n static imageAvailable(image: string): Promise<\"local\" | \"remote\"> {\n return DockerLauncher.imageAvailable(image);\n }\n\n /**\n * The URL of the server the nearest `zitadel start` record names, when that\n * server is the one running and answering.\n *\n * A URL alone is not enough. After a directory's server stops, another\n * directory's can take its port, and then \"something answers at the recorded\n * URL\" is true of the wrong server: the console would send this directory's\n * admin password there and `setup` would create projects in someone else's\n * data. So the record's own process or container must be the one running.\n * There is no fallback to a default port, for the same reason.\n *\n * The record is looked up from `cwd` upwards because `start` may have run in a\n * parent of the app directory.\n */\n static async resolveUrl(cwd: string): Promise<string> {\n const nearest = await readNearestRuntimeMetadata(cwd);\n if (!nearest) {\n throw localServerNotRunning();\n }\n if (await LocalServer.isServing(nearest.runtime)) {\n return nearest.runtime.server_url;\n }\n throw localServerNotRunning(nearest.runtime.server_url);\n }\n\n /**\n * {@link resolveUrl} for optional UI such as the setup wizard's server\n * choice: it never throws, and a malformed record or a server that is not\n * running yields `undefined` (`doctor` owns diagnosing those states).\n */\n static async detectUrl(cwd: string): Promise<string | undefined> {\n try {\n return await LocalServer.resolveUrl(cwd);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Whether nothing on this machine holds `port`, decided the way `start`\n * decides it for a server (connect and bind, never `lsof`). For setup, which\n * asks for an app port, or warns when it cannot ask, only when the detected\n * one is taken.\n */\n static isPortFree(port: number): Promise<boolean> {\n return new TcpPorts().isFree(port);\n }\n\n /**\n * The first free port among the 20 after `port`, for setup to suggest in\n * place of a taken one, or `undefined` when they are all taken too.\n */\n static async nextFreePort(port: number): Promise<number | undefined> {\n for (let next = port + 1; next <= Math.min(port + 20, 65535); next += 1) {\n if (await LocalServer.isPortFree(next)) {\n return next;\n }\n }\n return undefined;\n }\n\n /** Whether the server a record names is running (see the identity checks in the launchers) and answering. */\n private static async isServing(runtime: RuntimeMetadata): Promise<boolean> {\n const alive =\n runtime.backend === \"binary\"\n ? await BinaryLauncher.isRecordRunning(runtime)\n : (await DockerLauncher.inspect(runtime.container_name).catch(() => undefined))?.running ===\n true;\n return alive && (await checkLocalServerHealth(runtime.server_url));\n }\n\n /**\n * Stops every CLI-managed server process on the machine, whichever directory\n * started it. It is the way out when a record is lost or wrong and `stop`\n * cannot find the server: the processes are found by their command lines, not\n * by any directory's record.\n */\n static async stopAll(servers: LocalServers): Promise<SweepResult> {\n const discovery = await servers.current();\n if (!discovery.supported) {\n return { supported: false, error: discovery.error };\n }\n const results: Array<{ process: ManagedRuntimeProcess; stop_result: StopBinaryRuntimeResult }> =\n [];\n for (const processInfo of discovery.processes) {\n results.push({\n process: processInfo,\n stop_result: await BinaryLauncher.stopPid(processInfo.pid),\n });\n }\n if (results.some((result) => result.stop_result.status === \"failed\")) {\n throw new ZitadelError(\"E_VALIDATION\", \"Some managed local runtime processes did not stop\", {\n hint: \"Inspect the failed process IDs and stop them manually, then rerun `zitadel stop --all`.\",\n details: { supported: true, results },\n });\n }\n return { supported: true, results };\n }\n\n /**\n * Starts the directory's server, or finds it already running.\n *\n * A running server is kept only if it is what was asked for: the server\n * version this CLI ships (binary) or the same image (Docker). Otherwise it is\n * restarted on the same data.\n *\n * Port rules, each there for a reason. The directory keeps the port it had,\n * because the URLs `setup` wrote into the app's configuration name it. With no\n * record it takes the first free port from 8080, so a second directory never\n * competes for the first one's. A port passed as `options.port` is taken as\n * asked or refused, never moved, because a server where the caller did not\n * look for it is worse than an error. Whether a port is free is decided by\n * claiming it, not by listing sockets: see `TcpPorts`.\n *\n * Starts are serialised per directory by a lock, so two at once cannot run two\n * servers over one data directory; the second finds the first's. Failures are\n * mapped to the errors the commands report in `internal/failures.ts`.\n */\n async start(\n config: RunConfig,\n options: { port?: number } = {},\n ): Promise<{ runtime: RuntimeMetadata; alreadyRunning: boolean }> {\n // One start at a time per directory: two at once would pick the same port\n // and run two servers over one data directory. The second finds the first's.\n return withStartLock(join(localRuntimePaths(this.cwd).runtimeDir, \"start.lock\"), () =>\n this.startLocked(config, options),\n );\n }\n\n /**\n * The body of {@link start}, run while holding the directory's start lock.\n * Switching backends (container to process, or back) stops the other\n * backend's server to make way, but never for a port that cannot be had: a\n * refused move must leave the working server running, so the destination\n * port is checked before anything is torn down. The port the directory had is\n * carried over (`previousPort`) so a backend switch does not change its URLs.\n */\n private async startLocked(\n config: RunConfig,\n options: { port?: number },\n ): Promise<{ runtime: RuntimeMetadata; alreadyRunning: boolean }> {\n const existing = await readRuntimeMetadata(this.cwd);\n const paths = localRuntimePaths(this.cwd);\n // The server another backend left. It is stopped to make way for this one,\n // but not for a port that cannot be had: a refused move leaves it running.\n const other = existing && existing.backend !== config.backend ? existing : undefined;\n try {\n if (\n other &&\n options.port !== undefined &&\n options.port !== other.port &&\n !(await new TcpPorts().isFree(options.port))\n ) {\n throw new PortInUseError(options.port);\n }\n if (config.backend === \"binary\") {\n // A server another CLI release started serves that release's API, and\n // `setup` against it fails halfway, after the project exists. So a\n // running server is reused only when it is the version this CLI ships;\n // the Docker backend compares the image for the same reason. `version` is\n // `undefined` only when the package cannot be read, and then any running\n // server is kept: there is nothing to compare with.\n const version = BinaryLauncher.bundledVersion();\n if (\n existing?.backend === \"binary\" &&\n version !== undefined &&\n existing.server_version !== version &&\n (await BinaryLauncher.isRecordRunning(existing))\n ) {\n consola.info(\n `Restarting the local Zitadel server on ${version}: it ran ${existing.server_version}. Its data stays.`,\n );\n }\n if (existing?.backend === \"docker\") {\n await DockerLauncher.remove(existing.container_name);\n }\n return await this.run(\n \"binary\",\n new BinaryLauncher({\n cliVersion: this.cliVersion,\n dataDir: paths.dataDir,\n logPath: paths.logFile,\n env: config.env,\n userFile: config.userFile,\n }),\n {\n port: options.port,\n previousPort: other?.port,\n reusable: (record) => version === undefined || record.server_version === version,\n },\n );\n }\n\n const { image } = config;\n await assertDockerAvailable(this.cliVersion);\n if (existing?.backend === \"binary\") {\n await BinaryLauncher.stopRecord(existing);\n }\n return await this.run(\n \"docker\",\n new DockerLauncher({\n cliVersion: this.cliVersion,\n containerName: localContainerName(this.cwd),\n image,\n dataDir: paths.dataDir,\n identity: await ensureContainerIdentity(this.cwd, DockerLauncher.currentUser()),\n env: config.env,\n userFile: config.userFile,\n }),\n {\n port: options.port,\n previousPort: other?.port,\n reusable: (record) => record.image === image,\n },\n );\n } catch (error) {\n throw await startFailure(error, this.cliVersion);\n }\n }\n\n /**\n * Where the directory's server stands. It never throws for a server that is\n * down, a missing record or an unreachable Docker (that is the answer, and the\n * `docker` part says why), because `status` and `doctor` exist to report those\n * states. \"Running\" for a process means its recorded pid still belongs to the\n * server that was started, not merely that some process has that pid.\n */\n async status(): Promise<ServerStatus> {\n const runtime = await readRuntimeMetadata(this.cwd);\n let container: Awaited<ReturnType<typeof DockerLauncher.inspect>> | undefined;\n let dockerError: string | undefined;\n if (runtime?.backend === \"docker\") {\n try {\n container = await DockerLauncher.inspect(runtime.container_name);\n } catch (error) {\n dockerError = error instanceof Error ? error.message : String(error);\n }\n }\n const healthy = runtime ? await checkLocalServerHealth(runtime.server_url) : false;\n const running =\n runtime?.backend === \"binary\" ? await BinaryLauncher.isRecordRunning(runtime) : false;\n return {\n lifecycle: lifecycleOf({ runtime, healthy, running, container }),\n runtime,\n healthy,\n ...(runtime?.backend === \"binary\" ? { process: { pid: runtime.pid, running } } : {}),\n docker: {\n available: dockerError === undefined,\n error: dockerError,\n container_exists: container?.exists ?? false,\n container_running: container?.running ?? false,\n },\n };\n }\n\n /**\n * Stops the directory's server and keeps its data. Idempotent: with nothing\n * recorded, or a recorded server that is already gone, it reports that\n * nothing was stopped instead of failing, so scripts can run it twice.\n */\n async stop(): Promise<StopReport> {\n return this.halt();\n }\n\n /**\n * Stops the directory's server and deletes its data and its record. The\n * server is stopped first so its database is not deleted from under it. The\n * local admin credential is kept: deleting it would leave a start that cannot\n * sign in, because the server only imports the admin once.\n */\n async reset(): Promise<StopReport> {\n const report = await this.halt();\n await removeLocalData(this.cwd);\n await removeRuntimeMetadata(this.cwd);\n return report;\n }\n\n /**\n * The end of the server's log: its last `tail` lines, or with `level` the\n * last `tail` lines at that level or above. The log is read by the record,\n * so it works for a server that has stopped, which is when the log is most\n * wanted.\n */\n async logs(options: {\n tail: number;\n level?: LogLevel;\n }): Promise<{ runtime: RuntimeMetadata; lines: LogLine[] }> {\n const runtime = await this.recordedRuntime();\n // Docker picks the last lines itself, but by count only, so lines at a\n // level are picked here from the whole log.\n const text =\n runtime.backend === \"binary\"\n ? await BinaryLauncher.readLog(runtime.log_path)\n : await DockerLauncher.readLogs(\n runtime.container_name,\n options.level ? \"all\" : options.tail,\n );\n return { runtime, lines: lastLines(logLines(text), options.tail, options.level) };\n }\n\n /**\n * Prints the end of the server's log, the lines {@link logs} picks, and then\n * each line the server writes, until interrupted. With `level`, the lines\n * below it are left out of both.\n */\n async followLogs(options: {\n tail: number;\n level?: LogLevel;\n print: (lines: readonly LogLine[]) => void;\n }): Promise<RuntimeMetadata> {\n const runtime = await this.recordedRuntime();\n const reader = new LogLineReader();\n const sink: LogSink = {\n existing: (text) => options.print(lastLines(reader.read(text), options.tail, options.level)),\n appended: (text) => options.print(atLeast(reader.read(text), options.level)),\n };\n if (runtime.backend === \"binary\") {\n await BinaryLauncher.followLogs(runtime.log_path, sink);\n } else {\n await DockerLauncher.followLogs(\n runtime.container_name,\n options.level ? \"all\" : options.tail,\n sink,\n );\n }\n options.print(atLeast(reader.end(), options.level));\n return runtime;\n }\n\n /** The directory's record, which reading the log needs: the log is found by it. */\n private async recordedRuntime(): Promise<RuntimeMetadata> {\n const runtime = await readRuntimeMetadata(this.cwd);\n if (!runtime) {\n throw new ZitadelError(\"E_VALIDATION\", \"Local Zitadel runtime has not been started\", {\n hint: \"Run `zitadel start` first.\",\n nextCommands: [unscopedCommand(\"start\", this.cliVersion)],\n });\n }\n return runtime;\n }\n\n /**\n * Stops what the record names. For a process, the whole process group is\n * signalled and a pid that is no longer the server is left alone (see\n * `BinaryLauncher.stopRecord`). For a container, or with no record at all, the\n * container named for this directory is removed if there is one: a start that\n * failed halfway can leave a container behind with no record of it. Where\n * Docker is not installed there is none, and that is not an error.\n */\n private async halt(): Promise<StopReport> {\n const runtime = await readRuntimeMetadata(this.cwd);\n if (runtime?.backend === \"binary\") {\n const outcome = await BinaryLauncher.stopRecord(runtime);\n if (outcome.status === \"failed\") {\n throw new ZitadelError(\"E_VALIDATION\", \"Local Zitadel server did not stop\", {\n hint: \"Inspect the local runtime process and stop it manually, then rerun the command.\",\n details: { runtime, stop_result: outcome },\n });\n }\n return { runtime, stopped: outcome.status !== \"stale\", outcome };\n }\n const removed = await DockerLauncher.remove(\n runtime?.backend === \"docker\" ? runtime.container_name : localContainerName(this.cwd),\n );\n return { runtime, stopped: removed };\n }\n\n /**\n * Runs the lifecycle for one backend. The store is typed to that backend so a\n * record the other backend wrote reads as \"nothing here\": the other backend's\n * server is handled explicitly by {@link startLocked}, never by accident.\n */\n private async run<B extends RuntimeBackend>(\n backend: B,\n launcher: Launcher<Extract<RuntimeMetadata, { backend: B }>>,\n options: LifecycleOptions<Extract<RuntimeMetadata, { backend: B }>>,\n ): Promise<{ runtime: RuntimeMetadata; alreadyRunning: boolean }> {\n const { record, alreadyRunning } = await new Lifecycle<\n Extract<RuntimeMetadata, { backend: B }>\n >(\n {\n store: new RuntimeFileStore(this.cwd, backend),\n launcher,\n ports: new TcpPorts(),\n health: new HttpHealth(),\n },\n options,\n ).start();\n return { runtime: record, alreadyRunning };\n }\n}\n\nfunction lifecycleOf(input: {\n runtime: RuntimeMetadata | undefined;\n healthy: boolean;\n running: boolean;\n container: { exists: boolean; running: boolean } | undefined;\n}): ServerStatus[\"lifecycle\"] {\n if (!input.runtime) {\n return \"missing\";\n }\n if (input.runtime.backend === \"binary\") {\n if (input.running && input.healthy) {\n return \"running\";\n }\n return input.running ? \"unhealthy\" : \"stopped\";\n }\n if (input.container?.running && input.healthy) {\n return \"running\";\n }\n return input.container?.exists ? \"unhealthy\" : \"stopped\";\n}\n","import { ZitadelError } from \"./errors\";\nimport { LocalServer } from \"./local-server/server\";\nimport type { Parsed } from \"@zitadel/config/idp\";\nimport type { FlagVariable } from \"./oclif/types\";\nimport { DEFAULT_SERVER } from \"@zitadel/config/server\";\n\n/**\n * Server URL used when nothing else resolves (`@zitadel/config/server`, which\n * the console shares). Also surfaced in hints and the interactive setup\n * prompt as the suggested value, so it is re-exported here.\n */\nexport { DEFAULT_SERVER } from \"@zitadel/config/server\";\n\n/** The variable {@link resolveServer} reads when `--server` is not given. */\nexport const SERVER_VARIABLE: FlagVariable = {\n name: \"ZITADEL_API_BASE\",\n flag: \"server\",\n description: \"The server URL, or `local`, as `--server` takes it.\",\n precedence: \"`--server` wins over it, and it wins over `server` in `zitadel.json`.\",\n};\n\n/**\n * The resolved target server plus the source it came from. `origin` is\n * retained (not just the value) so callers can report *why* a server was\n * chosen.\n */\nexport type ResolvedServer = {\n value: string;\n origin: \"flag\" | \"default\" | \"local\";\n};\n\n/**\n * Inputs to {@link resolveServer}. Passed explicitly (cwd) rather than read\n * from globals so resolution is pure and testable. `serverFlag` comes from the\n * parsed CLI invocation.\n */\nexport type ResolveServerInput = {\n cwd: string;\n serverFlag?: string;\n};\n\n/**\n * Resolves which server `setup` should create its project on: the `--server`\n * flag, else {@link DEFAULT_SERVER}. Every other command takes its server from\n * `ZITADEL_URL` (see `resolveEnvironment`), because a project belongs to the\n * server that created it and the default says nothing about that. A flag\n * value is validated to a normalised origin; an invalid URL throws a\n * `ZitadelError` rather than silently falling through.\n */\nexport async function resolveServer(input: ResolveServerInput): Promise<ResolvedServer> {\n if (!input.serverFlag) {\n return { value: DEFAULT_SERVER, origin: \"default\" };\n }\n if (input.serverFlag === \"local\") {\n return { value: await LocalServer.resolveUrl(input.cwd), origin: \"local\" };\n }\n return { value: serverOrigin(input.serverFlag), origin: \"flag\" };\n}\n\n/**\n * A typed or flagged server as its origin, or the problem with it: the `parse`\n * an input question takes, so a prompt re-asks instead of throwing out of it.\n */\nexport function parseServer(value: string): Parsed<string> {\n const typed = value.trim();\n if (typed === \"\") {\n return { ok: false, problem: \"Enter the server URL.\" };\n }\n try {\n return { ok: true, value: serverOrigin(typed) };\n } catch (error) {\n return { ok: false, problem: error instanceof Error ? error.message : String(error) };\n }\n}\n\n/** Normalises a server URL to its origin, or throws `E_VALIDATION` when it is not an http(s) URL. */\nexport function serverOrigin(value: string): string {\n if (!URL.canParse(value)) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid server \"${value}\"`, {\n hint: `Use a URL like ${DEFAULT_SERVER}.`,\n });\n }\n const url = new URL(value);\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n throw new ZitadelError(\"E_VALIDATION\", `Server URL must use http(s): ${value}`, {\n hint: `Use a URL like ${DEFAULT_SERVER}.`,\n });\n }\n return url.origin;\n}\n\n/**\n * Loopback check on the URL's hostname: `localhost`, the whole `127.0.0.0/8`\n * block, or `[::1]` (how WHATWG URLs spell IPv6 loopback).\n */\nexport function isLoopbackUrl(value: string): boolean {\n try {\n const hostname = new URL(value).hostname;\n return hostname === \"localhost\" || hostname === \"[::1]\" || /^127(\\.\\d{1,3}){3}$/.test(hostname);\n } catch {\n return false;\n }\n}\n","import type { Property } from \"../property\";\nimport { envEnabled } from \"./env-flag\";\n\n/** Whether the process is running inside an automated CI environment. */\nclass CiFlag implements Property<NodeJS.ProcessEnv, boolean> {\n public value(env: NodeJS.ProcessEnv): boolean {\n return envEnabled(env.CI) || envEnabled(env.GITHUB_ACTIONS) || envEnabled(env.GITLAB_CI);\n }\n}\n\nexport const ciFlag = new CiFlag();\n","import { ciFlag } from \"./dimensions/ci-flag\";\n\n/**\n * Resolves the Mixpanel ingestion token and endpoint for a CLI invocation, and\n * the channel that decides whether a run is production traffic.\n *\n * Mixpanel is paused: the production project the CLI sent to is in Mixpanel's\n * US region while its events went to the EU endpoint, which drops them. Until\n * a project and its region agree, no token is baked in, so only\n * `ZITADEL_TELEMETRY_TOKEN` sends to Mixpanel. The events still go to Vercel\n * Web Analytics (`vercel.ts`).\n *\n * A Mixpanel token is a *write-only* project token: it can ingest events but\n * cannot read data back, so — unlike the project service-key — it is safe to\n * ship inside the published CLI. This mirrors how Next.js, Astro, and other dev\n * tools embed their telemetry token, and is the only workable model for a CLI\n * (we cannot ask end users to supply one). It is intentionally not a secret.\n */\n\n/** The hosted cloud's address, where released CLIs send their events. */\nexport const CLOUD_HOST = \"preview.zitadel.com\";\n\n/**\n * Where Mixpanel events go, by data-residency region. EU events go through the\n * cloud: the repo-root `vercel.json` forwards `/telemetry/mixpanel/*` to\n * `api-eu.mixpanel.com`, so released CLIs name our host rather than\n * Mixpanel's. A US project is reached directly.\n */\nconst ENDPOINTS = {\n us: { host: \"api.mixpanel.com\", path: \"\" },\n eu: { host: CLOUD_HOST, path: \"/telemetry/mixpanel\" },\n} as const;\n\nexport type TelemetryRegion = keyof typeof ENDPOINTS;\n\n/** The Mixpanel client's host, and the path its requests start with. */\nexport type TelemetryEndpoint = { readonly host: string; readonly path: string };\n\n/**\n * Decide whether a run's events are production traffic, which only the\n * production channel reports.\n *\n * `ZITADEL_TELEMETRY_ENV` selects `development` or `production` explicitly and\n * wins outright. With no explicit selection the default is `production`, so the\n * single generic build (no channel stamp) reports real user traffic with no\n * per-user env — EXCEPT that an unattended CI/automation run is development\n * instead. CI runs normally opt out entirely (`DO_NOT_TRACK` /\n * `ZITADEL_TELEMETRY=0`, which our own CI sets); the CI check is a belt-and-\n * braces guard so that if telemetry is somehow left on in an automated\n * environment, it can never pollute production data.\n *\n * Ambient `NODE_ENV` is deliberately NOT consulted: a run with\n * `NODE_ENV=development` must not silently switch channels.\n */\nexport function resolveChannel(env: NodeJS.ProcessEnv): \"development\" | \"production\" {\n const explicit = (env.ZITADEL_TELEMETRY_ENV ?? \"\").trim().toLowerCase();\n if (explicit === \"development\") {\n return \"development\";\n }\n if (explicit === \"production\") {\n return \"production\";\n }\n // Never let an unattended CI/automation run reach production data.\n if (ciFlag.value(env)) {\n return \"development\";\n }\n return \"production\";\n}\n\n/**\n * Resolve the Mixpanel ingestion token, or `undefined` for no Mixpanel events.\n * Mixpanel is paused, so only a `ZITADEL_TELEMETRY_TOKEN` override names one.\n */\nexport function resolveTelemetryToken(env: NodeJS.ProcessEnv): string | undefined {\n return env.ZITADEL_TELEMETRY_TOKEN?.trim() || undefined;\n}\n\n/**\n * Resolve where Mixpanel events go from `ZITADEL_TELEMETRY_REGION`. Defaults to\n * the EU region. Set `ZITADEL_TELEMETRY_REGION=us` for a US-hosted project —\n * events sent to the wrong region are silently dropped, so verify the first\n * event lands in Live View.\n */\nexport function resolveTelemetryEndpoint(env: NodeJS.ProcessEnv): TelemetryEndpoint {\n const region = (env.ZITADEL_TELEMETRY_REGION ?? \"eu\").trim().toLowerCase();\n return region === \"us\" ? ENDPOINTS.us : ENDPOINTS.eu;\n}\n","import type { Properties } from \"mixpanel\";\n\n/**\n * Return a new bag with empty values stripped, per Mixpanel's \"omit, never send\n * null/''\" rule. Pure — the input is never mutated.\n */\nexport function compact(properties: Properties): Properties {\n return Object.fromEntries(\n Object.entries(properties).filter(\n ([, value]) => value !== undefined && value !== null && value !== \"\",\n ),\n );\n}\n","import type { Properties } from \"mixpanel\";\n\nimport { CLOUD_HOST, resolveChannel } from \"./config\";\n\n/**\n * A copy of each event for Vercel Web Analytics, under the event's own name,\n * posted the way `@vercel/analytics/server` posts a custom event.\n */\n\n/** The cloud project's Web Analytics intake. */\nexport const VERCEL_ENDPOINT = `https://${CLOUD_HOST}/_vercel/insights/event`;\n\n/** The custom-event property limit of Web Analytics Plus. */\nexport const VERCEL_MAX_PROPERTIES = 8;\n\n/** The intake's limit on an event name or value. */\nconst MAX_LENGTH = 255;\n\n/** Where the copy goes, and which properties it keeps, in priority order. */\nexport type VercelSink = {\n readonly endpoint: string;\n readonly keys: readonly string[];\n};\n\n/**\n * Where the copy goes, or `undefined` for no copy. A run on the development\n * channel (CI included) sends none: the cloud's intake has no dev counterpart.\n * `ZITADEL_TELEMETRY_VERCEL_ENDPOINT` names an intake for any run.\n */\nexport function resolveVercelEndpoint(env: NodeJS.ProcessEnv): string | undefined {\n const override = env.ZITADEL_TELEMETRY_VERCEL_ENDPOINT?.trim();\n if (override) {\n return override;\n }\n return resolveChannel(env) === \"production\" ? VERCEL_ENDPOINT : undefined;\n}\n\n/**\n * The intake body for one event. It keeps the first\n * {@link VERCEL_MAX_PROPERTIES} of `sink.keys` that hold a non-empty string,\n * a number or a boolean, and drops everything else.\n */\nexport function vercelEventBody(\n event: string,\n properties: Properties,\n sink: VercelSink,\n now: number,\n): string {\n const data: Record<string, string | number | boolean> = {};\n for (const key of sink.keys) {\n if (Object.keys(data).length === VERCEL_MAX_PROPERTIES) {\n break;\n }\n const value: unknown = properties[key];\n if (typeof value === \"string\" && value !== \"\") {\n data[key] = value.slice(0, MAX_LENGTH);\n } else if (typeof value === \"number\" || typeof value === \"boolean\") {\n data[key] = value;\n }\n }\n const version = properties.cli_version;\n return JSON.stringify({\n o: new URL(sink.endpoint).origin,\n ts: now,\n sdkn: \"zitadel-cli\",\n sdkv: typeof version === \"string\" ? version : \"\",\n r: \"\",\n en: event.slice(0, MAX_LENGTH),\n ed: data,\n });\n}\n","import { randomUUID } from \"node:crypto\";\nimport { setTimeout as delay } from \"node:timers/promises\";\n\nimport mixpanelLib, {\n type Mixpanel as MixpanelClient,\n type Modifiers,\n type Properties,\n} from \"mixpanel\";\n\nimport { resolveTelemetryEndpoint, resolveTelemetryToken, type TelemetryEndpoint } from \"./config\";\nimport { resolveConsent } from \"./consent\";\nimport { type Identity, loadOrCreateIdentity } from \"./identity\";\nimport { compact } from \"./util\";\nimport { resolveVercelEndpoint, type VercelSink, vercelEventBody } from \"./vercel\";\n\nexport type { Properties, Modifiers } from \"mixpanel\";\nexport type { TelemetryRegion } from \"./config\";\n\n/** Property bag accepted by {@link Telemetry.track} / {@link Telemetry.profile}. */\nexport type TelemetryProperties = Properties;\n\n/**\n * Inputs to {@link Telemetry.create}. `env` is required; the rest are optional —\n * `flag`/`debug` are set by the production wiring, while `initClient`,\n * `loadIdentity`, and `newId` are test seams that default to the real\n * implementations when omitted.\n */\nexport type TelemetryDeps = {\n readonly env: NodeJS.ProcessEnv;\n /**\n * Resolved telemetry flag (the `--telemetry/--no-telemetry` value). Defaults\n * to `true` (telemetry enabled); `false` opts out. Undefined leaves the\n * decision to the other consent signals.\n */\n readonly flag?: boolean;\n /** Emit each payload to stderr before sending — for `--debug`. */\n readonly debug?: boolean;\n /**\n * The properties a copy of each event sends to Vercel Web Analytics, in\n * priority order. Without them no copy is sent.\n */\n readonly vercelKeys?: readonly string[];\n readonly initClient?: (token: string, endpoint: TelemetryEndpoint) => MixpanelClient;\n readonly loadIdentity?: (env: NodeJS.ProcessEnv) => Identity;\n readonly newId?: () => string;\n /** Sends the Vercel copy; defaults to the global `fetch`. */\n readonly fetch?: typeof fetch;\n};\n\n/**\n * A generic, application-agnostic telemetry client for a single short process:\n * Mixpanel, when a token names a project, and a copy of each event for Vercel\n * Web Analytics. It knows nothing about commands, CLIs, or event names —\n * callers supply fully-built property bags. Its only opinions are operational,\n * because telemetry must never degrade the host program:\n *\n * - Never throws — a missing token, opt-out, or transport error all degrade to\n * a silent no-op.\n * - Never blocks beyond {@link shutdown}'s timeout.\n * - Never writes to stdout; the optional debug trace goes to stderr.\n *\n * Inputs are treated as immutable: {@link track}/{@link profile} build a new\n * payload via spread and never mutate the bag they are given.\n */\nexport class Telemetry {\n private readonly pending: Promise<void>[] = [];\n\n private readonly client: MixpanelClient | undefined;\n readonly distinctId: string;\n readonly isFirstRun: boolean;\n private readonly debug: boolean;\n private readonly newId: () => string;\n private readonly vercel: VercelSink | undefined;\n private readonly fetch: typeof fetch;\n\n private constructor(\n client: MixpanelClient | undefined,\n distinctId: string,\n isFirstRun: boolean,\n debug: boolean,\n newId: () => string,\n vercel: VercelSink | undefined,\n fetchFn: typeof fetch,\n ) {\n this.client = client;\n this.distinctId = distinctId;\n this.isFirstRun = isFirstRun;\n this.debug = debug;\n this.newId = newId;\n this.vercel = vercel;\n this.fetch = fetchFn;\n }\n\n /** Whether events will actually be sent: consent granted, and Mixpanel or the Vercel copy to send to. */\n get enabled(): boolean {\n return this.client !== undefined || this.vercel !== undefined;\n }\n\n /**\n * Resolve consent and where events go, then identity, and build the Mixpanel\n * client lazily — only when a token names a project. Without a destination,\n * or on any failure along the way, the instance is inert and its methods are\n * no-ops; it then never writes an install id.\n */\n static create(deps: TelemetryDeps): Telemetry {\n const newId = deps.newId ?? randomUUID;\n const debug = deps.debug ?? false;\n const fetchFn = deps.fetch ?? fetch;\n const inert = (firstRun: boolean): Telemetry =>\n new Telemetry(undefined, \"\", firstRun, debug, newId, undefined, fetchFn);\n\n const consent = resolveConsent({ env: deps.env, flag: deps.flag });\n if (debug) {\n process.stderr.write(`[telemetry] consent: ${consent.reason}\\n`);\n }\n if (!consent.enabled) {\n return inert(false);\n }\n\n const token = resolveTelemetryToken(deps.env);\n if (debug && !token) {\n process.stderr.write(\"[telemetry] mixpanel: no token\\n\");\n }\n const vercelKeys = deps.vercelKeys?.length ? deps.vercelKeys : undefined;\n const vercelEndpoint = vercelKeys && resolveVercelEndpoint(deps.env);\n if (debug && vercelKeys && !vercelEndpoint) {\n process.stderr.write(\"[telemetry] vercel: no copy on the development channel\\n\");\n }\n const vercel =\n vercelKeys && vercelEndpoint ? { endpoint: vercelEndpoint, keys: vercelKeys } : undefined;\n if (!token && !vercel) {\n return inert(false);\n }\n\n const identity = (deps.loadIdentity ?? loadOrCreateIdentity)(deps.env);\n\n let client: MixpanelClient | undefined;\n if (token) {\n try {\n client = (deps.initClient ?? defaultInit)(token, resolveTelemetryEndpoint(deps.env));\n } catch {\n client = undefined;\n }\n }\n if (!client && !vercel) {\n return inert(identity.isFirstRun);\n }\n return new Telemetry(\n client,\n identity.distinctId,\n identity.isFirstRun,\n debug,\n newId,\n vercel,\n fetchFn,\n );\n }\n\n /** Send an event with the given properties; `distinct_id`/`$insert_id` are stamped here. */\n track(event: string, properties: TelemetryProperties): void {\n if (!this.enabled) {\n return;\n }\n const payload = compact({\n ...properties,\n distinct_id: this.distinctId,\n $insert_id: this.newId(),\n });\n if (this.debug && this.client) {\n process.stderr.write(`[telemetry] ${event} ${JSON.stringify(payload)}\\n`);\n }\n this.enqueue((client, done) => client.track(event, payload, done));\n this.sendVercel(event, payload);\n }\n\n /** Send the Vercel copy of an event, fire-and-forget like every send. */\n private sendVercel(event: string, payload: TelemetryProperties): void {\n const sink = this.vercel;\n if (!sink) {\n return;\n }\n let body: string;\n try {\n body = vercelEventBody(event, payload, sink, Date.now());\n } catch {\n return;\n }\n if (this.debug) {\n process.stderr.write(`[telemetry] vercel ${body}\\n`);\n }\n this.pending.push(\n Promise.resolve()\n .then(() =>\n this.fetch(sink.endpoint, {\n method: \"POST\",\n // The global dispatcher sets the CLI's User-Agent; `x-va-server`\n // is what `@vercel/analytics/server` sends.\n headers: { \"content-type\": \"application/json\", \"x-va-server\": \"1\" },\n body,\n }),\n )\n .then(\n (response) => {\n if (this.debug) {\n process.stderr.write(`[telemetry] vercel answered ${response.status}\\n`);\n }\n },\n () => undefined,\n ),\n );\n }\n\n /** Write a user profile via the People API. `modifiers` carries `$ip` etc. */\n profile(properties: TelemetryProperties, modifiers: Modifiers = {}): void {\n if (!this.client) {\n return;\n }\n const payload = compact(properties);\n if (this.debug) {\n process.stderr.write(`[telemetry] people.set ${JSON.stringify(payload)}\\n`);\n }\n this.enqueue((client, done) => client.people.set(this.distinctId, payload, modifiers, done));\n }\n\n /**\n * Await in-flight sends so a short-lived process does not exit before the\n * requests complete, bounded by `timeoutMs`. The timeout is unref'd so the\n * losing race branch never holds the event loop open or needs a manual clear.\n * Safe to call on an inert instance.\n */\n async shutdown(timeoutMs = 2000): Promise<void> {\n if (this.pending.length === 0) {\n return;\n }\n await Promise.race([\n Promise.allSettled(this.pending),\n delay(timeoutMs, undefined, { ref: false }),\n ]);\n }\n\n /**\n * Enqueue one fire-and-forget send. Resolves (never rejects) on any failure —\n * a synchronous throw or an error callback must not surface to the caller or\n * leak as an unhandled rejection.\n */\n private enqueue(send: (client: MixpanelClient, done: () => void) => void): void {\n const client = this.client;\n if (!client) {\n return;\n }\n this.pending.push(\n new Promise<void>((resolve) => {\n try {\n send(client, () => resolve());\n } catch {\n resolve();\n }\n }),\n );\n }\n}\n\n/** Real Mixpanel client construction, isolated so {@link Telemetry.create} can swap it in tests. */\nfunction defaultInit(token: string, { host, path }: TelemetryEndpoint): MixpanelClient {\n return mixpanelLib.init(token, { host, path, geolocate: false });\n}\n","import type { Property } from \"../property\";\n\n/**\n * ISO 3166-1 alpha-2 country for an IANA timezone, defaulting to the machine's\n * own zone. A curated subset of common zones — any zone not listed (or an\n * unknown/unavailable one) yields `undefined`, since we report no country\n * rather than guess. Derived from the timezone, never the IP, so no city or\n * region is ever inferred. The machine's own zone is resolved once and cached:\n * `Intl.DateTimeFormat` construction loads ICU data and is process-stable.\n */\nclass Country implements Property<string | undefined, string | undefined> {\n private readonly byTimezone: Record<string, string> = {\n \"Africa/Abidjan\": \"CI\",\n \"Africa/Accra\": \"GH\",\n \"Africa/Addis_Ababa\": \"ET\",\n \"Africa/Algiers\": \"DZ\",\n \"Africa/Cairo\": \"EG\",\n \"Africa/Casablanca\": \"MA\",\n \"Africa/Johannesburg\": \"ZA\",\n \"Africa/Lagos\": \"NG\",\n \"Africa/Nairobi\": \"KE\",\n \"Africa/Tunis\": \"TN\",\n \"America/Anchorage\": \"US\",\n \"America/Argentina/Buenos_Aires\": \"AR\",\n \"America/Bogota\": \"CO\",\n \"America/Chicago\": \"US\",\n \"America/Denver\": \"US\",\n \"America/Halifax\": \"CA\",\n \"America/Lima\": \"PE\",\n \"America/Los_Angeles\": \"US\",\n \"America/Mexico_City\": \"MX\",\n \"America/New_York\": \"US\",\n \"America/Phoenix\": \"US\",\n \"America/Santiago\": \"CL\",\n \"America/Sao_Paulo\": \"BR\",\n \"America/Toronto\": \"CA\",\n \"America/Vancouver\": \"CA\",\n \"Asia/Bangkok\": \"TH\",\n \"Asia/Dhaka\": \"BD\",\n \"Asia/Dubai\": \"AE\",\n \"Asia/Hong_Kong\": \"HK\",\n \"Asia/Jakarta\": \"ID\",\n \"Asia/Jerusalem\": \"IL\",\n \"Asia/Karachi\": \"PK\",\n \"Asia/Kolkata\": \"IN\",\n \"Asia/Kuala_Lumpur\": \"MY\",\n \"Asia/Manila\": \"PH\",\n \"Asia/Riyadh\": \"SA\",\n \"Asia/Seoul\": \"KR\",\n \"Asia/Shanghai\": \"CN\",\n \"Asia/Singapore\": \"SG\",\n \"Asia/Taipei\": \"TW\",\n \"Asia/Tehran\": \"IR\",\n \"Asia/Tokyo\": \"JP\",\n \"Australia/Adelaide\": \"AU\",\n \"Australia/Brisbane\": \"AU\",\n \"Australia/Melbourne\": \"AU\",\n \"Australia/Perth\": \"AU\",\n \"Australia/Sydney\": \"AU\",\n \"Europe/Amsterdam\": \"NL\",\n \"Europe/Athens\": \"GR\",\n \"Europe/Berlin\": \"DE\",\n \"Europe/Brussels\": \"BE\",\n \"Europe/Bucharest\": \"RO\",\n \"Europe/Budapest\": \"HU\",\n \"Europe/Copenhagen\": \"DK\",\n \"Europe/Dublin\": \"IE\",\n \"Europe/Helsinki\": \"FI\",\n \"Europe/Istanbul\": \"TR\",\n \"Europe/Kyiv\": \"UA\",\n \"Europe/Lisbon\": \"PT\",\n \"Europe/London\": \"GB\",\n \"Europe/Madrid\": \"ES\",\n \"Europe/Moscow\": \"RU\",\n \"Europe/Oslo\": \"NO\",\n \"Europe/Paris\": \"FR\",\n \"Europe/Prague\": \"CZ\",\n \"Europe/Rome\": \"IT\",\n \"Europe/Stockholm\": \"SE\",\n \"Europe/Vienna\": \"AT\",\n \"Europe/Warsaw\": \"PL\",\n \"Europe/Zurich\": \"CH\",\n \"Pacific/Auckland\": \"NZ\",\n \"Pacific/Honolulu\": \"US\",\n };\n\n private machineZone: string | undefined;\n private machineZoneResolved = false;\n\n public value(timezone: string | undefined): string | undefined {\n const zone = timezone ?? this.resolveMachineZone();\n return zone ? this.byTimezone[zone] : undefined;\n }\n\n private resolveMachineZone(): string | undefined {\n if (!this.machineZoneResolved) {\n this.machineZoneResolved = true;\n try {\n this.machineZone = new Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n this.machineZone = undefined;\n }\n }\n return this.machineZone;\n }\n}\n\nexport const country = new Country();\n","import type { Property } from \"../property\";\n\n/** Package manager that launched the process, read from its user-agent. */\nclass InvocationChannel implements Property<NodeJS.ProcessEnv, string> {\n /** Ordered so a more specific name wins — `pnpm` is matched before the `npm` prefix. */\n private static readonly managers = [\"pnpm\", \"yarn\", \"bun\", \"npm\"] as const;\n\n public value(env: NodeJS.ProcessEnv): string {\n const userAgent = env.npm_config_user_agent ?? \"\";\n return InvocationChannel.managers.find((manager) => userAgent.startsWith(manager)) ?? \"unknown\";\n }\n}\n\nexport const invocationChannel = new InvocationChannel();\n","import type { Property } from \"../property\";\n\n/** Maps `process.platform` to Mixpanel's canonical `$os` label. */\nclass OperatingSystem implements Property<NodeJS.Platform, string> {\n private static readonly labels: Partial<Record<NodeJS.Platform, string>> = {\n darwin: \"Mac OS X\",\n win32: \"Windows\",\n linux: \"Linux\",\n freebsd: \"BSD\",\n openbsd: \"BSD\",\n netbsd: \"BSD\",\n aix: \"AIX\",\n sunos: \"Solaris\",\n };\n\n public value(platform: NodeJS.Platform): string {\n return OperatingSystem.labels[platform] ?? platform;\n }\n}\n\nexport const operatingSystem = new OperatingSystem();\n","import { DEFAULT_SERVER } from \"../server\";\nimport type { Property } from \"../telemetry/property\";\n\n/**\n * Buckets the resolved backend `source` into a coarse kind. The raw URL is never\n * emitted — it can carry an internal/self-hosted hostname — only which kind of\n * backend the command targeted.\n */\nclass ServerKind implements Property<string, \"cloud\" | \"local\" | \"self_hosted\" | \"unknown\"> {\n public value(source: string): \"cloud\" | \"local\" | \"self_hosted\" | \"unknown\" {\n if (source === \"mock\") {\n return \"local\";\n }\n if (!URL.canParse(source)) {\n return \"unknown\";\n }\n const { hostname } = new URL(source);\n if (\n hostname === new URL(DEFAULT_SERVER).hostname ||\n hostname === \"zitadel.cloud\" ||\n hostname.endsWith(\".zitadel.cloud\")\n ) {\n return \"cloud\";\n }\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"::1\") {\n return \"local\";\n }\n return \"self_hosted\";\n }\n}\n\nexport const serverKind = new ServerKind();\n","import type { Properties } from \"../telemetry\";\nimport { ciFlag } from \"../telemetry/dimensions/ci-flag\";\nimport { ciProvider } from \"../telemetry/dimensions/ci-provider\";\nimport { country } from \"../telemetry/dimensions/country\";\nimport { hostAgent } from \"../telemetry/dimensions/host-agent\";\nimport { invocationChannel } from \"../telemetry/dimensions/invocation-channel\";\nimport { operatingSystem } from \"../telemetry/dimensions/operating-system\";\nimport { serverKind } from \"./server-kind\";\nimport type { GlobalOptions } from \"./types\";\n\n/**\n * CLI-specific telemetry glue: the only place that turns a {@link GlobalOptions}\n * invocation into the property bags the generic `Telemetry` client sends,\n * keeping `lib/telemetry` free of CLI coupling.\n */\n\nexport const CLI_COMMAND_STARTED = \"cli_command_started\";\nexport const CLI_COMMAND_COMPLETED = \"cli_command_completed\";\nexport const CLI_COMMAND_FAILED = \"cli_command_failed\";\n\n/**\n * The properties the Vercel Web Analytics copy of a lifecycle event keeps, in\n * priority order, the header first: the intake takes 8.\n */\nexport const VERCEL_EVENT_KEYS = [\n \"surface\",\n \"cli_version\",\n \"server_kind\",\n \"command\",\n \"status\",\n \"reason\",\n \"host_agent\",\n \"non_interactive\",\n] as const;\n\nexport const FIRST_RUN_NOTICE =\n \"Zitadel CLI collects anonymous usage analytics to help improve the tool. \" +\n \"No personal data, project details, server URLs, or file contents are ever \" +\n \"collected. Opt out any time with DO_NOT_TRACK=1, ZITADEL_TELEMETRY=0, or \" +\n \"the --no-telemetry flag.\";\n\ntype DeviceFacts = {\n readonly osLabel: string;\n readonly countryCode: string | undefined;\n readonly platform: NodeJS.Platform;\n readonly arch: string;\n readonly nodeVersion: string;\n readonly cliVersion: string;\n};\n\n/**\n * Process-stable device facts shared by both the event bag and the user\n * profile, so the two never disagree on the same install's OS/arch/version.\n */\nfunction deviceFacts(meta: GlobalOptions): DeviceFacts {\n return {\n osLabel: operatingSystem.value(process.platform),\n countryCode: country.value(undefined),\n platform: process.platform,\n arch: process.arch,\n nodeVersion: process.versions.node,\n cliVersion: meta.cliVersion,\n };\n}\n\nfunction eventDeviceProperties(meta: GlobalOptions): Properties {\n const facts = deviceFacts(meta);\n return {\n $os: facts.osLabel,\n mp_country_code: facts.countryCode,\n os: facts.platform,\n arch: facts.arch,\n node_version: facts.nodeVersion,\n cli_version: facts.cliVersion,\n };\n}\n\nfunction profileDeviceProperties(meta: GlobalOptions): Properties {\n const facts = deviceFacts(meta);\n return {\n $os: facts.osLabel,\n $country_code: facts.countryCode,\n os: facts.platform,\n arch: facts.arch,\n node_version: facts.nodeVersion,\n cli_version: facts.cliVersion,\n };\n}\n\n/**\n * Build the dimensions shared by every lifecycle event, merged with any\n * per-command `extra`. They include the header every Zitadel component sends,\n * as `docs/product-analytics-events.yaml` defines it. The allow-list: only\n * enums, booleans, counts, and versions cross the boundary — never URLs,\n * project ids, file paths, emails, or secrets. `extra` is spread first so the\n * canonical base dimensions always win; callers order their own extras so\n * reserved lifecycle fields win over command props.\n */\nexport function commandEventProperties(\n meta: GlobalOptions,\n invocationId: string,\n extra: Properties = {},\n): Properties {\n const { env } = meta;\n return {\n ...extra,\n surface: \"cli\",\n ...eventDeviceProperties(meta),\n ip: 0,\n invocation_id: invocationId,\n command: meta.command,\n non_interactive: meta.nonInteractive,\n is_tty: meta.isTTY,\n is_ci: ciFlag.value(env),\n ci_provider: ciProvider.value(env),\n host_agent: hostAgent.value(env),\n invocation_channel: invocationChannel.value(env),\n dry_run: meta.dryRun,\n force: meta.force,\n server_kind: serverKind.value(meta.source),\n };\n}\n\n/**\n * Anonymous user-profile properties for this install, so the device appears\n * under Mixpanel \"Users\". Only non-PII device facts; `$name` is a readable,\n * non-identifying label that falls back to the OS when the host agent is\n * unknown. `$ip` is passed separately as a modifier by the caller.\n */\nexport function deviceProfileProperties(meta: GlobalOptions, distinctId: string): Properties {\n const agent = hostAgent.value(meta.env);\n const label = agent === \"unknown\" ? process.platform : agent;\n return {\n ...profileDeviceProperties(meta),\n $name: `${label} · ${distinctId.slice(0, 8)}`,\n host_agent: agent,\n };\n}\n","/**\n * Quote a value for safe interpolation into a `nextCommands` string an agent or\n * a human may paste into a shell. Values that come from the project or the\n * server — an origin, a cursor, a filter — are untrusted: origin validation\n * permits shell metacharacters, so a value such as one containing `$()` must not\n * be emitted raw into an executable command. A value made only of shell-safe\n * characters is returned as-is; anything else is wrapped in single quotes with\n * embedded quotes escaped.\n */\nexport const shellArg = (value: string): string =>\n /^[A-Za-z0-9_.:@/=+-]+$/.test(value) ? value : `'${value.replaceAll(\"'\", `'\\\\''`)}'`;\n\n/**\n * An option and its value for a suggested command's text: `--cwd path`, but\n * `--cwd=-path` for a value that starts with a dash. A separate token would be\n * read as the next option rather than as this one's value, and quoting does not\n * prevent that — `--cwd '--force'` still parses as two options — so the value\n * is joined with `=`, which no parser splits. The argument-list form of the\n * same rule is `optionArgs` in `public-cli.ts`.\n */\nexport const shellOption = (option: string, value: string): string =>\n value.startsWith(\"-\") ? `${option}=${shellArg(value)}` : `${option} ${shellArg(value)}`;\n","import { randomUUID } from \"node:crypto\";\n\nimport { Command, Flags } from \"@oclif/core\";\n\nimport { nonBlankString } from \"./flags\";\nimport consola from \"consola\";\n\nimport { toZitadelError, type ZitadelError } from \"../errors\";\nimport { listenForInterrupt, stopListeningForInterrupt } from \"../interrupt\";\nimport { isObject } from \"../json\";\nimport { type LocalServers, PsLocalServers } from \"../local-server/processes\";\nimport { resolveCwd } from \"../paths\";\nimport { normalizePublicCliCommand, normalizePublicCliCommands } from \"../public-cli\";\nimport { DEFAULT_SERVER, resolveServer, SERVER_VARIABLE } from \"../server\";\nimport { type SuggestedCommand, unscopedCommand } from \"../suggestion\";\nimport { type Properties, Telemetry, type TelemetryDeps } from \"../telemetry\";\nimport { DO_NOT_TRACK, ZITADEL_TELEMETRY } from \"../telemetry/consent\";\nimport { buildUserAgent, installUserAgent, processUserAgentFacts } from \"../user-agent\";\nimport { takeReportedWarnings } from \"../warnings\";\nimport {\n CLI_COMMAND_COMPLETED,\n CLI_COMMAND_FAILED,\n CLI_COMMAND_STARTED,\n commandEventProperties,\n deviceProfileProperties,\n FIRST_RUN_NOTICE,\n VERCEL_EVENT_KEYS,\n} from \"./command-telemetry\";\nimport type { CommandGroup } from \"./groups\";\nimport type {\n CommandResult,\n ErrorEnvelope,\n EnvelopeMeta,\n FlagVariable,\n GlobalOptions,\n JsonEnvelope,\n SkippedEnvelope,\n} from \"./types\";\nimport { shellOption } from \"../shell\";\n\n/**\n * The colour variables, which `bin/run.js` sets from `--color`/`--no-color`\n * and the colour libraries read. The libraries agree that off wins.\n */\nconst NO_COLOR: FlagVariable = {\n name: \"NO_COLOR\",\n flag: \"color\",\n description: \"A non-empty value turns color off, as `--no-color` does (https://no-color.org).\",\n precedence: \"Turns color off even with `--color` or `FORCE_COLOR`.\",\n};\nconst FORCE_COLOR: FlagVariable = {\n name: \"FORCE_COLOR\",\n flag: \"color\",\n description: \"Turns color on where it would be off, such as in a pipe, as `--color` does.\",\n precedence: \"`--no-color` and `NO_COLOR` win over it.\",\n};\n\n/**\n * The environment variables that set what a global flag sets, each declared\n * beside the code that reads it. The CLI reference lists them beside the\n * flags (`./reference.ts`).\n */\nexport const FLAG_VARIABLES: readonly FlagVariable[] = [\n SERVER_VARIABLE,\n NO_COLOR,\n FORCE_COLOR,\n DO_NOT_TRACK,\n ZITADEL_TELEMETRY,\n];\n\n/**\n * Base class for every oclif command. Owns the global flags, builds the\n * {@link GlobalOptions} context (including server `source` resolution) the\n * subclass's `run` reads via `this.meta`, and turns the {@link CommandResult}\n * it returns into the JSON envelope (oclif serialises it natively in `--json`\n * mode) or human-facing text. Errors are translated into the failure envelope\n * and the mapped process exit code. Subclasses stay thin: parse flags, call\n * {@link toMeta}, do their work, and `return this.emit(...)`. The agent\n * contract (ADR 004) is preserved — oclif only replaces parsing, dispatch,\n * help, and JSON emission.\n */\nexport abstract class BaseCommand extends Command {\n /** Opt into oclif's native `--json` flag and JSON serialisation of the result. */\n static override enableJsonFlag = true;\n\n /**\n * The group the root help lists this command under (see `lib/oclif/groups`).\n * Every product command must set it; the root-help test fails otherwise.\n */\n static group?: CommandGroup;\n\n /** Position within {@link group} on the root help, lowest first. */\n static groupOrder?: number;\n\n /**\n * Flags shared by every command, inherited via oclif `baseFlags`. `--force` is\n * deliberately absent: what it permits differs per command (overwrite a\n * managed file, delete a resource), so each command that honours it declares\n * its own with wording that says what it does. {@link toMeta} still reads\n * `flags.force` into {@link GlobalOptions.force} for those commands.\n */\n static override baseFlags = {\n cwd: nonBlankString({ char: \"c\", description: \"Project directory to operate on.\" }),\n server: nonBlankString({ char: \"s\", description: \"Override the resolved server URL.\" }),\n \"non-interactive\": Flags.boolean({\n char: \"n\",\n description: \"Disable prompts. Required when scripting or running as an agent.\",\n }),\n \"dry-run\": Flags.boolean({ description: \"Preview without mutating files or the platform.\" }),\n // `-v` is the short form curl, ssh and wget bind to verbosity, so an agent\n // reaches for it by reflex; the root `--version` here carries no short form,\n // so there is nothing to collide with.\n verbose: Flags.boolean({ char: \"v\", description: \"Verbose logging.\" }),\n debug: Flags.boolean({ description: \"Debug logging.\" }),\n // Declared so oclif accepts `--color`/`--no-color` rather than refusing them\n // as unknown; the colour decision itself is applied in `bin/run.js` (which\n // sets NO_COLOR/FORCE_COLOR before the libraries load) and honoured here.\n // picocolors reads `--no-color` from argv on its own; consola reads the env.\n color: Flags.boolean({\n default: true,\n allowNo: true,\n description:\n \"Colorize human output. Disable with --no-color; NO_COLOR and FORCE_COLOR are honored too.\",\n }),\n telemetry: Flags.boolean({\n default: true,\n allowNo: true,\n description: \"Send anonymous usage analytics. Disable with --no-telemetry.\",\n }),\n };\n\n /** Resolved context for the current invocation; set by {@link toMeta}. */\n protected meta: GlobalOptions = this.fallbackMeta();\n\n /**\n * Anonymous usage analytics for this invocation, created once in\n * {@link toMeta}. Subclasses add command-specific dimensions (framework,\n * counts, `step`, …) via {@link recordTelemetry}; the base class\n * fires the lifecycle events and flushes in {@link finally}.\n */\n protected telemetry?: Telemetry;\n\n /**\n * Per-command dimensions merged onto each lifecycle event emitted *after* they\n * are recorded — typically `completed`/`failed`, since `started` fires from\n * {@link openTelemetry} before a command body runs. Updated immutably via\n * {@link recordTelemetry} — never mutated in place.\n */\n protected telemetryProps: Readonly<Properties> = Object.freeze({});\n\n /** `--cwd` as typed, carried into the unscoped follow-ups this run suggests. */\n private typedCwd: string | undefined;\n\n /** Correlates the started/completed pair; minted at instance construction. */\n private readonly telemetryInvocationId = randomUUID();\n\n /**\n * Wall-clock start used to derive `duration_ms`. Captured at instance\n * construction (before flag parsing and server resolution) so the duration\n * covers the full invocation, even when telemetry is opened late from\n * {@link catch} after an early failure.\n */\n private readonly telemetryStartedAt = Date.now();\n\n /**\n * oclif runs this before `run`. The user agent goes in here, ahead of flag\n * parsing and server resolution, so every request the command makes carries\n * it — including the local-server health probes {@link toMeta} can trigger.\n * Flags are not parsed yet, so `--no-telemetry` is looked for in this\n * command's argv — a plain match that errs towards opting out. (oclif's own\n * `config.userAgent` only feeds its `http-call` client, which the CLI does\n * not use.)\n */\n protected override async init(): Promise<void> {\n // A fresh invocation starts with no warnings, even when an earlier one in\n // the same process (a test run, say) failed before emitting its own.\n takeReportedWarnings();\n await super.init();\n listenForInterrupt();\n const telemetryFlag = this.argv.includes(\"--no-telemetry\") ? false : undefined;\n installUserAgent(buildUserAgent(processUserAgentFacts(this.config.version, telemetryFlag)));\n }\n\n /**\n * A `zitadel` command that does not target a project, in the public `npx`\n * form: `setup`, `start`, `doctor`, the local runtime. A command that talks\n * to a project suggests through `EnvironmentCommand.suggest` instead, which\n * keeps the run's environment selector; reaching for this one is the\n * deliberate opt-out.\n */\n protected suggestUnscoped(args: string): SuggestedCommand {\n // A follow-up run from the shell's directory would act on whatever project\n // is there, so the directory this run addressed goes with it.\n return unscopedCommand(\n this.typedCwd === undefined ? args : `${args} ${shellOption(\"--cwd\", this.typedCwd)}`,\n this.meta.cliVersion,\n );\n }\n\n /**\n * Merge command-specific dimensions into {@link telemetryProps} immutably: a\n * new frozen bag replaces the previous one, so no shared object is ever\n * mutated. `step` advances by re-recording it at each milestone.\n */\n protected recordTelemetry(patch: Properties): void {\n this.telemetryProps = Object.freeze({ ...this.telemetryProps, ...patch });\n }\n\n /**\n * Builds {@link GlobalOptions} from parsed flags and stores the result on\n * `this.meta` so the error handler can render a complete envelope. The server\n * `source` is `--server` or the cloud default, which is `setup`'s rule; a\n * command that takes its server from the environment extends\n * `EnvironmentCommand`, and one that never talks to a server passes\n * `resolveServer: false`.\n */\n protected async toMeta(\n flags: Record<string, unknown>,\n options: { resolveServer?: boolean; source?: string } = {},\n ): Promise<GlobalOptions> {\n const cwd = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n this.typedCwd = typeof flags.cwd === \"string\" ? flags.cwd : undefined;\n const serverFlag = typeof flags.server === \"string\" ? flags.server : undefined;\n const source =\n options.resolveServer === false\n ? { value: options.source ?? \"\", origin: \"default\" as const }\n : await resolveServer({ cwd, serverFlag });\n const json = this.jsonEnabled();\n const isTTY = Boolean(process.stdout.isTTY && process.stdin.isTTY);\n const verbose = Boolean(flags.verbose);\n const debug = Boolean(flags.debug);\n // Default to `info` (3) so users see step-by-step narration (start/info/\n // success/box). `--json` silences consola entirely so the structured\n // envelope is the only thing on stdout. `--debug` raises to 4 (debug);\n // `--verbose` is reserved for richer per-step detail and currently maps\n // to the same level as default.\n consola.level = json ? -999 : debug ? 4 : 3;\n // `--no-color` (or the `NO_COLOR` env) turns colour off; both reach this\n // process as `NO_COLOR` via `bin/run.js`, and `--no-color` also unsets the\n // parsed `color` flag. The flag's value is the source of truth here so that\n // a programmatic `run()` (tests) honours it without the entry-point shim.\n const useColor = flags.color !== false && !process.env[NO_COLOR.name];\n // Drop the right-aligned timestamp the FancyReporter adds by default.\n // Timestamps add no value in a one-off CLI run, wrap awkwardly on long\n // lines (e.g. created-schema URL), and clutter the visual rhythm of the\n // ◐/✔/ℹ glyphs that anchor each step.\n consola.options.formatOptions = {\n ...consola.options.formatOptions,\n date: false,\n colors: useColor,\n compact: true,\n };\n this.meta = {\n cwd,\n nonInteractive: Boolean(flags[\"non-interactive\"]) || !isTTY || json,\n dryRun: Boolean(flags[\"dry-run\"]),\n force: Boolean(flags.force),\n command: this.id ?? \"(default)\",\n cliVersion: this.config.version,\n source: source.value,\n serverFlag,\n verbose,\n debug,\n env: process.env,\n isTTY,\n };\n this.openTelemetry(typeof flags.telemetry === \"boolean\" ? flags.telemetry : undefined);\n return this.meta;\n }\n\n /**\n * Create telemetry once per invocation and open the lifecycle (started event +\n * anonymous profile + first-run notice), reading every dimension from the\n * current {@link meta}. Guarded so a command that resolves meta more than once\n * does not double-count. Also called from {@link catch} so a failure thrown\n * before {@link toMeta} finished (e.g. server resolution, flag parsing) still\n * records the run. Returns early for an inert (opted-out / test-runner /\n * nowhere to send) instance so a disabled run never builds the property bags —\n * no timezone→country resolution or URL parsing for users who opted out. The\n * anonymous device profile is install-level and stable, so it is written only\n * on first run rather than paying a `people.set` request on every command.\n */\n /**\n * Telemetry factory seam. Production returns the real {@link Telemetry.create};\n * tests override it to inject a recording client and assert the lifecycle\n * ordering and opt-out behaviour that the central Vitest consent guard would\n * otherwise make untestable.\n */\n protected createTelemetry(deps: TelemetryDeps): Telemetry {\n return Telemetry.create(deps);\n }\n\n /**\n * Which local servers are running on the machine. Production asks `ps`; a\n * test overrides this, like {@link createTelemetry}, to answer for the machine.\n */\n protected localServers(): LocalServers {\n return new PsLocalServers();\n }\n\n private openTelemetry(flag: boolean | undefined): void {\n if (this.telemetry) {\n return;\n }\n this.telemetry = this.createTelemetry({\n env: process.env,\n flag,\n debug: this.meta.debug,\n vercelKeys: VERCEL_EVENT_KEYS,\n });\n if (!this.telemetry.enabled) {\n return;\n }\n this.telemetry.track(\n CLI_COMMAND_STARTED,\n commandEventProperties(this.meta, this.telemetryInvocationId, this.telemetryProps),\n );\n if (this.telemetry.isFirstRun) {\n this.telemetry.profile(deviceProfileProperties(this.meta, this.telemetry.distinctId), {\n $ip: 0,\n });\n if (this.isInteractive()) {\n process.stderr.write(`${FIRST_RUN_NOTICE}\\n`);\n }\n }\n }\n\n /**\n * Whether this invocation is an interactive human session, used to gate the\n * one-time first-run notice. Derived from argv + `jsonEnabled()` + TTY rather\n * than `meta.nonInteractive`, so it is correct even on the early-failure path\n * where {@link catch} opens telemetry against a fallback meta that has not yet\n * computed `nonInteractive` from the flags.\n */\n private isInteractive(): boolean {\n if (this.meta.nonInteractive || this.jsonEnabled()) {\n return false;\n }\n const argv = process.argv;\n if (argv.includes(\"--json\") || argv.includes(\"--non-interactive\") || argv.includes(\"-n\")) {\n return false;\n }\n return Boolean(process.stdout.isTTY && process.stdin.isTTY);\n }\n\n /**\n * Final step of every command: in human mode it prints the rendered result\n * (oclif suppresses {@link Command.log} under `--json`); it returns the\n * envelope so oclif's `--json` path serialises it.\n */\n protected emit(result: CommandResult): JsonEnvelope {\n const normalized = normalizeCommandResult(result, this.meta);\n if (this.telemetry?.enabled) {\n this.telemetry.track(\n CLI_COMMAND_COMPLETED,\n commandEventProperties(this.meta, this.telemetryInvocationId, {\n ...this.telemetryProps,\n status: result.status,\n duration_ms: Date.now() - this.telemetryStartedAt,\n }),\n );\n }\n // An empty rendering is written as nothing, not as a blank line: a piped\n // list of no records must leave stdout empty, so `wc -l` reports 0.\n const rendered = renderPretty(normalized, this.meta);\n if (rendered !== \"\") {\n this.log(rendered);\n }\n if (normalized.status === \"ok\" && normalized.footer !== undefined) {\n this.log(`\\n${normalized.footer}`);\n }\n // Reported warnings were printed when they happened, so they join the\n // envelope only: printing them again here would show them twice.\n const reported = takeReportedWarnings();\n const envelope = toEnvelope(withReportedWarnings(normalized, reported), this.meta);\n return envelope.status === \"skipped\" ? withWarnings(envelope, reported) : envelope;\n }\n\n /**\n * Renders any thrown error as the failure envelope and exits with its code.\n * A flag-parse error fires before {@link toMeta} runs, so the local `meta`\n * here refreshes `command` from the now-resolved command id to keep the\n * envelope's `command` field accurate. If that early failure left telemetry\n * unopened, {@link openTelemetry} runs here so the failure is still recorded;\n * the flag isn't parsed yet on that path, so `--no-telemetry` is honoured from\n * argv.\n */\n protected override async catch(error: unknown): Promise<never> {\n const meta: GlobalOptions = { ...this.meta, command: this.id ?? this.meta.command };\n const zitadelError = toZitadelError(error);\n this.meta = meta;\n this.openTelemetry(process.argv.includes(\"--no-telemetry\") ? false : undefined);\n if (this.telemetry?.enabled) {\n this.telemetry.track(\n CLI_COMMAND_FAILED,\n commandEventProperties(meta, this.telemetryInvocationId, {\n ...this.telemetryProps,\n status: \"error\",\n reason: zitadelError.code,\n exit_code: zitadelError.exitCode,\n duration_ms: Date.now() - this.telemetryStartedAt,\n }),\n );\n }\n if (this.jsonEnabled()) {\n this.logJson(withWarnings(toErrorEnvelope(zitadelError, meta), takeReportedWarnings()));\n } else if (zitadelError.code !== \"E_CANCELLED\") {\n // Ctrl-C is the person's own decision, and the terminal already shows it\n // (`^C`, or a cancelled prompt's \"Cancelled.\"), so it gets no error\n // block. The exit code still says the command did not finish.\n this.logToStderr(renderError(zitadelError, meta));\n }\n return this.exit(zitadelError.exitCode);\n }\n\n /**\n * oclif runs this after `run`/`catch` on every path. We flush pending\n * telemetry so a short-lived CLI process does not exit before the lifecycle\n * event is sent. The await is bounded by the flush budget, so a hung or\n * firewalled network adds at most ~1s.\n *\n * `mixpanel@0.18` always uses keep-alive agents (hardcoded; not configurable)\n * and exposes no request timeout or handle, so a completed *or* hung request\n * leaves a socket that keeps Node's event loop open past the await. The\n * failure path force-exits via oclif's `exit()`, but the success path would\n * otherwise hang, so we arm an unref'd watchdog: it cannot keep the loop alive\n * on a clean exit, but if a telemetry socket is still holding it open after\n * the grace, it force-exits with the resolved code.\n */\n protected override async finally(error: Error | undefined): Promise<void> {\n stopListeningForInterrupt();\n await this.telemetry?.shutdown(1000);\n if (this.telemetry?.enabled) {\n setTimeout(() => process.exit(process.exitCode ?? 0), 250).unref();\n }\n await super.finally(error);\n }\n\n /**\n * Context used before {@link toMeta} runs, so an error thrown during flag\n * parsing still renders a complete envelope. Version comes from oclif's\n * resolved {@link Command.config}.\n */\n private fallbackMeta(): GlobalOptions {\n return {\n cwd: resolveCwd(undefined),\n nonInteractive: false,\n dryRun: false,\n force: false,\n command: \"(default)\",\n cliVersion: this.config.version,\n source: \"\",\n verbose: false,\n debug: false,\n env: process.env,\n isTTY: Boolean(process.stdout.isTTY && process.stdin.isTTY),\n };\n }\n}\n\nfunction normalizeCommandResult(result: CommandResult, meta: GlobalOptions): CommandResult {\n if (result.status === \"ok\") {\n return {\n ...result,\n data: normalizeDataNextCommands(result.data, meta),\n };\n }\n return {\n ...result,\n data: normalizeDataNextCommands(result.data, meta),\n nextCommands: normalizePublicCliCommands(result.nextCommands, meta.cliVersion),\n };\n}\n\nfunction normalizeDataNextCommands(data: unknown, meta: GlobalOptions): unknown {\n if (!isObject(data) || !Array.isArray(data.next_commands)) {\n return data;\n }\n return {\n ...data,\n next_commands: data.next_commands.map((command) =>\n typeof command === \"string\" ? normalizePublicCliCommand(command, meta.cliVersion) : command,\n ),\n };\n}\n\n/** Add the warnings reported while the command ran to an ok result. */\nfunction withReportedWarnings(result: CommandResult, reported: readonly string[]): CommandResult {\n if (result.status !== \"ok\" || reported.length === 0) {\n return result;\n }\n return { ...result, warnings: [...reported, ...(result.warnings ?? [])] };\n}\n\n/**\n * Add reported warnings to a skipped or error envelope. Those envelopes carry\n * `warnings` only when there are some, so their shape is otherwise unchanged.\n */\nfunction withWarnings<T extends SkippedEnvelope | ErrorEnvelope>(\n envelope: T,\n warnings: readonly string[],\n): T {\n return warnings.length === 0 ? envelope : { ...envelope, warnings: [...warnings] };\n}\n\n/** Wraps a {@link CommandResult} with the invocation metadata into the final envelope. */\nfunction toEnvelope(result: CommandResult, meta: GlobalOptions): JsonEnvelope {\n const base: EnvelopeMeta = {\n cli_version: meta.cliVersion,\n command: meta.command,\n source: meta.source,\n };\n if (result.status === \"ok\") {\n return {\n ...base,\n status: \"ok\",\n data: result.data,\n warnings: result.warnings ? [...result.warnings] : [],\n };\n }\n return {\n ...base,\n status: \"skipped\",\n reason: result.reason,\n data: result.data,\n next_commands: result.nextCommands ? [...result.nextCommands] : undefined,\n };\n}\n\n/** Builds the failure envelope from a {@link ZitadelError} and the invocation metadata. */\nfunction toErrorEnvelope(error: ZitadelError, meta: GlobalOptions): ErrorEnvelope {\n return {\n status: \"error\",\n cli_version: meta.cliVersion,\n command: meta.command,\n source: meta.source,\n code: error.code,\n message: error.message,\n hint: error.hint,\n next_commands: normalizePublicCliCommands(error.nextCommands, meta.cliVersion),\n details: error.details,\n };\n}\n\n/**\n * Renders a {@link CommandResult} as human-facing text for non-JSON mode. A\n * command may supply a bespoke `pretty` string (e.g. `deploy`'s summary);\n * otherwise success payloads are summarised by {@link formatData} and skips are\n * shown with their reason and follow-up commands.\n */\nfunction renderPretty(result: CommandResult, meta: GlobalOptions): string {\n if (result.pretty !== undefined) {\n // A command's own rendering replaces the generic one, but not its\n // warnings: those are printed after it, so setting `pretty` cannot hide them.\n const warnings = result.status === \"ok\" ? (result.warnings ?? []) : [];\n return [result.pretty, ...warnings.map((warning) => `Warning: ${warning}`)]\n .filter((line) => line !== \"\")\n .join(\"\\n\");\n }\n if (result.status === \"ok\") {\n return formatData(result.data, result.warnings ? [...result.warnings] : [], meta);\n }\n const lines = [`Skipped: ${result.reason}${suffixBlock(meta)}`];\n if (result.nextCommands && result.nextCommands.length > 0) {\n lines.push(\"Next:\");\n for (const cmd of result.nextCommands) {\n lines.push(` $ ${cmd}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Renders a {@link ZitadelError} as a human-readable block for stderr: the\n * coded message, an optional hint, and any suggested next commands.\n */\nfunction renderError(error: ZitadelError, meta: GlobalOptions): string {\n const lines = [`Error ${error.code}: ${error.message}`];\n if (error.hint) {\n lines.push(error.hint);\n }\n const nextCommands = normalizePublicCliCommands(error.nextCommands, meta.cliVersion);\n if (nextCommands && nextCommands.length > 0) {\n lines.push(\"Next:\");\n for (const cmd of nextCommands) {\n lines.push(` $ ${cmd}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatData(data: unknown, warnings: string[], opts: GlobalOptions): string {\n if (typeof data === \"string\") {\n const suffix = sourceSuffix(opts);\n return suffix ? `${data}\\n${suffix}` : data;\n }\n\n const lines: string[] = [];\n const titleLine =\n isObject(data) && typeof data.title === \"string\"\n ? String(data.title)\n : \"Zitadel command completed.\";\n lines.push(titleLine);\n const suffix = sourceSuffix(opts);\n if (suffix) {\n lines.push(suffix);\n }\n\n if (isObject(data)) {\n renderKnownSections(lines, data);\n\n if (Array.isArray(data.next_actions) && data.next_actions.length > 0) {\n lines.push(\"\");\n lines.push(\"Next:\");\n for (const action of data.next_actions) {\n lines.push(` ${String(action)}`);\n }\n }\n if (Array.isArray(data.next_commands) && data.next_commands.length > 0) {\n if (!Array.isArray(data.next_actions) || data.next_actions.length === 0) {\n lines.push(\"\");\n lines.push(\"Next:\");\n }\n for (const cmd of data.next_commands) {\n lines.push(` $ ${String(cmd)}`);\n }\n }\n }\n\n for (const warning of warnings.filter((warning) => !warningRenderedInChecks(data, warning))) {\n lines.push(`Warning: ${warning}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction warningRenderedInChecks(data: unknown, warning: string): boolean {\n if (!isObject(data) || !Array.isArray(data.checks)) {\n return false;\n }\n return data.checks.some((check) => {\n if (!isObject(check) || check.status !== \"warn\") {\n return false;\n }\n return warning === `${String(check.name ?? \"check\")}: ${String(check.message ?? \"\")}`;\n });\n}\n\nfunction renderKnownSections(lines: string[], data: Record<string, unknown>): void {\n if (isObject(data.project)) {\n const project = data.project;\n const segments: string[] = [];\n if (typeof project.project_id === \"string\") {\n segments.push(`project=${project.project_id}`);\n }\n if (typeof project.lifecycle === \"string\") {\n segments.push(`lifecycle=${project.lifecycle}`);\n }\n if (typeof project.issuer === \"string\") {\n segments.push(`issuer=${project.issuer}`);\n }\n if (segments.length > 0) {\n lines.push(`Project: ${segments.join(\" \")}`);\n }\n }\n\n if (typeof data.framework === \"string\") {\n lines.push(`framework=${data.framework}`);\n }\n\n if (Array.isArray(data.files_written) || Array.isArray(data.files_skipped)) {\n const written = Array.isArray(data.files_written) ? data.files_written.length : 0;\n const skippedCount = Array.isArray(data.files_skipped) ? data.files_skipped.length : 0;\n lines.push(`Files: ${written} written, ${skippedCount} unchanged`);\n }\n\n if (isObject(data.apply)) {\n const apply = data.apply;\n const bits: string[] = [];\n if (typeof apply.config_version === \"number\") {\n bits.push(`v${apply.config_version}`);\n }\n if (typeof apply.hash === \"string\") {\n bits.push(`hash=${String(apply.hash).slice(0, 12)}`);\n }\n if (typeof apply.environment === \"string\") {\n bits.push(`env=${apply.environment}`);\n }\n if (bits.length > 0) {\n lines.push(`Apply: ${bits.join(\" \")}`);\n }\n }\n\n if (Array.isArray(data.checks) && data.checks.length > 0) {\n lines.push(\"Checks:\");\n for (const check of data.checks) {\n if (!isObject(check)) {\n continue;\n }\n const status = check.status === \"pass\" ? \"ok\" : check.status === \"warn\" ? \"warn\" : \"fail\";\n lines.push(` [${status}] ${String(check.name ?? \"check\")}: ${String(check.message ?? \"\")}`);\n }\n }\n}\n\nfunction sourceSuffix(opts: GlobalOptions): string {\n try {\n const url = new URL(opts.source);\n if (url.host === new URL(DEFAULT_SERVER).host) {\n return \"\";\n }\n return `(server: ${url.host})`;\n } catch {\n return \"\";\n }\n}\n\nfunction suffixBlock(opts: GlobalOptions): string {\n const suffix = sourceSuffix(opts);\n return suffix ? ` ${suffix}` : \"\";\n}\n","import { cancel, confirm, isCancel, multiselect, password, select, text } from \"@clack/prompts\";\n\nimport type { Parsed } from \"@zitadel/config/idp\";\n\nimport { ZitadelError } from \"./errors\";\nimport { readStdin } from \"./variables\";\nimport type { SuggestedCommand } from \"./suggestion\";\n\n/**\n * One option of a `select` or `multiselect`. A `disabled` one is shown, with\n * its hint always visible, but cannot be chosen: for a choice that exists but\n * is not available yet, such as a server that is not running.\n */\ntype Choice<V> = { value: V; label: string; hint?: string; disabled?: boolean };\n\n/** What every question says about itself, whatever it asks for. */\ntype Common = {\n /**\n * What is being asked for, as a lowercase noun phrase (\"client id\"). It is\n * required because any question can meet a run with nobody to ask, and the\n * refusal names it: \"No client id supplied\". For a `confirm` it is the\n * action instead (\"delete the variable\"), which completes \"Cannot delete the\n * variable without --force\". A question that is only ever asked in a\n * terminal never shows it.\n */\n name: string;\n /** The question as the prompt shows it. */\n message: string;\n /**\n * The flag that carries this value (`--client-id`), when there is one. The\n * refusal tells a scripted caller to pass it. Leave it out for a question a\n * script cannot answer with a flag. It is ignored for a `secret`, which is\n * never a flag.\n */\n flag?: string;\n /**\n * The command to run again with the missing input, written for an agent to\n * run. It becomes the refusal's `nextCommands`, and for a value it is also\n * quoted in the hint as an example.\n */\n retry?: SuggestedCommand;\n};\n\n/** A question whose answer is text that must parse. */\ntype TextQuestion = Common & {\n kind: \"text\" | \"secret\";\n /**\n * Turns the text into the value that is returned, or says what is wrong\n * with it. It runs on the value from every source, and in the prompt it is\n * what refuses an answer as it is typed. Use the parser the flag for this\n * value uses and the flag and the prompt cannot disagree.\n */\n parse: (value: string) => Parsed<unknown>;\n /** The value from a flag, if the command line gave one. */\n given?: string;\n /** Whether piped stdin may answer, for a value a script supplies. */\n stdin?: boolean;\n /**\n * Whether having no answer is acceptable, for a value a rerun may replace\n * but does not need. The question then never prompts and never refuses for\n * want of a value: it returns `undefined` when nothing was given and\n * nothing, or only an empty pipe, was piped in. A pipe that has content that\n * does not parse is still an `E_VALIDATION` error, like any other source.\n */\n optional?: boolean;\n initialValue?: string;\n placeholder?: string;\n};\n\ntype SelectQuestion = Common & {\n kind: \"select\";\n options: Choice<unknown>[];\n initialValue?: unknown;\n};\n\ntype MultiselectQuestion = Common & {\n kind: \"multiselect\";\n options: Choice<unknown>[];\n /** Whether at least one option must be ticked. */\n required?: boolean;\n};\n\ntype ConfirmQuestion = Common & {\n kind: \"confirm\";\n initialValue?: boolean;\n};\n\ntype Question = TextQuestion | SelectQuestion | MultiselectQuestion | ConfirmQuestion;\n\n/** What `input` returns for a question: it follows the question's kind. */\ntype Answer<Q extends Question> = Q extends { kind: \"confirm\" }\n ? boolean\n : Q extends { kind: \"multiselect\"; options: Choice<infer V>[] }\n ? V[]\n : Q extends { kind: \"select\"; options: Choice<infer V>[] }\n ? V\n : Q extends { optional: true; parse: (value: string) => Parsed<infer T> }\n ? T | undefined\n : Q extends { parse: (value: string) => Parsed<infer T> }\n ? T\n : never;\n\n/** What the session says about who can answer, beyond the question itself. */\ntype Session = {\n /** Whether a person is at a terminal to be asked. */\n interactive: boolean;\n /** The command's `--force`: it answers a `confirm` without asking. */\n force: boolean;\n /** The stream piped input is read from. Defaults to the process's stdin. */\n stdin?: NodeJS.ReadableStream & { isTTY?: boolean };\n};\n\n/**\n * `input` with the session already filled in, which is what a command's\n * `this.input` and the setup wizard's prompt context hand out.\n */\nexport type Asker = <Q extends Question>(question: Q) => Promise<Answer<Q>>;\n\n/**\n * The one way the CLI takes input from a person or a script. Every command\n * that needs a value, a choice or a confirmation goes through here, so they\n * all look, feel and fail the same way. It is the only module that imports\n * clack's input prompts, and a test fails if any other file does.\n *\n * The sources are tried in a fixed order, and the first that applies answers:\n *\n * 1. **`given`**, the value the command line already carried (a flag).\n * 2. **Piped stdin**, only when the question sets `stdin` and stdin is not a\n * terminal. A terminal on stdin means nothing was piped, and reading it\n * would block forever, so it is never read. An empty pipe that does not\n * parse is a script that piped nothing, and counts as no pipe.\n * 3. **A prompt**, only when the session is `interactive`.\n * 4. **Otherwise an `E_VALIDATION` error**: \"No <name> supplied\", with a hint\n * built from the question's `flag`, whether stdin is accepted and, as an\n * example, its `retry`; and `retry` as `nextCommands` for an agent to run.\n *\n * What comes back follows the `kind`:\n *\n * - `text` and `secret` return what `parse` produced. `parse` runs on the\n * value from every source, so a flag, a pipe and a typed answer are held to\n * one rule, and the caller never parses again. In the prompt it is the\n * validator that refuses an answer as it is typed. A value from a flag or a\n * pipe that does not parse is an `E_VALIDATION` error saying why. `secret`\n * masks what is typed, is never a flag, and is never echoed or put in an\n * error. With `optional`, the answer may be `undefined` (see its docs).\n * - `select` returns the chosen option's `value`.\n * - `multiselect` returns the chosen options' `value`s.\n * - `confirm` returns a boolean. The session's `force` (the command's\n * `--force`) answers it yes without asking. With no one to ask and no\n * `force`, it throws an `E_VALIDATION` error saying `--force` is required.\n * A command whose `--force` means something else must not hand out a\n * session with `force` set.\n *\n * Cancelling a prompt (Ctrl-C) throws `E_CANCELLED` instead of returning a\n * sentinel, so a command never carries on with a missing answer, and exits\n * 130 like Ctrl-C anywhere else. The prompt closes with \"Cancelled.\", which is\n * all a person is shown: a cancel is their own decision, not an error.\n *\n * Commands call this through `this.input(...)` on `BaseCommand`, which fills in\n * `session` from the command's own flags. It takes the session as an argument\n * so it can be tested without a terminal.\n *\n * @example\n * const clientId = await this.input({\n * kind: \"text\",\n * name: \"client id\",\n * message: \"What is the client ID of your Google OAuth app?\",\n * flag: \"--client-id\",\n * parse: parseClientId,\n * given: flags[\"client-id\"],\n * });\n */\nexport async function input<Q extends Question>(question: Q, session: Session): Promise<Answer<Q>> {\n const q: Question = question;\n const stdin = session.stdin ?? process.stdin;\n const refusal = (message: string, hint?: string): ZitadelError =>\n new ZitadelError(\"E_VALIDATION\", message, {\n ...(hint === undefined ? {} : { hint }),\n ...(q.retry === undefined ? {} : { nextCommands: [q.retry] }),\n });\n const cancelled = (): ZitadelError => {\n cancel(\"Cancelled.\");\n return new ZitadelError(\"E_CANCELLED\", \"Cancelled by user\");\n };\n const unsupplied = (): ZitadelError => {\n const isText = q.kind === \"text\" || q.kind === \"secret\";\n // A secret is never a flag, whatever the question says, because that would\n // put it in shell history, a process listing and CI logs.\n const secret = q.kind === \"secret\";\n const ways = [\n ...(q.flag === undefined || secret ? [] : [`pass ${q.flag}`]),\n ...(isText && q.stdin === true ? [\"pipe it in on stdin\"] : []),\n ];\n const hint = [\n ...(ways.length === 0\n ? []\n : [`${ways.join(\", or \").replace(/^./, (c) => c.toUpperCase())}.`]),\n ...(secret\n ? [\"It is never a flag: that would put it in shell history, a process listing and CI logs.\"]\n : []),\n ...(isText && q.retry !== undefined ? [`For example: ${q.retry}`] : []),\n ].join(\" \");\n return refusal(`No ${q.name} supplied`, hint === \"\" ? undefined : hint);\n };\n\n const answer = async (): Promise<unknown> => {\n if (q.kind === \"confirm\") {\n if (session.force) {\n return true;\n }\n if (!session.interactive) {\n throw refusal(\n `Cannot ${q.name} without --force in non-interactive mode`,\n `Pass --force to ${q.name}.`,\n );\n }\n const confirmed = await confirm({\n message: q.message,\n initialValue: q.initialValue ?? false,\n });\n if (isCancel(confirmed)) {\n throw cancelled();\n }\n return confirmed;\n }\n\n if (q.kind === \"select\" || q.kind === \"multiselect\") {\n if (!session.interactive) {\n throw unsupplied();\n }\n const chosen =\n q.kind === \"select\"\n ? await select({\n message: q.message,\n options: q.options,\n initialValue: q.initialValue,\n })\n : await multiselect({\n message: q.message,\n options: q.options,\n required: q.required,\n });\n if (isCancel(chosen)) {\n throw cancelled();\n }\n return chosen;\n }\n\n const accept = (raw: string): unknown => {\n const parsed = q.parse(raw);\n if (!parsed.ok) {\n throw refusal(parsed.problem);\n }\n return parsed.value;\n };\n if (q.given !== undefined) {\n return accept(q.given);\n }\n if (q.stdin === true && !stdin.isTTY) {\n const piped = await readStdin(stdin);\n const parsed = q.parse(piped);\n if (parsed.ok) {\n return parsed.value;\n }\n if (piped.trim() !== \"\") {\n throw refusal(parsed.problem);\n }\n }\n if (q.optional === true) {\n return undefined;\n }\n if (!session.interactive) {\n throw unsupplied();\n }\n const validate = (value: string | undefined): string | undefined => {\n const parsed = q.parse(value ?? \"\");\n return parsed.ok ? undefined : parsed.problem;\n };\n const typed =\n q.kind === \"secret\"\n ? await password({ message: q.message, validate })\n : await text({\n message: q.message,\n validate,\n initialValue: q.initialValue,\n placeholder: q.placeholder,\n });\n if (isCancel(typed)) {\n throw cancelled();\n }\n return accept(String(typed ?? \"\"));\n };\n\n // The one cast: `Answer<Q>` is computed from the question's type, which the\n // branches above cannot see, so each branch returns `unknown` and this is\n // where the kind-to-type mapping the question's type promises is trusted.\n return (await answer()) as Answer<Q>;\n}\n","import { chmod, readFile, writeFile } from \"node:fs/promises\";\nimport { parseEnv } from \"node:util\";\n\nimport { ZitadelError } from \"./errors\";\nimport { reportWarning } from \"./warnings\";\n\n/**\n * The single writer for a managed `.env.<name>.local` file.\n *\n * These files may hold a credential (`ZITADEL_PROJECT_SECRET`,\n * `ZITADEL_PREVIEW_TOKEN`), so the mode, the chmod-failure policy and the\n * line-break guard are decided here once rather than re-decided — or forgotten —\n * at each write site. Nothing else in the CLI should call `node:fs`\n * `writeFile`/`chmod` on one of these files; use {@link writeManagedEnvFile} to\n * (re)write a whole file and {@link appendManagedEnvValue} to add one value.\n */\n\n/** A file that may carry a credential is owner read/write only. */\nconst SECRET_MODE = 0o600;\n\n/**\n * One `key=value` per line is the whole file format, so a line break in a value\n * would inject a spurious line (or split a secret) that the next run reads back\n * as different keys. A break is never a legitimate credential, URL or id, so\n * refuse it rather than write a file we cannot read back faithfully. Every other\n * value is quoted as much as it needs to read back exactly.\n */\nexport function envLine(key: string, value: string): string {\n if (/[\\n\\r]/.test(value)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Cannot persist ${key}: its value contains a line break.`,\n {\n hint: \"A .env value is a single line; remove the newline or store the value another way.\",\n },\n );\n }\n // Written as the first form the reader gives back unchanged: bare, then\n // single- then double-quoted. A bare `#` starts a comment and a bare quote is\n // stripped, so a secret holding one would otherwise read back truncated. A\n // quote the value opens and never closes would run on into the next line, so\n // each form is read with a line after it, which must come back untouched.\n const forms = [`${key}=${value}`, `${key}='${value}'`, `${key}=\"${value}\"`];\n const faithful = forms.find((line) => {\n // Followed by lines quoted every way a later value might be, any of which\n // would close a quote this line left open.\n const read = parseEnv(`${line}\\nNEXT_A='a'\\nNEXT_B=\"b\"\\nNEXT_C=\\`c\\`\\n`);\n return read[key] === value && read.NEXT_A === \"a\" && read.NEXT_B === \"b\" && read.NEXT_C === \"c\";\n });\n if (faithful === undefined) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Cannot persist ${key}: no .env quoting reads its value back unchanged.`,\n { hint: \"Set it in the process environment instead of a .env file.\" },\n );\n }\n return faithful;\n}\n\n/**\n * `writeFile`'s `mode` applies only when it creates the file and is masked by\n * the umask, so re-assert the intended mode after every write. A filesystem that\n * cannot chmod (FAT/exFAT, some bind mounts) must not fail the write — the\n * content is already on disk and the next run would read it back without\n * re-prompting, so a throw would be one confusing failure followed by silent\n * success with the same file. Warn once that it could not be locked down, and\n * proceed. This is the only place the CLI calls `chmod` after a write: a bare\n * `chmod(...).catch(() => undefined)` hides the failure from the user and the\n * JSON envelope, and a lint rule (`no-swallowed-chmod`) rejects it.\n */\nexport async function enforceMode(path: string, mode: number): Promise<void> {\n try {\n await chmod(path, mode);\n } catch (error) {\n reportWarning(\n `Wrote ${path} but could not set it to ${mode.toString(8).padStart(4, \"0\")} (${(error as NodeJS.ErrnoException).code ?? \"unknown\"}); its permissions may be broader than intended.`,\n );\n }\n}\n\nfunction enforceSecretMode(path: string): Promise<void> {\n return enforceMode(path, SECRET_MODE);\n}\n\n/**\n * Write a managed env file from scratch, creating or overwriting it, held at\n * 0600. Every value is line-break checked before anything is written, so a bad\n * value fails the whole write rather than corrupting the file.\n */\nexport async function writeManagedEnvFile(\n path: string,\n values: Record<string, string>,\n): Promise<void> {\n const body = `${Object.entries(values)\n .map(([key, value]) => envLine(key, value))\n .join(\"\\n\")}\\n`;\n await writeFile(path, body, { mode: SECRET_MODE });\n await enforceSecretMode(path);\n}\n\n/**\n * Append one `key=value` to a managed env file, creating it if absent. Newline-\n * safe so a file without a trailing newline is not concatenated onto its last\n * line.\n */\nexport async function appendManagedEnvValue(\n path: string,\n key: string,\n value: string,\n): Promise<void> {\n const line = envLine(key, value);\n let existing = \"\";\n try {\n existing = await readFile(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n const next = `${existing}${existing && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\"}${line}\\n`;\n await writeFile(path, next, { mode: SECRET_MODE });\n await enforceSecretMode(path);\n}\n","import { readFile, rename, stat, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ZitadelError } from \"./errors\";\nimport { enforceMode } from \"./fs-safe\";\nimport { isObject, parseJsonObject, stableStringify } from \"./json\";\nimport { DEFAULT_SERVER } from \"./server\";\nimport { unscopedCommand } from \"./suggestion\";\n\n/**\n * Reports whether `cwd` has already been initialized, i.e. a committed\n * `zitadel.json` exists. Used to decide whether setup should run or skip.\n */\nexport async function hasZitadelConfig(cwd: string): Promise<boolean> {\n return exists(join(cwd, \"zitadel.json\"));\n}\n\n/**\n * Reports whether local secret material (`.zitadel/secret`) is present. Gates\n * commands that need credentials, and signals that secrets were already pulled.\n */\nexport async function hasZitadelSecret(cwd: string): Promise<boolean> {\n return exists(join(cwd, \".zitadel/secret\"));\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch (error) {\n if (isNotFound(error)) {\n return false;\n }\n throw error;\n }\n}\n\n/**\n * Shape of the project secret persisted at `.zitadel/secret`. Holds the\n * project identity plus the credentials used to talk to the platform in\n * preview and production. Validated structurally by {@link readZitadelSecret}.\n */\nexport type ZitadelSecret = {\n project_id: string;\n project_secret: string;\n preview_secret: string;\n /** Exact primary origin patterns that admit requests. */\n primary_origins: string[];\n /** Preview origin patterns that bound which preview URLs may register. */\n preview_origins: string[];\n created_at: string;\n /**\n * When the project was attached to an owning team, recorded by\n * `zitadel claim`. Absent until then. The durable record lives on the\n * platform (the team's project grant); this is a local cache so commands can\n * answer \"is this already attached?\" without a round trip.\n */\n claimed_at?: string;\n /** The team that owns the project, recorded alongside {@link claimed_at}. */\n team_id?: string;\n};\n\n/**\n * Reads and parses `zitadel.json` into a plain object. Translates a missing\n * file into an actionable `E_VALIDATION` error pointing at `zitadel setup`;\n * other errors (e.g. malformed JSON) propagate unchanged.\n */\nexport async function readZitadelConfig(cwd: string): Promise<Record<string, unknown>> {\n try {\n return parseJsonObject(await readFile(join(cwd, \"zitadel.json\"), \"utf8\"), \"zitadel.json\");\n } catch (error) {\n if (isNotFound(error)) {\n throw new ZitadelError(\"E_VALIDATION\", \"zitadel.json was not found\", {\n hint: \"Run `zitadel setup` first.\",\n nextCommands: [unscopedCommand(\"setup\")],\n });\n }\n throw error;\n }\n}\n\n/**\n * Reads, parses, and structurally validates `.zitadel/secret`, returning it\n * as a {@link ZitadelSecret}. A missing file becomes an actionable\n * `E_VALIDATION` error pointing at `zitadel setup` / `zitadel doctor --fix`;\n * a present-but-incomplete file throws so callers never proceed with partial\n * credentials.\n */\nexport async function readZitadelSecret(cwd: string): Promise<ZitadelSecret> {\n try {\n const secret = parseJsonObject(\n await readFile(join(cwd, \".zitadel/secret\"), \"utf8\"),\n \".zitadel/secret\",\n );\n if (\n typeof secret.project_id !== \"string\" ||\n typeof secret.project_secret !== \"string\" ||\n typeof secret.preview_secret !== \"string\" ||\n !Array.isArray(secret.preview_origins)\n ) {\n throw new Error(\".zitadel/secret is missing required fields\");\n }\n // primary_origins was added with kinded origins; older secrets only have\n // preview_origins. Treat a missing array as empty so doctor --fix can\n // still rebuild from the rest of the file.\n if (secret.primary_origins === undefined) {\n secret.primary_origins = [];\n }\n if (!Array.isArray(secret.primary_origins)) {\n throw new Error(\".zitadel/secret is missing required fields\");\n }\n return secret as ZitadelSecret;\n } catch (error) {\n if (isNotFound(error)) {\n throw new ZitadelError(\"E_VALIDATION\", \".zitadel/secret was not found\", {\n hint: \"Run `zitadel setup` first, or restore the project secret with `zitadel doctor --fix`.\",\n nextCommands: [unscopedCommand(\"setup\"), unscopedCommand(\"doctor --fix\")],\n });\n }\n throw error;\n }\n}\n\n/**\n * Writes `.zitadel/secret` back after a command mutated it (today only\n * `zitadel claim`, which records `claimed_at` and `team_id`).\n *\n * Atomic by construction: the bytes land in a sibling temp file that is\n * `chmod`ed and then `rename`d over the target, so a crash mid-write can never\n * leave a truncated or world-readable credentials file — the same\n * temp-then-rename the file-writer uses for managed files. Serialised with\n * {@link stableStringify} at mode `0600` to match exactly how setup's patcher\n * first wrote it, so a claim does not churn the file's formatting or loosen\n * the permissions `doctor` asserts.\n */\nexport async function writeZitadelSecret(cwd: string, secret: ZitadelSecret): Promise<void> {\n const path = join(cwd, \".zitadel/secret\");\n const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;\n await writeFile(tmp, `${stableStringify(secret)}\\n`, { mode: 0o600 });\n // `writeFile`'s mode is masked by the process umask, so re-assert it.\n await enforceMode(tmp, 0o600);\n await rename(tmp, path);\n}\n\n/**\n * Reads the configured renderer id from a parsed `zitadel.json`, normalising the\n * legacy `default` alias to `react` and falling back to `react` when unset. The\n * value is validated downstream by `getRenderer`, so callers need not re-check.\n */\nexport function readRendererId(config: Record<string, unknown>): string {\n const branding = isObject(config.branding) ? config.branding : undefined;\n const value = branding && typeof branding.renderer === \"string\" ? branding.renderer : \"react\";\n return value === \"default\" ? \"react\" : value;\n}\n\n/**\n * Reads the recorded sign-in preset from a parsed `zitadel.json`, if present.\n * Setup persists it (see the patcher's `projectConfig`); absent means\n * password-first per the setup default.\n */\nexport function readPreset(config: Record<string, unknown>): string | undefined {\n return typeof config.preset === \"string\" ? config.preset : undefined;\n}\n\n/**\n * Reads the recorded use case from a parsed `zitadel.json`, if present.\n * Guidance-only, like the field itself — behavior lives in the generated\n * schema/flow files.\n */\nexport function readUseCase(config: Record<string, unknown>): string | undefined {\n return typeof config.useCase === \"string\" ? config.useCase : undefined;\n}\n\n/**\n * Reads the top-level `server` origin from a parsed `zitadel.json`, falling\n * back to {@link DEFAULT_SERVER} when the key is absent.\n *\n * Top-level only: `zitadel.json` holds no other server, and setup always writes\n * a concrete one.\n *\n * This is the server the project actually lives on, which is not always the one\n * a command is talking to: `doctor` pins its own source to the local runtime URL\n * and `status --server local` overrides it. Anything reasoning about the\n * project itself (rather than about this invocation) has to read it from here.\n */\nexport function readProjectServer(config: Record<string, unknown>): string {\n return typeof config.server === \"string\" ? config.server : DEFAULT_SERVER;\n}\n\nfunction isNotFound(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: string }).code === \"ENOENT\"\n );\n}\n","import { readdir, readFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { parseEnv } from \"node:util\";\n\nimport { ZitadelError } from \"./errors\";\nimport { input } from \"./input\";\nimport { hasZitadelSecret, readZitadelSecret } from \"./project\";\nimport { appendManagedEnvValue } from \"./fs-safe\";\nimport { parseServer, resolveServer, serverOrigin } from \"./server\";\nimport { unscopedCommand } from \"./suggestion\";\nimport { shellOption } from \"./shell\";\n\n/**\n * The values a command reads from an environment. Each resolves on its own, so\n * a file holding only the project id leaves the server to the process\n * environment. `ZITADEL_ISSUER` is the origin the app serves from, which\n * `setup` records beside the CLI's own values.\n */\nexport const ENVIRONMENT_KEYS = [\n \"ZITADEL_URL\",\n \"ZITADEL_PROJECT_ID\",\n \"ZITADEL_PROJECT_SECRET\",\n \"ZITADEL_PREVIEW_TOKEN\",\n \"ZITADEL_PUBLISHABLE_KEY\",\n \"ZITADEL_RELEASE\",\n \"ZITADEL_ISSUER\",\n] as const;\n\nexport type EnvironmentKey = (typeof ENVIRONMENT_KEYS)[number];\n\n/** One resolved value and where it came from. */\nexport type Resolved = Readonly<{ value: string; source: string }>;\n\n/** One place the chain looked, and which keys it supplied. */\nexport type Consulted = Readonly<{\n source: string;\n /** Whether the flag was given, or the file exists. */\n present: boolean;\n /** The keys this source supplied that no earlier source had. */\n supplied: readonly EnvironmentKey[];\n}>;\n\n/** What a directory resolves to for one invocation. */\nexport type Environment = Readonly<{\n name: Resolved;\n values: Readonly<Partial<Record<EnvironmentKey, Resolved>>>;\n consulted: readonly Consulted[];\n /** The `--env-file` path as given, if one was. */\n envFile?: string;\n /** The project directory the run resolved against. */\n cwd: string;\n}>;\n\nexport type ResolveEnvironmentInput = Readonly<{\n cwd: string;\n env: NodeJS.ProcessEnv;\n serverFlag?: string;\n envName?: string;\n envFile?: string;\n}>;\n\ntype Values = Partial<Record<EnvironmentKey, string>>;\n\n/** The environment names a platform build announces, by the variable it sets. */\nconst PLATFORM_SIGNALS: ReadonlyArray<{\n variable: string;\n /** Set only inside that platform's build, for a signal whose name is too generic to trust alone. */\n platform?: string;\n name: (value: string) => string;\n}> = [\n { variable: \"VERCEL_ENV\", name: (value) => value },\n {\n variable: \"CONTEXT\",\n platform: \"NETLIFY\",\n name: (value) => {\n if (value === \"deploy-preview\" || value === \"branch-deploy\") {\n return \"preview\";\n }\n return value === \"dev\" ? \"development\" : value;\n },\n },\n];\n\n/**\n * Which environment this invocation is in: `--env`, `ZITADEL_ENV`, a hosting\n * platform's own signal, else `development`. `NODE_ENV` is not consulted:\n * platforms set it to `production` for every build, previews included.\n */\nfunction environmentName(env: NodeJS.ProcessEnv, flag?: string): Resolved {\n if (flag) {\n return { value: flag, source: \"--env\" };\n }\n if (env.ZITADEL_ENV) {\n return { value: env.ZITADEL_ENV, source: \"ZITADEL_ENV\" };\n }\n for (const signal of PLATFORM_SIGNALS) {\n const value = env[signal.variable];\n if (value && (signal.platform === undefined || env[signal.platform] === \"true\")) {\n return { value: signal.name(value), source: signal.variable };\n }\n }\n return { value: \"development\", source: \"default\" };\n}\n\n/**\n * An environment name is interpolated into the `.env.<name>.local` paths the\n * chain reads and writes, so a name carrying a slash or `..` would let a value\n * from `--env` or `ZITADEL_ENV` escape the project directory. Only a\n * conservative charset is allowed — letters, digits, dot, dash, underscore —\n * and a `..` sequence is refused outright, before the name reaches any path.\n */\nconst ENVIRONMENT_NAME = /^[A-Za-z0-9._-]+$/;\n\n/**\n * Whether a value is usable as an environment name: the rule the\n * `.env.<name>.local` paths require, shared with `env add` so a name `--env`\n * resolves can also be bound.\n */\nexport function isEnvironmentName(value: string): boolean {\n // `.env.<name>` for `local` is `.env.local`, setup's development file, and a\n // name ending in `.local` would read another environment's `.local` file.\n return (\n ENVIRONMENT_NAME.test(value) &&\n !value.includes(\"..\") &&\n value !== \"local\" &&\n !value.endsWith(\".local\")\n );\n}\n\nfunction assertEnvironmentName(name: Resolved): void {\n if (isEnvironmentName(name.value)) {\n return;\n }\n throw new ZitadelError(\"E_VALIDATION\", `${name.value} is not a valid environment name`, {\n hint:\n `The ${name.source} environment name may use only letters, digits, dot, dash ` +\n 'and underscore, may not contain \"..\", and may not be `local` or end in `.local`. ' +\n \"Pass a safe --env or set ZITADEL_ENV.\",\n });\n}\n\n/**\n * The dotenv files read for an environment, highest priority first.\n * `.env.local` is setup's development project, so only the development\n * environment reads it: another name falling through to it would quietly\n * address the development project.\n */\nfunction environmentFiles(name: string, setupFiles: boolean): readonly string[] {\n return [`.env.${name}.local`, ...(setupFiles ? [\".env.local\"] : []), `.env.${name}`, \".env\"];\n}\n\nfunction pick(values: Readonly<Record<string, string | undefined>>): Values {\n const picked: Values = {};\n for (const key of ENVIRONMENT_KEYS) {\n const value = values[key];\n if (value) {\n picked[key] = value;\n }\n }\n return picked;\n}\n\n/**\n * Reads the keys an environment cares about from one dotenv file, or\n * `undefined` when the file does not exist. Parsed with `node:util`'s\n * `parseEnv`, which is why this stays separate from the local runtime's loader\n * in `local-server/env-vars.ts`: that one is hard-coded to its own keys.\n */\nasync function readEnvFile(path: string): Promise<Values | undefined> {\n try {\n return pick(parseEnv(await readFile(path, \"utf8\")));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\n/**\n * Resolves the server, project and credentials a command addresses, each\n * value from the first source that supplies it: `--server`, `--env-file`, the\n * process environment, `.env.<env>.local`, `.env.local`, `.env.<env>`, `.env`,\n * then `.zitadel/secret`. `.env.local` and `.zitadel/secret` hold the project\n * setup created, so only the default development environment, without\n * `--env-file`, reads them.\n *\n * `--env-file` outranks the process environment because a path typed on this\n * invocation is as explicit as `--server`; everywhere else the process\n * environment wins over files, so values a platform injects beat a stale\n * `.env` left in the tree.\n */\nexport async function resolveEnvironment(input: ResolveEnvironmentInput): Promise<Environment> {\n if (input.envName && input.envFile) {\n throw new ZitadelError(\"E_VALIDATION\", \"--env and --env-file cannot be used together\", {\n hint: \"--env picks the .env.<name>.local files; --env-file names one file outright.\",\n });\n }\n const name = environmentName(input.env, input.envName);\n assertEnvironmentName(name);\n\n const sources: Array<{ source: string; values: Values | undefined }> = [\n {\n source: \"--server\",\n values: input.serverFlag\n ? {\n ZITADEL_URL: (await resolveServer({ cwd: input.cwd, serverFlag: input.serverFlag }))\n .value,\n }\n : undefined,\n },\n ];\n if (input.envFile) {\n const values = await readEnvFile(resolve(input.cwd, input.envFile));\n if (values === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", `--env-file ${input.envFile} was not found`);\n }\n sources.push({ source: `--env-file ${input.envFile}`, values });\n }\n sources.push({ source: \"process environment\", values: pick(input.env) });\n // `.env.local` and `.zitadel/secret` hold the project setup created, which is\n // the development one. A named environment or an explicit --env-file that\n // lacks a value must fail naming it, not borrow the development project's\n // id or credential and send it to another server.\n // An --env-file names its file outright, so no `.env.*` file fills its gaps:\n // with no --env the name is `development`, and `.env.development.local` is\n // setup's development project too.\n const setupFiles = name.value === \"development\" && input.envFile === undefined;\n if (input.envFile === undefined) {\n for (const file of environmentFiles(name.value, setupFiles)) {\n sources.push({ source: file, values: await readEnvFile(join(input.cwd, file)) });\n }\n }\n if (setupFiles) {\n const secret = (await hasZitadelSecret(input.cwd))\n ? await readZitadelSecret(input.cwd)\n : undefined;\n sources.push({\n source: \".zitadel/secret\",\n values: secret && {\n ZITADEL_PROJECT_ID: secret.project_id,\n ZITADEL_PROJECT_SECRET: secret.project_secret,\n ZITADEL_PREVIEW_TOKEN: secret.preview_secret,\n },\n });\n }\n\n const values: Partial<Record<EnvironmentKey, Resolved>> = {};\n const consulted: Consulted[] = [];\n for (const { source, values: supplied } of sources) {\n const taken: EnvironmentKey[] = [];\n for (const key of ENVIRONMENT_KEYS) {\n const value = supplied?.[key];\n if (value !== undefined && values[key] === undefined) {\n values[key] = { value: key === \"ZITADEL_URL\" ? originFrom(value, source) : value, source };\n taken.push(key);\n }\n }\n consulted.push({ source, present: supplied !== undefined, supplied: taken });\n }\n\n return {\n name,\n values,\n consulted,\n cwd: input.cwd,\n ...(input.envFile === undefined ? {} : { envFile: input.envFile }),\n };\n}\n\n/** A server value as an origin, or an `E_VALIDATION` naming where it came from. */\nfunction originFrom(value: string, source: string): string {\n try {\n return serverOrigin(value);\n } catch (error) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `ZITADEL_URL from ${source} is not a valid server: ${value}`,\n {\n hint: `Fix or remove ZITADEL_URL in ${source}; it must be a URL such as https://api.zitadel.cloud.`,\n ...(error instanceof Error ? { details: { cause: error.message } } : {}),\n },\n );\n }\n}\n\n/**\n * The value a command cannot run without, or an `E_VALIDATION` naming the\n * environment, the variable and every source the chain looked in.\n */\nexport function requireValue(environment: Environment, key: EnvironmentKey): string {\n const resolved = environment.values[key];\n if (resolved) {\n return resolved.value;\n }\n const name = environment.name.value;\n const consulted = `Consulted, in order: ${environment.consulted.map((entry) => entry.source).join(\", \")}.`;\n // The file to set the value in. An --env-file run reads that file; an\n // environment already bound by `env add` has its `.env.<name>.local`. Only an\n // environment with no project at all is pointed at `env add` (or `setup` for\n // development): re-running `env add` on a bound one would refuse, and with\n // --force replace the binding with a new project, and creating one where the\n // process environment already names a project would pair that project with\n // another's credential.\n const boundFile = `.env.${name}.local`;\n const bound = environment.consulted.some((entry) => entry.source === boundFile && entry.present);\n const file = environment.envFile ?? (bound ? boundFile : undefined);\n const unbound = file === undefined && environment.values.ZITADEL_PROJECT_ID === undefined;\n throw new ZitadelError(\"E_VALIDATION\", `${key} is not set for the ${name} environment`, {\n hint: unbound\n ? `${consulted} Set ${key} in ${boundFile} or the process environment, or run \\`zitadel env add ${name}\\`.`\n : `${consulted} Set ${key} in ${file ?? `${boundFile} or the process environment`}${file === undefined ? \"\" : \" or the process environment\"}.`,\n ...(unbound\n ? {\n // Run in the directory this run addressed, which need not be the\n // shell's: `setup` and `env add` both write their files there.\n nextCommands: [\n unscopedCommand(\n `${name === \"development\" ? \"setup\" : `env add ${name}`}${\n environment.cwd === process.cwd() ? \"\" : ` ${shellOption(\"--cwd\", environment.cwd)}`\n }`,\n ),\n ],\n }\n : {}),\n details: {\n environment: name,\n variable: key,\n consulted: environment.consulted.map((entry) => entry.source),\n },\n });\n}\n\n/** The values that grant access, prompted without echo and persisted at 0600. */\nconst SECRET_KEYS: ReadonlySet<EnvironmentKey> = new Set([\n \"ZITADEL_PROJECT_SECRET\",\n \"ZITADEL_PREVIEW_TOKEN\",\n]);\n\n/**\n * Like {@link requireValue}, but on an interactive terminal a missing value is\n * asked for and persisted to `.env.<name>.local` before it is returned, so the\n * next run resolves it from the file rather than asking again (#1313). A secret\n * is asked for without echo and the file is written `0600`. A run that named\n * its own file with `--env-file` keeps the value for this run only: writing it\n * to `.env.<name>.local` would hand it to every later run of that environment.\n *\n * Non-interactive runs never prompt: they throw exactly as {@link requireValue}\n * does, naming every source the chain consulted, so a scripted caller stays\n * deterministic. The prompt is gated by the caller passing `interactive`, which\n * is already false under `--json`, `--non-interactive` and a non-TTY.\n */\nexport async function requireValueInteractive(\n environment: Environment,\n key: EnvironmentKey,\n options: { cwd: string; interactive: boolean },\n): Promise<string> {\n const resolved = environment.values[key];\n if (resolved) {\n return resolved.value;\n }\n if (!options.interactive) {\n // Deterministic failure, identical to the non-interactive contract.\n return requireValue(environment, key);\n }\n const name = environment.name.value;\n const value = await input(\n {\n kind: SECRET_KEYS.has(key) ? \"secret\" : \"text\",\n name: key,\n message: `${key} for the ${name} environment`,\n // Persist (and return) the normalized form, matching how the resolver\n // stores a server value, so the file and this run agree with every later run.\n parse: (answer: string) => {\n const typed = answer.trim();\n if (typed === \"\") {\n return { ok: false, problem: `Enter ${key}.` } as const;\n }\n return key === \"ZITADEL_URL\" ? parseServer(typed) : ({ ok: true, value: typed } as const);\n },\n },\n { interactive: true, force: false },\n );\n if (environment.envFile === undefined) {\n await persistEnvValue(join(options.cwd, `.env.${name}.local`), key, value);\n }\n return value;\n}\n\n/**\n * Appends `key=value` to a `.env.<name>.local`, creating it if absent. The\n * managed-env-file writer ({@link appendManagedEnvValue}) owns the 0600 mode,\n * the chmod-failure policy and the line-break guard, so every secret-file write\n * in the CLI goes through one place.\n */\nasync function persistEnvValue(path: string, key: EnvironmentKey, value: string): Promise<void> {\n await appendManagedEnvValue(path, key, value);\n}\n\n/**\n * The `.env.<name>.local` files in `cwd` that bind an environment to a\n * project, as `[name, file, values]`, ordered by name.\n */\nexport async function readBoundEnvironments(\n cwd: string,\n): Promise<Array<{ name: string; file: string; values: Values }>> {\n const bound: Array<{ name: string; file: string; values: Values }> = [];\n for (const file of (await readdir(cwd)).sort()) {\n const name = /^\\.env\\.(.+)\\.local$/.exec(file)?.[1];\n const values = name === undefined ? undefined : await readEnvFile(join(cwd, file));\n if (name !== undefined && values?.ZITADEL_PROJECT_ID) {\n bound.push({ name, file, values });\n }\n }\n return bound;\n}\n","import type { EnvironmentKey } from \"../environment\";\n\n/**\n * The credentials a command can authenticate with, and the variable each one\n * is read from. A command declares which one it needs (`static credential` on\n * {@link import(\"./environment-command\").EnvironmentCommand}); the other is\n * never tried in its place, because a token that works but carries the wrong\n * reach is worse than a command that stops and names the variable it wants.\n */\nexport const CREDENTIALS = {\n project: \"ZITADEL_PROJECT_SECRET\",\n preview: \"ZITADEL_PREVIEW_TOKEN\",\n} as const satisfies Record<string, EnvironmentKey>;\n\nexport type CredentialKind = keyof typeof CREDENTIALS;\n","import { shellOption } from \"../shell\";\nimport { nonBlankString } from \"./flags\";\nimport { asEnvironmentSelector, type EnvironmentSelector } from \"../suggestion\";\n\n/**\n * The flags that choose the environment a command runs against, spread into\n * the `baseFlags` of {@link import(\"./environment-command\").EnvironmentCommand}.\n * Kept as a bag of their own so a test can check them against every other bag\n * for a clashing name or short form.\n */\nexport const environmentFlags = {\n env: nonBlankString({\n char: \"e\",\n description:\n \"Environment to run against, e.g. production. Defaults to ZITADEL_ENV, then the hosting platform's build (VERCEL_ENV, or Netlify's CONTEXT), then development.\",\n }),\n \"env-file\": nonBlankString({\n description:\n \"Read ZITADEL_* values from this file ahead of the process environment. Cannot be combined with --env.\",\n }),\n};\n\n/**\n * The flags the `preview` command adds on top of the environment ones: which\n * preview URLs to deploy to and for how long. Kept as a bag so `preview` can\n * spread them while `preview list` and `preview rm`, which share the preview\n * credential but take neither, stay free of them.\n */\nexport const previewFlags = {\n origin: nonBlankString({\n description:\n \"A preview URL to deploy to, instead of detecting them from the platform build. Repeatable.\",\n multiple: true,\n }),\n ttl: nonBlankString({\n description:\n \"How long each preview stays live, e.g. 7d, 12h or 90m. Between 60s and 365d. Omitted, the project's default applies.\",\n }),\n};\n\n/**\n * The `--env`/`--env-file`/`--server` suffix — a leading-space string, or empty\n * — that reproduces an invocation's environment selection, appended to a\n * `zitadel` command a run suggests so the retry resolves the same server,\n * project and credential instead of silently falling back to the default\n * environment and quietly targeting the wrong project.\n *\n * This is the single source for the suffix format. {@link\n * import(\"./environment-command\").EnvironmentCommand.environmentSelector}\n * derives these arguments from its resolved environment; a command that only\n * reads the raw flags (e.g. `doctor`, which is not an `EnvironmentCommand` but\n * still honours `--env`/`--env-file`) passes them straight through. Only a\n * value that actually came from a flag is reproduced — `--env` and `--env-file`\n * are mutually exclusive, and `--server` can accompany either; an inherited\n * value needs no flag because the next run in the same environment inherits it.\n */\nexport function environmentSelectorSuffix(input: {\n /** `--cwd` as typed: the project the run was about, and what `--env-file` resolves against. */\n cwd?: string;\n envFile?: string;\n envName?: string;\n server?: string;\n}): EnvironmentSelector {\n const parts: string[] = [];\n if (input.envFile !== undefined) {\n parts.push(shellOption(\"--env-file\", input.envFile));\n } else if (input.envName !== undefined) {\n parts.push(shellOption(\"--env\", input.envName));\n }\n if (input.server !== undefined) {\n parts.push(shellOption(\"--server\", input.server));\n }\n // Last, as the least interesting part to read; flag order does not matter.\n if (input.cwd !== undefined) {\n parts.push(shellOption(\"--cwd\", input.cwd));\n }\n return asEnvironmentSelector(parts.length === 0 ? \"\" : ` ${parts.join(\" \")}`);\n}\n","import { consola } from \"consola\";\n\nimport { createZitadelClient, type ZitadelClient } from \"../api-client\";\nimport { type Environment, requireValueInteractive, resolveEnvironment } from \"../environment\";\nimport { resolveCwd } from \"../paths\";\nimport { BaseCommand } from \"./base\";\nimport { CREDENTIALS, type CredentialKind } from \"./credentials\";\nimport { environmentFlags, environmentSelectorSuffix } from \"./environment-flags\";\nimport type { GlobalOptions } from \"./types\";\nimport { type EnvironmentSelector, projectCommand, type SuggestedCommand } from \"../suggestion\";\nimport { optionArgs } from \"../public-cli\";\n\n/** The platform connection {@link EnvironmentCommand.connect} opens. */\nexport type Connection = Readonly<{\n client: ZitadelClient;\n projectId: string;\n server: string;\n environment: Environment;\n}>;\n\n/**\n * A command that talks to a project. The server, the project and the\n * credential all come from the environment it runs in — `--env`,\n * `--env-file`, the process environment and the `.env` files, then\n * `.zitadel/secret` — so every such command resolves them the same way and\n * fails the same way when one is missing.\n *\n * Which credential it authenticates with is `static credential`; the project\n * secret unless a subclass says otherwise.\n */\nexport abstract class EnvironmentCommand extends BaseCommand {\n static override baseFlags = { ...BaseCommand.baseFlags, ...environmentFlags };\n\n static credential: CredentialKind = \"project\";\n\n /** What the invocation resolved to; set by {@link toMeta}. */\n protected environment!: Environment;\n\n /** `--cwd` as typed, reproduced by {@link environmentSelector}. */\n private cwdFlag: string | undefined;\n\n /**\n * Resolve the environment, then build the invocation context from its server.\n *\n * A missing server is not an error here: whether a command needs one is for\n * {@link connect} to say, so `zitadel env` can show an environment that\n * resolves to nothing. `options.source` stands in for `--server`, for the\n * commands that read the server from somewhere the chain does not know (the\n * local runtime metadata `status --server local` reads).\n */\n protected override async toMeta(\n flags: Record<string, unknown>,\n options: { resolveServer?: boolean; source?: string; environment?: boolean } = {},\n ): Promise<GlobalOptions> {\n const text = (value: unknown): string | undefined =>\n typeof value === \"string\" ? value : undefined;\n this.cwdFlag = text(flags.cwd);\n // A command that only edits files in the project directory resolves none:\n // a stray ZITADEL_ENV must not stop it, and it names no server or project.\n if (options.environment === false) {\n return super.toMeta(flags, { resolveServer: options.resolveServer, source: options.source });\n }\n this.environment = await resolveEnvironment({\n cwd: resolveCwd(text(flags.cwd)),\n env: process.env,\n serverFlag: options.source ?? text(flags.server),\n envName: text(flags.env),\n envFile: text(flags[\"env-file\"]),\n });\n return super.toMeta(flags, {\n resolveServer: false,\n source: this.environment.values.ZITADEL_URL?.value ?? \"\",\n });\n }\n\n /**\n * The flags that reproduce this invocation's environment selection, as a\n * suffix to append to a `zitadel` command this run suggests (e.g.\n * ` --env production`). A retry the CLI prints must resolve the same server,\n * project and credential this run did; without the selector it would fall\n * back to the default environment and quietly target the wrong project.\n *\n * Only flags actually passed are reproduced: a name that came from\n * `ZITADEL_ENV` or a platform signal needs none, because the next run in the\n * same environment inherits it. `--env` and `--env-file` are mutually\n * exclusive; `--server` (the URL only) can accompany either. Empty when the\n * invocation used no selector.\n */\n protected environmentSelector(): EnvironmentSelector {\n const { environment } = this;\n return environmentSelectorSuffix({\n cwd: this.cwdFlag,\n envFile: environment.envFile,\n envName: environment.name.source === \"--env\" ? environment.name.value : undefined,\n server:\n environment.values.ZITADEL_URL?.source === \"--server\"\n ? environment.values.ZITADEL_URL.value\n : undefined,\n });\n }\n\n /**\n * {@link environmentSelector} as arguments, for a result that reports its\n * follow-ups as argument lists too (`next_args`).\n */\n protected environmentSelectorArgs(): string[] {\n const { environment } = this;\n return [\n ...(environment.envFile !== undefined\n ? optionArgs(\"--env-file\", environment.envFile)\n : environment.name.source === \"--env\"\n ? optionArgs(\"--env\", environment.name.value)\n : []),\n ...(environment.values.ZITADEL_URL?.source === \"--server\"\n ? optionArgs(\"--server\", environment.values.ZITADEL_URL.value)\n : []),\n ...(this.cwdFlag === undefined ? [] : optionArgs(\"--cwd\", this.cwdFlag)),\n ];\n }\n\n /**\n * A `zitadel` command aimed at this run's project: `args` with this run's\n * {@link environmentSelector} appended, in the public `npx` form. Use it for\n * every suggestion a project command makes; a command that deliberately\n * leaves the project uses {@link BaseCommand.suggestUnscoped}.\n */\n protected suggest(args: string): SuggestedCommand {\n return projectCommand(args, this.environmentSelector(), this.meta.cliVersion);\n }\n\n /**\n * Open the platform connection, authenticated with this command's\n * credential. It fails, naming the variable, when the server, the project or\n * the credential is missing.\n *\n * Which project and server the command is about is worth stating to a person,\n * but those lines share stdout with the result, so they are printed only on a\n * terminal: on a pipe the result travels alone, and `--json` silences them\n * either way. `quiet` is for a command whose own output is that summary.\n *\n * `verbatim` is for a caller that stores or compares what it reads (see\n * `SanitizeOptions`).\n * `prompt: false` is for a best-effort probe that must never stop to ask\n * (or write `.env.<name>.local`): a missing value then fails as it would\n * non-interactively.\n */\n protected async connect(\n options: { verbatim?: boolean; quiet?: boolean; prompt?: boolean } = {},\n ): Promise<Connection> {\n const { credential } = this.constructor as typeof EnvironmentCommand;\n const { environment } = this;\n // Recorded before anything is required, so a run stopped for a missing\n // value still says which credential it was after.\n this.recordTelemetry({ credential, has_env_file: environment.envFile !== undefined });\n // On a terminal a missing value is prompted for and persisted to\n // `.env.<name>.local` (#1313); non-interactively each still throws, naming\n // the sources consulted, so a scripted run stays deterministic.\n // A dry run writes nothing, and an answer is persisted to a file, so it\n // never asks: a missing value fails it exactly as a scripted run.\n const ask = {\n cwd: this.meta.cwd,\n interactive: !this.meta.nonInteractive && !this.meta.dryRun && options.prompt !== false,\n };\n const server = await requireValueInteractive(environment, \"ZITADEL_URL\", ask);\n const projectId = await requireValueInteractive(environment, \"ZITADEL_PROJECT_ID\", ask);\n const token = await requireValueInteractive(environment, CREDENTIALS[credential], ask);\n if (process.stdout.isTTY && !options.quiet) {\n consola.info(`Project ${projectId}`);\n consola.info(`Server ${server}`);\n }\n return {\n client: createZitadelClient({ baseUrl: server, token }, { verbatim: options.verbatim }),\n projectId,\n server,\n environment,\n };\n }\n}\n\n/**\n * A command that runs in a pull-request build and talks to the project with one\n * credential, never falling back to the other: a missing one fails and names\n * the variable. The `preview` command adds the `--origin`/`--ttl` flag bag\n * itself; `preview list` and `preview rm` extend this for the credential alone.\n *\n * The reach the credential carries — the release/deployment/preview operations\n * these commands make — is granted and enforced by the server, not by the CLI:\n * the CLI only chooses which token to present.\n *\n * Which one that is, is {@link PREVIEW_CREDENTIAL}: the project secret for now,\n * because the server does not accept the narrower preview token yet (#1575).\n * Every message naming the variable derives it from there, so moving back to\n * `preview` is this one constant.\n */\nexport const PREVIEW_CREDENTIAL: CredentialKind = \"project\";\n\nexport abstract class PreviewCommand extends EnvironmentCommand {\n static override credential: CredentialKind = PREVIEW_CREDENTIAL;\n\n /**\n * Never prompts: a pull-request build has no one to ask, and a missing\n * value, the preview token above all, fails naming the variable rather\n * than being typed in and saved to `.env.<name>.local`.\n */\n protected override connect(\n options: { verbatim?: boolean; quiet?: boolean; prompt?: boolean } = {},\n ): Promise<Connection> {\n return super.connect({ ...options, prompt: false });\n }\n}\n","/**\n * Where a provider sends the browser back to, for the connection `slug`.\n *\n * Fixed rather than configurable: the route is served by the dev proxy every\n * framework patcher installs, so a Project cannot change it without changing\n * the scaffold, and a developer who has to register the URI with the vendor\n * benefits from it being the same everywhere.\n *\n * One per connection rather than shared: the path names the connection the\n * provider answered, so the engine can refuse a callback that arrives on\n * another connection's route than the one the sign-in started (the mix-up\n * attack, RFC 9700 §4.4). A connection's slug never changes, so neither does\n * its URI.\n */\nexport function idpCallbackPath(slug: string): string {\n return `/__nextgen/idp/${encodeURIComponent(slug)}/callback`;\n}\n\n/**\n * The redirect URI to register with a provider for the connection `slug`, on\n * the Project's own origin.\n *\n * The trailing slash an issuer may carry is dropped: vendors match redirect\n * URIs literally, and `http://localhost:3000//__nextgen/...` is a different\n * string from the one the browser will actually arrive at.\n */\nexport function callbackUriFor(issuer: string, slug: string): string {\n return `${issuer.replace(/\\/$/, \"\")}${idpCallbackPath(slug)}`;\n}\n","import type { FlowValidationIssue } from \"@zitadel/config/validate\";\n\nimport { ZitadelError } from \"./errors\";\nimport { checkFlow, offeredSignInMethods } from \"./flows\";\nimport { type FlowFile, methodsOf, type SchemaFile } from \"./idp\";\nimport { isObject } from \"./json\";\n\n/**\n * The methods `auth-method password` and `auth-method passkey` switch on and\n * off by a flag alone (ADR 070).\n *\n * SSO is not one of them: a provider needs credentials, a connection file and\n * flow edits, so `auth-method sso` handles it with its own commands.\n */\nexport const TOGGLEABLE_METHODS = [\"password\", \"passkey\"] as const;\nexport type ToggleableMethod = (typeof TOGGLEABLE_METHODS)[number];\n\n/**\n * Set `x-auth-methods.<method>.enabled` on a schema document.\n *\n * Only `enabled` is written. Anything else under the method, and every other\n * method, belongs to whoever put it there. A method already in the requested\n * state is reported as unchanged and the input returned as it is, so running\n * the command twice writes nothing the second time.\n *\n * @param schema - The schema document, which is not mutated.\n * @param method - The method to switch.\n * @param enabled - The state to put it in.\n */\nexport function setMethodEnabled(\n schema: Record<string, unknown>,\n method: ToggleableMethod,\n enabled: boolean,\n): { readonly document: Record<string, unknown>; readonly changed: boolean } {\n const existing = isObject(schema[\"x-auth-methods\"]) ? schema[\"x-auth-methods\"] : {};\n const entry = isObject(existing[method]) ? existing[method] : {};\n if ((entry.enabled === true) === enabled) {\n return { document: schema, changed: false };\n }\n return {\n document: { ...schema, \"x-auth-methods\": { ...existing, [method]: { ...entry, enabled } } },\n changed: true,\n };\n}\n\n/**\n * The ways a schema's users can actually sign in.\n *\n * Only what the login engine serves counts: password, passkey, and SSO with at\n * least one provider. The meta-schema also accepts `otp` and `magic_link`, but\n * nothing in a flow can use them yet, so a schema left with only those has no\n * way in.\n */\nexport function usableSignInMethods(schema: Record<string, unknown>): string[] {\n return methodsOf(schema).filter((method) =>\n method === \"sso\"\n ? enabledProviders(schema).length > 0\n : (TOGGLEABLE_METHODS as readonly string[]).includes(method),\n );\n}\n\n/**\n * Every string a schema lists under `x-auth-methods.sso.providers`, as\n * written. Some may be no way to sign in at all (see\n * {@link usableSignInMethods}); this is what the schema says, for a hint that\n * names what the developer can remove.\n */\nexport function listedProviders(schema: Record<string, unknown>): string[] {\n const methods = schema[\"x-auth-methods\"];\n const sso = isObject(methods) ? methods.sso : undefined;\n return isObject(sso) && Array.isArray(sso.providers)\n ? sso.providers.filter((p): p is string => typeof p === \"string\")\n : [];\n}\n\n/** The provider slug format the SSO auth-method meta-schema allows. */\nconst PROVIDER_SLUG = /^[a-z0-9][a-z0-9_-]*$/;\n\n/**\n * The listed providers that are well-formed slugs: an entry like `Not A Slug`\n * names no connection, so it is no way to sign in.\n */\nfunction enabledProviders(schema: Record<string, unknown>): string[] {\n return listedProviders(schema).filter((p) => p.length <= 64 && PROVIDER_SLUG.test(p));\n}\n\n/**\n * Whether the schema names the property that identifies a user. The server\n * refuses a schema that enables password without one, because a password is\n * checked against a user found by that property.\n */\nexport function hasIdentifier(schema: Record<string, unknown>): boolean {\n const identifier = schema[\"x-identifier\"];\n return typeof identifier === \"string\" && identifier.trim() !== \"\";\n}\n\n/**\n * The methods a schema enables that some active flow lets an existing user\n * sign in with. SSO counts only through a step offering a provider the schema\n * itself enables.\n *\n * @param schema - The schema document.\n * @param flows - The flows that run against it, whatever their status: only\n * the active ones count.\n */\nexport function reachableSignInMethods(\n schema: Record<string, unknown>,\n flows: readonly Record<string, unknown>[],\n): string[] {\n const offered = offeredSignInMethods(flows, enabledProviders(schema));\n return usableSignInMethods(schema).filter((method) => offered.includes(method));\n}\n\n/**\n * Why the schema's `x-auth-methods` cannot be edited safely for one method, or\n * `undefined` when it can. Only an absent container or entry counts as empty:\n * a value of the wrong shape was written by someone, and rewriting it would\n * discard it.\n */\nexport function malformedAuthMethods(\n schema: Record<string, unknown>,\n method: ToggleableMethod,\n): string | undefined {\n const methods = schema[\"x-auth-methods\"];\n if (methods === undefined) {\n return undefined;\n }\n if (!isObject(methods)) {\n return \"x-auth-methods is not an object\";\n }\n const entry = methods[method];\n if (entry === undefined) {\n return undefined;\n }\n if (!isObject(entry)) {\n return `x-auth-methods.${method} is not an object`;\n }\n // The meta-schema requires a boolean. A missing one or a string \"true\" is\n // neither on nor off, so it is refused rather than overwritten or read as\n // disabled.\n if (typeof entry.enabled !== \"boolean\") {\n return `x-auth-methods.${method}.enabled is not a boolean`;\n }\n return undefined;\n}\n\n/**\n * Refuse to edit a file whose region is not the shape the command edits.\n * Rewriting it would discard whatever a developer put there, so the run stops\n * before anything is written or published.\n *\n * @param path - The project-relative file the region is in.\n * @param region - What is wrong with it, or `undefined` when nothing is, in\n * which case this returns.\n */\nexport function refuseUneditable(path: string, region: string | undefined): void {\n if (region === undefined) {\n return;\n }\n throw new ZitadelError(\"E_VALIDATION\", `${path}: ${region}`, {\n hint:\n \"This command edits that region, and it is not the shape it edits. \" +\n \"Fix it against the dialect in .zitadel/meta/, then run the command again.\",\n details: { file: path, region },\n });\n}\n\n/**\n * Refuse when a flow running against the schema would stop validating once\n * the schema and the flows are changed, or cannot be checked at all. `deploy`\n * would reject either, so the change is refused before it is written.\n *\n * @param schema - The schema being changed.\n * @param after - The schema as the change leaves it.\n * @param flows - Each flow that runs against the schema, with its body as the\n * change leaves it.\n * @param introduced - What to say about errors the change introduces. Neutral\n * by default; a command that leaves flows alone says which method is still\n * used instead.\n */\nexport function refuseBrokenFlows(\n schema: SchemaFile,\n after: Record<string, unknown>,\n flows: ReadonlyArray<{ readonly file: FlowFile; readonly after: Record<string, unknown> }>,\n introduced: { heading: string; hint: string } = {\n heading: \"A login flow would stop validating after this change:\",\n hint: \"Fix the steps named above, then run the command again.\",\n },\n): void {\n const unchecked: FlowIssue[] = [];\n const added: FlowIssue[] = [];\n for (const { file, after: flowAfter } of flows) {\n const check = checkFlow(file.body, schema.body, after, flowAfter);\n if (check.kind === \"unchecked\") {\n unchecked.push(...check.issues.map((issue) => ({ path: file.path, issue })));\n } else {\n added.push(...check.introduced.map((issue) => ({ path: file.path, issue })));\n }\n }\n if (unchecked.length > 0) {\n throw brokenFlowsError(\n schema.path,\n unchecked,\n \"A login flow has errors, so it cannot be checked against the changed schema:\",\n \"Fix those errors first (`zitadel deploy --dry-run` reports them too), then run the command again.\",\n );\n }\n if (added.length > 0) {\n throw brokenFlowsError(schema.path, added, introduced.heading, introduced.hint);\n }\n}\n\n/** A validation issue and the flow file it was found in. */\ntype FlowIssue = { readonly path: string; readonly issue: FlowValidationIssue };\n\nfunction brokenFlowsError(\n file: string,\n issues: readonly FlowIssue[],\n heading: string,\n hint: string,\n): ZitadelError {\n return new ZitadelError(\n \"E_VALIDATION\",\n `${heading}\\n${issues.map(({ path, issue }) => ` - ${path}: ${issue.message}`).join(\"\\n\")}`,\n {\n hint,\n details: {\n file,\n issues: issues.map(({ path, issue }) => ({\n path,\n rule: issue.rule,\n message: issue.message,\n ...(issue.step === undefined ? {} : { step: issue.step }),\n })),\n },\n },\n );\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport type { ResourceEntry, ScaffoldManifest, ZitadelState } from \"./types.js\";\n\nexport type { ZitadelState } from \"./types.js\";\n\n/**\n * Read and parse `.zitadel/state.json`. Throws if the file is\n * missing or malformed; callers run `zitadel setup` first to bring\n * the file into existence.\n */\nexport async function readState(cwd: string): Promise<ZitadelState> {\n const raw = await readFile(join(cwd, \".zitadel/state.json\"), \"utf8\");\n return JSON.parse(raw) as ZitadelState;\n}\n\n/**\n * Merge an entry into the state file under `key`, preserving any\n * fields the caller did not override. Reads the file, writes it back\n * with sorted keys disabled (state is engine-managed, not human-\n * authored, so deterministic ordering isn't required here).\n */\nexport async function updateState(cwd: string, key: string, entry: ResourceEntry): Promise<void> {\n const current = await readState(cwd);\n const updated: ZitadelState = {\n ...current,\n resources: {\n ...current.resources,\n [key]: { ...current.resources[key], ...entry },\n },\n };\n await writeFile(join(cwd, \".zitadel/state.json\"), JSON.stringify(updated, null, 2));\n}\n\n/**\n * Replace the scaffold manifest section wholesale, preserving the sync\n * `resources`. Setup owns the full manifest (it knows exactly what it wrote);\n * `doctor --fix` re-writes it after restoring files. Kept here so state.json\n * retains a single writer module.\n */\nexport async function updateScaffold(cwd: string, scaffold: ScaffoldManifest): Promise<void> {\n const current = await readState(cwd);\n const updated: ZitadelState = { ...current, scaffold };\n await writeFile(join(cwd, \".zitadel/state.json\"), JSON.stringify(updated, null, 2));\n}\n","import { isErrno, ZitadelError } from \"./errors\";\nimport { isObject } from \"./json\";\nimport { readFlowFiles, type FlowFile, type SchemaFile } from \"./idp\";\nimport { readState } from \"./sync/state\";\n\n/**\n * The login flows that run against a user schema.\n *\n * A command that changes a schema has to know which journeys the change\n * reaches: enabling a provider adds it to them, and disabling a sign-in method\n * must not leave one asking for it. A flow belonging to another schema is\n * never returned, so changing customers never touches the employee journey.\n */\nexport async function flowsForSchema(cwd: string, schema: SchemaFile): Promise<FlowFile[]> {\n const publishedIds = await publishedIdsOf(cwd, schema.path);\n return (await readFlowFiles(cwd)).filter((flow) =>\n flowUsesSchema(flow.body, schema, publishedIds),\n );\n}\n\n/**\n * Whether a flow runs against this schema. A flow names its schema by the\n * schema's `objectType`, the handle the platform resolves `user_schema` by;\n * older files name it by the id the platform assigned or by the URL setup\n * wrote, which the schema's own `$id` states.\n */\nfunction flowUsesSchema(\n flow: Record<string, unknown>,\n schema: SchemaFile,\n publishedIds: readonly string[],\n): boolean {\n const used = flow.user_schema;\n if (typeof used !== \"string\") {\n return false;\n }\n // The same order `deploy` resolves a flow's schema in\n // (`pinnedSchemaPath` in lib/release/steps/sso-consistency.ts): `objectType` first.\n const objectType = schema.body.objectType;\n if (typeof objectType === \"string\" && used === objectType) {\n return true;\n }\n // Once a Project has been applied, the flow names the schema by the id the\n // platform assigned, which `.zitadel/state.json` records against the schema\n // file. Before that it still carries the scaffolded URL.\n if (publishedIds.includes(used)) {\n return true;\n }\n const id = schema.body.$id;\n if (typeof id === \"string\") {\n // An `$id` is the schema's own statement of what flows name it by, so a\n // flow that names something else is about a different schema — even when\n // the two URLs end in the same file name. Guessing past a disagreement is\n // how a command would edit the wrong flow.\n return id === used;\n }\n // No `$id` to go on: a Project scaffolded but never applied names the\n // schema by the URL setup wrote, whose last segment is the file name.\n return used.endsWith(`/${schema.name}.json`);\n}\n\n/**\n * The platform ids a local file is known by, from `.zitadel/state.json`: the\n * id it was last synced as, and the one it replaced. `setup` records them, and a\n * flow left behind by an interrupted run may still name the replaced id, so it\n * must still count as this schema's flow. Absent before the first sync, and absent entirely on a Project that has\n * never synced — both mean \"fall back to matching on the scaffolded URL\".\n *\n * Only a missing file falls back. A malformed or unreadable state file is the\n * authoritative record failing to answer, and the fallback matches on a URL\n * suffix rather than an id, so it could pick a flow bound to a different\n * schema. Saying so beats editing the wrong flow quietly.\n */\nasync function publishedIdsOf(cwd: string, path: string): Promise<string[]> {\n try {\n // readState only parses JSON, so the shape is checked here: a valid but\n // corrupt file must not read as \"never synced\" and skip a pinned flow.\n const state: unknown = await readState(cwd);\n if (!isObject(state) || !isObject(state.resources)) {\n throw new Error(\"resources is not an object\");\n }\n const entry = state.resources[path];\n if (entry === undefined) {\n return [];\n }\n if (!isObject(entry)) {\n throw new Error(`resources[\"${path}\"] is not an object`);\n }\n const ids = [entry.id, entry.previousId].filter((id) => id !== undefined);\n // An empty id is as corrupt as a missing one would be wrong to assume:\n // dropping it would fall back to URL matching and could skip the flow\n // pinned to the real published id.\n if (!ids.every((id) => typeof id === \"string\" && id !== \"\")) {\n throw new Error(`resources[\"${path}\"] has an id that is not a non-empty string`);\n }\n return ids as string[];\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return [];\n }\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Cannot read .zitadel/state.json: ${error instanceof Error ? error.message : String(error)}`,\n {\n hint:\n \"The file records which platform resource each local file was synced as. \" +\n \"Fix or remove it, then run this command again.\",\n details: { file: \".zitadel/state.json\" },\n },\n );\n }\n}\n","import type { SuggestedCommand } from \"../suggestion\";\n\n/**\n * Builders for the `data` of a command's JSON envelope.\n *\n * Every command emits `data`, and an agent reads all of them, so the shapes\n * must not drift. These builders are the one place each shape is defined; the\n * spec harness (`assertEnvelope`) enforces the same shapes on every `--json`\n * invocation, so a command that hand-builds a divergent shape fails in its own\n * spec. Use the builder rather than an object literal.\n */\n\n/**\n * The canonical list/collection envelope: `{ items, count, next_page_token }`,\n * plus optional `next_commands`. Every command that returns a collection emits\n * this, so `{ items, count, next_page_token }` reads uniformly across all of\n * them. A single-page endpoint passes `nextPageToken: null` (the default); a\n * paginated one passes the server cursor (or `null` once drained).\n */\nexport function listData<T>(\n items: readonly T[],\n opts: { nextPageToken?: string | null; nextCommands?: readonly SuggestedCommand[] } = {},\n): {\n items: readonly T[];\n count: number;\n next_page_token: string | null;\n next_commands?: readonly SuggestedCommand[];\n} {\n const base = {\n items,\n count: items.length,\n next_page_token: opts.nextPageToken ?? null,\n };\n return opts.nextCommands && opts.nextCommands.length > 0\n ? { ...base, next_commands: opts.nextCommands }\n : base;\n}\n\n/**\n * The canonical delete/remove confirmation: the resource's identifier plus\n * `deleted: true`. The verb is always `deleted` — never `removed` — so an agent\n * reads \"did the delete succeed?\" the same way for every resource, whether it is\n * addressed by `id` or by a natural key (`url`, `pattern`, `name`). A lifecycle\n * verb (revoke, deactivate) uses {@link mutatedData} instead.\n */\nexport function deletedData<I extends Record<string, string>>(\n identifier: I,\n): I & { deleted: true } {\n return { ...identifier, deleted: true };\n}\n\n/**\n * A mutation confirmation whose verb is the lifecycle action, not `deleted`:\n * the identifier plus `<verb>: true` (e.g. `revoked`, `deactivated`). Keeps the\n * `{ identifier, <past-tense>: true }` shape of {@link deletedData} while naming\n * the specific action.\n */\nexport function mutatedData<I extends Record<string, string>, V extends string>(\n identifier: I,\n verb: V,\n): I & Record<V, true> {\n return { ...identifier, [verb]: true } as I & Record<V, true>;\n}\n\n/**\n * The `next_commands` a command's `data` carries, spread into the data object:\n * `{ ...result, ...nextCommandsData(commands) }`. It takes `SuggestedCommand`s,\n * which only the `lib/suggestion` builders make, so every entry has had its\n * environment selector decided (#1689). A Biome GritQL rule\n * (`biome-plugins/no-raw-next-commands.grit`) rejects a hand-written\n * `next_commands:` key anywhere else.\n */\nexport function nextCommandsData(commands: readonly SuggestedCommand[]): {\n next_commands: readonly SuggestedCommand[];\n} {\n return { next_commands: commands };\n}\n","import { type Asker, input as askInput } from \"../input\";\nimport type { BaseCommand } from \"./base\";\n\n/** A class that can be extended, abstract or not, whatever arguments it takes. */\n// biome-ignore lint/suspicious/noExplicitAny: the constructor of any command, which a mixin cannot name\ntype CommandClass<T extends BaseCommand> = abstract new (...args: any[]) => T;\n\n/**\n * Marks a command that can ask a person a question, and gives it the one way\n * to do it. Only a command built on this has `this.input`, so what can prompt\n * is visible in the class it extends, and a command that does not extend it\n * cannot start prompting without that showing in review.\n *\n * ```ts\n * export default class Reset extends Promptable(BaseCommand) {}\n * export default class VariableSet extends Promptable(EnvironmentCommand) {}\n * ```\n *\n * `input` is {@link askInput} with this invocation's interactivity\n * (`--non-interactive`, `--json`, no terminal) and `--force` filled in, so a\n * command states only the question. See {@link askInput} for the order the\n * answer is looked for in and what is thrown when there is none.\n */\nexport function Promptable<TBase extends CommandClass<BaseCommand>>(Base: TBase) {\n abstract class PromptableCommand extends Base {\n protected readonly input: Asker = (question) =>\n askInput(question, { interactive: !this.meta.nonInteractive, force: this.meta.force });\n }\n return PromptableCommand;\n}\n","import { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { consola } from \"consola\";\n\nimport {\n hasIdentifier,\n malformedAuthMethods,\n reachableSignInMethods,\n refuseBrokenFlows,\n refuseUneditable,\n setMethodEnabled,\n TOGGLEABLE_METHODS,\n type ToggleableMethod,\n usableSignInMethods,\n} from \"../auth-methods\";\nimport { ZitadelError } from \"../errors\";\nimport { type FlowFile, readSchemaFiles, type SchemaFile, selectSchema } from \"../idp\";\nimport { stableStringify } from \"../json\";\nimport { optionArgs } from \"../public-cli\";\nimport { flowsForSchema } from \"../schema-flows\";\nimport { reportWarning } from \"../warnings\";\nimport { nextCommandsData } from \"./envelope\";\nimport { EnvironmentCommand } from \"./environment-command\";\nimport { environmentFlags } from \"./environment-flags\";\nimport { portableSuggestions, type SuggestedCommand } from \"../suggestion\";\nimport { nonBlankString } from \"./flags\";\nimport type { JsonEnvelope } from \"./types\";\nimport { Promptable } from \"./promptable\";\n\n/** The message `deploy` needs, which only the caller can write. */\nconst DEPLOY_MESSAGE = \"<what changed>\";\n\n/** What every `auth-method` command reads before changing anything. */\ntype Target = {\n readonly cwd: string;\n /** `--cwd` for a follow-up command, or none when the run had none. */\n readonly cwdArgs: string[];\n readonly schema: SchemaFile;\n /** The login flows that run against the schema, whatever their status. */\n readonly flows: FlowFile[];\n};\n\n/**\n * What the `auth-method` commands share (ADR 070): finding the schema and its\n * flows, the last-method guard and the refusals in §3, the warnings in §3 and\n * §4, and the result shape. `auth-method password` and `auth-method passkey`\n * are nothing else, so {@link toggle} is all they run.\n *\n * Only `auth-method sso enable` talks to a server, to store the provider's\n * credentials. Every other edit is local, and `deploy` publishes it like any\n * configuration change.\n */\nexport abstract class AuthMethodCommand extends Promptable(EnvironmentCommand) {\n // The environment flags are hidden here: most `auth-method` commands only\n // edit files and resolve no environment. The one that publishes credentials\n // to the project lists them among its own flags.\n static override baseFlags = {\n ...EnvironmentCommand.baseFlags,\n env: { ...environmentFlags.env, hidden: true } as typeof environmentFlags.env,\n \"env-file\": {\n ...environmentFlags[\"env-file\"],\n hidden: true,\n } as (typeof environmentFlags)[\"env-file\"],\n schema: nonBlankString({\n description: \"User schema to change. Required when the Project has more than one.\",\n }),\n };\n\n /**\n * Set up the invocation, then read the schema and the flows that run\n * against it, refusing a schema whose methods live elsewhere.\n *\n * @param flags - The parsed flags.\n * @param options.resolveServer - Whether the command talks to a server.\n * Off by default: a stopped local runtime must not block staging a change\n * for a later `deploy`.\n * @param options.preflight - Checks of the flags that must answer before the\n * schema is read, with what they read handed back as `preflight`. It must\n * not ask a question, use the network or write anything: ask in the\n * command's own `run`, after `connect()`.\n */\n protected async target<T = undefined>(\n flags: { schema?: string; cwd?: string },\n options: { resolveServer?: boolean; preflight?: (cwd: string) => Promise<T> } = {},\n ): Promise<Target & { readonly preflight: T }> {\n await this.toMeta(flags, {\n resolveServer: options.resolveServer ?? false,\n // Only a command that talks to a server has an environment to resolve.\n environment: options.resolveServer === true,\n });\n const { cwd } = this.meta;\n const preflight = (await options.preflight?.(cwd)) as T;\n const schema = selectSchema(await readSchemaFiles(cwd), flags.schema);\n refuseExternalSchema(schema);\n return {\n cwd,\n // A follow-up run from where the user stands must reach the same Project.\n cwdArgs: flags.cwd === undefined ? [] : optionArgs(\"--cwd\", cwd),\n schema,\n flows: await flowsForSchema(cwd, schema),\n preflight,\n };\n }\n\n /**\n * The last-method guard (ADR 070 §3). Returns `false` when the user declined\n * the prompt, which ends the run as skipped; refuses without `--force` when\n * nobody can be asked. The question goes through `input`, which `--force`\n * answers yes without asking.\n *\n * A dry run answers before the guard, as it does `variable rm`'s: it\n * changes nothing, so there is nothing to confirm, and {@link reportOutcome}\n * still warns that the schema would have no way to sign in left.\n *\n * @param input.disabling - What the prompt names as being disabled: the\n * method, or the provider for `auth-method sso disable`.\n * @param input.retryArgs - The command's own arguments, which the refusal\n * suggests again with `--force`.\n */\n protected async confirmLastMethod(input: {\n schema: SchemaFile;\n after: Record<string, unknown>;\n disabling: string;\n retryArgs: string[];\n cwdArgs: string[];\n }): Promise<boolean> {\n const { dryRun, force, nonInteractive, cliVersion } = this.meta;\n if (dryRun || !removesLastMethod(input.schema.body, input.after)) {\n return true;\n }\n const retryArgs = [...input.retryArgs, ...input.cwdArgs, \"--force\"];\n if (nonInteractive && !force) {\n // Refused here rather than by `input`, whose refusal names only the\n // --force re-run: this one also lists the methods that could be enabled\n // instead, as argument lists an agent can run whatever the quoting.\n refuseLastMethod({ schema: input.schema, retryArgs, cwdArgs: input.cwdArgs, cliVersion });\n }\n return this.input({\n kind: \"confirm\",\n name: `disable ${input.disabling}, the last way to sign in to ${input.schema.name}`,\n message: `Disable ${input.disabling} anyway? Nobody will be able to sign in to ${input.schema.name}.`,\n retry: portableSuggestions([retryArgs], cliVersion)[0],\n });\n }\n\n /**\n * Report what the change leaves behind (ADR 070 §3 and §4). Called once the\n * change is previewed or written, never before: a failed write must not\n * claim it.\n *\n * @param input.flowsAfter - The flows as the change leaves them, whatever\n * their status.\n * @param input.notOffered - Methods the run enabled that no flow offers.\n */\n protected reportOutcome(input: {\n schema: SchemaFile;\n before: Record<string, unknown>;\n after: Record<string, unknown>;\n flowsAfter: readonly Record<string, unknown>[];\n notOffered?: readonly string[];\n }): void {\n const { dryRun } = this.meta;\n for (const method of input.notOffered ?? []) {\n // Enabling first and editing the flow second is a normal order of work.\n reportWarning(\n `No login flow for ${input.schema.name} offers ${method} yet. Add it to a flow to show it.`,\n );\n }\n if (removesLastMethod(input.before, input.after)) {\n // Reached only through --force, a confirmed prompt or a dry run: said\n // even so.\n reportWarning(\n `${input.schema.name} ${dryRun ? \"would have\" : \"has\"} no way to sign in left. ` +\n \"Its users can only be managed through the API.\",\n );\n return;\n }\n // A schema that enables nothing has nothing for a flow to offer; that is\n // the API-only case the last-method guard already let through.\n if (\n usableSignInMethods(input.after).length > 0 &&\n reachableSignInMethods(input.after, input.flowsAfter).length === 0\n ) {\n // The schema still enables something, but no active flow offers it.\n // Flows are not these commands' to rewrite (ADR 070 §2), so it is said.\n reportWarning(\n `No active login flow for ${input.schema.name} offers a method it enables, ` +\n \"so nobody can sign in until one does.\",\n );\n }\n }\n\n /**\n * The follow-up commands of a result, as strings when every argument is\n * safe to run as written, and always as argument lists.\n *\n * @param changed - Whether a file changed, which `deploy` then publishes.\n * @param cwdArgs - `--cwd` for `deploy`, from {@link target}.\n * @param leading - Commands that come first, such as publishing a credential\n * that did not reach the project.\n */\n protected followUps(\n changed: boolean,\n cwdArgs: string[],\n leading: string[][] = [],\n ): { next_commands: readonly SuggestedCommand[]; next_args: string[][] } {\n const args = [\n ...leading,\n ...(changed\n ? [\n [\"deploy\", \"--dry-run\", ...cwdArgs],\n [\"deploy\", \"-m\", DEPLOY_MESSAGE, ...cwdArgs],\n ]\n : []),\n ];\n return {\n // The message is a placeholder the caller fills in, so it is quoted in\n // the command string and listed as written in `next_args`.\n ...nextCommandsData(portableSuggestions(args, this.meta.cliVersion, [DEPLOY_MESSAGE])),\n next_args: args,\n };\n }\n\n /**\n * `auth-method password|passkey enable|disable`: set\n * `x-auth-methods.<method>.enabled` on one schema. Login flows are never\n * edited, so a change one of them would reject is refused instead.\n */\n protected async toggle(\n flags: { schema?: string; cwd?: string },\n method: ToggleableMethod,\n enabled: boolean,\n ): Promise<JsonEnvelope> {\n const { cwd, cwdArgs, schema, flows } = await this.target(flags);\n const { dryRun } = this.meta;\n const verb = enabled ? \"enable\" : \"disable\";\n\n refuseUneditable(schema.path, malformedAuthMethods(schema.body, method));\n const change = setMethodEnabled(schema.body, method, enabled);\n if (change.changed) {\n if (enabled) {\n refuseMissingIdentifier(schema, method);\n }\n // Both directions: a changed schema re-pins its flows, so `deploy` would\n // reject one it cannot check either way. Before the last-method guard,\n // because these refusals have no override, and nobody should be asked\n // to confirm a change that fails anyway.\n refuseBrokenFlows(\n schema,\n change.document,\n flows.map((file) => ({ file, after: file.body })),\n enabled\n ? undefined\n : {\n heading: `A login flow still uses what ${schema.path} would disable:`,\n hint:\n \"Remove the method from those steps first, then run the command again. \" +\n \"Login flows are not edited for you.\",\n },\n );\n const proceed = await this.confirmLastMethod({\n schema,\n after: change.document,\n disabling: method,\n retryArgs: [\"auth-method\", method, \"disable\", ...optionArgs(\"--schema\", schema.name)],\n cwdArgs,\n });\n if (!proceed) {\n return this.emit({ status: \"skipped\", reason: \"disable-cancelled\" });\n }\n }\n\n const flowsAfter = flows.map((file) => file.body);\n // Judged on the login journey, as the reachability warning is: a passkey\n // that a register step only enrols is not offered to anyone signing in.\n const notOffered =\n enabled && !reachableSignInMethods(change.document, flowsAfter).includes(method)\n ? [method]\n : [];\n const data = {\n schema: schema.name,\n file: schema.path,\n method,\n changed: change.changed ? [schema.path] : [],\n usable: usableSignInMethods(change.document),\n not_offered: notOffered,\n };\n const outcome = {\n schema,\n before: schema.body,\n after: change.document,\n flowsAfter,\n notOffered,\n };\n\n if (dryRun) {\n this.reportOutcome(outcome);\n return this.emit({\n status: \"skipped\",\n reason: \"dry-run\",\n data,\n pretty: change.changed\n ? `Would ${verb} ${method} for ${schema.name}`\n : `Nothing to ${verb} for ${schema.name}`,\n });\n }\n if (change.changed) {\n await writeFile(join(cwd, schema.path), `${stableStringify(change.document)}\\n`);\n consola.success(`Updated ${schema.path}`);\n } else {\n consola.info(`${method} is already ${verb}d for ${schema.name}`);\n }\n this.reportOutcome(outcome);\n return this.emit({\n status: \"ok\",\n data: { ...data, ...this.followUps(change.changed, cwdArgs) },\n pretty: change.changed\n ? `${enabled ? \"Enabled\" : \"Disabled\"} ${method} for ${schema.name}`\n : `Nothing to ${verb} for ${schema.name}`,\n });\n }\n}\n\n/**\n * A schema that points at an external URL holds no sign-in methods of its own:\n * they live in the schema the server fetches, so editing the pointer would\n * change nothing.\n */\nfunction refuseExternalSchema(schema: SchemaFile): void {\n if (schema.body.kind !== \"schema-url\") {\n return;\n }\n throw new ZitadelError(\"E_VALIDATION\", `${schema.path} points at an external schema`, {\n hint:\n \"Its sign-in methods live in the schema at its url, which the server fetches. \" +\n \"Edit x-auth-methods there instead.\",\n details: { file: schema.path, url: schema.body.url },\n });\n}\n\n/** The server refuses password on a schema without an identifier. */\nfunction refuseMissingIdentifier(schema: SchemaFile, method: ToggleableMethod): void {\n if (method !== \"password\" || hasIdentifier(schema.body)) {\n return;\n }\n throw new ZitadelError(\"E_VALIDATION\", `${schema.path} has no x-identifier for password`, {\n hint:\n \"A password is checked against the user found by the schema's identifier. \" +\n 'Set \"x-identifier\" to the property users sign in with, e.g. \"email\", then run the command again.',\n details: { file: schema.path, method: \"password\" },\n });\n}\n\n/** Whether a change takes the schema from some way to sign in to none. */\nfunction removesLastMethod(before: Record<string, unknown>, after: Record<string, unknown>) {\n return usableSignInMethods(before).length > 0 && usableSignInMethods(after).length === 0;\n}\n\n/**\n * Refuse removing the last way in without --force. The exact re-run comes\n * first. The alternatives are the methods the schema does not enable, which\n * leaves out the one being turned off, and password only where the schema can\n * take it (it needs an identifier).\n */\nfunction refuseLastMethod(input: {\n schema: SchemaFile;\n retryArgs: string[];\n cwdArgs: string[];\n cliVersion: string;\n}): never {\n const { schema } = input;\n const enabled = usableSignInMethods(schema.body);\n const alternatives = TOGGLEABLE_METHODS.filter(\n (method) => !enabled.includes(method) && (method !== \"password\" || hasIdentifier(schema.body)),\n );\n // Every suggestion as an argument list, the re-run first. The schema name\n // comes from a file name and the --cwd path from the user; one that would\n // need quoting leaves the strings out, because quoting differs between POSIX\n // shells, PowerShell and cmd.exe and none is safe on all of them.\n const suggestedArgs = [\n input.retryArgs,\n ...alternatives.map((method) => [\n \"auth-method\",\n method,\n \"enable\",\n ...optionArgs(\"--schema\", schema.name),\n ...input.cwdArgs,\n ]),\n ];\n throw new ZitadelError(\"E_VALIDATION\", `${schema.path} would have no way to sign in left`, {\n hint:\n \"Enable another method first, such as `zitadel auth-method sso enable --provider <name>`. \" +\n \"If the schema's users are only managed through the API, re-run with --force \" +\n \"(the first of details.suggested_args holds the exact arguments).\",\n details: {\n file: schema.path,\n usable: enabled,\n suggested_args: suggestedArgs,\n },\n nextCommands: portableSuggestions(suggestedArgs, input.cliVersion),\n });\n}\n","import { Args, Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { sendAll, send } from \"../../lib/api/call\";\nimport { curlOf } from \"../../lib/api/curl\";\nimport {\n type ApiOperation,\n OPERATIONS,\n resolveTarget,\n type Target,\n uncallable,\n} from \"../../lib/api/operations\";\nimport { buildRequest, pathValuesOf, readInput, urlOf } from \"../../lib/api/request\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope, nonBlankString } from \"../../lib/oclif\";\nimport { readZitadelSecret } from \"../../lib/project\";\nimport { Promptable } from \"../../lib/oclif/promptable\";\n\nconst METHODS = [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\"] as const;\n\n/**\n * `zitadel api` — call any operation of the Zitadel API with the server and\n * project secret every other command uses: the escape hatch for what no\n * resource command covers yet, as `gh api` and `vercel api` are for theirs.\n *\n * The operations are the spec's (`@zitadel/api/generated/operations`), so an\n * operation is named by its `operationId` or found by its path, a field is\n * typed by the operation's schema, and `--paginate` knows where the cursor\n * goes. `--json`'s `data` is the response body as the API reference documents\n * it.\n */\nexport default class Api extends Promptable(BaseCommand) {\n static override group = CommandGroups.diagnostics;\n static override description =\n \"Call any operation of the Zitadel API, with this project's server and project secret.\";\n static override examples = [\n \"<%= config.bin %> api queryUsers -F limit=5\",\n \"<%= config.bin %> api GetUserByID user_01JZ8Y3V4Q0K7N2M5P6R8S9T0W\",\n \"<%= config.bin %> api /users/user_01JZ8Y3V4Q0K7N2M5P6R8S9T0W/passkeys --json\",\n \"<%= config.bin %> api listEvents -F category=auth --paginate --json\",\n \"<%= config.bin %> api createTeam -F name=Support --dry-run\",\n \"<%= config.bin %> api createTeam --input - < team.json\",\n ];\n // The path parameters follow the operation as further arguments.\n static override strict = false;\n static override args = {\n operation: Args.string({\n description:\n \"An operationId (queryUsers) or a path (/users/query), then the path parameters. Omit it to choose one.\",\n }),\n };\n static override flags = {\n method: Flags.string({\n char: \"X\",\n description: \"The HTTP method, to choose among a path's operations.\",\n helpValue: METHODS.join(\"|\"),\n // In any case, as curl takes it: oclif's `options` would refuse `-X delete`.\n parse: async (input) => {\n const method = input.toUpperCase();\n if (!(METHODS as readonly string[]).includes(method)) {\n throw new ZitadelError(\"E_VALIDATION\", `-X ${input} is not one of ${METHODS.join(\", \")}`);\n }\n return method;\n },\n }),\n field: Flags.string({\n char: \"F\",\n description:\n \"A field: name=value, or name:=json for JSON, typed by the operation's schema. A query parameter's name sets it; any other name is a dot path into the body. Repeatable.\",\n multiple: true,\n multipleNonGreedy: true,\n }),\n input: nonBlankString({\n description: \"Read the JSON body from a file, or from stdin with -. --field lays over it.\",\n }),\n paginate: Flags.boolean({\n description:\n \"Follow next_page_token to the last page, and answer with every page's items in one list.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, argv, flags } = await this.parse(Api);\n const meta = await this.toMeta(flags);\n\n const ref = args.operation ?? (await this.chooseOperation());\n const target = resolveTarget(ref, flags.method);\n const { operation } = target;\n const refusal = uncallable(operation);\n if (refusal) {\n throw new ZitadelError(\"E_VALIDATION\", refusal, {\n hint: \"Call it from the app it belongs to, through the SDK; `zitadel api ls` marks what the CLI can call.\",\n });\n }\n if (flags.paginate && operation.paging === null) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${operation.id} does not page, so --paginate has nothing to follow`,\n {\n hint: \"Leave out --paginate.\",\n },\n );\n }\n this.recordTelemetry({ operation: operation.id, is_paginated: flags.paginate });\n\n // An operation that needs no credential runs anywhere; one that does\n // needs the project `zitadel setup` wrote. Either way a project at hand\n // fills a `project_id` left out.\n const secret =\n operation.auth === \"secret\"\n ? await readZitadelSecret(meta.cwd)\n : await readZitadelSecret(meta.cwd).catch(() => undefined);\n const positionals = (argv as string[]).slice(args.operation === undefined ? 0 : 1);\n const pathValues = await this.pathValues(target, positionals, secret?.project_id);\n const request = buildRequest({\n target,\n pathValues,\n fields: flags.field ?? [],\n input: await readInput(flags.input),\n projectId: secret?.project_id,\n });\n\n if (meta.dryRun) {\n return this.emit({\n status: \"ok\",\n data: {\n operation: operation.id,\n method: operation.method,\n url: urlOf(meta.source, request),\n ...(request.body === undefined ? {} : { body: request.body }),\n },\n pretty: curlOf(meta.source, request),\n });\n }\n\n // As the resource commands do: say which server is called, on a terminal\n // only, so a pipe receives the response alone.\n if (process.stdout.isTTY) {\n consola.info(`${operation.method} ${urlOf(meta.source, request)}`);\n }\n const token = operation.auth === \"secret\" ? secret?.project_secret : undefined;\n const response = flags.paginate\n ? await sendAll(meta.source, token, request)\n : await send(meta.source, token, request);\n return this.emit({\n status: \"ok\",\n data: response.body ?? null,\n pretty:\n response.body === undefined\n ? process.stdout.isTTY\n ? `No content (${response.status}).`\n : \"\"\n : typeof response.body === \"string\"\n ? response.body\n : JSON.stringify(response.body, null, 2),\n });\n }\n\n /** Choose an operation the CLI can call: its part of the API, then the operation. */\n private async chooseOperation(): Promise<string> {\n const callable = OPERATIONS.filter((operation) => uncallable(operation) === undefined);\n const retry = this.suggestUnscoped(\"api ls --json\");\n const tag = await this.input({\n kind: \"select\",\n name: \"operation\",\n message: \"Which part of the API would you like to use?\",\n retry,\n options: [...new Set(callable.map((operation) => operation.tag))].map((value) => ({\n value,\n label: value,\n })),\n });\n return this.input({\n kind: \"select\",\n name: \"operation\",\n message: \"Which operation would you like to run?\",\n retry,\n options: callable\n .filter((operation) => operation.tag === tag)\n .map((operation: ApiOperation) => ({\n value: operation.id,\n label: `${operation.method} ${operation.path}`,\n hint: operation.summary,\n })),\n });\n }\n\n /** Every path parameter's value, asking for the ones the command line left out. */\n private async pathValues(\n target: Target,\n positionals: readonly string[],\n projectId: string | undefined,\n ): Promise<Readonly<Record<string, string>>> {\n const { values, missing } = pathValuesOf(target, positionals, projectId);\n const filled: Record<string, string> = { ...values };\n for (const name of missing) {\n filled[name] = await this.input({\n kind: \"text\",\n name,\n message: `What is the value of ${name}?`,\n retry: this.suggestUnscoped(\n `api ${target.operation.id} ${missing.map((each) => `<${each}>`).join(\" \")}`,\n ),\n parse: (value: string) =>\n value.trim() === \"\"\n ? { ok: false as const, problem: `${name} cannot be empty` }\n : { ok: true as const, value: value.trim() },\n });\n }\n return filled;\n }\n}\n","import { isObject } from \"../../json\";\n\n/**\n * The machine form of a list: one record per line, fields separated by tabs,\n * no header and no padding, so `cut -f2` and `awk -F'\\t'` work. This is what a\n * piped run emits — the aligned table is for a terminal, where nothing is\n * parsing it. Tabs and newlines inside a value would break the record, so they\n * are escaped rather than passed through.\n */\nexport const renderRows = (columns: readonly string[], items: readonly unknown[]): string =>\n items\n .map((item) =>\n columns\n .map((column) => readCell(column, item).replaceAll(\"\\t\", \"\\\\t\").replaceAll(\"\\n\", \"\\\\n\"))\n .join(\"\\t\"),\n )\n .join(\"\\n\");\n\n/**\n * Render `items` as an aligned text table, one column per dot-path in\n * `columns`, headed by each path's last segment. Nested paths resolve\n * through objects; missing values render empty; non-strings render as JSON.\n */\nexport const renderTable = (columns: readonly string[], items: readonly unknown[]): string => {\n const headers = columns.map((column) => column.split(\".\").at(-1) ?? column);\n const rows = items.map((item) => columns.map((column) => readCell(column, item)));\n // Folded rather than spread into `Math.max`: a wide `--all` can return more\n // rows than the engine accepts as arguments in one call.\n const widths = rows.reduce<number[]>(\n (current, row) => current.map((width, i) => Math.max(width, row[i]?.length ?? 0)),\n headers.map((header) => header.length),\n );\n const line = (cells: readonly string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i] ?? 0))\n .join(\" \")\n .trimEnd();\n return [line(headers), line(widths.map((width) => \"-\".repeat(width))), ...rows.map(line)].join(\n \"\\n\",\n );\n};\n\n/**\n * The whole terminal rendering of a list, so no command re-derives the\n * plain/TTY/empty/footer logic (and so none forgets `--plain`): a pipe (or\n * `--plain`) gets tab-separated rows with no header and nothing when empty, so\n * `cut`/`awk`/`wc -l` work; a terminal gets the aligned table, a blank line, a\n * `${n} ${singular|plural}` count, and any `footer` lines. Pair it with\n * `listData()` for the JSON envelope.\n */\nexport const renderList = (\n columns: readonly string[],\n rows: readonly unknown[],\n opts: {\n plain: boolean;\n singular: string;\n plural?: string;\n empty: string;\n footer?: readonly string[];\n },\n): string => {\n if (opts.plain) {\n return renderRows(columns, rows);\n }\n if (rows.length === 0) {\n return opts.empty;\n }\n const count = `${rows.length} ${rows.length === 1 ? opts.singular : (opts.plural ?? `${opts.singular}s`)}`;\n return [renderTable(columns, rows), \"\", count, ...(opts.footer ?? [])].join(\"\\n\");\n};\n\n/** One cell: a dot-path resolved through objects, rendered as text. */\nconst readCell = (column: string, item: unknown): string => {\n const value = column\n .split(\".\")\n .reduce<unknown>((current, key) => (isObject(current) ? current[key] : undefined), item);\n return value == null ? \"\" : typeof value === \"string\" ? value : JSON.stringify(value);\n};\n\n/**\n * One record for a person: the heading first, then a labelled field per line.\n * Nested paths are labelled by their last segment, so `metadata.status` reads\n * as `status`. It is the terminal rendering of `get`; a pipe (and `--json`)\n * still receives the whole object, since a script wants the record, not a view\n * of it.\n */\nexport const renderDetail = (\n heading: string | undefined,\n fields: readonly string[],\n item: unknown,\n): string => {\n // Width is measured over the fields that survive, so an omitted one cannot\n // pad every other label out of alignment.\n const rows = fields\n .map((field) => [field.split(\".\").at(-1) ?? field, readCell(field, item)] as const)\n .filter(([, value]) => value !== \"\");\n const width = Math.max(0, ...rows.map(([label]) => label.length));\n const body = rows.map(([label, value]) => `${label.padEnd(width)} ${value}`);\n return [...(heading ? [heading, \"\"] : []), ...body].join(\"\\n\");\n};\n","import { Args, Flags } from \"@oclif/core\";\n\nimport { type ApiOperation, findOperations, uncallable } from \"../../lib/api/operations\";\nimport { renderRows, renderTable } from \"../../lib/oclif/crud/table\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../../lib/oclif\";\n\n/** One operation as `api ls` lists it. */\nconst entryOf = (operation: ApiOperation) => ({\n id: operation.id,\n method: operation.method,\n path: operation.path,\n summary: operation.summary,\n tag: operation.tag,\n auth: operation.auth,\n callable: uncallable(operation) === undefined,\n parameters: operation.parameters,\n body: operation.body,\n paging: operation.paging,\n command: operation.cli,\n});\n\n/**\n * `zitadel api ls` — the operations `zitadel api` can call, from the spec the\n * CLI was built with. It talks to no server, so the answer is the same\n * offline. `--json` carries each one's parameters, body and paging, which is\n * what an agent needs to build the call.\n */\nexport default class ApiLs extends BaseCommand {\n static override group = CommandGroups.diagnostics;\n static override description = \"List the operations of the Zitadel API that `zitadel api` calls.\";\n static override examples = [\n \"<%= config.bin %> api ls\",\n \"<%= config.bin %> api ls passkey\",\n \"<%= config.bin %> api ls --tag Users --json\",\n \"<%= config.bin %> api ls --json | jq -r '.data.operations[] | select(.command == null) | .id'\",\n ];\n static override args = {\n filter: Args.string({\n description: \"Only operations whose id, path, summary or tag contains this text.\",\n }),\n };\n static override flags = {\n tag: Flags.string({\n description: \"Only the operations of this part of the API (Users, Teams, …).\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(ApiLs);\n await this.toMeta(flags, { resolveServer: false });\n const operations = findOperations({ filter: args.filter, tag: flags.tag }).map(entryOf);\n\n const columns = [\"id\", \"method\", \"path\", \"summary\"];\n return this.emit({\n status: \"ok\",\n data: { operations, count: operations.length },\n pretty: process.stdout.isTTY\n ? [\n renderTable(columns, operations),\n \"\",\n `${operations.length} operations. Call one with \\`${this.config.bin} api <id>\\`; --json has each one's parameters.`,\n ].join(\"\\n\")\n : renderRows(columns, operations),\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { AuthMethodCommand, CommandGroups, type JsonEnvelope } from \"../../../lib/oclif\";\n\n/** `auth-method passkey disable` (ADR 070). */\nexport default class AuthMethodPasskeyDisable extends AuthMethodCommand {\n static override description = \"Disable passkey sign-in for a user schema.\";\n static override group = CommandGroups.authentication;\n static override examples = [\n \"<%= config.bin %> auth-method passkey disable\",\n \"<%= config.bin %> auth-method passkey disable --schema customers\",\n ];\n static override flags = {\n // `--force` is per command, not global (ADR 064 §10): here it permits\n // removing the last way to sign in, which the server allows for a schema\n // whose users are only managed through the API.\n force: Flags.boolean({\n char: \"f\",\n description:\n \"Disable the schema's last way to sign in. Its users can then only be managed through the API.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(AuthMethodPasskeyDisable);\n return this.toggle(flags, \"passkey\", false);\n }\n}\n","import { AuthMethodCommand, CommandGroups, type JsonEnvelope } from \"../../../lib/oclif\";\n\n/** `auth-method passkey enable` (ADR 070). */\nexport default class AuthMethodPasskeyEnable extends AuthMethodCommand {\n static override description = \"Enable passkey sign-in for a user schema.\";\n static override group = CommandGroups.authentication;\n static override examples = [\n \"<%= config.bin %> auth-method passkey enable\",\n \"<%= config.bin %> auth-method passkey enable --schema customers\",\n ];\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(AuthMethodPasskeyEnable);\n return this.toggle(flags, \"passkey\", true);\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { AuthMethodCommand, CommandGroups, type JsonEnvelope } from \"../../../lib/oclif\";\n\n/** `auth-method password disable` (ADR 070). */\nexport default class AuthMethodPasswordDisable extends AuthMethodCommand {\n static override description = \"Disable password sign-in for a user schema.\";\n static override group = CommandGroups.authentication;\n static override examples = [\n \"<%= config.bin %> auth-method password disable\",\n \"<%= config.bin %> auth-method password disable --schema customers\",\n ];\n static override flags = {\n // `--force` is per command, not global (ADR 064 §10): here it permits\n // removing the last way to sign in, which the server allows for a schema\n // whose users are only managed through the API.\n force: Flags.boolean({\n char: \"f\",\n description:\n \"Disable the schema's last way to sign in. Its users can then only be managed through the API.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(AuthMethodPasswordDisable);\n return this.toggle(flags, \"password\", false);\n }\n}\n","import { AuthMethodCommand, CommandGroups, type JsonEnvelope } from \"../../../lib/oclif\";\n\n/** `auth-method password enable` (ADR 070). */\nexport default class AuthMethodPasswordEnable extends AuthMethodCommand {\n static override description = \"Enable password sign-in for a user schema.\";\n static override group = CommandGroups.authentication;\n static override examples = [\n \"<%= config.bin %> auth-method password enable\",\n \"<%= config.bin %> auth-method password enable --schema customers\",\n ];\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(AuthMethodPasswordEnable);\n return this.toggle(flags, \"password\", true);\n }\n}\n","import { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { Flags } from \"@oclif/core\";\nimport { IDP_PROVIDERS } from \"@zitadel/config/idp\";\nimport { consola } from \"consola\";\n\nimport {\n listedProviders,\n refuseBrokenFlows,\n refuseUneditable,\n usableSignInMethods,\n} from \"../../../lib/auth-methods\";\nimport { ZitadelError } from \"../../../lib/errors\";\nimport {\n removeSsoFromFlow,\n removeSsoFromSchema,\n ssoEditRefusal,\n ssoProvidersRefusal,\n} from \"../../../lib/idp\";\nimport { stableStringify } from \"../../../lib/json\";\nimport {\n AuthMethodCommand,\n CommandGroups,\n type JsonEnvelope,\n nonBlankString,\n} from \"../../../lib/oclif\";\nimport { optionArgs } from \"../../../lib/public-cli\";\n\n/**\n * `auth-method sso disable` (ADR 070 §2): remove one provider from a schema\n * and from the login flows that run against it.\n *\n * The connection file and its published credentials are kept, so enabling the\n * provider again does not ask for them. The routes and steps\n * `auth-method sso enable` added stay in the flows; without a provider they\n * are never reached.\n */\nexport default class AuthMethodSsoDisable extends AuthMethodCommand {\n static override description = \"Remove an identity provider from a user schema.\";\n static override group = CommandGroups.authentication;\n static override examples = [\n \"<%= config.bin %> auth-method sso disable --provider google\",\n \"<%= config.bin %> auth-method sso disable --provider google --schema customers\",\n ];\n static override flags = {\n // Not `required`, as on `auth-method sso enable`: the refusal below names\n // the next move, and oclif's own would not. A provider is always named,\n // because removing every provider at once would be a different, larger\n // change.\n provider: nonBlankString({ description: \"Identity provider to remove.\" }),\n // `--force` is per command, not global (ADR 064 §10): here it permits\n // removing the last way to sign in, which the server allows for a schema\n // whose users are only managed through the API.\n force: Flags.boolean({\n char: \"f\",\n description:\n \"Disable the schema's last way to sign in. Its users can then only be managed through the API.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(AuthMethodSsoDisable);\n const { cwd, cwdArgs, schema, flows } = await this.target(flags);\n const { dryRun } = this.meta;\n\n const provider = flags.provider;\n if (provider === undefined) {\n // Every provider the schema lists, well-formed or not: any of them is\n // one the developer may want to remove.\n throw new ZitadelError(\"E_VALIDATION\", \"Name the provider to remove\", {\n hint: `Pass --provider, e.g. --provider ${IDP_PROVIDERS[0]}. ${schema.name} offers: ${listedProviders(schema.body).join(\", \") || \"none\"}.`,\n });\n }\n // The same shapes `auth-method sso enable` refuses: a region that is not\n // what these editors write is someone's, and is not overwritten.\n refuseUneditable(schema.path, ssoEditRefusal(schema.body, \"schema\"));\n for (const file of flows) {\n refuseUneditable(file.path, ssoProvidersRefusal(file.body));\n }\n\n const schemaChange = removeSsoFromSchema(schema.body, provider);\n const after = schemaChange.document as Record<string, unknown>;\n const flowChanges = flows.map((file) => {\n const change = removeSsoFromFlow(file.body, provider);\n return {\n file,\n after: change.document as Record<string, unknown>,\n changed: change.changed,\n };\n });\n const changedFlows = flowChanges.filter((change) => change.changed);\n const changed = [\n ...(schemaChange.changed ? [schema.path] : []),\n ...changedFlows.map(({ file }) => file.path),\n ];\n\n if (changed.length > 0) {\n // Before the last-method guard: these refusals have no override, so\n // nobody should be asked to confirm a change that fails anyway.\n refuseBrokenFlows(schema, after, flowChanges);\n const proceed = await this.confirmLastMethod({\n schema,\n after,\n disabling: provider,\n retryArgs: [\n \"auth-method\",\n \"sso\",\n \"disable\",\n ...optionArgs(\"--provider\", provider),\n ...optionArgs(\"--schema\", schema.name),\n ],\n cwdArgs,\n });\n if (!proceed) {\n return this.emit({ status: \"skipped\", reason: \"disable-cancelled\" });\n }\n }\n\n // When only a flow still offered the provider, say so: the schema itself\n // did not change.\n const where = schemaChange.changed ? schema.name : `the login flows of ${schema.name}`;\n const data = {\n schema: schema.name,\n file: schema.path,\n method: \"sso\",\n provider,\n changed,\n usable: usableSignInMethods(after),\n };\n const outcome = {\n schema,\n before: schema.body,\n after,\n flowsAfter: flowChanges.map(({ after: body }) => body),\n };\n\n if (dryRun) {\n this.reportOutcome(outcome);\n return this.emit({\n status: \"skipped\",\n reason: \"dry-run\",\n data,\n pretty:\n changed.length > 0\n ? `Would remove ${provider} from ${where}`\n : `${schema.name} does not offer ${provider}`,\n });\n }\n if (schemaChange.changed) {\n await writeFile(join(cwd, schema.path), `${stableStringify(after)}\\n`);\n }\n for (const { file, after: body } of changedFlows) {\n await writeFile(join(cwd, file.path), `${stableStringify(body)}\\n`);\n }\n for (const path of changed) {\n consola.success(`Updated ${path}`);\n }\n if (changed.length === 0) {\n consola.info(`${schema.name} does not offer ${provider}`);\n }\n this.reportOutcome(outcome);\n return this.emit({\n status: \"ok\",\n data: { ...data, ...this.followUps(changed.length > 0, cwdArgs) },\n pretty:\n changed.length > 0\n ? `Removed ${provider} from ${where}`\n : `${schema.name} does not offer ${provider}`,\n });\n }\n}\n","/**\n * Whether this is a contributor's development run.\n *\n * The CLI ships as a single generic build — nothing is stamped into the bundle\n * — so development mode is an explicit runtime opt-in via `ZITADEL_CLI_DEV`. A\n * published CLI never has it set, so developer-only affordances (such as the\n * local-IdP issuer prompt in `setup`/`auth-method sso enable`) can never appear\n * for someone who installed the CLI. Contributors set `ZITADEL_CLI_DEV=1` when\n * they want them; everything else — real installs, scripted runs, CI — is a\n * normal run.\n */\nexport function isDevelopmentBuild(): boolean {\n const flag = process.env.ZITADEL_CLI_DEV?.trim().toLowerCase();\n return flag !== undefined && flag !== \"\" && flag !== \"0\" && flag !== \"false\";\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport {\n type ClientIdVariable,\n type ConnectionSlug,\n credentialVariables,\n CUSTOM_PROVIDER,\n DEFAULT_SCOPES,\n IDP_PROVIDERS,\n parseClientId,\n parseClientSecret,\n parseConnectionSlug,\n parseDisplayName,\n parseIssuer,\n type Parsed,\n parseScopes,\n type ProviderName,\n type ProviderSelection,\n providerOf,\n RESERVED_SLUGS,\n selectionName,\n validated,\n} from \"@zitadel/config/idp\";\n\nimport type { ZitadelClient } from \"../../../lib/api-client\";\nimport { loopbackReach } from \"../../../lib/local-server/runtime\";\nimport { refuseBrokenFlows, refuseUneditable } from \"../../../lib/auth-methods\";\nimport { isDevelopmentBuild } from \"../../../lib/build-channel\";\nimport { ZitadelError } from \"../../../lib/errors\";\nimport { stableStringify } from \"../../../lib/json\";\nimport {\n applySsoToFlow,\n applySsoToSchema,\n askConnectionEndpoints,\n callbackUriFor,\n checkCustomSlug,\n checkGivenCustomFlags,\n CONNECTION_SCHEMA_REF,\n enabledMethods,\n type ConnectionFile,\n type ConnectionPlan,\n type FlowFile,\n credentialVariablesOf,\n type CustomFlagValues,\n customExample,\n customFlagValues,\n ENABLE_FLAG_KEYS,\n ENABLE_FLAG_NAMES,\n loopbackIssuerWarning,\n planConnection,\n publishClientId,\n type PublishState,\n readConnectionFiles,\n refuseChangedIssuer,\n reportClientIdOutcome,\n republishArgs,\n selectionFromFlags,\n type StoredVariables,\n ssoEditRefusal,\n type SsoResult,\n type SsoSkipped,\n reportSecretOutcome,\n storeClientSecret,\n storedCustomSettings,\n type SchemaFile,\n type SecretOutcome,\n type SecretPublisher,\n} from \"../../../lib/idp\";\nimport {\n AuthMethodCommand,\n CommandGroups,\n type JsonEnvelope,\n nonBlankString,\n} from \"../../../lib/oclif\";\nimport { environmentFlags } from \"../../../lib/oclif/environment-flags\";\nimport { inShell, type SuggestedCommand } from \"../../../lib/suggestion\";\nimport { reportWarning } from \"../../../lib/warnings\";\n\n/**\n * The `auth-method sso enable` command (ADR 070) — add a provider to a\n * Project's sign-in methods. It replaces the former `sso enable`.\n *\n * One direct journey: the developer is told what to register with the\n * provider, gives back the credentials, and the Project's configuration is\n * written. It works on the local Project `zitadel setup` created and does not\n * require claiming, because this is the local development path.\n *\n * The client secret never comes from a flag, following `variable set`: it is\n * prompted for, or read from stdin when scripting, so it cannot land in shell\n * history, a process listing, or CI logs.\n */\nexport default class AuthMethodSsoEnable extends AuthMethodCommand {\n static override description = \"Add an identity provider to a user schema.\";\n static override group = CommandGroups.authentication;\n static override examples = [\n \"<%= config.bin %> auth-method sso enable --provider google\",\n \"<%= config.bin %> auth-method sso enable --provider google --schema customers\",\n \"<%= config.bin %> auth-method sso enable --provider google --client-id 1234-abc.apps.googleusercontent.com --non-interactive < secret.txt\",\n `<%= config.bin %> auth-method sso enable ${customExample(ENABLE_FLAG_NAMES)}`,\n `<%= config.bin %> auth-method sso enable ${customExample(ENABLE_FLAG_NAMES, true)} --client-id abc123 --non-interactive < secret.txt`,\n ];\n // The one `auth-method` command that resolves an environment, so the one that\n // lists `--env` and `--env-file`; the others hide them.\n static override baseFlags = { ...AuthMethodCommand.baseFlags, ...environmentFlags };\n static override flags = {\n // Not `required`: oclif's own \"Missing required flag provider\" is the one\n // refusal in this command that would carry no hint, and every other error\n // here names the next move. The check below does that instead.\n [ENABLE_FLAG_KEYS.provider]: Flags.string({\n options: [...IDP_PROVIDERS, CUSTOM_PROVIDER],\n description: `Identity provider to enable, or \"${CUSTOM_PROVIDER}\" for a custom OpenID Connect (OIDC) provider.`,\n }),\n [ENABLE_FLAG_KEYS.slug]: nonBlankString({\n description: \"Name of the custom connection. Schemas and flows refer to it by this.\",\n }),\n [ENABLE_FLAG_KEYS.displayName]: nonBlankString({\n description: \"Name shown on the custom connection's sign-in button.\",\n }),\n [ENABLE_FLAG_KEYS.issuer]: nonBlankString({\n description: \"Issuer URL of the custom provider. Its endpoints are found by OIDC discovery.\",\n }),\n [ENABLE_FLAG_KEYS.scopes]: nonBlankString({\n description:\n \"Scopes the custom connection requests, separated by spaces or commas. Must include openid. Default: openid profile email.\",\n }),\n \"client-id\": nonBlankString({\n description: \"Client id of the application registered with the provider.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(AuthMethodSsoEnable);\n const {\n cwd,\n schema,\n flows: candidates,\n preflight: project,\n } = await this.target(flags, {\n // The credentials are published to the project, so the environment is\n // resolved, unlike for the other auth-method commands.\n resolveServer: true,\n preflight: () =>\n readProject(\n flags,\n this.environment.values.ZITADEL_ISSUER?.value,\n !this.meta.nonInteractive && !this.meta.dryRun,\n ),\n });\n const { issuer } = project;\n const connections = await readConnectionFiles(cwd);\n // Before dry-run and before the first question, including the ones\n // `connect()` asks: a Project whose flows all name another schema, or whose\n // schema or flow was edited by hand where the editors write, must fail\n // identically whether or not anything was asked.\n const flows = targetFlows(schema, candidates);\n // Resolved before anything else is asked for: being turned away after\n // typing a secret would mean typing it again.\n const { client, projectId, server } = await this.connect({ quiet: true });\n // The schema and flow edits for a slug, with the refusals they bring (an\n // edit the editors cannot make, or a flow `deploy` would then reject), so\n // the run stops with nothing changed (ADR 070 §3).\n const editsFor = (slug: ConnectionSlug): PlannedEdits => {\n const edits = planEdits(schema, slug, flows);\n refuseBrokenFlows(\n schema,\n edits.schema.document as Record<string, unknown>,\n edits.flows.map(({ flow, result }) => ({\n file: flow,\n after: result.document as Record<string, unknown>,\n })),\n );\n return edits;\n };\n // A custom provider's settings are asked here, after the checks on the\n // Project; the ones that need an answer run the moment the answer that\n // decides them is given (see `askCustomSettings`).\n const selection =\n project.selection ??\n selectionFromFlags(\n CUSTOM_PROVIDER,\n await this.askCustomSettings(project.values, connections, (slug) => {\n editsFor(slug);\n }),\n ENABLE_FLAG_NAMES,\n customExample(ENABLE_FLAG_NAMES),\n );\n const entry = providerOf(selection);\n const { nonInteractive, dryRun } = this.meta;\n // A loopback issuer works only on a server that may fetch from this machine.\n const loopback = loopbackIssuerWarning(selection, await loopbackReach(cwd, server));\n if (loopback !== undefined) {\n reportWarning(loopback);\n }\n const provider = selectionName(selection);\n // `--cwd` and the run's `--env`/`--env-file`/`--server`, so every follow-up\n // reaches the project this run published to.\n const scopeArgs = this.environmentSelectorArgs();\n // What an agent can run once the missing credential is to hand. Only for a\n // catalog provider: a custom connection needs its settings repeated too.\n const retryFor = (clientId: string, pipe = \"\"): SuggestedCommand | undefined =>\n selection.kind === \"catalog\"\n ? inShell(\n this.suggest(`auth-method sso enable --provider ${provider} --client-id ${clientId}`),\n { before: pipe },\n )\n : undefined;\n\n // `nonBlankString` has already refused a blank one.\n const clientIdFlag =\n flags[\"client-id\"] === undefined ? undefined : validated(parseClientId(flags[\"client-id\"]));\n const plan = planConnection({\n selection,\n files: connections,\n clientId: clientIdFlag,\n scopesGiven: flags[ENABLE_FLAG_KEYS.scopes] !== undefined,\n slugFlag: ENABLE_FLAG_NAMES.slug,\n });\n // The connection's own route, so the slug decides it: a reused connection\n // keeps the slug it was created with.\n const callbackUri = callbackUriFor(issuer, plan.slug);\n\n const reusing = plan.action === \"reuse\";\n if (plan.action === \"create\" && plan.alsoUsesIssuer !== undefined) {\n reportWarning(\n `${plan.alsoUsesIssuer.join(\", \")} already connects to ${provider}'s issuer under another slug, so this adds a second ${provider} connection and button.`,\n );\n }\n if (plan.action === \"reuse\" && plan.notApplied !== undefined) {\n reportWarning(\n `${plan.file.path} already exists, so the ${plan.notApplied.join(\" and \")} you gave ${plan.notApplied.length === 1 ? \"was\" : \"were\"} not applied. Edit the file to change ${plan.notApplied.length === 1 ? \"it\" : \"them\"}.`,\n );\n }\n // What a newly written connection will reference: this command writes both\n // as `${{ NAME }}`, so on the create path the names are certain.\n const scaffolded = credentialVariables(plan.slug);\n // A reused connection may name its own variables — it is an editable file\n // — so the credentials go where it actually looks rather than where this\n // command would have put them. A name is `undefined` when the file holds\n // that credential as a literal: there is no variable to publish to, and\n // publishing to a derived name would report success for a value the\n // connection never reads.\n const names: StoredVariables = reusing\n ? credentialVariablesOf(plan.file, plan.slug)\n : scaffolded;\n const variable = names.clientSecret;\n const idVariable = names.clientId;\n\n // Worked out before the dry-run return and before the connection is\n // written or a credential published.\n const edits = editsFor(plan.slug);\n const outcome = {\n schema,\n before: schema.body,\n after: edits.schema.document as Record<string, unknown>,\n flowsAfter: edits.flows.map(({ result }) => result.document as Record<string, unknown>),\n };\n\n consola.info(`Project ${projectId}`);\n consola.info(\n `Schema ${schema.path}${schema.methods.length > 0 ? ` (${schema.methods.join(\", \")})` : \"\"}`,\n );\n\n if (dryRun) {\n this.reportOutcome(outcome);\n return this.emit({\n status: \"skipped\",\n reason: \"dry-run\",\n data: this.payload({\n projectId,\n provider,\n schema: schema.name,\n plan,\n callbackUri,\n secret: undefined,\n clientId: undefined,\n idVariable,\n changed: editedFiles(schema, edits),\n }),\n pretty: `Would ${plan.action} ${plan.action === \"reuse\" ? plan.file.path : plan.path}`,\n });\n }\n // An existing connection is reused rather than rewritten, but the schema\n // and flow edits still run: those are the point of the command, they are\n // per-schema, and they are idempotent. Enabling the provider for a second\n // user type, and finishing a run interrupted after the connection file was\n // written, both arrive here.\n let secret: SecretOutcome | undefined;\n let clientIdState: PublishState | undefined;\n\n if (reusing) {\n consola.success(`Reusing ${plan.file.path}`);\n // Shown on reuse too: the URI moved to one per connection after the\n // first release, and rerunning this command is how a developer finds\n // the one to register now.\n consola.info(`Callback URI ${callbackUri}`);\n // The connection references its credentials rather than holding them, so\n // reuse is not evidence they were ever published: a run interrupted\n // between writing the file and publishing leaves the document pointing\n // at variables that do not exist. A supplied credential is published\n // again, which costs one call and makes the command idempotent --\n // rerunning with a changed client id now takes effect instead of being\n // silently ignored. Nothing is prompted for: an unattended rerun should\n // not start asking for credentials the project already has.\n const publish = this.publisher(client, projectId);\n if (clientIdFlag !== undefined) {\n if (idVariable === undefined) {\n reportWarning(\n `${plan.file.path} holds its client id directly, so nothing was published. ` +\n \"Edit the file to change it.\",\n );\n } else {\n clientIdState = await publishClientId({\n name: idVariable,\n value: clientIdFlag,\n publish,\n });\n }\n }\n // Reuse never demands a secret: the project may already hold it, and\n // refusing an unattended rerun for a credential that has not changed\n // would be noise. It is only read so that a rerun can replace it.\n const piped = await this.input({\n kind: \"secret\",\n name: \"client secret\",\n message: `What is the client secret of your ${entry.displayName} OAuth app?`,\n parse: parseClientSecret,\n stdin: true,\n optional: true,\n });\n if (piped !== undefined) {\n if (variable === undefined) {\n reportWarning(\n `${plan.file.path} holds its client secret directly, so nothing was published. ` +\n \"Replace it with a ${{ NAME }} reference so the secret is not committed.\",\n );\n } else {\n secret = await storeClientSecret({ name: variable, value: piped, publish });\n }\n }\n } else {\n consola.info(`${entry.displayName} needs an OAuth application.`);\n consola.info(`Callback URI ${callbackUri}`);\n // A custom provider has no console to send the developer to: it is\n // theirs, and the issuer they gave is the only address known.\n consola.info(\n entry.consoleUrl === undefined\n ? `Register it as a client at ${entry.issuer}, with the callback URI above.`\n : `Create it at ${entry.consoleUrl}`,\n );\n\n // Before the credentials: on a development run (ZITADEL_CLI_DEV) the\n // provider may be a local stand-in, and the client is registered with\n // whatever answers. Not asked of a custom connection, whose issuer the\n // developer has already given.\n const endpoints =\n selection.kind === \"catalog\"\n ? await askConnectionEndpoints({\n provider: selection.id,\n developmentBuild: isDevelopmentBuild() && !nonInteractive,\n ask: this.input,\n })\n : undefined;\n const clientId = await this.input({\n kind: \"text\",\n name: `client id for ${entry.displayName}`,\n message: `What is the client ID of your ${entry.displayName} OAuth app?`,\n flag: \"--client-id\",\n parse: parseClientId,\n given: flags[\"client-id\"],\n retry: retryFor(\"<client-id>\"),\n });\n // Required, like the client id. The connection document references the\n // secret as `${{ NAME }}` and the engine resolves that from the project's\n // variables, so enabling a provider without one writes a sign-in button\n // that fails at the token endpoint with `invalid_client` -- a failure\n // that surfaces in a browser, not here. Refusing now is the cheaper answer.\n const secretValue = await this.input({\n kind: \"secret\",\n name: `client secret for ${scaffolded.clientSecret}`,\n message: `What is the client secret of your ${entry.displayName} OAuth app? It will be stored on the project as ${scaffolded.clientSecret}.`,\n parse: parseClientSecret,\n stdin: true,\n retry: retryFor(clientId, `printf '%s' \"$CLIENT_SECRET\" | `),\n });\n\n const publish = this.publisher(client, projectId);\n const connection = entry.connection({\n slug: plan.slug,\n schemaProperties: schema.properties,\n schemaRef: CONNECTION_SCHEMA_REF,\n endpoints,\n });\n // A connection is scaffolded with the properties the provider maps by\n // default, narrowed to what the schema defines. A schema that defines none\n // of them leaves it with no mapping, and `deploy` refuses a connection that\n // fills nothing, so say so now and not on the next command.\n if (!(\"claim_mapping\" in connection)) {\n reportWarning(\n `${schema.path} defines none of the properties ${entry.displayName} maps by default, so ${plan.path} has no claim_mapping ` +\n `and no sign-in can fill a user. Add the properties your provider returns to claim_mapping in ${plan.path}.`,\n );\n }\n if (endpoints?.issuer !== undefined && endpoints.issuer !== entry.issuer) {\n // Said out loud: a connection pointing somewhere other than the\n // vendor is not what the developer will want in the end, and nothing\n // else in the output would show it.\n reportWarning(`${entry.displayName} points at ${endpoints.issuer}, not the provider`);\n }\n const target = join(cwd, plan.path);\n await mkdir(dirname(target), { recursive: true });\n // `wx` rather than a plain write: planConnection decided this file does\n // not exist, and anything that appeared since is not ours to overwrite.\n await writeFile(target, `${stableStringify(connection)}\\n`, { flag: \"wx\" });\n // The id first: it is the half the developer can read back afterwards,\n // and a connection missing either credential fails the same way.\n clientIdState = await publishClientId({\n name: scaffolded.clientId,\n value: clientId,\n publish,\n });\n secret = await storeClientSecret({\n name: scaffolded.clientSecret,\n value: secretValue,\n publish,\n });\n consola.success(`Wrote ${plan.path}`);\n if (selection.kind === \"custom\") {\n for (const note of mappingNotes({\n file: plan.path,\n provider: entry.displayName,\n connection,\n })) {\n consola.info(note);\n }\n }\n }\n\n const written = await this.enableInConfiguration(cwd, schema, edits);\n\n for (const file of written) {\n consola.success(`Updated ${file}`);\n }\n for (const skipped of edits.skipped) {\n const toDo =\n skipped.step === \"password\"\n ? `Add ${plan.slug} to its sso_providers, and route sso_authenticated to the step a sign-in ends on, sso_user_not_found to register-sso and user_already_exists to sso-conflict.`\n : skipped.step === \"sso-conflict\"\n ? `Add ${plan.slug} to its sso_providers.`\n : \"Update it yourself.\";\n reportWarning(`Left ${skipped.region} alone: it has been edited by hand. ${toDo}`);\n }\n if (written.length === 0 && edits.skipped.length === 0) {\n consola.info(`${schema.name} and its login flow already offer ${entry.displayName}`);\n }\n if (clientIdState !== undefined && idVariable !== undefined) {\n reportClientIdOutcome(\n idVariable,\n clientIdState,\n this.meta.cliVersion,\n this.environmentSelector(),\n );\n }\n if (secret) {\n // A reuse that piped nothing in had no value to publish; a create always\n // has one, because the command refuses without it.\n reportSecretOutcome(secret, this.meta.cliVersion, reusing, this.environmentSelector());\n }\n this.reportOutcome(outcome);\n // `variable set` first, for a credential that did not reach the project:\n // the connection references it as `${{ NAME }}` and the engine resolves\n // that from the project's variables, so a button whose credential never\n // arrived fails at token exchange. Then deploy, when a file\n // changed. All carry --cwd when the run did.\n const recovery = republishArgs(\n [\n { name: idVariable, secret: false, published: clientIdState },\n { name: variable, secret: true, published: secret?.published },\n ],\n scopeArgs,\n );\n\n // A file changed or a connection was created, which only a deploy publishes.\n const unpublished = !reusing || written.length > 0;\n const credentialsStored =\n secret?.published === \"stored\" && (clientIdState === undefined || clientIdState === \"stored\");\n const stored = credentialsStored ? [\"Provider credentials are stored on your Project.\"] : [];\n const name = entry.displayName;\n\n return this.emit({\n status: \"ok\",\n data: {\n // Configured is not live, and stored credentials are only claimed once\n // they reached the Project (a failed or deferred publish warns instead).\n title: unpublished\n ? [`${name} sign-in is configured locally.`, ...stored].join(\" \")\n : `${name} sign-in is already configured locally.`,\n ...(unpublished\n ? {\n next_actions: [\n `Deploy the configuration to make ${name} sign-in available in your app, then reload your app and test ${name} sign-in.`,\n ],\n }\n : {}),\n ...this.payload({\n projectId,\n provider,\n schema: schema.name,\n plan,\n callbackUri,\n secret,\n clientId: clientIdState,\n idVariable,\n changed: written,\n skipped: edits.skipped,\n }),\n // An ok result carries its follow-ups in data.next_commands (errors\n // use the top-level nextCommands instead).\n ...this.followUps(unpublished, scopeArgs, recovery),\n },\n });\n }\n\n /**\n * How the connection's credentials reach the project, or `undefined` when\n * there is no project behind this run: `--source mock` answers from fixtures\n * and has no variables to write. It publishes to the project's own variables,\n * which is where the engine resolves a connection's `${{ NAME }}` references\n * from.\n */\n private publisher(client: ZitadelClient, projectId: string): SecretPublisher | undefined {\n if (this.meta.source === \"mock\") {\n return undefined;\n }\n return async (name, value, { secret }) => {\n await client.updateVariables({ [name]: { value, secret } }, { project_id: projectId });\n };\n }\n\n /** Write the edits `planEdits` worked out, and say which files changed. */\n private async enableInConfiguration(\n cwd: string,\n schema: SchemaFile,\n edits: PlannedEdits,\n ): Promise<string[]> {\n if (edits.schema.changed) {\n await writeFile(join(cwd, schema.path), `${stableStringify(edits.schema.document)}\\n`);\n }\n for (const { flow, result } of edits.flows) {\n if (result.changed) {\n await writeFile(join(cwd, flow.path), `${stableStringify(result.document)}\\n`);\n }\n }\n return editedFiles(schema, edits);\n }\n\n /**\n * The settings of a custom connection, asking only for the ones not already\n * given, in the order that lets each answer decide what comes next. The slug\n * comes first because it decides the most: it names the file the connection\n * is kept in, so everything that depends on the slug alone is checked the\n * moment it is typed (`checkCustomSlug`, then `beforeAsking`), and a connection that already exists\n * answers the rest from its file. A given value goes through the same parser\n * as a typed one, and the ones given on the command line were checked under\n * their flag before this ran (`checkGivenCustomFlags`).\n *\n * @param beforeAsking - Raises whatever else is known once the slug is.\n */\n private async askCustomSettings(\n given: CustomFlagValues,\n files: readonly ConnectionFile[],\n beforeAsking: (slug: ConnectionSlug) => void,\n ): Promise<Required<CustomFlagValues>> {\n const slug = await this.input({\n kind: \"text\",\n name: \"connection name\",\n message:\n \"What would you like to call this connection? It is used in your configuration, for example acme-sso.\",\n parse: (value) => parseConnectionSlug(value, RESERVED_SLUGS),\n given: given.slug,\n });\n const existing = checkCustomSlug(files, slug, ENABLE_FLAG_NAMES.slug);\n beforeAsking(slug);\n // An existing connection is described by its file, so nothing it already\n // holds is asked again; reuse never applies scopes, so they are not asked.\n const stored = existing === undefined ? undefined : usableStoredSettings(existing, slug, given);\n // An issuer given as a flag must be the one the connection was written with:\n // that is known now, not after the next answer.\n const givenIssuer = given.issuer === undefined ? undefined : parseIssuer(given.issuer);\n if (existing !== undefined && givenIssuer?.ok) {\n refuseChangedIssuer(existing, slug, givenIssuer.value, ENABLE_FLAG_NAMES.slug);\n }\n const displayName = await this.input({\n kind: \"text\",\n name: \"display name\",\n message: \"What name should the sign-in button show? For example Acme SSO.\",\n parse: parseDisplayName,\n given: given.displayName ?? stored?.displayName,\n });\n const issuer = await this.input({\n kind: \"text\",\n name: \"issuer\",\n message: \"What is the issuer URL of the provider?\",\n parse: parseIssuer,\n given: given.issuer ?? stored?.issuer,\n });\n const scopes = await this.input({\n kind: \"text\",\n name: \"scopes\",\n message: \"Which scopes should we request? Separate them with spaces.\",\n parse: parseScopes,\n given: given.scopes ?? (existing === undefined ? undefined : DEFAULT_SCOPES.join(\" \")),\n initialValue: DEFAULT_SCOPES.join(\" \"),\n });\n return { slug, displayName, issuer, scopes: scopes.join(\" \") };\n }\n\n /**\n * The machine-readable payload. Never the secret, only whether it is held.\n */\n private payload(input: {\n /**\n * The Project the run addresses. `--json` suppresses the console line that\n * otherwise carries it, and a result that names only the schema does not\n * say which Project was changed.\n */\n projectId: string;\n provider: ProviderName;\n schema: string;\n plan: ConnectionPlan;\n callbackUri: string;\n secret: SecretOutcome | undefined;\n clientId: PublishState | undefined;\n /**\n * The variable the connection names, which need not be the slug's, and is\n * `undefined` when the connection holds its client id as a literal.\n */\n idVariable: ClientIdVariable | undefined;\n changed?: string[];\n skipped?: SsoSkipped[];\n }): Record<string, unknown> {\n return {\n project_id: input.projectId,\n provider: input.provider,\n schema: input.schema,\n connection: {\n action: input.plan.action,\n slug: input.plan.slug,\n file: input.plan.action === \"reuse\" ? input.plan.file.path : input.plan.path,\n },\n callback_uri: input.callbackUri,\n changed: input.changed ?? [],\n untouched: (input.skipped ?? []).map((s) => s.region),\n client_id:\n input.clientId === undefined || input.idVariable === undefined\n ? null\n : { variable: input.idVariable, published: input.clientId },\n secret:\n input.secret === undefined\n ? null\n : { variable: input.secret.name, published: input.secret.published },\n };\n }\n}\n\n/**\n * What the run needs from the flags before the schema is read. `selection` is\n * undefined for a custom provider whose settings a person will be asked for\n * once everything that can fail has passed; `values` are the settings the\n * flags gave.\n */\ntype ProjectContext = {\n readonly selection: ProviderSelection | undefined;\n readonly values: CustomFlagValues;\n readonly issuer: string;\n};\n\n/**\n * This command's `preflight`: quick checks of the flags, and nothing else.\n *\n * It runs inside `AuthMethodCommand.target`, before the schema is read, so it\n * must neither ask a question nor use the network or write anything: anything that\n * fails later would otherwise fail after the person had answered. Questions\n * for a custom provider's settings are asked in `run`, after the Project is\n * connected.\n *\n * The provider and a custom connection's settings are checked first, before\n * the Project's issuer: a name or issuer the server would refuse on deploy is\n * refused here, at once, under its flag.\n *\n * @param flags - `--provider`, which is named rather than prompted for, and\n * the custom connection's settings.\n * @param issuer - The origin the app serves from, from the environment.\n * @param interactive - Whether a person is there to be asked for settings left\n * out. A dry run never asks, so it is held to the flags like a script is.\n */\nasync function readProject(\n flags: { readonly [K in (typeof ENABLE_FLAG_KEYS)[keyof typeof ENABLE_FLAG_KEYS]]?: string },\n issuer: string | undefined,\n interactive: boolean,\n): Promise<ProjectContext> {\n const provider = flags[ENABLE_FLAG_KEYS.provider];\n if (provider === undefined) {\n // Named rather than prompted for: the catalog holds one provider today,\n // and a question offering a single answer is a keystroke, not a choice.\n throw new ZitadelError(\"E_VALIDATION\", \"Name the provider to enable\", {\n hint: `Pass --provider, e.g. --provider ${IDP_PROVIDERS[0]}.`,\n });\n }\n const values = customFlagValues(flags, ENABLE_FLAG_KEYS);\n // A person at a terminal is asked for the settings they left out, but later:\n // here the settings they did give are only checked, so nobody is asked before\n // being turned away. A script, a dry run or --non-interactive is held to the\n // flags and told which are missing.\n let selection: ProviderSelection | undefined;\n if (provider === CUSTOM_PROVIDER && interactive && !hasAllCustomSettings(values)) {\n checkGivenCustomFlags(values, ENABLE_FLAG_NAMES);\n } else {\n selection = selectionFromFlags(\n provider,\n values,\n ENABLE_FLAG_NAMES,\n customExample(ENABLE_FLAG_NAMES),\n );\n }\n if (issuer === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"This Project has no development issuer\", {\n hint: \"Run `zitadel setup` first, or set ZITADEL_ISSUER to the origin your app serves from.\",\n });\n }\n return { selection, values, issuer };\n}\n\n/**\n * What the file of an existing custom connection holds, checked as a typed\n * answer is, or a refusal that names the file and the setting: a stored value\n * that cannot be used would otherwise surface as an error about a flag the\n * person never passed. A file with no issuer is not an OIDC connection to\n * reuse at all, whatever issuer is typed.\n */\nfunction usableStoredSettings(\n file: ConnectionFile,\n slug: ConnectionSlug,\n given: CustomFlagValues,\n): CustomFlagValues {\n const stored = storedCustomSettings(file);\n if (stored.issuer === undefined) {\n throw new ZitadelError(\n \"E_CONFLICT\",\n `${file.path} is already named ${slug} and is not an OIDC connection`,\n {\n hint: `Fix the file, or choose another ${ENABLE_FLAG_NAMES.slug}, then run the command again.`,\n details: { file: file.path, slug },\n },\n );\n }\n // Only a stored value that will be used is held to the rules: one a flag\n // replaces is not read at all.\n const usable = <T>(\n what: string,\n value: string | undefined,\n flag: string | undefined,\n parse: (v: string) => Parsed<T>,\n ) => {\n const parsed = flag !== undefined || value === undefined ? undefined : parse(value);\n if (parsed !== undefined && !parsed.ok) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${file.path} holds ${what} that cannot be used: ${parsed.problem}`,\n {\n hint: `Fix it in that file, or choose another ${ENABLE_FLAG_NAMES.slug}.`,\n details: { file: file.path, slug },\n },\n );\n }\n return flag === undefined ? value : undefined;\n };\n return {\n displayName: usable(\"a display name\", stored.displayName, given.displayName, parseDisplayName),\n issuer: usable(\"an issuer\", stored.issuer, given.issuer, parseIssuer),\n };\n}\n\n/** Whether a custom connection's name, button text and issuer were all given. */\nfunction hasAllCustomSettings(values: CustomFlagValues): boolean {\n return (\n values.slug !== undefined && values.displayName !== undefined && values.issuer !== undefined\n );\n}\n\n/**\n * The flows this provider must be added to, or a refusal.\n *\n * Called before the connection is written and before either credential is\n * published, because no flow means no button however well everything else\n * went: `deploy` succeeds and the sign-in screen simply never offers the\n * provider. Failing afterwards would leave a connection file and two\n * published variables behind for a provider that cannot be shown.\n *\n * @param schema - The schema the provider is enabled for.\n * @param flows - The flows that run against it.\n */\nfunction targetFlows(schema: SchemaFile, flows: FlowFile[]): FlowFile[] {\n if (flows.length === 0) {\n throw new ZitadelError(\"E_NOT_FOUND\", `No login flow runs against ${schema.name}`, {\n hint:\n \"The provider is offered by a flow, and none of the files under .zitadel/flows/ \" +\n \"names this schema. Check that the flow's user_schema names the schema's objectType.\",\n details: { schema: schema.path },\n });\n }\n // The editors read a region they cannot recognise as absent and write the\n // generated one over it. Refuse here, before anything is written or\n // published, rather than discard whatever a developer put there.\n refuseUneditable(schema.path, ssoEditRefusal(schema.body, \"schema\"));\n for (const flow of flows) {\n refuseUneditable(flow.path, ssoEditRefusal(flow.body, \"flow\"));\n }\n return flows;\n}\n\n/** The schema and flow edits a run will make, before anything is written. */\ntype PlannedEdits = {\n readonly schema: SsoResult<object>;\n readonly flows: ReadonlyArray<{ flow: FlowFile; result: SsoResult<object> }>;\n /** Hand-edited regions the flow editors leave alone, named by file. */\n readonly skipped: SsoSkipped[];\n};\n\n/**\n * Enable the provider in the schema and every login flow that runs against\n * it, without writing anything. A flow belonging to another schema is left\n * alone: enabling Google for customers must not touch the employee journey.\n * The editors are pure and throw their refusals, so calling this before any\n * write or publish is what makes those refusals leave nothing behind.\n */\nfunction planEdits(\n schema: SchemaFile,\n slug: ConnectionSlug,\n flows: readonly FlowFile[],\n): PlannedEdits {\n const methods = enabledMethods(schema);\n const results = flows.map((flow) => ({ flow, result: applySsoToFlow(flow.body, slug, methods) }));\n return {\n schema: applySsoToSchema(schema.body, slug),\n flows: results,\n skipped: results.flatMap(({ flow, result }) =>\n result.skipped.map((entry) => ({ ...entry, region: `${flow.path} ${entry.region}` })),\n ),\n };\n}\n\n/** The project-relative files the planned edits change. */\nfunction editedFiles(schema: SchemaFile, edits: PlannedEdits): string[] {\n return [\n ...(edits.schema.changed ? [schema.path] : []),\n ...edits.flows.filter(({ result }) => result.changed).map(({ flow }) => flow.path),\n ];\n}\n\n/**\n * What a person needs to know about the claim mappings a custom connection was\n * written with, in two parts: the mappings (where they are, which side of each\n * line is their user schema's and which is the claim the provider must return),\n * then what verifies a value, which a mapping alone does not. Nothing here\n * edits a mapping; the connection file is where that happens.\n */\nfunction mappingNotes(options: { file: string; provider: string; connection: object }): string[] {\n const { file, provider, connection } = options;\n const document = connection as {\n claim_mapping?: Readonly<Record<string, string>>;\n verified_claims?: Readonly<Record<string, string | true>>;\n };\n const mappings = Object.entries(document.claim_mapping ?? {});\n if (mappings.length === 0) {\n return [];\n }\n const verified = Object.entries(document.verified_claims ?? {});\n return [\n `Claim mappings in ${file}. Each line is an attribute of your user schema, then the claim ${provider} must return for it:`,\n ...mappings.map(([attribute, claim]) => ` ${attribute} ← ${claim}`),\n ...(verified.length === 0\n ? [\"Nothing is treated as verified.\"]\n : [\n \"Verification, which a mapping alone does not give:\",\n ...verified.map(([attribute, how]) =>\n how === true\n ? ` ${attribute} is treated as verified.`\n : ` ${attribute} is treated as verified only when ${provider} says so in the ${how} claim.`,\n ),\n ]),\n \"Edit the mappings in that file if your provider returns other claims.\",\n ];\n}\n","import { BRANDING_DESIGNS, type BrandingDesign } from \"@zitadel/config/defaults\";\n\nimport { ZitadelError } from \"../errors\";\nimport { unscopedCommand } from \"../suggestion\";\n\n/**\n * Human-facing name and one-line hint for each shipped login design, shown by\n * the `branding eject` design picker. Setup no longer offers designs (#1039).\n */\nexport const BRANDING_DESIGN_INFO: Record<BrandingDesign, { label: string; hint: string }> = {\n centered: {\n label: \"Default card\",\n hint: \"the built-in widget, forked as an editable template\",\n },\n minimal: {\n label: \"Minimal\",\n hint: \"the same form without card chrome\",\n },\n};\n\n/**\n * Designs the eject catalog used to ship (#1039). They were page layout\n * around the default card, not widget structure, so they are refused by name\n * with a pointer to where page layout lives now — scripts and agents that\n * learned `--design split` get an actionable error instead of oclif's generic\n * \"expected one of\".\n */\nexport const RETIRED_BRANDING_DESIGNS = [\"split\", \"split-right\", \"hero\"] as const;\n\n/** Where page layout lives now, shared by every retired-design error. */\nconst PAGE_LAYOUT_HINT =\n \"Build page layout (split screens, hero panes, marketing copy) in your app around \" +\n \"<zitadel-login>, and theme the widget with --zl-* custom properties in your stylesheet.\";\n\n/**\n * Resolves a `branding eject --design` value to a shipped design. A retired\n * design fails with a hint naming the replacement, an unknown one lists the\n * catalog.\n */\nexport function resolveBrandingDesign(design: string, cliVersion: string): BrandingDesign {\n if ((BRANDING_DESIGNS as readonly string[]).includes(design)) {\n return design as BrandingDesign;\n }\n const catalog = BRANDING_DESIGNS.join(\", \");\n if ((RETIRED_BRANDING_DESIGNS as readonly string[]).includes(design)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `The ${design} design was retired: it was page layout, not widget structure`,\n {\n hint: `${PAGE_LAYOUT_HINT} To own the widget's structure, eject one of: ${catalog}.`,\n nextCommands: [unscopedCommand(\"branding eject --design centered\", cliVersion)],\n },\n );\n }\n throw new ZitadelError(\"E_VALIDATION\", `Unknown design ${JSON.stringify(design)}`, {\n hint: `Pick one of: ${catalog}.`,\n });\n}\n\n/**\n * The error for `setup --design`, which setup kept as a hidden flag only to\n * explain its removal (#1039): setup embeds the maintained login and never\n * applies a template.\n */\nexport function setupDesignRemovedError(cliVersion: string): ZitadelError {\n return new ZitadelError(\n \"E_VALIDATION\",\n \"setup no longer applies a login template, so --design was removed\",\n {\n hint:\n `Rerun setup without --design. ${PAGE_LAYOUT_HINT} ` +\n `To own the widget's structure after setup, eject one of: ${BRANDING_DESIGNS.join(\", \")}.`,\n nextCommands: [unscopedCommand(\"branding eject\", cliVersion)],\n },\n );\n}\n","/**\n * The editor meta-schemas a project carries in `.zitadel/meta/`, as this CLI\n * writes them. One writer for `setup`, `branding eject` and `doctor`, so the\n * file a project holds and the file `doctor` compares it with cannot drift.\n *\n * They are CLI-owned generated output (ADR 042's amendment): pure functions of\n * `@zitadel/config`'s `metaSchemaFiles()` and the CLI version, read only by\n * editors and agents, never by `deploy` or the server. The `zitadel …`\n * mentions in their descriptions become the runnable public command on the\n * way out ({@link normalizePublicCliJson}), so they differ between CLI\n * versions.\n */\nimport { lstat, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\n\nimport { META_SCHEMA_DIR, metaSchemaFiles } from \"@zitadel/config/meta-schemas\";\n\nimport { isErrno } from \"./errors\";\nimport { maskPublicCliVersion, normalizePublicCliJson } from \"./public-cli\";\n\n/** One meta-schema file: its project-relative path, its body, and the bytes written. */\nexport type ProjectMetaSchema = {\n path: string;\n body: object;\n contents: string;\n};\n\n/**\n * How a project's copy of one meta-schema compares with this CLI's. `linked`\n * means it is missing or outdated, but a symlink on its path keeps it from\n * being written.\n */\nexport type MetaSchemaState = \"current\" | \"missing\" | \"outdated\" | \"linked\";\n\n/** Every meta-schema file a project should hold, as this CLI version writes it. */\nexport function projectMetaSchemas(cliVersion: string): ReadonlyArray<ProjectMetaSchema> {\n return metaSchemaFiles().map((file) => {\n const body = normalizePublicCliJson(file.body, cliVersion);\n return {\n path: `${META_SCHEMA_DIR}/${file.name}`,\n body,\n contents: `${JSON.stringify(body, null, 2)}\\n`,\n };\n });\n}\n\n/**\n * Compares the project's copy of `file` with this CLI's: as parsed JSON, so\n * formatting and key order do not count, and with the CLI version in its\n * command mentions masked, so a release that left the dialect alone does not\n * either. A file that does not parse is outdated. Any read error other than a\n * missing file (a directory in its place, no permission) is thrown.\n *\n * Reading follows symlinks, so a linked file or folder that holds the current\n * schema passes. Writing must not: a missing or outdated file is overwritten,\n * and through a link at the file or at a directory on its way (`.zitadel`,\n * `.zitadel/meta`) that write would land on whatever the link names, such as\n * `.zitadel/secret` or a file outside the project. Such a file is `linked`,\n * and {@link linkOnPath} names the link.\n */\nexport async function metaSchemaState(\n cwd: string,\n file: ProjectMetaSchema,\n): Promise<MetaSchemaState> {\n const state = await contentState(cwd, file);\n if (state !== \"current\" && (await linkOnPath(cwd, file.path)) !== undefined) {\n return \"linked\";\n }\n return state;\n}\n\n/** {@link metaSchemaState} without the symlink rule. */\nasync function contentState(\n cwd: string,\n file: ProjectMetaSchema,\n): Promise<\"current\" | \"missing\" | \"outdated\"> {\n let text: string;\n try {\n text = await readFile(join(cwd, file.path), \"utf8\");\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return \"missing\";\n }\n throw error;\n }\n let held: unknown;\n try {\n held = JSON.parse(text);\n } catch {\n return \"outdated\";\n }\n return isDeepStrictEqual(maskPublicCliVersion(held), maskPublicCliVersion(file.body))\n ? \"current\"\n : \"outdated\";\n}\n\n/**\n * The first segment of the project-relative `path`, the last one included,\n * that is a symlink, or undefined. Checked without following links, and up to\n * the first segment that does not exist, since nothing below it can be a link.\n */\nexport async function linkOnPath(cwd: string, path: string): Promise<string | undefined> {\n const segments = path.split(\"/\");\n for (let end = 1; end <= segments.length; end++) {\n const segment = segments.slice(0, end).join(\"/\");\n try {\n if ((await lstat(join(cwd, segment))).isSymbolicLink()) {\n return segment;\n }\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return undefined;\n }\n throw error;\n }\n }\n return undefined;\n}\n","import type { ZitadelClient } from \"@zitadel/api/client\";\nimport type { BuildRelease201, BuildReleaseBody } from \"@zitadel/api/generated/model\";\n\nimport type { ConfigurationBundle } from \"./bundle\";\n\n/**\n * A release, as every build/get returns it. `BuildRelease200` (the dedupe\n * answer) and `BuildRelease201` share this shape, so one alias covers both.\n */\nexport type Release = BuildRelease201;\n\n/** Metadata recorded alongside a release, mirroring the source commit. */\nexport type ReleaseSource = {\n message?: string;\n gitSha: string | null;\n gitDirty: boolean;\n};\n\n/**\n * Build a release from the `.zitadel/` bundle (`POST /releases/build`). The\n * server reuses the revisions that already match and allocates the rest, and\n * dedupes on content: re-posting the same bundle returns the release that\n * already carries it. (`POST /releases` pins pre-existing revision ids and is\n * not a CLI flow.)\n */\nexport async function createReleaseFromBundle(\n client: ZitadelClient,\n projectId: string,\n bundle: ConfigurationBundle,\n source: ReleaseSource,\n): Promise<Release> {\n // The bundle is read from disk as loose JSON; the generated body types each\n // resource strictly. The server re-validates every one, so cast at the edge.\n const body = {\n bundle,\n ...(source.message === undefined ? {} : { message: source.message }),\n ...(source.gitSha === null ? {} : { git_sha: source.gitSha }),\n git_dirty: source.gitDirty,\n } as unknown as BuildReleaseBody;\n const result = await client.buildRelease(body, { project_id: projectId });\n return result as Release;\n}\n\n/** Revoke a release so its content is never served again. Idempotent. */\nexport async function revokeRelease(\n client: ZitadelClient,\n projectId: string,\n releaseId: string,\n): Promise<Release> {\n return client.revokeRelease(releaseId, { project_id: projectId });\n}\n","import type { ZitadelClient } from \"@zitadel/api/client\";\n\nimport type { SuggestedCommand } from \"../suggestion\";\nimport type { ConfigurationBundle } from \"./bundle\";\n\n/** Which publish a step runs for. `preview` lands with the preview command. */\nexport type PipelineMode = \"deploy\" | \"preview\";\n\n/**\n * What every step is handed. The bundle is built once by the command and shared\n * across the steps, so a step never re-reads `.zitadel/`.\n */\nexport interface StepContext {\n readonly cwd: string;\n readonly client: ZitadelClient;\n readonly projectId: string;\n readonly env: Record<string, string | undefined>;\n readonly mode: PipelineMode;\n /** No server write happens on a dry run; a writing step is skipped. */\n readonly dryRun: boolean;\n /** Colour and stray stdout are both suppressed under `--json`. */\n readonly json: boolean;\n readonly color: boolean;\n readonly bundle: ConfigurationBundle;\n /**\n * The branding descriptors as authored, before `$file` inlining, so\n * `validate` can report a missing reference the wire bundle has dropped.\n */\n readonly brandingSources: readonly Record<string, unknown>[];\n /**\n * The connection files' names, positional with `bundle.idps`, so a check can\n * name the file a bad connection came from.\n */\n readonly idpFiles: readonly string[];\n /** The policy files' names, positional with `bundle.policies`, likewise. */\n readonly policyFiles: readonly string[];\n /**\n * A command against the project this run addresses, carrying its\n * environment selector, for a step's error to suggest its own fix.\n */\n readonly suggest: (args: string) => SuggestedCommand;\n}\n\n/**\n * One stage of the publish pipeline. `runsFor` keeps a step out of the publishes\n * it does not belong to — the IdP sync is deploy-only, never preview — and\n * `writes` marks a step that mutates the server, so a dry run skips it while\n * still validating and showing the diff.\n */\nexport interface Step {\n readonly name: string;\n readonly runsFor: readonly PipelineMode[];\n readonly writes?: boolean;\n run(ctx: StepContext): Promise<void>;\n}\n\n/**\n * Run the before-release steps in order, skipping the ones that do not apply to\n * this publish or that write on a dry run. The command creates the release and\n * the deployment itself, between and after the step groups: before-release\n * steps → create release → before-deploy steps → create deployment.\n */\nexport async function runSteps(steps: readonly Step[], ctx: StepContext): Promise<void> {\n for (const step of steps) {\n if (!step.runsFor.includes(ctx.mode)) {\n continue;\n }\n if (ctx.dryRun && step.writes) {\n continue;\n }\n await step.run(ctx);\n }\n}\n","/** One of a project's origin patterns, as `GET /projects/{id}` returns it. */\nexport type ProjectOriginEntry = Readonly<{ pattern: string; kind: string }>;\n\n/**\n * Whether an origin pattern covers a concrete origin URL, matching the server's\n * glob rule: a `*` stands for one or more characters, none of them a dot, so\n * `https://*.preview.acme.com` covers `https://pr-7.preview.acme.com` but not a\n * deeper label. A pattern with no `*` matches only its exact self.\n */\nexport function originMatchesPattern(pattern: string, origin: string): boolean {\n // Every literal part is escaped whole, so only the `*` between them is a\n // wildcard in the expression.\n const literal = (part: string) => part.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const expression = pattern.split(\"*\").map(literal).join(\"[^.]+\");\n return new RegExp(`^${expression}$`).test(origin);\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport {\n BRANDING_DESIGNS,\n DEFAULT_BRANDING_CONFIG_PATH,\n DEFAULT_BRANDING_DESIGN,\n DEFAULT_BRANDING_TEMPLATE_PATH,\n brandingReadmeContent,\n getDefaultBrandingConfig,\n} from \"@zitadel/config/defaults\";\nimport { BRANDING_FILE_SCHEMA_REF, META_SCHEMA_DIR } from \"@zitadel/config/meta-schemas\";\n\nimport { BRANDING_DIR } from \"../../lib/branding\";\nimport { BRANDING_DESIGN_INFO, resolveBrandingDesign } from \"../../lib/branding/designs\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { stableStringify } from \"../../lib/json\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope, nonBlankString } from \"../../lib/oclif\";\nimport { hasZitadelConfig } from \"../../lib/project\";\nimport { metaSchemaState, projectMetaSchemas } from \"../../lib/meta-schemas\";\nimport { normalizePublicCliProse } from \"../../lib/public-cli\";\nimport { nextCommandsData } from \"../../lib/oclif/envelope\";\nimport { DEPLOY_ARGS } from \"../../lib/release\";\nimport { Promptable } from \"../../lib/oclif/promptable\";\n\n/**\n * The `branding eject` command — take ownership of the login template.\n *\n * Scaffolds `.zitadel/branding/` from a shipped design: the `branding.json`\n * descriptor, the `login.liquid` template it references, a README, and the\n * branding dialect meta-schema when the project's copy is missing or\n * outdated (set up before the dialect existed or changed).\n * Purely local — nothing is uploaded; the first `zitadel deploy` publishes\n * revision 1. Ejecting the template is the last rung of the branding\n * override ladder (docs/design/branding/override-ladder.md); unrelated to\n * `zitadel eject`, which removes the Zitadel integration.\n */\nexport default class BrandingEject extends Promptable(BaseCommand) {\n static override description =\n \"Take ownership of the login template: scaffold .zitadel/branding/ from a shipped design.\";\n static override group = CommandGroups.configuration;\n static override flags = {\n force: Flags.boolean({ char: \"f\", description: \"Overwrite an existing branding file.\" }),\n // No oclif `options`: the retired designs (#1039) must reach\n // resolveBrandingDesign to get their targeted error instead of oclif's\n // generic \"expected one of\".\n design: nonBlankString({\n description: `Design to start from: ${BRANDING_DESIGNS.join(\" or \")} (default: ${DEFAULT_BRANDING_DESIGN}).`,\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(BrandingEject);\n await this.toMeta(flags, { resolveServer: false });\n const { cwd, force, nonInteractive } = this.meta;\n const flagDesign =\n flags.design === undefined\n ? undefined\n : resolveBrandingDesign(flags.design, this.meta.cliVersion);\n\n if (!(await hasZitadelConfig(cwd))) {\n throw new ZitadelError(\"E_VALIDATION\", \"This directory is not a Zitadel project\", {\n hint: \"Run setup first; branding files live under .zitadel/.\",\n nextCommands: [this.suggestUnscoped(\"setup\")],\n });\n }\n\n const design = flagDesign ?? (await this.promptDesign(nonInteractive));\n this.recordTelemetry({ design, force });\n const { branding, template } = getDefaultBrandingConfig(design);\n\n const filesWritten: string[] = [];\n const write = async (relPath: string, content: string, overwrite: boolean): Promise<void> => {\n const dest = join(cwd, relPath);\n await mkdir(dirname(dest), { recursive: true });\n try {\n await writeFile(dest, content, overwrite ? undefined : { flag: \"wx\" });\n filesWritten.push(relPath);\n } catch (error) {\n if (isErrno(error, \"EEXIST\")) {\n throw new ZitadelError(\"E_CONFLICT\", `${relPath} already exists`, {\n hint: \"Rerun with --force to replace it, or edit the existing file directly.\",\n });\n }\n throw error;\n }\n };\n\n await write(\n DEFAULT_BRANDING_CONFIG_PATH,\n `${stableStringify({ $schema: BRANDING_FILE_SCHEMA_REF, ...branding })}\\n`,\n force,\n );\n await write(DEFAULT_BRANDING_TEMPLATE_PATH, template, force);\n\n // Never overwrite a hand-edited README.\n await write(\n join(BRANDING_DIR, \"README.md\"),\n normalizePublicCliProse(brandingReadmeContent(), this.meta.cliVersion),\n false,\n ).catch(swallowConflict);\n // The descriptor's `$schema` must resolve to the dialect it was written\n // in, so the CLI-owned meta-schema is written when missing or outdated,\n // as `doctor --fix` does; one that cannot be read, or sits behind a\n // symlink, is doctor's to report.\n const brandingMeta = projectMetaSchemas(this.meta.cliVersion).find(\n (file) => file.path === `${META_SCHEMA_DIR}/branding.json`,\n );\n if (brandingMeta) {\n const state = await metaSchemaState(cwd, brandingMeta).catch(() => \"current\" as const);\n if (state === \"missing\" || state === \"outdated\") {\n await write(brandingMeta.path, brandingMeta.contents, true);\n }\n }\n\n for (const file of filesWritten) {\n consola.info(`Wrote ${file}`);\n }\n consola.success(`Ejected the ${design} design into ${BRANDING_DIR}/`);\n\n return this.emit({\n status: \"ok\",\n data: {\n design,\n files_written: filesWritten,\n next_actions: [\n `Edit ${DEFAULT_BRANDING_TEMPLATE_PATH} — the login UI is yours now.`,\n \"Deploy --dry-run validates the template and shows the diff; deploy publishes it.\",\n ],\n // `branding eject` reads no environment, so it has no selector to\n // carry: the follow-ups run against whichever one the developer uses.\n ...nextCommandsData([\n this.suggestUnscoped(\"deploy --dry-run\"),\n this.suggestUnscoped(DEPLOY_ARGS),\n ]),\n },\n });\n }\n\n private async promptDesign(nonInteractive: boolean): Promise<string> {\n if (nonInteractive) {\n return DEFAULT_BRANDING_DESIGN;\n }\n return this.input({\n kind: \"select\",\n name: \"design\",\n message: \"Which design would you like to start from?\",\n initialValue: DEFAULT_BRANDING_DESIGN as string,\n options: BRANDING_DESIGNS.map((design) => ({\n value: design as string,\n label: BRANDING_DESIGN_INFO[design].label,\n hint: BRANDING_DESIGN_INFO[design].hint,\n })),\n });\n }\n}\n\nfunction swallowConflict(error: unknown): void {\n if (error instanceof ZitadelError && error.code === \"E_CONFLICT\") {\n return;\n }\n throw error;\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 NodeJS.ErrnoException).code === code\n );\n}\n","import { spawn as nodeSpawn } from \"node:child_process\";\nimport { access, readFile } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\n\n/**\n * Why a browser launch did not happen. Never an error condition: every reason\n * resolves to the same caller behaviour (show the link and let the user open\n * it themselves), so this exists for narration and telemetry, not control flow.\n *\n * - `headless` — a graphical session was not detected (no `DISPLAY`, no\n * `WAYLAND_DISPLAY`, or a plain SSH session). Spawning would either fail\n * noisily or open a browser on a machine nobody is looking at.\n * - `no-opener` — no known opener binary is on `PATH`. Common on minimal\n * containers and BSDs without `xdg-utils`.\n * - `disabled` — `BROWSER=none`, the convention honoured by webbrowser(3) and\n * most dev servers for \"never open anything\".\n * - `spawn-failed` — the opener exists but the process could not be started.\n */\nexport type OpenFailure = \"headless\" | \"no-opener\" | \"disabled\" | \"spawn-failed\";\n\n/** Outcome of {@link openInBrowser}. `opened` is best effort: see the note there. */\nexport type OpenResult = { opened: boolean; reason?: OpenFailure };\n\n/**\n * Injectable seams so the platform matrix is unit-testable without touching\n * the real machine: every environment probe this module makes goes through\n * one of these.\n */\nexport type BrowserDeps = {\n platform: NodeJS.Platform;\n env: NodeJS.ProcessEnv;\n /**\n * Resolves an executable name against `PATH`, or `undefined` if absent.\n * The default implementation reads `PATH` from {@link BrowserDeps.env}, not\n * from `process.env`, so overriding `env` alone is enough to redirect\n * executable resolution.\n */\n lookupPath: (command: string) => Promise<string | undefined>;\n /** Reads `/proc/version` for WSL detection; `undefined` when unreadable. */\n readProcVersion: () => Promise<string | undefined>;\n spawn: (command: string, args: string[]) => void;\n};\n\n/**\n * Openers tried in order on Linux and the BSDs. `xdg-open` is the standard and\n * covers any desktop that ships `xdg-utils`; the rest are the fallbacks that\n * exist on systems that don't (GNOME-only, Debian's alternatives system, KDE).\n * `gio` takes a subcommand, so it carries its own argv shape.\n */\nconst UNIX_OPENERS: ReadonlyArray<{ command: string; args: (url: string) => string[] }> = [\n { command: \"xdg-open\", args: (url) => [url] },\n { command: \"gio\", args: (url) => [\"open\", url] },\n { command: \"x-www-browser\", args: (url) => [url] },\n { command: \"sensible-browser\", args: (url) => [url] },\n { command: \"gnome-open\", args: (url) => [url] },\n { command: \"kde-open\", args: (url) => [url] },\n];\n\n/**\n * Opens `url` in the user's default browser, best effort.\n *\n * Best effort is the contract, not a caveat: this never throws and never\n * reports a failure the caller must handle. There is no portable way to know a\n * browser actually rendered the page — the opener returns as soon as it has\n * handed the URL off — so `opened: true` means only \"an opener was started\".\n * Callers must print the URL regardless and treat the launch as a convenience\n * on top of it, which is what makes headless machines, bare containers, and\n * SSH sessions work without a special case.\n */\nexport async function openInBrowser(\n url: string,\n overrides: Partial<BrowserDeps> = {},\n): Promise<OpenResult> {\n // Resolve `env` first so the default `lookupPath` closes over the *effective*\n // environment: overriding `env.PATH` alone must redirect executable\n // resolution, without the caller also having to replace `lookupPath`.\n const env = overrides.env ?? process.env;\n const deps: BrowserDeps = { ...defaultDeps(env), ...overrides };\n\n const browser = deps.env.BROWSER?.trim();\n if (browser === \"none\") {\n return { opened: false, reason: \"disabled\" };\n }\n if (browser) {\n return launch(deps, browser, [url]);\n }\n\n if (deps.platform === \"darwin\") {\n return launch(deps, \"open\", [url]);\n }\n if (deps.platform === \"win32\") {\n // `start` is a cmd builtin, not an executable, and its first quoted\n // argument is taken as the window title — hence the empty \"\" before the\n // URL, without which a quoted URL would be swallowed as the title.\n return launch(deps, \"cmd\", [\"/c\", \"start\", \"\", url]);\n }\n\n if (await isWsl(deps)) {\n // Inside WSL the browser lives on the Windows side. `wslview` (wslu) is\n // the purpose-built bridge; PowerShell is the fallback every WSL install\n // has.\n const wslview = await deps.lookupPath(\"wslview\");\n if (wslview) {\n return launch(deps, \"wslview\", [url]);\n }\n return launch(deps, \"powershell.exe\", [\"-NoProfile\", \"-Command\", \"Start-Process\", url]);\n }\n\n if (!hasGraphicalSession(deps.env)) {\n return { opened: false, reason: \"headless\" };\n }\n\n for (const opener of UNIX_OPENERS) {\n if (await deps.lookupPath(opener.command)) {\n return launch(deps, opener.command, opener.args(url));\n }\n }\n return { opened: false, reason: \"no-opener\" };\n}\n\n/**\n * Whether a graphical session is plausibly present and worth opening into.\n *\n * X11 and Wayland both advertise themselves through an env var. SSH is\n * excluded even when `DISPLAY` is set, because X11 forwarding sets it: the\n * browser would launch on the remote host and, at best, tunnel a window back\n * over a link nobody asked to render one on.\n */\nfunction hasGraphicalSession(env: NodeJS.ProcessEnv): boolean {\n if (env.SSH_CONNECTION || env.SSH_TTY || env.SSH_CLIENT) {\n return false;\n }\n return Boolean(env.DISPLAY || env.WAYLAND_DISPLAY);\n}\n\n/**\n * WSL advertises itself through `WSL_DISTRO_NAME`/`WSLENV`, but neither is set\n * under every shell, so fall back to the kernel release string, which carries\n * `microsoft` on all WSL kernels.\n */\nasync function isWsl(deps: BrowserDeps): Promise<boolean> {\n if (deps.platform !== \"linux\") {\n return false;\n }\n if (deps.env.WSL_DISTRO_NAME || deps.env.WSLENV) {\n return true;\n }\n const version = await deps.readProcVersion();\n return version?.toLowerCase().includes(\"microsoft\") ?? false;\n}\n\n/**\n * Starts the opener fully detached: the CLI keeps polling for the claim while\n * the browser lives on, and must not hold the event loop open waiting for a\n * process it does not own. Output is discarded because openers write\n * diagnostics to stderr that would interleave with the CLI's own narration.\n */\nfunction launch(deps: BrowserDeps, command: string, args: string[]): OpenResult {\n try {\n deps.spawn(command, args);\n return { opened: true };\n } catch {\n return { opened: false, reason: \"spawn-failed\" };\n }\n}\n\nfunction defaultDeps(env: NodeJS.ProcessEnv): BrowserDeps {\n return {\n platform: process.platform,\n env,\n lookupPath: (command) => lookupPath(command, env.PATH ?? \"\"),\n readProcVersion: async () => {\n try {\n return await readFile(\"/proc/version\", \"utf8\");\n } catch {\n return undefined;\n }\n },\n spawn: (command, args) => {\n const child = nodeSpawn(command, args, { stdio: \"ignore\", detached: true });\n // A spawn error surfaces asynchronously; swallow it so an opener that\n // vanishes between the PATH probe and the spawn cannot crash the CLI\n // with an unhandled 'error' event.\n child.on(\"error\", () => undefined);\n child.unref();\n },\n };\n}\n\n/**\n * Minimal `which`: the first entry of `pathEnv` holding an executable\n * `command`. Probing the filesystem directly avoids shelling out (and avoids\n * depending on a `which`/`where` binary being present on the very systems that\n * are missing `xdg-open`). `pathEnv` is passed in rather than read from\n * `process.env` so it follows whatever environment the caller injected.\n */\nasync function lookupPath(command: string, pathEnv: string): Promise<string | undefined> {\n for (const dir of pathEnv.split(delimiter).filter(Boolean)) {\n const candidate = join(dir, command);\n try {\n await access(candidate, constants.X_OK);\n return candidate;\n } catch {}\n }\n return undefined;\n}\n","import type { BoxAction } from \"./box\";\nimport { serverKind } from \"./oclif/server-kind\";\nimport type { ZitadelSecret } from \"./project\";\nimport { publicCliCommand } from \"./public-cli\";\nimport { type EnvironmentSelector, projectCommand, type SuggestedCommand } from \"./suggestion\";\n\n/**\n * Mirrors domain.ClaimWindow (internal/domain/claim.go): the server refuses\n * `claim/init` and `claim/complete` with `proj.claim_window_expired` once the\n * project is more than this many days old. Keep the two in sync — drift here\n * shows as a wrong printed deadline, the enforcement stays server-side.\n */\nexport const CLAIM_WINDOW_DAYS = 14;\n\n/**\n * The date after which the platform refuses to claim, from the project's\n * creation time. Falls back to `now` when creation time is unknown, which is\n * exact at setup time (the project was just created) and the only caller\n * without a recorded creation time.\n */\nexport function claimWindowDeadline(createdAt: string | undefined, now = Date.now()): Date {\n const base = createdAt === undefined ? now : Date.parse(createdAt);\n return new Date((Number.isNaN(base) ? now : base) + CLAIM_WINDOW_DAYS * 24 * 60 * 60 * 1000);\n}\n\n/**\n * Time and zone included, not just the date: the server closes the window\n * at an exact timestamp (created_at + 14 x 24h), and a bare \"before Sep 18\"\n * misleads in both directions at the boundary day.\n */\nfunction formatDeadline(deadline: Date): string {\n return deadline.toLocaleString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n timeZoneName: \"short\",\n });\n}\n\n/**\n * Whether this project is attached to a team, as the CLI can tell locally.\n *\n * `not-applicable` is its own variant rather than a boolean flag on the caller\n * because \"there is nothing to attach here\" and \"nothing is attached yet\" want\n * opposite output: the first prints nothing at all, the second nudges.\n */\nexport type ClaimState =\n | { kind: \"attached\"; team_id: string; claimed_at: string }\n /**\n * `claimable` classifies the claim window from the locally recorded\n * creation time: once it has passed, nudges switch to reconciliation\n * wording (claimWindowClosedAction). Never proof of anything: the local\n * record can be stale (a project claimed from another machine still reads\n * detached), so the claim command stays advertised as the safe check —\n * the server resolves the grant before the window. Lenient on an unknown\n * or unparsable creation time (claimable, no deadline) because the server\n * is the enforcer and the CLI only advises. `deadline` is the ISO date\n * the window closes, when the creation time is known.\n */\n | { kind: \"detached\"; claimable: boolean; deadline?: string }\n | { kind: \"not-applicable\" };\n\n/**\n * Whether the local record says a team owns this project.\n *\n * Both fields or neither: a half-written record is not an attachment, and\n * treating it as one would hand callers a `team_id` with no idea when it\n * landed. Shared with `zitadel claim`, which asks the same question before it\n * decides to skip, so the two cannot drift as the record grows fields.\n *\n * Deliberately separate from {@link claimState}: the command must answer this\n * on any server, while the nudges only ask it on the cloud.\n */\nexport function isAttached(\n secret: Pick<ZitadelSecret, \"claimed_at\" | \"team_id\">,\n): secret is { claimed_at: string; team_id: string } {\n return Boolean(secret.claimed_at && secret.team_id);\n}\n\n/**\n * Decides the attachment state from local state alone.\n *\n * **Why no network call.** The contract exposes no ambient claim-state read:\n * `getClaimStatus` answers for one live challenge and rejects a secret that did\n * not mint it, and claim attributes were deliberately kept off\n * `GET /projects/{id}` because they belong to the grant, not the project. So\n * `.zitadel/secret` is the only source, which is also why `status` and `doctor`\n * stay fast and work offline. `zitadel claim` reaches the same conclusion the\n * same way before it decides to skip.\n *\n * **Why cloud only.** Claiming attaches a project to a team on the platform\n * that hosts it. The cloud always has one. A local or self-hosted server has\n * one only when it opted into `platform.bootstrap_project`. `zitadel start`\n * does opt in, but a server started any other way — or one that opted out with\n * `NEXTGEN_PLATFORM_BOOTSTRAP_PROJECT=false` — has no platform project, so this\n * offline classifier cannot know whether a local claim could complete. `setup` is online anyway and probes the local server's runtime\n * document to decide the nudge there; the offline surfaces (`status`,\n * `doctor`) stay cloud-gated rather than advertise a possibly impossible\n * action.\n *\n * The local record can be stale in one direction: a project claimed from\n * another machine, or a `.zitadel/secret` restored from a backup, reads as\n * `detached` here. That is tolerable because everything downstream is\n * advisory, and `zitadel claim` itself turns the resulting `409` into a clean\n * skip rather than an error.\n */\nexport function claimState(input: {\n secret: Pick<ZitadelSecret, \"claimed_at\" | \"team_id\"> & { created_at?: string };\n server: string;\n}): ClaimState {\n if (serverKind.value(input.server) !== \"cloud\") {\n return { kind: \"not-applicable\" };\n }\n if (isAttached(input.secret)) {\n return {\n kind: \"attached\",\n team_id: input.secret.team_id,\n claimed_at: input.secret.claimed_at,\n };\n }\n const createdAt = Date.parse(input.secret.created_at ?? \"\");\n if (Number.isNaN(createdAt)) {\n return { kind: \"detached\", claimable: true };\n }\n const deadline = claimWindowDeadline(input.secret.created_at);\n return {\n kind: \"detached\",\n claimable: deadline.getTime() > Date.now(),\n deadline: deadline.toISOString(),\n };\n}\n\n/**\n * The one claim nudge, shared by `setup` and `status` (doctor mirrors it with\n * plain `zitadel` command names). Names the claim window because the server\n * enforces it at claim time (`proj.claim_window_expired`), and names the\n * data-loss stake per product decision: temporary projects get purged after\n * the window. That supersedes the no-deletion stance in ADR 046 §Non-goals;\n * amending the ADR is the follow-up tracked on PR #1194.\n */\nfunction claimSentence(deadline?: Date): string {\n const when =\n deadline === undefined\n ? `within ${CLAIM_WINDOW_DAYS} days of creation`\n : `before ${formatDeadline(deadline)}`;\n return (\n `Claim your Project ${when} to make it permanent and start collaborating with your team. ` +\n \"Until then, your Project is temporary and its data may be lost.\"\n );\n}\n\n/**\n * The nudge for `next_actions`, quoting the command in prose. `selector` is the\n * environment suffix (e.g. ` --env-file .env.development.local`) the suggested\n * `claim` must carry so it targets the project this run is about rather than\n * whatever the next shell's environment resolves to; empty when none applies.\n */\nexport function claimAction(\n cliVersion: string,\n deadline: Date | undefined,\n selector: EnvironmentSelector,\n): string {\n return `${claimSentence(deadline)} Run ${claimCommand(cliVersion, selector)}.`;\n}\n\n/** The same nudge for the human box, with the command on its own styled line. */\nexport function claimBoxAction(\n cliVersion: string,\n deadline: Date | undefined,\n selector: EnvironmentSelector,\n): BoxAction {\n return {\n text: claimSentence(deadline),\n command: claimCommand(cliVersion, selector),\n };\n}\n\n/** The command for `next_commands`. `selector` carries the environment suffix. */\nexport function claimCommand(cliVersion: string, selector: EnvironmentSelector): SuggestedCommand {\n return projectCommand(\"claim\", selector, cliVersion);\n}\n\n/**\n * The nudge's counterpart for a closed claim window. Deliberately framed as\n * reconciliation, not a verdict: the local record can be stale in one\n * direction (a project claimed from another machine still reads detached\n * here), so \"window closed\" from local data alone must not send the user off\n * to duplicate a project that is already attached and working. Running\n * `zitadel claim` is safe either way — the server checks the grant before\n * the window, so an attached project answers with a clean already-claimed\n * skip, and only a genuinely unattached one gets the final refusal.\n */\nexport function claimWindowClosedAction(cliVersion: string, selector: EnvironmentSelector): string {\n return (\n `The local record says this project's ${CLAIM_WINDOW_DAYS}-day claim window has ` +\n `closed. Run ${claimCommand(cliVersion, selector)} to reconcile: a project ` +\n \"claimed from another machine confirms its team, and one never claimed can no \" +\n `longer be claimed. ${publicCliCommand(\"setup\", cliVersion)} in a fresh directory ` +\n \"gets you a new project you can claim.\"\n );\n}\n","import { setTimeout as sleep } from \"node:timers/promises\";\n\nimport { Flags } from \"@oclif/core\";\nimport { getClaimStatusQueryChallengeIdRegExp } from \"@zitadel/api/generated/endpoints/zitadelNextGen.zod\";\nimport { ApiError } from \"@zitadel/api/runtime/fetch\";\nimport consola from \"consola\";\n\nimport type { ZitadelClient } from \"../lib/api-client\";\nimport { wrapForBox } from \"../lib/box\";\nimport { openInBrowser } from \"../lib/browser\";\nimport { CLAIM_WINDOW_DAYS, isAttached } from \"../lib/claim-state\";\nimport { requireValue } from \"../lib/environment\";\nimport { ZitadelError } from \"../lib/errors\";\nimport { isObject } from \"../lib/json\";\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { nextCommandsData } from \"../lib/oclif/envelope\";\nimport { hasZitadelSecret, readZitadelSecret, writeZitadelSecret } from \"../lib/project\";\nimport { isLoopbackUrl } from \"../lib/server\";\nimport { reportWarning } from \"../lib/warnings\";\nimport type { SuggestedCommand } from \"../lib/suggestion\";\n\n/**\n * Poll cadence while a human completes the browser step. Starts responsive so\n * a claim finished in a few seconds is reported almost immediately, then eases\n * off so a link left open for the full ten minutes costs a few hundred\n * requests rather than a few thousand.\n */\nconst INITIAL_POLL_MS = 1000;\nconst MAX_POLL_MS = 5000;\nconst POLL_BACKOFF_FACTOR = 1.5;\n\n/**\n * Backstop for the poll deadline, used only when the server's own `expires_at`\n * cannot be parsed. The challenge TTL is the platform's to decide (ADR 046) and\n * the response carries it, so this is never the normal path — but without it a\n * malformed or misrouted response would leave the loop with no deadline at all\n * and the CLI polling forever. Matches the TTL the ADR documents.\n */\nconst FALLBACK_TTL_MS = 10 * 60 * 1000;\n\n/**\n * When to stop polling: the earlier of the server's own expiry and any\n * `--timeout` the caller set.\n *\n * Trusts `expires_at` rather than assuming the TTL, because the contract\n * documents it as the authority and the CLI should not go stale if the platform\n * ever retunes it. An unparseable value falls back to {@link FALLBACK_TTL_MS}\n * rather than to no deadline: a malformed or misrouted response must not leave\n * the loop running forever. So does a resumed wait (`--challenge-id`), which has\n * no `expires_at` to read because the status route does not repeat it; the\n * server's own `410` still ends that wait when the link really expires.\n * Exported so that fallback is testable without waiting out a real TTL.\n */\nexport function claimDeadline(input: {\n expiresAt?: string;\n timeoutSeconds?: number;\n now: number;\n}): number {\n const parsed = input.expiresAt === undefined ? Number.NaN : Date.parse(input.expiresAt);\n const serverDeadline = Number.isNaN(parsed) ? input.now + FALLBACK_TTL_MS : parsed;\n if (input.timeoutSeconds === undefined) {\n return serverDeadline;\n }\n return Math.min(serverDeadline, input.now + input.timeoutSeconds * 1000);\n}\n\n/**\n * `zitadel claim` — claim this project for a team to make it permanent.\n *\n * Shaped like the device-authorization grant (ADR 046): the CLI mints a\n * challenge with the project secret, hands a URL to a browser, and polls until\n * the human finishes. The project secret never leaves the machine and the\n * browser only ever sees the challenge id.\n *\n * The command blocks for as long as the link is valid. That is the point: the\n * developer is looking at the terminal, finishes in the browser, and comes\n * back to a terminal that already knows. Nothing about the project changes —\n * the issuer, users, and applications keep working exactly as before, so this\n * is purely additive.\n *\n * A caller that reads only the `--json` envelope cannot see the link while\n * the command blocks, and an agent has to hand that link to a person. So\n * `--no-wait` returns the link as the result, and `--challenge-id` resumes\n * waiting on it in a second run.\n */\nexport default class Claim extends EnvironmentCommand {\n static override description =\n \"Claim this project to make it permanent. Opens a browser to create an account or sign in.\";\n static override group = CommandGroups.gettingStarted;\n static override groupOrder = 4;\n\n static override examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --no-open\",\n \"<%= config.bin %> <%= command.id %> --timeout 120\",\n \"<%= config.bin %> <%= command.id %> --no-wait\",\n \"<%= config.bin %> <%= command.id %> --challenge-id ch_01J0Z9KX7Y0Q2Y7JX5M9K2YF3C\",\n ];\n\n static override flags = {\n \"no-open\": Flags.boolean({\n description: \"Print the link instead of opening a browser.\",\n }),\n timeout: Flags.integer({\n min: 1,\n description:\n \"Seconds to wait for the browser step. Defaults to the link's own expiry (10 minutes).\",\n }),\n \"no-wait\": Flags.boolean({\n description:\n \"Print the link and exit, without opening a browser or waiting for the browser step. The result names the command that waits for it.\",\n exclusive: [\"challenge-id\", \"timeout\"],\n }),\n \"challenge-id\": Flags.string({\n description: \"Wait for the link a --no-wait run printed, instead of creating a new one.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Claim);\n await this.toMeta(flags);\n const { cwd, dryRun, nonInteractive } = this.meta;\n const challengeId = flags[\"challenge-id\"];\n // The id goes back to the platform and into this run's suggestions, so it\n // has to be the contract's shape before anything is asked or sent.\n if (challengeId !== undefined && !isChallengeId(challengeId)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"--challenge-id takes the challenge_id a `claim --no-wait` run returned, which starts with ch_.\",\n { nextCommands: [this.suggest(\"claim --no-wait\")] },\n );\n }\n // Where a fresh link comes from when this one dies: a run that is part of\n // the two-step flow suggests the step that hands the link back, so\n // following the suggestion never blocks with the link out of sight.\n const startOver = this.suggest(\n flags[\"no-wait\"] || challengeId !== undefined ? \"claim --no-wait\" : \"claim\",\n );\n\n // The project to claim is the one the resolved environment points at — the\n // same project (and credential) `connect()` authenticates — so a\n // `--env`/`--env-file` claim targets that environment's project, never the\n // fallback `.zitadel/secret`.\n // On a terminal a missing project id is asked for by `connect()`, as every\n // other project command does. A dry run writes nothing, a prompted answer's\n // file included, so it still fails naming the sources it consulted.\n const prompted =\n this.environment.values.ZITADEL_PROJECT_ID === undefined && !dryRun && !nonInteractive\n ? await this.connect()\n : undefined;\n const projectId = prompted?.projectId ?? requireValue(this.environment, \"ZITADEL_PROJECT_ID\");\n // `.zitadel/secret` is only the place a completed claim is recorded, and\n // only when it is this very project's record. An env file can supply a\n // different project, so the legacy secret is neither required nor touched\n // then — the durable record is the platform grant (ADR 046), and the local\n // cache must not claim a project it does not describe.\n const localSecret = (await hasZitadelSecret(cwd)) ? await readZitadelSecret(cwd) : undefined;\n const localRecord = localSecret?.project_id === projectId ? localSecret : undefined;\n\n // The local record is authoritative enough to skip the round trip: the\n // platform enforces first-claim-wins anyway, so re-asking could only ever\n // return the same answer at the cost of a request. An env project with no\n // matching local record falls through and lets the platform answer.\n if (localRecord && isAttached(localRecord)) {\n return this.alreadyClaimed({\n project_id: projectId,\n team_id: localRecord.team_id,\n claimed_at: localRecord.claimed_at,\n });\n }\n\n // `--dry-run` promises to mutate neither files nor the platform, so it has\n // to stop before `initClaim`: minting a challenge is a platform write, and\n // a developer who then finished the browser step would really claim the\n // project while this run deliberately skipped recording it — the local file\n // and the platform would disagree, which is worse than not previewing at\n // all. There is nothing further to preview here anyway: the outcome of a\n // claim is decided in a browser, not by anything the CLI could compute.\n if (dryRun) {\n const action = flags[\"no-wait\"]\n ? \"Create a link to claim this project\"\n : challengeId === undefined\n ? \"Open a browser to claim this project\"\n : \"Wait for the link to be used to claim this project\";\n this.recordTelemetry({ claim_outcome: \"dry_run\" });\n return this.emit({\n status: \"skipped\",\n reason: \"dry-run\",\n data: {\n title: \"Zitadel claim was not started.\",\n project_id: projectId,\n would:\n localRecord && !flags[\"no-wait\"]\n ? `${action}, then record the owning team in .zitadel/secret.`\n : `${action}.`,\n },\n nextCommands: [\n challengeId === undefined\n ? startOver\n : this.suggest(`claim --challenge-id ${challengeId}`),\n ],\n });\n }\n\n const { client } = prompted ?? (await this.connect());\n\n let waitFor: { challengeId: string; deadline: number };\n let opened: boolean | undefined;\n if (challengeId === undefined) {\n let challenge: Awaited<ReturnType<typeof client.initClaim>>;\n try {\n challenge = await client.initClaim(projectId);\n } catch (error) {\n const claimed = alreadyClaimedDetails(error);\n if (claimed) {\n return this.alreadyClaimed({ project_id: projectId, ...claimed });\n }\n if (isClaimWindowExpired(error)) {\n this.recordTelemetry({ claim_outcome: \"window_expired\" });\n throw claimWindowExpiredError();\n }\n throw error;\n }\n\n // A local server left on the default public base advertises a claim page\n // on a remote origin — the exact confusion this warning names. Cloud\n // servers legitimately use a console origin different from the API one,\n // so only a loopback API paired with a non-loopback claim page warns.\n if (isLoopbackUrl(this.meta.source) && !isLoopbackUrl(challenge.claim_url)) {\n reportWarning(\n `The server at ${this.meta.source} advertised a claim page on ${new URL(challenge.claim_url).origin}. ` +\n \"If you started that server yourself, set NEXTGEN_SERVER_PUBLIC_BASE to its reachable origin (e.g. http://localhost:8080).\",\n );\n }\n\n // Always show the link first, before attempting anything: it is the whole\n // instruction on its own, so a launch that never happens (headless box,\n // no `xdg-open`, `--no-open`, an agent) needs no separate path.\n //\n // The URL prints as a bare line under the frame rather than inside it:\n // it must never be split (clickability, and the journey e2e scrape reads\n // it out of the narration), and consola pads every box line to the\n // longest one, so a ~110-character URL inside the box would re-break the\n // frame on any terminal narrower than the URL itself. `wrapForBox` keeps\n // the frame's own content inside the terminal width.\n consola.box({\n title: \"Finish in your browser\",\n message: wrapForBox(\n \"Create an account or sign in to claim your Project, make it permanent and start collaborating.\",\n ),\n style: { padding: 1, borderStyle: \"rounded\", borderColor: \"cyan\" },\n });\n consola.log(challenge.claim_url);\n\n if (flags[\"no-wait\"]) {\n return this.linkIssued(projectId, challenge);\n }\n\n const skipLaunch = flags[\"no-open\"] || nonInteractive;\n opened = skipLaunch ? false : (await openInBrowser(challenge.claim_url)).opened;\n if (!opened) {\n consola.info(\"Open the link above to continue.\");\n }\n waitFor = {\n challengeId: challenge.challenge_id,\n deadline: claimDeadline({\n expiresAt: challenge.expires_at,\n timeoutSeconds: flags.timeout,\n now: Date.now(),\n }),\n };\n } else {\n // Resuming mints nothing: the link is already with whoever opens it, so\n // this run only waits on it.\n waitFor = {\n challengeId,\n deadline: claimDeadline({ timeoutSeconds: flags.timeout, now: Date.now() }),\n };\n }\n consola.start(\"Waiting for the browser step to finish\");\n\n const completed = await this.poll(\n client,\n projectId,\n waitFor.challengeId,\n waitFor.deadline,\n startOver,\n );\n\n // Record the completed claim only in a `.zitadel/secret` that is this\n // project's own record: writing it into a secret that describes a different\n // project would conflate environments, marking the fallback project claimed\n // when another was. An env-supplied project keeps no local cache — the\n // platform grant is the durable record, and a rerun resolves it through the\n // idempotent already-claimed response rather than a stale local one.\n if (localRecord) {\n await writeZitadelSecret(cwd, {\n ...localRecord,\n claimed_at: completed.claimed_at,\n team_id: completed.team_id,\n });\n }\n // The team id stays out of the human output by design (it lives in the\n // envelope and .zitadel/secret); the user-facing outcome is permanence.\n consola.success(\"Project claimed\");\n\n this.recordTelemetry({ claim_outcome: \"completed\", browser_opened: opened });\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Your Project is now permanent.\",\n project_id: projectId,\n team_id: completed.team_id,\n claimed_at: completed.claimed_at,\n dashboard_url: completed.dashboard_url,\n // Two entries so the pretty renderer puts the URL on its own line.\n next_actions: [\n \"Manage your Project and collaborate in the Console:\",\n completed.dashboard_url,\n ],\n },\n });\n }\n\n /**\n * Polls `claim/status` until the browser leg lands or the link dies.\n *\n * The two failure modes read the same to a user (the link no longer works,\n * start another one), so they share an error shape and differ only in\n * wording — a `410` means the platform expired it, a passed deadline means\n * we stopped waiting first. `startOver` is how this run gets a new link.\n */\n private async poll(\n client: ZitadelClient,\n projectId: string,\n challengeId: string,\n deadline: number,\n startOver: SuggestedCommand,\n ): Promise<{ team_id: string; claimed_at: string; dashboard_url: string }> {\n let interval = INITIAL_POLL_MS;\n let polls = 0;\n\n while (Date.now() < deadline) {\n polls += 1;\n try {\n const status = await client.getClaimStatus(projectId, { challenge_id: challengeId });\n if (status.status === \"completed\") {\n this.recordTelemetry({ poll_count: polls });\n return status;\n }\n } catch (error) {\n // The window can close between init and poll (a challenge minted in\n // the window's last minutes); the status route reports that as its\n // own 410 code, and it must not read as the retryable link expiry.\n if (isClaimWindowExpired(error)) {\n this.recordTelemetry({ claim_outcome: \"window_expired\", poll_count: polls });\n throw claimWindowExpiredError();\n }\n if (error instanceof ApiError && error.status === 410) {\n this.recordTelemetry({ claim_outcome: \"expired\", poll_count: polls });\n throw expiredError(\"The link expired before the browser step finished.\", startOver);\n }\n // Only a resumed wait can name a challenge the platform never minted\n // for this project.\n if (isChallengeNotFound(error)) {\n this.recordTelemetry({ claim_outcome: \"not_found\", poll_count: polls });\n throw new ZitadelError(\n \"E_NOT_FOUND\",\n \"This project has no claim link with that challenge id.\",\n { hint: \"Start a new link.\", nextCommands: [startOver] },\n );\n }\n if (error instanceof ApiError && error.status === 429) {\n // Polled too eagerly. Back off to the ceiling immediately rather\n // than easing towards it, so a rate limit is never compounded.\n interval = MAX_POLL_MS;\n } else {\n this.recordTelemetry({ poll_count: polls });\n throw error;\n }\n }\n\n // Never sleep past the deadline: the last wait should end the loop, not\n // overshoot it by up to a full interval.\n const remaining = deadline - Date.now();\n if (remaining <= 0) {\n break;\n }\n await sleep(Math.min(interval, remaining));\n interval = Math.min(interval * POLL_BACKOFF_FACTOR, MAX_POLL_MS);\n }\n\n this.recordTelemetry({ claim_outcome: \"timeout\", poll_count: polls });\n throw expiredError(\"Stopped waiting for the browser step to finish.\", startOver);\n }\n\n /**\n * The `--no-wait` result: the link a person has to open, and the command\n * that waits for them to finish. Nothing is claimed yet, so nothing is\n * recorded in `.zitadel/secret`.\n */\n private linkIssued(\n projectId: string,\n challenge: { claim_url: string; challenge_id: string; expires_at: string },\n ): JsonEnvelope {\n this.recordTelemetry({ claim_outcome: \"link_issued\" });\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Open the link in a browser to make your Project permanent.\",\n project_id: projectId,\n claim_url: challenge.claim_url,\n challenge_id: challenge.challenge_id,\n expires_at: challenge.expires_at,\n next_actions: [\"Wait for the browser step to finish with:\"],\n // The id comes from the server, so it reaches a command an agent may\n // run only in the contract's own shape, which a shell reads as one word.\n ...nextCommandsData(\n isChallengeId(challenge.challenge_id)\n ? [this.suggest(`claim --challenge-id ${challenge.challenge_id}`)]\n : [],\n ),\n },\n });\n }\n\n /**\n * The idempotent outcome: the project already belongs to a team, whether we\n * learned that locally or from a `409`. Reported as a skip, not an error, so\n * re-running the command (or an agent retrying it) is a clean no-op.\n */\n private alreadyClaimed(data: {\n project_id: string;\n team_id: string;\n claimed_at?: string;\n dashboard_url?: string;\n }): JsonEnvelope {\n this.recordTelemetry({ claim_outcome: \"already_claimed\" });\n consola.info(`This project already belongs to team ${data.team_id}.`);\n return this.emit({\n status: \"skipped\",\n reason: \"already-claimed\",\n data: { title: \"Zitadel project already belongs to a team.\", ...data },\n });\n }\n}\n\n/**\n * Extracts the owning team from a `409 proj.already_claimed` envelope. Reads\n * the body defensively rather than casting to the generated type: this is the\n * one place a malformed error body would otherwise turn a clean skip into a\n * crash.\n */\nfunction alreadyClaimedDetails(\n error: unknown,\n): { team_id: string; dashboard_url?: string } | undefined {\n if (!(error instanceof ApiError) || error.status !== 409 || !isObject(error.body)) {\n return undefined;\n }\n const details = error.body.details;\n if (!isObject(details) || typeof details.team_id !== \"string\") {\n return undefined;\n }\n return {\n team_id: details.team_id,\n dashboard_url: typeof details.dashboard_url === \"string\" ? details.dashboard_url : undefined,\n };\n}\n\n/**\n * A `410 proj.claim_window_expired` from `claim/init`: the project outlived\n * domain.ClaimWindow before anyone claimed it. Distinct from the plain 410 the\n * poll maps to \"the link expired\", which a new link fixes; this one nothing\n * fixes.\n */\nfunction isClaimWindowExpired(error: unknown): boolean {\n return (\n error instanceof ApiError &&\n error.status === 410 &&\n isObject(error.body) &&\n error.body.code === \"proj.claim_window_expired\"\n );\n}\n\n/** Whether `value` has the shape the claim contract gives a `challenge_id`. */\nfunction isChallengeId(value: string): boolean {\n return getClaimStatusQueryChallengeIdRegExp.test(value);\n}\n\n/** A `404 claim_challenge.not_found` from `claim/status`. */\nfunction isChallengeNotFound(error: unknown): boolean {\n return (\n error instanceof ApiError &&\n error.status === 404 &&\n isObject(error.body) &&\n error.body.code === \"claim_challenge.not_found\"\n );\n}\n\nfunction expiredError(message: string, claimAgain: SuggestedCommand): ZitadelError {\n return new ZitadelError(\"E_VALIDATION\", message, {\n hint: \"Links are valid for 10 minutes. Start a new one.\",\n nextCommands: [claimAgain],\n });\n}\n\n/**\n * Deliberately not the retryable \"start a new link\" shape: a new challenge\n * cannot fix a closed window, so suggesting `claim` again would send the\n * user in a circle.\n */\nfunction claimWindowExpiredError(): ZitadelError {\n return new ZitadelError(\n \"E_VALIDATION\",\n `This project was not claimed within ${CLAIM_WINDOW_DAYS} days of creation, so it can no longer be claimed.`,\n {\n hint: \"The project still works for now, but it stays temporary and its data may be lost. To get a claimable project, run `zitadel setup` in a fresh directory (here it would just skip as already initialized) and claim the new one within the window.\",\n },\n );\n}\n","import { pbkdf2Sync, randomBytes } from \"node:crypto\";\nimport { mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { defaultHumanUserSchemaUrl } from \"@zitadel/config\";\n\nimport { ZitadelError } from \"../errors\";\nimport { enforceMode } from \"../fs-safe\";\nimport { isObject } from \"../json\";\nimport {\n findUpward,\n LOCAL_RUNTIME_DIR,\n PLATFORM_PROJECT_ID,\n readRuntimeMetadata,\n sameLocalServer,\n} from \"./runtime\";\nimport { shellCommand, unscopedCommand } from \"../suggestion\";\n\n/**\n * The local admin's two files under `.zitadel/local/` (gitignored):\n *\n * - `admin.json` — the credential the CLI keeps: email, generated password, ids.\n * - `admin-user.json` — the server's bootstrap user document, passed to the\n * binary as `--user-file`. Carries a PBKDF2 hash, never the password.\n *\n * The password is never printed. It exists so the CLI can sign the developer in\n * (see `sign-in.ts`) without them registering on their own server.\n */\nexport const LOCAL_ADMIN_FILE = `${LOCAL_RUNTIME_DIR}/admin.json`;\nexport const LOCAL_ADMIN_USER_FILE = `${LOCAL_RUNTIME_DIR}/admin-user.json`;\n\n/** The local admin's sign-in identifier; the default user schema identifies users by email. */\nexport const LOCAL_ADMIN_EMAIL = \"admin@zitadel.localhost\";\n\nconst ADMIN_USER_ID = \"user_localadmin\";\nconst ADMIN_TEAM_ID = \"team_localadmin\";\n\nconst PBKDF2_ROUNDS = 210_000;\n\nexport type LocalAdmin = {\n email: string;\n password: string;\n user_id: string;\n team_id: string;\n};\n\n/** The directory holding the local admin: `cwd`, or the nearest parent `zitadel start` ran in. */\nexport function findLocalAdminDir(cwd: string): Promise<string | undefined> {\n return findUpward(cwd, LOCAL_ADMIN_FILE);\n}\n\n/**\n * The local admin of the server at `serverUrl`: the nearest one, from `cwd`\n * upward, whose `start` recorded that server beside it. An admin beside another\n * server's metadata holds a password this server never imported, so it is\n * passed over.\n */\nexport async function findLocalAdminFor(\n cwd: string,\n serverUrl: string,\n): Promise<LocalAdmin | undefined> {\n for (let from = cwd; ; ) {\n const dir = await findLocalAdminDir(from);\n if (!dir) return undefined;\n const runtime = await readRuntimeMetadata(dir).catch(() => undefined);\n if (runtime && sameLocalServer(runtime.server_url, serverUrl)) {\n return readLocalAdmin(dir);\n }\n if (dir === homedir() || dirname(dir) === dir) return undefined;\n from = dirname(dir);\n }\n}\n\n/** Reads the local admin credential, or `undefined` when `start` never wrote one. */\nexport async function readLocalAdmin(cwd: string): Promise<LocalAdmin | undefined> {\n let raw: string;\n try {\n raw = await readFile(join(cwd, LOCAL_ADMIN_FILE), \"utf8\");\n } catch (error) {\n // Only a missing file means `start` never created the admin. A file that\n // exists but cannot be read is still the credential the server imported,\n // and minting a replacement would leave the two holding different passwords.\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw new ZitadelError(\"E_VALIDATION\", `${LOCAL_ADMIN_FILE} cannot be read`, {\n hint: `Check that ${LOCAL_ADMIN_FILE} is readable by you; \\`zitadel start\\` writes it owner-only.`,\n details: { cause: error instanceof Error ? error.message : String(error) },\n });\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n throw malformedAdminFile(error);\n }\n if (!isLocalAdmin(parsed)) {\n throw malformedAdminFile();\n }\n return parsed;\n}\n\nfunction isLocalAdmin(value: unknown): value is LocalAdmin {\n return (\n isObject(value) &&\n typeof value.email === \"string\" &&\n typeof value.password === \"string\" &&\n typeof value.user_id === \"string\" &&\n typeof value.team_id === \"string\"\n );\n}\n\n/**\n * Recovery needs both halves. `zitadel reset` clears the server's data but keeps\n * `admin.json`, so the next start would read the same broken file; deleting the\n * file alone leaves the server holding a hash of the old password, so the admin\n * could never sign in. Removing the file and resetting the data lets the next\n * start mint a fresh credential and import it.\n */\nfunction malformedAdminFile(cause?: unknown): ZitadelError {\n return new ZitadelError(\"E_VALIDATION\", `${LOCAL_ADMIN_FILE} is malformed`, {\n hint: `Delete ${LOCAL_ADMIN_FILE} and run \\`zitadel reset --force\\`, then \\`zitadel start\\`. Both are needed: reset keeps ${LOCAL_ADMIN_FILE}, and deleting it alone leaves the server holding the old password.`,\n nextCommands: [\n shellCommand(`rm ${LOCAL_ADMIN_FILE}`),\n unscopedCommand(\"reset --force\"),\n unscopedCommand(\"start\"),\n ],\n ...(cause\n ? { details: { cause: cause instanceof Error ? cause.message : String(cause) } }\n : {}),\n });\n}\n\n/**\n * Creates the local admin on first use and (re)writes the server's bootstrap\n * user document, returning the credential and the document path for\n * `--user-file`. The server imports the user once; later starts skip it because\n * the user already exists, so the stored password stays valid.\n *\n * `builtinSchemaBase` is the server's `schema.builtin_public_base`, when the\n * environment overrides it. The platform project's default user schema is\n * published under that base, and a document naming a schema the server does\n * not have is bootstrapped against an empty placeholder — the admin could\n * never sign in.\n */\nexport async function ensureLocalAdmin(\n cwd: string,\n builtinSchemaBase?: string,\n): Promise<{ admin: LocalAdmin; userFile: string }> {\n await mkdir(join(cwd, LOCAL_RUNTIME_DIR), { recursive: true, mode: 0o700 });\n\n const admin = (await readLocalAdmin(cwd)) ?? (await createLocalAdmin(cwd));\n\n // Readable beyond the owner, unlike admin.json: the docker runtime mounts\n // this document into a container running as the host user, and an unreadable\n // file fails the server's bootstrap import at startup. It carries a hash.\n // Written beside it and renamed into place: a concurrent start may be\n // launching a server that reads this document, and a rename is atomic where\n // an in-place rewrite is not.\n const userFile = join(cwd, LOCAL_ADMIN_USER_FILE);\n const schemaUrl = defaultHumanUserSchemaUrl(builtinSchemaBase || undefined);\n // Unique per write, not per process: two starts in one process (or a retry)\n // must not rename each other's staging file away.\n const staging = `${userFile}.${randomBytes(6).toString(\"hex\")}.tmp`;\n await writeFile(\n staging,\n `${JSON.stringify(bootstrapUserDocument(admin, schemaUrl), null, 2)}\\n`,\n {\n mode: 0o644,\n },\n );\n await enforceMode(staging, 0o644);\n await rename(staging, userFile);\n\n return { admin, userFile };\n}\n\n/**\n * Mints the credential, or adopts the one a concurrent `zitadel start` in this\n * directory minted first. The write is exclusive so the two cannot each mint a\n * password and leave the bootstrap document holding the loser's hash.\n */\nasync function createLocalAdmin(cwd: string): Promise<LocalAdmin> {\n const candidate: LocalAdmin = {\n // A fixed, clearly-local identity rather than anything inferred from Git\n // config, which can carry a stale, work, or noreply address.\n email: LOCAL_ADMIN_EMAIL,\n password: randomBytes(24).toString(\"base64url\"),\n user_id: ADMIN_USER_ID,\n team_id: ADMIN_TEAM_ID,\n };\n\n const path = join(cwd, LOCAL_ADMIN_FILE);\n const won = await writePrivateIfAbsent(path, `${JSON.stringify(candidate, null, 2)}\\n`);\n return won ? candidate : ((await readLocalAdmin(cwd)) ?? candidate);\n}\n\n/** Writes owner-only, reporting `false` when another run got there first. */\nasync function writePrivateIfAbsent(path: string, content: string): Promise<boolean> {\n try {\n await writeFile(path, content, { mode: 0o600, flag: \"wx\" });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"EEXIST\") return false;\n throw error;\n }\n await enforceMode(path, 0o600);\n return true;\n}\n\nfunction bootstrapUserDocument(admin: LocalAdmin, schemaUrl: string) {\n return {\n header: {\n project_id: PLATFORM_PROJECT_ID,\n team_id: admin.team_id,\n schema_url: schemaUrl,\n id: admin.user_id,\n },\n attributes: {\n username: admin.email,\n email: admin.email,\n \"zitadel.source\": \"cli\",\n \"zitadel.default_user\": true,\n },\n authenticators: {\n password: { encoded_hash: pbkdf2Hash(admin.password), change_required: false },\n },\n };\n}\n\n/**\n * passlib's `$pbkdf2-sha256$rounds$salt$hash`, which passwap verifies on the\n * server (`internal/crypto/passwap.go`). Salt and digest use passlib's adapted\n * base64: `+` becomes `.` and the padding is dropped.\n */\nfunction pbkdf2Hash(password: string): string {\n const salt = randomBytes(16);\n const hash = pbkdf2Sync(password, salt, PBKDF2_ROUNDS, 32, \"sha256\");\n return `$pbkdf2-sha256$${String(PBKDF2_ROUNDS)}$${ab64(salt)}$${ab64(hash)}`;\n}\n\nfunction ab64(bytes: Buffer): string {\n return bytes.toString(\"base64\").replace(/=+$/, \"\").replaceAll(\"+\", \".\");\n}\n","import type { VerifyChallengeProofBody } from \"@zitadel/api/generated/model\";\nimport { ApiError, request } from \"@zitadel/api/runtime/fetch\";\n\nimport { createZitadelClient } from \"../api-client\";\nimport { ZitadelError } from \"../errors\";\nimport { interruptSignal } from \"../interrupt\";\nimport { isObject } from \"../json\";\nimport type { LocalAdmin } from \"./admin-credential\";\nimport { PLATFORM_PROJECT_ID, readPlatformRuntime } from \"./runtime\";\nimport { unscopedCommand } from \"../suggestion\";\n\n/**\n * Signing the local admin in without a browser.\n *\n * The auth-attempt API is the state machine the login widget drives; the widget\n * adds the rendering. With no page to render, the CLI states the factors\n * outright: open an attempt, prove the identifier, prove the password, take the\n * one-time `handoff_token`. That token becomes either a console sign-in link or,\n * exchanged, a session cookie.\n */\n\n/**\n * Every call here runs after the server answered `/readyz`, so a stall means a\n * wedged server rather than a slow start. Without a bound, `zitadel start`\n * would hang on a socket that accepts and never answers.\n */\nconst REQUEST_TIMEOUT_MS = 10_000;\n\n/**\n * Per-call request options: the server's own origin, and a fresh timeout (the\n * bound starts when the signal is made, so it cannot be shared across calls).\n */\nexport function localAdminRequest(\n serverUrl: string,\n headers: Record<string, string> = {},\n): RequestInit {\n return {\n headers: { origin: new URL(serverUrl).origin, ...headers },\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n };\n}\n\n/** A console URL that signs the admin in once, via a fresh handoff token. */\nexport async function consoleSignInUrl(serverUrl: string, admin: LocalAdmin): Promise<string> {\n const { handoffToken } = await signIn(serverUrl, admin);\n return `${serverUrl}/ui/console/login?handoff=${encodeURIComponent(handoffToken)}`;\n}\n\n/**\n * Signs in and trades the handoff token for the `__nextgen_session` cookie —\n * the credential endpoints like `claim/complete` authenticate against, which a\n * bare handoff token cannot satisfy.\n */\nexport async function adminSessionCookie(serverUrl: string, admin: LocalAdmin): Promise<string> {\n const { handoffToken, publishableKey } = await signIn(serverUrl, admin);\n\n // The one call made without the generated client: the session comes back\n // only as a Set-Cookie header, which that client does not expose. `request`\n // still types its failures and honours Ctrl-C the way the client does.\n const { res } = await request(\n `${serverUrl}/sessions/exchange?project_id=${encodeURIComponent(PLATFORM_PROJECT_ID)}`,\n {\n ...localAdminRequest(serverUrl, {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${publishableKey}`,\n }),\n method: \"POST\",\n body: JSON.stringify({ handoff_token: handoffToken }),\n },\n { signal: interruptSignal() },\n );\n const cookie = res.headers\n .getSetCookie()\n .find((value) => value.startsWith(\"__nextgen_session=\"))\n ?.split(\";\", 1)[0];\n if (!res.ok || !cookie) {\n throw new ZitadelError(\n \"E_AUTH\",\n `Local admin session exchange failed (${String(res.status)})`,\n {\n details: { status: res.status },\n },\n );\n }\n return cookie;\n}\n\n/**\n * Proves the admin's identifier and password against a fresh auth attempt and\n * returns its terminal handoff token, without exchanging it.\n */\nasync function signIn(\n serverUrl: string,\n admin: LocalAdmin,\n): Promise<{ handoffToken: string; publishableKey: string }> {\n const runtime = await readPlatformRuntime(serverUrl, REQUEST_TIMEOUT_MS);\n if (!runtime) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"The local server does not host the platform project, so the local admin cannot sign in\",\n {\n // `zitadel start` adopts a healthy running server untouched, so it\n // cannot fix this on its own: the server has to stop first.\n hint: \"Stop it with `zitadel stop`, then run `zitadel start` so it boots with the platform project and the local admin.\",\n nextCommands: [unscopedCommand(\"stop\"), unscopedCommand(\"start\")],\n details: { server_url: serverUrl },\n },\n );\n }\n const client = createZitadelClient({ baseUrl: serverUrl, token: runtime.publishable_key });\n\n const { attempt_id } = await client.createAuthAttempt(\n { project_id: PLATFORM_PROJECT_ID },\n localAdminRequest(serverUrl),\n );\n // Just the value: the server resolves it against the platform project's\n // designated identifier — the default user schema designates `email`, the\n // attribute the bootstrap document writes — rather than a property the\n // client names.\n await prove(client, serverUrl, attempt_id, \"identifier\", { login_name: admin.email });\n await prove(client, serverUrl, attempt_id, \"password\", { password: admin.password });\n\n const { handoff_token } = await client.createHandoff(attempt_id, localAdminRequest(serverUrl));\n return { handoffToken: handoff_token, publishableKey: runtime.publishable_key };\n}\n\n/**\n * Issues a challenge for one factor and answers it. The proof must carry the\n * challenge just issued: the server rejects a proof against a re-issued\n * challenge, so the two calls belong together.\n */\nasync function prove(\n client: ReturnType<typeof createZitadelClient>,\n serverUrl: string,\n attemptId: string,\n method: \"identifier\" | \"password\",\n proof: VerifyChallengeProofBody,\n): Promise<void> {\n const { challenge_id } = await client.issueChallenge(\n attemptId,\n { method },\n localAdminRequest(serverUrl),\n );\n try {\n await client.verifyChallengeProof(attemptId, challenge_id, proof, localAdminRequest(serverUrl));\n } catch (error) {\n if (method === \"identifier\" && isProofRejected(error)) {\n throw adminNotFound();\n }\n throw error;\n }\n}\n\nfunction isProofRejected(error: unknown): boolean {\n return (\n error instanceof ApiError && isObject(error.body) && error.body.code === \"att.proof_rejected\"\n );\n}\n\n/**\n * A rejected identifier usually means this server never imported the admin — a\n * data directory from before the local admin existed. But the server reports a\n * failed lookup with the same code, so the message names both causes, and the\n * command it suggests is the harmless one: the reset that fixes the first cause\n * deletes local data, so it stays a hint a person reads, never a next command\n * an agent runs.\n */\nfunction adminNotFound(): ZitadelError {\n return new ZitadelError(\"E_AUTH\", \"The local server could not find the local admin\", {\n hint: \"Check `zitadel logs` first: a server that failed the lookup reports it the same way. If the logs show no error, the local data directory predates the local admin — `zitadel reset --force` deletes the local data so `zitadel start` can import it again.\",\n nextCommands: [unscopedCommand(\"logs\")],\n });\n}\n","import { Flags } from \"@oclif/core\";\nimport consola from \"consola\";\n\nimport { openInBrowser } from \"../lib/browser\";\nimport { ZitadelError } from \"../lib/errors\";\nimport { findLocalAdminDir, readLocalAdmin } from \"../lib/local-server/admin-credential\";\nimport { consoleSignInUrl } from \"../lib/local-server/sign-in\";\nimport { DEFAULT_LOCAL_SERVER_URL, readRuntimeMetadata } from \"../lib/local-server/runtime\";\nimport { LocalServer } from \"../lib/local-server/server\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\n\n/**\n * `zitadel console` — open the local console signed in as the local\n * admin `zitadel start` created. Every run mints a fresh one-time link, so the\n * command is also how you get back in after the session ends.\n */\nexport default class Console extends BaseCommand {\n static override description =\n \"Open the local console, signed in as the local admin.\\n\\nThe local admin is the one `zitadel start` created. Run this in the directory `zitadel start` ran in, or one inside it: the local admin is read from the nearest `.zitadel/local/` on the way up.\";\n static override group = CommandGroups.localDevelopment;\n static override groupOrder = 1;\n\n static override examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --no-open\",\n ];\n\n static override flags = {\n \"no-open\": Flags.boolean({\n description: \"Print the sign-in link instead of opening a browser.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Console);\n const cwd = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n // `start` may have run in a parent of the app directory; its runtime\n // metadata sits beside the admin it created.\n const localDir = (await findLocalAdminDir(cwd)) ?? cwd;\n const runtime = await readRuntimeMetadata(localDir);\n await this.toMeta(flags, {\n resolveServer: false,\n source: runtime?.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n\n const admin = await readLocalAdmin(localDir);\n if (!admin) {\n throw new ZitadelError(\"E_VALIDATION\", \"No local admin in this directory or its parents\", {\n hint: \"Run this from the directory `zitadel start` ran in, or one inside it. If the server was never started, run `zitadel start` first; it creates the local admin the console signs in as.\",\n nextCommands: [this.suggestUnscoped(\"start\")],\n });\n }\n\n // A link is minted by running the real login flow, which burns a one-time\n // handoff token on the server — a mutation, so a dry run only reports who\n // it would sign in as.\n if (this.meta.dryRun) {\n consola.info(`Would mint a console sign-in link for ${admin.email}.`);\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local console sign-in link.\",\n signed_in_as: admin.email,\n dry_run: true,\n },\n });\n }\n\n const serverUrl = await LocalServer.resolveUrl(localDir);\n const signInUrl = await consoleSignInUrl(serverUrl, admin);\n\n consola.log(`Signed in to the local console as ${admin.email}:`);\n consola.log(signInUrl);\n const skipLaunch = flags[\"no-open\"] || this.meta.nonInteractive;\n const opened = skipLaunch ? false : (await openInBrowser(signInUrl)).opened;\n if (!opened) {\n consola.info(\"Open the link above. It works once; run this command again for a new one.\");\n }\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local console sign-in link.\",\n signed_in_as: admin.email,\n sign_in_url: signInUrl,\n browser_opened: opened,\n next_actions: [\"The link signs you in once. Run `zitadel console` again for a fresh one.\"],\n },\n });\n }\n}\n","/** One of a project's origins, as the API returns it and `.zitadel/secret` records it. */\nexport type ProjectOrigin = Readonly<{ pattern: string; kind: string }>;\n\n/**\n * The stored pattern of `issuer` when a project holds it as a preview origin\n * and has no primary one, or `undefined`.\n *\n * That is how `zitadel setup` 0.1.0 registered the app's own URL; setup now\n * registers it as primary. A deploy lands only on primary origins, so such a\n * project has nowhere to deploy, and `origin add <issuer> --kind primary` is\n * refused because the pattern is already stored with another kind\n * (`origin.kind_conflict`): it has to be removed and added back as primary.\n */\nexport function issuerHeldAsPreview(\n origins: ReadonlyArray<ProjectOrigin>,\n issuer: string,\n): string | undefined {\n if (origins.some((origin) => origin.kind === \"primary\")) {\n return undefined;\n }\n const wanted = originOf(issuer);\n return origins.find((origin) => origin.kind === \"preview\" && originOf(origin.pattern) === wanted)\n ?.pattern;\n}\n\n/** The origins `.zitadel/secret` records, in the shape the API returns them. */\nexport function recordedOrigins(secret: {\n primary_origins: readonly string[];\n preview_origins: readonly string[];\n}): ProjectOrigin[] {\n return [\n ...secret.primary_origins.map((pattern) => ({ pattern, kind: \"primary\" })),\n ...secret.preview_origins.map((pattern) => ({ pattern, kind: \"preview\" })),\n ];\n}\n\n/**\n * A URL as its origin, the form a stored pattern takes, so an issuer written\n * `http://localhost:3000/` matches the stored `http://localhost:3000`. A value\n * that is not a URL is returned as written.\n */\nexport function originOf(value: string): string {\n return URL.canParse(value) ? new URL(value).origin : value;\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport {\n buildBundle,\n createDeployment,\n DEPLOY_ARGS,\n createReleaseFromBundle,\n diffStep,\n headSha,\n listLiveDeployments,\n runSteps,\n servesPrimary,\n type StepContext,\n validateStep,\n worktreeIsDirty,\n} from \"../lib/release\";\nimport { ApiError } from \"@zitadel/api/runtime/fetch\";\n\nimport { ZitadelError } from \"../lib/errors\";\nimport { issuerHeldAsPreview, originOf, type ProjectOrigin } from \"../lib/origins\";\nimport { readZitadelSecret } from \"../lib/project\";\nimport { shellArg } from \"../lib/shell\";\nimport { type EnvironmentSelector, projectCommand } from \"../lib/suggestion\";\nimport { reportWarning } from \"../lib/warnings\";\nimport { nextCommandsData } from \"../lib/oclif/envelope\";\n\n/**\n * `zitadel deploy` — publish `.zitadel/` to the project's primary origins.\n *\n * It assembles a release bundle from the files on disk, validates it and syncs\n * identity-provider connections, shows what changed since the live release as a\n * git diff, then creates the release and deploys it to every primary origin\n * (primary origins are never named one by one). `--dry-run` stops after the\n * diff, writing nothing to the server.\n *\n * It replaces `plan` and `apply`: a release is published as one immutable unit\n * and deployed, rather than each resource being synced in place.\n */\n\nexport default class Deploy extends EnvironmentCommand {\n static override description =\n \"Apply your local configuration to Zitadel.\\n\\nBuilds a release from .zitadel/ and deploys it to the project. Use --dry-run to preview what would change.\";\n static override group = CommandGroups.configuration;\n static override groupOrder = 1;\n static override examples = [\n \"<%= config.bin %> deploy -m 'add phone_number to human-user'\",\n \"<%= config.bin %> deploy --dry-run\",\n ];\n static override flags = {\n message: Flags.string({\n char: \"m\",\n description: \"A short summary of what this release changes.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Deploy);\n await this.toMeta(flags);\n const { cwd, env, dryRun, isTTY, nonInteractive } = this.meta;\n const json = this.jsonEnabled();\n const color = !json && isTTY && flags.color !== false && !process.env.NO_COLOR;\n\n // A deploy records why it happened. Interactively the reason can be left\n // off, but a non-interactive caller (CI) has no prompt to fall back on, so\n // it must name one. Rejected here, before the pipeline writes anything, so\n // a missing message never leaves a half-synced IdP behind. A dry run makes\n // no release, so it is exempt.\n const message = flags.message?.trim() ? flags.message.trim() : undefined;\n if (nonInteractive && !dryRun && message === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"A deploy needs a message in non-interactive mode\", {\n hint: \"Pass -m/--message with a short summary of what this release changes.\",\n });\n }\n\n const { client, projectId } = await this.connect();\n\n // The origins this deploy lands on, for the optimistic guard below.\n let landing: string[] = [];\n if (!dryRun) {\n // The deploy goes to every primary origin, so the project must have at\n // least one. Checked here, before the bundle is built and the IdP\n // connections are synced, so a project with no primary origin fails\n // before the IdP step does a partial write rather than after it, when the\n // final deploy would report the missing origin. A dry run writes nothing\n // and never reaches the deploy, so it is exempt: it still validates and\n // previews a project that has no primary origin yet.\n const origins = (await client.getProject(projectId)).origins ?? [];\n landing = origins.filter((entry) => entry.kind === \"primary\").map((entry) => entry.pattern);\n if (landing.length === 0) {\n throw noPrimaryOriginError({\n origins,\n issuer: this.environment.values.ZITADEL_ISSUER?.value,\n setupProject: (await setupProjectId(cwd)) === projectId,\n selector: this.environmentSelector(),\n cliVersion: this.meta.cliVersion,\n });\n }\n }\n\n const { bundle, resourceCount, brandingSources, idpFiles, policyFiles } =\n await buildBundle(cwd);\n this.recordTelemetry({ resources: resourceCount });\n const ctx: StepContext = {\n cwd,\n client,\n projectId,\n env,\n mode: \"deploy\",\n dryRun,\n json,\n color,\n bundle,\n brandingSources,\n idpFiles,\n policyFiles,\n suggest: (args) => this.suggest(args),\n };\n\n // Before-release steps: validate, sync IdPs (validated and previewed but\n // not written on a dry run), diff.\n await runSteps([validateStep, diffStep], ctx);\n\n if (dryRun) {\n return this.emit({\n status: \"ok\",\n data: {\n dry_run: true,\n resources: resourceCount,\n targets: [\"primary\"],\n },\n pretty: `Validated ${resourceCount} resource${resourceCount === 1 ? \"\" : \"s\"}. Nothing was deployed (dry run).`,\n });\n }\n\n // Record whether the whole worktree was dirty when this release was built,\n // and warn: a release pins content, but its git provenance is only exact\n // when the tree was clean, so the reader knows the commit is approximate.\n const gitDirty = await worktreeIsDirty(cwd);\n if (gitDirty) {\n reportWarning(\n \"The git working tree has uncommitted changes; this release records its commit as approximate.\",\n );\n }\n\n const release = await createReleaseFromBundle(client, projectId, bundle, {\n message,\n gitSha: await headSha(cwd),\n gitDirty,\n });\n\n // What the targets serve right now. The guard id is the newest deployment\n // to any origin this deploy lands on — the contract's rule — so a live\n // preview, which never targets a primary, is never it. It guards the\n // create against another deploy that raced in since we inspected: the\n // server refuses with 409 rather than overwriting that deploy unseen (#538).\n const live = await listLiveDeployments(client, projectId);\n const observed = live.find((deployment) =>\n deployment.targets.some((entry) => landing.includes(entry.origin)),\n )?.id;\n const targets = [\"primary\"];\n let deployment: Awaited<ReturnType<typeof createDeployment>>;\n try {\n deployment = await createDeployment(client, projectId, {\n releaseId: release.id,\n targets,\n message,\n // On a project's first deploy nothing is live, so there is no\n // deployment to guard against: the field is omitted rather than sent\n // empty or as a placeholder, which an optional id cannot stand in for.\n // When a deployment is live its id is sent so a racing deploy is caught\n // with a 409 (#538).\n ...(observed === undefined ? {} : { expectedDeploymentId: observed }),\n });\n } catch (error) {\n // A 409 means another deploy landed between our inspection and this\n // create. Re-read what the targets serve now and report that actual\n // deployment, so the caller re-runs against current state (#538).\n if (!(error instanceof ApiError) || error.status !== 409) {\n throw error;\n }\n // Building dedupes on content, revoked releases included, so a tree\n // that matches a revoked release builds back to it and cannot deploy.\n // That is not a race: re-running would fail the same way.\n if (errorCode(error) === \"rel.revoked\") {\n throw new ZitadelError(\n \"E_CONFLICT\",\n `This content was already released as ${release.id}, which is revoked`,\n {\n hint: \"A revoked release can never be served again. Change the configuration so it builds a new release, then deploy.\",\n details: { release_id: release.id, content_hash: release.content_hash },\n },\n );\n }\n // The deployment that raced in on a primary origin, not a live preview.\n const current = (await listLiveDeployments(client, projectId)).find(servesPrimary);\n throw new ZitadelError(\n \"E_CONFLICT\",\n \"Another deploy changed the targets since this one was prepared\",\n {\n hint: `Re-run \\`zitadel ${DEPLOY_ARGS}${this.environmentSelector()}\\`; it will build and deploy against the current state.`,\n details: current === undefined ? undefined : { current_deployment: current },\n nextCommands: [this.suggest(\"deployment list --live\")],\n },\n );\n }\n\n const servedOrigins = deployment.targets.map((target) => target.origin);\n this.recordTelemetry({ origin_count: servedOrigins.length });\n return this.emit({\n status: \"ok\",\n data: {\n release_id: release.id,\n content_hash: release.content_hash,\n deployment_id: deployment.id,\n resources: resourceCount,\n origins: servedOrigins,\n ...nextCommandsData([this.suggest(\"deployment list\")]),\n },\n pretty: [\n `Deployed ${release.content_hash}`,\n ` ${resourceCount} resource${resourceCount === 1 ? \"\" : \"s\"} to ${servedOrigins.length} origin${servedOrigins.length === 1 ? \"\" : \"s\"}`,\n ...servedOrigins.map((served) => ` - ${served}`),\n ].join(\"\\n\"),\n });\n }\n}\n\n/** The `code` of an API error body, when it carries one. */\nfunction errorCode(error: ApiError): string | undefined {\n const body = error.body;\n return typeof body === \"object\" &&\n body !== null &&\n typeof (body as { code?: unknown }).code === \"string\"\n ? (body as { code: string }).code\n : undefined;\n}\n\n/**\n * The error for a deploy with no primary origin to land on, naming the step\n * that gives this project one. A project `zitadel setup` 0.1.0 created holds\n * its issuer as a preview origin, which `origin add --kind primary` refuses as\n * a conflict: `doctor --fix` makes it primary for the project\n * `.zitadel/secret` records, the one doctor repairs, and any other project\n * removes the pattern and adds it back. Otherwise the issuer is added as\n * primary, or the URL the developer fills in when no issuer resolves.\n */\nexport function noPrimaryOriginError(input: {\n origins: ReadonlyArray<ProjectOrigin>;\n /** The resolved environment's `ZITADEL_ISSUER`, the URL the app serves from. */\n issuer: string | undefined;\n /** Whether the deploy targets the project `.zitadel/secret` records. */\n setupProject: boolean;\n selector: EnvironmentSelector;\n cliVersion: string;\n}): ZitadelError {\n const message = \"The project has no primary origin to deploy to\";\n const suggest = (args: string) => projectCommand(args, input.selector, input.cliVersion);\n const preview =\n input.issuer === undefined ? undefined : issuerHeldAsPreview(input.origins, input.issuer);\n if (preview !== undefined) {\n const held = `It holds its issuer ${preview} as a preview origin, as \\`zitadel setup\\` 0.1.0 registered it, so adding it as primary conflicts.`;\n if (input.setupProject) {\n const doctor = suggest(\"doctor --fix\");\n return new ZitadelError(\"E_VALIDATION\", message, {\n hint: `${held} Run \\`${doctor}\\` to make it primary, then deploy.`,\n nextCommands: [doctor],\n });\n }\n const remove = suggest(`origin rm ${shellArg(preview)} --force`);\n const add = suggest(`origin add ${shellArg(preview)} --kind primary`);\n return new ZitadelError(\"E_VALIDATION\", message, {\n hint: `${held} Remove it with \\`${remove}\\`, add it back with \\`${add}\\`, then deploy.`,\n nextCommands: [remove, add],\n });\n }\n if (input.issuer !== undefined) {\n const add = suggest(`origin add ${shellArg(originOf(input.issuer))} --kind primary`);\n return new ZitadelError(\"E_VALIDATION\", message, {\n hint: `Add the URL the app serves from with \\`${add}\\`, then deploy.`,\n nextCommands: [add],\n });\n }\n return new ZitadelError(\"E_VALIDATION\", message, {\n // Named in the text, not as a next command: the URL is the developer's to\n // fill in, and a `<url>` placeholder is a shell redirection.\n hint: `Add one with \\`zitadel origin add <url> --kind primary${input.selector}\\`, then deploy.`,\n nextCommands: [suggest(\"origin list\")],\n });\n}\n\n/** The project `.zitadel/secret` records, or nothing when it cannot be read. */\nasync function setupProjectId(cwd: string): Promise<string | undefined> {\n return readZitadelSecret(cwd).then(\n (secret) => secret.project_id,\n () => undefined,\n );\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { createDeployment } from \"../../lib/release\";\nimport { nextCommandsData } from \"../../lib/oclif/envelope\";\n\n/**\n * `zitadel deployment create --release <id>` — make an existing release live.\n *\n * The low-level counterpart of `deploy`: it deploys a release that already\n * exists rather than assembling one from `.zitadel/`. By default it targets\n * every primary origin: primary origins are never named one by one. Deploying\n * the release a target already serves changes nothing.\n */\nexport default class DeploymentCreate extends EnvironmentCommand {\n static override description = \"Deploy an existing release to the project's origins.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> deployment create --release rel_01KX3RG8A7F0N9WD3P2E4YM5C1\",\n ];\n static override flags = {\n release: Flags.string({ description: \"The release id to deploy.\", required: true }),\n message: Flags.string({ char: \"m\", description: \"A short summary of why this deploys.\" }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(DeploymentCreate);\n await this.toMeta(flags);\n\n const targets = [\"primary\"];\n\n // A dry run makes no request, so it answers before the connection — the\n // order `origin add`/`deploy` use, which keeps the no-mutation promise\n // literal: deploying an existing release writes a deployment record, and a\n // dry run must write none.\n if (this.meta.dryRun) {\n return this.emit({\n status: \"ok\",\n data: { dry_run: true, release_id: flags.release, targets },\n pretty: `Would deploy ${flags.release} to ${targets.join(\", \")}. Nothing was deployed (dry run).`,\n });\n }\n\n const { client, projectId } = await this.connect();\n\n const deployment = await createDeployment(client, projectId, {\n releaseId: flags.release,\n targets,\n message: flags.message,\n });\n\n const origins = deployment.targets.map((target) => target.origin);\n return this.emit({\n status: \"ok\",\n data: {\n deployment_id: deployment.id,\n release_id: deployment.release_id,\n origins,\n ...nextCommandsData([this.suggest(\"deployment list\")]),\n },\n pretty: [\n `Deployed ${deployment.release_id} to ${origins.length} origin${origins.length === 1 ? \"\" : \"s\"}`,\n ...origins.map((origin) => ` - ${origin}`),\n ].join(\"\\n\"),\n });\n }\n}\n","import { CommandGroups, EnvironmentCommand, type JsonEnvelope, nonBlankArg } from \"../../lib/oclif\";\n\n/**\n * `zitadel deployment get <deployment_id>` — read one deployment record: the\n * release it made live, the origins it went to, and when.\n */\nexport default class DeploymentGet extends EnvironmentCommand {\n static override description = \"Read one deployment by id.\";\n static override group = CommandGroups.configuration;\n static override examples = [\"<%= config.bin %> deployment get dep_01KX5N7C9D2E7F0N9WD3P2E4YM6\"];\n static override args = {\n deployment_id: nonBlankArg({ required: true, description: \"The deployment to read.\" }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(DeploymentGet);\n await this.toMeta(flags);\n const { client, projectId } = await this.connect();\n\n const deployment = await client.getDeploymentById(args.deployment_id, {\n project_id: projectId,\n });\n\n const origins = deployment.targets.map((target) => target.origin);\n return this.emit({\n status: \"ok\",\n data: deployment,\n pretty: [\n `${deployment.id}`,\n ` release ${deployment.release_id}`,\n ` reason ${deployment.metadata.reason ?? \"deploy\"}`,\n ` deployed ${deployment.deployed_at}`,\n ` origins ${origins.join(\", \")}`,\n ].join(\"\\n\"),\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport {\n CommandGroups,\n EnvironmentCommand,\n type JsonEnvelope,\n nonBlankString,\n} from \"../../lib/oclif\";\nimport { collectPages } from \"../../lib/oclif/crud/paging\";\nimport { renderList } from \"../../lib/oclif/crud/table\";\nimport { listData } from \"../../lib/oclif/envelope\";\nimport { shellArg } from \"../../lib/shell\";\n\n/** The columns `list` renders, in order. */\nconst COLUMNS = [\"id\", \"release_id\", \"reason\", \"origins\", \"deployed_at\"] as const;\n\n/** A deployment as the list endpoint returns it, narrowed to what the table reads. */\ntype DeploymentRow = {\n id: string;\n release_id: string;\n metadata: { reason?: string };\n targets: { origin: string }[];\n deployed_at: string;\n};\n\n/**\n * `zitadel deployment list` — show the project's deployment history.\n *\n * Newest first: what went live where, and when. `--origin` narrows it to one\n * origin's history; `--live` shows what each target serves now instead of the\n * full history. Like every list verb it fetches one page and reports\n * `next_page_token`; `--all` drains the history, `--limit` / `--page-token`\n * walk it a page at a time.\n */\nexport default class DeploymentList extends EnvironmentCommand {\n static override description = \"List the project's deployments, newest first.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> deployment list\",\n \"<%= config.bin %> deployment list --all\",\n \"<%= config.bin %> deployment list --live\",\n \"<%= config.bin %> deployment list --origin https://app.acme.com\",\n ];\n static override flags = {\n origin: Flags.string({ description: \"Only deployments that targeted this origin.\" }),\n live: Flags.boolean({ description: \"What each target serves now, not the full history.\" }),\n limit: Flags.integer({\n description: \"Page size (server default 20, max 100).\",\n min: 1,\n max: 100,\n }),\n \"page-token\": nonBlankString({\n description: \"Continue from a previous page's next_page_token.\",\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Fetch every page instead of one.\",\n exclusive: [\"page-token\"],\n }),\n plain: Flags.boolean({\n description:\n \"Tab-separated rows with no header, for piping. Implied when stdout is not a terminal.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(DeploymentList);\n await this.toMeta(flags);\n const { client, projectId } = await this.connect();\n\n const request = (token?: string): Promise<unknown> =>\n client.listDeployments({\n project_id: projectId,\n ...(flags.origin === undefined ? {} : { origin: flags.origin }),\n ...(flags.live ? { live: true } : {}),\n ...(flags.limit === undefined ? {} : { limit: flags.limit }),\n ...(token === undefined ? {} : { page_token: token }),\n });\n\n const { items, next } = await collectPages(request, {\n items: \"deployments\",\n all: flags.all === true,\n token: flags[\"page-token\"],\n nextPageToken: \"next_page_token\",\n });\n const deployments = items as DeploymentRow[];\n\n // Flatten each deployment's targets to one `origins` cell for the table.\n const rows = deployments.map((deployment) => ({\n id: deployment.id,\n release_id: deployment.release_id,\n reason: deployment.metadata.reason ?? \"deploy\",\n origins: deployment.targets.map((target) => target.origin).join(\", \"),\n deployed_at: deployment.deployed_at,\n }));\n\n // A page token is only valid alongside the flags that issued it, so the\n // suggested next page repeats the whole invocation rather than a bare\n // token. `--all` already drained everything, so it suggests nothing.\n const nextCommand =\n next && flags.all !== true\n ? this.suggest(\n [\n \"deployment list\",\n ...(flags.origin === undefined ? [] : [`--origin ${shellArg(flags.origin)}`]),\n ...(flags.live ? [\"--live\"] : []),\n ...(flags.limit === undefined ? [] : [`--limit ${flags.limit}`]),\n // `next` is an opaque server cursor: quote it so whitespace or shell\n // metacharacters in a copied command cannot execute as server-controlled\n // text or break the suggestion.\n `--page-token ${shellArg(next)}`,\n \"--json\",\n ].join(\" \"),\n )\n : undefined;\n\n const plain = flags.plain || !process.stdout.isTTY;\n return this.emit({\n status: \"ok\",\n data: listData(deployments, {\n nextPageToken: next,\n nextCommands: nextCommand === undefined ? undefined : [nextCommand],\n }),\n pretty: renderList(COLUMNS, rows, {\n plain,\n singular: \"deployment\",\n empty: \"No deployments yet.\",\n footer: next ? [`More available: --page-token ${shellArg(next)} (or --all)`] : [],\n }),\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\nimport type { ZitadelClient } from \"@zitadel/api/client\";\nimport type {\n GetReleaseById200PointersItem,\n ListDeployments200DeploymentsItem,\n} from \"@zitadel/api/generated/model\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope, nonBlankArg } from \"../../lib/oclif\";\nimport { collectPages } from \"../../lib/oclif/crud/paging\";\nimport { renderTable } from \"../../lib/oclif/crud/table\";\nimport { listLiveDeployments, rollbackDeployment, servesPrimary } from \"../../lib/release\";\nimport { toZitadelError, ZitadelError } from \"../../lib/errors\";\nimport { Promptable } from \"../../lib/oclif/promptable\";\nimport { reportWarning } from \"../../lib/warnings\";\n\n/**\n * `zitadel deployment rollback [<deployment_id>]` — re-apply an earlier\n * deployment.\n *\n * Bare, it undoes the last deploy: it re-applies the deployment that was live\n * before the current one. Given a `<deployment_id>`, it re-applies exactly that\n * one. A rollback re-serves an earlier release, so it takes the `--force`-or-confirm\n * gate the destructive commands use. It reports the revisions that release\n * pins, and that users keep theirs: configuration rolls back, user data does\n * not.\n */\nexport default class DeploymentRollback extends Promptable(EnvironmentCommand) {\n static override description = \"Roll back to an earlier deployment.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> deployment rollback\",\n \"<%= config.bin %> deployment rollback dep_01KX5N7C9D2E7F0N9WD3P2E4YM6\",\n \"<%= config.bin %> deployment rollback --force\",\n ];\n static override args = {\n deployment_id: nonBlankArg({\n required: false,\n description: \"The deployment to re-apply. Omit to undo the last deploy.\",\n }),\n };\n static override flags = {\n force: Flags.boolean({\n char: \"f\",\n description: \"Roll back without the confirmation prompt. Required when non-interactive.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(DeploymentRollback);\n await this.toMeta(flags);\n const { dryRun } = this.meta;\n\n const { client, projectId } = await this.connect();\n\n // Bare: undo the latest deployment by re-applying what its targets served\n // before it. With an id, re-apply exactly that one.\n let targetId = args.deployment_id as string | undefined;\n // The bare form decides from one read of the history, so its guard comes\n // from that same read: a deploy landing after it is one the caller never\n // saw, and must make the server refuse rather than become the expected one.\n let bareGuard: string | undefined;\n if (targetId === undefined) {\n // The prior deployment of a long-lived origin can sit beyond the\n // server's first page, so the whole history is drained rather than the\n // default page searched — otherwise a bare rollback would miss a target\n // further back and refuse a rollback it should resolve.\n const { items } = await collectPages(\n (token) =>\n client.listDeployments({\n project_id: projectId,\n ...(token === undefined ? {} : { page_token: token }),\n }),\n { items: \"deployments\", all: true, nextPageToken: \"next_page_token\" },\n );\n // A preview deployment is never the deploy a bare rollback undoes, nor\n // one it can restore: the server refuses to roll one back. Primary\n // deployments make one history for the project, newest first.\n const history = (items as ListDeployments200DeploymentsItem[]).filter(servesPrimary);\n const [latest, prior] = history;\n if (!latest) {\n throw new ZitadelError(\"E_VALIDATION\", \"There is no deployment to roll back\", {\n hint: `Nothing has been deployed yet; check \\`zitadel deployment list${this.environmentSelector()}\\`.`,\n });\n }\n if (!prior) {\n throw new ZitadelError(\"E_VALIDATION\", \"There is no earlier deployment to roll back to\", {\n hint: `Name a deployment to re-apply, or check \\`zitadel deployment list${this.environmentSelector()}\\`.`,\n });\n }\n targetId = prior.id;\n bareGuard = latest.id;\n }\n\n // A dry run re-applies nothing, so it stops once the target is resolved,\n // before the destructive-confirm gate and the write: a rollback re-serves\n // an earlier release, and a dry run must leave what is served untouched.\n if (dryRun) {\n return this.emit({\n status: \"ok\",\n data: { dry_run: true, deployment_id: targetId },\n pretty: `Would re-apply ${targetId}. Nothing was rolled back (dry run).`,\n });\n }\n\n // The deployment the caller currently sees live: the project's newest\n // primary deployment, which is what the server compares against. Read before the\n // confirmation gate and passed through as the optimistic guard, so a\n // deploy that lands while the prompt is open (or between this read and the\n // write in non-interactive mode) makes the server answer 409 rather than\n // letting the rollback overwrite a change the caller never saw. Omitted\n // when nothing is live there, which an optional id cannot stand in for.\n const expectedDeploymentId = bareGuard ?? (await liveGuard(client, projectId));\n\n const confirmed = await this.input({\n kind: \"confirm\",\n name: `re-apply ${targetId}`,\n message: `Re-apply ${targetId}? Its release goes live again.`,\n retry: this.suggest(`deployment rollback ${targetId} --force`),\n });\n if (!confirmed) {\n return this.emit({ status: \"skipped\", reason: \"rollback-cancelled\" });\n }\n\n const deployment = await rollbackDeployment(client, projectId, targetId, {\n ...(expectedDeploymentId === undefined ? {} : { expectedDeploymentId }),\n });\n\n let pointers: readonly GetReleaseById200PointersItem[] | undefined;\n try {\n pointers = (await client.getReleaseById(deployment.release_id, { project_id: projectId }))\n .pointers;\n } catch (error) {\n reportWarning(\n `Rolled back, but the revisions ${deployment.release_id} pins could not be read: ${toZitadelError(error).message}`,\n );\n }\n\n const origins = deployment.targets.map((target) => target.origin);\n return this.emit({\n status: \"ok\",\n data: {\n deployment_id: deployment.id,\n release_id: deployment.release_id,\n rolled_back_to: deployment.metadata.rollback_to,\n origins,\n ...(pointers === undefined ? {} : { pointers }),\n },\n pretty: [\n `Rolled back to ${deployment.release_id} on ${origins.join(\", \")}`,\n ...(pointers === undefined\n ? []\n : [\"\", renderTable([\"kind\", \"handle\", \"revision_id\"], pointers)]),\n \"\",\n \"Users keep the schema revision and attributes they have: a rollback does not migrate them back.\",\n ].join(\"\\n\"),\n });\n }\n}\n\n/** The project's newest primary deployment, which a rollback is guarded by. */\nasync function liveGuard(client: ZitadelClient, projectId: string): Promise<string | undefined> {\n return (await listLiveDeployments(client, projectId)).find(servesPrimary)?.id;\n}\n","import { readFile, realpath } from \"node:fs/promises\";\nimport { dirname, join, resolve } 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 dependencySpecProvablyBelow}.\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 `minimum` (a version such as `15` or `15.2.3`) or newer: a valid semver\n * range with no overlap with `>=minimum-0`. Everything unprovable returns\n * `undefined` — protocol specs (`file:`, `link:`, `workspace:`, git URLs),\n * dist-tags (`latest`, `canary`), absent deps, and ranges that also admit a\n * compliant version (`>=14`, `14 || 16`, `^15.0.0` for `15.2.3`). A range\n * that explicitly names a prerelease at or above the floor (`15.0.0-rc.0`,\n * `16.0.0-rc.1` for the 15 floor) is not rejected; ranges like `<15.2.3`\n * resolve no prerelease of it. For an exact floor (`15.2.3`) a prerelease of\n * that very release (`15.2.3-canary.0`) predates it and is rejected.\n */\nexport function dependencySpecProvablyBelow(\n pkg: PackageJson,\n name: string,\n minimum: string,\n): string | undefined {\n const spec = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name];\n const floor = semver.coerce(minimum);\n if (!spec || !floor || semver.validRange(spec) === null) {\n return undefined;\n }\n // A prerelease floor (`2.0.0-beta.45`) is itself the bound: a range is judged\n // by whether npm can resolve that version or a newer one. A prerelease is\n // resolvable only through a comparator set that names a prerelease of the\n // same base version, so `<2.0.0` admits no beta and is refused.\n if (isPrereleaseFloor(minimum)) {\n return admitsAtOrAbovePrereleaseFloor(spec, minimum, floor) ? undefined : spec;\n }\n if (semver.intersects(spec, `>=${floor.version}`)) {\n return undefined;\n }\n return declaresPrereleaseAtOrAbove(spec, floor, isExactFloor(minimum)) ? undefined : spec;\n}\n\n/** Whether `spec` can resolve `minimum` (a prerelease such as `2.0.0-beta.45`) or newer under npm's rules. */\nfunction admitsAtOrAbovePrereleaseFloor(\n spec: string,\n minimum: string,\n floor: semver.SemVer,\n): boolean {\n if (semver.intersects(spec, `>=${floor.version}`)) {\n return true;\n }\n return new semver.Range(spec).set.some((comparators) => {\n const range = comparators.map((comparator) => comparator.value).join(\" \");\n return comparators.some(({ semver: version }) => {\n const base = `${version.major}.${version.minor}.${version.patch}`;\n if (version.prerelease.length === 0 || semver.lt(base, floor.version)) {\n return false;\n }\n const lower = semver.gt(`${base}-0`, minimum) ? `${base}-0` : minimum;\n return semver.intersects(range, `>=${lower} <${base}`, { includePrerelease: true });\n });\n });\n}\n\n/**\n * Whether `spec` admits a prerelease whose base version is at or above the\n * floor (`15.3.0-canary.1`, `16.0.0-rc.1`, `15.0.0-rc.0` for a 15 floor).\n * npm resolves a prerelease only for a comparator set that spells out a\n * prerelease of the same base version, so each such comparator names a base to\n * probe; the set admits one when it overlaps that base's prerelease window,\n * `[base-0, base)`. That holds for strict bounds too: `>15.2.3-canary.1\n * <15.2.3` admits `15.2.3-canary.2` though neither endpoint does.\n */\nfunction declaresPrereleaseAtOrAbove(spec: string, floor: semver.SemVer, exact: boolean): boolean {\n return new semver.Range(spec).set.some((comparators) => {\n const range = comparators.map((comparator) => comparator.value).join(\" \");\n return comparators.some(({ semver: version }) => {\n const base = `${version.major}.${version.minor}.${version.patch}`;\n return (\n version.prerelease.length > 0 &&\n (exact ? semver.gt(base, floor) : semver.gte(base, floor)) &&\n semver.intersects(range, `>=${base}-0 <${base}`, { includePrerelease: true })\n );\n });\n });\n}\n\n/**\n * Whether `minimum` names one exact release (`15.2.3`) rather than a major or\n * minor line (`18`, `1.6`). A prerelease of a line's first version (`18.0.0-rc.0`)\n * counts as at-floor, but a prerelease of an exact release (`15.2.3-canary.0`)\n * predates it, and for a security floor that means predates the fix.\n */\nfunction isExactFloor(minimum: string): boolean {\n return semver.valid(minimum) !== null;\n}\n\n/** Whether `minimum` is itself a prerelease (`2.0.0-beta.45`), so it is the bound as written. */\nfunction isPrereleaseFloor(minimum: string): boolean {\n return (semver.prerelease(minimum)?.length ?? 0) > 0;\n}\n\n/** A package found in `node_modules`: its version and the manifest it was read from. */\nexport type InstalledPackage = { version: string; path: string };\n\n/** Whether `dir` is the root of a workspace, above which no app's dependencies are installed. */\nasync function isWorkspaceRoot(dir: string): Promise<boolean> {\n if (\n await readFile(join(dir, \"pnpm-workspace.yaml\")).then(\n () => true,\n () => false,\n )\n ) {\n return true;\n }\n try {\n const { workspaces } = JSON.parse(await readFile(join(dir, \"package.json\"), \"utf8\")) as {\n workspaces?: unknown;\n };\n return workspaces !== undefined && workspaces !== null;\n } catch {\n return false;\n }\n}\n\n/**\n * The package `name` installed for the app at `cwd`: the `package.json` that\n * Node's own lookup reaches first, walking up from `cwd` through each\n * `node_modules`, so a hoisted install in a monorepo counts too. The walk ends\n * after the workspace root (a directory with `pnpm-workspace.yaml` or a\n * `package.json` `workspaces` field) or the filesystem root, so a stray\n * `node_modules` above the project is never mistaken for the app's install.\n * `undefined` when nothing is installed there, or the file names no valid version.\n */\nexport async function installedPackage(\n cwd: string,\n name: string,\n): Promise<InstalledPackage | undefined> {\n let dir = await realpath(resolve(cwd)).catch(() => resolve(cwd));\n for (;;) {\n const path = join(dir, \"node_modules\", name, \"package.json\");\n const contents = await readFile(path, \"utf8\").catch(() => undefined);\n if (contents !== undefined) {\n const version = versionIn(contents);\n return version === undefined ? undefined : { version, path };\n }\n const parent = dirname(dir);\n if (parent === dir || (await isWorkspaceRoot(dir))) {\n return undefined;\n }\n dir = parent;\n }\n}\n\n/** The version of `name` installed for the app at `cwd`; see {@link installedPackage}. */\nexport async function installedVersion(cwd: string, name: string): Promise<string | undefined> {\n return (await installedPackage(cwd, name))?.version;\n}\n\n/** The valid semver `version` a `package.json` declares, if any. */\nfunction versionIn(contents: string): string | undefined {\n try {\n const { version } = JSON.parse(contents) as { version?: unknown };\n return typeof version === \"string\" ? (semver.valid(version) ?? undefined) : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Returns the installed package `name` for the app at `cwd` when it is older\n * than `minimum`. A range such as `^15.0.0` passes {@link dependencySpecProvablyBelow}\n * because it can resolve to a supported release, but the lockfile may still hold\n * an older one; this judges what actually runs. Nothing installed returns\n * `undefined`, leaving the declared spec as the only gate. A prerelease of a\n * major-only floor (`18`) is not below it; a prerelease of an exact floor\n * (`15.2.3-canary.0`) is, and a prerelease floor (`2.0.0-beta.45`) is the bound\n * as written, as for the spec.\n */\nexport async function installedVersionBelow(\n cwd: string,\n name: string,\n minimum: string,\n): Promise<InstalledPackage | undefined> {\n const installed = await installedPackage(cwd, name);\n const floor = semver.coerce(minimum);\n if (installed === undefined || !floor) {\n return undefined;\n }\n const bound = isPrereleaseFloor(minimum)\n ? minimum\n : isExactFloor(minimum)\n ? floor.version\n : `${floor.version}-0`;\n return semver.lt(installed.version, bound) ? installed : undefined;\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 }\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 {\n dependencySpecProvablyBelow,\n installedVersionBelow,\n type PackageJson,\n} from \"./package-json\";\nimport type { Detector } from \"./types\";\n\n/**\n * The one place a framework version floor is enforced (ADR 043). Each detector\n * declares its `versionFloor` and `versionPackage`; its `detect` calls this\n * once it has recognised the project, so `setup` and `doctor` share a single\n * loud gate and no detector carries its own checking logic.\n *\n * Throws `E_UNSUPPORTED_PROJECT_SHAPE` only for a provable violation: a\n * declared spec that cannot resolve to the floor or newer, or an installed\n * release older than the floor (a range such as `^15.0.0` can still be locked\n * to an older one). Protocol specs and dist-tags pass, a prerelease of a\n * major-only floor counts as at-floor (of an exact floor, it is below), and a newer major is never refused. With nothing\n * installed the declared spec is the only gate.\n */\nexport async function enforceVersionFloor(\n detector: Pick<Detector, \"displayName\" | \"versionPackage\" | \"versionFloor\" | \"versionFloorNote\">,\n pkg: PackageJson,\n cwd: string,\n): Promise<void> {\n const { displayName, versionPackage, versionFloor, versionFloorNote } = detector;\n const hint = [`Upgrade the app to ${displayName} ${versionFloor} or later and rerun.`]\n .concat(versionFloorNote ?? [])\n .join(\" \");\n const supported = `the CLI integrates ${displayName} ${versionFloor} and newer`;\n\n const declared = dependencySpecProvablyBelow(pkg, versionPackage, versionFloor);\n if (declared !== undefined) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n `${displayName} \"${declared}\" is below the supported floor — ${supported}`,\n { hint },\n );\n }\n\n const installed = await installedVersionBelow(cwd, versionPackage, versionFloor);\n if (installed !== undefined) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n `${displayName} ${installed.version} is installed (${installed.path}), below the supported floor — ${supported}`,\n { hint },\n );\n }\n}\n","import { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\nimport { enforceVersionFloor } from \"./version-floor\";\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 project\n * below the declared floor fails fast with `E_UNSUPPORTED_PROJECT_SHAPE` instead of scaffolding files\n * that won't compile.\n */\nexport class AngularDetector implements Detector {\n readonly framework = \"angular\";\n readonly displayName = \"Angular\";\n readonly versionPackage = \"@angular/core\";\n readonly versionFloor = \"17\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, this.versionPackage)) {\n return null;\n }\n\n await enforceVersionFloor(this, pkg, cwd);\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 { dependencyVersionMajor, hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\nimport { enforceVersionFloor } from \"./version-floor\";\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 readonly displayName = \"Next.js\";\n readonly versionPackage = \"next\";\n readonly versionFloor = \"15.2.3\";\n readonly versionFloorNote = \"Earlier releases let a request skip middleware (CVE-2025-29927).\";\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 await enforceVersionFloor(this, pkg, cwd);\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\";\nimport { enforceVersionFloor } from \"./version-floor\";\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` is the Nuxt srcDir. Nuxt 4 keeps `app.vue`/`pages/`/`plugins/` under\n * `app/` but still honours a root-layout app: like Nuxt itself, it falls back to\n * the root when `app/` is absent and the root holds `assets`, `layouts`,\n * `middleware`, `pages` or `plugins`. A fresh project gets `app/`.\n */\nexport class NuxtDetector implements Detector {\n readonly framework = \"nuxt\";\n readonly displayName = \"Nuxt\";\n readonly versionPackage = \"nuxt\";\n readonly versionFloor = \"4\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, this.versionPackage)) {\n return null;\n }\n\n await enforceVersionFloor(this, pkg, cwd);\n\n const appDir = await detectSrcDir(cwd);\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"nuxt\", appDir, devPort, url: issuerFromPort(devPort) };\n }\n}\n\nasync function detectSrcDir(cwd: string): Promise<string> {\n if (await dirExists(join(cwd, \"app\"))) {\n return \"app\";\n }\n for (const dir of [\"assets\", \"layouts\", \"middleware\", \"pages\", \"plugins\"]) {\n if (await dirExists(join(cwd, dir))) {\n return \".\";\n }\n }\n return \"app\";\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\";\nimport { enforceVersionFloor } from \"./version-floor\";\n\n/**\n * Detects a Vite + Qwik 2 single-page app: depends on `@qwik.dev/core` and\n * `vite` but NOT `@qwik.dev/router` (Qwik's meta-framework, formerly Qwik City,\n * is its own thing and ships Qwik). `@zitadel/sdk-qwik` requires Qwik 2, so a\n * Qwik 1 app (`@builder.io/qwik`) is intentionally not matched — it would get an\n * incompatible SDK peer. 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 readonly displayName = \"Qwik\";\n readonly versionPackage = \"@qwik.dev/core\";\n readonly versionFloor = \"2.0.0-beta.45\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"@qwik.dev/router\") ||\n !hasDependency(pkg, this.versionPackage) ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n await enforceVersionFloor(this, pkg, cwd);\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"qwik\", 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\";\nimport { enforceVersionFloor } from \"./version-floor\";\n\n/**\n * Detects a Qwik Router project on Qwik 2: depends on both `@qwik.dev/core` and\n * `@qwik.dev/router` (the meta-framework, renamed from `@builder.io/qwik-city`\n * in Qwik 2). Like Next.js and SvelteKit, Qwik Router proxies the auth backend and\n * verifies the session through a server entrypoint (`@zitadel/sdk-qwik-router`) —\n * here the `onRequest` plugin in `src/routes/plugin@nextgen.ts`, a plain route\n * file — not a Vite dev-server proxy.\n *\n * A Qwik 1 app (`@builder.io/qwik` + `@builder.io/qwik-city`) is intentionally\n * not matched, like the Qwik detector: its pages render the `@zitadel/sdk-qwik`\n * widgets, which require Qwik 2, so it would get an SDK it cannot install.\n *\n * Runs before the Qwik detector (which excludes `@qwik.dev/router`) since Qwik\n * Router ships Qwik — so a Qwik Router project is never mistaken for a bare Qwik\n * SPA. Routes/managed files live under `src` (`src/routes`).\n */\nexport class QwikRouterDetector implements Detector {\n readonly framework = \"qwik-router\";\n readonly displayName = \"Qwik Router\";\n readonly versionPackage = \"@qwik.dev/router\";\n readonly versionFloor = \"2.0.0-beta.45\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, \"@qwik.dev/core\") || !hasDependency(pkg, \"@qwik.dev/router\")) {\n return null;\n }\n\n await enforceVersionFloor(this, pkg, cwd);\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"qwik-router\", appDir: \"src\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { dependencyVersionMajor, hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\nimport { enforceVersionFloor } from \"./version-floor\";\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 * or `@tanstack/react-start` — Next.js and TanStack Start both ship React too,\n * so their detectors must run first (and do, by registry order) and this\n * detector excludes them so a meta-framework app is never seen as a bare SPA.\n */\nexport class ReactDetector implements Detector {\n readonly framework = \"react\";\n readonly displayName = \"React\";\n readonly versionPackage = \"react\";\n readonly versionFloor = \"18\";\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, \"@tanstack/react-start\") ||\n !hasDependency(pkg, this.versionPackage) ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n await enforceVersionFloor(this, pkg, cwd);\n\n const devPort = await detectDevPort(cwd, pkg);\n const versionMajor = dependencyVersionMajor(pkg, this.versionPackage);\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\";\nimport { enforceVersionFloor } from \"./version-floor\";\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 readonly displayName = \"Solid\";\n readonly versionPackage = \"solid-js\";\n readonly versionFloor = \"1.6\";\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, this.versionPackage) ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n await enforceVersionFloor(this, pkg, cwd);\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\";\nimport { enforceVersionFloor } from \"./version-floor\";\n\n/**\n * Detects a SolidStart project by its `solid-js` AND `@solidjs/start`\n * dependencies. Like Next.js and Nuxt, SolidStart proxies the auth backend and\n * verifies the session through server middleware (`@zitadel/sdk-solid-start`),\n * not a Vite dev-server proxy — so the patcher wires `src/middleware.ts` and\n * file-based routes.\n *\n * Runs before the Solid detector (which excludes `@solidjs/start`) since\n * SolidStart ships Solid — so a SolidStart project is never mistaken for a bare\n * Solid SPA. Routes/managed files live under `src` (`src/routes`,\n * `src/middleware.ts`).\n */\nexport class SolidStartDetector implements Detector {\n readonly framework = \"solid-start\";\n readonly displayName = \"SolidStart\";\n readonly versionPackage = \"@solidjs/start\";\n readonly versionFloor = \"2\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, \"solid-js\") || !hasDependency(pkg, \"@solidjs/start\")) {\n return null;\n }\n\n // SolidStart 1 registers middleware in app.config.ts and has no\n // vite.config, which the patch edits; refuse up front with a clear reason\n // instead of failing later on a missing config file.\n await enforceVersionFloor(this, pkg, cwd);\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"solid-start\", 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\";\nimport { enforceVersionFloor } from \"./version-floor\";\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 readonly displayName = \"Svelte\";\n readonly versionPackage = \"svelte\";\n readonly versionFloor = \"5\";\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, this.versionPackage) ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n await enforceVersionFloor(this, pkg, cwd);\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\";\nimport { enforceVersionFloor } from \"./version-floor\";\n\n/**\n * Detects a SvelteKit project by its `@sveltejs/kit` dependency. Like Next.js\n * and Nuxt, SvelteKit proxies the auth backend and verifies the session through\n * a server hook (`@zitadel/sdk-sveltekit`), not a Vite dev-server proxy — so the\n * patcher wires `src/hooks.server.ts` and file-based routes.\n *\n * Runs before the Svelte detector (which excludes SvelteKit) since SvelteKit\n * ships Svelte — so a SvelteKit project is never mistaken for a bare Svelte SPA.\n * Routes/managed files live under `src` (`src/routes`, `src/hooks.server.ts`).\n * SvelteKit 3 is the floor: the hook reads its settings from `$app/env/private`,\n * which SvelteKit 2 does not have.\n */\nexport class SvelteKitDetector implements Detector {\n readonly framework = \"sveltekit\";\n readonly displayName = \"SvelteKit\";\n readonly versionPackage = \"@sveltejs/kit\";\n readonly versionFloor = \"3\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, \"@sveltejs/kit\")) {\n return null;\n }\n\n await enforceVersionFloor(this, pkg, cwd);\n\n // The widgets come from @zitadel/sdk-svelte, which peers Svelte 5 and is\n // written with runes; a Svelte 4 app cannot install or compile it.\n await enforceVersionFloor(\n { displayName: \"Svelte\", versionPackage: \"svelte\", versionFloor: \"5\" },\n pkg,\n cwd,\n );\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"sveltekit\", 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\";\nimport { enforceVersionFloor } from \"./version-floor\";\n\n/**\n * Detects a TanStack Start project by its `@tanstack/react-start` dependency\n * (alongside `react`). TanStack Start runs on Vite + React, so the\n * {@link import(\"./react\").ReactDetector} would also match — this detector must\n * run first (and does, by registry order), and the React detector excludes\n * `@tanstack/react-start` so a TanStack Start app is never mistaken for a bare\n * Vite + React SPA.\n *\n * Like Next.js and SvelteKit, TanStack Start proxies the auth backend and\n * verifies the session through a server entrypoint — here the\n * `@zitadel/sdk-tanstack-start` request middleware registered in `src/start.ts`\n * — so the patcher wires that file and file-based routes under `src`.\n */\nexport class TanStackStartDetector implements Detector {\n readonly framework = \"tanstack-start\";\n readonly displayName = \"TanStack Start\";\n readonly versionPackage = \"@tanstack/react-start\";\n readonly versionFloor = \"1.168.10\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, \"react\") || !hasDependency(pkg, \"@tanstack/react-start\")) {\n return null;\n }\n\n await enforceVersionFloor(this, pkg, cwd);\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"tanstack-start\", 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\";\nimport { enforceVersionFloor } from \"./version-floor\";\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 readonly displayName = \"Vue\";\n readonly versionPackage = \"vue\";\n readonly versionFloor = \"3.2\";\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, this.versionPackage) ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n await enforceVersionFloor(this, pkg, cwd);\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 { QwikRouterDetector } from \"./qwik-router\";\nimport { ReactDetector } from \"./react\";\nimport { SolidDetector } from \"./solid\";\nimport { SolidStartDetector } from \"./solid-start\";\nimport { SvelteDetector } from \"./svelte\";\nimport { SvelteKitDetector } from \"./sveltekit\";\nimport { TanStackStartDetector } from \"./tanstack-start\";\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 so a\n * meta-framework project is never mistaken for a bare SPA: Next before React,\n * TanStack Start before React, Nuxt before Vue (Vue excludes Nuxt), SolidStart\n * before Solid, SvelteKit before Svelte, and Qwik Router before Qwik (each base\n * SPA detector excludes its meta-framework).\n */\nexport const detectors = [\n new NextDetector(),\n new NuxtDetector(),\n new TanStackStartDetector(),\n new ReactDetector(),\n new VueDetector(),\n new SolidStartDetector(),\n new SolidDetector(),\n new SvelteKitDetector(),\n new SvelteDetector(),\n new QwikRouterDetector(),\n new QwikDetector(),\n new AngularDetector(),\n] as const satisfies ReadonlyArray<Detector>;\n","import { ZitadelError } from \"../../../errors\";\nimport { isObject, parseJsonObject, setTopLevelJsonKey } from \"../../../json\";\nimport type { FileOp } from \"./file-writer/types\";\n\n/**\n * Sets `key` in a dotenv file to `value`, rewriting its first assignment in\n * place or appending one. Unlike the `merge-env` op, which only adds missing\n * keys, this replaces a value: moving the dev port has to change the\n * `ZITADEL_ISSUER` setup wrote. Every other line stays as it was.\n */\nexport function envValueEdit(key: string, value: string): (source: string | undefined) => string {\n const assignment = new RegExp(`^(\\\\s*(?:export\\\\s+)?${key}\\\\s*=).*$`, \"m\");\n return (source) => {\n const existing = source ?? \"\";\n if (assignment.test(existing)) {\n return existing.replace(assignment, (_line, prefix: string) => `${prefix}${value}`);\n }\n const eol = existing.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n const separator = existing === \"\" || existing.endsWith(\"\\n\") ? \"\" : eol;\n return `${existing}${separator}${key}=${value}${eol}`;\n };\n}\n\n/**\n * Moves `zitadel.json` from one issuer to another: the development issuer and\n * any preview `issuer_pattern` equal to the old issuer. Only the\n * `environments` value is rewritten, so the rest of the file keeps its bytes.\n */\nexport function configIssuerEdit(\n previousIssuer: string,\n issuer: string,\n): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"zitadel.json was not found\", {\n hint: \"Run `zitadel setup` first.\",\n });\n }\n const config = parseJsonObject(source, \"zitadel.json\");\n const environments = isObject(config.environments) ? config.environments : {};\n const development = isObject(environments.development) ? environments.development : {};\n const next: Record<string, unknown> = {\n ...environments,\n development: { ...development, issuer },\n };\n if (isObject(environments.preview) && Array.isArray(environments.preview.issuer_pattern)) {\n next.preview = {\n ...environments.preview,\n issuer_pattern: replaceOrigin(environments.preview.issuer_pattern, previousIssuer, issuer),\n };\n }\n if (JSON.stringify(next) === JSON.stringify(environments)) {\n return source;\n }\n return setTopLevelJsonKey(source, \"zitadel.json\", \"environments\", next);\n };\n}\n\n/**\n * `patterns` with `previous` replaced by `next` (kept once, in place), or\n * `next` appended when `previous` is absent. Non-string entries pass through.\n */\nexport function replaceOrigin(\n patterns: ReadonlyArray<unknown>,\n previous: string,\n next: string,\n): unknown[] {\n const out: unknown[] = [];\n let placed = false;\n for (const pattern of patterns) {\n if (pattern === previous || pattern === next) {\n if (!placed) {\n out.push(next);\n placed = true;\n }\n continue;\n }\n out.push(pattern);\n }\n if (!placed) {\n out.push(next);\n }\n return out;\n}\n\n/** The `.env.local` op that points the app's `ZITADEL_ISSUER` at its new origin. */\nexport function envIssuerOp(issuer: string): FileOp {\n return { kind: \"edit\", path: \".env.local\", edit: envValueEdit(\"ZITADEL_ISSUER\", issuer) };\n}\n\n/** The `zitadel.json` op that moves the recorded issuer. */\nexport function configIssuerOp(previousIssuer: string, issuer: string): FileOp {\n return { kind: \"edit\", path: \"zitadel.json\", edit: configIssuerEdit(previousIssuer, issuer) };\n}\n","import { mkdir, readFile, rename, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { ZitadelError } from \"../../../../errors\";\nimport { enforceMode, envLine } from \"../../../../fs-safe\";\nimport { isObject, parseJsonObject, setTopLevelJsonKey, stableStringify } 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(\n abs(opts.cwd, op.path),\n op.entries,\n { comment: op.comment ?? [], mode: op.mode, overwrite: op.overwrite === true },\n opts.dryRun,\n result,\n );\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 const [preferred] = candidates;\n if (preferred === undefined) {\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 // The first candidate is where the file is created when none of them exist.\n let path = preferred;\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 enforceMode(tmp, mode);\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 ?? 0) & 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 enforceMode(path, mode);\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 enforceMode(tmp, opts.mode);\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 {\n comment,\n mode,\n overwrite,\n }: { comment: ReadonlyArray<string>; mode?: number; overwrite: boolean },\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const raw = await readIfExists(path);\n const keyOf = (line: string) => line.match(/^\\s*([A-Za-z_][A-Za-z0-9_]*)=/)?.[1];\n // With `overwrite`, a line holding one of the entries is rewritten in place\n // with this run's value; otherwise the file's own value stands.\n const replaced = overwrite\n ? (raw ?? \"\")\n .split(\"\\n\")\n .map((line) => {\n const key = keyOf(line);\n return key !== undefined && key in entries ? envLine(key, entries[key] as string) : line;\n })\n .join(\"\\n\")\n : raw;\n const existing = replaced ?? \"\";\n const present = new Set(\n existing\n .split(/\\r?\\n/g)\n .map(keyOf)\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 && replaced !== raw) {\n if (!dryRun) {\n await writeFile(path, existing, { mode });\n if (mode !== undefined) {\n await enforceMode(path, mode);\n }\n }\n record(result, path, \"file\", \"update\");\n return;\n }\n if (additions.length === 0) {\n // Nothing to add, but a secret-bearing target (`mode` set) must still have\n // its permissions re-asserted: `writeFile`'s mode applied only when the\n // file was first created and is masked by the umask, so a setup or\n // `doctor --fix` rerun would otherwise leave an existing `.env.*.local` at\n // whatever loose mode it drifted to. Matches how `env add` and\n // `writeZitadelSecret` chmod unconditionally.\n if (mode !== undefined && raw !== undefined && !dryRun) {\n await enforceMode(path, mode);\n }\n result.filesSkipped.push(path);\n return;\n }\n\n const commentLines = comment.map((line) => `# ${line}`);\n const [firstCommentLine] = commentLines;\n const header =\n firstCommentLine !== undefined && !existing.includes(firstCommentLine) ? commentLines : [];\n const block = [...header, ...additions.map(([key, value]) => envLine(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, { mode });\n // `writeFile`'s mode is honoured only when it creates the file and is masked\n // by the umask, so re-assert it when rewriting an existing secret-bearing\n // target too (see the no-additions path above).\n if (mode !== undefined) {\n await enforceMode(path, mode);\n }\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 // A package the app needs at runtime stays in `dependencies`: a dev add never\n // demotes it, because that would break `--omit=dev` installs.\n if (\n op.dev &&\n isObject(current.dependencies) &&\n Object.hasOwn(current.dependencies as Record<string, unknown>, op.name)\n ) {\n result.filesSkipped.push(path);\n return;\n }\n // Only devDependencies -> dependencies moves. peerDependencies and\n // optionalDependencies entries are the developer's and are left alone.\n const other =\n !op.dev && isObject(current.devDependencies)\n ? (current.devDependencies as Record<string, unknown>)\n : undefined;\n const listedInOther = other !== undefined && Object.hasOwn(other, op.name);\n if (deps[op.name] === op.version && !listedInOther) {\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 let contents = setTopLevelJsonKey(\n existing,\n path,\n key,\n sortByKey({ ...deps, [op.name]: op.version }),\n );\n // A package listed in both sections is never intended, and some toolchains\n // refuse it outright (Qwik's starter vite.config.ts throws on start). Move a\n // devDependencies entry the developer already has into dependencies instead\n // of duplicating it.\n if (listedInOther) {\n contents = setTopLevelJsonKey(\n contents,\n path,\n \"devDependencies\",\n Object.fromEntries(Object.entries(other).filter(([name]) => name !== op.name)),\n );\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(Object.entries(value).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)));\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 deployDryRun = publicCliCommand(\"deploy --dry-run\", ctx.cliVersion);\n const deploy = publicCliCommand(\"deploy\", ctx.cliVersion);\n const movePort = movePortCommand(ctx);\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 stable tokens and the forwarded parts are the embedding levers, and\n // they live nowhere an integrator would otherwise look (component source).\n // The docs list their names, so this points there instead of keeping a\n // copy that drifts.\n const themingParagraph =\n \"Theming the widgets from your app: two hooks in your own stylesheet reach into their shadow DOM — the stable `--zl-*` design tokens, set on the element, and the parts `<zitadel-login>` forwards from its inner components as `zitadel-login::part(<atom>-<part>)` (the `card` part of `zl-card` is `zitadel-login::part(card-card)`). Both are listed under \\\"Style the login from your app\\\" in https://preview.zitadel.com/docs/guides/customize-design#style-the-login-from-your-app; any other `--zl-*` variable is internal. 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. The login moves between sign-in and sign-up by itself (its own switch link, and an email it does or does not know), so a heading of your own must follow its `zitadel-flow-step` event, which the SDK wrappers forward: `step.purpose` is `login` while it signs in and `register` while it signs up. When it switches without being asked, the login tells the visitor why itself. To only reword the widget's heading, pass `locales` instead. Page layout around the widget (split screens, hero panes, marketing copy) is your app's code, not a Zitadel template.\";\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({ projectId: process.env.NEXT_PUBLIC_ZITADEL_PROJECT_ID })` from `@zitadel/sdk-next/session` — a no-store client read of the same-origin `/__nextgen/sessions/me?project_id=…` that the session card itself uses. It returns identity only for 200 with a non-empty `user_id` in this app's project, and signed-out for the backend's canonical `401/auth.unauthorized`, `403/sess.project_mismatch` (a session of another project on the same host, such as the console's on localhost) or `404/sess.not_found`; any other response is unknown/error, never signed-out. In Server Components, `auth()` from `@zitadel/sdk-next/server` works too, on every page: the request boundary's `matcher` covers every route, which also makes `protectedRoutes` the one list of routes that need a sign-in (a protected route that a narrower `matcher` leaves out stays public). 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?project_id=<project id>`, naming the project id the app passes to `configureZitadel()` — 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 that `project_id`, and signed-out only for the canonical error envelope `401/auth.unauthorized`, `403/sess.project_mismatch` (a session of another project on the same host, such as the console\\'s on localhost) 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 for what the login collects and how sign-in works (step 3 below). The app files setup generated are yours to change, from the pages to the request boundary that protects routes in a server-rendered app: \\`doctor\\` reports a file you changed as \\`edited\\`, or as \\`adopted\\` once you delete its \\`zitadel-cli: managed-file\\` comment, and \\`doctor --fix\\` restores only a missing file, never one you changed.\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.)\n - Port taken (\\`EADDRINUSE\\`) or another port wanted: run \\`${movePort}\\`. It moves the dev script or dev-server config, \\`ZITADEL_ISSUER\\` and the project's allowed origin together; changing only one of them breaks sign-in.\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 - \\`${deployDryRun}\\`\n - \\`${deploy}\\`\n - Agents: run both with \\`--non-interactive\\`; the publish also needs \\`-m \"<why this release changes>\"\\`, because a non-interactive \\`deploy\\` requires a message (\\`--dry-run\\` is exempt). \\`deploy --dry-run\\` validates flow invariants with the server's own rules and prints the diff **before** anything uploads — fix what it reports and re-run. Leave \\`--json\\` off the dry run to see that diff: its envelope carries only what would be published.\n\n${presentationParagraph}${jsxTypesNote}\n\n${themingParagraph}\n\n${sessionStateParagraph}\n\nMachine-readable dialect (read these before authoring flow or schema edits):\n\n- \\`zitadel.json\\` carries \\`\"$schema\": \"./.zitadel/meta/project.json\"\\`, the schema of the project configuration.\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\\`, \\`sso-auth-method.json\\`) specifies the user-schema dialect (\\`x-auth-methods\\`, \\`x-unique\\`, property constraints).\n- \\`.zitadel/meta/idp-connection.json\\` specifies a provider connection file under \\`.zitadel/idps/\\` (protocol block, credentials as \\`\\${{ NAME }}\\` variable references, claim mapping). A user schema lists the connection slugs it allows under \\`x-auth-methods.sso.providers\\`.\n- The files in \\`.zitadel/meta/\\` are generated by the CLI; do not edit them. After upgrading the CLI, run the new version's \\`doctor --fix\\` (\\`npx @zitadel/cli@<version> doctor --fix\\`) to write its schemas.\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 deployDryRun = publicCliCommand(\"deploy --dry-run\", ctx.cliVersion);\n const deploy = publicCliCommand(\"deploy\", ctx.cliVersion);\n const movePort = movePortCommand(ctx);\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\nIf the dev server's port is taken (\\`EADDRINUSE\\`), or you want another one, move the app with \\`${movePort}\\`: it updates the dev script, \\`ZITADEL_ISSUER\\` and the project's allowed origin together.\n\nThe dev server keeps its terminal busy, so run the commands below from a second terminal in this directory.\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${deployDryRun}\n${deploy}\n\\`\\`\\``;\n}\n\n/** The command that moves the app to another dev port, `<port>` left to fill in. */\nfunction movePortCommand(ctx: PatchContext): string {\n return publicCliCommand(\"setup --dev-port <port>\", ctx.cliVersion);\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 published by `deploy`, 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 (\n plan.ops\n .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 // A repair only adds what is missing: setup may replace its own stale\n // values, but a value the developer changed since (`env add --force`, a\n // prompt's answer) is theirs, so a replayed merge never overwrites.\n .map((op) => (op.kind === \"merge-env\" && op.overwrite ? { ...op, overwrite: false } : op))\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 { META_SCHEMA_DIR, PROJECT_FILE_SCHEMA_REF } from \"@zitadel/config/meta-schemas\";\n\nimport { stableStringify } from \"../../../json\";\nimport { projectMetaSchemas } from \"../../../meta-schemas\";\nimport { DEFAULT_SERVER } from \"../../../server\";\nimport { portFromIssuer } from \"../../detectors/port\";\nimport { configIssuerOp, envIssuerOp } from \"./dev-port-move\";\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 * Closes every {@link AbstractRulePatcher.preflight} refusal. `--force` is the\n * obvious next try after an `E_CONFLICT`, and it changes nothing there.\n */\nexport const PREFLIGHT_FORCE_NOTE =\n \"--force can't fix this: it only replaces files at the paths setup writes.\";\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 */\n/**\n * Written above the scaffolded entries in `.env.example` and `.env.local`.\n * `zitadel start` hands every `NEXTGEN_*` variable in these files to the\n * local server, so the files are also where a developer configures it.\n */\nconst LOCAL_SERVER_ENV_COMMENT = [\n \"Variables the scaffolded app reads. Any NEXTGEN_* variable added here\",\n \"configures the local server that `zitadel start` runs, for example\",\n \"NEXTGEN_INSTRUMENTATION_LOG_LEVEL=debug.\",\n];\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 await this.preflight(ctx, opts.cwd);\n return scaffold(this.plan(ctx), opts);\n }\n\n /**\n * Refuses, with `E_CONFLICT`, a project the plan would leave broken without\n * conflicting on any path it writes: the file-writer only stops on a file\n * at exactly a path in the plan, and some of the app's own files break the\n * integration from another path. Setup's dry-run patch runs this before it\n * creates a project. `force` does not skip it: forcing replaces files at the\n * plan's paths, and these files sit elsewhere. `repair` does not run it —\n * `doctor` reports what it finds instead. Defaults to nothing to check.\n */\n protected async preflight(_ctx: PatchContext, _cwd: string): Promise<void> {}\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 /** See {@link Patcher.moveDevPort}. */\n async moveDevPort(\n ctx: PatchContext,\n previousIssuer: string,\n opts: PatchExecOptions,\n ): Promise<PatchResult> {\n const ops: FileOp[] = [\n ...this.devPortOps(ctx, portFromIssuer(previousIssuer)),\n envIssuerOp(ctx.issuer),\n configIssuerOp(previousIssuer, ctx.issuer),\n ...guidanceOps(ctx),\n ];\n return scaffold({ ops, summary: [this.summary(ctx)] }, opts);\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. An op whose transform leaves a file it cannot recognize as it is\n * brings its own `verify`, so that such a file reads as `unknown`, not\n * applied. 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 const verdict = op.verify\n ? op.verify(source)\n : op.edit(source) === source\n ? \"applied\"\n : \"detached\";\n statuses.push(\n typeof verdict === \"string\"\n ? { path, wiring: op.wiring, state: verdict }\n : { path, wiring: op.wiring, state: \"unknown\", reason: verdict.unknown },\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\", \".env.development.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) => [\n path,\n infrastructure.has(path) ? \"infrastructure\" : \"presentation\",\n ]),\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 primary_origins: ctx.project.origins\n .filter((origin) => origin.kind === \"primary\")\n .map((origin) => origin.pattern),\n preview_origins: ctx.project.origins\n .filter((origin) => origin.kind === \"preview\")\n .map((origin) => origin.pattern),\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 comment: LOCAL_SERVER_ENV_COMMENT,\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 comment: LOCAL_SERVER_ENV_COMMENT,\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 // What the CLI reads, as opposed to `.env.local`, which the app reads.\n {\n kind: \"merge-env\",\n path: \".env.development.local\",\n mode: 0o600,\n // The CLI's own file: a value a prompt saved here before setup ran\n // must give way to the project setup just created.\n overwrite: true,\n entries: {\n ZITADEL_URL: ctx.server,\n ZITADEL_PROJECT_ID: ctx.project.id,\n ZITADEL_PROJECT_SECRET: ctx.project.project_secret,\n ZITADEL_PREVIEW_TOKEN: ctx.project.preview_secret,\n // The setup issuer, so the SSO recovery command (which pins\n // `--env-file .env.development.local`) resolves the local origin\n // rather than falling through to a production `ZITADEL_ISSUER` in\n // the process environment.\n ZITADEL_ISSUER: ctx.issuer,\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 the relative\n // `$schema` pointers of `zitadel.json` and the flow files resolve\n // offline (editor validation) and agents can read the flow/schema\n // 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 ...projectMetaSchemas(ctx.cliVersion).map(\n (file): FileOp => ({ kind: \"write\", path: file.path, contents: file.contents }),\n ),\n ...guidanceOps(ctx),\n ];\n }\n\n /**\n * The ops that hold the dev server to `ctx.framework.devPort`, for\n * {@link moveDevPort}. `previousPort` is the port the app is moving off: a\n * config pin still on it is rewritten, any other pin is left alone. Each\n * framework names its own, because the port lives in the dev script for\n * some and in the dev-server config for others.\n */\n protected abstract devPortOps(\n ctx: PatchContext,\n previousPort: number | undefined,\n ): ReadonlyArray<FileOp>;\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/**\n * Guidance for humans (README) and agents (AGENTS.md): the golden journey and\n * the customize→plan→apply loop. Marker-fenced managed sections — existing\n * content is never clobbered.\n */\nfunction guidanceOps(ctx: PatchContext): FileOp[] {\n return [\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/** 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 return {\n // The copy setup writes into .zitadel/meta/, so an editor validates the\n // file offline against the CLI version that wrote it.\n $schema: PROJECT_FILE_SCHEMA_REF,\n project: ctx.project.id,\n server: resolveServerOrigin(ctx.server),\n framework: { id: ctx.framework.id },\n branding: { renderer: ctx.rendererId, attribution: \"visible\" },\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 { readFile, stat } from \"node:fs/promises\";\nimport { join, posix } from \"node:path\";\n\nimport { parseModule } from \"magicast\";\n\nimport { ZitadelError } from \"../../../errors\";\nimport { isObject } from \"../../../json\";\nimport { PREFLIGHT_FORCE_NOTE } from \"./base\";\n\n/**\n * How a single-page app mounts the root component its patcher writes.\n *\n * The patcher writes the root to one fixed path, and the file-writer conflicts\n * only on a file at exactly that path. An app whose root component lives\n * somewhere else — a Vite JavaScript template's `src/App.jsx`, Angular 17–19's\n * `src/app/app.component.ts` — would get the managed root beside its own and\n * keep loading its own. {@link assertMountsRootComponent} reads the app's entry\n * to catch that before anything is written.\n */\nexport type RootMount = Readonly<{\n /** The root component the patcher writes, relative to the project root. */\n path: string;\n /** What the managed root exports: `export default App` or `export class App`. */\n binding: Readonly<{ name: string; named: boolean }>;\n /**\n * Whether the suggested import names the file extension. A Vite app needs\n * it: `./App` would still resolve to an `App.jsx` left beside the managed\n * `App.tsx`. Angular's TypeScript resolution takes none.\n */\n extension: boolean;\n /** The calls that mount the root, by callee or method name. */\n calls: ReadonlyArray<string>;\n /**\n * Where a mount call names the root: as its first argument\n * (`createApp(App)`, `bootstrapApplication(App)`) or as the JSX it renders\n * (`createRoot(el).render(<App />)`).\n */\n mounts: \"argument\" | \"jsx\";\n /**\n * The extension of components the entry mounts with `new Root({ target })`\n * (Svelte 3 and 4). Limited to it so an unrelated `new Router()` is never\n * mistaken for the root.\n */\n constructs?: string;\n}>;\n\n/**\n * Vite's own extension order for a specifier without one (its\n * `resolve.extensions` default, minus JSON). The order matters: with an\n * `App.jsx` beside an `App.tsx`, Vite resolves `./App` to the `.jsx`.\n */\nconst SCRIPT_EXTENSIONS = [\".mjs\", \".js\", \".mts\", \".ts\", \".jsx\", \".tsx\"] as const;\n\n/** The TypeScript files a `.js`-style specifier resolves to from a TypeScript importer. */\nconst TYPESCRIPT_FOR_JAVASCRIPT: Readonly<Record<string, ReadonlyArray<string>>> = {\n \".js\": [\".ts\", \".tsx\"],\n \".jsx\": [\".tsx\"],\n \".mjs\": [\".mts\"],\n};\n\n/**\n * Throws `E_CONFLICT` when the app's entry mounts a root component from a\n * file other than `root.path`, so setup stops before it creates a project\n * instead of writing a root component the app never loads.\n *\n * Conservative by design: it stops only on a root it can see, a local file\n * the entry mounts. An entry it cannot find or parse, a mount it does not\n * recognise, or a root it cannot resolve (an unfamiliar alias, a component\n * from a package) all let setup go ahead as before.\n */\nexport async function assertMountsRootComponent(\n cwd: string,\n entry: string | undefined,\n root: RootMount,\n): Promise<void> {\n if (entry === undefined) {\n return;\n }\n const source = await readTextIfExists(join(cwd, entry));\n if (source === undefined) {\n return;\n }\n const mounted = mountedSpecifiers(source, root);\n const foreign: string[] = [];\n for (const specifier of mounted) {\n const file = await resolveLocalModule(cwd, entry, specifier, root.path);\n if (file === root.path) {\n return;\n }\n if (file !== undefined) {\n foreign.push(file);\n }\n }\n // Several candidates only come from JSX that renders siblings, such as a\n // toaster beside the app; the one named like the root is the one to report.\n const mountedRoot = foreign.find((file) => stem(file) === stem(root.path)) ?? foreign[0];\n if (mountedRoot === undefined) {\n return;\n }\n const statement = importStatement(entry, root);\n throw new ZitadelError(\n \"E_CONFLICT\",\n `${entry} mounts ${mountedRoot}, not the ${root.path} setup writes`,\n {\n hint:\n `Your app would keep loading ${mountedRoot}, and the root component setup writes would ` +\n `never run. In ${entry}, import the root as \\`${statement}\\` and mount that instead, ` +\n `then rerun setup and move what you need from ${mountedRoot} into ${root.path}. ` +\n PREFLIGHT_FORCE_NOTE,\n details: { path: mountedRoot, entry, writes: root.path },\n },\n );\n}\n\n/**\n * The module script a Vite app's `index.html` loads, relative to the project\n * root: the entry that mounts the root component. `undefined` when there is\n * no `index.html` or it loads no local module.\n */\nexport async function viteEntry(cwd: string): Promise<string | undefined> {\n const html = await readTextIfExists(join(cwd, \"index.html\"));\n if (html === undefined) {\n return undefined;\n }\n // A commented-out script is not the one Vite loads.\n for (const tag of withoutComments(html).match(/<script\\b[^>]*>/gi) ?? []) {\n if (!/\\btype\\s*=\\s*[\"']?module\\b/i.test(tag)) {\n continue;\n }\n const src = tag.match(/\\bsrc\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1];\n // A URL, protocol-relative or not, is a module from elsewhere.\n if (src === undefined || /^(?:[a-z][a-z\\d+.-]*:|\\/\\/)/i.test(src)) {\n continue;\n }\n return projectPath(src);\n }\n return undefined;\n}\n\n/**\n * `html` without its comments. Scanned rather than replaced by a pattern: the\n * text is only searched for a script tag, never served, but code scanning\n * reads a pattern replace over HTML as sanitizing it.\n */\nfunction withoutComments(html: string): string {\n let text = \"\";\n let from = 0;\n for (let start = html.indexOf(\"<!--\"); start !== -1; start = html.indexOf(\"<!--\", from)) {\n text += html.slice(from, start);\n const end = html.indexOf(\"-->\", start + 4);\n if (end === -1) {\n return text;\n }\n from = end + 3;\n }\n return text + html.slice(from);\n}\n\n/**\n * The browser entry `angular.json` builds (`browser` for the application\n * builder, `main` for the older browser builder), relative to the project\n * root. Falls back to the Angular CLI's `src/main.ts` when the workspace does\n * not say, including when it holds several projects and names no default.\n */\nexport async function angularEntry(cwd: string): Promise<string> {\n const fallback = \"src/main.ts\";\n const text = await readTextIfExists(join(cwd, \"angular.json\"));\n if (text === undefined) {\n return fallback;\n }\n let workspace: unknown;\n try {\n workspace = JSON.parse(text);\n } catch {\n return fallback;\n }\n if (!isObject(workspace) || !isObject(workspace.projects)) {\n return fallback;\n }\n const projects = workspace.projects;\n const names = Object.keys(projects);\n const name =\n typeof workspace.defaultProject === \"string\"\n ? workspace.defaultProject\n : names.length === 1\n ? names[0]\n : undefined;\n const project = name === undefined ? undefined : projects[name];\n if (!isObject(project)) {\n return fallback;\n }\n // Angular CLI has used both \"architect\" and \"targets\" for the target map.\n const targets = isObject(project.architect)\n ? project.architect\n : isObject(project.targets)\n ? project.targets\n : undefined;\n const build = targets !== undefined && isObject(targets.build) ? targets.build : undefined;\n const options = build !== undefined && isObject(build.options) ? build.options : undefined;\n const entry = options?.browser ?? options?.main;\n return typeof entry === \"string\" ? projectPath(entry) : fallback;\n}\n\n/**\n * The specifiers of the local modules the entry's mount calls name as the\n * root, in source order. Empty when the entry cannot be parsed or mounts\n * nothing this recognises.\n */\nfunction mountedSpecifiers(source: string, root: RootMount): string[] {\n let program: AstNode | undefined;\n try {\n // magicast's `$ast` may be a babel `File` (with `.program`) or the\n // `Program` node itself.\n const ast = parseModule(source).$ast as AstNode;\n program = (ast.program as AstNode | undefined) ?? ast;\n } catch {\n return [];\n }\n const imports = importedSpecifiers(program);\n const names: string[] = [];\n walk(program, (node) => {\n if (node.type === \"CallExpression\" || node.type === \"OptionalCallExpression\") {\n if (!root.calls.includes(calleeName(node.callee as AstNode | undefined) ?? \"\")) {\n return;\n }\n const args = (node.arguments as AstNode[] | undefined) ?? [];\n if (root.mounts === \"argument\") {\n const [first] = args;\n if (first?.type === \"Identifier\" && typeof first.name === \"string\") {\n names.push(first.name);\n }\n return;\n }\n for (const arg of args) {\n names.push(...leafComponents(arg));\n }\n return;\n }\n if (node.type === \"NewExpression\" && root.constructs !== undefined) {\n const callee = node.callee as AstNode | undefined;\n const specifier =\n callee?.type === \"Identifier\" && typeof callee.name === \"string\"\n ? imports.get(callee.name)\n : undefined;\n if (specifier !== undefined && posix.extname(stripQuery(specifier)) === root.constructs) {\n names.push(callee?.name as string);\n }\n }\n });\n return names.flatMap((name) => {\n const specifier = imports.get(name);\n return specifier === undefined ? [] : [specifier];\n });\n}\n\n/** Local binding name to import specifier, for every value import. */\nfunction importedSpecifiers(program: AstNode): Map<string, string> {\n const imports = new Map<string, string>();\n for (const statement of (program.body as AstNode[] | undefined) ?? []) {\n if (statement.type !== \"ImportDeclaration\" || statement.importKind === \"type\") {\n continue;\n }\n const specifier = (statement.source as AstNode | undefined)?.value;\n if (typeof specifier !== \"string\") {\n continue;\n }\n for (const binding of (statement.specifiers as AstNode[] | undefined) ?? []) {\n const local = (binding.local as AstNode | undefined)?.name;\n if (typeof local === \"string\" && binding.importKind !== \"type\") {\n imports.set(local, specifier);\n }\n }\n }\n return imports;\n}\n\n/**\n * The components a render call's argument mounts innermost: JSX components\n * with no component inside them. Providers wrap the app, so in\n * `<StrictMode><Provider><App /></Provider></StrictMode>` only `App` counts,\n * and an app rendering a router from a package names no local root at all.\n */\nfunction leafComponents(node: AstNode): string[] {\n const leaves: string[] = [];\n walk(node, (candidate) => {\n const name = componentName(candidate);\n if (name !== undefined && !hasComponentChild(candidate)) {\n leaves.push(name);\n }\n });\n return leaves;\n}\n\nfunction hasComponentChild(element: AstNode): boolean {\n let found = false;\n for (const child of (element.children as AstNode[] | undefined) ?? []) {\n walk(child, (node) => {\n if (componentName(node) !== undefined) {\n found = true;\n }\n });\n }\n return found;\n}\n\n/** The name of a JSX element that renders a component (`<App />`), not a tag (`<div>`). */\nfunction componentName(node: AstNode): string | undefined {\n if (node.type !== \"JSXElement\") {\n return undefined;\n }\n const name = ((node.openingElement as AstNode | undefined)?.name as AstNode | undefined) ?? {};\n return name.type === \"JSXIdentifier\" && typeof name.name === \"string\" && /^[A-Z]/.test(name.name)\n ? name.name\n : undefined;\n}\n\n/** `render` for `render(…)`, `root.render(…)` and `createRoot(el).render(…)` alike. */\nfunction calleeName(callee: AstNode | undefined): string | undefined {\n if (callee?.type === \"Identifier\" && typeof callee.name === \"string\") {\n return callee.name;\n }\n if (\n (callee?.type === \"MemberExpression\" || callee?.type === \"OptionalMemberExpression\") &&\n callee.computed !== true\n ) {\n const property = callee.property as AstNode | undefined;\n return typeof property?.name === \"string\" ? property.name : undefined;\n }\n return undefined;\n}\n\n/**\n * The project file a local specifier resolves to, the way Vite resolves it,\n * counting `managed` as present (the patch is about to write it). `undefined`\n * for a package, a path outside the project, or a file that is not there.\n * `@/` and `~/` are read as `src/`, the alias the Vue and shadcn templates\n * configure; any other alias stays unresolved.\n */\nasync function resolveLocalModule(\n cwd: string,\n importer: string,\n specifier: string,\n managed: string,\n): Promise<string | undefined> {\n const path = stripQuery(specifier);\n let base: string;\n if (path.startsWith(\"./\") || path.startsWith(\"../\")) {\n base = posix.join(posix.dirname(importer), path);\n } else if (path.startsWith(\"/\")) {\n // Vite serves the project root at `/`.\n base = path.slice(1);\n } else if (path.startsWith(\"@/\") || path.startsWith(\"~/\")) {\n base = posix.join(\"src\", path.slice(2));\n } else {\n return undefined;\n }\n base = posix.normalize(base);\n if (base === \"..\" || base.startsWith(\"../\")) {\n return undefined;\n }\n const extension = posix.extname(base);\n const withoutExtension = base.slice(0, base.length - extension.length);\n const candidates = [\n base,\n ...SCRIPT_EXTENSIONS.map((ext) => `${base}${ext}`),\n ...(TYPESCRIPT_FOR_JAVASCRIPT[extension] ?? []).map((ext) => `${withoutExtension}${ext}`),\n ...SCRIPT_EXTENSIONS.map((ext) => posix.join(base, `index${ext}`)),\n ];\n for (const candidate of candidates) {\n if (candidate === managed || (await isFile(join(cwd, candidate)))) {\n return candidate;\n }\n }\n return undefined;\n}\n\n/** The import line that mounts the managed root from the entry's directory. */\nfunction importStatement(entry: string, root: RootMount): string {\n let specifier = posix.relative(posix.dirname(entry), root.path);\n if (!root.extension) {\n specifier = specifier.slice(0, specifier.length - posix.extname(specifier).length);\n }\n if (!specifier.startsWith(\".\")) {\n specifier = `./${specifier}`;\n }\n const binding = root.binding.named ? `{ ${root.binding.name} }` : root.binding.name;\n return `import ${binding} from \"${specifier}\"`;\n}\n\n/** `app` for `src/app/app.component.ts` and `src/App.tsx` alike. */\nfunction stem(path: string): string {\n return (posix.basename(path).split(\".\")[0] ?? \"\").toLowerCase();\n}\n\n/** A path from `index.html` or `angular.json`, made relative to the project root. */\nfunction projectPath(path: string): string {\n return posix.normalize(path.replace(/^\\.?\\//, \"\"));\n}\n\nfunction stripQuery(specifier: string): string {\n return specifier.split(/[?#]/)[0] ?? specifier;\n}\n\n/** The slice of a babel AST node this module reads. */\ntype AstNode = { type?: string; [key: string]: unknown };\n\n/** Visits `node` and every node below it, depth first and in source order. */\nfunction walk(node: unknown, visit: (node: AstNode) => void): void {\n if (Array.isArray(node)) {\n for (const item of node) {\n walk(item, visit);\n }\n return;\n }\n if (typeof node !== \"object\" || node === null || typeof (node as AstNode).type !== \"string\") {\n return;\n }\n visit(node as AstNode);\n for (const [key, value] of Object.entries(node)) {\n // Position data and comments hold no nodes worth visiting.\n if (key === \"loc\" || key === \"comments\" || key === \"leadingComments\" || key === \"tokens\") {\n continue;\n }\n if (typeof value === \"object\" && value !== null) {\n walk(value, visit);\n }\n }\n}\n\nasync function readTextIfExists(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return undefined;\n }\n}\n\nasync function isFile(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isFile();\n } catch {\n return false;\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). `previousPort` moves\n * the app: a serve port still on that port is rewritten to `port`.\n */\nexport function angularProxyEdit(opts: {\n proxyConfig: string;\n port?: number;\n previousPort?: 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 const moving =\n opts.previousPort !== undefined &&\n options.port === opts.previousPort &&\n opts.port !== opts.previousPort;\n if (opts.port !== undefined && (options.port === undefined || moving)) {\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\";\nimport type { ProxifiedModule, ProxifiedObject } 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 * A magicast object literal these helpers edit by dynamic key. magicast's\n * published `Proxified*` types don't model arbitrary-key indexing (the proxy is\n * dynamic), so arbitrary string keys read back as `unknown` while `$type` still\n * identifies the node as an object.\n */\ntype EditableObject = ProxifiedObject<Record<string, unknown>>;\n\n/** The `$type` tag magicast puts on a proxified object node. */\ninterface ProxyObject {\n $type?: string;\n}\n\n/** The array surface {@link ensureArrayItem} reads and mutates. */\ninterface ProxyArray {\n push: (item: string) => void;\n length: number;\n [index: number]: unknown;\n}\n\n/**\n * The slice of a raw (babel) AST node {@link hasCommonJsExport} walks. Only the\n * members it reads are described; every one is optional because the shapes it\n * scans across (statements, expressions, member accesses) don't share them.\n */\ninterface AstNodeLike {\n type?: string;\n name?: string;\n expression?: AstNodeLike;\n left?: AstNodeLike;\n object?: AstNodeLike;\n property?: AstNodeLike;\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 * `options` go to the parser, e.g. `{ tabWidth: 1 }` for node offsets that index\n * the source even where it is indented with tabs.\n */\nexport function parseConfigModule(\n source: string | undefined,\n filename: string,\n options?: Parameters<typeof parseModule>[1],\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, options);\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(\n \"E_VALIDATION\",\n `${filename} is a CommonJS module, which can't be edited`,\n {\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 }\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 */\nfunction hasCommonJsExport(mod: ProxifiedModule): boolean {\n // magicast's `$ast` may be a babel `File` (with `.program.body`) or the\n // `Program` node itself (`.body`) — handle both.\n const ast = mod.$ast as { program?: { body?: AstNodeLike[] }; body?: AstNodeLike[] };\n const body = ast.program?.body ?? ast.body ?? [];\n return body.some((node: AstNodeLike) => {\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 (\n object?.type === \"Identifier\" &&\n object.name === \"module\" &&\n left.property?.name === \"exports\"\n ) {\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 */\nexport function resolveDefaultExportObject(mod: ProxifiedModule, filename: string): EditableObject {\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?.$type !== \"object\") {\n throw unreachable();\n }\n return arg;\n }\n if (def.$type === \"object\") {\n return def;\n }\n throw unreachable();\n}\n\nexport function importIsPresent(mod: ProxifiedModule, 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 */\nexport function ensureArrayItem(parent: EditableObject, key: string, item: string): boolean {\n if (parent[key] === undefined) {\n parent[key] = [item];\n return true;\n }\n const arr = parent[key] as Partial<ProxyArray>;\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 array = arr as ProxyArray;\n const present = Array.from({ length: array.length }, (_unused, i) => array[i]).includes(item);\n if (!present) {\n array.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 */\nexport function ensureEditableObject(parent: EditableObject, key: string): EditableObject {\n if (parent[key] === undefined) {\n parent[key] = {};\n }\n const value = parent[key] as ProxyObject;\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 as unknown as EditableObject;\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/** The slice of magicast's array proxy this edit reads: indexed route objects, length, and push. */\ntype ProxifiedRouteArray = Readonly<{\n length: number;\n push: (item: unknown) => void;\n}> &\n Readonly<Record<number, { path?: unknown } | undefined>>;\n\n// magicast proxies answer property gets but not `in`, so members are read with Reflect.get.\nfunction isProxifiedArray(value: unknown): value is ProxifiedRouteArray {\n if (typeof value !== \"object\" || value === null) return false;\n return (\n Reflect.get(value, \"$type\") === \"array\" &&\n typeof Reflect.get(value, \"push\") === \"function\" &&\n typeof Reflect.get(value, \"length\") === \"number\"\n );\n}\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 // magicast types exports as an object with no declared members; reach `routes` as unknown.\n const moduleExports: unknown = mod.exports;\n const routes: unknown =\n typeof moduleExports === \"object\" && moduleExports !== null\n ? Reflect.get(moduleExports, \"routes\")\n : undefined;\n if (!isProxifiedArray(routes)) {\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 }, (_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 [whole = \"\", condition = \"\", body = \"\"] = match;\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 = whole.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","/**\n * The session-cookie hooks of the dev proxies the CLI writes for the SPA\n * frameworks (ADR 073). The server sets and reads one session cookie,\n * `__nextgen_session`; a browser shares a host's cookies across every port, so\n * under that name alone an SPA on `localhost` and the Console of a local server\n * would keep their sessions in one slot and sign each other out. The hooks keep\n * the app's session in `__nextgen_session_<project id>` instead, the name the\n * server SDKs use (`sessionCookieName` in `@zitadel/sdk-core`):\n *\n * - on the way up, the app's cookie goes under the server's name, and every\n * other session cookie stays back;\n * - on the way back, the server's `Set-Cookie` is renamed to the app's.\n *\n * Without a project id the cookies pass through unchanged. The code is plain\n * JavaScript, so it runs in a `vite.config.*` and in Angular's CommonJS\n * `proxy.conf.cjs` alike, and in a `vite.config.ts` it type-checks under\n * `strict`: every parameter is one Vite's `configure(proxy)` typing reaches.\n */\n\n/** Marks a generated dev proxy that carries the session-cookie hooks. */\nexport const SESSION_COOKIE_MARKER = \"zitadel:session-cookie:v1\";\n\n/** Says what the hooks do, above them in the generated proxy. */\nconst EXPLANATION = [\n `/* ${SESSION_COOKIE_MARKER} */`,\n \"// The browser keeps this app's session in a cookie named after its project,\",\n \"// the server in __nextgen_session (ADR 073). Without a project id, cookies\",\n \"// pass through.\",\n];\n\n/**\n * `appCookie`, the app's cookie name for `projectId`, or `undefined` without\n * one. It percent-encodes every byte outside `[A-Za-z0-9_-]`, as\n * `sessionCookieName` in sdk-core does.\n */\nconst APP_COOKIE = [\n \"const appCookie = projectId\",\n ' ? \"__nextgen_session_\" +',\n \" projectId.replace(/[^\\\\w-]/gu, (char) =>\",\n \" Array.from(new TextEncoder().encode(char), (byte) =>\",\n ' \"%\" + byte.toString(16).toUpperCase().padStart(2, \"0\"),',\n ' ).join(\"\"),',\n \" )\",\n \" : undefined;\",\n];\n\n/** The request hook's body, on `proxyReq`: only the app's cookie goes up, under the server's name. */\nconst FORWARD_BODY = [\n \"if (!appCookie) {\",\n \" return;\",\n \"}\",\n 'const cookies = String(proxyReq.getHeader(\"cookie\") ?? \"\")',\n ' .split(\";\")',\n \" .map((cookie) => cookie.trim())\",\n ' .filter((cookie) => cookie !== \"\");',\n \"const own = cookies.find(\",\n ' (cookie) => cookie.startsWith(appCookie + \"=\") && cookie.length > appCookie.length + 1,',\n \");\",\n \"const forwarded = cookies.filter((cookie) => !/^__nextgen_session(?:_[^=]*)?=/.test(cookie));\",\n \"if (own) {\",\n ' forwarded.push(\"__nextgen_session\" + own.slice(appCookie.length));',\n \"}\",\n \"if (forwarded.length > 0) {\",\n ' proxyReq.setHeader(\"cookie\", forwarded.join(\"; \"));',\n \"} else {\",\n ' proxyReq.removeHeader(\"cookie\");',\n \"}\",\n];\n\n/** The response hook's body, on `proxyRes`: the server's `Set-Cookie` comes back under the app's name. */\nconst RENAME_BODY = [\n 'const setCookies = proxyRes.headers[\"set-cookie\"];',\n \"if (appCookie && setCookies) {\",\n ' proxyRes.headers[\"set-cookie\"] = setCookies.map((setCookie) =>',\n ' setCookie.replace(/^__nextgen_session=/, appCookie + \"=\"),',\n \" );\",\n \"}\",\n];\n\n/** `lines`, each indented by two more spaces. */\nfunction nested(lines: readonly string[]): string[] {\n return lines.map((line) => (line === \"\" ? \"\" : ` ${line}`));\n}\n\n/**\n * The hooks as statements of a Vite proxy entry's `configure(proxy)` body,\n * after its bearer hook. The project id comes from `.env.local` through Vite's\n * `loadEnv`, as the project secret does. The hooks are the listeners\n * themselves, not functions they call, so Vite's types reach `proxyReq` and\n * `proxyRes` and a strict `vite.config.ts` type-checks.\n */\nexport function viteSessionCookieStatements(): string[] {\n return [\n ...EXPLANATION,\n 'const projectId = loadEnv(\"development\", process.cwd(), \"ZITADEL_\").ZITADEL_PROJECT_ID;',\n ...APP_COOKIE,\n 'proxy.on(\"proxyReq\", (proxyReq) => {',\n ...nested(FORWARD_BODY),\n \"});\",\n 'proxy.on(\"proxyRes\", (proxyRes) => {',\n ...nested(RENAME_BODY),\n \"});\",\n ];\n}\n\n/**\n * The hooks as top-level statements of Angular's `proxy.conf.cjs`, after its\n * bearer hook: the functions its entry attaches as `onProxyReq`/`onProxyRes`\n * and in `configure`. The project id comes from the environment, else from the\n * `.env.local` the file has already read into `env`; a managed file from\n * before it read `.env.local` has no `env`, and then only the environment\n * names the project.\n */\nexport function proxyConfSessionCookieStatements(): string[] {\n return [\n ...EXPLANATION,\n \"const projectId =\",\n ' process.env.ZITADEL_PROJECT_ID ?? (typeof env === \"undefined\" ? undefined : env.ZITADEL_PROJECT_ID);',\n ...APP_COOKIE,\n \"\",\n \"function forwardSessionCookie(proxyReq) {\",\n ...nested(FORWARD_BODY),\n \"}\",\n \"\",\n \"function renameSessionCookie(proxyRes) {\",\n ...nested(RENAME_BODY),\n \"}\",\n ];\n}\n\n/** `lines`, each indented by `indent` (blank lines stay blank), joined with `eol`. */\nexport function indented(lines: readonly string[], indent: string, eol = \"\\n\"): string {\n return lines.map((line) => (line === \"\" ? \"\" : `${indent}${line}`)).join(eol);\n}\n","/**\n * Runs `edit` on `source` with LF line ends and no byte-order mark, and hands\n * the result back in the file's own: an edit that matches or splices text, or\n * indexes it by parser offsets, then works the same on a file saved on Windows.\n * A result `edit` left unchanged returns `source` exactly, so a transform stays\n * idempotent and the doctor still reads it as applied.\n */\nexport function withLfLineEnds(source: string, edit: (lf: string) => string): string {\n const lf = lfText(source);\n const next = edit(lf);\n if (next === lf) {\n return source;\n }\n const bom = source.startsWith(\"\") ? \"\" : \"\";\n return bom + (source.includes(\"\\r\\n\") ? next.replace(/\\n/g, \"\\r\\n\") : next);\n}\n\n/** `source` with LF line ends and without a byte-order mark. */\nexport function lfText(source: string): string {\n return source.replace(/^/, \"\").replace(/\\r\\n/g, \"\\n\");\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\nimport type { PatchContext } from \"../../types\";\nimport type { WiringVerdict } from \"../file-writer/types\";\nimport { PROXY_PATH } from \"../proxy\";\nimport {\n assertNoUnreviewedProjectSecretProxy,\n PROXY_CREDENTIAL_POLICY_MARKER,\n} from \"../proxy-credential-policy\";\nimport {\n indented,\n proxyConfSessionCookieStatements,\n SESSION_COOKIE_MARKER,\n} from \"../session-cookie\";\nimport { lfText, withLfLineEnds } from \"../utils/line-ends\";\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. Like the Vite proxy (`vite-support.ts`), it addresses the\n * backend by its own name (`changeOrigin`), which a remote https server\n * requires, and forwards the app's origin in `X-Forwarded-Host` and\n * `X-Forwarded-Proto` (`xfwd`), and it keeps the session cookie under the\n * app's project's name in the browser (`ZITADEL_PROJECT_ID`, ADR 073).\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\n${SESSION_COOKIE_FUNCTIONS}\n\nfunction stripPrefix(path) {\n return path.replace(/^\\\\${PROXY_PATH}/, \"\").replace(/^(?!\\\\/)/, \"/\");\n}\n\nmodule.exports = {\n \"${PROXY_PATH}\": {\n target: server,\n changeOrigin: true,\n xfwd: true,\n pathRewrite: stripPrefix,\n rewrite: stripPrefix,\n${SESSION_COOKIE_HOOKS} },\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/** The session-cookie hooks' functions, after the bearer hook (ADR 073). */\nconst SESSION_COOKIE_FUNCTIONS = indented(proxyConfSessionCookieStatements(), \"\");\n\n/** How the managed entry attached its hooks before it carried the session-cookie ones. */\nconst BEARER_ONLY_HOOKS = ` onProxyReq: setBearer,\n configure: (proxy) => proxy.on(\"proxyReq\", setBearer),\n`;\n\n/** How the managed entry attaches the bearer and the session-cookie hooks. */\nconst SESSION_COOKIE_HOOKS = ` onProxyReq: (proxyReq) => {\n setBearer(proxyReq);\n forwardSessionCookie(proxyReq);\n },\n onProxyRes: renameSessionCookie,\n configure: (proxy) => {\n proxy.on(\"proxyReq\", setBearer);\n proxy.on(\"proxyReq\", forwardSessionCookie);\n proxy.on(\"proxyRes\", renameSessionCookie);\n },\n`;\n\n/**\n * The managed entry as emitted before it forwarded the app's origin, and what\n * replaces it. Keeping the browser's `Host` also kept `localhost` as the TLS\n * server name, so that proxy could reach no remote https server.\n */\nconst HOST_KEEPING_ENTRY = ` target: server,\n changeOrigin: false,\n`;\n\nconst ORIGIN_FORWARDING_ENTRY = ` target: server,\n changeOrigin: true,\n xfwd: true,\n`;\n\n/** Upgrades the exact host-keeping entry, unless the file already chose its own `xfwd`. */\nfunction forwardAppOrigin(source: string): string {\n if (/\\bxfwd\\s*:/.test(source)) {\n return source;\n }\n return source.replace(HOST_KEEPING_ENTRY, ORIGIN_FORWARDING_ENTRY);\n}\n\n/**\n * Creates the managed Angular proxy and upgrades the exact shapes earlier CLIs\n * emitted: the insecure unconditional bearer hook and the host-keeping entry.\n * Other edits are preserved; a safe custom proxy is left untouched, while an\n * unrecognized proxy that may still over-forward the project secret is\n * surfaced for manual review.\n */\nexport function proxyConfEdit(): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n return proxyConfTemplate();\n }\n return withLfLineEnds(source, (text) => {\n if (text.includes(MANAGED_MARKER) && text.includes(LEGACY_UNCONDITIONAL_BEARER)) {\n return forwardAppOrigin(text.replace(LEGACY_UNCONDITIONAL_BEARER, EXCHANGE_ONLY_BEARER));\n }\n assertNoUnreviewedProjectSecretProxy(text, \"proxy.conf.cjs\");\n return text.includes(MANAGED_MARKER) ? forwardAppOrigin(text) : text;\n });\n };\n}\n\n/** Whether `text` (LF line ends) is the managed proxy as an earlier CLI wrote it, without the session-cookie hooks. */\nfunction hasBearerOnlyHooks(text: string): boolean {\n return (\n text.includes(MANAGED_MARKER) &&\n text.includes(EXCHANGE_ONLY_BEARER) &&\n text.includes(BEARER_ONLY_HOOKS)\n );\n}\n\n/**\n * Gives the managed proxy the session-cookie hooks (ADR 073) when it is the\n * exact file an earlier CLI wrote: the hook functions go after the bearer hook,\n * and the entry attaches them beside it. A file that carries them already, an\n * unmanaged one, and a managed one whose hooks were changed by hand are left as\n * they are; {@link proxyConfSessionCookieVerdict} tells the doctor which it is.\n * Line ends are the file's own (CRLF or LF). Creates the managed proxy when it\n * is absent, as {@link proxyConfEdit} does.\n */\nexport function proxyConfSessionCookieEdit(): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n return proxyConfTemplate();\n }\n return withLfLineEnds(source, (text) =>\n text.includes(SESSION_COOKIE_MARKER) || !hasBearerOnlyHooks(text)\n ? text\n : text\n .replace(EXCHANGE_ONLY_BEARER, `${EXCHANGE_ONLY_BEARER}\\n\\n${SESSION_COOKIE_FUNCTIONS}`)\n .replace(BEARER_ONLY_HOOKS, SESSION_COOKIE_HOOKS),\n );\n };\n}\n\n/**\n * Whether `proxy.conf.cjs` carries the session-cookie hooks, for the doctor.\n * The managed file as an earlier CLI wrote it is `detached` (`doctor --fix`\n * adds them). One the edit cannot place them in, a managed file changed by\n * hand or a proxy of the developer's own, is `unknown`: only the developer can.\n */\nexport function proxyConfSessionCookieVerdict(source: string): WiringVerdict {\n const text = lfText(source);\n if (text.includes(SESSION_COOKIE_MARKER)) {\n return \"applied\";\n }\n if (hasBearerOnlyHooks(text)) {\n return \"detached\";\n }\n return {\n unknown: text.includes(MANAGED_MARKER)\n ? \"it was changed since zitadel setup wrote it, so the session-cookie hooks (ADR 073) must be added by hand\"\n : \"it is not the proxy zitadel setup writes, so the session-cookie hooks (ADR 073) must be added by hand\",\n };\n}\n","import { ZitadelError } from \"../../../../errors\";\nimport { isObject, parseJsonObject, setTopLevelJsonKey } from \"../../../../json\";\nimport { sdkVersionForCli } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { angularEntry, assertMountsRootComponent, type RootMount } from \"../root-component\";\nimport { angularProxyEdit } from \"./angular-json\";\nimport { angularRoutesEdit } from \"./angular-routes\";\nimport {\n appComponentTemplate,\n appTemplateHtml,\n proxyConfEdit,\n proxyConfSessionCookieEdit,\n proxyConfSessionCookieVerdict,\n} from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-angular\";\n\n/**\n * The managed root component, in the layout Angular 20 generates, and how\n * `main.ts` bootstraps it. Angular 17–19 keep theirs in `app.component.ts`,\n * and a module-based app bootstraps an `AppModule`.\n */\nconst ROOT: RootMount = {\n path: \"src/app/app.ts\",\n binding: { name: \"App\", named: true },\n extension: false,\n calls: [\"bootstrapApplication\", \"bootstrapModule\"],\n mounts: \"argument\",\n};\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 override async preflight(_ctx: PatchContext, cwd: string): Promise<void> {\n await assertMountsRootComponent(cwd, await angularEntry(cwd), ROOT);\n }\n\n protected devPortOps(ctx: PatchContext, previousPort: number | undefined): FileOp[] {\n return [\n {\n kind: \"edit\",\n path: \"angular.json\",\n edit: angularProxyEdit({\n proxyConfig: \"proxy.conf.cjs\",\n port: ctx.framework.devPort,\n previousPort,\n }),\n },\n ];\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n {\n kind: \"write\",\n path: ROOT.path,\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: \"proxy.conf.cjs\",\n edit: proxyConfSessionCookieEdit(),\n // A session cookie per project (ADR 073) keeps the Console and the app\n // from signing each other out on localhost. Sign-in works without it,\n // so the doctor only warns while it is missing.\n wiring: \"convenience\",\n verify: proxyConfSessionCookieVerdict,\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: sdkVersionForCli(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [ROOT.path, \"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/** Options for {@link devScriptPortEdit}. */\nexport interface DevScriptPortOptions {\n /**\n * Also pass `--strictPort`, for a Vite dev server. `vite dev --port N`\n * silently serves the next free port when N is taken, landing on an origin\n * the project does not allow; with `--strictPort` it exits instead.\n */\n readonly strictPort?: boolean;\n}\n\nconst STRICT_PORT_FLAG = /(?:^|\\s)--strictPort(?:\\s|=|$)/;\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(\n issuer: string,\n options: DevScriptPortOptions = {},\n): (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 const needsStrict = options.strictPort === true && !STRICT_PORT_FLAG.test(dev);\n if (extractPort(dev) === devPort && !needsStrict) {\n return source;\n }\n const pinned = withDevPort(dev, devPort);\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: needsStrict ? `${pinned.trimEnd()} --strictPort` : pinned,\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, options: DevScriptPortOptions = {}): FileOp {\n return {\n kind: \"edit\",\n path: \"package.json\",\n edit: devScriptPortEdit(issuer, options),\n wiring: \"convenience\",\n };\n}\n","/**\n * The variable each framework's client code reads the project id from. Each\n * framework exposes only variables with its own prefix to the browser, so the\n * id is written under this name beside `ZITADEL_PROJECT_ID`. Angular is absent:\n * its dev proxy attaches the project, and no client code reads an id.\n */\nexport const PUBLIC_PROJECT_ID_VARIABLE = {\n next: \"NEXT_PUBLIC_ZITADEL_PROJECT_ID\",\n nuxt: \"NUXT_PUBLIC_ZITADEL_PROJECT_ID\",\n qwik: \"VITE_ZITADEL_PROJECT_ID\",\n react: \"VITE_ZITADEL_PROJECT_ID\",\n solid: \"VITE_ZITADEL_PROJECT_ID\",\n svelte: \"VITE_ZITADEL_PROJECT_ID\",\n vue: \"VITE_ZITADEL_PROJECT_ID\",\n} as const;\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\" },\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 through the `ZitadelLogin` and `ZitadelSession` React\n * wrappers from `@zitadel/sdk-next/components`. `/profile` is the post-sign-in\n * \"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={...}`. The wrappers register the elements and are\n * imported from `@zitadel/sdk-next/components`, because importing\n * `@zitadel/components` directly would fail on strict-resolution package\n * managers (pnpm, yarn PnP) when the app only declares `sdk-next` as a direct\n * dep. SSR is disabled because Lit's element registration needs a browser.\n *\n * The wrappers set `project` and `locales` as DOM properties on React 18 and\n * 19 alike, where a raw `<zitadel-login>` would lose them on 19 hydration and\n * write `[object Object]` attributes on 18. The backend URL never reaches the\n * browser: the client talks to the 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 pass the SDK's\n * `businessLocales` overlay to the auth pages, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries.\n */\n/**\n * The dark page surface `variant=\"page\"` paints by default\n * (`--zl-background` under `data-theme=\"dark\"`). The widget loads client-only,\n * so until it mounts only the server-rendered wrapper is on screen: the\n * wrapper paints the same surface, or the first paint is the host page's own\n * background (white under a light OS preference) and then flips to dark.\n */\nexport const PAGE_SURFACE_BACKGROUND = \"#050505\";\n\nconst PAGE_WRAPPER_OPEN = `<main style={{ minHeight: \"100vh\", background: \"${PAGE_SURFACE_BACKGROUND}\", colorScheme: \"dark\" }}>`;\n\nconst PAGE_WRAPPER_COMMENT = ` // The wrapper paints the widget's dark page surface before the client-only\n // widget mounts, so the page does not flash the app's own background first.\n // Change both when you pin another theme on the widget.`;\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\" },\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\n ? \"ZitadelLogin: Login, businessLocales, configureZitadel\"\n : \"ZitadelLogin: Login, 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. Remove the\n // locales prop to fall back to the neutral wording.`\n : \"\";\n const localesAttr = business\n ? `\n locales={businessLocales}`\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 suppressHeader 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. The login\n // moves between sign-in and sign-up by itself, so that heading has to\n // follow it, as AGENTS.md describes.`\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${PAGE_WRAPPER_COMMENT}`;\n const wrapperOpen = widget\n ? `<div style={{ display: \"flex\", justifyContent: \"center\", padding: \"4rem 1rem\" }}>`\n : PAGE_WRAPPER_OPEN;\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/components\");\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 <Login\n ${variantAttrs}${localesAttr}\n project={project}\n purpose=\"${mode}\"\n postSignInUrl=\"/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 suppressHeader 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${PAGE_WRAPPER_COMMENT}`;\n const wrapperOpen = widget\n ? `<div style={{ display: \"flex\", justifyContent: \"center\", padding: \"4rem 1rem\" }}>`\n : PAGE_WRAPPER_OPEN;\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 { ZitadelSession: Session, configureZitadel } = await import(\n \"@zitadel/sdk-next/components\"\n );\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 <Session\n ${variantAttrs}\n project={project}\n postSignOutUrl=\"/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 { stat } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { ZitadelError } from \"../../../../errors\";\nimport { MANAGED_MARKER } from \"../../../../paths\";\nimport { sdkVersionForCli } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher, PREFLIGHT_FORCE_NOTE } from \"../base\";\nimport { devScriptPortOp } from \"../dev-script-port\";\nimport { PUBLIC_PROJECT_ID_VARIABLE } from \"../public-project-id\";\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 * The matcher covers every route but Next's build files, so `protectedRoutes`\n * alone decides what needs a sign-in: with a matcher listing routes, a\n * protected route it misses never reaches the middleware and stays public.\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 // The routes that need a sign-in. To protect another, add it here; a\n // trailing * covers every path that starts with it, as in \"/orders*\".\n protectedRoutes: [\"/profile\"],\n loginPath: \"/login\",\n });\n}\n\nexport const config = {\n // Every route but Next.js's build files and favicon.ico, so the list above\n // alone decides what needs a sign-in, and auth() sees the session on every\n // page. A protected route that a narrower matcher leaves out stays public.\n matcher: [\"/((?!_next/static|_next/image|favicon.ico).*)\"],\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 /**\n * Next.js runs one request boundary, and it looks for it in two places and\n * under every page extension: `middleware.ts` beside the boundary setup\n * writes is as much a conflict as one at the same path, but the file-writer\n * only sees the latter. Next 16 refuses to start with both a `proxy.*` and a\n * `middleware.*` at the project root or in `src/` (its dev server checks\n * both levels), and a second file under the same name means one of them\n * silently never runs. On Next 15 a `proxy.ts` is just a file of the app's,\n * unless the version is unknown: then setup writes Next 15's\n * `middleware.ts`, and cannot rule out a Next 16 that rejects the pair.\n */\n protected override async preflight(ctx: PatchContext, cwd: string): Promise<void> {\n const boundary = requestBoundaryFile(ctx.framework);\n const target = join(ctx.framework.appDir, `../${boundary.filename}`);\n const unknownVersion = ctx.framework.versionMajor === undefined;\n const names =\n boundary.functionName === \"proxy\" || unknownVersion\n ? [\"middleware\", \"proxy\"]\n : [\"middleware\"];\n for (const dir of [\".\", \"src\"]) {\n for (const name of names) {\n for (const extension of BOUNDARY_EXTENSIONS) {\n const path = join(dir, `${name}.${extension}`);\n if (path !== target && (await isFile(join(cwd, path)))) {\n throw boundaryConflict(path, target, unknownVersion);\n }\n }\n }\n }\n }\n\n protected devPortOps(ctx: PatchContext): FileOp[] {\n return [devScriptPortOp(ctx.issuer)];\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: { [PUBLIC_PROJECT_ID_VARIABLE.next]: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.next]: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: renderer.dependency.name,\n version: sdkVersionForCli(ctx.cliVersion),\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\n/**\n * The home page of an app setup scaffolded: a redirect to `/login`. The\n * pinned `create-next-app` turns on Cache Components, whose dev server\n * validates every page for instant navigation and logs the redirect it throws\n * as an error on each request to `/`; `instant = false` exempts the page.\n */\nfunction homePageTemplate(): string {\n return `${MANAGED_MARKER}\nimport { redirect } from \"next/navigation\";\n\n// A redirect is never an instant navigation: tell Next.js not to validate it.\nexport const instant = false;\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\n/** The extensions Next.js reads a request boundary under: its default `pageExtensions`. */\nconst BOUNDARY_EXTENSIONS = [\"tsx\", \"ts\", \"jsx\", \"js\"] as const;\n\n/** Why the app's own request boundary at `existing` stops setup, which writes `target`. */\nfunction boundaryConflict(existing: string, target: string, unknownVersion: boolean): ZitadelError {\n const existingName = basename(existing).split(\".\")[0];\n const targetName = basename(target, \".ts\");\n const details = { path: existing, writes: target };\n if (existingName === targetName) {\n return new ZitadelError(\n \"E_CONFLICT\",\n `Next.js runs one ${targetName} file, and this app already has ${existing}`,\n {\n hint:\n `Setup writes ${target}, and one of the two would never run. Move ${existing} ` +\n `aside and rerun setup, then merge it into ${target}. ${PREFLIGHT_FORCE_NOTE}`,\n details,\n },\n );\n }\n // With no version, the existing proxy.ts may be Next 16's boundary or, on\n // Next 15, just a module of the app's: only the version decides, so pinning\n // it is the fix, not moving the file.\n const remedy = unknownVersion\n ? 'Setup reads no Next.js version from package.json (a tag such as \"latest\" names ' +\n `none), so it writes the ${target} of Next 15. Pin next to the version range the app ` +\n 'runs, such as \"^16.0.0\", and rerun setup: on Next 16 it then writes proxy.ts, and on ' +\n `Next 15 it leaves your ${existing} alone.`\n : \"Next.js 16 renamed middleware.ts to proxy.ts. Move \" +\n `${existing} aside and rerun setup, then merge it into ${target}.`;\n return new ZitadelError(\n \"E_CONFLICT\",\n `Next.js 16 won't start with both ${existing} and the ${target} setup writes`,\n { hint: `${remedy} ${PREFLIGHT_FORCE_NOTE}`, details },\n );\n}\n\nasync function isFile(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isFile();\n } catch {\n return false;\n }\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\";\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 and the\n * protected route, and marks the `zitadel-*` Lit elements as custom elements for\n * the Vue compiler — preserving the user's existing config via magicast. The\n * backend URL and the project id stay out of the config: the module reads\n * `ZITADEL_URL` and `NUXT_PUBLIC_ZITADEL_PROJECT_ID` from the environment or\n * `.env.local`, where setup writes them, so a changed `.env.local` takes effect.\n * Idempotent. Throws `E_VALIDATION` when the file is absent or\n * `defineNuxtConfig` cannot be reached.\n */\nexport function nuxtConfigEdit(): (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.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 // 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/**\n * `pages/index.vue` — redirects the app root to `/login`. The redirect runs\n * before render; the empty template only keeps Vue from warning that the page\n * has nothing to render.\n */\nexport function indexPageTemplate(): string {\n return `<script setup lang=\"ts\">\n${MANAGED_MARKER}\nawait navigateTo(\"/login\", { replace: true });\n</script>\n\n<template>\n <div />\n</template>\n`;\n}\n\n/**\n * The `<script setup>` every page shares. It imports nothing: the module\n * auto-imports `useZitadelProject`, and an import from `@zitadel/sdk-nuxt`'s\n * root would evaluate the Lit elements during SSR.\n */\nconst PROJECT_SETUP = \"const project = useZitadelProject();\";\n\n/**\n * A login/register page rendering `<zitadel-login>` inside `<ClientOnly>`.\n * Business-use-case projects additionally bind the `businessLocales`\n * overlay, which the SDK module's client plugin provides as\n * `useNuxtApp().$zitadelBusinessLocales`, 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 // The overlay ships with the SDK, so the generated page only wires it up\n // (and stays plain otherwise).\n const localesSetup = 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. The SDK module provides the\n// overlay in the browser, where <ClientOnly> renders the widget.\nconst { $zitadelBusinessLocales: businessLocales } = useNuxtApp();`\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}\n${PROJECT_SETUP}${localesSetup}\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}\n${PROJECT_SETUP}\n</script>\n\n<template>\n ${wrapperOpen}\n <ClientOnly>\n ${postureComment}\n ${element}\n </ClientOnly>\n ${wrapperClose}\n</template>\n`;\n}\n","import { join } from \"node:path\";\n\nimport { sdkVersionForCli } 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 { PUBLIC_PROJECT_ID_VARIABLE } from \"../public-project-id\";\nimport { nuxtConfigEdit } from \"./nuxt-config\";\nimport {\n appVueTemplate,\n indexPageTemplate,\n loginPageTemplate,\n profilePageTemplate,\n registerPageTemplate,\n} from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-nuxt\";\n\n/**\n * Written by older setups, before `@zitadel/sdk-nuxt`'s module seeded the auth\n * state and loaded the elements itself. No longer written; still listed so\n * eject removes them and doctor does not fail on their absence.\n */\nconst RETIRED_AUTH_PLUGIN = \"plugins/auth.server.ts\";\nconst RETIRED_COMPONENTS_PLUGIN = \"plugins/zitadel-components.client.ts\";\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-session>`\n * elements), the `app.vue` router, and the SDK dep. The SDK module itself loads the elements\n * and seeds the auth state, so no plugin is scaffolded.\n */\nexport class NuxtPatcher extends AbstractRulePatcher {\n canPatch(framework: string): boolean {\n return framework === \"nuxt\";\n }\n\n protected devPortOps(ctx: PatchContext): FileOp[] {\n return [devScriptPortOp(ctx.issuer)];\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/`, or the root for a root-layout app); nuxt.config,\n // 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: \"edit\",\n path: [...NUXT_CONFIG_PATHS],\n edit: nuxtConfigEdit(),\n // Module registration + proxy wiring: auth breaks without it.\n wiring: \"infrastructure\",\n },\n {\n kind: \"merge-env\",\n path: \".env.example\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.nuxt]: \"\" },\n },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.nuxt]: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: sdkVersionForCli(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(RETIRED_COMPONENTS_PLUGIN),\n src(RETIRED_AUTH_PLUGIN),\n ];\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 // The retired plugins exist only in apps an older setup wrote.\n return [\n src(\"app.vue\"),\n src(\"pages/index.vue\"),\n src(RETIRED_COMPONENTS_PLUGIN),\n src(RETIRED_AUTH_PLUGIN),\n ];\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 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, WiringVerdict } from \"./file-writer/types\";\nimport { PROXY_PATH } from \"./proxy\";\nimport {\n assertNoUnreviewedProjectSecretProxy,\n PROXY_CREDENTIAL_POLICY_MARKER,\n} from \"./proxy-credential-policy\";\nimport { indented, SESSION_COOKIE_MARKER, viteSessionCookieStatements } from \"./session-cookie\";\nimport { lfText, withLfLineEnds } from \"./utils/line-ends\";\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 *\n * The backend is addressed by its own name: `changeOrigin` sends the target's\n * host as `Host`, which Node also uses as the TLS server name and for the\n * certificate check, so a remote https server accepts the connection — and one\n * behind a shared edge such as Vercel, which routes by `Host`, finds the\n * deployment. The app's own origin travels in `X-Forwarded-Host` and\n * `X-Forwarded-Proto` (`xfwd`), which the server reads before `Host`, as the\n * Next and Nuxt middleware send it. The WebAuthn relying party comes from the\n * browser's `Origin`, which the proxy passes on untouched.\n *\n * The session cookie travels under the app's project's name in the browser and\n * the server's name upstream ({@link viteSessionCookieStatements}, ADR 073).\n */\nfunction proxyEntryCode(server: string): string {\n return `/* ${PROXY_CREDENTIAL_POLICY_MARKER} */ {\n target: ${JSON.stringify(server)},\n changeOrigin: true,\n xfwd: true,\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${bearerListener(\" \")}\n${indented(viteSessionCookieStatements(), \" \")}\n },\n}`;\n}\n\n/** The generated hook that attaches the project secret to the session exchange only. */\nfunction bearerListener(indent: string): string {\n return `${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\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${bearerListener(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 [\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)) &&\n LEGACY_PROXY_REQUEST_LISTENER.test(source)\n );\n}\n\n/**\n * The generated entry as emitted before it forwarded the app's origin:\n * `changeOrigin: false` straight after `target`. Keeping the browser's `Host`\n * also kept `localhost` as the TLS server name, so that proxy could reach no\n * remote https server.\n */\nconst HOST_KEEPING_ENTRY =\n /([\"']\\/__nextgen[\"']:\\s*(?:\\/\\* zitadel:proxy:v2 \\*\\/\\s*)?\\{\\r?\\n([\\t ]+)target: [^\\r\\n]+,\\r?\\n)\\2changeOrigin: false,(\\r?\\n)/;\n\n/**\n * Moves the CLI's own host-keeping entry to the origin-forwarding shape of\n * {@link proxyEntryCode}. Only the generated layout in a config that carries\n * the credential-policy marker qualifies, and a config that already sets\n * `xfwd` has made its own forwarding choice: a hand-written `/__nextgen` entry\n * is never touched.\n */\nfunction forwardAppOrigin(source: string): string {\n if (!source.includes(PROXY_CREDENTIAL_POLICY_MARKER) || /\\bxfwd\\s*:/.test(source)) {\n return source;\n }\n return source.replace(\n HOST_KEEPING_ENTRY,\n (_entry, head: string, indent: string, eol: string) =>\n `${head}${indent}changeOrigin: true,${eol}${indent}xfwd: true,${eol}`,\n );\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, except the CLI's own earlier proxy\n * shapes, which are migrated in place: the unconditional bearer listener and\n * the host-keeping entry. Throws `E_VALIDATION` when the file is absent or the\n * config object cannot be reached (function-built/exotic configs), with a hint\n * to add the block manually.\n *\n * `previousPort` moves the app: a `server.port` still on that port is\n * rewritten to `devPort`, while any other pinned port stays the user's.\n */\nexport function viteProxyEdit(\n devPort: number,\n server: string,\n previousPort?: number,\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 if (workingSource !== undefined) {\n workingSource = forwardAppOrigin(workingSource);\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 (\n serverConfig.port === undefined ||\n (previousPort !== undefined && serverConfig.port === previousPort && devPort !== previousPort)\n ) {\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/** The slice of a babel AST node {@link cliConfigureStatements} walks. */\ninterface AstNode {\n readonly type: string;\n readonly start: number;\n readonly end: number;\n /** An object property's key: an identifier's `name`, a string literal's `value`. */\n readonly key?: { readonly name?: string; readonly value?: unknown };\n readonly value?: AstNode;\n readonly body?: AstNode | ReadonlyArray<AstNode>;\n readonly properties?: ReadonlyArray<AstNode>;\n}\n\n/** The property `name` of an object literal node, if it has one. */\nfunction propertyOf(node: AstNode | undefined, name: string): AstNode | undefined {\n return node?.properties?.find(\n (property) =>\n (property.type === \"ObjectProperty\" || property.type === \"ObjectMethod\") &&\n (property.key?.name === name || property.key?.value === name),\n );\n}\n\n/**\n * `source` as the tokens a formatter leaves alone, so Prettier's or Biome's\n * layout of what the CLI wrote still matches it: no whitespace, semicolons or\n * trailing commas, double quotes, and a lone arrow-function parameter in\n * parentheses.\n */\nfunction fingerprint(source: string): string {\n return source\n .replace(/\\s+/g, \"\")\n .replace(/'/g, '\"')\n .replace(/;/g, \"\")\n .replace(/,(?=[)\\]}])/g, \"\")\n .replace(/(^|[(,:=])([A-Za-z_$][\\w$]*)=>/g, \"$1($2)=>\");\n}\n\n/**\n * The statements of the `configure(proxy)` body of the `/__nextgen` entry the\n * CLI wrote: one carrying the credential-policy marker and the CLI's own\n * exchange-only bearer hook, however it was formatted since. A hand-written\n * entry, or one whose hook was changed, yields `undefined`.\n */\nfunction cliConfigureStatements(\n config: unknown,\n source: string,\n): ReadonlyArray<AstNode> | undefined {\n const root = (config as { $ast?: AstNode }).$ast;\n const proxy = propertyOf(propertyOf(root, \"server\")?.value, \"proxy\")?.value;\n const entry = propertyOf(proxy, PROXY_PATH);\n const configure = propertyOf(entry?.value, \"configure\");\n const fn = configure?.type === \"ObjectMethod\" ? configure : configure?.value;\n const body = fn?.body;\n if (!entry || !body || Array.isArray(body) || (body as AstNode).type !== \"BlockStatement\") {\n return undefined;\n }\n const block = body as AstNode;\n const statements = block.body as ReadonlyArray<AstNode>;\n const owned =\n source.slice(entry.start, entry.end).includes(PROXY_CREDENTIAL_POLICY_MARKER) &&\n fingerprint(source.slice(block.start, block.end)).includes(fingerprint(bearerListener(\"\")));\n return owned && statements.length > 0 ? statements : undefined;\n}\n\n/** What the session-cookie edit and its verdict call the file they read. */\nconst VITE_CONFIG_LABEL = \"the Vite config (vite.config.*)\";\n\n/**\n * The statements of the CLI's own `/__nextgen` entry's `configure(proxy)` body\n * in `source` (LF line ends), or `undefined` when there is no such entry.\n */\nfunction cliEntryStatements(source: string): ReadonlyArray<AstNode> | undefined {\n // At tabWidth 1 the node offsets index the source itself; at recast's\n // default a tab counts as four, which a tab-indented config would expose.\n const mod = parseConfigModule(source, VITE_CONFIG_LABEL, { tabWidth: 1 });\n return cliConfigureStatements(resolveDefaultExportObject(mod, VITE_CONFIG_LABEL), source);\n}\n\n/**\n * Builds the `edit` transform that gives the CLI's own `/__nextgen` entry the\n * session-cookie hooks (ADR 073), for apps set up before the entry carried\n * them: the hooks go after the last statement of its `configure(proxy)` body,\n * at that statement's indentation, and nothing else in the file changes. A\n * config whose entry carries them already, a hand-written entry, and one whose\n * bearer hook was changed are returned untouched; {@link viteSessionCookieVerdict}\n * tells the doctor which it is. Line ends are the file's own (CRLF or LF).\n * Throws `E_VALIDATION`, as {@link viteProxyEdit} does, when the file is absent\n * or unreadable.\n */\nexport function viteSessionCookieEdit(): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n // Throws the E_VALIDATION a missing config gets everywhere.\n parseConfigModule(source, VITE_CONFIG_LABEL, { tabWidth: 1 });\n return \"\";\n }\n return withLfLineEnds(source, (text) => {\n if (text.includes(SESSION_COOKIE_MARKER)) {\n return text;\n }\n const last = cliEntryStatements(text)?.at(-1);\n if (!last) {\n return text;\n }\n const lineStart = text.lastIndexOf(\"\\n\", last.start - 1) + 1;\n const indent = /^[\\t ]*/.exec(text.slice(lineStart, last.start))?.[0] ?? \"\";\n return `${text.slice(0, last.end)}\\n${indented(viteSessionCookieStatements(), indent)}${text.slice(last.end)}`;\n });\n };\n}\n\n/**\n * Whether the Vite config carries the session-cookie hooks, for the doctor.\n * The CLI's entry without them is `detached` (`doctor --fix` adds them), and so\n * is a config without the CLI's entry, which the proxy edit writes with them.\n * An entry the CLI wrote whose bearer hook was changed by hand is `unknown`:\n * the edit cannot place the hooks there, and only the developer can.\n */\nexport function viteSessionCookieVerdict(source: string): WiringVerdict {\n const text = lfText(source);\n if (text.includes(SESSION_COOKIE_MARKER)) {\n return \"applied\";\n }\n if (cliEntryStatements(text)) {\n return \"detached\";\n }\n return text.includes(PROXY_CREDENTIAL_POLICY_MARKER)\n ? {\n unknown:\n \"its /__nextgen proxy entry was changed since zitadel setup wrote it, so the session-cookie hooks (ADR 073) must be added by hand\",\n }\n : \"detached\";\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-ops that non-destructively merge the\n * `/__nextgen` dev proxy into the project's Vite config. A patcher opts in by\n * declaring `implements ViteSupport` and spreading {@link viteProxyOp} and\n * {@link viteSessionCookieOp} into its `routeOps`, so the proxy logic is\n * written once and reused everywhere — no 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, previousPort?: number): FileOp;\n /** The `edit` file-op that gives a proxy setup wrote before its session-cookie hooks. */\n viteSessionCookieOp(): FileOp;\n}\n\n/** Builds the shared Vite-config proxy {@link FileOp} for a {@link ViteSupport} patcher. */\nexport function buildViteProxyOp(devPort: number, server: string, previousPort?: number): FileOp {\n return {\n kind: \"edit\",\n path: [...VITE_CONFIG_PATHS],\n edit: viteProxyEdit(devPort, server, previousPort),\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\n/** Builds the shared session-cookie {@link FileOp} for a {@link ViteSupport} patcher. */\nexport function buildViteSessionCookieOp(): FileOp {\n return {\n kind: \"edit\",\n path: [...VITE_CONFIG_PATHS],\n edit: viteSessionCookieEdit(),\n // A session cookie per project (ADR 073) keeps the Console and the app\n // from signing each other out on localhost. Sign-in works without it, so\n // the doctor only warns while it is missing.\n wiring: \"convenience\",\n verify: viteSessionCookieVerdict,\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 \"@qwik.dev/core\";\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 { sdkVersionForCli } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { PUBLIC_PROJECT_ID_VARIABLE } from \"../public-project-id\";\nimport { assertMountsRootComponent, type RootMount, viteEntry } from \"../root-component\";\nimport { type ViteSupport, buildViteProxyOp, buildViteSessionCookieOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-qwik\";\n\n/** The managed root component, and how `main.tsx` renders it. */\nconst ROOT: RootMount = {\n path: \"src/app.tsx\",\n binding: { name: \"App\", named: true },\n extension: true,\n calls: [\"render\"],\n mounts: \"jsx\",\n};\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, previousPort?: number): FileOp {\n return buildViteProxyOp(devPort, server, previousPort);\n }\n\n viteSessionCookieOp(): FileOp {\n return buildViteSessionCookieOp();\n }\n\n protected override async preflight(_ctx: PatchContext, cwd: string): Promise<void> {\n await assertMountsRootComponent(cwd, await viteEntry(cwd), ROOT);\n }\n\n protected devPortOps(ctx: PatchContext, previousPort: number | undefined): FileOp[] {\n return [this.viteProxyOp(ctx.framework.devPort, ctx.server, previousPort)];\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: ROOT.path, contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n this.viteSessionCookieOp(),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n {\n kind: \"merge-env\",\n path: \".env.example\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.qwik]: \"\" },\n },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.qwik]: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: sdkVersionForCli(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [ROOT.path];\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// Enforce the dark surface the Zitadel widgets are designed for, so pages never\n// follow the OS light/dark setting.\nconst WIDGET_WRAP = \"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\";\n\n/**\n * `src/routes/plugin@nextgen.ts` — the Qwik Router root `onRequest` plugin.\n * `createNextgenOnRequest` proxies `/__nextgen/*` to the auth backend (attaching\n * the project service-key from `ZITADEL_PROJECT_SECRET`), verifies the session\n * JWT, and redirects unauthenticated requests away from protected routes. `url`\n * and `projectSecret` are read per request from Qwik Router's `ev.env` (which\n * carries `.env.local`), so only the route policy is spelled out here. The\n * managed marker sits in a JS comment.\n */\nexport function pluginTemplate(): string {\n return `${MANAGED_MARKER}\nimport { createNextgenOnRequest } from \"@zitadel/sdk-qwik-router/server\";\n\nexport const onRequest = createNextgenOnRequest({\n protectedRoutes: [\"/profile\"],\n loginPath: \"/login\",\n});\n`;\n}\n\n/** `src/routes/index.tsx` — the landing chooser linking to login/register/profile. */\nexport function indexPageTemplate(): string {\n return `${MANAGED_MARKER}\nimport { component$ } from \"@qwik.dev/core\";\n\nexport default component$(() => (\n <main style=\"position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;color-scheme:dark;color:#f4f4f6;font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;line-height:1.5;letter-spacing:normal;text-align:center\">\n <section style=\"width:100%;max-width:560px\">\n <p style=\"margin:0 0 12px;color:#9ca3af;font-size:14px\">Zitadel auth</p>\n <h1 style=\"margin:0 0 24px;font-size:32px;line-height:1.15;font-weight:600;color:#f4f4f6\">Sign in, create an account, or open your profile.</h1>\n <div style=\"display:flex;flex-wrap:wrap;gap:12px;justify-content:center\">\n <a href=\"/login\" style=\"padding:10px 16px;border-radius:8px;background:#f4f4f6;color:#0f0f11;text-decoration:none;font-weight:600;font-size:14px\">Sign in</a>\n <a href=\"/register\" style=\"padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px\">Create account</a>\n <a href=\"/profile\" style=\"padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px\">Profile</a>\n </div>\n </section>\n </main>\n));\n`;\n}\n\n/**\n * A login/register page. Renders the idiomatic `<ZitadelLogin>` Qwik component\n * from `@zitadel/sdk-qwik` (typed props, callback events). `configureZitadel`\n * returns the project handle at module scope; the public project id comes from\n * `PUBLIC_ZITADEL_PROJECT_ID` via Qwik's `import.meta.env`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the widget, restoring work-email copy on top of\n * the widget's neutral built-in dictionaries.\n */\nfunction authPage(purpose: \"login\" | \"register\", ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, businessLocales, configureZitadel\"\n : \"ZitadelLogin, configureZitadel\";\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$ } from \"@qwik.dev/core\";\nimport { ${importNames} } from \"@zitadel/sdk-qwik\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.PUBLIC_ZITADEL_PROJECT_ID ?? \"\",\n proxyPath: \"${PROXY_PATH}\",\n});\n\nexport default component$(() => {\n return (\n <div style=\"${WIDGET_WRAP}\">\n <ZitadelLogin project={project}${localesAttr} purpose=\"${purpose}\" postSignInUrl=\"/profile\" />\n </div>\n );\n});\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/** `src/routes/profile/index.tsx` — the signed-in view: the \"signed in as\" session card, with sign-out. */\nexport function profilePageTemplate(): string {\n return `${MANAGED_MARKER}\nimport { component$ } from \"@qwik.dev/core\";\nimport { ZitadelSession, configureZitadel } from \"@zitadel/sdk-qwik\";\n\nconst project = configureZitadel({\n projectId: import.meta.env.PUBLIC_ZITADEL_PROJECT_ID ?? \"\",\n proxyPath: \"${PROXY_PATH}\",\n});\n\nexport default component$(() => {\n return (\n <div style=\"${WIDGET_WRAP}\">\n <ZitadelSession project={project} postSignOutUrl=\"/login\" />\n </div>\n );\n});\n`;\n}\n","import { join } from \"node:path\";\n\nimport { sdkVersionForCli } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { devScriptPortOp } from \"../dev-script-port\";\nimport {\n indexPageTemplate,\n loginPageTemplate,\n pluginTemplate,\n profilePageTemplate,\n registerPageTemplate,\n} from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-qwik-router\";\n/**\n * The idiomatic Qwik component library that ships the `<ZitadelLogin>` /\n * `<ZitadelSession>` Qwik components the routes render. The server SDK above is\n * plumbing only; the widget comes from here, so a Qwik Router app gets the native\n * Qwik component (typed props, callback events) rather than the bare element.\n */\nconst COMPONENT_DEPENDENCY = \"@zitadel/sdk-qwik\";\n\n/**\n * Rule-based patcher for a Qwik Router app. Like Next.js and SvelteKit, Qwik Router\n * proxies the backend and verifies the session through a server entrypoint —\n * here the `@zitadel/sdk-qwik-router` `onRequest` plugin in\n * `src/routes/plugin@nextgen.ts`. Contributes the landing/login/register/profile\n * file-based routes (the idiomatic `<ZitadelLogin>`/`<ZitadelSession>` Qwik\n * components from `@zitadel/sdk-qwik`), the public project-id env var, and both\n * deps. No config edit is needed — the plugin is a plain route file, so (like\n * Next) every managed file carries the marker.\n */\nexport class QwikRouterPatcher extends AbstractRulePatcher {\n canPatch(framework: string): boolean {\n return framework === \"qwik-router\";\n }\n\n protected devPortOps(ctx: PatchContext): FileOp[] {\n return [devScriptPortOp(ctx.issuer, { strictPort: true })];\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n const src = (rel: string) => join(ctx.framework.appDir, rel);\n return [\n // The auth boundary is written on every setup; a pre-existing plugin at\n // this exact path is a genuine conflict the file-writer refuses (and\n // --force replaces), the same way Next writes its request boundary.\n { kind: \"write\", path: src(\"routes/plugin@nextgen.ts\"), contents: pluginTemplate() },\n // The landing page is written only when setup created the skeleton\n // itself — a pre-existing app keeps its own landing page (ADR 044),\n // same as the Next/Nuxt homepage.\n ...(ctx.scaffoldedFramework\n ? ([\n { kind: \"write\", path: src(\"routes/index.tsx\"), contents: indexPageTemplate() },\n ] satisfies FileOp[])\n : []),\n { kind: \"write\", path: src(\"routes/login/index.tsx\"), contents: loginPageTemplate(ctx) },\n {\n kind: \"write\",\n path: src(\"routes/register/index.tsx\"),\n contents: registerPageTemplate(ctx),\n },\n { kind: \"write\", path: src(\"routes/profile/index.tsx\"), contents: profilePageTemplate() },\n // Pin the dev script to the origin setup registered; --strictPort makes\n // Vite exit instead of drifting to a port the project does not allow.\n devScriptPortOp(ctx.issuer, { strictPort: true }),\n { kind: \"merge-env\", path: \".env.example\", entries: { PUBLIC_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { PUBLIC_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n // Qwik's convention: `devDependencies` are bundled into the server\n // build, `dependencies` stay external (the starter's `vite.config.ts`\n // documents this). Ecosystem packages like this one belong in\n // `devDependencies`. That config also throws when one package is\n // listed in both sections, so the writer moves an existing\n // `dependencies` entry rather than duplicating it.\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: sdkVersionForCli(ctx.cliVersion),\n dev: true,\n },\n {\n // The component library is a Qwik-ecosystem package too, so it is\n // bundled the same way.\n kind: \"add-dep\",\n name: COMPONENT_DEPENDENCY,\n version: sdkVersionForCli(ctx.cliVersion),\n dev: true,\n },\n ];\n }\n\n protected routeFiles(view: PatchView): ReadonlyArray<string> {\n const src = (rel: string) => join(view.framework.appDir, rel);\n return [\n src(\"routes/plugin@nextgen.ts\"),\n src(\"routes/index.tsx\"),\n src(\"routes/login/index.tsx\"),\n src(\"routes/register/index.tsx\"),\n src(\"routes/profile/index.tsx\"),\n ];\n }\n\n protected override infrastructureFiles(view: PatchView): ReadonlyArray<string> {\n // The auth boundary — proxy, session check and route protection — is\n // infrastructure: without it /__nextgen/* 404s and protected routes open, so\n // doctor fails rather than warning about a missing page.\n return [join(view.framework.appDir, \"routes/plugin@nextgen.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 landing page stays user-owned (see routeOps), so\n // the managed-files check must not expect it on a manifest-less app.\n return [join(view.framework.appDir, \"routes/index.tsx\")];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY, COMPONENT_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n // The dev script's port is pinned in place by an `edit` op eject can't\n // revert, so it is listed as a manual cleanup step.\n return [\"package.json\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Qwik Router integration\",\n detail:\n \"Wrote src/routes/plugin@nextgen.ts (@zitadel/sdk-qwik-router onRequest) plus landing/login/register/profile routes using @zitadel/sdk-qwik.\",\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 { sdkVersionForCli } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { PUBLIC_PROJECT_ID_VARIABLE } from \"../public-project-id\";\nimport { assertMountsRootComponent, type RootMount, viteEntry } from \"../root-component\";\nimport { type ViteSupport, buildViteProxyOp, buildViteSessionCookieOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-react\";\n\n/** The managed root component, and how `main.tsx` renders it. */\nconst ROOT: RootMount = {\n path: \"src/App.tsx\",\n binding: { name: \"App\", named: false },\n extension: true,\n calls: [\"render\", \"hydrateRoot\", \"hydrate\"],\n mounts: \"jsx\",\n};\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, previousPort?: number): FileOp {\n return buildViteProxyOp(devPort, server, previousPort);\n }\n\n viteSessionCookieOp(): FileOp {\n return buildViteSessionCookieOp();\n }\n\n protected override async preflight(_ctx: PatchContext, cwd: string): Promise<void> {\n await assertMountsRootComponent(cwd, await viteEntry(cwd), ROOT);\n }\n\n protected devPortOps(ctx: PatchContext, previousPort: number | undefined): FileOp[] {\n return [this.viteProxyOp(ctx.framework.devPort, ctx.server, previousPort)];\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: ROOT.path, contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n this.viteSessionCookieOp(),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n {\n kind: \"merge-env\",\n path: \".env.example\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.react]: \"\" },\n },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.react]: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: sdkVersionForCli(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [ROOT.path];\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 { sdkVersionForCli } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { PUBLIC_PROJECT_ID_VARIABLE } from \"../public-project-id\";\nimport { assertMountsRootComponent, type RootMount, viteEntry } from \"../root-component\";\nimport { type ViteSupport, buildViteProxyOp, buildViteSessionCookieOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-solid\";\n\n/** The managed root component, and how `index.tsx` renders it. */\nconst ROOT: RootMount = {\n path: \"src/App.tsx\",\n binding: { name: \"App\", named: false },\n extension: true,\n calls: [\"render\", \"hydrate\"],\n mounts: \"jsx\",\n};\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, previousPort?: number): FileOp {\n return buildViteProxyOp(devPort, server, previousPort);\n }\n\n viteSessionCookieOp(): FileOp {\n return buildViteSessionCookieOp();\n }\n\n protected override async preflight(_ctx: PatchContext, cwd: string): Promise<void> {\n await assertMountsRootComponent(cwd, await viteEntry(cwd), ROOT);\n }\n\n protected devPortOps(ctx: PatchContext, previousPort: number | undefined): FileOp[] {\n return [this.viteProxyOp(ctx.framework.devPort, ctx.server, previousPort)];\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: ROOT.path, contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n this.viteSessionCookieOp(),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n {\n kind: \"merge-env\",\n path: \".env.example\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.solid]: \"\" },\n },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.solid]: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: sdkVersionForCli(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [ROOT.path];\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 { ZitadelError } from \"../../../../errors\";\n\nconst MIDDLEWARE_PATH = \"./src/middleware.ts\";\n\n/**\n * Builds the pure `edit` transform the file-writer applies to a SolidStart\n * project's `vite.config.*`: registers the managed `src/middleware.ts` (which\n * wires the server-side proxy + session middleware) by adding the `middleware`\n * option to the `solidStart()` plugin call.\n *\n * SolidStart 2 reads middleware from the `solidStart({ middleware })` plugin\n * option (`@solidjs/start/config`), not from a top-level `app.config.ts` field\n * as SolidStart 1 did — so the edit targets the plugin call. Because the option\n * lives inside a call-expression argument (which magicast's object helpers do\n * not model), this is a small, idempotent source transform rather than a\n * magicast object edit: it injects into a bare `solidStart()` or merges into an\n * existing `solidStart({ ... })`, and returns the source untouched once the\n * `middleware` option is present. Throws `E_VALIDATION` when no `solidStart(`\n * plugin call is found (an unexpected SolidStart config shape).\n */\nexport function solidStartConfigEdit(): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"Cannot edit the SolidStart Vite config: file not found\",\n {\n hint: \"Run setup from a SolidStart project that has a vite.config.ts.\",\n },\n );\n }\n\n const callIndex = source.indexOf(\"solidStart(\");\n if (callIndex === -1) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"Cannot wire middleware: no solidStart() plugin call found in the Vite config\",\n {\n hint: \"Ensure vite.config.ts registers the solidStart() plugin from @solidjs/start/config.\",\n },\n );\n }\n\n const openParen = callIndex + \"solidStart(\".length - 1;\n const args = readBalanced(source, openParen);\n const inner = args.text.slice(1, -1).trim();\n\n // Already wired (idempotent): the call carries a `middleware` option, or our\n // managed path is present anywhere in the config.\n if (/(^|[{,\\s])middleware\\s*:/.test(inner) || source.includes(MIDDLEWARE_PATH)) {\n return source;\n }\n\n const option = `middleware: ${JSON.stringify(MIDDLEWARE_PATH)}`;\n let replacement: string;\n if (inner === \"\") {\n // solidStart() -> solidStart({ middleware: \"./src/middleware.ts\" })\n replacement = `solidStart({ ${option} })`;\n } else if (inner.startsWith(\"{\")) {\n // solidStart({ ...existing }) -> inject the option after the opening\n // brace. `args.text` is the whole argument list INCLUDING the parens\n // (e.g. \"({ ssr: true })\"), so reuse it verbatim prefixed by `solidStart`\n // — building from `solidStart(` + args.text would double the opening paren\n // and produce an invalid config.\n const braceIdx = args.text.indexOf(\"{\");\n replacement = `solidStart${args.text.slice(0, braceIdx + 1)} ${option},${args.text.slice(braceIdx + 1)}`;\n } else {\n // Unusual: a non-object argument (e.g. a variable). Don't guess — fail loud.\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"Cannot wire middleware: solidStart() is called with a non-object argument\",\n {\n hint: 'Pass an options object to solidStart(), e.g. solidStart({ middleware: \"./src/middleware.ts\" }).',\n },\n );\n }\n\n return source.slice(0, callIndex) + replacement + source.slice(args.end);\n };\n}\n\n/**\n * Returns the parenthesised text starting at `openParenIndex` (which must point\n * at a `(`), respecting nested parens/braces/brackets, string literals and line/block comments, plus\n * the index just past the closing `)`.\n */\nfunction readBalanced(source: string, openParenIndex: number): { text: string; end: number } {\n let depth = 0;\n let quote: string | null = null;\n for (let i = openParenIndex; i < source.length; i += 1) {\n const ch = source[i];\n if (quote) {\n if (ch === \"\\\\\") {\n i += 1;\n } else if (ch === quote) {\n quote = null;\n }\n continue;\n }\n if (ch === \"/\" && source[i + 1] === \"/\") {\n const newline = source.indexOf(\"\\n\", i);\n if (newline === -1) break;\n i = newline;\n } else if (ch === \"/\" && source[i + 1] === \"*\") {\n const close = source.indexOf(\"*/\", i + 2);\n if (close === -1) break;\n i = close + 1;\n } else if (ch === '\"' || ch === \"'\" || ch === \"`\") {\n quote = ch;\n } else if (ch === \"(\" || ch === \"{\" || ch === \"[\") {\n depth += 1;\n } else if (ch === \")\" || ch === \"}\" || ch === \"]\") {\n depth -= 1;\n if (depth === 0) {\n return { text: source.slice(openParenIndex, i + 1), end: i + 1 };\n }\n }\n }\n throw new ZitadelError(\"E_VALIDATION\", \"Malformed Vite config: unbalanced solidStart() call\");\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n// Enforce the dark surface the Zitadel widgets are designed for, so pages never\n// follow the OS light/dark setting.\nconst WIDGET_WRAP = \"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\";\n\n/**\n * `src/middleware.ts` — the SolidStart middleware entrypoint. `createNextgenMiddleware`\n * returns a `{ onRequest: [...] }` config object that proxies `/__nextgen/*` to\n * the auth backend (attaching the project service-key from\n * `ZITADEL_PROJECT_SECRET`), verifies the session JWT, and redirects\n * unauthenticated requests away from protected routes. `url` and `projectSecret`\n * default from `process.env` (seeded in `.env.local`), so only the route policy\n * is spelled out here. The managed marker sits in a JS comment.\n *\n * SolidStart 2 imports this module's default export and registers it as an\n * array of h3 middleware (`middleware.map(...)`). The config object is wrapped\n * in SolidStart's own `createMiddleware`, which turns `{ onRequest }` into that\n * array — exporting the bare config would leave SolidStart with nothing to run,\n * so `/__nextgen/*` would 404. The SDK stays framework-agnostic; the wrap lives\n * here in the generated app.\n */\nexport function middlewareTemplate(): string {\n return `${MANAGED_MARKER}\nimport { createMiddleware } from \"@solidjs/start/middleware\";\nimport { createNextgenMiddleware } from \"@zitadel/sdk-solid-start/server\";\n\nexport default createMiddleware(\n createNextgenMiddleware({\n protectedRoutes: [\"/profile\"],\n loginPath: \"/login\",\n }),\n);\n`;\n}\n\n/** `src/routes/index.tsx` — the landing chooser linking to login/register/profile. */\nexport function indexPageTemplate(): string {\n return `${MANAGED_MARKER}\nexport default function Index() {\n return (\n <main style=\"position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;color-scheme:dark;color:#f4f4f6;font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;line-height:1.5;letter-spacing:normal;text-align:center\">\n <section style=\"width:100%;max-width:560px\">\n <p style=\"margin:0 0 12px;color:#9ca3af;font-size:14px\">Zitadel auth</p>\n <h1 style=\"margin:0 0 24px;font-size:32px;line-height:1.15;font-weight:600;color:#f4f4f6\">Sign in, create an account, or open your profile.</h1>\n <div style=\"display:flex;flex-wrap:wrap;gap:12px;justify-content:center\">\n <a href=\"/login\" style=\"padding:10px 16px;border-radius:8px;background:#f4f4f6;color:#0f0f11;text-decoration:none;font-weight:600;font-size:14px\">Sign in</a>\n <a href=\"/register\" style=\"padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px\">Create account</a>\n <a href=\"/profile\" style=\"padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px\">Profile</a>\n </div>\n </section>\n </main>\n );\n}\n`;\n}\n\n/**\n * A login/register page rendering the `<ZitadelLogin>` widget from\n * `@zitadel/sdk-solid`, loaded with SolidStart's `clientOnly`. The widget module\n * imports `@zitadel/components`, which registers Lit custom elements by calling\n * `customElements.define` at import time — undefined during SSR, so a static\n * import would crash the server render and the page would come back empty.\n * `clientOnly` defers the import to the browser, so the route renders on the\n * server and the widget mounts after hydration (like Nuxt's `<ClientOnly>`).\n *\n * The public project id (`VITE_ZITADEL_PROJECT_ID`; Vite only exposes\n * `VITE_`-prefixed env to the client) and proxy path are passed as props rather\n * than a `configureZitadel` handle — building the handle here would require\n * importing `@zitadel/sdk-solid` at module scope, reintroducing the SSR crash.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the widget, restoring work-email copy on top of\n * the widget's neutral built-in dictionaries. The overlay ships in the same\n * client-only module, so the loader wraps the widget to apply it.\n */\nfunction authPage(purpose: \"login\" | \"register\", ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const loader = business\n ? `import type { ComponentProps } from \"solid-js\";\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Have the loader return the\n// plain ZitadelLogin to fall back to the neutral wording.\nconst ZitadelLogin = clientOnly(() =>\n import(\"@zitadel/sdk-solid\").then(({ ZitadelLogin: Login, businessLocales }) => ({\n default: (props: ComponentProps<typeof Login>) => (\n <Login {...props} locales={businessLocales} />\n ),\n })),\n);`\n : `\nconst ZitadelLogin = clientOnly(() =>\n import(\"@zitadel/sdk-solid\").then((m) => ({ default: m.ZitadelLogin })),\n);`;\n return `${MANAGED_MARKER}\nimport { clientOnly } from \"@solidjs/start\";\n${loader}\n\nexport default function ${purpose === \"login\" ? \"Login\" : \"Register\"}() {\n return (\n <main style=\"${WIDGET_WRAP}\">\n <ZitadelLogin\n projectId={import.meta.env.VITE_ZITADEL_PROJECT_ID ?? \"\"}\n proxyPath=\"${PROXY_PATH}\"\n purpose=\"${purpose}\"\n postSignInUrl=\"/profile\"\n />\n </main>\n );\n}\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/**\n * `src/routes/profile.tsx` — the signed-in view: the \"signed in as\" session card, with sign-out. Loaded\n * with `clientOnly` for the same reason as the auth pages: `@zitadel/sdk-solid`\n * registers Lit custom elements at import time, which would crash SSR.\n */\nexport function profilePageTemplate(): string {\n return `${MANAGED_MARKER}\nimport { clientOnly } from \"@solidjs/start\";\n\nconst ZitadelSession = clientOnly(() =>\n import(\"@zitadel/sdk-solid\").then((m) => ({ default: m.ZitadelSession })),\n);\n\nexport default function Profile() {\n return (\n <main style=\"${WIDGET_WRAP}\">\n <ZitadelSession\n projectId={import.meta.env.VITE_ZITADEL_PROJECT_ID ?? \"\"}\n proxyPath=\"${PROXY_PATH}\"\n postSignOutUrl=\"/login\"\n />\n </main>\n );\n}\n`;\n}\n","import { join } from \"node:path\";\n\nimport { sdkVersionForCli } 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 { solidStartConfigEdit } from \"./vite-config\";\nimport {\n indexPageTemplate,\n loginPageTemplate,\n middlewareTemplate,\n profilePageTemplate,\n registerPageTemplate,\n} from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-solid-start\";\n/**\n * The idiomatic Solid component library that ships the `<ZitadelLogin>` /\n * `<ZitadelSession>` Solid components the routes render. The server SDK above is\n * plumbing only; the widget comes from here, so a SolidStart app gets the native\n * Solid component (typed props, callback events) rather than the bare element.\n */\nconst COMPONENT_DEPENDENCY = \"@zitadel/sdk-solid\";\n\nconst VITE_CONFIG_PATHS = configCandidates(\"vite.config\");\n\n/**\n * Rule-based patcher for a SolidStart app. Like Next.js and Nuxt, SolidStart\n * proxies the backend and verifies the session through server middleware — here\n * the `@zitadel/sdk-solid-start` `createNextgenMiddleware` in `src/middleware.ts`,\n * registered via the `solidStart({ middleware })` plugin option in a\n * non-destructive `vite.config.*` edit (SolidStart 2 reads middleware from the\n * Vite plugin, not a top-level `app.config.ts` field). Contributes the\n * landing/login/register/profile file-based routes (the idiomatic\n * `<ZitadelLogin>`/`<ZitadelSession>` Solid components from `@zitadel/sdk-solid`),\n * the public project-id env var, and both deps.\n */\nexport class SolidStartPatcher extends AbstractRulePatcher {\n canPatch(framework: string): boolean {\n return framework === \"solid-start\";\n }\n\n protected devPortOps(ctx: PatchContext): FileOp[] {\n return [devScriptPortOp(ctx.issuer, { strictPort: true })];\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n const src = (rel: string) => join(ctx.framework.appDir, rel);\n return [\n // The auth boundary is written on every setup; a pre-existing middleware\n // at this exact path is a genuine conflict the file-writer refuses (and\n // --force replaces), the same way Next writes its request boundary.\n { kind: \"write\", path: src(\"middleware.ts\"), contents: middlewareTemplate() },\n // The landing page is written only when setup created the skeleton\n // itself — a pre-existing app keeps its own landing page (ADR 044),\n // same as the Next/Nuxt homepage.\n ...(ctx.scaffoldedFramework\n ? ([\n { kind: \"write\", path: src(\"routes/index.tsx\"), contents: indexPageTemplate() },\n ] satisfies FileOp[])\n : []),\n { kind: \"write\", path: src(\"routes/login.tsx\"), contents: loginPageTemplate(ctx) },\n { kind: \"write\", path: src(\"routes/register.tsx\"), contents: registerPageTemplate(ctx) },\n { kind: \"write\", path: src(\"routes/profile.tsx\"), contents: profilePageTemplate() },\n {\n kind: \"edit\",\n path: [...VITE_CONFIG_PATHS],\n edit: solidStartConfigEdit(),\n // Registers the auth middleware: without it doctor must fail, not pass.\n wiring: \"infrastructure\",\n },\n // Pin the dev script to the origin setup registered; --strictPort makes\n // Vite exit instead of drifting to a port the project does not allow.\n devScriptPortOp(ctx.issuer, { strictPort: true }),\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: sdkVersionForCli(ctx.cliVersion),\n },\n {\n kind: \"add-dep\",\n name: COMPONENT_DEPENDENCY,\n version: sdkVersionForCli(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(view: PatchView): ReadonlyArray<string> {\n const src = (rel: string) => join(view.framework.appDir, rel);\n return [\n src(\"middleware.ts\"),\n src(\"routes/index.tsx\"),\n src(\"routes/login.tsx\"),\n src(\"routes/register.tsx\"),\n src(\"routes/profile.tsx\"),\n ];\n }\n\n protected override infrastructureFiles(view: PatchView): ReadonlyArray<string> {\n // The auth boundary — proxy, session check and route protection — is\n // infrastructure: without it /__nextgen/* 404s and protected routes open, so\n // doctor fails rather than warning about a missing page.\n return [join(view.framework.appDir, \"middleware.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 landing page stays user-owned (see routeOps), so\n // the managed-files check must not expect it on a manifest-less app.\n return [join(view.framework.appDir, \"routes/index.tsx\")];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY, COMPONENT_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\", \"package.json\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"SolidStart integration\",\n detail:\n \"Wrote src/middleware.ts (@zitadel/sdk-solid-start) plus landing/login/register/profile routes using @zitadel/sdk-solid components and wired the middleware via solidStart({ middleware }) in 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 { sdkVersionForCli } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { PUBLIC_PROJECT_ID_VARIABLE } from \"../public-project-id\";\nimport { assertMountsRootComponent, type RootMount, viteEntry } from \"../root-component\";\nimport { type ViteSupport, buildViteProxyOp, buildViteSessionCookieOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-svelte\";\n\n/**\n * The managed root component, and how `main.ts` mounts it: `mount(App, …)`,\n * or `new App(…)` before Svelte 5.\n */\nconst ROOT: RootMount = {\n path: \"src/App.svelte\",\n binding: { name: \"App\", named: false },\n extension: true,\n calls: [\"mount\", \"hydrate\"],\n mounts: \"argument\",\n constructs: \".svelte\",\n};\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, previousPort?: number): FileOp {\n return buildViteProxyOp(devPort, server, previousPort);\n }\n\n viteSessionCookieOp(): FileOp {\n return buildViteSessionCookieOp();\n }\n\n protected override async preflight(_ctx: PatchContext, cwd: string): Promise<void> {\n await assertMountsRootComponent(cwd, await viteEntry(cwd), ROOT);\n }\n\n protected devPortOps(ctx: PatchContext, previousPort: number | undefined): FileOp[] {\n return [this.viteProxyOp(ctx.framework.devPort, ctx.server, previousPort)];\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: ROOT.path, contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n this.viteSessionCookieOp(),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n {\n kind: \"merge-env\",\n path: \".env.example\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.svelte]: \"\" },\n },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.svelte]: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: sdkVersionForCli(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [ROOT.path];\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 { ZitadelError } from \"../../../../errors\";\nimport { withLfLineEnds } from \"../utils/line-ends\";\nimport { parseConfigModule } from \"../utils/magicast\";\n\n/**\n * The settings the hook passes to `createNextgenHandle`, read from\n * `$app/env/private`. SvelteKit keeps a declared variable server-only unless it\n * is marked `public`, and shows the description on hover.\n */\nconst HOOK_VARIABLES = [\n { name: \"ZITADEL_URL\", description: \"The Zitadel server the hook proxies /__nextgen to.\" },\n {\n name: \"ZITADEL_PROJECT_SECRET\",\n description: \"The project's service key, sent on the session exchange only.\",\n },\n { name: \"ZITADEL_PROJECT_ID\", description: \"The project whose sessions count as signed in.\" },\n] as const;\n\n/** What the edit and its errors call the file it reads. */\nconst ENV_LABEL = \"src/env.ts\";\n\n/** One `defineEnvVars` entry, e.g. `ZITADEL_URL: { description: \"…\" }`. */\nfunction entry(variable: (typeof HOOK_VARIABLES)[number]): string {\n return `${variable.name}: { description: ${JSON.stringify(variable.description)} }`;\n}\n\n/**\n * `src/env.ts` for an app that has none: declares the hook's three settings, so\n * SvelteKit 3 serves them from `$app/env/private`, from `.env.local` in dev and\n * from the platform's environment in production. A missing one fails each\n * request with an error naming it, rather than the hook falling back to a\n * default backend. It carries no managed marker: SvelteKit reads every env\n * variable an app declares from this one file, so the developer's own entries\n * belong in it too.\n */\nexport function envTemplate(): string {\n return `import { defineEnvVars } from \"@sveltejs/kit/env\";\n\nexport const variables = defineEnvVars({\n${HOOK_VARIABLES.map((variable) => ` ${entry(variable)},`).join(\"\\n\")}\n});\n`;\n}\n\n/** The slice of a babel AST node {@link envVarsEdit} reads. */\ninterface AstNode {\n readonly type: string;\n readonly start: number;\n readonly end: number;\n /** An object property's key: an identifier's `name`, a string literal's `value`. */\n readonly key?: { readonly name?: string; readonly value?: unknown };\n readonly properties?: ReadonlyArray<AstNode>;\n}\n\n/**\n * Builds the `edit` transform for the app's env declarations (`src/env.ts`, or\n * an existing `src/env.js`): writes {@link envTemplate} when the app has none,\n * and otherwise adds whichever of the hook's settings its\n * `defineEnvVars({ ... })` call lacks after the last entry, at that entry's\n * indentation, leaving the rest of the file as it is. Idempotent: a file that\n * declares all three is returned untouched, which is how the doctor reads the\n * wiring as applied. Line ends are the file's own. Throws `E_VALIDATION` when\n * the file does not export `variables` as an object literal or as a call with\n * one as its argument, with a hint to declare the three by hand.\n */\nexport function envVarsEdit(): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n return envTemplate();\n }\n return withLfLineEnds(source, (text) => {\n const object = variablesObject(text);\n const properties = object.properties ?? [];\n const missing = HOOK_VARIABLES.filter(\n (variable) => !properties.some((property) => keyOf(property) === variable.name),\n );\n if (missing.length === 0) {\n return text;\n }\n const last = properties.at(-1);\n if (!last) {\n // `defineEnvVars({})`: one entry per line, a level in from the call.\n const lineStart = text.lastIndexOf(\"\\n\", object.start - 1) + 1;\n const indent = /^[\\t ]*/.exec(text.slice(lineStart))?.[0] ?? \"\";\n const unit = /^\\t/m.test(text) ? \"\\t\" : \" \";\n const body = missing.map((variable) => `${indent}${unit}${entry(variable)},\\n`).join(\"\");\n return `${text.slice(0, object.start)}{\\n${body}${indent}}${text.slice(object.end)}`;\n }\n const lineStart = text.lastIndexOf(\"\\n\", last.start - 1) + 1;\n // An object written on one line stays on one line.\n const separator =\n lineStart <= object.start\n ? \", \"\n : `,\\n${/^[\\t ]*/.exec(text.slice(lineStart, last.start))?.[0] ?? \"\"}`;\n const added = missing.map((variable) => `${separator}${entry(variable)}`).join(\"\");\n return `${text.slice(0, last.end)}${added}${text.slice(last.end)}`;\n });\n };\n}\n\n/**\n * The slice of a magicast proxy {@link variablesObject} reads. magicast's\n * published types don't model a named export, so it is described here.\n */\ninterface ProxyNode {\n readonly $type?: string;\n readonly $args?: ReadonlyArray<ProxyNode | undefined>;\n readonly $ast?: unknown;\n}\n\n/** The object literal of `export const variables`, read from `text` (LF line ends). */\nfunction variablesObject(text: string): AstNode {\n // At tabWidth 1 the node offsets index the source itself; at recast's\n // default a tab counts as four, which a tab-indented file would expose.\n const mod = parseConfigModule(text, ENV_LABEL, { tabWidth: 1 });\n const variables = (mod.exports as { variables?: ProxyNode } | undefined)?.variables;\n const object = variables?.$type === \"function-call\" ? variables.$args?.[0] : variables;\n if (object?.$type !== \"object\") {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Could not find the env variables ${ENV_LABEL} declares`,\n {\n hint: `Export them as \\`export const variables = defineEnvVars({ ... })\\` from @sveltejs/kit/env, or declare ${HOOK_VARIABLES.map((variable) => variable.name).join(\", \")} there by hand.`,\n },\n );\n }\n return object.$ast as AstNode;\n}\n\n/** The key an object literal property declares, if it is a plain one. */\nfunction keyOf(property: AstNode): unknown {\n return property.type === \"ObjectProperty\" || property.type === \"ObjectMethod\"\n ? (property.key?.name ?? property.key?.value)\n : undefined;\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n// Enforce the dark surface the Zitadel widgets are designed for, so pages never\n// follow the OS light/dark setting.\nconst WIDGET_WRAP = \"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\";\n\n/**\n * `src/hooks.server.ts` — the SvelteKit server hook. `createNextgenHandle`\n * proxies `/__nextgen/*` to the auth backend (attaching the project service-key\n * from `ZITADEL_PROJECT_SECRET`), verifies the session JWT, and redirects\n * unauthenticated requests away from protected routes. The settings come from\n * `$app/env/private`, declared in `src/env.ts` (see `envVarsEdit`), so the hook names no Node\n * global an app without `@types/node` cannot type-check. The managed marker\n * sits in a JS comment.\n */\nexport function hooksServerTemplate(): string {\n return `${MANAGED_MARKER}\nimport { ZITADEL_PROJECT_ID, ZITADEL_PROJECT_SECRET, ZITADEL_URL } from \"$app/env/private\";\nimport { createNextgenHandle } from \"@zitadel/sdk-sveltekit/server\";\n\nexport const handle = createNextgenHandle({\n url: ZITADEL_URL,\n projectSecret: ZITADEL_PROJECT_SECRET,\n projectId: ZITADEL_PROJECT_ID,\n protectedRoutes: [\"/profile\"],\n loginPath: \"/login\",\n});\n`;\n}\n\n/**\n * `src/routes/+layout.svelte` — applies the dark surface to every page and\n * renders the routed page with Svelte 5's `{@render children()}`; `<slot />`\n * is deprecated there and warns on every dev start. The detectors refuse\n * Svelte 4, which the widget library does not support either.\n */\nexport function layoutTemplate(): string {\n return `<script lang=\"ts\">\n ${MANAGED_MARKER}\n let { children } = $props();\n</script>\n\n{@render children()}\n\n<style>\n :global(:root) {\n color-scheme: dark;\n }\n :global(body) {\n margin: 0;\n background: #0f0f11;\n color: #f4f4f6;\n font-family: sans-serif;\n }\n</style>\n`;\n}\n\n/** `src/routes/+page.svelte` — the landing chooser linking to login/register/profile. */\nexport function indexPageTemplate(): string {\n return `<!-- ${MANAGED_MARKER} -->\n<main style=\"position:fixed;inset:0;padding:48px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#0f0f11;color-scheme:dark;color:#f4f4f6;font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;line-height:1.5;letter-spacing:normal;text-align:center\">\n <section style=\"width:100%;max-width:560px\">\n <p style=\"margin:0 0 12px;color:#9ca3af;font-size:14px\">Zitadel auth</p>\n <h1 style=\"margin:0 0 24px;font-size:32px;line-height:1.15;font-weight:600;color:#f4f4f6\">Sign in, create an account, or open your profile.</h1>\n <div style=\"display:flex;flex-wrap:wrap;gap:12px;justify-content:center\">\n <a href=\"/login\" style=\"padding:10px 16px;border-radius:8px;background:#f4f4f6;color:#0f0f11;text-decoration:none;font-weight:600;font-size:14px\">Sign in</a>\n <a href=\"/register\" style=\"padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px\">Create account</a>\n <a href=\"/profile\" style=\"padding:10px 16px;border-radius:8px;border:1px solid #3f3f46;color:#f4f4f6;text-decoration:none;font-weight:600;font-size:14px\">Profile</a>\n </div>\n </section>\n</main>\n`;\n}\n\n/**\n * A login/register page. Renders the idiomatic `<ZitadelLogin>` Svelte component\n * from `@zitadel/sdk-svelte` (typed props, callback events) behind an `onMount`\n * guard so the widget only mounts on the client. `configureZitadel` returns the\n * project handle.\n *\n * The public project id comes from `VITE_ZITADEL_PROJECT_ID` through Vite's\n * `import.meta.env`, which SvelteKit exposes to the browser. Setup seeds the\n * variable in `.env.local`, as it does for the other Vite-based frameworks.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the widget, restoring work-email copy on top of\n * the widget's neutral built-in dictionaries.\n */\nfunction authPage(purpose: \"login\" | \"register\", ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, businessLocales, configureZitadel\"\n : \"ZitadelLogin, configureZitadel\";\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 prop to\n // fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? \" locales={businessLocales}\" : \"\";\n return `<script lang=\"ts\">\n ${MANAGED_MARKER}\n import { onMount } from \"svelte\";\n import { ${importNames} } from \"@zitadel/sdk-svelte\";${localesComment}\n\n const project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID ?? \"\",\n proxyPath: \"${PROXY_PATH}\",\n });\n // Mount the widget on the client only. onMount never runs during SSR, and\n // unlike $app/environment (deprecated in SvelteKit 3) it works on 2 and 3.\n let mounted = $state(false);\n onMount(() => {\n mounted = true;\n });\n</script>\n\n<main style=\"${WIDGET_WRAP}\">\n {#if mounted}\n <ZitadelLogin {project}${localesAttr} purpose=\"${purpose}\" postSignInUrl=\"/profile\" />\n {/if}\n</main>\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/** `src/routes/profile/+page.svelte` — the signed-in view: the \"signed in as\" session card, with sign-out. */\nexport function profilePageTemplate(): string {\n return `<script lang=\"ts\">\n ${MANAGED_MARKER}\n import { onMount } from \"svelte\";\n import { ZitadelSession, configureZitadel } from \"@zitadel/sdk-svelte\";\n\n const project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID ?? \"\",\n proxyPath: \"${PROXY_PATH}\",\n });\n // Mount the widget on the client only. onMount never runs during SSR, and\n // unlike $app/environment (deprecated in SvelteKit 3) it works on 2 and 3.\n let mounted = $state(false);\n onMount(() => {\n mounted = true;\n });\n</script>\n\n<main style=\"${WIDGET_WRAP}\">\n {#if mounted}\n <ZitadelSession {project} postSignOutUrl=\"/login\" />\n {/if}\n</main>\n`;\n}\n","import { join } from \"node:path\";\n\nimport { sdkVersionForCli } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { devScriptPortOp } from \"../dev-script-port\";\nimport { envVarsEdit } from \"./env-vars\";\nimport {\n hooksServerTemplate,\n indexPageTemplate,\n layoutTemplate,\n loginPageTemplate,\n profilePageTemplate,\n registerPageTemplate,\n} from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-sveltekit\";\n/**\n * The idiomatic Svelte component library that ships the `<ZitadelLogin>` /\n * `<ZitadelSession>` Svelte components the routes render. The server SDK above is\n * plumbing only; the widget comes from here, so a SvelteKit app gets the native\n * Svelte component (typed props, callback events) rather than the bare element.\n */\nconst COMPONENT_DEPENDENCY = \"@zitadel/sdk-svelte\";\n\n/**\n * Rule-based patcher for a SvelteKit app. Like Next.js and Nuxt, SvelteKit\n * proxies the backend and verifies the session through a server entrypoint —\n * here the `@zitadel/sdk-sveltekit` `handle` hook in `src/hooks.server.ts`.\n * Contributes the layout + landing/login/register/profile file-based routes (the\n * idiomatic `<ZitadelLogin>`/`<ZitadelSession>` Svelte components from\n * `@zitadel/sdk-svelte`), the public project-id env var, and both deps. No config\n * edit is needed — the hook is a plain file, so (like Next) every managed file\n * carries the marker.\n */\nexport class SvelteKitPatcher extends AbstractRulePatcher {\n canPatch(framework: string): boolean {\n return framework === \"sveltekit\";\n }\n\n protected devPortOps(ctx: PatchContext): FileOp[] {\n return [devScriptPortOp(ctx.issuer, { strictPort: true })];\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n const src = (rel: string) => join(ctx.framework.appDir, rel);\n return [\n // The auth boundary is written on every setup; a pre-existing hook at\n // this exact path is a genuine conflict the file-writer refuses (and\n // --force replaces), the same way Next writes its request boundary.\n { kind: \"write\", path: src(\"hooks.server.ts\"), contents: hooksServerTemplate() },\n {\n kind: \"edit\",\n // SvelteKit reads every env variable an app declares from src/env.ts\n // (or .js), so the settings the hook imports from $app/env/private are\n // merged into the app's own file, and the file is written only where\n // there is none.\n path: [src(\"env.ts\"), src(\"env.js\")],\n edit: envVarsEdit(),\n // Undeclared, the hook cannot read its settings: doctor must fail, not pass.\n wiring: \"infrastructure\",\n },\n // The app shell and landing page are written only when setup created the\n // skeleton itself — a pre-existing app keeps its own root layout, theme,\n // and landing page (ADR 044), same as the Next/Nuxt homepage.\n ...(ctx.scaffoldedFramework\n ? ([\n { kind: \"write\", path: src(\"routes/+layout.svelte\"), contents: layoutTemplate() },\n { kind: \"write\", path: src(\"routes/+page.svelte\"), contents: indexPageTemplate() },\n ] satisfies FileOp[])\n : []),\n {\n kind: \"write\",\n path: src(\"routes/login/+page.svelte\"),\n contents: loginPageTemplate(ctx),\n },\n {\n kind: \"write\",\n path: src(\"routes/register/+page.svelte\"),\n contents: registerPageTemplate(ctx),\n },\n {\n kind: \"write\",\n path: src(\"routes/profile/+page.svelte\"),\n contents: profilePageTemplate(),\n },\n // Pin the dev script to the origin setup registered; --strictPort makes\n // Vite exit instead of drifting to a port the project does not allow.\n devScriptPortOp(ctx.issuer, { strictPort: true }),\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: sdkVersionForCli(ctx.cliVersion),\n },\n {\n kind: \"add-dep\",\n name: COMPONENT_DEPENDENCY,\n version: sdkVersionForCli(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(view: PatchView): ReadonlyArray<string> {\n const src = (rel: string) => join(view.framework.appDir, rel);\n return [\n src(\"hooks.server.ts\"),\n src(\"routes/+layout.svelte\"),\n src(\"routes/+page.svelte\"),\n src(\"routes/login/+page.svelte\"),\n src(\"routes/register/+page.svelte\"),\n src(\"routes/profile/+page.svelte\"),\n ];\n }\n\n protected override infrastructureFiles(view: PatchView): ReadonlyArray<string> {\n // The auth boundary — proxy, session check and route protection — is\n // infrastructure: without it /__nextgen/* 404s and protected routes open, so\n // doctor fails rather than warning about a missing page.\n return [join(view.framework.appDir, \"hooks.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 landing page stay user-owned (see routeOps),\n // so the managed-files check must not expect them on a manifest-less app.\n const src = (rel: string) => join(view.framework.appDir, rel);\n return [src(\"routes/+layout.svelte\"), src(\"routes/+page.svelte\")];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY, COMPONENT_DEPENDENCY];\n }\n\n protected override routeConfigEdits(view: PatchView): ReadonlyArray<string> {\n // The dev script's port and the env declarations are edited in place by\n // `edit` ops eject can't revert, so they are listed as manual cleanup steps.\n return [\"package.json\", join(view.framework.appDir, \"env.*\")];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"SvelteKit integration\",\n detail:\n \"Wrote src/hooks.server.ts (@zitadel/sdk-sveltekit handle), declared its settings in src/env.ts, plus layout and landing/login/register/profile routes using @zitadel/sdk-svelte.\",\n };\n }\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n// Enforce the dark surface the Zitadel widgets are designed for, so pages never\n// follow the OS light/dark setting. Inlined as a React style object on each\n// widget wrapper since TanStack Start routes render JSX.\n\n/**\n * `src/start.ts` — the TanStack Start server entry that the framework auto-loads\n * (`#tanstack-start-entry`). It must export a `startInstance` from `createStart`;\n * we wire a global request middleware via `requestMiddleware`. The middleware is\n * built from `createNextgenRequestMiddleware`, which on every request proxies\n * `/__nextgen/*` to the auth backend (attaching the project service-key from\n * `ZITADEL_PROJECT_SECRET`), verifies the session JWT, and redirects\n * unauthenticated requests away from protected routes. `url` and `projectSecret`\n * default from `process.env` (seeded in `.env.local`), so only the route policy\n * is spelled out here. The managed marker sits in a JS comment.\n *\n * `createCsrfMiddleware` is listed first and kept explicitly: TanStack Start\n * only auto-installs its CSRF protection for server functions when the app has\n * no `src/start.ts`. Writing this file opts out of that default, so we restore\n * it here (ahead of auth, so cross-site requests are rejected before any\n * session work runs) rather than silently dropping CSRF protection.\n */\nexport function startTemplate(): string {\n return `${MANAGED_MARKER}\nimport { createCsrfMiddleware, createMiddleware, createStart } from \"@tanstack/react-start\";\nimport { createNextgenRequestMiddleware } from \"@zitadel/sdk-tanstack-start/server\";\n\nconst csrfMiddleware = createCsrfMiddleware({\n filter: (ctx) => ctx.handlerType === \"serverFn\",\n});\n\nconst authMiddleware = createMiddleware({ type: \"request\" }).server(\n createNextgenRequestMiddleware({\n protectedRoutes: [\"/profile\"],\n loginPath: \"/login\",\n }),\n);\n\nexport const startInstance = createStart(() => ({\n requestMiddleware: [csrfMiddleware, authMiddleware],\n}));\n`;\n}\n\n/** `src/routes/index.tsx` — the landing chooser linking to login/register/profile. */\nexport function indexRouteTemplate(): string {\n return `${MANAGED_MARKER}\nimport { createFileRoute, Link } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/\")({\n component: Home,\n});\n\nfunction Home() {\n return (\n <main style={{ position: \"fixed\", inset: 0, padding: \"48px\", boxSizing: \"border-box\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", background: \"#0f0f11\", colorScheme: \"dark\", color: \"#f4f4f6\", fontFamily: \"system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\", lineHeight: 1.5, letterSpacing: \"normal\", textAlign: \"center\" }}>\n <section style={{ width: \"100%\", maxWidth: \"560px\" }}>\n <p style={{ margin: \"0 0 12px\", color: \"#9ca3af\", fontSize: \"14px\" }}>Zitadel auth</p>\n <h1 style={{ margin: \"0 0 24px\", fontSize: \"32px\", lineHeight: 1.15, fontWeight: 600, color: \"#f4f4f6\" }}>Sign in, create an account, or open your profile.</h1>\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"12px\", justifyContent: \"center\" }}>\n <Link to=\"/login\" style={{ padding: \"10px 16px\", borderRadius: \"8px\", background: \"#f4f4f6\", color: \"#0f0f11\", textDecoration: \"none\", fontWeight: 600, fontSize: \"14px\" }}>\n Sign in\n </Link>\n <Link to=\"/register\" style={{ padding: \"10px 16px\", borderRadius: \"8px\", border: \"1px solid #3f3f46\", color: \"#f4f4f6\", textDecoration: \"none\", fontWeight: 600, fontSize: \"14px\" }}>\n Create account\n </Link>\n <Link to=\"/profile\" style={{ padding: \"10px 16px\", borderRadius: \"8px\", border: \"1px solid #3f3f46\", color: \"#f4f4f6\", textDecoration: \"none\", fontWeight: 600, fontSize: \"14px\" }}>\n Profile\n </Link>\n </div>\n </section>\n </main>\n );\n}\n`;\n}\n\n/**\n * A login/register route. Configures the SDK once at module scope with\n * `configureZitadel` from the `/client` entry and passes the returned project\n * handle straight to the typed `<ZitadelLogin>` React wrapper from\n * `@zitadel/sdk-tanstack-start/react` as its `project` prop. The public project\n * id comes from Vite's `import.meta.env.VITE_ZITADEL_PROJECT_ID`; the backend URL\n * never reaches the browser (the widget talks to the same-origin `${PROXY_PATH}`\n * proxy). The wrapper mounts the widget on the client only, after hydration, so\n * it starts its flow with these props in place.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the widget, restoring work-email copy on top of\n * the widget's neutral built-in dictionaries.\n */\nfunction authRoute(purpose: \"login\" | \"register\", ctx: PatchContext): string {\n const path = purpose === \"login\" ? \"/login\" : \"/register\";\n const componentName = purpose === \"login\" ? \"LoginPage\" : \"RegisterPage\";\n const business = ctx.useCase === \"business\";\n const reactImports = business ? \"ZitadelLogin, businessLocales\" : \"ZitadelLogin\";\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 { createFileRoute } from \"@tanstack/react-router\";\nimport { ${reactImports} } from \"@zitadel/sdk-tanstack-start/react\";\nimport { configureZitadel } from \"@zitadel/sdk-tanstack-start/client\";${localesComment}\n\nconst projectId = import.meta.env.VITE_ZITADEL_PROJECT_ID ?? \"\";\n\nconst project = configureZitadel({ projectId, proxyPath: \"${PROXY_PATH}\" });\n\nexport const Route = createFileRoute(\"${path}\")({\n component: ${componentName},\n});\n\nfunction ${componentName}() {\n return (\n <div style={{ position: \"fixed\", inset: 0, overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelLogin project={project}${localesAttr} purpose=\"${purpose}\" postSignInUrl=\"/profile\" />\n </div>\n );\n}\n`;\n}\n\nexport function loginRouteTemplate(ctx: PatchContext): string {\n return authRoute(\"login\", ctx);\n}\n\nexport function registerRouteTemplate(ctx: PatchContext): string {\n return authRoute(\"register\", ctx);\n}\n\n/**\n * `src/routes/profile.tsx` — the signed-in view: the \"signed in as\" session card, with sign-out.\n *\n * `protectedRoutes` in `src/start.ts` only guards document requests: a\n * client-side `<Link to=\"/profile\">` never reaches the request middleware. So\n * the route also guards itself in `beforeLoad` by calling a server function —\n * the call always goes to the server, where the request middleware has put the\n * session on the server function's context (a route's own `beforeLoad` context\n * does not carry it).\n */\nexport function profileRouteTemplate(): string {\n return `${MANAGED_MARKER}\nimport { createFileRoute, redirect } from \"@tanstack/react-router\";\nimport { createServerFn } from \"@tanstack/react-start\";\nimport { ZitadelSession } from \"@zitadel/sdk-tanstack-start/react\";\nimport { configureZitadel } from \"@zitadel/sdk-tanstack-start/client\";\nimport { getAuth } from \"@zitadel/sdk-tanstack-start/server\";\n\nconst projectId = import.meta.env.VITE_ZITADEL_PROJECT_ID ?? \"\";\n\nconst project = configureZitadel({ projectId, proxyPath: \"${PROXY_PATH}\" });\n\n// Runs on the server on every navigation, client-side ones included. Its\n// return value is sent to the browser, so it returns only client-safe fields:\n// getAuth's session carries the raw session credential, which must stay on the server.\nconst fetchAuth = createServerFn().handler(({ context }) => {\n const { isAuthenticated, session } = getAuth(context);\n return { isAuthenticated, userId: session?.userId ?? null };\n});\n\nexport const Route = createFileRoute(\"/profile\")({\n beforeLoad: async () => {\n const auth = await fetchAuth();\n if (!auth.isAuthenticated) {\n throw redirect({ to: \"/login\" });\n }\n },\n component: ProfilePage,\n});\n\nfunction ProfilePage() {\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`;\n}\n","import { join } from \"node:path\";\n\nimport { sdkVersionForCli } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { devScriptPortOp } from \"../dev-script-port\";\nimport {\n indexRouteTemplate,\n loginRouteTemplate,\n profileRouteTemplate,\n registerRouteTemplate,\n startTemplate,\n} from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-tanstack-start\";\n\n/**\n * Rule-based patcher for a TanStack Start app. Like Next.js and SvelteKit,\n * TanStack Start proxies the backend and verifies the session through a server\n * entrypoint — here the `@zitadel/sdk-tanstack-start` request middleware\n * registered in `src/start.ts`. Contributes the landing/login/register/profile\n * file-based routes (rendering the typed `<ZitadelLogin>`/`<ZitadelSession>`\n * React wrappers), the public project-id env var, and the SDK dep. No config\n * edit is needed — `src/start.ts` is a plain file, so (like Next) every managed\n * file carries the marker.\n */\nexport class TanStackStartPatcher extends AbstractRulePatcher {\n canPatch(framework: string): boolean {\n return framework === \"tanstack-start\";\n }\n\n protected devPortOps(ctx: PatchContext): FileOp[] {\n return [devScriptPortOp(ctx.issuer, { strictPort: true })];\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n const src = (rel: string) => join(ctx.framework.appDir, rel);\n return [\n // The auth boundary is written on every setup; a pre-existing start entry\n // at this exact path (e.g. another auth provider's src/start.ts) is a\n // genuine conflict the file-writer refuses (and --force replaces), the\n // same way Next writes its request boundary.\n { kind: \"write\", path: src(\"start.ts\"), contents: startTemplate() },\n // The landing page is written only when setup created the skeleton\n // itself — a pre-existing app keeps its own landing page (ADR 044),\n // same as the Next/Nuxt homepage.\n ...(ctx.scaffoldedFramework\n ? ([\n { kind: \"write\", path: src(\"routes/index.tsx\"), contents: indexRouteTemplate() },\n ] satisfies FileOp[])\n : []),\n { kind: \"write\", path: src(\"routes/login.tsx\"), contents: loginRouteTemplate(ctx) },\n { kind: \"write\", path: src(\"routes/register.tsx\"), contents: registerRouteTemplate(ctx) },\n { kind: \"write\", path: src(\"routes/profile.tsx\"), contents: profileRouteTemplate() },\n // Pin the dev script to the origin setup registered; --strictPort makes\n // Vite exit instead of drifting to a port the project does not allow.\n devScriptPortOp(ctx.issuer, { strictPort: true }),\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: sdkVersionForCli(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(view: PatchView): ReadonlyArray<string> {\n const src = (rel: string) => join(view.framework.appDir, rel);\n return [\n src(\"start.ts\"),\n src(\"routes/index.tsx\"),\n src(\"routes/login.tsx\"),\n src(\"routes/register.tsx\"),\n src(\"routes/profile.tsx\"),\n ];\n }\n\n protected override infrastructureFiles(view: PatchView): ReadonlyArray<string> {\n // The auth boundary — proxy, session check and route protection — is\n // infrastructure: without it /__nextgen/* 404s and protected routes open, so\n // doctor fails rather than warning about a missing page.\n return [join(view.framework.appDir, \"start.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 landing page stays user-owned (see routeOps), so\n // the managed-files check must not expect it on a manifest-less app.\n return [join(view.framework.appDir, \"routes/index.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 // The dev script's port is pinned in place by an `edit` op eject can't\n // revert, so it is listed as a manual cleanup step.\n return [\"package.json\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"TanStack Start integration\",\n detail:\n \"Wrote src/start.ts (@zitadel/sdk-tanstack-start request middleware) plus landing/login/register/profile routes.\",\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 { sdkVersionForCli } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { PUBLIC_PROJECT_ID_VARIABLE } from \"../public-project-id\";\nimport { assertMountsRootComponent, type RootMount, viteEntry } from \"../root-component\";\nimport { type ViteSupport, buildViteProxyOp, buildViteSessionCookieOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-vue\";\n\n/** The managed root component, and how `main.ts` creates the app from it. */\nconst ROOT: RootMount = {\n path: \"src/App.vue\",\n binding: { name: \"App\", named: false },\n extension: true,\n calls: [\"createApp\", \"createSSRApp\"],\n mounts: \"argument\",\n};\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, previousPort?: number): FileOp {\n return buildViteProxyOp(devPort, server, previousPort);\n }\n\n viteSessionCookieOp(): FileOp {\n return buildViteSessionCookieOp();\n }\n\n protected override async preflight(_ctx: PatchContext, cwd: string): Promise<void> {\n await assertMountsRootComponent(cwd, await viteEntry(cwd), ROOT);\n }\n\n protected devPortOps(ctx: PatchContext, previousPort: number | undefined): FileOp[] {\n return [this.viteProxyOp(ctx.framework.devPort, ctx.server, previousPort)];\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: ROOT.path, contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n this.viteSessionCookieOp(),\n {\n kind: \"merge-env\",\n path: \".env.example\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.vue]: \"\" },\n },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { [PUBLIC_PROJECT_ID_VARIABLE.vue]: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: sdkVersionForCli(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [ROOT.path];\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 { QwikRouterPatcher } from \"./rule/qwik-router\";\nimport { ReactPatcher } from \"./rule/react\";\nimport { SolidPatcher } from \"./rule/solid\";\nimport { SolidStartPatcher } from \"./rule/solid-start\";\nimport { SveltePatcher } from \"./rule/svelte\";\nimport { SvelteKitPatcher } from \"./rule/sveltekit\";\nimport { TanStackStartPatcher } from \"./rule/tanstack-start\";\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.\n */\nexport const patchers = [\n new NextPatcher(),\n new NuxtPatcher(),\n new TanStackStartPatcher(),\n new ReactPatcher(),\n new VuePatcher(),\n new SolidStartPatcher(),\n new SolidPatcher(),\n new SvelteKitPatcher(),\n new SveltePatcher(),\n new QwikRouterPatcher(),\n new QwikPatcher(),\n new AngularPatcher(),\n] as const satisfies ReadonlyArray<Patcher>;\n","import { spawnSync } from \"node:child_process\";\n\nimport semver from \"semver\";\n\n/**\n * How a framework CLI treats a Node outside its `engines.node`, which decides\n * what setup does about it:\n *\n * - `refuse`: the CLI exits on it (the Angular CLI's `bin/ng.js` exits 3), so\n * setup refuses it first, with a message that names the range.\n * - `warn`: the CLI carries on, at most printing its own warning into output\n * setup never shows (`nuxi` warns, `create-vite` and `create-next-app` say\n * nothing, and npx only prints `EBADENGINE`), so setup refuses nothing and\n * reports the warning itself.\n */\nexport type NodeEnforcement = \"refuse\" | \"warn\";\n\n/**\n * What a scaffolder declares about the Node the framework CLI it runs needs.\n * The range itself is asked of npm at run time, so a new release's range\n * applies without a CLI release.\n */\nexport interface NodeEngines {\n /** How the CLI is named in messages, e.g. `The Angular CLI` or `create-vite`. */\n readonly label: string;\n /** The npm package spec setup runs, so npm reports the range of that very version. */\n readonly spec: string;\n /** The range to use when npm cannot report one, as of the version setup runs. */\n readonly fallback: string;\n readonly enforcement: NodeEnforcement;\n}\n\n/** Whether a framework CLI runs on a Node, refuses it, or runs on it with a warning. */\nexport type NodeSupport = \"supported\" | \"warned\" | \"refused\";\n\n/**\n * How long npm may take to report a framework CLI's range before setup falls\n * back to the declared one. npm's own fetch timeout is five minutes, and on a\n * network that cannot reach the registry the scaffolding command fails\n * anyway, so the lookup must not hold setup up for long.\n */\nexport const NODE_ENGINES_TIMEOUT_MS = 5_000;\n\n/**\n * Decides a Node version against a framework CLI's `engines.node`, the way\n * that CLI does:\n *\n * - `refuse` follows the Angular CLI's own `bin/ng.js`. Each `||` part of the\n * range, stripped of its operators, names a major and its lowest\n * `minor.patch`; a Node of that major at or above it is supported (so\n * `>=26.0.0` covers Node 26 only, as it does for `ng`). An odd major between\n * the lowest and highest listed majors (Node 23 and 25 for Angular 22) is\n * warned about, as it never reaches LTS. Anything else, including a major\n * above the highest listed one, is refused.\n * - `warn` follows the plain semver range, which is what `nuxi` checks: a\n * Node in the range is supported, any other is warned about, none is refused.\n */\nexport function nodeSupport(\n node: string,\n range: string,\n enforcement: NodeEnforcement,\n): NodeSupport {\n if (enforcement === \"warn\") {\n return semver.satisfies(node, range) ? \"supported\" : \"warned\";\n }\n const [major = 0, minor = 0, patch = 0] = node.split(\".\", 3).map(Number);\n const listed = range\n .replace(/[\\^~<>=]/g, \"\")\n .split(\"||\")\n .map((part) => part.trim().split(\".\", 3).map(Number));\n const supported = listed.some(\n ([lMajor, lMinor = 0, lPatch = 0]) =>\n lMajor === major && (minor > lMinor || (minor === lMinor && patch >= lPatch)),\n );\n if (supported) {\n return \"supported\";\n }\n const majors = listed.map(([lMajor = 0]) => lMajor);\n const between = major > Math.min(...majors) && major < Math.max(...majors);\n return major % 2 === 1 && between ? \"warned\" : \"refused\";\n}\n\n/**\n * The Node versions a `refuse` range accepts, in words, derived from the same\n * parts {@link nodeSupport} reads: each part names a major and its lowest\n * `minor.patch`, so `^22.22.3 || ^24.15.0 || >=26.0.0` reads `22.22.3 or newer\n * 22, 24.15.0 or newer 24, or 26`. A range read as a whole would mislead, as\n * `>=26.0.0` also covers Node 27, which the Angular CLI refuses.\n */\nexport function describeAcceptedNode(range: string): string {\n const parts = range\n .replace(/[\\^~<>=]/g, \"\")\n .split(\"||\")\n .map((part) => {\n const [major = 0, minor = 0, patch = 0] = part.trim().split(\".\", 3).map(Number);\n return minor === 0 && patch === 0\n ? String(major)\n : `${String(major)}.${String(minor)}.${String(patch)} or newer ${String(major)}`;\n });\n const last = parts.pop();\n return parts.length === 0 ? `${last}` : `${parts.join(\", \")}, or ${last}`;\n}\n\n/**\n * The Node range the framework CLI that setup will run publishes, asked of\n * npm. Falls back to the declared range when npm is unavailable, takes longer\n * than {@link NODE_ENGINES_TIMEOUT_MS} (a killed spawn has no exit status), or\n * answers with something that is not a range.\n *\n * On Windows npm is a `.cmd` shim, which `spawnSync` cannot start without a\n * shell (it reports ENOENT, or EINVAL on current Node), so the lookup would\n * always fall back there. The command line is constant, so running it through\n * the shell on Windows is safe. The call is synchronous and may block for up to\n * the timeout, once, before scaffolding starts; nothing else is running in the\n * process at that point.\n */\nexport function nodeEnginesRange(\n engines: NodeEngines,\n cwd: string,\n platform: NodeJS.Platform,\n): string {\n const result = spawnSync(\"npm\", [\"view\", engines.spec, \"engines.node\"], {\n cwd,\n encoding: \"utf8\",\n timeout: NODE_ENGINES_TIMEOUT_MS,\n shell: platform === \"win32\",\n });\n const range = result.status === 0 ? String(result.stdout ?? \"\").trim() : \"\";\n return range && semver.validRange(range) ? range : engines.fallback;\n}\n\n/**\n * The `create-vite` release every Vite scaffolder (React, Vue, Solid, Svelte\n * and Qwik) runs, pinned exactly. 9.3.2 was published without its templates:\n * it fails to scaffold yet exits 0, so setup went on to report an empty\n * directory as an undetectable framework. Bump it by hand once a release\n * ships its templates again. The templates write `^` ranges, so a fresh app\n * still picks up framework and Vite patch releases.\n */\nexport const CREATE_VITE_VERSION = \"9.3.1\";\n\n/**\n * What every scaffolder that runs `create-vite` declares. `create-vite` never\n * checks the Node itself, so setup only warns.\n */\nexport const CREATE_VITE_NODE_ENGINES: NodeEngines = {\n label: \"create-vite\",\n spec: `create-vite@${CREATE_VITE_VERSION}`,\n fallback: \"^20.19.0 || >=22.12.0\",\n enforcement: \"warn\",\n};\n","import { spawnSync } from \"node:child_process\";\n\nimport { ZitadelError } from \"../../errors\";\nimport { reportWarning } from \"../../warnings\";\nimport {\n describeAcceptedNode,\n type NodeEngines,\n nodeEnginesRange,\n nodeSupport,\n} from \"./node-engines\";\nimport type { Scaffolder } from \"./types\";\n\n/**\n * Base for scaffolders that delegate to an external CLI (e.g. create-next-app).\n * Subclasses declare the Node the CLI needs in {@link nodeEngines}, implement\n * {@link create} and call {@link runCommand}. {@link scaffold} checks the Node\n * first, for every subclass, so no scaffolder can skip the check.\n */\nexport abstract class AbstractCLIScaffolder implements Scaffolder {\n abstract readonly displayName: string;\n abstract readonly supportedFrameworks: ReadonlyArray<string>;\n /** The Node the framework CLI this scaffolder runs accepts, and how it treats any other. */\n abstract readonly nodeEngines: NodeEngines;\n /**\n * The packages a fresh app gets at an exact version because this scaffolder\n * pins them, as `name@version`: the framework CLI, when it runs a fixed\n * release, and any package that release writes at a fixed version. A\n * framework CLI run `@latest`, and the ranges it writes, move to patched\n * releases by themselves; a pin stays on its version until someone bumps\n * it, so `cli:check-advisories` checks each against the npm advisory\n * database.\n */\n readonly pinnedPackages: ReadonlyArray<string> = [];\n\n private readonly nodeVersion: string;\n private readonly platform: NodeJS.Platform;\n\n /** `nodeVersion` and `platform` default to the running ones; tests pass others. */\n constructor(\n nodeVersion: string = process.versions.node,\n platform: NodeJS.Platform = process.platform,\n ) {\n this.nodeVersion = nodeVersion;\n this.platform = platform;\n }\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 /**\n * Checks the running Node against the framework CLI's `engines.node`\n * ({@link enforceNodeEngines}), then creates the project ({@link create}).\n */\n async scaffold(cwd: string, framework: string): Promise<void> {\n this.enforceNodeEngines(cwd);\n await this.create(cwd, framework);\n }\n\n /** Creates the project in `cwd` by running the framework CLI. */\n protected abstract create(cwd: string, framework: string): Promise<void>;\n\n /**\n * The framework CLI may refuse a Node outside its `engines.node`, which can\n * be narrower than this CLI's own. That refusal would surface as a generic\n * command failure, so the range is checked first ({@link nodeSupport}): a\n * Node the CLI refuses is refused here, naming the versions it needs, and\n * one it only warns about is warned about here too.\n */\n private enforceNodeEngines(cwd: string): void {\n const engines = this.nodeEngines;\n const range = nodeEnginesRange(engines, cwd, this.platform);\n const support = nodeSupport(this.nodeVersion, range, engines.enforcement);\n if (support === \"warned\") {\n const reason =\n engines.enforcement === \"refuse\" ? \", as odd-numbered Node versions never reach LTS\" : \"\";\n reportWarning(\n `${engines.label} supports Node ${range}; it runs on Node v${this.nodeVersion} with a warning${reason}`,\n );\n }\n if (support === \"refused\") {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${engines.label} needs Node ${range}; this is Node v${this.nodeVersion}`,\n {\n hint: `Switch to Node ${describeAcceptedNode(range)} and rerun, or create the ${this.displayName} app with that Node and run setup inside it.`,\n details: { node: this.nodeVersion, required: range },\n },\n );\n }\n }\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\";\nimport type { NodeEngines } from \"./node-engines\";\n\n/** The Angular CLI setup runs, for both `ng new` and the engine lookup. */\nconst ANGULAR_CLI = \"@angular/cli@latest\";\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 *\n * The Angular CLI refuses Node versions outside its `engines.node` range, so\n * {@link nodeEngines} declares it with `refuse` enforcement and the base\n * class checks the range before `ng new` runs.\n */\nexport class AngularScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Angular\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"angular\"];\n readonly nodeEngines: NodeEngines = {\n label: \"The Angular CLI\",\n spec: ANGULAR_CLI,\n fallback: \"^22.22.3 || ^24.15.0 || >=26.0.0\",\n enforcement: \"refuse\",\n };\n\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npx\",\n [\n \"-y\",\n ANGULAR_CLI,\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\";\nimport type { NodeEngines } from \"./node-engines\";\n\n/**\n * The `create-next-app` release setup runs, pinned exactly so a fresh app is\n * the one the patcher was written against. `create-next-app` writes `next` at\n * its own version, so this is also the Next.js every fresh app runs, until its\n * developer upgrades it. Its route protection is `nextgenMiddleware`, which\n * runs in Next's Middleware / Proxy, and 16.2.x had several bypasses of that\n * layer: keep the pin on a release with no high or critical advisory, as\n * `cli:check-advisories` checks.\n */\nconst CREATE_NEXT_APP_VERSION = \"16.4.2\";\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 readonly nodeEngines: NodeEngines = {\n label: \"create-next-app\",\n spec: `create-next-app@${CREATE_NEXT_APP_VERSION}`,\n fallback: \">=20.9.0\",\n enforcement: \"warn\",\n };\n override readonly pinnedPackages: ReadonlyArray<string> = [\n `create-next-app@${CREATE_NEXT_APP_VERSION}`,\n `next@${CREATE_NEXT_APP_VERSION}`,\n ];\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 protected async create(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\";\nimport type { NodeEngines } from \"./node-engines\";\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 readonly nodeEngines: NodeEngines = {\n label: \"nuxi\",\n spec: \"nuxi@latest\",\n fallback: \"^22.21.0 || ^24.11.0 || >=26.0.0\",\n enforcement: \"warn\",\n };\n\n protected async create(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 { readFile, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\nimport { CREATE_VITE_NODE_ENGINES, CREATE_VITE_VERSION } from \"./node-engines\";\n\n/** Qwik 2 version the generated app is migrated to — matches the peer range of\n * `@zitadel/sdk-qwik`, which requires Qwik 2 (`@qwik.dev/core`). */\nconst QWIK2_VERSION = \"^2.0.0-beta.45\";\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 *\n * `create-vite`'s `qwik-ts` template still ships Qwik 1 (`@builder.io/qwik`) on\n * Vite 8, but Qwik 1 peers `vite \">=5 <8\"` (so a bare install ERESOLVEs) and\n * `@zitadel/sdk-qwik` now requires Qwik 2. So the generated app is migrated to\n * Qwik 2 (`@qwik.dev/core`), which runs on Vite 8 — the template's Vite version\n * is left untouched, no downgrade needed.\n */\nexport class QwikScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Qwik (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"qwik\"];\n readonly nodeEngines = CREATE_VITE_NODE_ENGINES;\n override readonly pinnedPackages: ReadonlyArray<string> = [CREATE_VITE_NODE_ENGINES.spec];\n\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npm\",\n [\"create\", `vite@${CREATE_VITE_VERSION}`, \".\", \"--\", \"--template\", \"qwik-ts\"],\n cwd,\n );\n await rm(join(cwd, \"src/app.tsx\"), { force: true });\n await rm(join(cwd, \"src/app.css\"), { force: true });\n await this.migrateToQwik2(cwd);\n }\n\n /**\n * Repoints the generated app from Qwik 1 to Qwik 2: swaps the `@builder.io/qwik`\n * dependency for `@qwik.dev/core` in `package.json` and rewrites the `@builder.io/qwik`\n * references create-vite emits in `vite.config.ts` (`/optimizer`), `src/main.tsx`\n * (the runtime and `/qwikloader.js`), and `tsconfig.app.json` (`jsxImportSource`,\n * which `tsc -b && vite build` needs). Edits `package.json` directly rather than\n * via `npm pkg`, which cannot address keys containing dots (`@builder.io/qwik`,\n * `@qwik.dev/core`). No-ops cleanly if a future template already ships Qwik 2.\n */\n private async migrateToQwik2(cwd: string): Promise<void> {\n const pkgPath = join(cwd, \"package.json\");\n const pkg = JSON.parse(await readFile(pkgPath, \"utf8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n for (const field of [\"dependencies\", \"devDependencies\"] as const) {\n delete pkg[field]?.[\"@builder.io/qwik\"];\n }\n pkg.dependencies = { ...pkg.dependencies, \"@qwik.dev/core\": QWIK2_VERSION };\n await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n for (const file of [\"vite.config.ts\", \"src/main.tsx\", \"tsconfig.app.json\"]) {\n await this.repointQwikRefs(join(cwd, file));\n }\n }\n\n /** Rewrites every `@builder.io/qwik…` reference (import specifier or\n * `jsxImportSource`) to `@qwik.dev/core…` in one generated file. Skips a file\n * that is absent (a future template may not emit it) or already migrated, but\n * rethrows any other read error (e.g. `EACCES`) rather than silently leaving a\n * half-migrated app that reports success but cannot build. */\n private async repointQwikRefs(file: string): Promise<void> {\n let source: string;\n try {\n source = await readFile(file, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return;\n }\n throw error;\n }\n if (!source.includes(\"@builder.io/qwik\")) {\n return;\n }\n await writeFile(file, source.replaceAll(\"@builder.io/qwik\", \"@qwik.dev/core\"));\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\n/**\n * Removes a scaffolder's auto-generated dependency install — `node_modules` and\n * every lockfile shape. Some `create-*` tools (e.g. `create-solid`,\n * `create-qwik`) install dependencies as part of scaffolding, leaving a\n * lockfile that pins the public registry. Setup detects the package manager from\n * that lockfile and would then install the workspace packages from the wrong\n * registry. Removing the install leaves no lockfile, so setup falls back to npm\n * and installs from the registry it is pointed at.\n */\nexport async function removeInstall(cwd: string): Promise<void> {\n await Promise.all(\n [\"node_modules\", \"pnpm-lock.yaml\", \"package-lock.json\", \"yarn.lock\", \"bun.lockb\"].map((entry) =>\n rm(join(cwd, entry), { recursive: true, force: true }),\n ),\n );\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\nimport type { NodeEngines } from \"./node-engines\";\nimport { removeInstall } from \"./remove-install\";\n\n/**\n * The `create-qwik` release that scaffolds a Qwik 2 app (`@qwik.dev/core` +\n * `@qwik.dev/router` on Vite 8). Pinned exactly: `create-qwik@latest` still\n * scaffolds Qwik 1 (`@builder.io/qwik-city`), whose `vite <8` peer conflicts\n * with the Qwik 2 `@zitadel/sdk-qwik` widgets the pages render, and the moving\n * `rc` dist-tag would follow a future major's release candidate. The generated\n * app declares `^` ranges, so it still picks up Qwik 2 patch releases.\n */\nconst CREATE_QWIK = \"create-qwik@2.0.0-rc.3\";\n\n/**\n * Scaffolds a new Qwik Router app with `create-qwik` (the `empty` starter), then\n * removes the starter `src/routes/index.tsx` so the patcher can write the\n * managed landing page without colliding with boilerplate. `vite.config.ts` is\n * left in place — the Qwik Router integration wires auth through the\n * `src/routes/plugin@nextgen.ts` `onRequest` plugin (a plain route file the\n * patcher writes), so no config edit is needed.\n */\nexport class QwikRouterScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Qwik Router\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"qwik-router\"];\n\n readonly nodeEngines: NodeEngines = {\n label: \"create-qwik\",\n spec: CREATE_QWIK,\n fallback: \"^18.17.0 || ^20.3.0 || >=21.0.0\",\n enforcement: \"warn\",\n };\n override readonly pinnedPackages: ReadonlyArray<string> = [CREATE_QWIK];\n\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npx\", [\"-y\", CREATE_QWIK, \"empty\", \".\", \"--installDeps=false\"], cwd);\n await rm(join(cwd, \"src/routes/index.tsx\"), { force: true });\n // Setup must install the workspace packages from the detected registry with\n // npm (no lockfile). `--installDeps=false` already skips create-qwik's own\n // install; removing any install it leaves keeps that true if a future\n // release flips the default.\n await removeInstall(cwd);\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\nimport { CREATE_VITE_NODE_ENGINES, CREATE_VITE_VERSION } from \"./node-engines\";\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 readonly nodeEngines = CREATE_VITE_NODE_ENGINES;\n override readonly pinnedPackages: ReadonlyArray<string> = [CREATE_VITE_NODE_ENGINES.spec];\n\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npm\",\n [\"create\", `vite@${CREATE_VITE_VERSION}`, \".\", \"--\", \"--template\", \"react-ts\"],\n cwd,\n );\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\";\nimport { CREATE_VITE_NODE_ENGINES, CREATE_VITE_VERSION } from \"./node-engines\";\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 readonly nodeEngines = CREATE_VITE_NODE_ENGINES;\n override readonly pinnedPackages: ReadonlyArray<string> = [CREATE_VITE_NODE_ENGINES.spec];\n\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npm\",\n [\"create\", `vite@${CREATE_VITE_VERSION}`, \".\", \"--\", \"--template\", \"solid-ts\"],\n cwd,\n );\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\";\nimport type { NodeEngines } from \"./node-engines\";\nimport { removeInstall } from \"./remove-install\";\n\n/**\n * Scaffolds a new SolidStart app with `create-solid`, then removes the starter\n * `src/routes/index.tsx` so the patcher can write the managed landing page\n * without colliding with boilerplate. `vite.config.ts` is left in place — the\n * patcher merges into it via an `edit` (adding `middleware` to the\n * `solidStart()` plugin), which preserves whatever `create-solid` generated.\n *\n * The flags pin a non-interactive run: `create-solid` otherwise prompts for the\n * project type, SolidStart version, and template. `--solidstart --ts --v2` plus\n * the `basic` template positional select a TypeScript SolidStart 2 app (the\n * version `create-solid` now ships and recommends) without any prompts.\n */\nexport class SolidStartScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"SolidStart\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"solid-start\"];\n\n readonly nodeEngines: NodeEngines = {\n label: \"create-solid\",\n spec: \"create-solid@latest\",\n fallback: \"^20.19.0 || >=22.12.0\",\n enforcement: \"warn\",\n };\n\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npx\",\n [\"-y\", \"create-solid@latest\", \".\", \"basic\", \"--solidstart\", \"--ts\", \"--v2\"],\n cwd,\n );\n await rm(join(cwd, \"src/routes/index.tsx\"), { force: true });\n // `create-solid` installs with pnpm, leaving a pnpm-lock.yaml that pins the\n // public registry. Remove the install so setup picks npm (no lockfile) and\n // installs the workspace packages from the detected registry instead.\n await removeInstall(cwd);\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\nimport { CREATE_VITE_NODE_ENGINES, CREATE_VITE_VERSION } from \"./node-engines\";\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 readonly nodeEngines = CREATE_VITE_NODE_ENGINES;\n override readonly pinnedPackages: ReadonlyArray<string> = [CREATE_VITE_NODE_ENGINES.spec];\n\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npm\",\n [\"create\", `vite@${CREATE_VITE_VERSION}`, \".\", \"--\", \"--template\", \"svelte-ts\"],\n cwd,\n );\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\";\nimport type { NodeEngines } from \"./node-engines\";\n\n/**\n * Scaffolds a new SvelteKit app with the `sv` CLI (`sv create`), then removes\n * the starter `src/routes/+page.svelte` and `src/routes/+layout.svelte` so the\n * patcher can write its managed landing page and layout without colliding with\n * boilerplate (the file-writer refuses to overwrite an unmarked file unless\n * `--force`). `svelte.config.js` and `vite.config.*` are left in place — the\n * SvelteKit integration wires auth through `src/hooks.server.ts` (a plain file\n * the patcher writes), so no config edit is needed.\n */\nexport class SvelteKitScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"SvelteKit\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"sveltekit\"];\n\n readonly nodeEngines: NodeEngines = {\n label: \"sv\",\n spec: \"sv@latest\",\n fallback: \"^20.19.0 || >=22.12.0\",\n enforcement: \"warn\",\n };\n\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npx\",\n [\n \"-y\",\n \"sv@latest\",\n \"create\",\n \".\",\n \"--template\",\n \"minimal\",\n \"--types\",\n \"ts\",\n \"--no-add-ons\",\n \"--install\",\n \"npm\",\n ],\n cwd,\n );\n await rm(join(cwd, \"src/routes/+page.svelte\"), { force: true });\n await rm(join(cwd, \"src/routes/+layout.svelte\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\nimport type { NodeEngines } from \"./node-engines\";\n\n/**\n * Scaffolds a new TanStack Start app with the TanStack CLI, then removes the\n * starter `src/routes/index.tsx` so the patcher can write the managed landing\n * page without colliding with boilerplate.\n *\n * Uses `@tanstack/cli create` (which replaces the deprecated\n * `create-start-app`) in its default (full TanStack Start) mode — NOT\n * `--router-only`, which produces a router-only SPA without\n * `@tanstack/react-start` (so the detector would not recognise it).\n * `--framework react` selects the React variant, `--deployment nitro` keeps the\n * Nitro target, and `--no-examples`/`--no-toolchain`/`--no-intent` keep the\n * output minimal. `vite.config.*` is left in place — auth is wired through\n * `src/start.ts` (the framework's server entry, which the patcher writes), so\n * no config edit is needed.\n */\nexport class TanStackStartScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"TanStack Start\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"tanstack-start\"];\n\n readonly nodeEngines: NodeEngines = {\n label: \"@tanstack/cli\",\n spec: \"@tanstack/cli@latest\",\n fallback: \"^20.19.0 || >=22.12.0\",\n enforcement: \"warn\",\n };\n\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npx\",\n [\n \"-y\",\n \"@tanstack/cli@latest\",\n \"create\",\n \".\",\n \"--framework\",\n \"react\",\n \"--deployment\",\n \"nitro\",\n \"--no-examples\",\n \"--no-toolchain\",\n \"--no-intent\",\n \"--no-git\",\n \"-y\",\n ],\n cwd,\n );\n await rm(join(cwd, \"src/routes/index.tsx\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\nimport { CREATE_VITE_NODE_ENGINES, CREATE_VITE_VERSION } from \"./node-engines\";\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 readonly nodeEngines = CREATE_VITE_NODE_ENGINES;\n override readonly pinnedPackages: ReadonlyArray<string> = [CREATE_VITE_NODE_ENGINES.spec];\n\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npm\",\n [\"create\", `vite@${CREATE_VITE_VERSION}`, \".\", \"--\", \"--template\", \"vue-ts\"],\n cwd,\n );\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 { QwikRouterScaffolder } from \"./qwik-router\";\nimport { ReactScaffolder } from \"./react\";\nimport { SolidScaffolder } from \"./solid\";\nimport { SolidStartScaffolder } from \"./solid-start\";\nimport { SvelteScaffolder } from \"./svelte\";\nimport { SvelteKitScaffolder } from \"./sveltekit\";\nimport { TanStackStartScaffolder } from \"./tanstack-start\";\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 TanStackStartScaffolder(),\n new ReactScaffolder(),\n new VueScaffolder(),\n new SolidStartScaffolder(),\n new SolidScaffolder(),\n new SvelteKitScaffolder(),\n new SvelteScaffolder(),\n new QwikRouterScaffolder(),\n new QwikScaffolder(),\n new AngularScaffolder(),\n] as const satisfies ReadonlyArray<Scaffolder>;\n","import { access, mkdir, readFile, readdir, rename, rm, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\n\nimport { ZitadelError } from \"../errors\";\nimport { LOCAL_RUNTIME_DIR } from \"../local-server/runtime\";\nimport { detectors } from \"./detectors\";\nimport { detectDevPort } from \"./detectors/port\";\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 reason?: string;\n entries: ReadonlyArray<string>;\n}>;\n\n/**\n * A new app {@link Orca.scaffoldUndoably} created. Call `keep` or `undo`, once:\n * until then, what the scaffold replaced waits beside the directory.\n */\nexport type UndoableScaffold = Readonly<{\n facts: FrameworkFacts;\n /** Keeps the new app, and lets go of what it replaced. */\n keep(): Promise<void>;\n /**\n * Removes the new app and what was written into the directory since, and\n * puts back what the directory held: an entry it did not hold goes, and so\n * does one added inside a directory it held; an entry the scaffold replaced\n * comes back. An edit to a file it already held stays.\n */\n undo(): Promise<void>;\n}>;\n\n/** A new app {@link Orca.scaffold} can create, as far as it is known before it exists. */\nexport type PlannedApp = Readonly<{\n framework: string;\n /**\n * The dev port to offer for the app. It has no `dev` script yet to read one\n * from, so this is the port a `.env` file in the directory declares, which\n * the scaffold keeps, else the default.\n */\n devPort: number;\n}>;\n\ntype ScaffoldStash = Readonly<{\n root: string;\n names: ReadonlyArray<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 private readonly detectors: ReadonlyArray<Detector>;\n private readonly scaffolders: ReadonlyArray<Scaffolder>;\n private readonly patchers: ReadonlyArray<Patcher>;\n\n constructor(\n detectors: ReadonlyArray<Detector>,\n scaffolders: ReadonlyArray<Scaffolder>,\n patchers: ReadonlyArray<Patcher>,\n ) {\n this.detectors = detectors;\n this.scaffolders = scaffolders;\n this.patchers = patchers;\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, and `E_CONFLICT` when\n * `cwd` holds an app of a framework other than `requested`; 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 if (requested) {\n // An app the requested framework's detector does not recognise is still\n // an app. Reported as not detected, it would read as a directory to\n // scaffold into, where `--force` creates a new app over this one.\n for (const detector of this.detectors) {\n if (detector.framework === requested) {\n continue;\n }\n const facts = await detector.detect(cwd);\n if (facts) {\n throw this.frameworkMismatch(requested, facts.id);\n }\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 * Describes the new `framework` app {@link scaffold} would create in `cwd`,\n * without touching the directory, so a caller can ask its questions first and\n * create the app only once it has every answer. Refuses up front what would\n * stop the app later: a directory name npm does not accept, or a framework\n * no scaffolder can create or no patcher can integrate.\n */\n async planScaffold(cwd: string, framework: string): Promise<PlannedApp> {\n assertNpmSafeScaffoldDirectoryName(cwd);\n this.scaffolderFor(framework);\n this.patcherFor(framework);\n return { framework, devPort: await detectDevPort(cwd, {}) };\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, force = false): Promise<FrameworkFacts> {\n const scaffold = await this.scaffoldUndoably(cwd, framework, force);\n await scaffold.keep();\n return scaffold.facts;\n }\n\n /**\n * {@link scaffold}, undoable until the caller keeps the new app: for a caller\n * with more to do before the app is worth keeping, which puts the directory\n * back as it was when that fails. A scaffold that fails itself is undone\n * before this throws.\n */\n async scaffoldUndoably(cwd: string, framework: string, force = false): Promise<UndoableScaffold> {\n const target = await inspectScaffoldTarget(cwd);\n if (!target.scaffoldable && !force) {\n throw new ZitadelError(\"E_CONFLICT\", `Cannot scaffold: ${cwd} is not empty`, {\n hint:\n `${target.reason ? `${target.reason} ` : \"\"}Pass --force to scaffold into a ` +\n \"non-empty directory, or run setup from an existing supported app project.\",\n details: { entries: target.entries },\n });\n }\n assertNpmSafeScaffoldDirectoryName(cwd);\n const before = await listEntries(cwd);\n // The underlying scaffolders require an empty directory. When it holds the\n // local runtime `start` left, or --force lets us scaffold into a non-empty\n // one, move the existing entries aside, scaffold, then restore anything the\n // scaffold did not create itself.\n const stash = await stashScaffoldDir(cwd, target.entries);\n const undo = () => undoScaffold(cwd, before, stash);\n let facts: FrameworkFacts;\n try {\n await this.scaffolderFor(framework).scaffold(cwd, framework);\n await restoreBesideScaffold(cwd, stash);\n facts = await this.detect(cwd, framework);\n } catch (error) {\n await undo();\n throw error;\n }\n return { facts, undo, keep: () => dropStash(stash) };\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 /** A framework's name as people write it (\"Next.js\" for `next`), or its id when it has none. */\n displayName(id: string): string {\n return this.availableFrameworks().find((framework) => framework.id === id)?.displayName ?? id;\n }\n\n /** `cwd` holds a `detected` app, and setup was asked to set up a `requested` one. */\n private frameworkMismatch(requested: string, detected: string): ZitadelError {\n const name = (id: string) => this.displayName(id);\n return new ZitadelError(\n \"E_CONFLICT\",\n `Setup detects ${name(detected)} here, not ${name(requested)}`,\n {\n hint:\n `Rerun setup without --framework, or with --framework ${detected}, to set up this ` +\n `app, or point --cwd at the ${name(requested)} app you meant. Setup never scaffolds ` +\n \"a new app over one it detects, --force or not.\",\n details: { requested, detected },\n },\n );\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: \"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(\n \"name may only contain lowercase letters, numbers, dots, underscores, tildes, and hyphens\",\n );\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 // A fresh scaffold needs an empty directory. We deliberately keep no allowlist\n // of other tools' \"harmless\" entries (`.claude`, editor settings, …): that list\n // is a maintenance treadmill, and each tool invents new metadata. Anything\n // present means not-fresh, and `--force` is the single, explicit override.\n //\n // The one exception is what `zitadel start` itself leaves, so that `start`\n // and then `setup` work in a new directory: the local runtime, and the\n // `.gitignore` line that keeps it out of git. `scaffold()` moves both aside\n // while the generator runs and merges the `.gitignore` back.\n const names = [...(await readdir(cwd))].sort();\n const others: string[] = [];\n for (const name of names) {\n if (!(await isLocalRuntimeEntry(cwd, name))) {\n others.push(name);\n }\n }\n if (others.length === 0) {\n return { scaffoldable: true, entries: names };\n }\n return {\n scaffoldable: false,\n reason: `Directory is not empty (contains ${others.join(\", \")}).`,\n entries: names,\n };\n}\n\n/**\n * Whether `name` in `cwd` is one of the entries `zitadel start` writes\n * (`ensureLocalState`): a `.zitadel` that holds nothing but the local runtime,\n * or a `.gitignore` that holds nothing but the line ignoring it. Either may be\n * empty once `reset` has removed the runtime.\n */\nasync function isLocalRuntimeEntry(cwd: string, name: string): Promise<boolean> {\n try {\n if (name === dirname(LOCAL_RUNTIME_DIR)) {\n const inside = await readdir(join(cwd, name));\n return inside.every((entry) => entry === basename(LOCAL_RUNTIME_DIR));\n }\n if (name === \".gitignore\") {\n const lines = (await readFile(join(cwd, name), \"utf8\")).split(/\\r?\\n/);\n return lines.every((line) => [\"\", `${LOCAL_RUNTIME_DIR}/`].includes(line.trim()));\n }\n } catch {\n // Not a directory, or not a readable file: not what `start` wrote.\n }\n return false;\n}\n\nasync function stashScaffoldDir(\n cwd: string,\n names: ReadonlyArray<string>,\n): Promise<ScaffoldStash | undefined> {\n if (names.length === 0) {\n return undefined;\n }\n\n const root = join(\n dirname(cwd),\n `.${basename(cwd)}.fresh-scaffold-stash-${String(process.pid)}-${String(Date.now())}`,\n );\n await mkdir(root, { mode: 0o700 });\n const moved: string[] = [];\n try {\n for (const name of names) {\n await rename(join(cwd, name), join(root, name));\n moved.push(name);\n }\n } catch (error) {\n // Put back what already moved, so a stash that fails halfway leaves the\n // directory as it was rather than stranding entries in the stash.\n for (const name of moved) {\n await rename(join(root, name), join(cwd, name));\n }\n await rm(root, { recursive: true, force: true });\n throw error;\n }\n return { root, names };\n}\n\n/**\n * Moves back each stashed entry the scaffold left free. An entry the scaffold\n * created its own file at stays in the stash, so an undo can put it back.\n */\nasync function restoreBesideScaffold(cwd: string, stash: ScaffoldStash | undefined): Promise<void> {\n if (!stash) {\n return;\n }\n for (const name of stash.names) {\n const dest = join(cwd, name);\n if (await pathExists(dest)) {\n // The scaffold created its own file at a stashed name. For `.gitignore`,\n // union the stashed rules back in so ignores the pre-existing setup\n // relied on — notably `.zitadel/local/`, which keeps the local admin\n // credential out of git — are not silently dropped. Any other collision\n // keeps the scaffold's version (that is what `--force` is for).\n if (name === \".gitignore\") {\n await mergeGitignore(join(stash.root, name), dest);\n }\n } else {\n // The scaffold left this name free; restore the pre-existing entry.\n await rename(join(stash.root, name), dest);\n }\n }\n}\n\n/**\n * What a directory holds: each entry, with the entries inside it when it is a\n * directory, so an undo can tell what was added since.\n */\ntype DirectoryListing = ReadonlyMap<string, ReadonlySet<string> | undefined>;\n\nasync function listEntries(cwd: string): Promise<DirectoryListing> {\n const listing = new Map<string, ReadonlySet<string> | undefined>();\n for (const entry of await readdir(cwd, { withFileTypes: true })) {\n listing.set(\n entry.name,\n entry.isDirectory() ? new Set(await readdir(join(cwd, entry.name))) : undefined,\n );\n }\n return listing;\n}\n\n/**\n * Puts `cwd` back to `before`: removes what the scaffold and anything after\n * it added, including entries added inside a directory `cwd` already held,\n * then moves back what is still in the stash, which the scaffold replaced or\n * a failure kept from coming back.\n */\nasync function undoScaffold(\n cwd: string,\n before: DirectoryListing,\n stash: ScaffoldStash | undefined,\n): Promise<void> {\n const stashed = new Set(stash ? await readdir(stash.root) : []);\n for (const entry of await readdir(cwd)) {\n const inside = before.get(entry);\n if (!before.has(entry) || stashed.has(entry)) {\n await rm(join(cwd, entry), { recursive: true, force: true });\n } else if (inside !== undefined) {\n for (const child of await readdir(join(cwd, entry))) {\n if (!inside.has(child)) {\n await rm(join(cwd, entry, child), { recursive: true, force: true });\n }\n }\n }\n }\n if (stash) {\n for (const name of stashed) {\n await rename(join(stash.root, name), join(cwd, name));\n }\n }\n await dropStash(stash);\n}\n\nasync function dropStash(stash: ScaffoldStash | undefined): Promise<void> {\n if (stash) {\n await rm(stash.root, { recursive: true, force: true });\n }\n}\n\n/** Append any lines from the stashed `.gitignore` that the scaffold's own one lacks. */\nasync function mergeGitignore(stashed: string, dest: string): Promise<void> {\n const [from, into] = await Promise.all([readFile(stashed, \"utf8\"), readFile(dest, \"utf8\")]);\n const present = new Set(into.split(\"\\n\").map((line) => line.trim()));\n const missing = from.split(\"\\n\").filter((line) => line.trim() && !present.has(line.trim()));\n if (missing.length === 0) {\n return;\n }\n await writeFile(dest, `${into}${into.endsWith(\"\\n\") ? \"\" : \"\\n\"}${missing.join(\"\\n\")}\\n`);\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { ZitadelError, type ZitadelErrorCode } from \"../../../lib/errors\";\nimport type { Orca } from \"../../../lib/orca\";\n\n/** Pass/fail/advisory outcome of a single {@link SanityCheck}. */\nexport type CheckOutcome = {\n details?: unknown;\n name: string;\n status: \"pass\" | \"warn\" | \"fail\";\n message: string;\n path?: string;\n /**\n * Set when the failure surfaced as a typed CLI error: the error's category\n * and remedy travel through the outcome so the doctor envelope can carry\n * the advertised code (e.g. the framework floor's\n * `E_UNSUPPORTED_PROJECT_SHAPE`) and hint instead of generic advice.\n */\n code?: ZitadelErrorCode;\n hint?: string;\n};\n\n/** Everything a check needs to inspect or repair a project. */\nexport type CheckContext = {\n readonly cwd: string;\n readonly orca: Orca;\n readonly cliVersion: string;\n /** When true, {@link SanityCheck.fix} must preview without writing. */\n readonly dryRun: boolean;\n};\n\n/**\n * One diagnostic the `doctor` command runs. Each concrete check is a small\n * standalone class that both verifies its concern ({@link run}) and knows how\n * to repair it ({@link fix}); the command executes every registered check,\n * aggregates the {@link CheckOutcome}s, and (under `--fix`) repairs the ones\n * that failed.\n */\nexport interface SanityCheck {\n /** Stable identifier surfaced in logs and the JSON envelope. */\n readonly name: string;\n run(ctx: CheckContext): Promise<CheckOutcome>;\n /** Repair what this check verifies. A no-op when there is no safe auto-fix. */\n fix(ctx: CheckContext): Promise<void>;\n}\n\n/**\n * Base class for checks: subclasses declare `name`, `path`, and a success\n * `summary`, and implement the single {@link verify} method that throws on\n * failure. {@link run} wraps it so a thrown error becomes a `fail` outcome\n * carrying the error message, and success becomes a `pass` with `summary`.\n *\n * {@link fix} defaults to a no-op: checks whose failure has no safe automatic\n * remedy (a missing secret, an invalid user schema) simply do not override it.\n */\nexport abstract class AbstractSanityCheck implements SanityCheck {\n abstract readonly name: string;\n abstract readonly path: string;\n protected abstract readonly summary: string;\n\n /** Throw to signal failure; the thrown message is surfaced to the user. */\n protected abstract verify(ctx: CheckContext): Promise<void>;\n\n async run(ctx: CheckContext): Promise<CheckOutcome> {\n try {\n await this.verify(ctx);\n return { name: this.name, status: \"pass\", message: this.summary, path: this.path };\n } catch (error) {\n return {\n name: this.name,\n status: \"fail\",\n message: error instanceof Error ? error.message : String(error),\n path: this.path,\n ...(error instanceof ZitadelError\n ? { code: error.code, ...(error.hint === undefined ? {} : { hint: error.hint }) }\n : {}),\n };\n }\n }\n\n async fix(_ctx: CheckContext): Promise<void> {\n return;\n }\n}\n","import { readZitadelConfig } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `zitadel.json` exists and parses. */\nexport class ConfigCheck extends AbstractSanityCheck {\n readonly name = \"config\";\n readonly path = \"zitadel.json\";\n protected readonly summary = \"zitadel.json parses\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n await readZitadelConfig(ctx.cwd);\n }\n}\n","import { readZitadelSecret } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `.zitadel/secret` exists and parses. */\nexport class SecretCheck extends AbstractSanityCheck {\n readonly name = \"secret\";\n readonly path = \".zitadel/secret\";\n protected readonly summary = \".zitadel/secret parses\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n await readZitadelSecret(ctx.cwd);\n }\n}\n","import { chmod, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `.zitadel/secret` is locked down to `0600`, and re-locks it on fix. */\nexport class SecretPermissionsCheck extends AbstractSanityCheck {\n readonly name = \"secret-permissions\";\n readonly path = \".zitadel/secret\";\n protected readonly summary = \".zitadel/secret has 0600 permissions\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const mode = (await stat(join(ctx.cwd, \".zitadel/secret\"))).mode & 0o777;\n if (mode !== 0o600) {\n throw new Error(`expected 0600, got ${mode.toString(8)}`);\n }\n }\n\n override async fix(ctx: CheckContext): Promise<void> {\n if (ctx.dryRun) {\n return;\n }\n await chmod(join(ctx.cwd, \".zitadel/secret\"), 0o600);\n }\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** The entries `.gitignore` must carry to keep secrets and env files untracked. */\nconst REQUIRED_ENTRIES = [\".zitadel/secret\", \".env*\", \"!.env.example\"];\n\n/** Verifies `.gitignore` excludes the local secret and env files; appends any missing. */\nexport class GitignoreCheck extends AbstractSanityCheck {\n readonly name = \"gitignore\";\n readonly path = \".gitignore\";\n protected readonly summary = \".gitignore protects local secret/env files\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const lines = (await readFile(join(ctx.cwd, \".gitignore\"), \"utf8\")).split(/\\r?\\n/g);\n for (const entry of REQUIRED_ENTRIES) {\n if (!lines.includes(entry)) {\n throw new Error(`missing ${entry}`);\n }\n }\n }\n\n override async fix(ctx: CheckContext): Promise<void> {\n const path = join(ctx.cwd, \".gitignore\");\n const existing = await readFile(path, \"utf8\").catch(() => \"\");\n const lines = existing.split(/\\r?\\n/g);\n const missing = REQUIRED_ENTRIES.filter((entry) => !lines.includes(entry));\n if (missing.length === 0 || ctx.dryRun) {\n return;\n }\n const prefix = existing.length > 0 && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\";\n await writeFile(path, `${existing}${prefix}${missing.join(\"\\n\")}\\n`);\n }\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** The keys `.env.example` must document for a Zitadel-managed project. */\nconst REQUIRED_KEYS = [\"ZITADEL_PROJECT_ID\", \"ZITADEL_ENVIRONMENT\", \"ZITADEL_ISSUER\"];\n\n/** Verifies `.env.example` documents the required Zitadel keys; appends any missing. */\nexport class EnvExampleCheck extends AbstractSanityCheck {\n readonly name = \"env-example\";\n readonly path = \".env.example\";\n protected readonly summary = \".env.example references required keys\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const contents = await readFile(join(ctx.cwd, \".env.example\"), \"utf8\");\n for (const key of REQUIRED_KEYS) {\n if (!contents.includes(`${key}=`)) {\n throw new Error(`missing ${key}`);\n }\n }\n }\n\n override async fix(ctx: CheckContext): Promise<void> {\n const path = join(ctx.cwd, \".env.example\");\n const existing = await readFile(path, \"utf8\").catch(() => \"\");\n const missing = REQUIRED_KEYS.filter((key) => !existing.includes(`${key}=`));\n if (missing.length === 0 || ctx.dryRun) {\n return;\n }\n const prefix = existing.length > 0 && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\";\n await writeFile(path, `${existing}${prefix}${missing.map((key) => `${key}=`).join(\"\\n\")}\\n`);\n }\n}\n","import { isObject } from \"../../../lib/json\";\nimport { readZitadelConfig } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies the framework detected on disk matches the one recorded in config. */\nexport class FrameworkCheck extends AbstractSanityCheck {\n readonly name = \"framework\";\n readonly path = \"zitadel.json\";\n protected readonly summary = \"Detected framework matches recorded framework\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const config = await readZitadelConfig(ctx.cwd);\n const detected = await ctx.orca.detect(ctx.cwd);\n const recorded = isObject(config.framework) ? config.framework.id : undefined;\n if (recorded !== detected.id) {\n throw new Error(`expected ${String(recorded)}, detected ${detected.id}`);\n }\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport { join, isAbsolute, relative, sep } from \"node:path\";\n\nimport { isObject } from \"./json\";\nimport type { EjectActions } from \"./orca/patchers/types\";\nimport { readState, updateScaffold } from \"./sync/state\";\nimport type { ScaffoldManifest, ScaffoldPosture } from \"./sync/types\";\n\n/**\n * Content hash of one scaffolded file as recorded in the scaffold manifest.\n * Deliberately hashes the raw text (not a parsed structure): the manifest\n * answers \"are these still the bytes setup wrote?\", nothing more. The sync\n * loop's hashers work on JSON objects and serve a different contract.\n */\nexport function hashScaffoldFile(contents: string): string {\n return createHash(\"sha256\").update(contents).digest(\"hex\");\n}\n\n/**\n * Read the scaffold manifest from `.zitadel/state.json`, or `undefined` when\n * the file, the section, its `files` record, or any file entry is missing or\n * malformed (each entry needs a string `hash` and a known `class`).\n * `undefined` sends the doctor managed-files check into its template-derived\n * fallback mode, so a corrupt or future-shaped manifest degrades rather than\n * breaks.\n */\nexport async function readScaffoldManifest(cwd: string): Promise<ScaffoldManifest | undefined> {\n try {\n const state = await readState(cwd);\n const scaffold = state.scaffold;\n // isObject rejects arrays too — `typeof [] === \"object\"`, and an array\n // `files` would otherwise enter manifest mode as \"0 tracked\".\n if (!isObject(scaffold)) {\n return undefined;\n }\n if (!isObject(scaffold.files)) {\n return undefined;\n }\n for (const entry of Object.values(scaffold.files)) {\n if (!isObject(entry)) {\n return undefined;\n }\n if (typeof entry.hash !== \"string\") {\n return undefined;\n }\n if (entry.class !== \"infrastructure\" && entry.class !== \"presentation\") {\n return undefined;\n }\n }\n // A posture value this CLI does not know is a future-shaped manifest —\n // degrade like any other malformed section rather than restoring a\n // posture the templates cannot render.\n if (\n scaffold.posture !== undefined &&\n scaffold.posture !== \"page\" &&\n scaffold.posture !== \"widget\"\n ) {\n return undefined;\n }\n return scaffold as unknown as ScaffoldManifest;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Record which managed app files `zitadel setup` actually wrote (or found\n * already matching), keyed by project-root-relative posix path with the\n * content hash and ownership class. Only marked files that the scaffold run\n * touched are recorded — a conditional file whose op never ran (e.g. the\n * framework home page on a pre-existing app) is simply absent, which is what\n * lets `doctor` later distinguish \"CLI wrote this and it vanished\" from \"the\n * CLI never owned this\".\n */\nexport async function writeScaffoldManifest(options: {\n cwd: string;\n actions: EjectActions;\n /** Paths the scaffold reported written or skipped-as-identical. */\n written: ReadonlyArray<string>;\n scaffoldedFramework?: boolean;\n devPort?: number;\n posture?: ScaffoldPosture;\n}): Promise<void> {\n const { cwd, actions, written, scaffoldedFramework, devPort, posture } = options;\n const touched = new Set(written.map((path) => relativePosix(cwd, path)));\n const files: ScaffoldManifest[\"files\"] = {};\n for (const path of actions.markedFiles) {\n const key = relativePosix(cwd, path);\n if (!touched.has(key)) {\n continue;\n }\n let contents: string;\n try {\n contents = await readFile(join(cwd, key), \"utf8\");\n } catch {\n continue;\n }\n files[key] = {\n hash: hashScaffoldFile(contents),\n class: actions.fileClasses?.[path] ?? \"presentation\",\n };\n }\n await updateScaffold(cwd, {\n files,\n ...(scaffoldedFramework ? { scaffolded_framework: true } : {}),\n ...(typeof devPort === \"number\" ? { dev_port: devPort } : {}),\n ...(posture === undefined ? {} : { posture }),\n });\n}\n\n/** Normalizes an absolute or relative path to a cwd-relative posix key. */\nfunction relativePosix(cwd: string, path: string): string {\n const rel = isAbsolute(path) ? relative(cwd, path) : path;\n return rel.split(sep).join(\"/\");\n}\n","import { resolveEnvironment } from \"../../lib/environment\";\nimport { issuerFromPort, type FrameworkFacts, type Orca } from \"../../lib/orca\";\nimport type { PatchContext } from \"../../lib/orca/patchers/types\";\nimport {\n readPreset,\n readRendererId,\n readUseCase,\n readZitadelConfig,\n readZitadelSecret,\n} from \"../../lib/project\";\nimport { readScaffoldManifest } from \"../../lib/scaffold-manifest\";\n\n/**\n * Reconstructs a {@link PatchContext} from the on-disk project (config,\n * secret, scaffold manifest) plus fresh framework detection, so a patcher\n * repair can rebuild its plan. Used by the doctor checks' `fix` paths.\n * `preset`/`useCase` come back from `zitadel.json` and\n * `scaffoldedFramework` from the scaffold manifest, so the rebuilt plan\n * matches what setup originally emitted (a fresh-scaffolded app's home page\n * is part of the plan again, for example). Schema and flow config are\n * user-editable sync resources, not patcher inputs, so nothing here reads\n * them.\n */\nexport async function loadPatchContext(\n cwd: string,\n orca: Orca,\n cliVersion: string,\n): Promise<PatchContext> {\n const config = await readZitadelConfig(cwd);\n const secret = await readZitadelSecret(cwd);\n const framework = await orca.detect(cwd);\n const scaffold = await readScaffoldManifest(cwd);\n return {\n framework,\n rendererId: readRendererId(config),\n issuer: await resolveIssuer(cwd, framework),\n server: typeof config.server === \"string\" ? config.server : \"\",\n cliVersion,\n scaffoldedFramework: scaffold?.scaffolded_framework,\n // Restore the posture setup recorded rather than re-deriving it — a\n // manifest-less legacy scaffold cannot answer the fresh-vs-pre-existing\n // hinge, and every scaffold before the record was full-page (ADR 044).\n posture: scaffold?.posture ?? \"page\",\n preset: readPreset(config),\n useCase: readUseCase(config),\n project: {\n id: secret.project_id,\n project_secret: secret.project_secret,\n preview_secret: secret.preview_secret,\n origins: [\n ...(secret.primary_origins ?? []).map((pattern) => ({\n pattern,\n kind: \"primary\" as const,\n })),\n ...secret.preview_origins.map((pattern) => ({\n pattern,\n kind: \"preview\" as const,\n })),\n ],\n created_at: secret.created_at,\n },\n };\n}\n\n/**\n * The issuer setup recorded for the development project (`ZITADEL_ISSUER`),\n * from its files alone: the repair writes it into `.env.local` and\n * `.env.development.local`, so a production issuer exported in the shell, or a\n * `ZITADEL_ENV` naming another environment, must never stand in for it.\n * `undefined` when no file sets it, or one the resolver cannot read.\n */\nexport async function configuredIssuer(cwd: string): Promise<string | undefined> {\n return resolveEnvironment({ cwd, env: {} }).then(\n ({ values }) => values.ZITADEL_ISSUER?.value,\n () => undefined,\n );\n}\n\nasync function resolveIssuer(cwd: string, facts: FrameworkFacts): Promise<string> {\n // A file the resolver cannot read leaves the issuer to the fallbacks below\n // rather than failing the repair.\n const issuer = await configuredIssuer(cwd);\n if (issuer !== undefined) {\n return issuer;\n }\n const scaffold = await readScaffoldManifest(cwd);\n if (typeof scaffold?.dev_port === \"number\") {\n return issuerFromPort(scaffold.dev_port);\n }\n return facts.url;\n}\n","import { readFile, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport type { ConfigWiringStatus, EjectActions } from \"../../../lib/orca/patchers/types\";\nimport { MANAGED_MARKER } from \"../../../lib/paths\";\nimport { readRendererId, readZitadelConfig } from \"../../../lib/project\";\nimport {\n hashScaffoldFile,\n readScaffoldManifest,\n writeScaffoldManifest,\n} from \"../../../lib/scaffold-manifest\";\nimport { updateScaffold } from \"../../../lib/sync/state\";\nimport type { ScaffoldFileClass, ScaffoldManifest } from \"../../../lib/sync/types\";\nimport { loadPatchContext } from \"../patch-context\";\nimport type { CheckContext, CheckOutcome, SanityCheck } from \"./types\";\n\n/**\n * Per-file classification reported in the check's `details`:\n *\n * - `pristine` — still the bytes setup wrote (manifest hash matches).\n * - `edited` — carries the managed marker but the content changed; the user\n * extended a managed file (e.g. added routes to the request boundary).\n * - `adopted` — the marker is gone; the user replaced the file and owns it\n * now (mirrors `eject`, which preserves marker-less files).\n * - `managed` — marker present; used in template mode, where no recorded\n * hash exists to tell pristine from edited.\n * - `missing` — the file is gone. Infrastructure ⇒ fail, presentation ⇒ warn.\n */\ntype ScaffoldFileState = \"pristine\" | \"edited\" | \"adopted\" | \"managed\" | \"missing\";\n\ntype ScaffoldFileRow = {\n path: string;\n class: ScaffoldFileClass;\n state: ScaffoldFileState;\n};\n\n/**\n * Verifies the scaffolded app files still exist: the ones `zitadel setup`\n * wrote per the scaffold manifest in `.zitadel/state.json`, or — for apps\n * scaffolded before the manifest existed — the patcher's current template\n * expectations minus conditionally-written files. A missing *infrastructure*\n * file (request boundary, provider, type declarations) breaks the auth\n * integration and fails the check; a missing *presentation* page only warns.\n * Edited and user-adopted files pass — they are the intended customization\n * paths — and are labelled in `details` for visibility.\n *\n * Implements {@link SanityCheck} directly rather than via the abstract base:\n * the base's `verify`-throws contract can only express pass/fail, and this\n * check needs the `warn` outcome.\n */\nexport class ManagedFilesCheck implements SanityCheck {\n readonly name = \"managed-files\";\n\n async run(ctx: CheckContext): Promise<CheckOutcome> {\n const manifest = await readScaffoldManifest(ctx.cwd);\n const evaluated = manifest\n ? await evaluateManifest(ctx.cwd, manifest)\n : await evaluateTemplates(ctx);\n if (!evaluated) {\n return {\n name: this.name,\n status: \"warn\",\n message:\n \"Could not enumerate scaffolded app files (framework or renderer unresolved); skipping the file check\",\n };\n }\n\n const { mode, rows } = evaluated;\n const wiring = await probeConfigWiring(ctx);\n const actions = await resolveArtifacts(ctx);\n const boundaries = actions ? await detectBoundaryConflicts(actions, ctx.cwd, manifest) : [];\n const missing = rows.filter((row) => row.state === \"missing\");\n const missingInfrastructure = missing.filter((row) => row.class === \"infrastructure\");\n const detachedInfrastructure = wiring.filter(\n (s) => s.state === \"detached\" && s.wiring === \"infrastructure\",\n );\n const detachedConvenience = wiring.filter(\n (s) => s.state === \"detached\" && s.wiring === \"convenience\",\n );\n const unverifiable = wiring.filter((s) => s.state === \"unknown\");\n const conflicts = boundaries.filter((b) => b.disposition === \"conflict\");\n const removable = boundaries.filter((b) => b.disposition === \"removable\");\n const details = {\n mode,\n files: rows,\n ...(wiring.length > 0 ? { config_wiring: wiring } : {}),\n ...(boundaries.length > 0 ? { boundary_conflicts: boundaries } : {}),\n };\n\n const failures: string[] = [];\n if (missingInfrastructure.length > 0) {\n failures.push(\n `missing scaffolded infrastructure file(s): ${listPaths(missingInfrastructure)}`,\n );\n }\n if (detachedInfrastructure.length > 0) {\n failures.push(\n `detached managed config wiring: ${detachedInfrastructure.map((s) => s.path).join(\", \")}`,\n );\n }\n for (const conflict of conflicts) {\n failures.push(\n `conflicting request boundaries: ${conflict.retired} is user-modified while the current templates use ${conflict.current} — migrate your changes and remove one of them manually`,\n );\n }\n if (failures.length > 0) {\n return { name: this.name, status: \"fail\", message: failures.join(\"; \"), details };\n }\n\n const warnings: string[] = [];\n if (missing.length > 0) {\n warnings.push(`missing scaffolded page(s): ${listPaths(missing)}`);\n }\n if (detachedConvenience.length > 0) {\n warnings.push(\n `unapplied managed config edit(s): ${detachedConvenience.map((s) => s.path).join(\", \")} (doctor --fix applies them)`,\n );\n }\n if (unverifiable.length > 0) {\n warnings.push(\n `unverifiable managed config wiring (manual review required): ${unverifiable\n .map((s) => (s.reason ? `${s.path} (${s.reason})` : s.path))\n .join(\", \")}`,\n );\n }\n for (const leftover of removable) {\n warnings.push(\n `retired boundary ${leftover.retired} left over from a template migration (doctor --fix removes it and installs ${leftover.current})`,\n );\n }\n if (warnings.length > 0) {\n return { name: this.name, status: \"warn\", message: warnings.join(\"; \"), details };\n }\n\n return {\n name: this.name,\n status: \"pass\",\n message: `Scaffolded app files are present (${rows.length} tracked${\n wiring.length > 0\n ? `, ${wiring.length} wiring${wiring.length === 1 ? \"\" : \"s\"} verified`\n : \"\"\n }${mode === \"template\" ? \", from templates\" : \"\"})`,\n details,\n };\n }\n\n /**\n * Restores missing managed files via the patcher's missing-only repair —\n * existing files, edited or adopted, are never overwritten — then refreshes\n * the manifest hashes of the files the repair brought back so they classify\n * as pristine again. The restored bytes come from the *current* templates,\n * which may differ from what the original CLI version wrote; the re-hash\n * records that honestly. On a pre-manifest app (template mode) a successful\n * repair also materializes the manifest from the marker-bearing files now\n * on disk, completing the migration ADR 042 promises — adopted files stay\n * the user's and are not recorded.\n */\n async fix(ctx: CheckContext): Promise<void> {\n const manifest = await readScaffoldManifest(ctx.cwd);\n const missingBefore = manifest ? await missingManifestPaths(ctx.cwd, manifest) : [];\n const patchCtx = await loadPatchContext(ctx.cwd, ctx.orca, ctx.cliVersion);\n const patcher = ctx.orca.patcherFor(patchCtx.framework.id);\n const actions = patcher.artifacts({\n framework: patchCtx.framework,\n rendererId: patchCtx.rendererId,\n });\n // Boundary migration: a *pristine* retired alternate (hash-proven CLI\n // bytes, e.g. Next 15's middleware.ts after an upgrade) is removed so the\n // current boundary can be installed without the framework rejecting the\n // pair. A user-modified or adopted alternate is a conflict: it stays, and\n // the current boundary is excluded from the repair — creating proxy.ts\n // beside an edited middleware.ts would break the build outright. Dry-run\n // deletes nothing and keeps the exclusion, so the preview stays safe.\n const boundaries = await detectBoundaryConflicts(actions, ctx.cwd, manifest);\n const excludePaths = boundaries\n .filter((b) => b.disposition === \"conflict\")\n .map((b) => b.current);\n const removed: string[] = [];\n if (!ctx.dryRun) {\n for (const boundary of boundaries) {\n if (boundary.disposition === \"removable\") {\n await rm(join(ctx.cwd, boundary.retired), { force: true });\n removed.push(boundary.retired);\n }\n }\n }\n await patcher.repair(patchCtx, {\n cwd: ctx.cwd,\n dryRun: ctx.dryRun,\n force: false,\n missingOnly: true,\n ...(excludePaths.length > 0 ? { excludePaths } : {}),\n });\n if (ctx.dryRun) {\n return;\n }\n if (!manifest) {\n await materializeManifest(ctx, patchCtx);\n return;\n }\n if (missingBefore.length === 0 && removed.length === 0) {\n return;\n }\n // Reconcile the manifest with the current template set before rewriting\n // it. Template migrations (Next 15's middleware.ts → Next 16's proxy.ts)\n // retire paths the current plan no longer writes: repair restores the\n // *new* boundary, so a retired entry whose file stays absent must be\n // dropped — keeping it would fail doctor forever, since setup skips\n // initialized projects. Paths the repair newly introduced are adopted\n // with their class and on-disk hash. A conditional path the repair did\n // not bring back is one the current plan does not write for this app\n // (Nuxt's retired plugins), so it is dropped the same way.\n const current = new Set(actions.markedFiles);\n const conditional = new Set(actions.conditionalFiles ?? []);\n const files: ScaffoldManifest[\"files\"] = {};\n for (const [path, entry] of Object.entries(manifest.files)) {\n const contents = await readIfExists(join(ctx.cwd, path));\n if (contents === undefined && (!current.has(path) || conditional.has(path))) {\n continue; // retired by a template migration and gone from disk\n }\n files[path] =\n contents !== undefined && missingBefore.includes(path)\n ? { ...entry, hash: hashScaffoldFile(contents) }\n : entry;\n }\n for (const path of actions.markedFiles) {\n if (files[path] || conditional.has(path)) {\n continue;\n }\n const contents = await readIfExists(join(ctx.cwd, path));\n if (contents !== undefined && contents.includes(MANAGED_MARKER)) {\n files[path] = {\n hash: hashScaffoldFile(contents),\n class: actions.fileClasses?.[path] ?? \"presentation\",\n };\n }\n }\n await updateScaffold(ctx.cwd, { ...manifest, files });\n }\n}\n\n/**\n * A retired template alternate (an old boundary filename) that still exists\n * beside — or instead of — the file the current templates write.\n * `removable`: hash-proven pristine CLI bytes per the manifest, safe for\n * `--fix` to delete during migration. `conflict`: user-modified, adopted, or\n * simply unhashable (template mode) — never deleted, and the current\n * counterpart must not be created next to it.\n */\ntype BoundaryConflict = {\n current: string;\n retired: string;\n disposition: \"removable\" | \"conflict\";\n};\n\nasync function detectBoundaryConflicts(\n actions: EjectActions,\n cwd: string,\n manifest: ScaffoldManifest | undefined,\n): Promise<BoundaryConflict[]> {\n const conflicts: BoundaryConflict[] = [];\n for (const [current, retiredPaths] of Object.entries(actions.retiredAlternates ?? {})) {\n for (const retired of retiredPaths) {\n const contents = await readIfExists(join(cwd, retired));\n if (contents === undefined) {\n continue;\n }\n const entry = manifest?.files[retired];\n const pristine =\n entry !== undefined &&\n contents.includes(MANAGED_MARKER) &&\n hashScaffoldFile(contents) === entry.hash;\n conflicts.push({ current, retired, disposition: pristine ? \"removable\" : \"conflict\" });\n }\n }\n return conflicts;\n}\n\n/**\n * Probe the patcher's managed config wirings (dev proxy merges, route\n * registrations). Needs the full patch context (project secret et al) to\n * rebuild the plan; when that fails — missing secret, undetectable\n * framework — the probe is skipped silently and the responsible check\n * reports the real problem.\n */\nasync function probeConfigWiring(ctx: CheckContext): Promise<ReadonlyArray<ConfigWiringStatus>> {\n try {\n const patchCtx = await loadPatchContext(ctx.cwd, ctx.orca, ctx.cliVersion);\n return await ctx.orca.patcherFor(patchCtx.framework.id).verify(patchCtx, { cwd: ctx.cwd });\n } catch {\n return [];\n }\n}\n\n/**\n * Migration path for apps scaffolded before the manifest existed: after a\n * template-mode repair, record the marker-bearing managed files now on disk\n * so the next doctor run gets exact manifest-mode verification instead of\n * template guessing (and its Next-major / template-growth misclassification\n * risk). Marker-less (adopted) files and conditionally-scaffolded ones are\n * deliberately absent.\n *\n * The manifest is only finalized when every current *infrastructure* file is\n * present and recordable (marker-bearing): materializing during an\n * unresolved boundary conflict — or over an adopted boundary — would write a\n * manifest that tracks no request boundary at all, and deleting the boundary\n * later would go undetected. Until then the app stays on the template\n * fallback, whose presence checks keep enforcing the boundary. Best-effort:\n * an unreadable state file leaves the app in template mode, same as before.\n */\nasync function materializeManifest(\n ctx: CheckContext,\n patchCtx: Awaited<ReturnType<typeof loadPatchContext>>,\n): Promise<void> {\n try {\n const actions = ctx.orca.patcherFor(patchCtx.framework.id).artifacts({\n framework: patchCtx.framework,\n rendererId: patchCtx.rendererId,\n });\n const conditional = new Set(actions.conditionalFiles ?? []);\n const marked: string[] = [];\n for (const path of actions.markedFiles) {\n if (conditional.has(path)) {\n continue;\n }\n const contents = await readIfExists(join(ctx.cwd, path));\n if (contents !== undefined && contents.includes(MANAGED_MARKER)) {\n marked.push(path);\n }\n }\n const infrastructure = actions.markedFiles.filter(\n (path) => actions.fileClasses?.[path] === \"infrastructure\" && !conditional.has(path),\n );\n if (!infrastructure.every((path) => marked.includes(path))) {\n return;\n }\n await writeScaffoldManifest({ cwd: ctx.cwd, actions, written: marked });\n } catch {\n // state.json unreadable or the write raced — stays in template mode.\n }\n}\n\nasync function evaluateManifest(\n cwd: string,\n manifest: ScaffoldManifest,\n): Promise<{ mode: \"manifest\"; rows: ScaffoldFileRow[] }> {\n const rows: ScaffoldFileRow[] = [];\n for (const [path, entry] of Object.entries(manifest.files)) {\n const contents = await readIfExists(join(cwd, path));\n rows.push({ path, class: entry.class, state: stateFor(contents, entry.hash) });\n }\n return { mode: \"manifest\", rows };\n}\n\n/**\n * Fallback for apps scaffolded before the manifest existed: derive the\n * expected set from the patcher's current templates. Conditionally-written\n * files (e.g. the framework home page) are excluded — without a manifest\n * there is no way to know whether setup ever wrote them. Presence-only:\n * no recorded hash means `pristine` vs `edited` cannot be told apart.\n */\nasync function evaluateTemplates(\n ctx: CheckContext,\n): Promise<{ mode: \"template\"; rows: ScaffoldFileRow[] } | undefined> {\n const actions = await resolveArtifacts(ctx);\n if (!actions) {\n return undefined;\n }\n const conditional = new Set(actions.conditionalFiles ?? []);\n const rows: ScaffoldFileRow[] = [];\n for (const path of actions.markedFiles) {\n if (conditional.has(path)) {\n continue;\n }\n const contents = await readIfExists(join(ctx.cwd, path));\n rows.push({\n path,\n class: actions.fileClasses?.[path] ?? \"presentation\",\n state: stateFor(contents, undefined),\n });\n }\n return { mode: \"template\", rows };\n}\n\n/**\n * Resolves the patcher artifacts the same way `eject` does, tolerating every\n * failure with `undefined`: a broken framework detection, an unreadable\n * config, or an unresolvable renderer are reported by their own checks —\n * this one only degrades to \"cannot enumerate\".\n */\nexport async function resolveArtifacts(ctx: CheckContext): Promise<EjectActions | undefined> {\n const framework = await ctx.orca.tryDetect(ctx.cwd);\n if (!framework) {\n return undefined;\n }\n try {\n const config = await readZitadelConfig(ctx.cwd).catch(() => ({}) as Record<string, unknown>);\n return ctx.orca.patcherFor(framework.id).artifacts({\n framework,\n rendererId: readRendererId(config),\n });\n } catch {\n return undefined;\n }\n}\n\nfunction stateFor(contents: string | undefined, hash: string | undefined): ScaffoldFileState {\n if (contents === undefined) {\n return \"missing\";\n }\n if (!contents.includes(MANAGED_MARKER)) {\n return \"adopted\";\n }\n if (hash === undefined) {\n return \"managed\";\n }\n return hashScaffoldFile(contents) === hash ? \"pristine\" : \"edited\";\n}\n\nasync function missingManifestPaths(cwd: string, manifest: ScaffoldManifest): Promise<string[]> {\n const missing: string[] = [];\n for (const path of Object.keys(manifest.files)) {\n if ((await readIfExists(join(cwd, path))) === undefined) {\n missing.push(path);\n }\n }\n return missing;\n}\n\nasync function readIfExists(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return undefined;\n }\n}\n\nfunction listPaths(rows: ReadonlyArray<ScaffoldFileRow>): string {\n return rows.map((row) => row.path).join(\", \");\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ManagedFilesCheck, resolveArtifacts } from \"./managed-files\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/**\n * Verifies the project still declares every package its Zitadel integration\n * imports. The patcher knows them (`@zitadel/sdk-next`, or a meta-framework's\n * server SDK plus the widget SDK its pages import), so the check requires\n * exactly those; another `@zitadel/*` package, such as the CLI as a\n * devDependency, does not stand in for a missing one. When the framework\n * cannot be resolved (the framework check reports why), any `@zitadel/*`\n * dependency passes.\n */\nexport class DependencyCheck extends AbstractSanityCheck {\n readonly name = \"dependency\";\n readonly path = \"package.json\";\n protected readonly summary = \"package.json depends on the Zitadel SDK packages the app imports\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const pkg = JSON.parse(await readFile(join(ctx.cwd, \"package.json\"), \"utf8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const names = new Set([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ]);\n const required = (await resolveArtifacts(ctx))?.dependencies;\n if (required === undefined || required.length === 0) {\n if (![...names].some((name) => name.startsWith(\"@zitadel\"))) {\n throw new Error(\"no @zitadel* dependency found in package.json\");\n }\n return;\n }\n const missing = required.filter((name) => !names.has(name));\n if (missing.length > 0) {\n throw new Error(`package.json does not declare ${missing.join(\", \")}, which the app imports`);\n }\n }\n\n /**\n * Repairs through the managed-files repair, which re-applies the patcher's\n * managed artifacts: its `add-dep` ops re-add the SDK dependencies. The exact\n * package names are framework + renderer specific and known only to the\n * patcher (which deliberately hides its file-op plan behind the\n * family-neutral `Patcher` interface), so going through `repair` is the only\n * sanctioned path. Delegating to the managed-files check keeps its boundary\n * handling: a restored Next 16 `proxy.ts` is never created beside an edited\n * `middleware.ts`, however the repair was started.\n */\n override async fix(ctx: CheckContext): Promise<void> {\n await new ManagedFilesCheck().fix(ctx);\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport type PackageManager = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\nexport type PackageCommand = {\n command: PackageManager;\n args: string[];\n display: string;\n};\n\nexport async function detectPackageManager(cwd: string): Promise<PackageManager> {\n const declared = await packageManagerFromManifest(cwd);\n if (declared) {\n return declared;\n }\n if (await exists(join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (await exists(join(cwd, \"yarn.lock\"))) return \"yarn\";\n if (await exists(join(cwd, \"bun.lock\"))) return \"bun\";\n if (await exists(join(cwd, \"bun.lockb\"))) return \"bun\";\n if (await exists(join(cwd, \"package-lock.json\"))) return \"npm\";\n return \"npm\";\n}\n\nexport function installCommandFor(packageManager: PackageManager): PackageCommand {\n return command(packageManager, [\"install\"]);\n}\n\n/**\n * Adds (or re-pins) the given `name@version` specs at exactly those versions.\n * Every manager saves a caret range by default, which would silently turn an\n * exact pin into a float — the exact-save flag keeps the written specifier\n * identical to the requested version.\n */\nexport function addExactCommandFor(\n packageManager: PackageManager,\n packages: ReadonlyArray<string>,\n): PackageCommand {\n switch (packageManager) {\n case \"npm\":\n return command(\"npm\", [\"install\", \"--save-exact\", ...packages]);\n case \"pnpm\":\n return command(\"pnpm\", [\"add\", \"--save-exact\", ...packages]);\n case \"yarn\":\n return command(\"yarn\", [\"add\", \"--exact\", ...packages]);\n case \"bun\":\n return command(\"bun\", [\"add\", \"--exact\", ...packages]);\n }\n}\n\nexport function devCommandFor(packageManager: PackageManager): PackageCommand {\n switch (packageManager) {\n case \"npm\":\n return command(\"npm\", [\"run\", \"dev\"]);\n case \"pnpm\":\n return command(\"pnpm\", [\"dev\"]);\n case \"yarn\":\n return command(\"yarn\", [\"dev\"]);\n case \"bun\":\n return command(\"bun\", [\"run\", \"dev\"]);\n }\n}\n\nexport async function runPackageCommand(\n packageCommand: PackageCommand,\n options: {\n cwd: string;\n env?: NodeJS.ProcessEnv;\n redirectStdoutToStderr?: boolean;\n },\n): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(packageCommand.command, packageCommand.args, {\n cwd: options.cwd,\n env: options.env ?? process.env,\n stdio: options.redirectStdoutToStderr ? [\"ignore\", \"pipe\", \"pipe\"] : \"inherit\",\n });\n\n if (options.redirectStdoutToStderr) {\n child.stdout?.on(\"data\", (chunk) => process.stderr.write(chunk));\n child.stderr?.on(\"data\", (chunk) => process.stderr.write(chunk));\n }\n\n child.on(\"error\", reject);\n child.on(\"close\", (code, signal) => {\n if (code === 0) {\n resolve();\n return;\n }\n const detail = signal ? `signal ${signal}` : `exit ${String(code ?? 1)}`;\n const error = new Error(`${packageCommand.display} failed with ${detail}`);\n Object.assign(error, { code: code ?? 1, signal });\n reject(error);\n });\n });\n}\n\nfunction command(packageManager: PackageManager, args: string[]): PackageCommand {\n return {\n command: packageManager,\n args,\n display: [packageManager, ...args].join(\" \"),\n };\n}\n\nasync function packageManagerFromManifest(cwd: string): Promise<PackageManager | undefined> {\n try {\n const raw = await readFile(join(cwd, \"package.json\"), \"utf8\");\n const parsed = JSON.parse(raw) as { packageManager?: unknown };\n return typeof parsed.packageManager === \"string\"\n ? packageManagerFromString(parsed.packageManager)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction packageManagerFromString(value: string): PackageManager | undefined {\n const name = value.split(\"@\")[0];\n return name === \"npm\" || name === \"pnpm\" || name === \"yarn\" || name === \"bun\" ? name : undefined;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(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 semver from \"semver\";\n\nimport { addExactCommandFor, detectPackageManager } from \"../../../lib/package-manager\";\nimport type { CheckContext, CheckOutcome, SanityCheck } from \"./types\";\n\n/**\n * Verifies that exactly-pinned `@zitadel/*` dependencies match this CLI's own\n * version. The packages publish as one lockstep train, and the scaffold pins\n * the SDK at the CLI's version — but the CLI floats (`npx @zitadel/cli@latest`)\n * while the app's pin stays put, so a newer CLI can restore files or write\n * guidance that references SDK entry points the older pinned SDK does not\n * ship (e.g. a subpath export added a train later). A mismatch therefore\n * *warns* with the exact remedy instead of leaving the skew to surface as a\n * module-not-found in the app.\n *\n * Only exact semver pins are compared: ranges, dist-tags, and `file:`/\n * `workspace:` specifiers express a deliberate resolution choice the check\n * cannot second-guess.\n *\n * Implements {@link SanityCheck} directly: the abstract base's verify-throws\n * contract can only express pass/fail, and a version skew is advisory — the\n * app keeps working on its pinned train until the user upgrades.\n */\nexport class DependencyVersionCheck implements SanityCheck {\n readonly name = \"dependency-version\";\n readonly path = \"package.json\";\n\n async run(ctx: CheckContext): Promise<CheckOutcome> {\n const base = { name: this.name, path: this.path };\n if (semver.valid(ctx.cliVersion) === null) {\n // A dev or placeholder CLI version has no train to compare against.\n return {\n ...base,\n status: \"pass\",\n message: `CLI version ${ctx.cliVersion} is not an exact release; skipping the pin comparison`,\n };\n }\n const exact = await exactZitadelPins(ctx.cwd);\n if (exact === undefined) {\n // A missing or unparsable package.json is the dependency check's\n // failure to report; double-flagging the same root cause helps nobody.\n return { ...base, status: \"pass\", message: \"no package.json to compare pins against\" };\n }\n const mismatched = exact.filter(([, version]) => !semver.eq(version, ctx.cliVersion));\n if (mismatched.length > 0) {\n // Repair with the project's own package manager and an exact-save flag:\n // a bare `npm install` would switch managers on a pnpm/yarn/bun project\n // and write a caret range — exactly the float this check ignores.\n const remedy = addExactCommandFor(\n await detectPackageManager(ctx.cwd),\n mismatched.map(([name]) => `${name}@${ctx.cliVersion}`),\n ).display;\n return {\n ...base,\n status: \"warn\",\n message:\n `${mismatched.map(([name, version]) => `${name}@${version}`).join(\", \")} ` +\n `does not match this CLI's version (${ctx.cliVersion}); scaffolded files and ` +\n `guidance target the CLI's train — update with \\`${remedy}\\``,\n details: {\n mismatched: mismatched.map(([name, version]) => ({\n name,\n declared: version,\n expected: ctx.cliVersion,\n })),\n remedy_command: remedy,\n },\n };\n }\n return {\n ...base,\n status: \"pass\",\n message:\n exact.length > 0\n ? `Zitadel package pins match the CLI version (${exact.length} compared)`\n : \"no exactly-pinned Zitadel packages to compare\",\n };\n }\n\n /**\n * No auto-fix: repair's dependency op is deliberately additive-only (it\n * never rewrites a version the user declared), so the repair ships as the\n * package-manager-aware install command in `details.remedy_command` — the\n * doctor command surfaces it in the envelope's `next_commands` — with the\n * same command quoted in the warn message for human readers.\n */\n async fix(_ctx: CheckContext): Promise<void> {\n return;\n }\n}\n\n/**\n * The `@zitadel/*` dependencies `package.json` pins to an exact version, as\n * `[name, version]`, or undefined without a readable `package.json`. Ranges,\n * dist-tags and `file:`/`workspace:` specifiers are left out: they express a\n * resolution choice, not a train.\n */\nexport async function exactZitadelPins(cwd: string): Promise<Array<[string, string]> | undefined> {\n let pkg: { dependencies?: Record<string, string>; devDependencies?: Record<string, string> };\n try {\n pkg = JSON.parse(await readFile(join(cwd, \"package.json\"), \"utf8\")) as typeof pkg;\n } catch {\n return undefined;\n }\n return Object.entries({ ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) })\n .filter(([name]) => name.startsWith(\"@zitadel/\"))\n .map(([name, version]): [string, string] => [name, version.trim()])\n .filter(([, version]) => semver.valid(version) !== null);\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport semver from \"semver\";\n\nimport { META_SCHEMA_DIR } from \"@zitadel/config/meta-schemas\";\n\nimport {\n linkOnPath,\n metaSchemaState,\n projectMetaSchemas,\n type ProjectMetaSchema,\n} from \"../../../lib/meta-schemas\";\nimport { exactZitadelPins } from \"./dependency-version\";\nimport type { CheckContext, CheckOutcome, SanityCheck } from \"./types\";\n\n/**\n * The meta-schemas a project lacks and the ones that differ from this CLI's,\n * which `--fix` writes; the symlinks that keep others from being written; and\n * the files that cannot be read, with the reason.\n */\ntype MetaSchemaDrift = {\n missing: ProjectMetaSchema[];\n outdated: ProjectMetaSchema[];\n links: string[];\n unreadable: { path: string; reason: string }[];\n};\n\n/** A `@zitadel/*` package the project pins to a version newer than this CLI. */\ntype NewerPin = { name: string; version: string };\n\n/**\n * Verifies the editor meta-schemas in `.zitadel/meta/` match this CLI. Only\n * `setup` writes them, so a project set up by an older CLI lacks the dialects\n * added since and holds the ones that changed in their old version: a file's\n * `$schema` points at nothing, or editors and agents read outdated rules.\n *\n * They are CLI-owned generated output (ADR 042's amendment), never read by\n * `deploy` or the server, so a stale file only misleads the editor: that is\n * a warning, not a failure, and `--fix` rewrites them. A file there the CLI\n * does not ship is left alone. {@link metaSchemaState} decides what differs,\n * and when a symlink keeps a file from being written.\n *\n * A file that differs may as well come from a newer CLI. When the project\n * pins a `@zitadel/*` package to a newer version than this CLI, the train it\n * deploys with is newer, so this CLI reports the difference and writes\n * nothing: writing its own version back would make the editor disagree with\n * what `deploy` enforces.\n *\n * Implements {@link SanityCheck} directly: the abstract base can only pass or\n * fail.\n */\nexport class MetaSchemasCheck implements SanityCheck {\n readonly name = \"meta-schemas\";\n readonly path = META_SCHEMA_DIR;\n\n async run(ctx: CheckContext): Promise<CheckOutcome> {\n const base = { name: this.name, path: this.path };\n const { missing, outdated, links, unreadable } = await drift(ctx);\n if (\n missing.length === 0 &&\n outdated.length === 0 &&\n links.length === 0 &&\n unreadable.length === 0\n ) {\n return {\n ...base,\n status: \"pass\",\n message: \"editor schemas in .zitadel/meta/ match this CLI\",\n };\n }\n const newer = missing.length > 0 || outdated.length > 0 ? await newerPin(ctx) : undefined;\n const parts = [\n missing.length > 0 ? `${missing.length} missing` : undefined,\n outdated.length > 0 ? `${outdated.length} differ from this CLI's` : undefined,\n ...links.map((link) => `${link} is a symbolic link, not rewritten`),\n ...unreadable.map((file) => `${file.path} unreadable (${file.reason})`),\n ].filter((part) => part !== undefined);\n const next =\n newer !== undefined\n ? `; the project pins ${newer.name}@${newer.version}, newer than this CLI ` +\n `(${ctx.cliVersion}), so it leaves them to that version's doctor --fix.`\n : missing.length > 0 || outdated.length > 0\n ? \"; doctor --fix writes this version's.\"\n : \".\";\n return {\n ...base,\n status: \"warn\",\n message: `editor schemas in .zitadel/meta/: ${parts.join(\", \")}. They are generated by the CLI${next}`,\n details: {\n missing: missing.map((file) => file.path),\n outdated: outdated.map((file) => file.path),\n ...(links.length > 0 ? { linked: links } : {}),\n ...(unreadable.length > 0 ? { unreadable } : {}),\n ...(newer !== undefined ? { newer_pin: newer } : {}),\n },\n };\n }\n\n async fix(ctx: CheckContext): Promise<void> {\n const { missing, outdated } = await drift(ctx);\n if (ctx.dryRun || (await newerPin(ctx)) !== undefined) {\n return;\n }\n for (const file of [...missing, ...outdated]) {\n const dest = join(ctx.cwd, file.path);\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, file.contents);\n }\n }\n}\n\n/**\n * Sorts this CLI's meta-schemas by what the project holds of each. A symlink\n * that keeps files from being written is listed once, however many files lie\n * behind it.\n */\nasync function drift(ctx: CheckContext): Promise<MetaSchemaDrift> {\n const result: MetaSchemaDrift = { missing: [], outdated: [], links: [], unreadable: [] };\n for (const file of projectMetaSchemas(ctx.cliVersion)) {\n try {\n const state = await metaSchemaState(ctx.cwd, file);\n if (state === \"linked\") {\n const link = (await linkOnPath(ctx.cwd, file.path)) ?? file.path;\n if (!result.links.includes(link)) {\n result.links.push(link);\n }\n } else if (state !== \"current\") {\n result[state].push(file);\n }\n } catch (error) {\n result.unreadable.push({\n path: file.path,\n reason: error instanceof Error && \"code\" in error ? String(error.code) : String(error),\n });\n }\n }\n return result;\n}\n\n/** The first exact `@zitadel/*` pin newer than this CLI, when both are releases. */\nasync function newerPin(ctx: CheckContext): Promise<NewerPin | undefined> {\n if (semver.valid(ctx.cliVersion) === null) {\n return undefined;\n }\n const pin = (await exactZitadelPins(ctx.cwd))?.find(([, version]) =>\n semver.gt(version, ctx.cliVersion),\n );\n return pin === undefined ? undefined : { name: pin[0], version: pin[1] };\n}\n","import { readZitadelConfig, readZitadelSecret } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `.zitadel/secret`'s project_id matches `zitadel.json`'s project. */\nexport class ProjectMatchCheck extends AbstractSanityCheck {\n readonly name = \"project-match\";\n readonly path = \".zitadel/secret\";\n protected readonly summary = \".zitadel/secret project_id matches zitadel.json project\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const config = await readZitadelConfig(ctx.cwd);\n const secret = await readZitadelSecret(ctx.cwd);\n const configProject = typeof config.project === \"string\" ? config.project : undefined;\n if (secret.project_id !== configProject) {\n throw new Error(\".zitadel/secret project_id does not match zitadel.json project\");\n }\n }\n}\n","import { createZitadelClient, type ZitadelClient } from \"../../../lib/api-client\";\nimport { issuerHeldAsPreview, recordedOrigins } from \"../../../lib/origins\";\nimport {\n readProjectServer,\n readZitadelConfig,\n readZitadelSecret,\n writeZitadelSecret,\n type ZitadelSecret,\n} from \"../../../lib/project\";\nimport { configuredIssuer } from \"../patch-context\";\nimport type { CheckContext, CheckOutcome, SanityCheck } from \"./types\";\n\n/** What {@link inspect} found: a pass, or the preview issuer `fix` makes primary. */\ntype Finding =\n | { readonly status: \"pass\"; readonly message: string }\n | {\n readonly status: \"warn\";\n readonly pattern: string;\n readonly server: string;\n readonly secret: ZitadelSecret;\n readonly client: ZitadelClient;\n };\n\n/**\n * Warns when the project has no primary origin but holds its issuer\n * (`ZITADEL_ISSUER`, the URL setup registers) as a preview origin, the way\n * `zitadel setup` 0.1.0 registered it. `deploy` lands only on primary origins,\n * so such a project cannot deploy, and `origin add --kind primary` refuses the\n * stored pattern. `--fix` makes it primary.\n *\n * It asks the server only when `.zitadel/secret` records the issuer that way,\n * as 0.1.0 wrote it, so doctor makes no request for any other project. The\n * project is the one `.zitadel/secret` names, on the server `zitadel.json`\n * names: doctor pins its own source to the local runtime URL.\n *\n * Implements {@link SanityCheck} directly, as `ClaimCheck` does: it is only\n * ever warn or pass. A server it cannot reach skips it, since doctor carries on\n * past a probe that fails.\n */\nexport class IssuerOriginCheck implements SanityCheck {\n readonly name = \"issuer-origin\";\n readonly path = \".zitadel/secret\";\n\n async run(ctx: CheckContext): Promise<CheckOutcome> {\n const finding = await inspect(ctx.cwd);\n if (finding.status === \"pass\") {\n return { name: this.name, status: \"pass\", message: finding.message, path: this.path };\n }\n return {\n name: this.name,\n status: \"warn\",\n message:\n `The project has no primary origin to deploy to: it holds ${finding.pattern} as a ` +\n \"preview origin, as `zitadel setup` 0.1.0 registered it. Run `zitadel doctor --fix` \" +\n \"to make it primary.\",\n details: { pattern: finding.pattern, server: finding.server },\n path: this.path,\n };\n }\n\n /**\n * Makes the preview issuer primary on the server, then in `.zitadel/secret`.\n * The API has no kind change, and adding the pattern as primary conflicts\n * with the stored preview one, so it is removed and added back. Should the\n * add fail, the preview pattern is put back: a project left with no origins\n * admits every origin.\n */\n async fix(ctx: CheckContext): Promise<void> {\n if (ctx.dryRun) {\n return;\n }\n const finding = await inspect(ctx.cwd);\n if (finding.status === \"pass\") {\n return;\n }\n const { client, pattern, secret } = finding;\n await client.removeOrigin(secret.project_id, { pattern });\n try {\n await client.addOrigin(secret.project_id, { pattern, kind: \"primary\" });\n } catch (error) {\n await client\n .addOrigin(secret.project_id, { pattern, kind: \"preview\" })\n .catch(() => undefined);\n throw error;\n }\n await writeZitadelSecret(ctx.cwd, {\n ...secret,\n primary_origins: [...secret.primary_origins, pattern],\n preview_origins: secret.preview_origins.filter((recorded) => recorded !== pattern),\n });\n }\n}\n\nasync function inspect(cwd: string): Promise<Finding> {\n let secret: ZitadelSecret;\n let server: string;\n try {\n secret = await readZitadelSecret(cwd);\n server = readProjectServer(await readZitadelConfig(cwd));\n } catch {\n // A missing or unparseable secret or config is the `secret` and `config`\n // checks' to report, with a repair path.\n return {\n status: \"pass\",\n message: \"Skipped: could not read the project files that record its origins\",\n };\n }\n const issuer = await configuredIssuer(cwd);\n if (issuer === undefined) {\n return { status: \"pass\", message: \"Skipped: no file sets ZITADEL_ISSUER\" };\n }\n if (issuerHeldAsPreview(recordedOrigins(secret), issuer) === undefined) {\n return { status: \"pass\", message: `${issuer} is not recorded as a preview origin` };\n }\n\n const client = createZitadelClient({ baseUrl: server, token: secret.project_secret });\n let origins: ReadonlyArray<{ pattern: string; kind: string }>;\n try {\n origins = (await client.getProject(secret.project_id)).origins ?? [];\n } catch (error) {\n return {\n status: \"pass\",\n message: `Skipped: could not read the project's origins from ${server}: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n const pattern = issuerHeldAsPreview(origins, issuer);\n if (pattern !== undefined) {\n return { status: \"warn\", pattern, server, secret, client };\n }\n return {\n status: \"pass\",\n message: origins.some((origin) => origin.kind === \"primary\")\n ? \"The project has a primary origin to deploy to\"\n : `${issuer} is not a preview origin of the project`,\n };\n}\n","import { join } from \"node:path\";\n\nimport { schemaConfigSchema } from \"@zitadel/config/schemas\";\n\nimport { readJsonDir } from \"../../../lib/json-dir\";\nimport { SCHEMAS_DIR } from \"../../../lib/user-schema\";\nimport { AbstractSanityCheck, type CheckContext, type CheckOutcome } from \"./types\";\n\n/**\n * Verifies local schema config files round-trip through the canonical\n * `schemaConfigSchema` from `@zitadel/config/schemas` — the same Zod the\n * release pipeline validates with, so doctor and `deploy` can never disagree\n * about a file. The union enforces the `kind` discriminator\n * (`user-schema` / `schema-url`) and the `metaSchema`/`x-auth-methods`/etc.\n * fields the platform requires.\n */\nexport class SchemaCheck extends AbstractSanityCheck {\n readonly name = \"schema\";\n readonly path = SCHEMAS_DIR;\n protected readonly summary = \"User schemas are valid Zitadel schema bodies\";\n\n /**\n * An empty `.zitadel/schemas/` is a warning, not a failure: projects\n * created before editable config existed were seeded server-side and have\n * no local schema files, and there is no safe auto-fix that could invent\n * them. Only invalid files fail the check.\n */\n override async run(ctx: CheckContext): Promise<CheckOutcome> {\n const schemas = await readJsonDir(join(ctx.cwd, SCHEMAS_DIR));\n if (schemas.length === 0) {\n return {\n name: this.name,\n status: \"warn\",\n message:\n `No schema files found in ${SCHEMAS_DIR} — this project predates editable ` +\n \"schema config or setup was interrupted. New projects scaffold editable \" +\n \"defaults via `zitadel setup`.\",\n path: this.path,\n };\n }\n return super.run(ctx);\n }\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const schemas = await readJsonDir(join(ctx.cwd, SCHEMAS_DIR));\n for (const schema of schemas) {\n const result = schemaConfigSchema.safeParse(schema);\n if (!result.success) {\n throw new Error(\n result.error.issues\n .map((issue) => `${issue.path.join(\".\") || \"/\"} ${issue.message}`)\n .join(\"; \"),\n );\n }\n }\n }\n}\n","import { CLAIM_WINDOW_DAYS, claimState, type ClaimState } from \"../../../lib/claim-state\";\nimport { readProjectServer, readZitadelConfig, readZitadelSecret } from \"../../../lib/project\";\nimport type { CheckContext, CheckOutcome, SanityCheck } from \"./types\";\n\n/**\n * Reports whether the project is attached to a team, reading `claimed_at` and\n * `team_id` from `.zitadel/secret`.\n *\n * Always advisory, never a failure. An unattached project works exactly like an\n * attached one — same issuer, same users, same applications — so the only thing\n * missing is durability, which is the developer's call and not a defect. That\n * matters mechanically too: `doctor` turns any `fail` into a thrown\n * `E_VALIDATION`, so failing here would break every scripted `zitadel doctor`\n * against a project nobody had claimed yet.\n *\n * Implements {@link SanityCheck} directly rather than via the abstract base,\n * for the same reason `ManagedFilesCheck` does: the base's `verify`-throws\n * contract can only express pass/fail, and this check is only ever warn or\n * pass.\n */\nexport class ClaimCheck implements SanityCheck {\n readonly name = \"claim\";\n readonly path = \".zitadel/secret\";\n\n async run(ctx: CheckContext): Promise<CheckOutcome> {\n let state: ClaimState;\n try {\n state = claimState({\n secret: await readZitadelSecret(ctx.cwd),\n // From `zitadel.json`, not the command's own source: `doctor` pins its\n // source to the local runtime URL, so asking it where the project lives\n // would report every project as local.\n server: readProjectServer(await readZitadelConfig(ctx.cwd)),\n });\n } catch {\n // A missing or unparseable secret/config is already reported, loudly and\n // with a repair path, by the `secret` and `config` checks. Implementing\n // `SanityCheck` directly means nothing wraps a throw here, so swallowing\n // it is what keeps a broken project reporting its real problem instead of\n // crashing the whole battery on a nudge.\n return {\n name: this.name,\n status: \"pass\",\n message: \"Skipped: could not read the project files that record the owning team\",\n path: this.path,\n };\n }\n\n if (state.kind === \"detached\") {\n // The window classification travels in `details` so the doctor\n // envelope's advisory can switch to the same reconciliation wording;\n // the claim command itself stays suggested either way, since the local\n // record may be stale and the server answers authoritatively.\n const message = state.claimable\n ? `Claim your Project within ${CLAIM_WINDOW_DAYS} days of creation to make it ` +\n \"permanent and start collaborating with your team. Until then, your Project \" +\n \"is temporary and its data may be lost. Run `zitadel claim`.\"\n : `The local record says this project's ${CLAIM_WINDOW_DAYS}-day claim window has ` +\n \"closed. Run `zitadel claim` to reconcile: a project claimed from another \" +\n \"machine confirms its team, and one never claimed can no longer be claimed. \" +\n \"`zitadel setup` in a fresh directory gets you a new project you can claim.\";\n return {\n name: this.name,\n status: \"warn\",\n message,\n details: { claimable: state.claimable },\n path: this.path,\n };\n }\n\n return {\n name: this.name,\n status: \"pass\",\n message:\n state.kind === \"attached\"\n ? `Project is attached to team ${state.team_id}`\n : // Local and self-hosted servers have no team to attach to, so the\n // check passes rather than warning about an impossible action.\n \"Project is not on a server where teams apply\",\n path: this.path,\n };\n }\n\n /**\n * Deliberately a no-op. `doctor --fix` calls `fix` on every non-passing\n * check, but claiming requires a human to sign in through a browser, so there\n * is nothing safe to automate here.\n */\n async fix(_ctx: CheckContext): Promise<void> {\n return;\n }\n}\n","/**\n * Public surface for the doctor sanity checks. The `doctor` command imports\n * {@link SANITY_CHECKS} and runs every entry, aggregating the outcomes. Each\n * check is a small standalone class (see its own file); add a new diagnostic\n * by writing a class and appending an instance to the registry below.\n */\nimport type { SanityCheck } from \"./types\";\nimport { ConfigCheck } from \"./config\";\nimport { SecretCheck } from \"./secret\";\nimport { SecretPermissionsCheck } from \"./secret-permissions\";\nimport { GitignoreCheck } from \"./gitignore\";\nimport { EnvExampleCheck } from \"./env-example\";\nimport { FrameworkCheck } from \"./framework\";\nimport { DependencyCheck } from \"./dependency\";\nimport { DependencyVersionCheck } from \"./dependency-version\";\nimport { ManagedFilesCheck } from \"./managed-files\";\nimport { MetaSchemasCheck } from \"./meta-schemas\";\nimport { ProjectMatchCheck } from \"./project-match\";\nimport { IssuerOriginCheck } from \"./issuer-origin\";\nimport { SchemaCheck } from \"./schema\";\nimport { ClaimCheck } from \"./claim\";\n\nexport type { SanityCheck, CheckContext, CheckOutcome } from \"./types\";\nexport { AbstractSanityCheck } from \"./types\";\nexport { ConfigCheck } from \"./config\";\nexport { SecretCheck } from \"./secret\";\nexport { SecretPermissionsCheck } from \"./secret-permissions\";\nexport { GitignoreCheck } from \"./gitignore\";\nexport { EnvExampleCheck } from \"./env-example\";\nexport { FrameworkCheck } from \"./framework\";\nexport { SchemaCheck } from \"./schema\";\nexport { DependencyCheck } from \"./dependency\";\nexport { DependencyVersionCheck } from \"./dependency-version\";\nexport { ManagedFilesCheck } from \"./managed-files\";\nexport { MetaSchemasCheck } from \"./meta-schemas\";\nexport { ProjectMatchCheck } from \"./project-match\";\nexport { IssuerOriginCheck } from \"./issuer-origin\";\nexport { ClaimCheck } from \"./claim\";\n\n/** Every diagnostic the `doctor` command runs, in display order. */\nexport const SANITY_CHECKS: ReadonlyArray<SanityCheck> = [\n new ConfigCheck(),\n new SecretCheck(),\n new SecretPermissionsCheck(),\n new GitignoreCheck(),\n new EnvExampleCheck(),\n new FrameworkCheck(),\n new SchemaCheck(),\n new DependencyCheck(),\n new DependencyVersionCheck(),\n new ManagedFilesCheck(),\n new MetaSchemasCheck(),\n new ProjectMatchCheck(),\n new IssuerOriginCheck(),\n new ClaimCheck(),\n];\n","import { dirname, join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { Flags } from \"@oclif/core\";\nimport consola from \"consola\";\n\nimport { createZitadelClient } from \"../../lib/api-client\";\nimport { claimAction, claimCommand, claimWindowClosedAction } from \"../../lib/claim-state\";\nimport { type Environment, resolveEnvironment } from \"../../lib/environment\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { serverLogAction } from \"../../lib/journey-guidance\";\nimport {\n dockerRuntimeGuidance,\n dockerUnavailableMessage,\n} from \"../../lib/local-server/docker-guidance\";\nimport type { LocalServers, ManagedRuntimeProcess } from \"../../lib/local-server/processes\";\nimport {\n DEFAULT_LOCAL_SERVER_PORT,\n LOCAL_RUNTIME_FILE,\n assertLocalStateWritable,\n checkLocalServerHealth,\n defaultLocalServerImageForCliVersion,\n findUpward,\n localServerUrl,\n readNearestRuntimeMetadata,\n type RuntimeBackend,\n type RuntimeMetadata,\n} from \"../../lib/local-server/runtime\";\nimport { LocalServer } from \"../../lib/local-server/server\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope, nonBlankString } from \"../../lib/oclif\";\nimport { environmentFlags, environmentSelectorSuffix } from \"../../lib/oclif/environment-flags\";\nimport { createOrca } from \"../../lib/orca\";\nimport { resolveCwd } from \"../../lib/paths\";\nimport {\n hasZitadelConfig,\n hasZitadelSecret,\n readProjectServer,\n readZitadelConfig,\n readZitadelSecret,\n} from \"../../lib/project\";\nimport { listenersForPort } from \"../../lib/prober/ports\";\nimport { isLoopbackUrl } from \"../../lib/server\";\nimport { SANITY_CHECKS, type CheckContext, type CheckOutcome } from \"./checks\";\nimport {\n type EnvironmentSelector,\n portableSuggestions,\n projectCommand,\n shellCommand,\n type SuggestedCommand,\n unscopedCommand,\n} from \"../../lib/suggestion\";\nimport { nextCommandsData } from \"../../lib/oclif/envelope\";\n\nconst LOCAL_RUNTIME_CHECK_NAMES = new Set([\n \"server-binary\",\n \"docker-cli\",\n \"image\",\n \"state-dir\",\n \"port\",\n \"runtime\",\n]);\n\n/**\n * `zitadel doctor` — verify generated files and local state.\n *\n * Runs every registered {@link SANITY_CHECKS} entry and emits the aggregate\n * result; if any check fails it throws `E_VALIDATION` carrying the full check\n * details. With `--fix`, each check that did not pass — failed or warned —\n * first attempts its own repair (a no-op for checks with no safe automatic\n * remedy), then the battery re-runs.\n *\n * The `--fix` loop is best-effort: a repair that throws (e.g. a missing\n * prerequisite file the check itself would also flag) is logged at debug\n * level and skipped, not propagated — the post-fix re-verify still reports\n * whatever remains broken.\n */\nexport default class Doctor extends BaseCommand {\n static override description = \"Verify local runtime and project state.\";\n static override group = CommandGroups.diagnostics;\n static override groupOrder = 1;\n static override flags = {\n fix: Flags.boolean({ description: \"Repair missing files and stale managed wiring.\" }),\n image: nonBlankString({ description: \"Container image to check.\" }),\n port: Flags.integer({\n description: \"Local HTTP port to check. Defaults to the port this directory's server uses.\",\n }),\n runtime: Flags.string({\n description: \"Local runtime backend.\",\n options: [\"binary\", \"docker\"],\n }),\n // Doctor's local-runtime checks are about the machine, but with `--env` /\n // `--env-file` it also verifies the environment a command would connect to:\n // the same flags every EnvironmentCommand takes, resolved the same way.\n ...environmentFlags,\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Doctor);\n // The local server this directory uses: the one `zitadel start` ran here,\n // or in the nearest parent, as setup and `console` find it. An unreadable\n // record only costs the port hint; the read below reports it.\n const startDir = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n const hint = await readNearestRuntimeMetadata(startDir).catch(() => undefined);\n const port = flags.port ?? hint?.runtime.port ?? DEFAULT_LOCAL_SERVER_PORT;\n const hostedServer = await hostedServerWithoutLocalRuntime(startDir, flags);\n await this.toMeta(flags, {\n resolveServer: false,\n source: hostedServer ?? localServerUrl(port),\n });\n const { cwd, dryRun } = this.meta;\n const nearest = await readNearestRuntimeMetadata(cwd);\n const existingRuntime = nearest?.runtime;\n const runtimeBackend = resolveRuntimeBackend({\n runtime: flags.runtime,\n image: flags.image,\n envImage: this.meta.env.ZITADEL_LOCAL_IMAGE,\n existingRuntime,\n });\n const image =\n flags.image ??\n this.meta.env.ZITADEL_LOCAL_IMAGE ??\n defaultLocalServerImageForCliVersion(this.meta.cliVersion);\n const runtimeChecks =\n hostedServer === undefined\n ? await runLocalRuntimeChecks(\n nearest?.dir ?? cwd,\n existingRuntime,\n runtimeBackend,\n image,\n port,\n this.localServers(),\n )\n : [];\n const hasConfig = await hasZitadelConfig(cwd);\n const ctx: CheckContext = { cwd, orca: createOrca(), cliVersion: this.meta.cliVersion, dryRun };\n\n if (hasConfig && flags.fix) {\n const before = await Promise.all(SANITY_CHECKS.map((check) => check.run(ctx)));\n for (const [index, check] of SANITY_CHECKS.entries()) {\n // Repair warn-level drift too (e.g. a deleted presentation page):\n // fixes are restore-missing-only, so running one on a warning is safe.\n if (before[index]?.status === \"pass\") {\n continue;\n }\n try {\n await check.fix(ctx);\n } catch (error) {\n consola.debug(`doctor --fix: ${check.name} repair failed`, error);\n }\n }\n }\n\n const projectChecks = hasConfig\n ? await Promise.all(SANITY_CHECKS.map((check) => check.run(ctx)))\n : [];\n const environmentChecks = await runEnvironmentChecks({\n cwd,\n env: this.meta.env,\n envName: typeof flags.env === \"string\" ? flags.env : undefined,\n envFile: typeof flags[\"env-file\"] === \"string\" ? flags[\"env-file\"] : undefined,\n serverFlag: typeof flags.server === \"string\" ? flags.server : undefined,\n });\n const checks = [...runtimeChecks, ...projectChecks, ...environmentChecks];\n const failed = checks.filter((check) => check.status === \"fail\");\n const warnings = checks.filter((check) => check.status === \"warn\");\n // `doctor` is not an EnvironmentCommand but honours --env/--env-file/--server\n // to check a chosen environment, so a suggested rerun of a failed check has\n // to carry that same selection or it would check the default project.\n const cwdFlag = typeof flags.cwd === \"string\" ? flags.cwd : undefined;\n const serverFlag = typeof flags.server === \"string\" ? flags.server : undefined;\n const selector = environmentSelectorSuffix({\n cwd: cwdFlag,\n envFile: typeof flags[\"env-file\"] === \"string\" ? flags[\"env-file\"] : undefined,\n envName: typeof flags.env === \"string\" ? flags.env : undefined,\n server: typeof flags.server === \"string\" ? flags.server : undefined,\n });\n // The claim check reads the local `.zitadel/secret`, which is setup's\n // project, so a claim is suggested only pinned to the file setup wrote for\n // it, as setup's own claim suggestion is: `--env-file` outranks the\n // process environment and the other `.env` files, which a bare claim\n // would read first and could name another project. Without a file that\n // names that very project nothing a command can carry selects it, so the\n // advice says so instead. The server is the project's own, from\n // `zitadel.json` where the claim check read it, not this run's `--server`.\n const projectId = await secretProjectId(cwd);\n // A `zitadel.json` that does not parse is the config check's to report,\n // not a reason for doctor itself to fail before it reports anything.\n const projectServer = hasConfig\n ? await readZitadelConfig(cwd).then(readProjectServer, () => serverFlag)\n : serverFlag;\n // A bare claim resolves as this shell does, so it is offered unpinned only\n // when that resolution lands on the very project the check read.\n const bareResolves =\n projectId !== undefined &&\n (await resolveEnvironment({ cwd, env: this.meta.env }).then(\n (environment) => environment.values.ZITADEL_PROJECT_ID?.value === projectId,\n () => false,\n ));\n const claimSelector = (await namesProject(\n join(cwd, \".env.development.local\"),\n Promise.resolve(projectId),\n ))\n ? environmentSelectorSuffix({\n cwd: cwdFlag,\n envFile: \".env.development.local\",\n server: projectServer,\n })\n : bareResolves\n ? environmentSelectorSuffix({ cwd: cwdFlag, server: projectServer })\n : undefined;\n const warningAdvice = advisoryForWarnings(\n warnings,\n this.meta.cliVersion,\n claimSelector,\n selector,\n );\n // A server that is running is one a sign-in or a request can fail\n // against, and its log is where the reason is.\n const serving =\n existingRuntime !== undefined &&\n runtimeChecks.find((check) => check.name === \"runtime\")?.status === \"pass\";\n const nextActions = [\n ...(warningAdvice?.nextActions ?? []),\n ...(serving ? [serverLogAction(this.meta.cliVersion)] : []),\n ];\n this.recordTelemetry({\n runtime: runtimeBackend,\n checks_total: checks.length,\n checks_failed: failed.length,\n checks_warn: warnings.length,\n failed_checks: failed.length > 0 ? failed.map((check) => check.name).join(\",\") : undefined,\n });\n const data = {\n title:\n failed.length > 0\n ? \"Zitadel doctor found issues.\"\n : warnings.length > 0\n ? \"Zitadel doctor passed with warnings.\"\n : \"Zitadel doctor passed.\",\n ok: failed.length === 0,\n ...(hostedServer === undefined\n ? { runtime: runtimeBackend, ...(runtimeBackend === \"docker\" ? { image } : {}), port }\n : {}),\n project: {\n lifecycle: hasConfig ? \"configured\" : \"not-configured\",\n },\n checks,\n ...(nextActions.length > 0 ? { next_actions: nextActions } : {}),\n ...(warningAdvice ? nextCommandsData(warningAdvice.nextCommands) : {}),\n };\n\n if (failed.length > 0) {\n const advice = failureAdvice(\n failed,\n image,\n port,\n this.meta.cliVersion,\n selector,\n nearest !== undefined && nearest.dir !== cwd ? nearest.dir : undefined,\n );\n // A check that failed with a typed CLI error advertises its own\n // category (e.g. the framework floor's E_UNSUPPORTED_PROJECT_SHAPE) —\n // surface that instead of the generic validation class so agents can\n // branch on it. The port check keeps its dedicated code first.\n const code = failed.some((check) => check.name === \"port\")\n ? \"E_PORT_IN_USE\"\n : (failed.find((check) => check.code !== undefined)?.code ?? \"E_VALIDATION\");\n throw new ZitadelError(code, \"Zitadel doctor found issues\", {\n hint: advice.hint,\n nextCommands: advice.nextCommands,\n details:\n advice.suggestedArgs === undefined\n ? data\n : { ...data, suggested_args: advice.suggestedArgs },\n });\n }\n\n return this.emit({\n status: \"ok\",\n data,\n warnings: warnings.map((warning) => `${warning.name}: ${warning.message}`),\n });\n }\n}\n\nexport function failureAdvice(\n failed: CheckOutcome[],\n image: string,\n port: number,\n cliVersion: string,\n // The invocation's --env/--env-file/--server suffix. Appended only to the\n // retries that resolve the environment (the env-connect failure and the\n // project `--fix`); the local-runtime remedies — docker, port, image,\n // state-dir — are machine checks the selector would only clutter.\n selector: EnvironmentSelector,\n runtimeDir?: string,\n): { hint: string; nextCommands: SuggestedCommand[]; suggestedArgs?: string[][] } {\n const failedNames = new Set(failed.map((check) => check.name));\n\n if (failedNames.has(\"server-binary\")) {\n return {\n hint: \"The Zitadel server npm package is not available. Reinstall the CLI package, then retry.\",\n nextCommands: [unscopedCommand(\"doctor\", cliVersion)],\n };\n }\n\n if (failedNames.has(\"docker-cli\")) {\n const advice = dockerRuntimeGuidance(\"doctor\", cliVersion);\n return {\n hint: advice.hint,\n nextCommands: advice.nextCommands,\n };\n }\n\n if (failedNames.has(\"image\")) {\n return {\n hint: \"The local Zitadel image is not available. Check Docker registry access, build it locally, or pass --image / ZITADEL_LOCAL_IMAGE.\",\n nextCommands: [shellCommand(`docker pull ${image}`), unscopedCommand(\"doctor\", cliVersion)],\n };\n }\n\n if (failedNames.has(\"state-dir\")) {\n return {\n hint: \"The local Zitadel state directory is not writable. Fix directory permissions, then rerun `zitadel doctor`.\",\n nextCommands: [unscopedCommand(\"doctor\", cliVersion)],\n };\n }\n\n if (failedNames.has(\"port\")) {\n const fallbackPort = port === DEFAULT_LOCAL_SERVER_PORT ? port + 1 : DEFAULT_LOCAL_SERVER_PORT;\n const stopCommand = unscopedCommand(\"stop --all\", cliVersion);\n const retryCommand = unscopedCommand(\"doctor\", cliVersion);\n const alternatePortCommand = unscopedCommand(\n `doctor --port ${String(fallbackPort)}`,\n cliVersion,\n );\n return {\n hint:\n `Port ${String(port)} is already in use. Stop the process using it, ` +\n `run \\`${stopCommand}\\` for CLI-managed local runtimes, then rerun ` +\n `\\`${retryCommand}\\`; or choose another port with \\`${alternatePortCommand}\\`.`,\n nextCommands: [stopCommand, retryCommand, alternatePortCommand],\n };\n }\n\n if (failedNames.has(\"runtime\")) {\n // `start` and `reset` act on their working directory, so a runtime found\n // in a parent is named explicitly. The directory comes from the file\n // system and quoting differs between POSIX shells, PowerShell and cmd.exe,\n // so a path that needs quoting leaves the strings out and the argument\n // lists in `details.suggested_args` carry the recovery.\n const at = runtimeDir === undefined ? [] : [\"--cwd\", runtimeDir];\n const suggestedArgs = [\n [\"start\", ...at],\n [\"reset\", \"--force\", ...at],\n ];\n const nextCommands = portableSuggestions(suggestedArgs, cliVersion);\n return {\n hint:\n \"Existing local runtime metadata was found, but the local Zitadel server is not healthy. Start it again or reset stale local data.\" +\n (nextCommands.length === 0\n ? ` The runtime is in ${runtimeDir ?? \"the working directory\"}, a directory that needs shell quoting, so no command is printed; run \\`zitadel doctor --json\\` and use details.suggested_args for the exact arguments.`\n : \"\"),\n nextCommands,\n suggestedArgs,\n };\n }\n\n // A failure that surfaced as a typed CLI error carries its own remedy —\n // e.g. the framework floor's upgrade hint. That beats the generic --fix\n // advice below, which cannot repair an unsupported version.\n const typed = failed.find((check) => check.code !== undefined && check.hint !== undefined);\n if (typed?.hint !== undefined) {\n return { hint: typed.hint, nextCommands: [projectCommand(\"doctor\", selector, cliVersion)] };\n }\n\n if (failedNames.has(\"environment\")) {\n return {\n hint: \"The resolved environment could not connect. Check the server, project and credential it resolves with `zitadel env`, then rerun `zitadel doctor` with the same --env / --env-file.\",\n nextCommands: [\n projectCommand(\"env\", selector, cliVersion),\n projectCommand(\"doctor\", selector, cliVersion),\n ],\n };\n }\n\n const hasProjectFailure = failed.some((check) => !LOCAL_RUNTIME_CHECK_NAMES.has(check.name));\n if (hasProjectFailure) {\n return {\n hint: `Run \\`${projectCommand(\"doctor --fix\", selector, cliVersion)}\\` to re-apply missing managed files.`,\n nextCommands: [projectCommand(\"doctor --fix\", selector, cliVersion)],\n };\n }\n\n return {\n hint: \"Fix the reported checks, then rerun `zitadel doctor`.\",\n nextCommands: [projectCommand(\"doctor\", selector, cliVersion)],\n };\n}\n\n/**\n * The follow-ups doctor offers for its warnings: the Docker guidance, the claim\n * nudge, the managed-runtime review, a dependency remedy, the primary issuer\n * origin and the meta-schema refresh.\n */\nexport function advisoryForWarnings(\n warnings: CheckOutcome[],\n cliVersion: string,\n /**\n * The selector for the local project, which is the one the claim check\n * reads, or nothing when no selector reaches it.\n */\n local: EnvironmentSelector | undefined,\n /** This run's selection, which a suggested rerun of doctor carries. */\n selector: EnvironmentSelector,\n): { nextActions: string[]; nextCommands: SuggestedCommand[] } | undefined {\n const nextActions: string[] = [];\n const nextCommands: SuggestedCommand[] = [];\n if (warnings.some((check) => check.name === \"docker-cli\")) {\n const advice = dockerRuntimeGuidance(\"doctor\", cliVersion);\n nextActions.push(...advice.nextActions);\n nextCommands.push(...advice.nextCommands);\n }\n\n const claimWarning = warnings.find((check) => check.name === \"claim\");\n if (claimWarning) {\n // The check classified the window (details.claimable). Once it looks\n // closed the advisory switches to reconciliation wording, but the claim\n // command stays suggested either way: the local record can be stale\n // (claimed from another machine reads detached), and the server checks\n // the grant before the window, so running claim is safe and answers\n // authoritatively.\n if (local === undefined) {\n nextActions.push(\n \"Claim this project with `zitadel claim` once .env.development.local sets ZITADEL_PROJECT_ID and ZITADEL_PROJECT_SECRET to the project in .zitadel/secret; until then claim would resolve a different project.\",\n );\n } else {\n nextActions.push(\n claimWindowClosed(claimWarning)\n ? claimWindowClosedAction(cliVersion, local)\n : claimAction(cliVersion, undefined, local),\n );\n nextCommands.push(claimCommand(cliVersion, local));\n }\n }\n\n const managedRuntimeWarning = warnings.find(\n (check) => check.name === \"managed-runtime-processes\",\n );\n if (hasManagedRuntimeProcesses(managedRuntimeWarning)) {\n nextActions.push(\n \"Review other host-wide CLI-managed local Zitadel runtimes before starting a new one.\",\n );\n nextCommands.push(unscopedCommand(\"stop --all\", cliVersion));\n }\n\n const dependencyRemedy = remedyCommandOf(\n warnings.find((check) => check.name === \"dependency-version\"),\n );\n if (dependencyRemedy !== undefined) {\n nextActions.push(\n \"Align the exactly-pinned @zitadel/* dependencies with the CLI version; scaffolded files and guidance target the CLI's train.\",\n );\n nextCommands.push(dependencyRemedy);\n }\n\n if (warnings.some((check) => check.name === \"issuer-origin\")) {\n nextActions.push(\n \"Make the app's issuer a primary origin; `zitadel deploy` lands only on primary origins, and `zitadel setup` 0.1.0 registered it as a preview one.\",\n );\n nextCommands.push(projectCommand(\"doctor --fix\", selector, cliVersion));\n }\n\n if (hasRepairableMetaSchemas(warnings.find((check) => check.name === \"meta-schemas\"))) {\n nextActions.push(\n \"Write this CLI version's editor schemas into .zitadel/meta/; editors and agents read the dialect from there.\",\n );\n nextCommands.push(projectCommand(\"doctor --fix\", selector, cliVersion));\n }\n\n if (nextActions.length === 0 && nextCommands.length === 0) {\n return undefined;\n }\n return { nextActions: unique(nextActions), nextCommands: unique(nextCommands) };\n}\n\n/**\n * Environment-aware checks, run only when `--env` / `--env-file` is given so a\n * plain `doctor` is unchanged (its default development environment is the local\n * server the runtime checks already cover). One authenticated `getProject`\n * against the resolved connection settles both questions at once: a response\n * proves the server is reachable, and that the resolved project exists and the\n * resolved credential can read it — the drift env resolution could introduce.\n *\n * Deliberately small: it does not re-run every sanity check against the remote\n * project (that would need the files the environment points at, which do not\n * exist locally), only the connection the environment resolves.\n */\nasync function runEnvironmentChecks(input: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n envName?: string;\n envFile?: string;\n serverFlag?: string;\n}): Promise<CheckOutcome[]> {\n if (input.envName === undefined && input.envFile === undefined) {\n return [];\n }\n let environment: Environment;\n try {\n environment = await resolveEnvironment({\n cwd: input.cwd,\n env: input.env,\n envName: input.envName,\n envFile: input.envFile,\n serverFlag: input.serverFlag,\n });\n } catch (error) {\n return [\n {\n name: \"environment\",\n status: \"fail\",\n message: error instanceof Error ? error.message : String(error),\n },\n ];\n }\n const name = environment.name.value;\n return [\n await check(`environment`, `Resolved ${name} environment connects`, async () => {\n const server = environment.values.ZITADEL_URL?.value;\n const projectId = environment.values.ZITADEL_PROJECT_ID?.value;\n const token = environment.values.ZITADEL_PROJECT_SECRET?.value;\n if (server === undefined || projectId === undefined) {\n throw new Error(\n `ZITADEL_URL and ZITADEL_PROJECT_ID must resolve for the ${name} environment`,\n );\n }\n if (token === undefined) {\n throw new Error(\n `ZITADEL_PROJECT_SECRET must resolve to verify project ${projectId} on ${server}`,\n );\n }\n const project = await createZitadelClient({ baseUrl: server, token }).getProject(projectId);\n if (project.id !== projectId) {\n throw new Error(`${server} returned project ${project.id}, not the resolved ${projectId}`);\n }\n return `${server} is reachable and project ${projectId} matches`;\n }),\n ];\n}\n\n/**\n * The server of a project set up against a hosted server, for which doctor\n * checks no local runtime: no local server runs for it, so the runtime says\n * nothing about it, and a port another app holds would fail it. `undefined`\n * (check the runtime) before setup, for a project on a local server or with a\n * `zitadel.json` that does not parse, where a server was started in the\n * directory or a parent, and when a flag asks about the runtime.\n */\nasync function hostedServerWithoutLocalRuntime(\n cwd: string,\n flags: { port?: number; runtime?: string; image?: string },\n): Promise<string | undefined> {\n if (flags.port !== undefined || flags.runtime !== undefined || flags.image !== undefined) {\n return undefined;\n }\n if ((await findUpward(cwd, LOCAL_RUNTIME_FILE)) !== undefined || !(await hasZitadelConfig(cwd))) {\n return undefined;\n }\n const server = await readZitadelConfig(cwd).then(readProjectServer, () => undefined);\n return server === undefined || isLoopbackUrl(server) ? undefined : server;\n}\n\n/**\n * The local runtime checks, against the server in `runtimeDir` (the directory\n * holding its `.zitadel/local` state, or the current directory when no server\n * was started yet).\n */\nasync function runLocalRuntimeChecks(\n runtimeDir: string,\n runtime: RuntimeMetadata | undefined,\n runtimeBackend: RuntimeBackend,\n image: string,\n port: number,\n servers: LocalServers,\n): Promise<CheckOutcome[]> {\n const managedRuntimeCheck = await checkManagedRuntimeProcesses(runtime, servers);\n if (runtimeBackend === \"binary\") {\n return [\n await check(\"server-binary\", \"Server npm package is available\", async () => {\n const version = LocalServer.assertBinaryAvailable();\n return `@zitadel/server ${version} is available`;\n }),\n await check(\n \"state-dir\",\n \"Local state directory is writable\",\n async () => {\n const probe = await assertLocalStateWritable(runtimeDir);\n return probe.checkedPath === probe.targetPath\n ? `${probe.targetPath} is writable`\n : `${probe.targetPath} can be created (${probe.checkedPath} is writable)`;\n },\n \"warn\",\n ),\n await check(\"port\", `Port ${String(port)} is available`, () =>\n checkPortAvailability(runtime, port),\n ),\n await checkRuntime(runtime, runtimeBackend),\n managedRuntimeCheck,\n ];\n }\n\n const docker = await check(\n \"docker-cli\",\n \"Docker is reachable\",\n async () => {\n let result: Awaited<ReturnType<typeof LocalServer.dockerReachable>>;\n try {\n result = await LocalServer.dockerReachable();\n } catch (error) {\n throw new Error(dockerUnavailableMessage(error), { cause: error });\n }\n if (result.status !== 0) {\n throw new Error(dockerUnavailableMessage(result.stderr || \"docker version failed\"));\n }\n return `Docker engine ${result.stdout.trim() || \"available\"}`;\n },\n \"warn\",\n );\n\n const imageCheck =\n docker.status === \"pass\"\n ? await check(\n \"image\",\n `Image ${image} is available`,\n async () => {\n try {\n const source = await LocalServer.imageAvailable(image);\n return source === \"local\"\n ? `Image ${image} is available locally`\n : `Image ${image} is available from the registry`;\n } catch (error) {\n throw new Error(imageUnavailableMessage(image, error), { cause: error });\n }\n },\n \"warn\",\n )\n : ({\n name: \"image\",\n status: \"warn\",\n message: \"Skipped image check because Docker is not reachable.\",\n } satisfies CheckOutcome);\n\n return [\n docker,\n imageCheck,\n await check(\n \"state-dir\",\n \"Local state directory is writable\",\n async () => {\n const probe = await assertLocalStateWritable(runtimeDir);\n return probe.checkedPath === probe.targetPath\n ? `${probe.targetPath} is writable`\n : `${probe.targetPath} can be created (${probe.checkedPath} is writable)`;\n },\n \"warn\",\n ),\n await check(\"port\", `Port ${String(port)} is available`, () =>\n checkPortAvailability(runtime, port),\n ),\n await checkRuntime(runtime, runtimeBackend),\n managedRuntimeCheck,\n ];\n}\n\nasync function checkPortAvailability(\n runtime: RuntimeMetadata | undefined,\n port: number,\n): Promise<string> {\n if (runtime?.port === port && (await checkLocalServerHealth(runtime.server_url))) {\n return `${runtime.server_url} is already healthy`;\n }\n const listeners = await listenersForPort(port);\n if (listeners.length > 0) {\n throw new PortInUseCheckError(port, localServerUrl(port), listeners);\n }\n return `Port ${String(port)} is available`;\n}\n\nclass PortInUseCheckError extends Error {\n readonly port: number;\n readonly serverUrl: string;\n readonly listeners: Awaited<ReturnType<typeof listenersForPort>>;\n\n constructor(\n port: number,\n serverUrl: string,\n listeners: Awaited<ReturnType<typeof listenersForPort>>,\n ) {\n super(`Port ${String(port)} is already in use by ${formatListeners(listeners)}`);\n this.port = port;\n this.serverUrl = serverUrl;\n this.listeners = listeners;\n }\n}\n\nasync function checkManagedRuntimeProcesses(\n runtime: RuntimeMetadata | undefined,\n servers: LocalServers,\n): Promise<CheckOutcome> {\n const discovery = await servers.current();\n if (!discovery.supported) {\n return {\n name: \"managed-runtime-processes\",\n status: \"warn\",\n message: \"Managed local runtime process discovery is unavailable.\",\n details: { supported: false, error: discovery.error },\n };\n }\n const processes = additionalManagedRuntimeProcesses(discovery.processes, runtime);\n if (processes.length === 0) {\n return {\n name: \"managed-runtime-processes\",\n status: \"pass\",\n message: \"No additional host-wide managed local runtime processes found.\",\n details: { supported: true, scope: \"host\", processes: [] },\n };\n }\n return {\n name: \"managed-runtime-processes\",\n status: \"warn\",\n message: `${String(processes.length)} other host-wide managed local runtime process${processes.length === 1 ? \"\" : \"es\"} found.`,\n details: { supported: true, scope: \"host\", processes },\n };\n}\n\nfunction additionalManagedRuntimeProcesses(\n processes: ReadonlyArray<ManagedRuntimeProcess>,\n runtime: RuntimeMetadata | undefined,\n): ReadonlyArray<ManagedRuntimeProcess> {\n if (runtime?.backend !== \"binary\") {\n return processes;\n }\n return processes.filter(\n (processInfo) => processInfo.pid !== runtime.pid && processInfo.ppid !== runtime.pid,\n );\n}\n\nasync function checkRuntime(\n runtime: { backend: RuntimeBackend; server_url: string } | undefined,\n runtimeBackend: RuntimeBackend,\n): Promise<CheckOutcome> {\n return check(\"runtime\", \"Existing local runtime is healthy\", async () => {\n if (!runtime) {\n return \"No existing runtime metadata\";\n }\n if (runtime.backend !== runtimeBackend) {\n throw new Error(\n `Existing local runtime uses ${runtime.backend}; run start --runtime ${runtimeBackend} to switch backends.`,\n );\n }\n if (!(await checkLocalServerHealth(runtime.server_url))) {\n throw new Error(`${runtime.server_url} is not ready: /readyz did not answer ok`);\n }\n return `${runtime.server_url} is healthy`;\n });\n}\n\nfunction formatListeners(listeners: Awaited<ReturnType<typeof listenersForPort>>): string {\n return listeners\n .map((listener) =>\n [listener.command ?? \"unknown\", listener.pid ? `pid ${String(listener.pid)}` : undefined]\n .filter(Boolean)\n .join(\" \"),\n )\n .join(\", \");\n}\n\n/**\n * A warning may carry its own repair as `details.remedy_command` (today: the\n * dependency-version check's package-manager-aware exact-pin install).\n * Surfacing that string keeps the structured advisory identical to the\n * command quoted in the warning's prose.\n */\nfunction remedyCommandOf(check: CheckOutcome | undefined): SuggestedCommand | undefined {\n if (check?.status !== \"warn\") {\n return undefined;\n }\n const details = check.details;\n if (typeof details !== \"object\" || details === null) {\n return undefined;\n }\n const remedy = (details as { remedy_command?: unknown }).remedy_command;\n return typeof remedy === \"string\" && remedy.length > 0 ? shellCommand(remedy) : undefined;\n}\n\n/**\n * Reads the claim check's window classification out of its details. Absent\n * or malformed details mean \"not closed\". The classification only selects\n * the advisory wording (deadline nudge vs reconciliation); the claim\n * command stays suggested either way, because the local record may be stale\n * and running claim lets the server answer authoritatively.\n */\nfunction claimWindowClosed(check: CheckOutcome): boolean {\n const details = check.details;\n return (\n typeof details === \"object\" &&\n details !== null &&\n (details as { claimable?: unknown }).claimable === false\n );\n}\n\n/**\n * Whether the meta-schemas warning lists a missing or outdated file that this\n * CLI's `--fix` writes: not when the project pins a newer `@zitadel/*`\n * version, whose own doctor writes them. A file behind a symlink, or one the\n * CLI cannot read, only gets the warning's reason.\n */\nfunction hasRepairableMetaSchemas(check: CheckOutcome | undefined): boolean {\n if (check?.status !== \"warn\") {\n return false;\n }\n const details = check.details as\n | { missing?: unknown[]; outdated?: unknown[]; newer_pin?: unknown }\n | undefined;\n return (\n details?.newer_pin === undefined &&\n (details?.missing?.length ?? 0) + (details?.outdated?.length ?? 0) > 0\n );\n}\n\nfunction hasManagedRuntimeProcesses(check: CheckOutcome | undefined): boolean {\n if (!check || check.status !== \"warn\") {\n return false;\n }\n const details = check.details;\n return (\n typeof details === \"object\" &&\n details !== null &&\n \"supported\" in details &&\n (details as { supported?: unknown }).supported === true &&\n Array.isArray((details as { processes?: unknown }).processes) &&\n ((details as { processes?: unknown[] }).processes?.length ?? 0) > 0\n );\n}\n\nfunction unique<T extends string>(values: T[]): T[] {\n return [...new Set(values)];\n}\n\nfunction resolveRuntimeBackend(input: {\n runtime: unknown;\n image: string | undefined;\n envImage: string | undefined;\n existingRuntime: { backend: RuntimeBackend } | undefined;\n}): RuntimeBackend {\n if (input.runtime === \"binary\" || input.runtime === \"docker\") {\n return input.runtime;\n }\n if (input.existingRuntime) {\n return input.existingRuntime.backend;\n }\n if (input.image || input.envImage) {\n return \"docker\";\n }\n return \"binary\";\n}\n\nasync function check(\n name: string,\n fallback: string,\n run: () => Promise<string>,\n failureStatus: \"warn\" | \"fail\" = \"fail\",\n): Promise<CheckOutcome> {\n try {\n return { name, status: \"pass\", message: await run() };\n } catch (error) {\n if (error instanceof PortInUseCheckError) {\n return {\n name,\n status: failureStatus,\n message: error.message,\n details: {\n port: error.port,\n server_url: error.serverUrl,\n listeners: error.listeners,\n },\n };\n }\n return {\n name,\n status: failureStatus,\n message: error instanceof Error ? error.message : fallback,\n };\n }\n}\n\nfunction imageUnavailableMessage(image: string, error: unknown): string {\n const detail = error instanceof Error ? error.message : String(error);\n const suffix = detail.trim() ? ` (${detail.trim()})` : \"\";\n return `Image ${image} is not available to Docker${suffix}; \\`zitadel start\\` may need a pull or a different image.`;\n}\n\n/** The project `.zitadel/secret` records, or nothing when it cannot be read. */\nasync function secretProjectId(cwd: string): Promise<string | undefined> {\n return (await hasZitadelSecret(cwd))\n ? readZitadelSecret(cwd).then(\n (secret) => secret.project_id,\n () => undefined,\n )\n : undefined;\n}\n\n/** Whether an env file sets `ZITADEL_PROJECT_ID` to this project. */\nasync function namesProject(\n path: string,\n projectId: Promise<string | undefined>,\n): Promise<boolean> {\n const id = await projectId;\n if (id === undefined || !existsSync(path)) {\n return false;\n }\n // Read through the resolver, as `claim --env-file` would read it; the\n // process environment is left out, so only the file answers. The file must\n // carry the credential too: for one it lacks, a pinned claim would take\n // whatever secret the shell exports and send it along for this project.\n return resolveEnvironment({ cwd: dirname(path), env: {}, envFile: path }).then(\n ({ values }) =>\n values.ZITADEL_PROJECT_ID?.value === id && values.ZITADEL_PROJECT_SECRET !== undefined,\n () => false,\n );\n}\n","import { Flags } from \"@oclif/core\";\nimport { readFile, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport { createOrca } from \"../lib/orca\";\nimport { AGENTS_HEADER, removeGuidanceSection } from \"../lib/orca/patchers/rule/guidance\";\nimport type { EjectActions } from \"../lib/orca/patchers/types\";\nimport { MANAGED_MARKER } from \"../lib/paths\";\nimport { readRendererId, readZitadelConfig } from \"../lib/project\";\nimport { shellArg } from \"../lib/shell\";\nimport { shellCommand, type SuggestedCommand } from \"../lib/suggestion\";\nimport { nextCommandsData } from \"../lib/oclif/envelope\";\nimport { Promptable } from \"../lib/oclif/promptable\";\n\n/**\n * Asks the framework patcher which artifacts it owns. Falls back to the\n * framework-agnostic set (`zitadel.json`, `.zitadel/`, `.env.local`,\n * `.env.development.local`) when the framework or its patcher cannot be\n * resolved, so an orphaned/partial project can still be cleaned up.\n */\nasync function resolveEjectActions(cwd: string): Promise<EjectActions> {\n const fallback: EjectActions = {\n markedFiles: [],\n rootConfigFiles: [\"zitadel.json\"],\n directories: [\".zitadel\"],\n envBackups: [\".env.local\", \".env.development.local\"],\n dependencies: [],\n configEdits: [],\n guidanceFiles: [\"AGENTS.md\", \"README.md\"],\n };\n const orca = createOrca();\n const framework = await orca.tryDetect(cwd);\n if (!framework) {\n return fallback;\n }\n try {\n const config = await readZitadelConfig(cwd).catch(() => ({}) as Record<string, unknown>);\n return orca.patcherFor(framework.id).artifacts({\n framework,\n rendererId: readRendererId(config),\n });\n } catch {\n return fallback;\n }\n}\n\n/**\n * Builds the `next_commands` envelope field — manual follow-ups `eject` can't\n * safely run itself: deleting the `.env*.ejected-*` backups it created (only\n * when some were made), and uninstalling the SDK packages the patcher added\n * (the CLI never modifies the user's `package.json` + lockfile +\n * `node_modules` directly; it just suggests the command).\n */\nfunction assembleNextCommands(\n backedUp: ReadonlyArray<string>,\n dependencies: ReadonlyArray<string>,\n // `--cwd` as typed: the backups and the package.json are in that directory,\n // so a command run from the shell's would miss them or touch another project.\n dir: string | undefined,\n): ReadonlyArray<SuggestedCommand> {\n const inDir = (command: string) =>\n shellCommand(dir === undefined ? command : `cd ${shellArg(dir)} && ${command}`);\n const commands: SuggestedCommand[] = [];\n if (backedUp.length > 0) {\n // Name only the backups eject actually created (each `backedUp` entry is\n // `<rel> -> <backup>`), so this destructive glob can't also sweep up\n // unrelated `.env*.ejected-*` files a user happens to keep.\n const patterns = backedUp.map((entry) => `${entry.split(\" -> \")[0]}.ejected-*`);\n commands.push(inDir(`rm -f ${patterns.join(\" \")}`));\n }\n for (const dep of dependencies) {\n commands.push(inDir(`npm uninstall ${dep}`));\n }\n return commands;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * `zitadel eject` — remove managed files and local Zitadel state.\n *\n * Removes Zitadel-managed files from the project, leaving the remote project\n * untouched. The set of files comes from the framework patcher's\n * {@link import(\"../lib/orca/patchers/types\").Patcher.artifacts}, so the patcher\n * is the single source of truth for what its integration owns.\n *\n * Marked code files are removed only when they still carry the managed marker\n * (user-replaced files are preserved); `zitadel.json` is removed; `.env.local`\n * is renamed to a timestamped backup; and `.zitadel/` is removed wholesale.\n * `--dry-run` reports without touching the filesystem; non-interactive runs\n * require `--force`.\n */\nexport default class Eject extends Promptable(BaseCommand) {\n static override description = \"Remove managed files and local Zitadel state.\";\n static override group = CommandGroups.localDevelopment;\n static override groupOrder = 5;\n static override aliases = [\"uninstall\"];\n static override flags = {\n force: Flags.boolean({\n char: \"f\",\n description: \"Remove the managed files without the confirmation prompt.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Eject);\n await this.toMeta(flags, { resolveServer: false });\n const { cwd, dryRun } = this.meta;\n\n // A dry run removes nothing, so it has nothing to confirm (as in `reset`).\n const confirmed =\n dryRun ||\n (await this.input({\n kind: \"confirm\",\n name: \"remove the managed files and local state\",\n message: \"Remove the managed files and local Zitadel state?\",\n retry: this.suggestUnscoped(\"eject --force\"),\n }));\n if (!confirmed) {\n return this.emit({ status: \"skipped\", reason: \"eject-cancelled\" });\n }\n\n const actions = await resolveEjectActions(cwd);\n const removed: string[] = [];\n const preserved: string[] = [];\n const backedUp: string[] = [];\n\n for (const rel of actions.markedFiles) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n const contents = await readFile(abs, \"utf8\").catch(() => \"\");\n if (!contents.includes(MANAGED_MARKER)) {\n preserved.push(rel);\n continue;\n }\n if (!dryRun) {\n await rm(abs, { force: true });\n }\n removed.push(rel);\n }\n\n for (const rel of actions.rootConfigFiles) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n if (!dryRun) {\n await rm(abs, { force: true });\n }\n removed.push(rel);\n }\n\n for (const rel of actions.envBackups) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n if (dryRun) {\n backedUp.push(`${rel} -> ${rel}.ejected-<timestamp>`);\n continue;\n }\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backup = `${abs}.ejected-${stamp}`;\n await rename(abs, backup);\n backedUp.push(`${rel} -> ${backup.slice(cwd.length + 1)}`);\n }\n\n for (const rel of actions.directories) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n if (!dryRun) {\n await rm(abs, { recursive: true, force: true });\n }\n removed.push(rel);\n }\n\n // Guidance sections live inside user-owned docs (README.md / AGENTS.md):\n // strip only the marker-fenced section so the stale golden path doesn't\n // outlive the files it points at. The whole file goes only when nothing\n // but the scaffold-created header (or whitespace) would remain — i.e. we\n // created it and nobody added anything since.\n for (const rel of actions.guidanceFiles) {\n const abs = join(cwd, rel);\n if (!(await pathExists(abs))) {\n continue;\n }\n const contents = await readFile(abs, \"utf8\").catch(() => \"\");\n const stripped = removeGuidanceSection(contents);\n if (stripped === contents) {\n continue;\n }\n const husk = stripped.trim() === \"\" || stripped.trim() === AGENTS_HEADER.trim();\n if (!dryRun) {\n if (husk) {\n await rm(abs, { force: true });\n } else {\n await writeFile(abs, stripped);\n }\n }\n removed.push(husk ? rel : `${rel} (managed section)`);\n }\n\n // In-place config merges (vite.config.ts / angular.json / nuxt.config.ts)\n // can't be auto-reverted, so surface them as manual cleanup steps.\n // package.json is not a config block: Angular has its `dev` script added\n // outright, while Next and Nuxt keep theirs and only get the dev-server\n // port pinned into it — one line has to cover both, so it names the\n // script and both ways setup touches it rather than claiming the script\n // itself should go.\n const manualSteps = actions.configEdits.map((rel) => {\n if (rel === \"package.json\" || rel.endsWith(\"/package.json\")) {\n return `Restore the \"dev\" script in ${rel} (setup added the script, or pinned its dev-server port)`;\n }\n if (rel === \"angular.json\" || rel.endsWith(\"/angular.json\")) {\n return `Remove the Zitadel proxyConfig (and dev-server port) from the serve target in ${rel}`;\n }\n return `Remove the Zitadel configuration block from ${rel}`;\n });\n\n if (removed.length === 0 && backedUp.length === 0 && manualSteps.length === 0) {\n return this.emit({ status: \"skipped\", reason: \"nothing-to-eject\", data: { cwd } });\n }\n\n const nextCommands = assembleNextCommands(\n backedUp,\n actions.dependencies,\n typeof flags.cwd === \"string\" ? flags.cwd : undefined,\n );\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Zitadel ejected. Remote project is untouched.\",\n files_removed: removed,\n files_preserved: preserved,\n backed_up: backedUp,\n ...nextCommandsData(nextCommands),\n manual_steps: manualSteps,\n },\n });\n }\n}\n","import { ENVIRONMENT_KEYS, type EnvironmentKey } from \"../../lib/environment\";\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { renderTable } from \"../../lib/oclif/crud/table\";\n\n/** The values that grant access, never printed — only named and masked. */\nconst SECRET_KEYS: ReadonlySet<EnvironmentKey> = new Set([\n \"ZITADEL_PROJECT_SECRET\",\n \"ZITADEL_PREVIEW_TOKEN\",\n]);\n\n/**\n * A fixed, length-independent mask for a secret's value. A prefix of the real\n * value would leak a short secret whole and narrow the search space of a long\n * one, so the output never derives from the secret at all.\n */\nconst REDACTED = \"••••••••\";\n\n/**\n * `zitadel env` — what this directory resolves to for the environment in use,\n * and which source supplied each value. It never prints a secret in full, so\n * the output is safe to paste into a bug report.\n */\nexport default class Env extends EnvironmentCommand {\n static override description =\n \"Show which server and project resolve, and where each value came from.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> env\",\n \"<%= config.bin %> env --env production\",\n \"<%= config.bin %> env --env-file ./infra/acme-staging.env\",\n ];\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Env);\n await this.toMeta(flags);\n const { name, values, consulted } = this.environment;\n\n const resolved = ENVIRONMENT_KEYS.flatMap((key) => {\n const entry = values[key];\n if (!entry) {\n return [];\n }\n const shown = SECRET_KEYS.has(key) ? REDACTED : entry.value;\n return [{ variable: key, value: shown, source: entry.source }];\n });\n const lookups = consulted.map(({ source, present, supplied }) => ({\n source,\n present,\n supplied: supplied.join(\", \"),\n }));\n\n return this.emit({\n status: \"ok\",\n data: {\n environment: { name: name.value, source: name.source },\n values: resolved,\n consulted: consulted.map(({ source, present, supplied }) => ({\n source,\n present,\n supplied: [...supplied],\n })),\n },\n pretty: [\n `Environment ${name.value} (from ${name.source})`,\n \"\",\n renderTable([\"variable\", \"value\", \"source\"], resolved),\n \"\",\n \"Consulted, in order:\",\n renderTable([\"source\", \"present\", \"supplied\"], lookups),\n ].join(\"\\n\"),\n });\n }\n}\n","import { stat } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"../../lib/api-client\";\nimport { toZitadelError, ZitadelError } from \"../../lib/errors\";\nimport { isEnvironmentName } from \"../../lib/environment\";\nimport { writeManagedEnvFile } from \"../../lib/fs-safe\";\nimport { input } from \"../../lib/input\";\nimport { isObject } from \"../../lib/json\";\nimport {\n buildBundle,\n createDeployment,\n createReleaseFromBundle,\n DEPLOY_ARGS,\n headSha,\n runSteps,\n type StepContext,\n validateStep,\n worktreeIsDirty,\n} from \"../../lib/release\";\nimport { reportWarning } from \"../../lib/warnings\";\nimport {\n BaseCommand,\n CommandGroups,\n type JsonEnvelope,\n nonBlankArg,\n nonBlankString,\n} from \"../../lib/oclif\";\nimport { PUBLIC_PROJECT_ID_VARIABLE } from \"../../lib/orca/patchers/rule/public-project-id\";\nimport { readZitadelConfig } from \"../../lib/project\";\nimport { DEFAULT_SERVER, parseServer, resolveServer } from \"../../lib/server\";\nimport { shellArg, shellOption } from \"../../lib/shell\";\nimport { environmentSelectorSuffix } from \"../../lib/oclif/environment-flags\";\nimport { nextCommandsData } from \"../../lib/oclif/envelope\";\nimport { type EnvironmentSelector, projectCommand } from \"../../lib/suggestion\";\nimport { Promptable } from \"../../lib/oclif/promptable\";\n\n/** A variable to set on a hosting platform or in a pipeline. A secret is named, never printed. */\ntype PlatformVariable = { name: string; value?: string; secret?: boolean };\n\n/** The frameworks whose server needs the project secret at runtime (the session exchange). */\nconst SERVER_RENDERED = [\"next\", \"nuxt\"];\n\n/** The message the release this command publishes carries. */\nconst INITIAL_DEPLOY_MESSAGE = \"Initial deployment from zitadel env add\";\n\n/** What the initial deploy published, for the envelope to report. */\ntype DeployedRelease = {\n readonly releaseId: string;\n readonly contentHash: string;\n readonly deploymentId: string;\n readonly origins: readonly string[];\n};\n\n/**\n * `zitadel env add` — bind an environment to a project: create one on the\n * server, or bind an id a teammate sent over, and write the\n * `.env.<name>.local` file that is the environment. The file is the only thing\n * it writes. The deployed app never reads it (it is gitignored and the hosting\n * platform builds from git), so the command ends by printing exactly which\n * values the platform and the pipeline need.\n */\nexport default class EnvAdd extends Promptable(BaseCommand) {\n static override description = \"Bind an environment to a project, creating the project if needed.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> env add production --server https://api.zitadel.cloud --app-url https://app.acme.com\",\n \"<%= config.bin %> env add staging --server https://api.zitadel.cloud --project proj_01K9AA9M3K7E2QX8VB4T\",\n ];\n static override args = {\n name: nonBlankArg({ required: true, description: \"The environment name, e.g. production.\" }),\n };\n static override flags = {\n project: nonBlankString({\n description:\n \"Bind this existing project instead of creating one. Its secrets come from ZITADEL_PROJECT_SECRET and ZITADEL_PREVIEW_TOKEN in the process environment.\",\n }),\n \"app-url\": nonBlankString({\n description:\n \"The URL this environment's app is served from. It becomes ZITADEL_ISSUER and is registered with a new project.\",\n }),\n force: Flags.boolean({ description: \"Overwrite an existing .env.<name>.local.\" }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(EnvAdd);\n // The server is chosen here, not resolved: the environment being added has\n // no file yet to say where its project lives.\n await this.toMeta(flags, { resolveServer: false });\n const { cwd, env, nonInteractive, dryRun, serverFlag } = this.meta;\n const name = args.name;\n if (!isEnvironmentName(name)) {\n throw new ZitadelError(\"E_VALIDATION\", `\"${name}\" is not a usable environment name`, {\n hint: 'Use letters, digits, dot, dash and underscore, and no \"..\", e.g. production.',\n });\n }\n const file = `.env.${name}.local`;\n const path = join(cwd, file);\n\n const config = await readZitadelConfig(cwd);\n const frameworkId = isObject(config.framework) ? config.framework.id : undefined;\n const publicVariable =\n typeof frameworkId === \"string\"\n ? PUBLIC_PROJECT_ID_VARIABLE[frameworkId as keyof typeof PUBLIC_PROJECT_ID_VARIABLE]\n : undefined;\n\n if (\n !flags.force &&\n (await stat(path).then(\n () => true,\n () => false,\n ))\n ) {\n throw new ZitadelError(\"E_CONFLICT\", `${file} already exists`, {\n hint: \"Pass --force to overwrite it.\",\n });\n }\n\n const server = serverFlag\n ? (await resolveServer({ cwd, serverFlag })).value\n : await this.input({\n kind: \"text\",\n name: \"server\",\n message: \"What is the URL of your Zitadel server?\",\n flag: \"--server\",\n initialValue: DEFAULT_SERVER,\n parse: parseServer,\n // The rerun keeps every choice this run made, so binding a project\n // (`--project`) stays a bind rather than creating a new project.\n retry: this.suggestUnscoped(\n [\n `env add ${shellArg(name)}`,\n \"--server https://api.zitadel.cloud\",\n ...(flags.project === undefined ? [] : [shellOption(\"--project\", flags.project)]),\n ...(flags[\"app-url\"] === undefined\n ? []\n : [shellOption(\"--app-url\", flags[\"app-url\"])]),\n ...(flags.force ? [\"--force\"] : []),\n ].join(\" \"),\n ),\n });\n\n const appUrl =\n flags[\"app-url\"] ??\n (nonInteractive\n ? undefined\n : await this.input({\n kind: \"text\",\n name: \"app URL\",\n message: \"What URL is your app served from? You can leave this empty to skip it.\",\n flag: \"--app-url\",\n placeholder: \"https://app.acme.com\",\n parse: (answer: string) => ({ ok: true, value: answer.trim() || undefined }) as const,\n }));\n if (\n appUrl !== undefined &&\n !(URL.canParse(appUrl) && /^https?:$/.test(new URL(appUrl).protocol))\n ) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid app URL \"${appUrl}\"`, {\n hint: \"Use a URL like https://app.acme.com.\",\n });\n }\n const issuer = appUrl === undefined ? undefined : new URL(appUrl).origin;\n\n if (dryRun) {\n return this.emit({\n status: \"skipped\",\n reason: \"dry-run\",\n data: { environment: name, file, server, project_id: flags.project, issuer },\n });\n }\n\n let projectId = flags.project;\n let projectSecret = env.ZITADEL_PROJECT_SECRET;\n let previewToken = env.ZITADEL_PREVIEW_TOKEN;\n if (projectId === undefined) {\n const created = await createZitadelClient({ baseUrl: server }).createProject({\n name: `${basename(cwd)}-${name}`,\n ...(issuer === undefined\n ? {}\n : { origins: [{ pattern: issuer, kind: \"primary\" as const }] }),\n seed_defaults: false,\n });\n consola.success(`Created project ${created.id}`);\n projectId = created.id;\n projectSecret = created.project_secret;\n previewToken = created.preview_secret;\n }\n\n const values: Record<string, string> = {\n ZITADEL_URL: server,\n ZITADEL_PROJECT_ID: projectId,\n ...(projectSecret === undefined ? {} : { ZITADEL_PROJECT_SECRET: projectSecret }),\n ...(previewToken === undefined ? {} : { ZITADEL_PREVIEW_TOKEN: previewToken }),\n // The origin the app serves from, so a CLI run against this environment\n // resolves the same ZITADEL_ISSUER the deployed app registers.\n ...(issuer === undefined ? {} : { ZITADEL_ISSUER: issuer }),\n ...(publicVariable === undefined ? {} : { [publicVariable]: projectId }),\n };\n await writeManagedEnvFile(path, values);\n consola.success(`Wrote ${file}`);\n\n const appVariables: PlatformVariable[] = [\n { name: \"ZITADEL_URL\", value: server },\n { name: \"ZITADEL_PROJECT_ID\", value: projectId },\n ...(publicVariable === undefined ? [] : [{ name: publicVariable, value: projectId }]),\n ];\n const serverRendered = typeof frameworkId === \"string\" && SERVER_RENDERED.includes(frameworkId);\n const platform = {\n production: [\n ...appVariables,\n ...(serverRendered ? [{ name: \"ZITADEL_PROJECT_SECRET\", secret: true }] : []),\n { name: \"ZITADEL_ENV\", value: \"production\" },\n ...(serverRendered\n ? [\n { name: \"ZITADEL_ENVIRONMENT\", value: \"production\" },\n {\n name: \"ZITADEL_ISSUER\",\n value: issuer ?? \"<the URL your production app is served from>\",\n },\n ]\n : []),\n ],\n preview: [\n ...appVariables,\n { name: \"ZITADEL_ENV\", value: \"preview\" },\n ...(serverRendered ? [{ name: \"ZITADEL_ENVIRONMENT\", value: \"preview\" }] : []),\n { name: \"ZITADEL_PREVIEW_TOKEN\", secret: true },\n ],\n pipeline: [\n { name: \"ZITADEL_URL\", value: server },\n { name: \"ZITADEL_PROJECT_ID\", value: projectId },\n { name: \"ZITADEL_PROJECT_SECRET\", secret: true },\n ],\n };\n // Only a secret actually written to the file can be copied from it. When\n // `--project` binds an id with no ZITADEL_PROJECT_SECRET / PREVIEW_TOKEN in\n // the process environment, the file holds neither, so \"copy it from <file>\"\n // would send the user to a value that is not there — point them at the\n // project's own secret instead.\n const writtenKeys = new Set(Object.keys(values));\n // The new environment, by the file just written rather than by its name:\n // `--env-file` outranks the process environment, which `--env` does not, so\n // a follow-up run in a shell exporting another project's ZITADEL_* values\n // still acts on the project this run bound. This run's own selection is\n // not it either way.\n const newEnvironment = environmentSelectorSuffix({\n envFile: file,\n ...(typeof flags.cwd === \"string\" ? { cwd: flags.cwd } : {}),\n });\n // A created project already holds its app URL as a primary origin, which\n // closes it; only a bound one (`--project`) still needs the pattern added.\n const needsOrigin = flags.project !== undefined;\n const createdProject = !needsOrigin;\n // A deploy lands on the project's primary origins, and a created project\n // holds one only when an app URL was given. Without it there is nowhere\n // to land, so the deploy is refused by the server however it is reached:\n // offering it would ask for something that cannot work, and naming it\n // would send the reader to a command that fails the same way.\n const hasSomewhereToLand = createdProject && issuer !== undefined;\n const { cliVersion } = this.meta;\n // A project this run created has never had a release, so the environment\n // serves the server's own defaults until something is deployed to it\n // (#1651). Offer that deploy here, the one moment the project, its secret\n // and its origin are all at hand. A bound project (`--project`) is\n // someone else's and may already serve a release of its own, so it is\n // never offered one, and a run with nobody to ask gets the suggestion in\n // the envelope instead — there is no flag to deploy without being asked,\n // because an agent that wants one runs `deploy` itself. The question does\n // not go through `this.input`: that one answers a confirm when `--force`\n // is given, and here `--force` permits overwriting the env file, so it\n // must never answer it.\n let deployment: DeployedRelease | undefined;\n if (hasSomewhereToLand && !nonInteractive && projectSecret !== undefined) {\n consola.info(\n \"Nothing is deployed to this environment yet, so it serves the server's default schema and login flow rather than your .zitadel/ files.\",\n );\n const confirmed = await input(\n {\n kind: \"confirm\",\n name: \"deploy .zitadel/ to the new environment\",\n message: \"Would you like to deploy .zitadel/ to it now?\",\n initialValue: true,\n },\n { interactive: !nonInteractive, force: false },\n );\n if (confirmed) {\n deployment = await this.deployInitialRelease({\n cwd,\n server,\n projectId,\n projectSecret,\n selector: newEnvironment,\n });\n }\n }\n const render = (variables: PlatformVariable[]): string[] =>\n variables.map((variable) =>\n variable.secret\n ? writtenKeys.has(variable.name)\n ? ` ${variable.name} (secret, copy it from ${file})`\n : ` ${variable.name} (secret, copy it from wherever you got this project)`\n : ` ${variable.name}=${variable.value}`,\n );\n\n return this.emit({\n status: \"ok\",\n data: {\n title: `Bound ${name} to ${projectId}.`,\n environment: name,\n file,\n server,\n project_id: projectId,\n keys: Object.keys(values),\n platform,\n // The deployment this run made, so the environment serves the\n // developer's `.zitadel/` rather than whatever the server serves a\n // project with nothing deployed to it. `null` whenever none was made:\n // a `--project` bind, a run with nobody to ask, a declined prompt, or\n // a deploy that failed.\n deployment:\n deployment === undefined\n ? null\n : {\n release_id: deployment.releaseId,\n content_hash: deployment.contentHash,\n deployment_id: deployment.deploymentId,\n origins: [...deployment.origins],\n },\n // A bound project admits every origin until the first pattern closes\n // it, so the first step is to add one — `origin add` — before anything\n // ships. `next_commands` is machine-readable, so the entry is included\n // only when it is actually runnable: a concrete origin (without\n // `--app-url` it would be a `<your-app-url>` placeholder the shell\n // reads as redirection) and a project secret in the file for it to\n // authenticate with (a `--project` bind with no secret cannot). The\n // human-facing line below still spells it out.\n ...nextCommandsData([\n ...(needsOrigin && issuer !== undefined && writtenKeys.has(\"ZITADEL_PROJECT_SECRET\")\n ? // shellArg quotes the origin: an IPv6 issuer like http://[::1]:3000\n // carries brackets a shell such as zsh would treat as a glob.\n [\n projectCommand(\n `origin add ${shellArg(issuer)} --kind primary`,\n newEnvironment,\n cliVersion,\n ),\n ]\n : []),\n // Only a created project is offered a deploy: it is this run's own,\n // it has never had a release, and the file just written holds the\n // secret the deploy authenticates with. A `--project` bind is a\n // project someone else owns and may already serve a release of\n // their own, so this run does not propose replacing it.\n ...(hasSomewhereToLand && deployment === undefined\n ? [projectCommand(DEPLOY_ARGS, newEnvironment, cliVersion)]\n : []),\n projectCommand(\"env\", newEnvironment, cliVersion),\n ]),\n },\n pretty: [\n `Wrote ${file} with ${Object.keys(values).join(\", \")}`,\n \"\",\n // Quoted like the machine command, and only offered when it can run:\n // without the project secret in the file it would fail to authenticate.\n ...(needsOrigin\n ? [\n writtenKeys.has(\"ZITADEL_PROJECT_SECRET\")\n ? `Allow this project's origin: zitadel origin add ${issuer === undefined ? \"'<your-app-url>'\" : shellArg(issuer)} --kind primary${newEnvironment}`\n : `Allow this project's origin once ZITADEL_PROJECT_SECRET is in ${file}: zitadel origin add ${issuer === undefined ? \"'<your-app-url>'\" : shellArg(issuer)} --kind primary${newEnvironment}`,\n ]\n : []),\n // Said even when nobody could be asked, because it is the one thing\n // standing between this environment and a working app: until a\n // release is deployed the project serves the server's own defaults,\n // not the `.zitadel/` files in this directory.\n ...(createdProject && deployment === undefined\n ? [\n `Nothing is deployed to ${name} yet, so it serves the server's defaults rather than .zitadel/.`,\n ...(hasSomewhereToLand\n ? [`Deploy to it: zitadel ${DEPLOY_ARGS}${newEnvironment}`]\n : [\n `Give it an origin first: zitadel origin add '<your-app-url>' --kind primary${newEnvironment}`,\n `Then deploy to it: zitadel ${DEPLOY_ARGS}${newEnvironment}`,\n ]),\n ]\n : []),\n `Check what resolves: zitadel env${newEnvironment}`,\n \"\",\n \"The deployed app never reads that file. Set these where it is built and run.\",\n \"\",\n \"Hosting platform, production scope:\",\n ...render(platform.production),\n \"\",\n \"Hosting platform, preview scope:\",\n ...render(platform.preview),\n \"\",\n \"Pipeline secret store, for the job that runs zitadel:\",\n ...render(platform.pipeline),\n ].join(\"\\n\"),\n });\n }\n\n /**\n * Publish `.zitadel/` to the project this run just created, the way `deploy`\n * does: build the bundle, validate it, create the release and deploy it to\n * every primary origin. `deploy`'s diff step is left out, because nothing\n * has ever been deployed here and there is no baseline to diff against.\n *\n * It authenticates with the new project's own secret rather than the one\n * this directory resolves to, since `env add` binds a different project from\n * the one in context. A failure is warned about rather than thrown: the\n * project exists, the file is written, and the deploy is one command away.\n */\n private async deployInitialRelease(opts: {\n cwd: string;\n server: string;\n projectId: string;\n projectSecret: string;\n selector: EnvironmentSelector;\n }): Promise<DeployedRelease | undefined> {\n const json = this.jsonEnabled();\n const client = createZitadelClient({ baseUrl: opts.server, token: opts.projectSecret });\n consola.start(\"Deploying .zitadel/ to the new environment\");\n try {\n const { bundle, brandingSources, idpFiles, policyFiles } = await buildBundle(opts.cwd);\n const ctx: StepContext = {\n cwd: opts.cwd,\n client,\n projectId: opts.projectId,\n env: this.meta.env,\n mode: \"deploy\",\n dryRun: false,\n json,\n color: !json && Boolean(process.stdout.isTTY) && !process.env.NO_COLOR,\n bundle,\n brandingSources,\n idpFiles,\n policyFiles,\n suggest: (args) => projectCommand(args, opts.selector, this.meta.cliVersion),\n };\n await runSteps([validateStep], ctx);\n const release = await createReleaseFromBundle(client, opts.projectId, bundle, {\n message: INITIAL_DEPLOY_MESSAGE,\n gitSha: await headSha(opts.cwd),\n gitDirty: await worktreeIsDirty(opts.cwd),\n });\n // No optimistic guard: the project was created moments ago and nothing\n // has ever been deployed to it, so there is no deployment to race with.\n const deployment = await createDeployment(client, opts.projectId, {\n releaseId: release.id,\n targets: [\"primary\"],\n message: INITIAL_DEPLOY_MESSAGE,\n });\n const origins = deployment.targets.map((target) => target.origin);\n consola.success(\n `Deployed ${release.content_hash} to ${origins.length} origin${origins.length === 1 ? \"\" : \"s\"}`,\n );\n return {\n releaseId: release.id,\n contentHash: release.content_hash,\n deploymentId: deployment.id,\n origins,\n };\n } catch (error) {\n reportWarning(\n `The environment was bound but the first deploy failed: ${toZitadelError(error).message}. Run \\`zitadel ${DEPLOY_ARGS}${opts.selector}\\` to publish it.`,\n );\n return undefined;\n }\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { readBoundEnvironments } from \"../../lib/environment\";\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { renderList } from \"../../lib/oclif/crud/table\";\nimport { listData } from \"../../lib/oclif/envelope\";\n\n/** The columns `list` renders, in order. */\nconst COLUMNS = [\"name\", \"source\", \"server\", \"project_id\", \"resolved\"] as const;\n\n/**\n * `zitadel env list` — the environments this machine can reach: one per\n * `.env.<name>.local` that holds a project id, plus the process environment\n * when it carries one. An environment that lives only in a CI secret store is\n * not visible here, which is correct.\n */\nexport default class EnvList extends EnvironmentCommand {\n static override description = \"List the environments bound in this directory's .env files.\";\n static override group = CommandGroups.configuration;\n static override examples = [\"<%= config.bin %> env list\", \"<%= config.bin %> env list --plain\"];\n static override flags = {\n plain: Flags.boolean({\n description:\n \"Tab-separated rows with no header, for piping. Implied when stdout is not a terminal.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(EnvList);\n const { cwd, env } = await this.toMeta(flags);\n const { name, values } = this.environment;\n\n const bound = await readBoundEnvironments(cwd);\n const items = [\n ...bound.map((entry) => ({\n name: entry.name,\n source: entry.file,\n server: entry.values.ZITADEL_URL ?? \"\",\n project_id: entry.values.ZITADEL_PROJECT_ID ?? \"\",\n })),\n ...(env.ZITADEL_PROJECT_ID\n ? [\n {\n name: name.value,\n source: \"process environment\",\n server: env.ZITADEL_URL ?? \"\",\n project_id: env.ZITADEL_PROJECT_ID,\n },\n ]\n : []),\n ].map((entry) => ({\n ...entry,\n resolved: entry.source === values.ZITADEL_PROJECT_ID?.source,\n }));\n\n const plain = flags.plain || !process.stdout.isTTY;\n return this.emit({\n status: \"ok\",\n // The canonical list envelope, plus `resolved` naming which environment\n // this run resolves to (each item also carries its own `resolved` flag).\n data: { ...listData(items), resolved: { name: name.value, source: name.source } },\n pretty: renderList(\n COLUMNS,\n items.map((entry) => ({ ...entry, resolved: entry.resolved ? \"yes\" : \"\" })),\n {\n plain,\n singular: \"environment\",\n empty: \"No environments are bound here. Run `zitadel env add <name>` to bind one.\",\n footer: [`Resolved now: ${name.value} (from ${name.source})`],\n },\n ),\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../lib/errors\";\nimport { DEFAULT_LOCAL_SERVER_URL, readNearestRuntimeMetadata } from \"../lib/local-server/runtime\";\nimport { LocalServer } from \"../lib/local-server/server\";\nimport { LOG_LEVELS, type LogLine, logText, renderLogLine } from \"../lib/local-server/server-log\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\n\nexport default class Logs extends BaseCommand {\n static override description =\n \"Show local Zitadel server logs.\\n\\nOn a terminal, warnings are yellow and errors red. Run it in the directory `zitadel start` ran in, or one inside it: the server is found from the nearest `.zitadel/local/` on the way up.\";\n static override group = CommandGroups.localDevelopment;\n static override groupOrder = 2;\n\n static override examples = [\n \"<%= config.bin %> <%= command.id %> --follow\",\n \"<%= config.bin %> <%= command.id %> --level warn\",\n ];\n\n static override flags = {\n follow: Flags.boolean({ description: \"Keep printing lines as the server writes them.\" }),\n level: Flags.string({\n description: \"Show only lines at this level or above.\",\n options: [...LOG_LEVELS],\n }),\n tail: Flags.integer({\n description: \"Number of lines to show, counting only those --level shows.\",\n default: 200,\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Logs);\n // The server this directory uses: the one `zitadel start` ran in here or\n // in the nearest parent, as `doctor` and `console` find it.\n const nearest = await readNearestRuntimeMetadata(\n resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined),\n );\n await this.toMeta(flags, {\n resolveServer: false,\n source: nearest?.runtime.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n\n if (!nearest) {\n throw new ZitadelError(\"E_VALIDATION\", \"Local Zitadel runtime has not been started\", {\n hint: \"Run `zitadel start` first.\",\n nextCommands: [this.suggestUnscoped(\"start\")],\n });\n }\n\n const tail = flags.tail ?? 200;\n if (!Number.isInteger(tail) || tail < 1) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid tail value ${String(tail)}`, {\n hint: \"Use a positive integer.\",\n });\n }\n\n const level = LOG_LEVELS.find((name) => name === flags.level);\n const color = colorsLines(flags.color, this.meta.env, Boolean(process.stdout.isTTY));\n const server = LocalServer.at(nearest.dir, { cliVersion: this.meta.cliVersion });\n if (flags.follow) {\n if (this.jsonEnabled()) {\n throw new ZitadelError(\"E_VALIDATION\", \"Cannot stream logs with --json\", {\n hint: \"Run without --json, or omit --follow.\",\n });\n }\n await server.followLogs({\n tail,\n level,\n print: (lines) => {\n if (lines.length > 0) {\n process.stdout.write(`${render(lines, color)}\\n`);\n }\n },\n });\n return this.emit({\n status: \"ok\",\n data: { title: \"Stopped following local Zitadel logs.\" },\n });\n }\n\n const { runtime, lines } = await server.logs({ tail, level });\n return this.emit({\n status: \"ok\",\n pretty: render(lines, color),\n data: {\n title: \"Local Zitadel server logs.\",\n runtime:\n runtime.backend === \"binary\"\n ? { backend: runtime.backend, pid: runtime.pid, log_path: runtime.log_path }\n : { backend: runtime.backend, container_name: runtime.container_name },\n logs: logText(lines),\n },\n });\n }\n}\n\nfunction render(lines: readonly LogLine[], color: boolean): string {\n return lines.map((line) => renderLogLine(line, color)).join(\"\\n\");\n}\n\n/**\n * Whether the lines are printed in color: on a terminal, unless `--no-color`\n * or `NO_COLOR` turns color off, and anywhere `--color` or `FORCE_COLOR` turns\n * it on, such as in a pipe (`bin/run.js` sets the variables from the flags).\n */\nexport function colorsLines(flag: boolean, env: NodeJS.ProcessEnv, isTTY: boolean): boolean {\n if (!flag || env.NO_COLOR) {\n return false;\n }\n return Boolean(env.FORCE_COLOR) || (isTTY && env.TERM !== \"dumb\");\n}\n","import { ZitadelError } from \"../../errors\";\nimport { isObject } from \"../../json\";\nimport { fieldOf, objectOf, unwrap, type ZodLike } from \"./zod\";\n\n/**\n * Names whose value is a credential. Anything on the command line — a flag\n * value, and equally `--data \"$(cat body.json)\"`, which the shell expands\n * before the CLI runs — is visible to other processes, kept in shell history,\n * and captured by CI logs. Only a named file or stdin keeps it out of argv,\n * so those are the routes the errors point at.\n */\nconst SECRET_WORDS = new Set([\n \"password\",\n \"passwd\",\n \"pwd\",\n \"secret\",\n \"token\",\n \"credential\",\n \"credentials\",\n]);\n\n/** Secret names that only read as such once their words are joined. */\nconst SECRET_COMPOUNDS = [\"apikey\", \"privatekey\", \"accesskey\", \"secretkey\"];\n\n/**\n * Last words that make a credential-sounding name the name of an address:\n * `token_endpoint` is where a token is fetched, not a token. The name alone\n * proves nothing about the value, though — `secret_url` may hold the secret\n * itself — so only a value that is an address passes ({@link isBareAddress}).\n */\nconst ADDRESS_WORDS = new Set([\"endpoint\", \"url\", \"uri\"]);\n\n/** A name's words, whether it is spelled in snake_case, kebab-case or camelCase. */\nconst wordsOf = (key: string): readonly string[] =>\n key\n .replaceAll(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n .map((word) => word.toLowerCase());\n\n/**\n * Whether a property name reads as a credential, so `client_secret`, `api-key`\n * and `userToken` all match while `passwordless` — one word that merely starts\n * the same way — does not. `token_endpoint` matches too: what lets its URL\n * through is the value, not the name.\n */\nexport const isSecretKey = (key: string): boolean => {\n const words = wordsOf(key);\n return (\n words.some((word) => SECRET_WORDS.has(word)) ||\n SECRET_COMPOUNDS.some((compound) => words.join(\"\").includes(compound))\n );\n};\n\n/** Whether a name ends in a word that names an address (`token_endpoint`, `jwks_uri`). */\nconst isAddressKey = (key: string): boolean => ADDRESS_WORDS.has(wordsOf(key).at(-1) ?? \"\");\n\n/**\n * Whether a value is an address and nothing more: a URL with a host that\n * carries no credential of its own — no user info (`https://user:pass@…`) and\n * no query parameter named like one (`?access_token=…`).\n */\nconst isBareAddress = (value: unknown): boolean => {\n if (typeof value !== \"string\" || !URL.canParse(value)) {\n return false;\n }\n const url = new URL(value);\n return (\n url.host !== \"\" &&\n url.username === \"\" &&\n url.password === \"\" &&\n ![...url.searchParams.keys()].some(isSecretKey)\n );\n};\n\n/** Where a credential can go without passing through the command line. */\nexport const SECRET_ROUTES = \"--file <path>, or --file - to read the body from stdin\";\n\n/**\n * How the platform spells a reference to a value it holds elsewhere — Zitadel's\n * `${{ NAME }}` variables (ADR 062). A reference names a credential without\n * revealing it, so it may stand on a command line: it is the only form some\n * fields accept (a connection's `client_secret`).\n */\nexport type References = Readonly<{\n /** Whether a whole value is a reference. */\n matches: (value: string) => boolean;\n /** A reference as an error shows one. */\n example: string;\n}>;\n\n/** What the guard and the redaction know about a value beyond its keys. */\nexport type CredentialContext = Readonly<{\n /** The schema the value follows, which says where a value cannot be a credential. */\n schema?: ZodLike | undefined;\n references?: References | undefined;\n}>;\n\n/** A credential found in a value: the key that names it, and where it sits. */\nexport type Credential = Readonly<{ key: string; path: string }>;\n\n/** Refuse a credential that reached the command line, naming a route that does not. */\nexport const refuseSecret = (\n key: string,\n source: string,\n context: Pick<CredentialContext, \"references\"> & { path?: string } = {},\n): never => {\n // A reference is the fix only where the field takes one (a connection's\n // client secret), so the hint offers it as that and not as a way around the\n // refusal for any value.\n const reference = context.references\n ? ` A field that takes a reference to a variable can name it instead, as ${context.references.example}.`\n : \"\";\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Refusing to read \"${key}\" from ${source}: the command line is visible to other processes and is kept in shell history`,\n {\n hint: `Pass the body with ${SECRET_ROUTES}.${reference}`,\n details: { field: key, ...(context.path ? { path: context.path } : {}) },\n },\n );\n};\n\n/** Whether a schema accepts any text at all, so a string under it may be anything. */\nconst freeText = (schema: ZodLike | undefined): boolean =>\n [\"string\", \"any\", \"unknown\", undefined].includes(unwrap(schema)?.def?.type);\n\n/**\n * Whether the schema types `value` as something no credential can be: one of\n * an enum's values, a number where it declares a number, a literal. A secret\n * is free-form text, and a field that only takes `client_secret_basic` or\n * `client_secret_post` holds neither.\n */\nconst fixedByTheSchema = (schema: ZodLike | undefined, value: unknown): boolean => {\n const type = unwrap(schema);\n switch (type?.def?.type) {\n case \"enum\":\n return typeof value === \"string\" && (type.options ?? []).includes(value);\n case \"number\":\n return typeof value === \"number\";\n case \"literal\":\n return (type.def?.values ?? []).includes(value);\n case \"union\": {\n const members = type.def?.options ?? [];\n if (typeof value === \"string\" && members.some(freeText)) {\n return false;\n }\n return members.some((member) => fixedByTheSchema(member, value));\n }\n default:\n return false;\n }\n};\n\n/** The schema of one key below `schema`: a field of an object, or a record's value. */\nconst childOf = (schema: ZodLike | undefined, key: string): ZodLike | undefined => {\n if (objectOf(schema)) {\n return fieldOf(schema, key);\n }\n const type = unwrap(schema);\n return type?.def?.type === \"record\" ? type.def.valueType : undefined;\n};\n\n/**\n * Whether one leaf is a credential: it sits under a credential-named key (its\n * own or an ancestor's, `key`) and is free-form. A boolean or `null` never is,\n * and neither is a reference, a value the schema fixes, or a bare URL under\n * the name of an address (ADR 071 §7).\n */\nconst isCredentialLeaf = (\n value: unknown,\n schema: ZodLike | undefined,\n context: CredentialContext,\n key: string,\n): boolean => {\n if (typeof value === \"boolean\" || value === null || value === undefined) {\n return false;\n }\n if (typeof value === \"string\" && context.references?.matches(value)) {\n return false;\n }\n if (isAddressKey(key) && isBareAddress(value)) {\n return false;\n }\n return !fixedByTheSchema(schema, value);\n};\n\n/** A leaf under a credential-named key, with the key and the schema it sits under. */\ntype GuardedLeaf = Readonly<{\n leaf: unknown;\n key: string;\n path: readonly string[];\n schema: ZodLike | undefined;\n}>;\n\n/** Every leaf of a value that sits under a credential-named key, its own or an ancestor's. */\nfunction* guardedLeaves(\n value: unknown,\n schema: ZodLike | undefined,\n under: string | undefined,\n path: readonly string[],\n): Generator<GuardedLeaf> {\n if (Array.isArray(value)) {\n const element = unwrap(schema)?.def?.element;\n for (const [index, entry] of value.entries()) {\n yield* guardedLeaves(entry, element, under, [...path, String(index)]);\n }\n return;\n }\n if (isObject(value)) {\n for (const [key, nested] of Object.entries(value)) {\n yield* guardedLeaves(nested, childOf(schema, key), isSecretKey(key) ? key : under, [\n ...path,\n key,\n ]);\n }\n return;\n }\n if (under !== undefined) {\n yield { leaf: value, key: under, path, schema };\n }\n}\n\n/** The first credential anywhere in a value, if there is one. */\nexport const findCredential = (\n value: unknown,\n context: CredentialContext = {},\n): Credential | undefined => {\n for (const { leaf, key, path, schema } of guardedLeaves(value, context.schema, undefined, [])) {\n if (isCredentialLeaf(leaf, schema, context, key)) {\n return { key, path: path.join(\".\") };\n }\n }\n return undefined;\n};\n\n/**\n * A value with every credential masked. A body may legitimately carry a\n * secret when it arrives by `--file` or stdin, but `--dry-run` prints what\n * would be sent — to a terminal, and to whatever captures CI logs — so the\n * value must not travel with it. Everything else is shown as it would be\n * sent, references included, so the preview can be checked and reused.\n */\nexport const redactCredentials = (\n value: unknown,\n context: CredentialContext = {},\n schema: ZodLike | undefined = context.schema,\n under?: string,\n): unknown => {\n if (Array.isArray(value)) {\n const element = unwrap(schema)?.def?.element;\n return value.map((entry) => redactCredentials(entry, context, element, under));\n }\n if (isObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, nested]) => [\n key,\n redactCredentials(nested, context, childOf(schema, key), isSecretKey(key) ? key : under),\n ]),\n );\n }\n return under !== undefined && isCredentialLeaf(value, schema, context, under)\n ? \"«redacted»\"\n : value;\n};\n","import { nonBlankArg } from \"../flags\";\n\nimport { ZitadelError } from \"../../errors\";\nimport type { CommandResult } from \"../types\";\nimport { type CredentialContext, redactCredentials } from \"./secrets\";\nimport type { Json, ResourceDescriptor, Schema } from \"./types\";\n\n/** Helpers shared by more than one verb builder. */\n\n/** The name of a resource's positional argument. */\nexport const idName = <Ctx>(resource: ResourceDescriptor<Ctx>): string => resource.idArg ?? \"id\";\n\n/** The single positional argument the id-taking verbs share. */\nexport const idArg = <Ctx>(resource: ResourceDescriptor<Ctx>) => {\n const name = idName(resource);\n const description = resource.idDescription ?? `${resource.singular} ${name}`;\n return { [name]: nonBlankArg({ required: true, description }) };\n};\n\n/** The value the caller passed for that argument. */\nexport const idValue = <Ctx>(resource: ResourceDescriptor<Ctx>, args: Json): string =>\n String(args[idName(resource)]);\n\n/**\n * Words spelled with a vowel but said with a \"yoo\" sound, so they take \"a\":\n * \"a user\", \"a unique id\". Add one here when a resource noun needs it.\n */\nconst YOO_SOUND = /^(?:user|unique|unit|usage)/i;\n\n/**\n * The indefinite article for a noun phrase, so a generated description reads\n * as English: \"an identity provider connection\", not \"a identity provider\n * connection\". A vowel letter takes \"an\", except a word in {@link YOO_SOUND}.\n * A silent \"h\" (\"an hour\") is not handled; no resource noun starts with one.\n */\nexport const article = (phrase: string): string =>\n /^[aeiou]/i.test(phrase) && !YOO_SOUND.test(phrase) ? \"an\" : \"a\";\n\nexport const capitalize = (word: string): string => word.charAt(0).toUpperCase() + word.slice(1);\n\n/**\n * Validate with a generated schema, translating a failure into the CLI's\n * `E_VALIDATION` envelope with the issues attached — the same shape\n * `toZitadelError` produces for a thrown Zod error, with a message and hint\n * that name the flag the user got wrong.\n */\nexport const parseOrThrow = <B>(\n schema: Schema<B>,\n value: unknown,\n message: string,\n hint?: string,\n): B => {\n const parsed = schema.safeParse(value);\n if (!parsed.success) {\n throw new ZitadelError(\"E_VALIDATION\", message, {\n hint,\n details: { issues: parsed.error.issues },\n });\n }\n return parsed.data;\n};\n\nexport const dryRunResult = (\n verb: string,\n topic: string,\n id?: string,\n body?: Json,\n context?: CredentialContext,\n): CommandResult => {\n // A body that came from a file may legitimately hold a credential; a preview\n // of it must not put that value on screen or into a CI log. Only the\n // credentials are masked: the rest is what would be sent, so the preview can\n // be checked, and saved as a document to send later (ADR 071 §8).\n const shown = body === undefined ? undefined : (redactCredentials(body, context) as Json);\n return {\n status: \"ok\",\n data: { dry_run: true, verb, topic, id, body: shown },\n pretty: `Dry run: would ${verb} ${[topic, id].filter(Boolean).join(\" \")}${shown ? `\\n${JSON.stringify(shown, null, 2)}` : \"\"}`,\n };\n};\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope, nonBlankArg } from \"../../lib/oclif\";\nimport { dryRunResult } from \"../../lib/oclif/crud/shared\";\nimport { nextCommandsData } from \"../../lib/oclif/envelope\";\n\n/** The two kinds an origin pattern can be, as the `--kind` flag accepts them. */\nconst ORIGIN_KINDS = [\"primary\", \"preview\"] as const;\n\n/**\n * `zitadel origin add <pattern> --kind primary|preview` — add one origin\n * pattern to the project.\n *\n * The CLI sends the pattern as it is and prints what the server stored, or the\n * server's rejection in words: a primary pattern must be an exact URL, and a\n * preview wildcard on a shared host needs a literal label of your own. The\n * check the pattern passed stands in for the review a committed list would have\n * had, which is why this is a deliberate command and never a side effect of a\n * deploy.\n */\nexport default class OriginAdd extends EnvironmentCommand {\n static override description = \"Add an origin pattern to the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> origin add https://app.acme.com --kind primary\",\n \"<%= config.bin %> origin add 'https://*-acme.vercel.app' --kind preview\",\n ];\n static override args = {\n pattern: nonBlankArg({ required: true, description: \"The origin pattern to add.\" }),\n };\n static override flags = {\n kind: Flags.string({\n description: \"What the pattern is for.\",\n options: [...ORIGIN_KINDS],\n required: true,\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(OriginAdd);\n await this.toMeta(flags);\n const kind = flags.kind as (typeof ORIGIN_KINDS)[number];\n\n // A dry run makes no request, so it answers before the connection — the\n // order the resource commands' `create` uses, which keeps\n // `--dry-run --non-interactive` usable.\n if (this.meta.dryRun) {\n return this.emit(dryRunResult(\"add\", \"origin\", args.pattern, { kind }));\n }\n\n const { client, projectId } = await this.connect();\n\n const added = await client.addOrigin(projectId, { pattern: args.pattern, kind });\n\n return this.emit({\n status: \"ok\",\n data: {\n pattern: added.pattern,\n kind: added.kind,\n // Carry the in-effect selectors so the follow-up list reads the same\n // environment this add targeted, not the default one.\n ...nextCommandsData([this.suggest(\"origin list\")]),\n },\n pretty: `Added ${added.pattern} (${added.kind})`,\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { renderList } from \"../../lib/oclif/crud/table\";\nimport { listData } from \"../../lib/oclif/envelope\";\n\n/** The columns `list` renders, in order. */\nconst COLUMNS = [\"pattern\", \"kind\"] as const;\n\n/**\n * `zitadel origin list` — show the project's origin patterns.\n *\n * Origins are read off the project itself, not from `zitadel.json`: they are\n * project state, so the server is the authority. An empty list means every\n * origin is admitted until the first pattern is added.\n */\nexport default class OriginList extends EnvironmentCommand {\n static override description = \"List the origin patterns on the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> origin list\",\n \"<%= config.bin %> origin list --plain\",\n ];\n static override flags = {\n plain: Flags.boolean({\n description:\n \"Tab-separated rows with no header, for piping. Implied when stdout is not a terminal.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(OriginList);\n await this.toMeta(flags);\n const { client, projectId } = await this.connect();\n\n const origins = (await client.getProject(projectId)).origins ?? [];\n\n // The resource commands' list rendering: a pipe (or `--plain`) gets one\n // tab-separated record per line, with no header and nothing at all when\n // empty, so `cut`, `awk` and `wc -l` work on it; a terminal gets a table.\n const plain = flags.plain || !process.stdout.isTTY;\n return this.emit({\n status: \"ok\",\n // The project returns its whole origin set in one page, so the token is null.\n data: listData(origins),\n pretty: renderList(COLUMNS, origins, {\n plain,\n singular: \"origin\",\n empty: \"No origins on the project.\",\n }),\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope, nonBlankArg } from \"../../lib/oclif\";\nimport { dryRunResult } from \"../../lib/oclif/crud/shared\";\nimport { deletedData } from \"../../lib/oclif/envelope\";\nimport { shellArg } from \"../../lib/shell\";\nimport { reportWarning } from \"../../lib/warnings\";\nimport { Promptable } from \"../../lib/oclif/promptable\";\n\n/**\n * `zitadel origin rm <pattern>` — remove one origin pattern from the project.\n *\n * It says what stops being admitted. Removing a preview pattern leaves its live\n * previews to expire on their own. Destructive, so it takes the same\n * `--force`-or-confirm gate the resource commands' `delete` uses.\n */\nexport default class OriginRm extends Promptable(EnvironmentCommand) {\n static override description = \"Remove an origin pattern from the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> origin rm https://app.acme.com\",\n \"<%= config.bin %> origin rm https://app.acme.com --force\",\n ];\n static override args = {\n pattern: nonBlankArg({ required: true, description: \"The origin pattern to remove.\" }),\n };\n static override flags = {\n // `--force` is per command, not global: here it permits a removal.\n force: Flags.boolean({\n char: \"f\",\n description:\n \"Remove the pattern without the confirmation prompt. Required when non-interactive.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(OriginRm);\n await this.toMeta(flags);\n const { dryRun } = this.meta;\n const pattern = args.pattern;\n\n // A dry run makes no request, so it answers before the connection — the\n // order the resource commands' `delete` uses, which keeps\n // `--dry-run --non-interactive` usable.\n if (dryRun) {\n const preview = dryRunResult(\"remove\", \"origin\", pattern);\n return this.emit({ ...preview, pretty: `${preview.pretty} from the project` });\n }\n\n // Resolved before the confirmation, so the prompt is answered knowing\n // which project it removes from: `connect` names it on a terminal, and\n // asks for a missing value before, not after, the removal is agreed.\n const { client, projectId } = await this.connect();\n\n // A preview pattern can carry a `*`, so the retry is copy-pasteable only if\n // the shell will not expand it: `shellArg` single-quotes any pattern holding\n // a glob or other special character before interpolating it.\n const confirmed = await this.input({\n kind: \"confirm\",\n name: `remove ${pattern} from the project`,\n message: `Remove ${pattern} from the project?`,\n retry: this.suggest(`origin rm ${shellArg(pattern)} --force`),\n });\n if (!confirmed) {\n return this.emit({ status: \"skipped\", reason: \"remove-cancelled\" });\n }\n\n await client.removeOrigin(projectId, { pattern });\n\n // An empty list admits every origin, so removing the last pattern opens the\n // project up rather than closing it: said aloud, since it is the opposite\n // of what removing one pattern otherwise does.\n // The pattern is already removed, so a failed read of what is left is said\n // aloud rather than reported as a failed removal.\n const remaining = await client.getProject(projectId).then(\n (project) => project.origins ?? [],\n (error: unknown) => {\n reportWarning(\n `${pattern} was removed, but the project's remaining origins could not be read: ${error instanceof Error ? error.message : String(error)}`,\n );\n return undefined;\n },\n );\n if (remaining?.length === 0) {\n reportWarning(\n // Named in the text, not as a next command: the URL is the developer's\n // to fill in, and a `<url>` placeholder is a shell redirection. The\n // selector keeps it on the environment that was just opened up.\n `${pattern} was the project's last origin, so the project now admits every origin. Add the ones it should admit with \\`zitadel origin add <url> --kind primary${this.environmentSelector()}\\`.`,\n );\n }\n\n return this.emit({\n status: \"ok\",\n data: deletedData({ pattern }),\n pretty:\n remaining?.length === 0\n ? `Removed ${pattern}; the project has no origins left and admits every origin`\n : `Removed ${pattern} from the project's origins`,\n });\n }\n}\n","/**\n * The hosting platforms a pull-request build announces its preview URLs\n * through, in the order they are tried. Each reads its own variables off the\n * environment and returns the preview URLs it finds, already normalised; a\n * platform that set none of its variables contributes nothing.\n *\n * Vercel exposes bare hosts, so a scheme is prepended; Netlify exposes the full\n * deployment URL, which is used as-is. Cloudflare Pages is not detected: it\n * sets `CF_PAGES_URL` on production deployments too, and nothing in its build\n * environment marks a preview, so its URLs are passed with `--origin` (#1692).\n *\n * Only a build's preview / per-deploy URLs belong here: a platform's\n * production or canonical-site variable (e.g. `VERCEL_PROJECT_PRODUCTION_URL`,\n * Netlify's `URL`, `CI_PAGES_URL`) is deliberately excluded, since `preview`\n * must never target a production origin. Anything not detected is passed with\n * `--origin`.\n */\nconst PREVIEW_PLATFORMS: ReadonlyArray<{\n variables: readonly string[];\n urls: (env: NodeJS.ProcessEnv) => string[];\n}> = [\n {\n variables: [\"VERCEL_BRANCH_URL\", \"VERCEL_URL\"],\n urls: (env) =>\n [env.VERCEL_BRANCH_URL, env.VERCEL_URL]\n .filter((host): host is string => Boolean(host))\n .map((host) => `https://${host}`),\n },\n {\n variables: [\"DEPLOY_PRIME_URL\", \"DEPLOY_URL\"],\n urls: (env) =>\n [env.DEPLOY_PRIME_URL, env.DEPLOY_URL].filter((url): url is string => Boolean(url)),\n },\n];\n\n/** What {@link detectPreviewUrls} resolved from the environment. */\nexport type DetectedPreviews = Readonly<{\n /** The preview URLs found, de-duplicated, in the order the platforms list them. */\n urls: readonly string[];\n /** Every variable consulted, for an error message when none were set. */\n variablesLookedFor: readonly string[];\n}>;\n\n/**\n * The preview URLs a hosting platform's build injected, read from the\n * environment. Normally only one platform's variables are present, but all are\n * consulted so a command can say exactly which it looked for when none are.\n */\nexport function detectPreviewUrls(env: NodeJS.ProcessEnv): DetectedPreviews {\n const urls = new Set<string>();\n const variablesLookedFor: string[] = [];\n for (const platform of PREVIEW_PLATFORMS) {\n variablesLookedFor.push(...platform.variables);\n for (const url of platform.urls(env)) {\n urls.add(url.replace(/\\/+$/, \"\"));\n }\n }\n return { urls: [...urls], variablesLookedFor };\n}\n","import { ZitadelError } from \"./errors\";\n\n/** Seconds per unit a TTL string accepts. */\nconst MINUTE = 60;\nconst HOUR = 60 * 60;\nconst DAY = 24 * 60 * 60;\n\n/**\n * A TTL parsed into its canonical single-unit string, the ISO-8601 duration the\n * wire carries, and its duration in milliseconds.\n */\nexport type Ttl = Readonly<{ canonical: string; iso: string; ms: number }>;\n\n/**\n * Parse a TTL like `7d`, `12h`, `90m` or `3600s` — a positive whole number\n * followed by a single `s`/`m`/`h`/`d` unit — into its canonical single-unit\n * string and its duration in milliseconds. Seconds are accepted as input, but\n * the canonical form is minutes, hours or days only (see {@link formatTtl}), so\n * a value given in seconds is re-expressed. A malformed input is an\n * `E_VALIDATION`. Range limits are the caller's to apply.\n */\nexport function parseTtl(input: string): Ttl {\n const match = /^([1-9][0-9]*)(s|m|h|d)$/.exec(input.trim());\n if (!match) {\n throw new ZitadelError(\"E_VALIDATION\", `${input} is not a valid ttl`, {\n hint: \"Use a whole number followed by s, m, h or d, e.g. 7d, 12h or 90m.\",\n });\n }\n const unit = match[2] === \"s\" ? 1 : match[2] === \"m\" ? MINUTE : match[2] === \"h\" ? HOUR : DAY;\n const seconds = Number(match[1]) * unit;\n return { canonical: formatTtl(seconds), iso: isoDuration(seconds), ms: seconds * 1000 };\n}\n\n/**\n * The ISO-8601 duration for a whole number of seconds, the form the API takes\n * (`P7D`, `PT1H`, `PT90M`). The flag keeps the shorter `7d`/`12h` spelling\n * because that is what a person writes; only the wire sees this one. A whole\n * number of days is a date-part duration (`P7D`); anything else is a time-part\n * one carrying the coarsest exact unit. It rounds a sub-minute remainder up to\n * the next whole minute exactly as {@link formatTtl} does, so what the caller\n * is shown and what the wire carries are the same duration.\n */\nexport function isoDuration(seconds: number): string {\n if (seconds % DAY === 0) {\n return `P${seconds / DAY}D`;\n }\n if (seconds % HOUR === 0) {\n return `PT${seconds / HOUR}H`;\n }\n return `PT${Math.ceil(seconds / MINUTE)}M`;\n}\n\n/**\n * The canonical TTL string for a whole number of seconds: the coarsest of day,\n * hour or minute that divides it exactly, else rounded up to the next whole\n * minute (the finest unit the canonical form uses).\n */\nexport function formatTtl(seconds: number): string {\n if (seconds % DAY === 0) {\n return `${seconds / DAY}d`;\n }\n if (seconds % HOUR === 0) {\n return `${seconds / HOUR}h`;\n }\n if (seconds % MINUTE === 0) {\n return `${seconds / MINUTE}m`;\n }\n return `${Math.ceil(seconds / MINUTE)}m`;\n}\n","import { Flags } from \"@oclif/core\";\nimport type { ZitadelClient } from \"@zitadel/api/client\";\nimport { ApiError } from \"@zitadel/api/runtime/fetch\";\n\nimport {\n CommandGroups,\n CREDENTIALS,\n type JsonEnvelope,\n PREVIEW_CREDENTIAL,\n PreviewCommand,\n previewFlags,\n} from \"../../lib/oclif\";\nimport {\n buildBundle,\n createDeployment,\n createReleaseFromBundle,\n headSha,\n runSteps,\n type StepContext,\n validateStep,\n worktreeIsDirty,\n} from \"../../lib/release\";\nimport { detectPreviewUrls } from \"../../lib/preview\";\nimport { parseTtl } from \"../../lib/ttl\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { reportWarning } from \"../../lib/warnings\";\nimport { ciProvider } from \"../../lib/telemetry/dimensions/ci-provider\";\nimport { envEnabled } from \"../../lib/telemetry/dimensions/env-flag\";\n\n/**\n * `zitadel preview` — publish `.zitadel/` to a pull-request build's preview URLs.\n *\n * It is `deploy`'s counterpart for a preview environment: it assembles the same\n * release bundle and validates it as `deploy` does, identity-provider\n * connections included, but never writes them — a pull-request build must not\n * touch the live connections a merged deploy syncs — and deploys to the preview URLs with a time-to-live rather than to the\n * primary origins. The URLs come from `--origin` or, failing that, from the\n * hosting platform's own build variables (Vercel, Netlify).\n *\n * It authenticates with the narrower preview credential and never falls back\n * to the project secret. A fork pull-request build has no `ZITADEL_PREVIEW_TOKEN`\n * — the secret is not shared with forks — so a missing one warns and exits\n * cleanly rather than failing the build (#1312); `--strict` turns that warning\n * into a failure for a trusted build that expects the token. Outside a preview\n * or development environment there is nothing to preview — even with an explicit\n * `--origin` — so it says so and exits cleanly without writing. The last line it\n * prints is the release digest as `NEXT_PUBLIC_ZITADEL_RELEASE`, for the build\n * to pin.\n */\nexport default class Preview extends PreviewCommand {\n static override description =\n \"Deploy a release from .zitadel/ to a pull-request build's preview URLs.\";\n static override group = CommandGroups.configuration;\n static override groupOrder = 2;\n static override examples = [\n \"<%= config.bin %> preview\",\n \"<%= config.bin %> preview --origin https://acme-git-sso-acmeinc.vercel.app\",\n \"<%= config.bin %> preview --ttl 24h\",\n ];\n static override flags = {\n ...previewFlags,\n // Preview-only: `preview list` and `preview rm` share the credential but\n // have no deploy to make strict, so this lives here, not in `previewFlags`.\n strict: Flags.boolean({\n description: `Fail instead of warning when no preview credential (${CREDENTIALS[PREVIEW_CREDENTIAL]}) is set.`,\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Preview);\n await this.toMeta(flags);\n const { cwd, env, isTTY, dryRun } = this.meta;\n const json = this.jsonEnabled();\n const color = !json && isTTY && flags.color !== false && !process.env.NO_COLOR;\n\n // Only a preview or development build has anything to preview: a production\n // (or any other non-preview) build serves the deployed release, published by\n // `zitadel deploy` after merge. The environment gates this, not `--origin`:\n // an explicit origin only selects which targets to preview, it never\n // authorizes a preview deploy into an environment that must not take writes.\n // An origin has no path, so a trailing slash is the same URL: dropped\n // here as detection drops it, so one preview is one spelling — and a URL\n // given twice is sent once, as the request's unique targets require.\n const requested = [...new Set((flags.origin ?? []).map((url) => url.replace(/\\/+$/, \"\")))];\n // `primary` is the deployment keyword for every primary origin. A preview\n // build carries the preview credential and must never be able to reach\n // production with it, so the keyword is refused outright.\n if (requested.includes(\"primary\")) {\n throw new ZitadelError(\"E_VALIDATION\", \"A preview cannot target the primary origins\", {\n hint: \"Pass the preview URLs with --origin; production is deployed by `zitadel deploy`, after merge.\",\n });\n }\n\n // `--ttl` is optional: omitted, nothing is sent and the server applies the\n // project's default, rather than the CLI pinning a lifetime of its own.\n // Checked before anything that can skip the run, so a bad value fails every\n // build rather than only the trusted ones that reach the deploy.\n const ttl = flags.ttl === undefined ? undefined : parseTtl(flags.ttl);\n // A preview lives a minute at least and 365 days at most — the server's\n // fixed limit (preview-ttl.yaml), applied here rather than in the generic\n // TTL parser so a bad value fails before a release is built.\n if (ttl !== undefined && (ttl.ms < 60 * 1000 || ttl.ms > 365 * 24 * 60 * 60 * 1000)) {\n throw new ZitadelError(\"E_VALIDATION\", `${flags.ttl} is outside the allowed range`, {\n hint: \"A preview lives between 60s and 365d.\",\n });\n }\n\n const envName = this.environment.name.value;\n if (envName !== \"preview\" && envName !== \"development\") {\n return this.emit({\n status: \"skipped\",\n reason: \"nothing-to-preview\",\n pretty: \"nothing to preview — production is deployed by `zitadel deploy`, after merge\",\n });\n }\n // `development` by default is a developer's machine. In a CI build it is\n // only a platform the resolver cannot read (anything but Vercel and\n // Netlify), which may be a production build, so it must say it is a\n // preview build rather than be taken for one.\n if (this.environment.name.source === \"default\" && runsInCi(env)) {\n reportWarning(\n \"This CI build names no environment, so the preview is skipped. Set ZITADEL_ENV=preview in the pull-request build that should deploy one.\",\n );\n return this.emit({\n status: \"skipped\",\n reason: \"nothing-to-preview\",\n pretty: \"nothing to preview — set ZITADEL_ENV=preview in the pull-request build\",\n });\n }\n\n // A fork pull-request build cannot read a secret — one is never exposed to\n // a fork — so a missing credential is not a build failure: the preview is\n // skipped and the build carries on (#1312). `--strict` is for a trusted\n // build that expects it, where a missing one is a misconfiguration worth\n // failing on. The other credential is never a stand-in, so its presence\n // does not satisfy this.\n const credential = CREDENTIALS[PREVIEW_CREDENTIAL];\n if (this.environment.values[credential] === undefined) {\n if (flags.strict) {\n throw new ZitadelError(\"E_VALIDATION\", `${credential} is not set`, {\n hint: `Set ${credential} for this build, or drop --strict to skip the preview when it is absent.`,\n });\n }\n reportWarning(\n `No preview credential (${credential}) is set, so the preview is skipped; a fork pull-request build cannot read it. Pass --strict to fail instead.`,\n );\n return this.emit({\n status: \"skipped\",\n reason: \"no-preview-credential\",\n pretty: `no preview credential (${credential}) — preview skipped`,\n });\n }\n\n // Preview URLs come from `--origin`, else from the platform build variables.\n let urls = requested;\n if (urls.length === 0) {\n const detected = detectPreviewUrls(env);\n if (detected.urls.length === 0) {\n throw new ZitadelError(\"E_VALIDATION\", \"No preview URLs to deploy to\", {\n hint: `Pass --origin, or run inside a pull-request build that sets one of: ${detected.variablesLookedFor.join(\", \")}.`,\n });\n }\n urls = [...detected.urls];\n }\n\n const { client, projectId } = await this.connect();\n\n // An exact primary origin is production as surely as the `primary`\n // keyword is, so it is refused too. The server is the authority on what\n // the preview token may reach; this catches the mistake before anything\n // is built, whenever the token can read the project's origins.\n const primaries = await primaryOrigins(client, projectId);\n const production = urls.filter((url) => primaries.includes(url));\n if (production.length > 0) {\n throw new ZitadelError(\"E_VALIDATION\", `${production.join(\", \")} is a primary origin`, {\n hint: \"Pass the preview URLs with --origin; production is deployed by `zitadel deploy`, after merge.\",\n });\n }\n\n const { bundle, brandingSources, idpFiles, policyFiles } = await buildBundle(cwd);\n const ctx: StepContext = {\n cwd,\n client,\n projectId,\n env,\n mode: \"preview\",\n dryRun,\n json,\n color,\n bundle,\n brandingSources,\n idpFiles,\n policyFiles,\n suggest: (args) => this.suggest(args),\n };\n\n // The IdP step validates the connection files and stops short of syncing\n // them in a preview, so a pull-request build never reconfigures the\n // connections a merged deploy owns.\n await runSteps([validateStep], ctx);\n\n // A dry run validates and resolves the targets but writes nothing — no\n // release, no deployment, no preview registration — so a pull-request build\n // can check its `.zitadel/` without publishing, as `deploy --dry-run` does.\n if (dryRun) {\n return this.emit({\n status: \"ok\",\n data: {\n dry_run: true,\n targets: urls,\n },\n pretty: [\n `Validated the preview for ${urls.length} URL${urls.length === 1 ? \"\" : \"s\"}. Nothing was deployed (dry run).`,\n ...urls.map((url) => ` - ${url}`),\n ].join(\"\\n\"),\n });\n }\n\n const release = await createReleaseFromBundle(client, projectId, bundle, {\n gitSha: await headSha(cwd),\n gitDirty: await worktreeIsDirty(cwd),\n });\n const deployment = await createDeployment(client, projectId, {\n releaseId: release.id,\n targets: urls,\n // The wire takes an ISO-8601 duration; `--ttl` keeps the `7d`/`12h`\n // spelling a person writes (create-deployment-request.yaml).\n ...(ttl === undefined ? {} : { ttl: ttl.iso }),\n });\n\n const previews = deployment.targets.map((target) => ({\n url: target.origin,\n expires_at: target.expires_at ?? null,\n }));\n return this.emit({\n status: \"ok\",\n data: {\n release_id: release.id,\n content_hash: release.content_hash,\n deployment_id: deployment.id,\n previews,\n release_env: `NEXT_PUBLIC_ZITADEL_RELEASE=${release.content_hash}`,\n },\n pretty: [\n `Previewed ${release.content_hash} on ${previews.length} URL${previews.length === 1 ? \"\" : \"s\"}`,\n ...previews.map((preview) =>\n preview.expires_at === null\n ? ` - ${preview.url}`\n : ` - ${preview.url} (until ${preview.expires_at})`,\n ),\n `NEXT_PUBLIC_ZITADEL_RELEASE=${release.content_hash}`,\n ].join(\"\\n\"),\n });\n }\n}\n\n/**\n * The project's primary origins, or none when the preview token may not read\n * the project (403): the server then decides alone what the token can deploy\n * to. A 401 is a token the server does not accept at all, which fails here\n * rather than after the whole bundle is built.\n */\nasync function primaryOrigins(client: ZitadelClient, projectId: string): Promise<string[]> {\n try {\n const origins = (await client.getProject(projectId)).origins ?? [];\n return origins.filter((entry) => entry.kind === \"primary\").map((entry) => entry.pattern);\n } catch (error) {\n if (error instanceof ApiError && error.status === 403) {\n return [];\n }\n throw error;\n }\n}\n\n/**\n * Whether this runs in a CI build: the providers the CLI already recognises\n * (`CI`, or a provider's own marker such as Jenkins' `JENKINS_URL`), plus the\n * builds that set neither: Cloudflare Pages, Azure Pipelines and AWS CodeBuild.\n */\nfunction runsInCi(env: NodeJS.ProcessEnv): boolean {\n return (\n ciProvider.value(env) !== undefined ||\n env.CF_PAGES === \"1\" ||\n envEnabled(env.TF_BUILD) ||\n envEnabled(env.CODEBUILD_BUILD_ID)\n );\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, type JsonEnvelope, nonBlankString, PreviewCommand } from \"../../lib/oclif\";\nimport { collectPages } from \"../../lib/oclif/crud/paging\";\nimport { renderList } from \"../../lib/oclif/crud/table\";\nimport { listData } from \"../../lib/oclif/envelope\";\nimport { shellArg } from \"../../lib/shell\";\n\n/** The columns `list` renders, in order. */\nconst COLUMNS = [\"url\", \"expires\", \"created\"] as const;\n\n/** A preview as the list endpoint returns it, narrowed to what the table reads. */\ntype PreviewRow = {\n origin: string;\n expires_at: string;\n created_at: string;\n};\n\n/**\n * `zitadel preview list` — show the project's live previews.\n *\n * Newest first: the preview URL, when it expires and when it was first\n * deployed. An expired or removed preview is not listed. Read with the preview\n * credential, so it works from a pull-request build. Like every list verb it\n * fetches one page and reports `next_page_token`; `--all` drains them,\n * `--limit` / `--page-token` walk them a page at a time.\n */\nexport default class PreviewList extends PreviewCommand {\n static override description = \"List the project's live previews, newest first.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> preview list\",\n \"<%= config.bin %> preview list --all\",\n \"<%= config.bin %> preview list --plain\",\n ];\n static override flags = {\n limit: Flags.integer({\n description: \"Page size (server default 20, max 100).\",\n min: 1,\n max: 100,\n }),\n \"page-token\": nonBlankString({\n description: \"Continue from a previous page's next_page_token.\",\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Fetch every page instead of one.\",\n exclusive: [\"page-token\"],\n }),\n plain: Flags.boolean({\n description:\n \"Tab-separated rows with no header, for piping. Implied when stdout is not a terminal.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(PreviewList);\n await this.toMeta(flags);\n const { client, projectId } = await this.connect();\n\n const request = (token?: string): Promise<unknown> =>\n client.listPreviews(projectId, {\n ...(flags.limit === undefined ? {} : { limit: flags.limit }),\n ...(token === undefined ? {} : { page_token: token }),\n });\n\n const { items, next } = await collectPages(request, {\n items: \"previews\",\n all: flags.all === true,\n token: flags[\"page-token\"],\n nextPageToken: \"next_page_token\",\n });\n const previews = items as PreviewRow[];\n\n const rows = previews.map((preview) => ({\n url: preview.origin,\n expires: preview.expires_at,\n created: preview.created_at,\n }));\n\n // A page token is only valid alongside the flags that issued it, so the\n // suggested next page repeats the whole invocation rather than a bare\n // token. `--all` already drained everything, so it suggests nothing.\n const nextCommand =\n next && flags.all !== true\n ? this.suggest(\n [\n \"preview list\",\n ...(flags.limit === undefined ? [] : [`--limit ${flags.limit}`]),\n `--page-token ${shellArg(next)}`,\n \"--json\",\n ].join(\" \"),\n )\n : undefined;\n\n const plain = flags.plain || !process.stdout.isTTY;\n return this.emit({\n status: \"ok\",\n data: listData(previews, {\n nextPageToken: next,\n nextCommands: nextCommand === undefined ? undefined : [nextCommand],\n }),\n pretty: renderList(COLUMNS, rows, {\n plain,\n singular: \"preview\",\n empty: \"No live previews.\",\n footer: next ? [`More available: --page-token ${shellArg(next)} (or --all)`] : [],\n }),\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, type JsonEnvelope, nonBlankArg, PreviewCommand } from \"../../lib/oclif\";\nimport { collectPages } from \"../../lib/oclif/crud/paging\";\nimport { dryRunResult } from \"../../lib/oclif/crud/shared\";\nimport { deletedData } from \"../../lib/oclif/envelope\";\nimport { shellArg } from \"../../lib/shell\";\nimport { Promptable } from \"../../lib/oclif/promptable\";\n\n/**\n * `zitadel preview rm <url>` — end a live preview before it expires.\n *\n * The URL stops being served at once; the deployments to it stay in the\n * history. Idempotent on the server, but destructive from the caller's point of\n * view, so it takes the same `--force`-or-confirm gate the resource deletes use.\n */\nexport default class PreviewRm extends Promptable(PreviewCommand) {\n static override description = \"Remove a live preview from the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> preview rm https://acme-git-sso-acmeinc.vercel.app\",\n \"<%= config.bin %> preview rm https://acme-git-sso-acmeinc.vercel.app --force\",\n ];\n static override args = {\n url: nonBlankArg({ required: true, description: \"The preview URL to remove.\" }),\n };\n static override flags = {\n // `--force` is per command, not global: here it permits a removal.\n force: Flags.boolean({\n char: \"f\",\n description:\n \"Remove the preview without the confirmation prompt. Required when non-interactive.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(PreviewRm);\n await this.toMeta(flags);\n const { dryRun } = this.meta;\n // An origin has no path, so a trailing slash is the same URL; sent as\n // typed it would remove nothing and still answer 204.\n const url = args.url.replace(/\\/+$/, \"\");\n\n // A dry run makes no request, so it answers before the connection — the\n // order the resource deletes use, which keeps `--dry-run --non-interactive`\n // usable.\n if (dryRun) {\n const preview = dryRunResult(\"remove\", \"preview\", url);\n return this.emit({ ...preview, pretty: `${preview.pretty} from the project` });\n }\n\n // Resolved before the confirmation, so the prompt is answered knowing\n // which project it removes from, and a missing token fails first.\n const { client, projectId } = await this.connect();\n\n // The server answers 204 whether or not the URL was live, so a typo would\n // otherwise read as a removal. Checked before asking, so nobody confirms\n // removing what is not there.\n const { items } = await collectPages(\n (token) => client.listPreviews(projectId, token === undefined ? {} : { page_token: token }),\n { items: \"previews\", all: true, nextPageToken: \"next_page_token\" },\n );\n if (!(items as Array<{ origin: string }>).some((preview) => preview.origin === url)) {\n return this.emit({\n status: \"skipped\",\n reason: \"not-live\",\n pretty: `${url} is not a live preview of the project; nothing was removed`,\n nextCommands: [this.suggest(\"preview list\")],\n });\n }\n\n const confirmed = await this.input({\n kind: \"confirm\",\n name: `remove ${url} from the project`,\n message: `Remove ${url} from the project?`,\n retry: this.suggest(`preview rm ${shellArg(url)} --force`),\n });\n if (!confirmed) {\n return this.emit({ status: \"skipped\", reason: \"remove-cancelled\" });\n }\n\n await client.removePreview(projectId, { origin: url });\n\n return this.emit({\n status: \"ok\",\n data: deletedData({ url }),\n pretty: `Stopped serving ${url}`,\n });\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { consola } from \"consola\";\n\nimport { stableStringify } from \"../json\";\n\n/**\n * The two reductions write-back needs from a resource. `normalize` is the\n * comparison form (so a reformatted file is not rewritten); `normalizeWrite` is\n * the form written to disk (transport noise stripped, meaning preserved).\n */\ntype Normalizer = {\n normalize?(data: object): object;\n normalizeWrite?(data: object): object;\n};\n\n/**\n * The hashing and write-back helpers scaffolding still needs after the sync\n * loop was removed: `setup-resources.ts` hashes a materialised resource and\n * writes the server's canonical body back to disk. These are the pure pieces of\n * the old loop — no diffing, no platform calls — kept because setup, not deploy,\n * is what writes a project's files.\n */\n\n/**\n * The content hash stored in `.zitadel/state.json`: key-order-insensitive (via\n * `stableStringify`) and computed on the syncer's normalized form, so\n * reordering keys or spelling out a meta-schema default does not read as an\n * edit.\n */\nexport function hashForState(syncer: Pick<Normalizer, \"normalize\">, data: object): string {\n const normalized = syncer.normalize?.(data) ?? data;\n return createHash(\"sha256\").update(stableStringify(normalized)).digest(\"hex\");\n}\n\n/**\n * Write a resource's canonical body back to its file when it materially\n * differs from what is on disk.\n *\n * The written form is the `normalizeWrite` form (strips pure transport noise\n * like the empty `audience` echo; for schemas the canonical body verbatim —\n * spelled-out x-* defaults must survive, or the next publish would drop them).\n * Equality is judged in the `normalize` comparison form, so the file is\n * rewritten only when it materially differs; hand-formatted files stay\n * untouched otherwise. Returns the state hash of the written form.\n */\nexport async function writeBackResource(\n cwd: string,\n relPath: string,\n syncer: Normalizer,\n canonical: object,\n): Promise<{ hash: string; changed: boolean }> {\n let writeBody = syncer.normalizeWrite?.(canonical) ?? canonical;\n const compare = (body: object) => stableStringify(syncer.normalize?.(body) ?? body);\n const absPath = join(cwd, relPath);\n let changed = true;\n try {\n const onDisk = JSON.parse(await readFile(absPath, \"utf8\")) as Record<string, unknown>;\n changed = compare(writeBody) !== compare(onDisk);\n // `$schema` is a local editor affordance (points at the dialect spec in\n // .zitadel/meta/); the server never echoes it, so a rewrite would drop it.\n // Carry the on-disk pointer over unless the canonical body has its own\n // (user-schema documents do).\n if (typeof onDisk.$schema === \"string\" && !(\"$schema\" in writeBody)) {\n writeBody = { ...writeBody, $schema: onDisk.$schema };\n }\n } catch (err) {\n consola.debug(`read ${relPath} for write-back failed:`, err);\n }\n if (changed) {\n await writeFile(absPath, `${stableStringify(writeBody)}\\n`);\n }\n return { hash: hashForState(syncer, writeBody), changed };\n}\n","import { mkdir } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { Args } from \"@oclif/core\";\n\nimport type { ZitadelClient } from \"../lib/api-client\";\nimport { ZitadelError } from \"../lib/errors\";\nimport { FLOWS_DIR } from \"../lib/flows\";\nimport { readJsonDirEntries } from \"../lib/json-dir\";\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { nextCommandsData } from \"../lib/oclif/envelope\";\nimport { DEPLOY_ARGS, listLiveDeployments, servesPrimary } from \"../lib/release\";\nimport { writeBackResource } from \"../lib/sync\";\nimport { SCHEMAS_DIR } from \"../lib/user-schema\";\nimport { reportWarning } from \"../lib/warnings\";\n\n/**\n * A resource kind `pull` can rebuild on disk from the revision a release pins:\n * it knows the kind's directory, how to read the pinned revision's body, and\n * how to read the handle off a body so an existing file for the same resource\n * is overwritten rather than duplicated.\n *\n * Only `schema` and `flow_definition` qualify (issue #541): their `revision_id`\n * is the id their read endpoint takes. A release also pins `branding` and `idp`,\n * but those pin a revision id the per-kind read endpoints do not accept yet, so\n * a release that carries them is pulled for the kinds it can and warns for the\n * rest — they gain a pull path when their reads are revision-addressable.\n */\ntype Reconstructable = {\n readonly dir: string;\n read(client: ZitadelClient, revisionId: string): Promise<Record<string, unknown>>;\n handleOf(body: Record<string, unknown>): string | undefined;\n};\n\n/** The release-pointer kinds `pull` can rebuild on disk. */\ntype ReconstructableKind = \"schema\" | \"flow_definition\";\n\nexport const RECONSTRUCTABLE: Readonly<Record<ReconstructableKind, Reconstructable>> = {\n schema: {\n dir: SCHEMAS_DIR,\n read: async (client, revisionId) => {\n const response = await client.getSchemaById(revisionId);\n return response.schema as Record<string, unknown>;\n },\n handleOf: (body) => (typeof body.objectType === \"string\" ? body.objectType : undefined),\n },\n flow_definition: {\n dir: FLOWS_DIR,\n read: async (client, revisionId) => {\n const response = await client.getFlowDefinition(revisionId);\n return response.flow_definition as Record<string, unknown>;\n },\n handleOf: (body) => (typeof body.name === \"string\" ? body.name : undefined),\n },\n};\n\n/** What a pull target names, or that it names nothing pull understands. */\nexport type PullTarget =\n | { readonly kind: \"latest\" }\n | { readonly kind: \"release\"; readonly id: string }\n | { readonly kind: \"deployment\"; readonly id: string }\n | { readonly kind: \"invalid\" };\n\n/**\n * Classify a pull target: `latest` (the live release), a release id (`rel_…`),\n * a deployment id (`dep_…`), or something pull does not understand. Kept pure\n * and separate from the lookups it drives so the shape is settled before any\n * server call.\n */\nexport function classifyTarget(target: string): PullTarget {\n if (target === \"latest\") {\n return { kind: \"latest\" };\n }\n if (target.startsWith(\"rel_\")) {\n return { kind: \"release\", id: target };\n }\n if (target.startsWith(\"dep_\")) {\n return { kind: \"deployment\", id: target };\n }\n return { kind: \"invalid\" };\n}\n\n/**\n * The file a handle already lives in under `dir`, or `<dir>/<handle>.json` when\n * none does. Setup writes a schema to `default-human-user.json` though its\n * object type is `human-user`, so matching by the body's handle — not by the\n * file name — keeps a pull overwriting that file instead of leaving a second\n * one for the same resource, which a deploy would then reject as two revisions\n * of one handle.\n */\nexport async function relPathForHandle(\n cwd: string,\n kind: Reconstructable,\n handle: string,\n): Promise<string> {\n const entries = await readJsonDirEntries(join(cwd, kind.dir));\n const match = entries.find((entry) => kind.handleOf(entry.body) === handle);\n return `${kind.dir}/${match ? match.name : `${handle}.json`}`;\n}\n\n/**\n * `zitadel pull [target]` — rebuild `.zitadel/` from the revisions a released\n * snapshot pins, the inverse of `deploy`.\n *\n * `deploy` builds an immutable release from the files on disk and makes it\n * live; `pull` goes the other way, writing each revision a release pins back\n * into `.zitadel/` so the working copy matches what a release shipped. The use\n * case is adoption: bring the live configuration (or a specific release) into\n * the git-tracked source of truth, then edit and `deploy` again.\n *\n * The target is the live release by default, a release id (`rel_…`), or a\n * deployment id (`dep_…`) whose release is pulled. A release references each\n * resource by handle, so files are written by handle and the next `deploy`\n * rebuilds the same release.\n */\nexport default class Pull extends EnvironmentCommand {\n static override description =\n \"Rebuild your .zitadel/ files from a release.\\n\\nWrites .zitadel/ from the revisions a released snapshot pins.\";\n static override group = CommandGroups.configuration;\n static override groupOrder = 2;\n static override examples = [\n \"<%= config.bin %> pull\",\n \"<%= config.bin %> pull rel_01KX3RG8A7F0N9WD3P2E4YM5C1\",\n \"<%= config.bin %> pull dep_01KX5N7C9D2E7F0N9WD3P2E4YM6\",\n ];\n static override args = {\n target: Args.string({\n required: false,\n default: \"latest\",\n description:\n \"What to pull: 'latest' (the live release), a release id (rel_…), or a deployment id (dep_…).\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(Pull);\n await this.toMeta(flags);\n const { cwd, dryRun } = this.meta;\n const { client, projectId } = await this.connect();\n\n const releaseId = await this.resolveReleaseId(client, projectId, args.target);\n const release = await client.getReleaseById(releaseId, { project_id: projectId });\n\n const pulled: { kind: string; handle: string; path: string }[] = [];\n const skipped: { kind: string; handle: string }[] = [];\n for (const pointer of release.pointers) {\n // A release may pin kinds pull cannot rebuild yet (branding, idp), so the\n // lookup is over the broad pointer kind and may miss.\n const kind = (RECONSTRUCTABLE as Record<string, Reconstructable | undefined>)[pointer.kind];\n if (kind === undefined) {\n skipped.push({ kind: pointer.kind, handle: pointer.handle });\n continue;\n }\n const body = await kind.read(client, pointer.revision_id);\n const relPath = await relPathForHandle(cwd, kind, pointer.handle);\n if (!dryRun) {\n await mkdir(dirname(join(cwd, relPath)), { recursive: true });\n // The read body is the server's canonical form; write it verbatim\n // (carrying over any local `$schema` editor pointer) with no\n // normalizer, so what lands is exactly what the release pinned.\n await writeBackResource(cwd, relPath, {}, body);\n }\n pulled.push({ kind: pointer.kind, handle: pointer.handle, path: relPath });\n }\n\n for (const resource of skipped) {\n reportSkipped(resource);\n }\n\n const nextCommands = dryRun ? [] : [this.suggest(DEPLOY_ARGS)];\n const summary = pulled.map((entry) => entry.path).join(\"\\n\");\n return this.emit({\n status: \"ok\",\n data: {\n release_id: release.id,\n pulled,\n skipped,\n ...(dryRun ? { dry_run: true } : {}),\n ...nextCommandsData(nextCommands),\n },\n pretty: dryRun\n ? `Would write ${pulled.length} file${pulled.length === 1 ? \"\" : \"s\"} from ${release.id} (dry run).\\n${summary}`\n : `Pulled ${pulled.length} file${pulled.length === 1 ? \"\" : \"s\"} from ${release.id}.\\n${summary}`,\n });\n }\n\n /**\n * The release a target names: `rel_…` as given, the release a `dep_…`\n * deployment made live, or — for `latest` — the release the newest primary\n * deployment serves. A preview deployment never serves a primary origin, so\n * `latest` is the project's live configuration, not a pull-request preview.\n */\n private async resolveReleaseId(\n client: ZitadelClient,\n projectId: string,\n target: string,\n ): Promise<string> {\n const classified = classifyTarget(target);\n if (classified.kind === \"release\") {\n return classified.id;\n }\n if (classified.kind === \"deployment\") {\n const deployment = (await client.getDeploymentById(classified.id, {\n project_id: projectId,\n })) as { release_id: string };\n return deployment.release_id;\n }\n if (classified.kind === \"latest\") {\n const live = await listLiveDeployments(client, projectId);\n const deployment = live.find(servesPrimary);\n if (deployment === undefined) {\n throw new ZitadelError(\"E_NOT_FOUND\", \"Nothing is deployed to a primary origin yet.\", {\n hint: `Deploy first with \\`zitadel ${DEPLOY_ARGS}${this.environmentSelector()}\\`, then pull.`,\n });\n }\n return deployment.release_id;\n }\n throw new ZitadelError(\"E_VALIDATION\", `Don't know how to pull \"${target}\".`, {\n hint: \"Pass 'latest', a release id (rel_…), or a deployment id (dep_…).\",\n });\n }\n}\n\n/**\n * Warn that a release pins a resource `pull` cannot rebuild on disk yet. A\n * reported warning rides the envelope (BaseCommand merges them), so a `--json`\n * caller sees it too.\n */\nfunction reportSkipped(resource: { kind: string; handle: string }): void {\n reportWarning(\n `The release pins ${resource.kind} \"${resource.handle}\", which pull cannot rebuild locally yet; reconcile it by hand.`,\n );\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport {\n buildBundle,\n createReleaseFromBundle,\n headSha,\n runSteps,\n type StepContext,\n validateStep,\n worktreeIsDirty,\n} from \"../../lib/release\";\nimport { nextCommandsData } from \"../../lib/oclif/envelope\";\nimport { ZitadelError } from \"../../lib/errors\";\n\n/**\n * `zitadel release create` — build a release from `.zitadel/` and post it,\n * without deploying it.\n *\n * The same bundle `deploy` assembles, validated the same way, but it stops at\n * the release: nothing is made live. Use it to pin a release a pipeline deploys\n * later, or to read back its content digest. Re-running on unchanged content\n * returns the release that already carries it.\n */\nexport default class ReleaseCreate extends EnvironmentCommand {\n static override description = \"Build a release from .zitadel/ without deploying it.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> release create\",\n \"<%= config.bin %> release create -m 'add phone_number to human-user'\",\n ];\n static override flags = {\n message: Flags.string({\n char: \"m\",\n description: \"A short summary of what this release changes.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(ReleaseCreate);\n await this.toMeta(flags);\n const { cwd, env, dryRun, isTTY } = this.meta;\n const json = this.jsonEnabled();\n\n const { client, projectId } = await this.connect();\n const { bundle, resourceCount, brandingSources, idpFiles, policyFiles } =\n await buildBundle(cwd);\n\n const ctx: StepContext = {\n cwd,\n client,\n projectId,\n env,\n mode: \"deploy\",\n dryRun,\n json,\n color: !json && isTTY && flags.color !== false && !process.env.NO_COLOR,\n bundle,\n brandingSources,\n idpFiles,\n policyFiles,\n suggest: (args) => this.suggest(args),\n };\n // The IdP connections sync before the build, as `deploy` does: a release\n // names its connections by slug, and the server refuses to build one\n // that names a slug the project does not hold yet.\n await runSteps([validateStep], ctx);\n\n // `release create` carries the same no-mutation promise every command does\n // under `--dry-run`: validate the bundle the same way, then stop before the\n // release is posted so nothing is written server-side.\n if (dryRun) {\n return this.emit({\n status: \"ok\",\n data: { dry_run: true, resources: resourceCount },\n pretty: `Validated ${resourceCount} resource${resourceCount === 1 ? \"\" : \"s\"}. No release was created (dry run).`,\n });\n }\n\n const release = await createReleaseFromBundle(client, projectId, bundle, {\n message: flags.message,\n gitSha: await headSha(cwd),\n gitDirty: await worktreeIsDirty(cwd),\n });\n // Building dedupes on content, revoked releases included: the same tree\n // answers with the revoked release, which can never be deployed.\n if (release.revoked_at) {\n throw new ZitadelError(\n \"E_CONFLICT\",\n `This content was already released as ${release.id}, which is revoked`,\n {\n hint: \"A revoked release can never be served again. Change the configuration so it builds a new release.\",\n details: { release_id: release.id, content_hash: release.content_hash },\n },\n );\n }\n\n return this.emit({\n status: \"ok\",\n data: {\n release_id: release.id,\n content_hash: release.content_hash,\n resources: resourceCount,\n ...nextCommandsData([this.suggest(`deployment create --release ${release.id}`)]),\n },\n pretty: `Created ${release.id} (${release.content_hash})`,\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope, nonBlankArg } from \"../../lib/oclif\";\nimport { mutatedData } from \"../../lib/oclif/envelope\";\nimport { revokeRelease } from \"../../lib/release\";\nimport { Promptable } from \"../../lib/oclif/promptable\";\n\n/**\n * `zitadel release revoke <release_id>` — mark a release so its content is\n * never served again.\n *\n * A release an origin still serves cannot be revoked; deploy another release\n * there or roll it back first. Revoking is idempotent and cannot be undone, so\n * it takes the same `--force`-or-confirm gate the destructive commands use.\n */\nexport default class ReleaseRevoke extends Promptable(EnvironmentCommand) {\n static override description = \"Revoke a release so its content is never served again.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> release revoke rel_01KX3RG8A7F0N9WD3P2E4YM5C1\",\n \"<%= config.bin %> release revoke rel_01KX3RG8A7F0N9WD3P2E4YM5C1 --force\",\n ];\n static override args = {\n release_id: nonBlankArg({ required: true, description: \"The release to revoke.\" }),\n };\n static override flags = {\n force: Flags.boolean({\n char: \"f\",\n description: \"Revoke without the confirmation prompt. Required when non-interactive.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(ReleaseRevoke);\n await this.toMeta(flags);\n const { dryRun } = this.meta;\n const releaseId = args.release_id;\n\n // A dry run makes no request, so it answers before the connection and\n // before the destructive-confirm gate: revoking cannot be undone, and a\n // dry run must revoke nothing and so needs no confirmation.\n if (dryRun) {\n return this.emit({\n status: \"ok\",\n data: { dry_run: true, release_id: releaseId },\n pretty: `Would revoke ${releaseId}. Nothing was revoked (dry run).`,\n });\n }\n\n const confirmed = await this.input({\n kind: \"confirm\",\n name: `revoke ${releaseId}`,\n message: `Revoke ${releaseId}? Its content can never be served again.`,\n retry: this.suggest(`release revoke ${releaseId} --force`),\n });\n if (!confirmed) {\n return this.emit({ status: \"skipped\", reason: \"revoke-cancelled\" });\n }\n\n const { client, projectId } = await this.connect();\n\n const release = await revokeRelease(client, projectId, releaseId);\n\n return this.emit({\n status: \"ok\",\n // The lifecycle-mutation shape every revoke answers with, plus when.\n data: {\n ...mutatedData({ release_id: release.id }, \"revoked\"),\n revoked_at: release.revoked_at,\n },\n pretty: `Revoked ${release.id}`,\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n localContainerName,\n readRuntimeMetadata,\n} from \"../lib/local-server/runtime\";\nimport { LocalServer } from \"../lib/local-server/server\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\nimport { nextCommandsData } from \"../lib/oclif/envelope\";\nimport { Promptable } from \"../lib/oclif/promptable\";\n\nexport default class Reset extends Promptable(BaseCommand) {\n static override description = \"Delete the local Zitadel server runtime and data.\";\n static override group = CommandGroups.localDevelopment;\n static override groupOrder = 4;\n static override flags = {\n force: Flags.boolean({\n char: \"f\",\n description: \"Delete the local runtime and its data without the confirmation prompt.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Reset);\n const cwd = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n const runtime = await readRuntimeMetadata(cwd);\n await this.toMeta(flags, {\n resolveServer: false,\n source: runtime?.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n\n const containerName =\n runtime?.backend === \"docker\" ? runtime.container_name : localContainerName(this.meta.cwd);\n if (this.meta.dryRun) {\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local Zitadel server runtime reset plan.\",\n runtime: {\n backend: runtime?.backend ?? \"missing\",\n ...(runtime?.backend === \"binary\"\n ? { pid: runtime.pid, log_path: runtime.log_path }\n : { container_name: containerName }),\n data_deleted: true,\n },\n ...nextCommandsData([this.suggestUnscoped(\"reset --force\")]),\n },\n });\n }\n\n const confirmed = await this.input({\n kind: \"confirm\",\n name: \"delete the local runtime and its data\",\n message: \"Delete the local Zitadel runtime and .zitadel/local/nextgen-data?\",\n retry: this.suggestUnscoped(\"reset --force\"),\n });\n if (!confirmed) {\n return this.emit({ status: \"skipped\", reason: \"reset-cancelled\" });\n }\n\n await LocalServer.at(this.meta.cwd, { cliVersion: this.meta.cliVersion }).reset();\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local Zitadel server runtime reset.\",\n runtime: {\n backend: runtime?.backend ?? \"missing\",\n ...(runtime?.backend === \"binary\"\n ? { pid: runtime.pid, log_path: runtime.log_path }\n : { container_name: containerName }),\n data_deleted: true,\n },\n },\n });\n }\n}\n","import type { Command, Interfaces } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../../../errors\";\nimport { EnvironmentCommand } from \"../../environment-command\";\nimport type { CommandResult, GlobalOptions, JsonEnvelope } from \"../../types\";\nimport type { Json, ResourceCommandOptions, ResourceDescriptor } from \"../types\";\nimport { Promptable } from \"../../promptable\";\n\n/** Everything an operation needs to know about the resource it serves. */\nexport type OperationDefinition<Ctx, Spec> = Readonly<{\n topic: string;\n resource: ResourceDescriptor<Ctx>;\n spec: Spec;\n options: ResourceCommandOptions<Ctx>;\n}>;\n\n/** The oclif statics an operation derives from its definition. */\nexport type OperationStatics = Readonly<{\n description: string;\n examples: readonly string[];\n flags: Interfaces.FlagInput;\n args: Interfaces.ArgInput;\n}>;\n\n/** Parsed flags and args, untyped: operations narrow what they read. */\nexport type OperationInput = Readonly<{ flags: Json; args: Json }>;\n\n/**\n * The static shape every operation class has: the {@link ResourceCommand}\n * statics, a concrete constructor oclif can instantiate, and a `describe`\n * that turns a definition into the command's statics.\n */\nexport type OperationClass<Ctx, Spec> = typeof ResourceCommand<Ctx, Spec> & {\n new (...args: ConstructorParameters<typeof Command>): ResourceCommand<Ctx, Spec>;\n describe(definition: OperationDefinition<Ctx, Spec>): OperationStatics;\n};\n\n/**\n * Base of every generated command. Owns the lifecycle all operations share —\n * parse, resolve meta, run, emit — so a concrete operation only implements\n * {@link execute} and its static {@link OperationClass.describe}. The\n * definition is bound onto a subclass by {@link bindOperation}; the operation\n * classes themselves are never registered with oclif directly.\n */\nexport class ResourceCommand<Ctx, Spec> extends Promptable(EnvironmentCommand) {\n protected get definition(): OperationDefinition<Ctx, Spec> {\n const definition = definitionOf(this.constructor as typeof Command);\n if (!definition) {\n throw new ZitadelError(\n \"E_NOT_IMPLEMENTED\",\n `${this.id ?? \"operation\"} was not built by bindOperation`,\n );\n }\n return definition as OperationDefinition<Ctx, Spec>;\n }\n\n async run(): Promise<JsonEnvelope> {\n const parsed = await this.parse(this.constructor as typeof ResourceCommand);\n const meta = await this.toMeta(parsed.flags);\n return this.emit(\n await this.execute({ flags: parsed.flags as Json, args: parsed.args as Json }, meta),\n );\n }\n\n /** Open the platform connection; deferred so `--dry-run` never connects. */\n protected context(): Promise<Ctx> {\n return this.definition.options.connect(() => this.connect());\n }\n\n /**\n * The operation's work. Every concrete operation overrides this; the base\n * implementation exists only so {@link bindOperation} can subclass through\n * the generic static type, which TypeScript cannot do for an abstract member.\n */\n protected execute(_input: OperationInput, _meta: GlobalOptions): Promise<CommandResult> {\n return Promise.reject(\n new ZitadelError(\"E_NOT_IMPLEMENTED\", `${this.id ?? \"operation\"} has no execute`),\n );\n }\n}\n\n/**\n * Produce the oclif command class for one operation on one resource: a\n * subclass carrying the definition and the statics `describe` derives from it.\n */\nexport const bindOperation = <Ctx, Spec>(\n operation: OperationClass<Ctx, Spec>,\n definition: OperationDefinition<Ctx, Spec>,\n): typeof Command => {\n const statics = operation.describe(definition);\n const bound = class extends operation {\n static override description = statics.description;\n static override examples = [...statics.examples];\n static override flags = statics.flags;\n static override args = statics.args;\n static override group = definition.resource.group;\n static override groupOrder = definition.resource.groupOrder;\n };\n // Beside the class, never on it: oclif copies a command's own statics into\n // `commands --json` and the published manifest, and a registry entry (with a\n // serialized request schema inside it) is implementation detail that would\n // dwarf the metadata an agent actually reads.\n definitions.set(bound, definition as OperationDefinition<unknown, unknown>);\n return bound;\n};\n\n/** Definitions held beside their command classes, keyed weakly so they are collectable. */\nconst definitions = new WeakMap<object, OperationDefinition<unknown, unknown>>();\n\n/** The definition {@link bindOperation} recorded for a command class, if any. */\nexport const definitionOf = (\n command: typeof Command,\n): OperationDefinition<unknown, unknown> | undefined => definitions.get(command);\n","import { Flags } from \"@oclif/core\";\n\nimport { deletedData, mutatedData } from \"../../envelope\";\nimport type { CommandResult, GlobalOptions } from \"../../types\";\nimport { article, capitalize, dryRunResult, idArg, idValue } from \"../shared\";\n\n/** Past tense reported beside the id, per verb. */\nconst PAST: Readonly<Record<string, string>> = {\n delete: \"deleted\",\n revoke: \"revoked\",\n deactivate: \"deactivated\",\n};\nimport type { DeleteSpec } from \"../types\";\nimport {\n type OperationDefinition,\n type OperationInput,\n type OperationStatics,\n ResourceCommand,\n} from \"./command\";\n\n/**\n * `<topic> delete <id>`, or the lifecycle verb the resource declares\n * (`revoke`, `deactivate`): guarded like `reset` — `--force` in\n * non-interactive mode, a confirm prompt otherwise — and honours `--dry-run`.\n */\nexport class DeleteOperation<Ctx> extends ResourceCommand<Ctx, DeleteSpec<Ctx>> {\n static describe<Ctx>({\n topic,\n resource,\n spec,\n options,\n }: OperationDefinition<Ctx, DeleteSpec<Ctx>>): OperationStatics {\n const verb = spec.verb ?? \"delete\";\n return {\n description: `${capitalize(verb)} ${article(resource.singular)} ${resource.singular} by id.`,\n examples: [`<%= config.bin %> ${topic} ${verb} <id> --force --json`],\n // `--force` is per command, not global: here it permits a deletion,\n // where on `setup` the same name permits overwriting a file.\n flags: {\n force: Flags.boolean({\n char: \"f\",\n description: `${capitalize(verb)} the ${resource.singular} without the confirmation prompt. Required when non-interactive.`,\n }),\n ...options.flags,\n },\n args: idArg(resource),\n };\n }\n\n protected override async execute(\n { args }: OperationInput,\n meta: GlobalOptions,\n ): Promise<CommandResult> {\n const { topic, resource, spec } = this.definition;\n const verb = spec.verb ?? \"delete\";\n const past = spec.outcome ?? PAST[verb] ?? \"deleted\";\n const id = idValue(resource, args);\n\n // A dry run makes no request, so it answers before the guard — the order\n // `reset` uses, and it keeps `--dry-run --non-interactive` usable.\n if (meta.dryRun) {\n return dryRunResult(verb, topic, id);\n }\n\n const confirmed = await this.input({\n kind: \"confirm\",\n name: `${verb} ${resource.singular} ${id}`,\n message: `${capitalize(verb)} ${resource.singular} ${id}?`,\n retry: this.suggest(`${topic} ${verb} ${id} --force`),\n });\n if (!confirmed) {\n return { status: \"skipped\", reason: `${verb}-cancelled` };\n }\n await spec.call(await this.context(), id);\n return {\n status: \"ok\",\n data: past === \"deleted\" ? deletedData({ id }) : mutatedData({ id }, past),\n pretty: `${capitalize(past)} ${resource.singular} ${id}`,\n };\n }\n}\n","import type { Json, QueryParts, WireConventions } from \"./types\";\n\n/**\n * The wire vocabulary this platform uses: cursor pagination named as\n * [ADR 027](../../../../../../docs/adrs/027-cursor-based-pagination.md)\n * defines it, and the structured-query body shape of\n * [ADR 031](../../../../../../docs/adrs/031-openapi-querying.md).\n *\n * These live behind {@link WireConventions} rather than inline in the list\n * operation so the factory stays honest about what it assumes: a platform\n * whose cursor is `next_cursor`, or whose filters are a map rather than a\n * list, overrides the vocabulary instead of forking the factory.\n */\nexport const DEFAULT_WIRE: WireConventions = {\n limit: \"limit\",\n pageToken: \"page_token\",\n nextPageToken: \"next_page_token\",\n query: ({ paging, filters, sorting }: QueryParts): Json => ({\n ...paging,\n ...(sorting && { sorting }),\n ...(filters.length > 0 && { filter: filters }),\n }),\n};\n\n/** The caller's overrides over {@link DEFAULT_WIRE}. */\nexport const wireOf = (overrides: Partial<WireConventions> | undefined): WireConventions => ({\n ...DEFAULT_WIRE,\n ...overrides,\n});\n","import { ZitadelError } from \"../../errors\";\nimport type { FilterField } from \"./types\";\n\n/**\n * The `--filter` / `--sort` grammar every list shares.\n *\n * A field's own declaration decides what it accepts, so the grammar is the\n * same whether the request goes out as a structured query body or as flat\n * query parameters. Anything the endpoint cannot honour is refused here,\n * naming the field and what it does accept, rather than becoming a 400.\n */\n\nexport type ParsedFilter = Readonly<{ field: FilterField; operation: string; value: string }>;\n\n/** `field=operation:value`, or `field=value` for `equals`. */\nexport const parseFilter = (raw: string, filters: readonly FilterField[]): ParsedFilter => {\n const names = filters.map((filter) => filter.field);\n const [name, ...rest] = raw.split(\"=\");\n if (!name || rest.length === 0) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid --filter \"${raw}\"`, {\n hint: `Use field=operation:value, e.g. ${names[0]}=${filters[0]?.operations[0]}:<value>.`,\n });\n }\n const field = filters.find((filter) => filter.field === name);\n if (!field) {\n const near = names.find((candidate) => within(name, candidate, 2));\n throw new ZitadelError(\"E_VALIDATION\", `Unknown filter field \"${name}\"`, {\n hint: `${near ? `Did you mean ${near}? ` : \"\"}Filterable fields: ${names.join(\", \")}.`,\n details: { field: name, ...(near ? { suggestion: near } : {}), fields: names },\n });\n }\n\n const expression = rest.join(\"=\");\n const [candidate = \"\", ...rawValue] = expression.split(\":\");\n const operations = field.operations;\n if (operations.includes(candidate) && rawValue.length > 0) {\n return checked({ field, operation: candidate, value: rawValue.join(\":\") });\n }\n // Everything else is an `equals` whose value happens to contain a colon (a\n // schema URL, a timestamp). A near-miss of a real operation is a typo, not a\n // literal: silently filtering for the string `contians:active` would answer\n // a question nobody asked.\n if (rawValue.length > 0) {\n const typo = operations.find((operation) => within(candidate, operation, 2));\n if (typo) {\n throw new ZitadelError(\"E_VALIDATION\", `Unknown filter operation \"${candidate}\"`, {\n hint: `Did you mean ${typo}? For a literal value containing a colon, say so explicitly: ${name}=equals:${expression}.`,\n details: { operation: candidate, suggestion: typo, operations: [...operations] },\n });\n }\n // A real operation the endpoint does not offer for this field is the\n // interesting case: the word is spelled right, so the caller believes it\n // works. Say which field is the limitation, not just that it failed.\n if (!operations.includes(candidate) && KNOWN_OPERATIONS.has(candidate)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Filter field \"${name}\" does not support the ${candidate} operation`,\n {\n hint: `${name} accepts: ${operations.join(\", \")}.`,\n details: { field: name, operation: candidate, operations: [...operations] },\n },\n );\n }\n }\n if (!operations.includes(\"equals\")) {\n throw new ZitadelError(\"E_VALIDATION\", `Filter field \"${name}\" needs an explicit operation`, {\n hint: `${name} accepts: ${operations.join(\", \")}.`,\n details: { field: name, operations: [...operations] },\n });\n }\n return checked({ field, operation: \"equals\", value: expression });\n};\n\n/**\n * Operation names the CLI recognises as operations at all, so a value that\n * merely looks like `something:else` is not mistaken for one.\n */\nconst KNOWN_OPERATIONS = new Set([\n \"equals\",\n \"not_equals\",\n \"contains\",\n \"not_contains\",\n \"less_than\",\n \"less_than_or_equal\",\n \"greater_than\",\n \"greater_than_or_equal\",\n \"array_contains\",\n]);\n\n/** Reject a value outside a field's closed set before any request is made. */\nconst checked = (parsed: ParsedFilter): ParsedFilter => {\n const { values } = parsed.field;\n if (values && !values.includes(parsed.value)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Invalid value \"${parsed.value}\" for filter field \"${parsed.field.field}\"`,\n {\n hint: `Accepted values: ${values.join(\", \")}.`,\n details: { field: parsed.field.field, value: parsed.value, values: [...values] },\n },\n );\n }\n return parsed;\n};\n\n/** `field:direction`; direction defaults to `asc`. */\nexport const parseSort = (\n raw: string,\n fields: readonly string[],\n): Readonly<{ field: string; direction: string }> => {\n // Exactly a field and a direction: a trailing segment means the caller meant\n // something the grammar cannot express, and silently sorting anyway hides it.\n const [field, direction = \"asc\", ...extra] = raw.split(\":\");\n if (!field || extra.length > 0) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid --sort \"${raw}\"`, {\n hint: `Use field:direction, e.g. ${fields[0]}:desc.`,\n });\n }\n if (!fields.includes(field)) {\n const near = fields.find((candidate) => within(field, candidate, 2));\n throw new ZitadelError(\"E_VALIDATION\", `Unknown sort field \"${field}\"`, {\n hint: `${near ? `Did you mean ${near}? ` : \"\"}Sortable fields: ${fields.join(\", \")}.`,\n details: { field, ...(near ? { suggestion: near } : {}), fields: [...fields] },\n });\n }\n if (direction !== \"asc\" && direction !== \"desc\") {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid sort direction \"${direction}\"`, {\n hint: \"Use asc or desc.\",\n });\n }\n return { field, direction };\n};\n\n/** Whether two words are within `max` single-character edits of each other. */\nconst within = (a: string, b: string, max: number): boolean => {\n if (a === b || Math.abs(a.length - b.length) > max) {\n return a === b;\n }\n let previous = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 1; i <= a.length; i += 1) {\n const current = [i];\n for (let j = 1; j <= b.length; j += 1) {\n current[j] = Math.min(\n (current[j - 1] ?? 0) + 1,\n (previous[j] ?? 0) + 1,\n (previous[j - 1] ?? 0) + (a[i - 1] === b[j - 1] ? 0 : 1),\n );\n }\n previous = current;\n }\n return (previous[b.length] ?? max + 1) <= max;\n};\n","import { isObject } from \"../../json\";\nimport type { Schema } from \"./types\";\nimport { unwrap, type ZodLike } from \"./zod\";\n\n/**\n * The dot-paths a record can carry, read from the generated response schema\n * rather than from whatever a given page happened to return. Sampling the\n * response would make `--fields` valid or invalid depending on how many records\n * came back — the same arguments failing on a full page and passing on an empty\n * one — so the shape decides instead.\n *\n * An open record (a user's `attributes`, whose keys come from the project's\n * user schema and not from the API spec) cannot be enumerated, so it is\n * reported as a prefix: anything beneath it is accepted.\n */\nexport type FieldPaths = Readonly<{\n /** Exact paths, such as `id` or `metadata.status`. */\n known: ReadonlySet<string>;\n /** Prefixes below which any path is legal, such as `attributes`. */\n open: readonly string[];\n}>;\n\nconst shapeOf = (schema: ZodLike | undefined): Record<string, ZodLike> | undefined => {\n const type = unwrap(schema);\n if (type?.shape) {\n return type.shape;\n }\n // An intersection (a shared envelope `and` a per-variant payload, which is how\n // the event union is generated) contributes both halves.\n if (type?.def?.left || type?.def?.right) {\n const merged = { ...(shapeOf(type.def?.left) ?? {}), ...(shapeOf(type.def?.right) ?? {}) };\n return Object.keys(merged).length > 0 ? merged : undefined;\n }\n // A union of variants (the event union) contributes every variant's fields:\n // any of them can arrive, so any of them is a legal path.\n const options = type?.def?.options;\n if (!options) {\n return undefined;\n }\n const merged = Object.assign({}, ...options.map((option) => shapeOf(option) ?? {})) as Record<\n string,\n ZodLike\n >;\n return Object.keys(merged).length > 0 ? merged : undefined;\n};\n\n/**\n * The element schema of a list response's item array. `key` names the property\n * holding the array; without one the response schema is the array itself.\n */\nexport const itemSchemaOf = (response: Schema | undefined, key?: string): Schema | undefined => {\n const array =\n key === undefined ? unwrap(response as ZodLike) : unwrap(shapeOf(response as ZodLike)?.[key]);\n return (unwrap(array?.def?.element) as Schema | undefined) ?? undefined;\n};\n\n/** Walk a record schema into the paths a caller may name. */\nexport const fieldPaths = (schema: Schema | undefined, depth = 3): FieldPaths | undefined => {\n const shape = shapeOf(schema as ZodLike);\n if (!shape) {\n return undefined;\n }\n const known = new Set<string>();\n const open: string[] = [];\n const walk = (current: Record<string, ZodLike>, prefix: string, left: number): void => {\n for (const [key, field] of Object.entries(current)) {\n const path = prefix ? `${prefix}.${key}` : key;\n known.add(path);\n const type = unwrap(field);\n if (type?.def?.type === \"record\") {\n open.push(path);\n continue;\n }\n const nested = left > 1 ? shapeOf(type) : undefined;\n if (nested) {\n walk(nested, path, left - 1);\n }\n }\n };\n walk(shape, \"\", depth);\n return { known, open };\n};\n\n/** Whether a path is legal for records of this shape. */\nexport const allows = (paths: FieldPaths, path: string): boolean =>\n paths.known.has(path) || paths.open.some((prefix) => path.startsWith(`${prefix}.`));\n\n/** The paths worth showing a caller who named one that does not exist. */\nexport const suggestable = (paths: FieldPaths): readonly string[] =>\n [...paths.known, ...paths.open.map((prefix) => `${prefix}.<key>`)].sort();\n\n/** Fallback when no schema is available: the paths these records actually carry. */\nexport const observedPaths = (items: readonly unknown[]): FieldPaths => {\n const known = new Set<string>();\n for (const item of items) {\n if (!isObject(item)) {\n continue;\n }\n for (const [key, value] of Object.entries(item)) {\n known.add(key);\n if (isObject(value)) {\n for (const nested of Object.keys(value)) {\n known.add(`${key}.${nested}`);\n }\n }\n }\n }\n return { known, open: [] };\n};\n","import { ZitadelError } from \"../../errors\";\nimport { allows, type FieldPaths, observedPaths, suggestable } from \"./paths\";\n\n/**\n * Which fields a human rendering shows: the resource's own by default, or the\n * caller's `--fields`. A path the record's shape cannot carry is refused with\n * the paths it can, so a typo is a local error with the answer attached rather\n * than a column of blanks — and the verdict comes from the shape, so it does\n * not change with how many records a page happened to return.\n */\nexport const chosenColumns = (\n fields: unknown,\n fallback: readonly string[],\n items: readonly unknown[],\n shape?: FieldPaths,\n): readonly string[] => {\n if (typeof fields !== \"string\") {\n return fallback;\n }\n const chosen = fields\n .split(\",\")\n .map((field) => field.trim())\n .filter(Boolean);\n if (chosen.length === 0) {\n throw new ZitadelError(\"E_VALIDATION\", \"--fields needs at least one column\", {\n hint: `Comma-separated dot-paths, e.g. --fields ${fallback.join(\",\")}.`,\n });\n }\n // The schema is authoritative; without one, fall back to the records in hand,\n // which can only judge when there are some.\n const paths = shape ?? (items.length > 0 ? observedPaths(items) : undefined);\n if (!paths) {\n return chosen;\n }\n const missing = chosen.filter((field) => !allows(paths, field));\n if (missing.length > 0) {\n const available = suggestable(paths);\n throw new ZitadelError(\n \"E_VALIDATION\",\n `--fields has no such ${missing.length === 1 ? \"column\" : \"columns\"}: ${missing.join(\", \")}`,\n { hint: `Available: ${available.join(\", \")}.`, details: { missing, available } },\n );\n }\n return chosen;\n};\n","import { spinner } from \"@clack/prompts\";\nimport { Flags } from \"@oclif/core\";\n\nimport { nonBlankString } from \"../../flags\";\n\nimport type { CommandResult, GlobalOptions } from \"../../types\";\nimport { collectPages } from \"../paging\";\nimport { wireOf } from \"../wire\";\nimport { type ParsedFilter, parseFilter, parseSort } from \"../query\";\nimport { parseOrThrow } from \"../shared\";\nimport { chosenColumns } from \"../columns\";\nimport { shellOption } from \"../../../shell\";\nimport { fieldPaths, itemSchemaOf } from \"../paths\";\nimport { renderRows, renderTable } from \"../table\";\nimport type { Json, ListSpec } from \"../types\";\nimport {\n type OperationDefinition,\n type OperationInput,\n type OperationStatics,\n ResourceCommand,\n} from \"./command\";\nimport { nextCommandsData } from \"../../envelope\";\n\n/**\n * `<topic> list`: one page by default, `--all` to drain, `--filter` / `--sort`\n * for query-backed lists or one flag per parameter for GET-backed ones.\n * Emits `{ items, count, next_page_token }` and a column table for humans.\n */\nexport class ListOperation<Ctx> extends ResourceCommand<Ctx, ListSpec<Ctx>> {\n static describe<Ctx>({\n topic,\n spec,\n options,\n }: OperationDefinition<Ctx, ListSpec<Ctx>>): OperationStatics {\n const paged = spec.paged !== false;\n const paging = {\n limit: Flags.integer({\n description: \"Page size (server default 20, max 100).\",\n min: 1,\n max: 100,\n }),\n \"page-token\": nonBlankString({\n description: \"Continue from a previous page's next_page_token.\",\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Fetch every page instead of one.\",\n exclusive: [\"page-token\"],\n }),\n };\n const presentation = {\n fields: nonBlankString({\n description:\n \"Columns to show, comma-separated dot-paths (e.g. id,attributes.email). Defaults to the resource's own columns; `--json` is unaffected.\",\n }),\n plain: Flags.boolean({\n description:\n \"Tab-separated rows with no header, for piping. Implied when stdout is not a terminal.\",\n }),\n };\n const filters = spec.filters ?? [];\n const sorts = spec.sorts ?? [];\n // One `--filter` for every list. The help names each field with the\n // operations that field accepts, so a grammar the endpoint cannot honour\n // is visible before it is typed rather than after it fails.\n const specific = {\n ...(filters.length > 0\n ? {\n filter: nonBlankString({\n multiple: true,\n description: `Filter as field=operation:value (operation defaults to equals). Fields: ${filters\n .map(\n (field) =>\n `${field.field} (${field.operations.join(\"|\")}${field.values ? `; values ${field.values.join(\"|\")}` : \"\"}${field.combine === \"or\" ? \"; repeats widen\" : \"\"})`,\n )\n .join(\", \")}.`,\n }),\n }\n : {}),\n ...(sorts.length > 0\n ? {\n sort: nonBlankString({\n description: `Sort as field:direction (asc|desc). Fields: ${sorts.join(\", \")}.`,\n }),\n }\n : {}),\n };\n return {\n description: `List ${topic}.${spec.drains === true ? \" Fetches every page unless --limit or --page-token asks for one.\" : \"\"}`,\n examples: [\n `<%= config.bin %> ${topic} list --json`,\n ...(paged && spec.drains !== true ? [`<%= config.bin %> ${topic} list --all --json`] : []),\n ...(filters[0]\n ? [\n `<%= config.bin %> ${topic} list --filter ${filters[0].field}=${filters[0].operations[0]}:<value>${sorts[0] ? ` --sort ${sorts[0]}:desc` : \"\"}`,\n ]\n : []),\n ],\n flags: { ...(paged ? paging : {}), ...presentation, ...specific, ...options.flags },\n args: {},\n };\n }\n\n protected override async execute(\n { flags }: OperationInput,\n _meta: GlobalOptions,\n ): Promise<CommandResult> {\n const { topic, resource, spec, options } = this.definition;\n const wire = wireOf(options.wire);\n // With a schema in hand the columns are known before any request, so a\n // typo fails without contacting the server at all.\n const shape = fieldPaths(itemSchemaOf(spec.response, spec.items));\n const early = shape ? chosenColumns(flags.fields, resource.columns, [], shape) : undefined;\n const ctx = await this.context();\n // An unpaged endpoint has no cursor flags to read and would reject the\n // parameters anyway, so nothing is sent and one request is the whole list.\n const paged = spec.paged !== false;\n const paging = (token?: string): Json =>\n paged\n ? {\n ...(typeof flags.limit === \"number\" && { [wire.limit]: flags.limit }),\n ...(token && { [wire.pageToken]: token }),\n }\n : {};\n\n // One request per page. Filters are parsed and checked against each\n // field's own declaration first, so an operation the endpoint does not\n // offer fails locally with what that field accepts.\n const given = (Array.isArray(flags.filter) ? flags.filter : []).map((raw) =>\n parseFilter(String(raw), spec.filters ?? []),\n );\n // A field that declares a default contributes it only when the caller did\n // not name that field, so naming it always wins.\n const defaults = (spec.filters ?? []).flatMap((field) =>\n field.default !== undefined && !given.some((one) => one.field.field === field.field)\n ? [{ field, operation: \"equals\", value: field.default }]\n : [],\n );\n const parsed = [...given, ...defaults];\n const sorting =\n typeof flags.sort === \"string\" ? parseSort(flags.sort, spec.sorts ?? []) : undefined;\n\n // Transport is the only thing that differs: a structured query endpoint\n // takes a validated body, a GET list takes flat parameters. The caller\n // typed the same thing either way.\n const request = (token?: string): Promise<unknown> =>\n spec.body\n ? spec.call(\n ctx,\n parseOrThrow(\n spec.body,\n wire.query({\n paging: paging(token),\n sorting,\n filters: parsed.map(({ field, operation, value }) => ({\n field: field.field,\n operation,\n value,\n })),\n }),\n \"Invalid list query\",\n `Filter fields: ${(spec.filters ?? []).map((f) => f.field).join(\", \")}. Sort fields: ${(spec.sorts ?? []).join(\", \")}.`,\n ),\n )\n : spec.call(ctx, {\n ...paging(token),\n ...queryParams(parsed),\n ...(sorting && spec.sortParam ? { [spec.sortParam]: sorting.direction } : {}),\n });\n\n // A resource that drains by default does so only when the caller named no\n // page: asking for one with --limit or --page-token is asking for one.\n const asked = flags.limit !== undefined || flags[\"page-token\"] !== undefined;\n const all = paged && (flags.all === true || (spec.drains === true && !asked));\n // `--all` is one request per page, so a wide drain would otherwise sit\n // silent. The spinner is terminal-only: no animation reaches a pipe, and\n // `--json` has already silenced everything.\n const progress = all && process.stdout.isTTY && !this.jsonEnabled() ? spinner() : undefined;\n progress?.start(`Fetching ${topic}`);\n let fetched = 0;\n let drained = false;\n // The spinner owns the cursor and a SIGINT handler until it is stopped, so a\n // page that fails mid-drain has to stop it too; otherwise the error prints\n // under a live spinner and the handler outlives the command.\n const { items, next } = await collectPages(\n async (token) => {\n const page = await request(token);\n fetched += 1;\n progress?.message(`Fetching ${topic} — page ${fetched}`);\n return page;\n },\n {\n items: spec.items,\n all,\n nextPageToken: wire.nextPageToken,\n token: paged && typeof flags[\"page-token\"] === \"string\" ? flags[\"page-token\"] : undefined,\n },\n )\n .then((page) => {\n drained = true;\n return page;\n })\n .finally(() => {\n if (!drained) {\n progress?.stop(`Fetching ${topic} failed`);\n }\n });\n progress?.stop(`Fetched ${items.length} ${items.length === 1 ? resource.singular : topic}`);\n\n // A terminal gets the aligned table with its header and footer; a pipe (or\n // `--plain`) gets one tab-separated record per line, which `cut` and `awk`\n // can split and nothing else has to parse around.\n const plain = flags.plain === true || !process.stdout.isTTY;\n const columns = early ?? chosenColumns(flags.fields, resource.columns, items);\n // A page token is only valid alongside the sorting and filters that issued\n // it, so the suggested next page repeats the whole invocation rather than\n // handing back a bare token. `--all` already drained everything, so it\n // suggests nothing.\n const nextCommands =\n next && !all\n ? [\n this.suggest(\n [\n `${topic} list`,\n ...repeatedFlags(flags),\n shellOption(\"--page-token\", next),\n \"--json\",\n ].join(\" \"),\n ),\n ]\n : [];\n return {\n status: \"ok\",\n data: {\n items,\n count: items.length,\n [wire.nextPageToken]: next,\n ...(nextCommands.length > 0 ? nextCommandsData(nextCommands) : {}),\n },\n pretty: plain\n ? renderRows(columns, items)\n : items.length === 0\n ? `No ${topic} found.`\n : [\n renderTable(columns, items),\n \"\",\n `${items.length} ${items.length === 1 ? resource.singular : topic}`,\n ...(next ? [`More available: ${shellOption(\"--page-token\", next)} (or --all)`] : []),\n ].join(\"\\n\"),\n };\n }\n}\n\n/**\n * The flags a follow-up page has to carry: a cursor is only valid with the\n * sorting and filters that produced it, and the page size is part of what the\n * caller asked for. Values are re-emitted exactly as they were typed.\n */\nconst repeatedFlags = (flags: Json): readonly string[] => {\n const limit = typeof flags.limit === \"number\" ? [`--limit ${flags.limit}`] : [];\n const sort = typeof flags.sort === \"string\" ? [shellOption(\"--sort\", flags.sort)] : [];\n const filters = (Array.isArray(flags.filter) ? flags.filter : []).map((filter) =>\n shellOption(\"--filter\", String(filter)),\n );\n return [...limit, ...sort, ...filters];\n};\n\n/**\n * Parsed filters as the flat query parameters a GET list expects. A field\n * names the parameter each of its operations travels as, and a field whose\n * repeats widen collects its values into an array rather than overwriting.\n */\nconst queryParams = (parsed: readonly ParsedFilter[]): Json =>\n parsed.reduce<Record<string, unknown>>((params, { field, operation, value }) => {\n const key = field.params?.[operation] ?? field.field;\n const existing = params[key];\n if (field.combine !== \"or\") {\n params[key] = value;\n return params;\n }\n params[key] = Array.isArray(existing)\n ? [...existing, value]\n : existing === undefined\n ? [value]\n : [existing, value];\n return params;\n }, {});\n","import { nonBlankString } from \"../../flags\";\n\nimport { chosenColumns } from \"../columns\";\nimport { fieldPaths } from \"../paths\";\nimport { idArg, idName, idValue } from \"../shared\";\nimport { renderDetail } from \"../table\";\nimport type { GetSpec } from \"../types\";\nimport type { CommandResult } from \"../../types\";\nimport {\n type OperationDefinition,\n type OperationInput,\n type OperationStatics,\n ResourceCommand,\n} from \"./command\";\n\n/**\n * `<topic> get <id>`. A terminal gets the record laid out field by field,\n * headed by whatever identifies it; a pipe (and `--json`) gets the object\n * itself, because a script wants the record rather than a view of it.\n */\nexport class GetOperation<Ctx> extends ResourceCommand<Ctx, GetSpec<Ctx>> {\n static describe<Ctx>({\n topic,\n resource,\n options,\n }: OperationDefinition<Ctx, GetSpec<Ctx>>): OperationStatics {\n return {\n // A resource addressed by more than an id says so, as its argument does.\n description: `Get one ${resource.singular} by ${resource.idDescription ?? \"id\"}.`,\n examples: [\n `<%= config.bin %> ${topic} get <${idName(resource)}>`,\n `<%= config.bin %> ${topic} get <${idName(resource)}> --json`,\n ],\n flags: {\n fields: nonBlankString({\n description:\n \"Fields to show, comma-separated dot-paths. Defaults to the resource's own; `--json` is unaffected.\",\n }),\n ...options.flags,\n },\n args: idArg(resource),\n };\n }\n\n protected override async execute({ flags, args }: OperationInput): Promise<CommandResult> {\n const { resource, spec } = this.definition;\n // Same as `list`: a schema decides `--fields` before the request is made.\n const shape = fieldPaths(spec.response);\n const early = shape\n ? chosenColumns(flags.fields, resource.detail ?? resource.columns, [], shape)\n : undefined;\n const item = await spec.call(await this.context(), idValue(resource, args));\n // Validated before the output branch, so the same arguments are valid (or\n // not) whether the result goes to a terminal or a pipe.\n const fields =\n early ?? chosenColumns(flags.fields, resource.detail ?? resource.columns, [item]);\n if (!process.stdout.isTTY) {\n return { status: \"ok\", data: item, pretty: JSON.stringify(item, null, 2) };\n }\n return {\n status: \"ok\",\n data: item,\n pretty: renderDetail(headingOf(resource.heading ?? resource.idField, item), fields, item),\n };\n }\n}\n\n/** The value that heads the rendering, when the record carries one. */\nconst headingOf = (path: string, item: unknown): string | undefined => {\n const value = path\n .split(\".\")\n .reduce<unknown>(\n (current, key) =>\n typeof current === \"object\" && current !== null\n ? (current as Record<string, unknown>)[key]\n : undefined,\n item,\n );\n return typeof value === \"string\" ? value : undefined;\n};\n","import { readFile } from \"node:fs/promises\";\nimport { text } from \"node:stream/consumers\";\n\nimport { ZitadelError } from \"../../errors\";\nimport { parseJsonObject } from \"../../json\";\nimport type { Json } from \"./types\";\n\n/**\n * The raw body of a write, from `--data` (inline), `--file <path>`, or\n * `--file -` (stdin). Returns `undefined` when none of them was given: the\n * caller decides whether that is an error, since a body can also be assembled\n * from the field flags and `--set`. `what` names the command in the stdin\n * hint.\n *\n * Nothing here judges the content: `--data` is on the command line like any\n * flag, so the write command checks it for credentials together with the\n * field flags and `--set`, against the schema that says what each value is.\n */\nexport const readRawBody = async (flags: Json, what: string): Promise<Json | undefined> => {\n if (typeof flags.data === \"string\") {\n return parseJsonObject(flags.data, \"--data\");\n }\n if (flags.file === \"-\") {\n // Reading stdin to end-of-file when stdin is the keyboard looks like a\n // hang: no output, no error, nothing to do but Ctrl-C. The CLI guidelines\n // say to notice and say so instead.\n if (process.stdin.isTTY) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"--file - reads the body from a pipe, but nothing is piped in\",\n {\n hint: `Pipe a body in (\\`cat body.json | zitadel ${what}\\`), or pass it with --file <path> or --data '<json>'.`,\n },\n );\n }\n return parseJsonObject(await text(process.stdin), \"stdin\");\n }\n if (typeof flags.file === \"string\") {\n return parseJsonObject(await readFile(flags.file, \"utf8\"), flags.file);\n }\n return undefined;\n};\n","import { Flags } from \"@oclif/core\";\n\nimport { nonBlankString } from \"../../flags\";\n\nimport { ZitadelError } from \"../../../errors\";\nimport { isObject } from \"../../../json\";\nimport type { CommandResult, GlobalOptions } from \"../../types\";\nimport { type Assignment, fragmentOf, readAssignments } from \"../assign\";\nimport { readRawBody } from \"../body\";\nimport { mergeDocuments, setAt, valueAt } from \"../document\";\nimport {\n type BodyField,\n bodyFieldFlags,\n bodyFromFlags,\n describeBody,\n documentSchemaOf,\n fieldExample,\n flagsAloneMayBeIncomplete,\n} from \"../fields\";\nimport { findCredential, refuseSecret, type References } from \"../secrets\";\nimport { article, dryRunResult, idArg, idName, parseOrThrow } from \"../shared\";\nimport type {\n CreateSpec,\n Json,\n ResourceCommandOptions,\n ResourceDescriptor,\n UpdateSpec,\n WriteShape,\n} from \"../types\";\nimport { objectOf, type ZodLike } from \"../zod\";\nimport {\n type OperationDefinition,\n type OperationInput,\n type OperationStatics,\n ResourceCommand,\n} from \"./command\";\nimport { nextCommandsData } from \"../../envelope\";\n\n/**\n * `--data` / `--file`: the whole document at once, and `--set`: one field of\n * it by path. Together with the field flags they make the body in one order\n * (ADR 071 §1): the document, then the field flags, then each `--set`, every\n * one merged over the last.\n */\nconst rawBodyFlags = {\n data: nonBlankString({\n // No `-d`: the CLI conventions reserve that short form for `--debug`.\n description: \"Whole body as a JSON object. Field flags and --set apply over it.\",\n exclusive: [\"file\"],\n helpGroup: \"RAW BODY\",\n }),\n file: nonBlankString({\n description:\n \"Read the body from a JSON file; `-` reads stdin. Field flags and --set apply over it.\",\n exclusive: [\"data\"],\n helpGroup: \"RAW BODY\",\n }),\n set: Flags.string({\n description:\n 'Set one field by its dot path: path=value, or path:=json for JSON. Repeatable; applied after the field flags, in order. A key that contains a dot is set through its parent: --set \\'parent:={\"a.b\":\"x\"}\\'.',\n multiple: true,\n helpGroup: \"RAW BODY\",\n }),\n};\n\n/** A write's fields, read the same way for its `--help` and for a run. */\nconst fieldsOf = <Ctx>(\n spec: WriteShape & { schema: CreateSpec<Ctx>[\"schema\"] },\n options: ResourceCommandOptions<Ctx>,\n) => describeBody(spec.schema, { root: spec.root, reserved: Object.keys(options.flags ?? {}) });\n\n/**\n * The `--file` example's file name, the singular as one shell word:\n * `./identity-provider-connection.json`, where the singular itself would be\n * split by a shell into three arguments.\n */\nconst exampleFile = (singular: string): string =>\n `./${singular.toLowerCase().replaceAll(/[^a-z0-9]+/g, \"-\")}.json`;\n\n/**\n * `<topic> create` and `<topic> update <id>` share everything but the id\n * argument. The body comes from a document (`--data` / `--file`), from one\n * flag per schema field, from `--set`, or from any mix of them. It is\n * validated against the request schema before the call, and the resource is\n * echoed back with a `next_commands` hint at the matching `get`.\n */\nconst describeWrite = <\n Ctx,\n Spec extends WriteShape & { readonly schema: CreateSpec<Ctx>[\"schema\"] },\n>(\n { topic, resource, spec }: OperationDefinition<Ctx, Spec>,\n options: ResourceCommandOptions<Ctx>,\n verb: \"create\" | \"update\",\n): OperationStatics => {\n const fields = fieldsOf(spec, options);\n const example =\n spec.example ?? (flagsAloneMayBeIncomplete(fields) ? undefined : fieldExample(fields));\n const command = `<%= config.bin %> ${topic} ${verb}${verb === \"update\" ? \" <id>\" : \"\"}`;\n return {\n description:\n verb === \"create\"\n ? `Create ${article(resource.singular)} ${resource.singular}.`\n : `Update ${article(resource.singular)} ${resource.singular} by id.`,\n examples: [\n ...(example ? [`${command} ${example} --json`] : []),\n `${command} --data '{...}' --json`,\n `${command} --file ${exampleFile(resource.singular)}`,\n ],\n flags: { ...bodyFieldFlags(fields), ...rawBodyFlags, ...options.flags },\n args: verb === \"create\" ? {} : idArg(resource),\n };\n};\n\n/** One part of the body that came in on the command line, and the flag it came through. */\ntype ArgvPart = Readonly<{ value: unknown; source: string }>;\n\n/**\n * The parts of the body that came in on the command line, each with the flag\n * it came through. `--file` and stdin are not among them: those routes never\n * pass through argv, which is why the refusal points at them.\n */\nconst argvParts = (\n flags: Json,\n base: Json | undefined,\n fields: readonly BodyField[],\n fromFlags: Json | undefined,\n assignments: readonly Assignment[],\n): ArgvPart[] => [\n ...(typeof flags.data === \"string\" && base ? [{ value: base, source: \"--data\" }] : []),\n ...fields.flatMap((field) => {\n const value = valueAt(fromFlags, field.path);\n return value === undefined || field.flag === undefined\n ? []\n : [{ value: setAt({}, field.path, value), source: `--${field.flag}` }];\n }),\n ...assignments.map((assignment) => ({ value: fragmentOf(assignment), source: \"--set\" })),\n];\n\n/**\n * Refuse a credential that reached the command line, through any flag that\n * carries part of the body. A reference to a variable is not one, nor is a\n * value the schema fixes (ADR 071 §7).\n */\nconst refuseArgvCredentials = (\n parts: readonly ArgvPart[],\n schema: ZodLike | undefined,\n references: References | undefined,\n): void => {\n for (const part of parts) {\n const credential = findCredential(part.value, { schema, references });\n if (credential) {\n refuseSecret(credential.key, part.source, { references, path: credential.path });\n }\n }\n};\n\n/**\n * The document of a body that arrived still wrapped in its root\n * (`{\"idp\": {…}}`, as the API reference shows one). Unwrapped only when the\n * wrapper cannot be a field of the document itself.\n */\nconst unwrapRoot = (raw: Json, root: string | undefined, document: ZodLike | undefined): Json => {\n if (root === undefined || !Object.hasOwn(raw, root) || Object.keys(raw).length !== 1) {\n return raw;\n }\n const inner = raw[root];\n const shape = objectOf(document)?.shape;\n const declared = shape !== undefined && Object.hasOwn(shape, root);\n return isObject(inner) && !declared ? inner : raw;\n};\n\n/**\n * Whether a field the body must carry is missing: one every body carries, or\n * one whose optional object was given (`oidc.issuer` once anything under\n * `oidc` is).\n */\nconst isMissing = (field: BodyField, document: unknown): boolean =>\n valueAt(document, field.path) === undefined &&\n (field.required ||\n (field.requiredWith !== undefined && isObject(valueAt(document, field.requiredWith))));\n\n/** How a missing field is named to the caller: its flag, or `--set` when it has none. */\nconst spelling = (field: BodyField): string =>\n field.flag ? `--${field.flag}` : `--set ${field.name}=…`;\n\nabstract class WriteOperation<\n Ctx,\n Spec extends WriteShape & { readonly schema: CreateSpec<Ctx>[\"schema\"] },\n> extends ResourceCommand<Ctx, Spec> {\n protected abstract verb: \"create\" | \"update\";\n\n protected override async execute(\n { flags, args }: OperationInput,\n meta: GlobalOptions,\n ): Promise<CommandResult> {\n const { topic, resource, spec, options } = this.definition;\n const idKey = idName(resource);\n const id = typeof args[idKey] === \"string\" ? (args[idKey] as string) : undefined;\n const document = documentSchemaOf(spec.schema, spec.root);\n const fields = fieldsOf(spec, options);\n\n const raw = await readRawBody(flags, `${topic} ${this.verb}`);\n const base = raw === undefined ? undefined : unwrapRoot(raw, spec.root, document);\n const fromFlags = bodyFromFlags(fields, flags);\n const assignments = readAssignments(flags.set, document, fields);\n if (!base && !fromFlags && assignments.length === 0) {\n throw new ZitadelError(\"E_VALIDATION\", `${topic} ${this.verb} needs a body`, {\n hint: `Pass the body's fields as flags (see \\`${topic} ${this.verb} --help\\`), --set <path>=<value>, or --data '<json>' / --file <path>.`,\n });\n }\n refuseArgvCredentials(\n argvParts(flags, base, fields, fromFlags, assignments),\n document,\n options.references,\n );\n\n // Each source merges over the one before (ADR 071 §1): a field flag over\n // the document changes the key it names, not the object around it.\n const merged = [fromFlags, ...assignments.map(fragmentOf)].reduce<unknown>(\n (body, overlay) => (overlay === undefined ? body : mergeDocuments(body, overlay)),\n base ?? {},\n );\n\n // Required fields are not oclif-required — `--data` / `--file` may carry\n // them — so presence is checked here, once every source is merged, and\n // reported as the flags the caller is missing rather than as schema issues.\n const missing = fields.filter((field) => isMissing(field, merged));\n if (missing.length > 0) {\n const flagNames = missing.map(spelling);\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${topic} ${this.verb} is missing required ${missing.length === 1 ? \"field\" : \"fields\"}: ${flagNames.join(\", \")}`,\n {\n hint: `Pass ${flagNames.join(\" and \")}, or include ${missing.length === 1 ? \"it\" : \"them\"} in --data / --file. See \\`${topic} ${this.verb} --help\\`.`,\n details: { missing: missing.map((field) => field.name) },\n },\n );\n }\n const wrapped = spec.root === undefined ? merged : { [spec.root]: merged };\n const body = parseOrThrow(spec.schema, wrapped, \"Body does not match the API schema\");\n if (meta.dryRun) {\n return dryRunResult(this.verb, topic, id, body, {\n schema: spec.schema as ZodLike,\n references: options.references,\n });\n }\n\n const result = await this.send(await this.context(), body, id);\n const resultId = isObject(result) ? result[resource.idField] : undefined;\n const nextCommands =\n typeof resultId === \"string\" && resource.get\n ? [this.suggest(`${topic} get ${resultId} --json`)]\n : [];\n return {\n status: \"ok\",\n // An ok envelope always carries `data`, also when the server accepts a\n // write without a body (`grants create` by identifier answers 202).\n data:\n isObject(result) && nextCommands.length > 0\n ? { ...result, ...nextCommandsData(nextCommands) }\n : (result ?? {}),\n pretty: JSON.stringify(result, null, 2),\n };\n }\n\n protected abstract send(ctx: Ctx, body: Json, id: string | undefined): Promise<unknown>;\n}\n\n/** `<topic> create`. */\nexport class CreateOperation<Ctx> extends WriteOperation<Ctx, CreateSpec<Ctx>> {\n static describe<Ctx>(definition: OperationDefinition<Ctx, CreateSpec<Ctx>>): OperationStatics {\n return describeWrite(definition, definition.options, \"create\");\n }\n\n protected readonly verb = \"create\";\n\n protected send(ctx: Ctx, body: Json): Promise<unknown> {\n return this.definition.spec.call(ctx, body);\n }\n}\n\n/** `<topic> update <id>`. */\nexport class UpdateOperation<Ctx> extends WriteOperation<Ctx, UpdateSpec<Ctx>> {\n static describe<Ctx>(definition: OperationDefinition<Ctx, UpdateSpec<Ctx>>): OperationStatics {\n return describeWrite(definition, definition.options, \"update\");\n }\n\n protected readonly verb = \"update\";\n\n protected send(ctx: Ctx, body: Json, id: string | undefined): Promise<unknown> {\n return this.definition.spec.call(ctx, id ?? \"\", body);\n }\n}\n\nexport type { ResourceDescriptor };\n","import { describeBody } from \"./fields\";\nimport type { Json, ResourceRegistry, Schema, WriteShape } from \"./types\";\n\n/**\n * A machine-readable description of what a registry exposes: one entry per\n * topic with its verbs, the fields each list accepts, and the body fields of\n * its writes. It is the same information `--help` renders for a reader, in the\n * shape an agent can consume in a single call — the role `stripe resources`\n * and `kubectl api-resources` play in those CLIs.\n */\nexport const describeRegistry = <Ctx>(registry: ResourceRegistry<Ctx>): readonly Json[] =>\n Object.entries(registry).map(([topic, resource]) => {\n const documentRoot = resource.create?.root ?? resource.update?.root;\n return {\n topic,\n singular: resource.singular,\n id_field: resource.idField,\n // The positional the id-taking verbs read, which is not always \"id\":\n // an environment is addressed by name.\n id_arg: resource.idArg ?? \"id\",\n verbs: [\n ...(resource.list ? [\"list\"] : []),\n ...(resource.get ? [\"get\"] : []),\n ...(resource.create ? [\"create\"] : []),\n ...(resource.update ? [\"update\"] : []),\n ...(resource.delete ? [resource.delete.verb ?? \"delete\"] : []),\n ],\n columns: [...resource.columns],\n // Whether `list` is cursor-paginated. An agent that loops on\n // `next_page_token` needs to know which collections arrive whole.\n ...(resource.list ? { paged: resource.list.paged !== false } : {}),\n // Whether a bare `list` returns the whole collection. An agent that must\n // not miss a row needs to know which resources it has to drain itself.\n ...(resource.list?.drains === true ? { drains: true } : {}),\n // The property a delete's envelope carries beside `id`. It is not always\n // `deleted` — a team's DELETE deactivates it (ADR 024) — and an agent\n // reading this surface should not have to guess which.\n ...(resource.delete\n ? {\n delete_outcome:\n resource.delete.outcome ??\n { delete: \"deleted\", revoke: \"revoked\", deactivate: \"deactivated\" }[\n resource.delete.verb ?? \"delete\"\n ],\n }\n : {}),\n // Every list shares one filter grammar, so the surface reports each\n // field with the operations that field accepts rather than a single set\n // the resource may not honour everywhere.\n ...(resource.list?.filters?.length\n ? {\n filters: resource.list.filters.map((field) => ({\n field: field.field,\n operations: [...field.operations],\n ...(field.values ? { values: [...field.values] } : {}),\n ...(field.default !== undefined ? { default: field.default } : {}),\n ...(field.combine === \"or\" ? { combine: \"or\" } : {}),\n })),\n }\n : {}),\n ...(resource.list?.sorts?.length ? { sort_fields: [...resource.list.sorts] } : {}),\n // The property of the request body the document sits under, which the\n // fields below are relative to; `--data` and `--file` take the document.\n ...(documentRoot ? { document_root: documentRoot } : {}),\n // Per verb, not per resource: a create's required field is often optional\n // on the update of the same resource, so one list would misdescribe one\n // of them.\n ...(resource.create ? { create_fields: fieldsOf(resource.create) } : {}),\n ...(resource.update ? { update_fields: fieldsOf(resource.update) } : {}),\n };\n });\n\n/**\n * A write's fields as an agent needs them, nested ones included: the dot path\n * (`name`), the flag that carries it — `null` when only `--set` reaches it —\n * its kind, and whether a body must carry it. Enough to assemble flags,\n * `--set` assignments or a whole document from one call (ADR 071 §9).\n */\nconst fieldsOf = (spec: WriteShape & { schema: Schema }): readonly Json[] =>\n describeBody(spec.schema, { root: spec.root }).map((field) => ({\n name: field.name,\n flag: field.flag ? `--${field.flag}` : null,\n kind: field.kind,\n required: field.required,\n ...(field.requiredWith ? { required_with: field.requiredWith.join(\".\") } : {}),\n ...(field.item ? { item: field.item } : {}),\n ...(field.options ? { options: [...field.options] } : {}),\n ...(field.default ? { default: field.default.value } : {}),\n ...(field.summary ? { description: field.summary } : {}),\n }));\n","import type { Command } from \"@oclif/core\";\n\nimport { bindOperation, type OperationClass } from \"./ops/command\";\nimport { DeleteOperation } from \"./ops/delete\";\nimport { ListOperation } from \"./ops/list\";\nimport { GetOperation } from \"./ops/read\";\nimport { CreateOperation, UpdateOperation } from \"./ops/write\";\nimport type {\n ResourceCommandId,\n ResourceCommandOptions,\n ResourceDescriptor,\n ResourceRegistry,\n Verb,\n} from \"./types\";\n\n/**\n * Generic `<topic> <verb>` command factory for oclif. It knows nothing about\n * the platform behind the commands: every API call is a closure in the\n * registry that receives a caller-supplied connection `Ctx`, and every\n * platform-specific flag or credential lookup arrives through\n * {@link ResourceCommandOptions}. What the factory owns is the CLI contract —\n * flag grammar, pagination, local schema validation, the dry-run and\n * destructive-action guards, and the JSON / table envelopes.\n */\n\nexport {\n bodyFieldFlags,\n bodyFromFlags,\n describeBody,\n documentSchemaOf,\n fieldExample,\n flagsAloneMayBeIncomplete,\n} from \"./fields\";\nexport type { BodyField, DescribeOptions, FieldKind } from \"./fields\";\nexport { readAssignment, readAssignments } from \"./assign\";\nexport type { Assignment } from \"./assign\";\nexport { jsonValue, mergeDocuments, setAt, typedValue, valueAt } from \"./document\";\nexport { findCredential, isSecretKey, redactCredentials } from \"./secrets\";\nexport type { Credential, CredentialContext, References } from \"./secrets\";\nexport { describeRegistry } from \"./describe\";\nexport { collectPages } from \"./paging\";\nexport { DEFAULT_WIRE, wireOf } from \"./wire\";\nexport { parseFilter, parseSort } from \"./query\";\nexport { chosenColumns } from \"./columns\";\nexport { allows, fieldPaths, itemSchemaOf, observedPaths, suggestable } from \"./paths\";\nexport type { FieldPaths } from \"./paths\";\nexport { renderDetail, renderRows, renderTable } from \"./table\";\nexport { bindOperation, definitionOf, ResourceCommand } from \"./ops/command\";\nexport type {\n OperationClass,\n OperationDefinition,\n OperationInput,\n OperationStatics,\n} from \"./ops/command\";\nexport { CreateOperation, DeleteOperation, GetOperation, ListOperation, UpdateOperation };\nexport type * from \"./types\";\n\n/**\n * Builds the command classes for every registry entry, keyed by oclif command\n * id (`users:list`), ready to spread into an explicit command table. oclif's\n * help, manifest, autocomplete, and README generation read them exactly as\n * they read hand-written classes.\n */\nexport const buildResourceCommands = <Ctx>(\n registry: ResourceRegistry<Ctx>,\n options: ResourceCommandOptions<Ctx>,\n): Readonly<Record<ResourceCommandId, typeof Command>> =>\n Object.fromEntries(\n Object.entries(registry).flatMap(([topic, resource]) => {\n const bind = <Spec>(\n verb: Verb,\n operation: OperationClass<Ctx, Spec>,\n spec: Spec | undefined,\n ): readonly (readonly [ResourceCommandId, typeof Command])[] =>\n spec === undefined\n ? []\n : [[`${topic}:${verb}`, bindOperation(operation, { topic, resource, spec, options })]];\n return [\n ...bind(\"list\", ListOperation, resource.list),\n ...bind(\"get\", GetOperation, resource.get),\n ...bind(\"create\", CreateOperation, resource.create),\n ...bind(\"update\", UpdateOperation, resource.update),\n ...bind(resource.delete?.verb ?? \"delete\", DeleteOperation, resource.delete),\n ];\n }),\n );\n\n/** Re-exported for registries that want to describe a resource in isolation. */\nexport type { ResourceDescriptor };\n","import {\n CreateGrantBody,\n CreateTeamBody,\n CreateUserBody,\n PatchProjectBody,\n PatchUserByIDBody,\n QueryGrantsBody,\n QueryProjectsBody,\n QuerySessionsBody,\n QueryTeamsBody,\n QueryUsersBody,\n UpdateTeamBody,\n} from \"@zitadel/api/generated/endpoints/zitadelNextGen.zod\";\nimport {\n GetBrandingByIdResponse,\n GetFlowDefinitionResponse,\n CreateIdpBody,\n GetGrantResponse,\n GetProjectResponse,\n GetSessionResponse,\n GetReleaseByIdResponse,\n GetSchemaByIdResponse,\n GetIdpByIdResponse,\n GetPolicyResponse,\n GetTeamResponse,\n GetUserByIDResponse,\n ListBrandingResponse,\n ListEventsResponse,\n ListFlowDefinitionsResponse,\n ListPoliciesResponse,\n ListReleasesResponse,\n PublishPolicyBody,\n ListSchemasResponse,\n QueryGrantsResponse,\n QueryIdpsBody,\n QueryIdpsResponse,\n QueryProjectsResponse,\n QuerySessionsResponse,\n QueryTeamsResponse,\n QueryUsersResponse,\n} from \"@zitadel/api/generated/endpoints/zitadelNextGen.zod\";\nimport { ApiError } from \"@zitadel/api/runtime/fetch\";\nimport { isVariableReference } from \"@zitadel/config/idp\";\n\nimport type { ZitadelClient } from \"../lib/api-client\";\nimport { CommandGroups } from \"../lib/oclif/groups\";\nimport { ZitadelError } from \"../lib/errors\";\nimport {\n buildResourceCommands,\n type CreateSpec,\n type ListSpec,\n type ResourceRegistry,\n type Schema,\n type UpdateSpec,\n type WriteShape,\n} from \"../lib/oclif/crud\";\n\n/**\n * The platform connection every resource verb calls through: the typed\n * client bound to the resolved server, plus the project the credential\n * belongs to. Endpoints that scope by `project_id` read it\n * from here; the flag surface never exposes it.\n */\nexport type Platform = Readonly<{ client: ZitadelClient; projectId: string }>;\n\n// Builders that infer a verb's body type from its Zod schema, so `call` gets\n// the typed body straight from `parseOrThrow` — no cast from `Json`.\nconst create = <B>(\n schema: Schema<B>,\n call: (ctx: Platform, body: B) => Promise<unknown>,\n shape: WriteShape = {},\n): CreateSpec<Platform, B> => ({ ...shape, schema, call });\n\nconst update = <B>(\n schema: Schema<B>,\n call: (ctx: Platform, id: string, body: B) => Promise<unknown>,\n shape: WriteShape = {},\n): UpdateSpec<Platform, B> => ({ ...shape, schema, call });\n\n// Infers a structured-query list's request type `B` from its `body` schema. A\n// `GET` list has no body, so it is written as a plain object (request stays `Json`).\nconst list = <B>(spec: ListSpec<Platform, B>): ListSpec<Platform, B> => spec;\n\n/** Filter operations of `POST /<resource>/query` endpoints (ADR 031). */\nconst FILTER_OPERATIONS = [\n \"equals\",\n \"not_equals\",\n \"contains\",\n \"not_contains\",\n \"less_than\",\n \"less_than_or_equal\",\n \"greater_than\",\n \"greater_than_or_equal\",\n] as const;\n\nconst EVENT_CATEGORIES = [\"request\", \"auth\", \"session\", \"admin\", \"entity\", \"signal\"] as const;\n\n/** The operations a policy can guard, as the generated publish body names them. */\nconst POLICY_OPERATIONS = PublishPolicyBody.shape.operation.options;\n\n/**\n * The runtime resources the CLI manages imperatively — one entry per topic.\n * Config resources (schemas, flows, branding, releases) are deliberately\n * absent: they are published from `.zitadel/**` through `deploy`\n * (ADR 007, ADR 035), and an imperative write path would fork that source of\n * truth. Adding a backend resource is adding an entry here.\n */\nexport const RESOURCES = {\n users: {\n group: CommandGroups.usersAndTeams,\n groupOrder: 1,\n singular: \"user\",\n idField: \"id\",\n // `identifier` is the user's login handle (their email under the default\n // schema); the schema URL it replaced is identical on every row.\n columns: [\"id\", \"identifier\", \"metadata.status\", \"metadata.created_at\"],\n heading: \"identifier\",\n detail: [\n \"id\",\n \"identifier_property\",\n \"metadata.status\",\n \"schema\",\n \"metadata.lifecycle_owner_team_id\",\n \"metadata.created_at\",\n \"metadata.updated_at\",\n ],\n list: list({\n items: \"users\",\n body: QueryUsersBody,\n response: QueryUsersResponse,\n filters: [\n { field: \"created_at\", operations: FILTER_OPERATIONS },\n { field: \"id\", operations: FILTER_OPERATIONS },\n { field: \"schema\", operations: FILTER_OPERATIONS },\n { field: \"status\", operations: FILTER_OPERATIONS },\n { field: \"team_id\", operations: FILTER_OPERATIONS },\n { field: \"lifecycle_owner_team_id\", operations: FILTER_OPERATIONS },\n ],\n sorts: [\"created_at\", \"id\", \"schema\", \"status\", \"lifecycle_owner_team_id\"],\n // No project_id: the users query defaults to the token's own project,\n // which is the only one a project secret can list.\n call: ({ client }, body) => client.queryUsers(body),\n }),\n get: { call: ({ client }, id) => client.getUserByID(id), response: GetUserByIDResponse },\n create: create(CreateUserBody, ({ client, projectId }, body) =>\n client.createUser(body, { project_id: projectId }),\n ),\n update: update(PatchUserByIDBody, ({ client }, id, body) => client.patchUserByID(id, body)),\n delete: { call: ({ client }, id) => client.deleteUserByID(id) },\n },\n\n teams: {\n group: CommandGroups.usersAndTeams,\n groupOrder: 2,\n singular: \"team\",\n idField: \"id\",\n columns: [\"id\", \"name\", \"status\", \"created_at\"],\n heading: \"name\",\n detail: [\"id\", \"status\", \"created_at\", \"updated_at\"],\n list: list({\n items: \"teams\",\n body: QueryTeamsBody,\n response: QueryTeamsResponse,\n filters: [\n { field: \"created_at\", operations: FILTER_OPERATIONS },\n { field: \"name\", operations: FILTER_OPERATIONS },\n { field: \"status\", operations: FILTER_OPERATIONS },\n ],\n sorts: [\"created_at\", \"name\", \"status\"],\n call: ({ client, projectId }, body) => client.queryTeams(body, { project_id: projectId }),\n }),\n get: { call: ({ client }, id) => client.getTeam(id), response: GetTeamResponse },\n create: create(CreateTeamBody, ({ client, projectId }, body) =>\n client.createTeam(body, { project_id: projectId }),\n ),\n update: update(UpdateTeamBody, ({ client }, id, body) => client.updateTeam(id, body)),\n // A team's DELETE deactivates it and leaves it readable (ADR 024), so the\n // command is named after that rather than claiming the team is gone.\n delete: { verb: \"deactivate\", call: ({ client }, id) => client.deleteTeam(id) },\n },\n\n sessions: {\n group: CommandGroups.authentication,\n singular: \"session\",\n idField: \"session_id\",\n columns: [\"session_id\", \"state\", \"user_id\", \"created_at\", \"expires_at\"],\n heading: \"session_id\",\n detail: [\"project_id\", \"state\", \"user_id\", \"created_at\", \"expires_at\"],\n list: list({\n items: \"sessions\",\n body: QuerySessionsBody,\n response: QuerySessionsResponse,\n filters: [\n { field: \"created_at\", operations: FILTER_OPERATIONS },\n { field: \"user_id\", operations: FILTER_OPERATIONS },\n { field: \"state\", operations: FILTER_OPERATIONS },\n { field: \"lifecycle_owner_team_id\", operations: FILTER_OPERATIONS },\n ],\n sorts: [\"created_at\", \"user_id\"],\n call: ({ client, projectId }, body) => client.querySessions(body, { project_id: projectId }),\n }),\n get: { call: ({ client }, id) => client.getSession(id), response: GetSessionResponse },\n // The endpoint terminates the session rather than removing a record, so\n // the command says `revoke`. `delete` would tell the caller it is gone.\n delete: { verb: \"revoke\", call: ({ client }, id) => client.revokeSession(id) },\n },\n\n events: {\n group: CommandGroups.diagnostics,\n singular: \"event\",\n idField: \"id\",\n columns: [\"id\", \"event_type\", \"category\", \"actor_id\", \"occurred_at\"],\n heading: \"event_type\",\n detail: [\n \"id\",\n \"category\",\n \"actor_id\",\n \"actor_type\",\n \"entity_type\",\n \"entity_id\",\n \"request_id\",\n \"occurred_at\",\n ],\n list: {\n items: \"data\",\n response: ListEventsResponse,\n // `GET /events` spells its filters as flat query parameters, and a range\n // as two of them. Declaring the parameter each operation travels as lets\n // the caller write the same `field=operation:value` they write for every\n // other resource, with no grammar invented that the endpoint cannot\n // honour.\n filters: [\n {\n field: \"category\",\n operations: [\"equals\"],\n values: EVENT_CATEGORIES,\n combine: \"or\",\n },\n { field: \"event_type\", operations: [\"equals\"], combine: \"or\" },\n { field: \"actor_id\", operations: [\"equals\"] },\n { field: \"session_id\", operations: [\"equals\"] },\n { field: \"flow_id\", operations: [\"equals\"] },\n { field: \"request_id\", operations: [\"equals\"] },\n { field: \"entity_type\", operations: [\"equals\"] },\n { field: \"entity_id\", operations: [\"equals\"] },\n { field: \"team_id\", operations: [\"equals\"] },\n {\n field: \"created_at\",\n operations: [\"greater_than_or_equal\", \"less_than\"],\n params: {\n greater_than_or_equal: \"created_after\",\n less_than: \"created_before\",\n },\n },\n ],\n // The endpoint orders by `occurred_at` and takes only the direction.\n sorts: [\"occurred_at\"],\n sortParam: \"order\",\n call: ({ client, projectId }, params) =>\n client.listEvents({ project_id: projectId, ...params }),\n },\n get: { call: ({ client, projectId }, id) => client.getEvent(id, { project_id: projectId }) },\n },\n\n grants: {\n group: CommandGroups.usersAndTeams,\n groupOrder: 3,\n singular: \"grant\",\n idField: \"id\",\n columns: [\"id\", \"user.user_id\", \"team.team_id\", \"relation\", \"created_at\", \"expires_at\"],\n heading: \"id\",\n detail: [\"user.user_id\", \"team.team_id\", \"relation\", \"object_type\", \"created_at\", \"expires_at\"],\n list: list({\n items: \"grants\",\n body: QueryGrantsBody,\n response: QueryGrantsResponse,\n filters: [\n { field: \"created_at\", operations: FILTER_OPERATIONS },\n { field: \"user_id\", operations: FILTER_OPERATIONS },\n { field: \"team_id\", operations: FILTER_OPERATIONS },\n { field: \"relation\", operations: FILTER_OPERATIONS },\n { field: \"expires_at\", operations: FILTER_OPERATIONS },\n ],\n sorts: [\"created_at\", \"expires_at\", \"id\"],\n call: ({ client, projectId }, body) => client.queryGrants(body, { project_id: projectId }),\n }),\n get: {\n call: ({ client, projectId }, id) => client.getGrant(id, { project_id: projectId }),\n response: GetGrantResponse,\n },\n create: create(\n CreateGrantBody,\n ({ client, projectId }, body) => client.createGrant(body, { project_id: projectId }),\n // A grant names exactly one of `user` and `team`, which the required\n // fields alone cannot say, so the example names the principal itself.\n { example: \"--relation viewer --user-identifier alice@acme.com\" },\n ),\n delete: {\n call: ({ client, projectId }, id) => client.deleteGrant(id, { project_id: projectId }),\n },\n },\n\n // Identity provider connections (#1217). They carry ADR 063's shape already:\n // a fixed `id` shared by every revision, and a `revision_id` per revision.\n // The revision routes are not modelled here — the CLI has no grammar for a\n // sub-resource listing yet, so `idps revisions` is deliberately absent.\n idps: {\n group: CommandGroups.authentication,\n singular: \"identity provider connection\",\n idField: \"id\",\n columns: [\"id\", \"slug\", \"definition.protocol\", \"definition.display_name\", \"created_at\"],\n heading: \"slug\",\n detail: [\"id\", \"revision_id\", \"slug\", \"created_at\", \"updated_at\"],\n list: list({\n items: \"idps\",\n body: QueryIdpsBody,\n response: QueryIdpsResponse,\n filters: [\n { field: \"slug\", operations: FILTER_OPERATIONS },\n { field: \"created_at\", operations: FILTER_OPERATIONS },\n ],\n sorts: [\"slug\", \"created_at\"],\n call: ({ client, projectId }, body) => client.queryIdps(body, { project_id: projectId }),\n }),\n get: {\n call: ({ client, projectId }, id) => client.getIdpById(id, { project_id: projectId }),\n response: GetIdpByIdResponse,\n },\n // The body nests the connection under `idp`. Rooted there, the flags and\n // `--set` paths address the connection itself (`--oidc-issuer`), and\n // `--file` takes the same document as `.zitadel/idps/<slug>.json`. A slug\n // that already exists is revised rather than duplicated (#1217).\n create: create(\n CreateIdpBody,\n ({ client, projectId }, body) => client.createIdp(body, { project_id: projectId }),\n {\n root: \"idp\",\n // The `oidc` block is optional to the generated schema, which cannot\n // say that the protocol requires it, so the example spells it out.\n example:\n \"--slug acme-sso --protocol oidc --display-name 'Acme SSO' --oidc-issuer https://sso.acme.example --oidc-client-id <client_id> --oidc-client-secret '${{ ACME_SSO_CLIENT_SECRET }}' --oidc-scopes openid --oidc-scopes profile --oidc-scopes email\",\n },\n ),\n },\n\n projects: {\n group: CommandGroups.configuration,\n singular: \"project\",\n idField: \"id\",\n columns: [\"id\", \"name\", \"created_at\"],\n heading: \"name\",\n detail: [\"id\", \"origins\", \"created_at\", \"updated_at\"],\n list: list({\n items: \"projects\",\n body: QueryProjectsBody,\n response: QueryProjectsResponse,\n filters: [{ field: \"created_at\", operations: FILTER_OPERATIONS }],\n sorts: [\"created_at\"],\n call: ({ client }, body) => client.queryProjects(body),\n }),\n get: { call: ({ client }, id) => client.getProject(id), response: GetProjectResponse },\n update: update(PatchProjectBody, ({ client }, id, body) => client.patchProject(id, body)),\n },\n\n // Configuration resources (ADR 035) are read-only here. They are authored as\n // files under `.zitadel/` and shipped through a release, so a write verb\n // would be a second writer over the same state; reading what the server\n // currently holds is how you check that a deploy landed.\n schemas: {\n group: CommandGroups.configuration,\n singular: \"schema\",\n idField: \"id\",\n // Addressed by object type as well as by revision id, so the argument is\n // named for the thing rather than for one of its two spellings.\n idArg: \"schema\",\n idDescription: \"object type (current revision) or revision id\",\n columns: [\"id\", \"schema.objectType\", \"schema.kind\", \"metadata.created_at\"],\n heading: \"schema.objectType\",\n detail: [\"id\", \"schema.objectType\", \"schema.kind\", \"metadata.created_at\"],\n list: {\n items: \"schemas\",\n response: ListSchemasResponse,\n filters: [\n { field: \"object_type\", operations: [\"equals\"] },\n { field: \"kind\", operations: [\"equals\"] },\n {\n field: \"revisions\",\n operations: [\"equals\"],\n values: [\"all\", \"latest\"],\n // Editing a schema mints a new revision rather than changing the old\n // one, so the unfiltered list is a history: the same object type over\n // and over. Someone typing `schemas list` means \"what schemas do I\n // have\", which is one row each. The console made the same choice.\n default: \"latest\",\n },\n ],\n call: ({ client, projectId }, params) =>\n client.listSchemas({ ...params, project_id: projectId }),\n },\n get: {\n response: GetSchemaByIdResponse,\n // A schema is addressed two ways: a revision id names one immutable\n // revision and fetches directly, an object type resolves to the current\n // revision through the list. A revision id is whatever the customer's\n // `$id` says — `sch_…`, a URL, `urn:example:human`, anything — so there\n // is no shape to test for. Ask the server instead: fetch, and read a 404\n // as \"that was an object type\". The API has no fetch-by-object-type\n // route yet; when it does, this collapses to one client call like every\n // other `get`.\n call: async ({ client, projectId }, ref) => {\n try {\n return await client.getSchemaById(ref);\n } catch (error) {\n if (!(error instanceof ApiError) || error.status !== 404) {\n throw error;\n }\n }\n const page = await client.listSchemas({\n project_id: projectId,\n object_type: ref,\n revisions: \"latest\",\n limit: 1,\n });\n const current = page.schemas[0];\n if (!current) {\n throw new ZitadelError(\"E_NOT_FOUND\", `No schema named \"${ref}\"`, {\n hint: \"Run `schemas list` to see the object types this project has.\",\n });\n }\n return current;\n },\n },\n },\n\n release: {\n group: CommandGroups.configuration,\n singular: \"release\",\n idField: \"id\",\n columns: [\"id\", \"metadata.message\", \"metadata.git_sha\", \"revoked_at\"],\n heading: \"id\",\n detail: [\n \"id\",\n \"project_id\",\n \"content_hash\",\n \"revoked_at\",\n \"metadata.message\",\n \"metadata.git_sha\",\n \"metadata.git_dirty\",\n ],\n list: {\n items: \"releases\",\n response: ListReleasesResponse,\n call: ({ client, projectId }, params) =>\n client.listReleases({ ...params, project_id: projectId }),\n },\n get: {\n call: ({ client, projectId }, id) => client.getReleaseById(id, { project_id: projectId }),\n response: GetReleaseByIdResponse,\n },\n },\n\n \"flow-definitions\": {\n group: CommandGroups.configuration,\n singular: \"flow definition\",\n idField: \"id\",\n // Addressed by flow name as well as by revision id; see `schemas`.\n idArg: \"flow\",\n idDescription: \"flow name (newest revision) or revision id\",\n columns: [\"id\", \"flow_definition.name\", \"flow_definition.status\", \"created_at\"],\n heading: \"flow_definition.name\",\n detail: [\"id\", \"flow_definition.name\", \"flow_definition.status\", \"created_at\", \"updated_at\"],\n list: {\n items: \"flow_definitions\",\n response: ListFlowDefinitionsResponse,\n filters: [\n { field: \"name\", operations: [\"equals\"] },\n { field: \"purpose\", operations: [\"equals\"] },\n {\n field: \"revisions\",\n operations: [\"equals\"],\n values: [\"all\", \"latest\"],\n // Publishing under an existing name mints a new row (#1246), so the\n // unfiltered list is a history of the same flows. Same reasoning as\n // `schemas`: a bare list is the current flows.\n default: \"latest\",\n },\n ],\n call: ({ client, projectId }, params) =>\n client.listFlowDefinitions({\n ...params,\n project_id: projectId,\n }),\n },\n get: {\n response: GetFlowDefinitionResponse,\n // `flowdef_…` names one revision. Anything else is a flow name, and the\n // endpoint returns that flow's revisions newest first, so the first row\n // is the current one.\n call: async ({ client, projectId }, ref) => {\n if (ref.startsWith(\"flowdef_\")) {\n return client.getFlowDefinition(ref);\n }\n const page = await client.listFlowDefinitions({\n project_id: projectId,\n name: ref,\n limit: 1,\n });\n const current = page.flow_definitions[0];\n if (!current) {\n throw new ZitadelError(\"E_NOT_FOUND\", `No flow definition named \"${ref}\"`, {\n hint: \"Run `flow-definitions list` to see the flows this project has.\",\n });\n }\n return current;\n },\n },\n },\n\n branding: {\n group: CommandGroups.configuration,\n singular: \"branding revision\",\n idField: \"id\",\n columns: [\"id\", \"created_at\"],\n heading: \"id\",\n detail: [\"id\", \"created_at\"],\n list: {\n // `GET /branding` answers with the array itself and takes no cursor, so\n // the paging flags are not generated for it.\n paged: false,\n response: ListBrandingResponse,\n call: ({ client, projectId }) => client.listBranding({ project_id: projectId }),\n },\n get: {\n call: ({ client }, id) => client.getBrandingById(id),\n response: GetBrandingByIdResponse,\n },\n },\n\n // Operation policies (ADR 066). Configuration: written from\n // .zitadel/policies/ by `apply`, so only read here. A project has one\n // policy per operation, and the list shows each at its newest revision.\n // The revision routes are not modelled, for the reason `idps` gives.\n policies: {\n group: CommandGroups.configuration,\n singular: \"policy\",\n idField: \"id\",\n // Addressed by operation as well as by id: the operation is what the\n // file is named after and what a developer knows the policy by.\n idArg: \"policy\",\n idDescription: \"policy id or operation\",\n columns: [\"id\", \"operation\", \"revision_id\", \"updated_at\"],\n heading: \"operation\",\n detail: [\"id\", \"operation\", \"config\", \"revision_id\", \"project_id\", \"created_at\", \"updated_at\"],\n list: {\n items: \"policies\",\n response: ListPoliciesResponse,\n filters: [{ field: \"operation\", operations: [\"equals\"] }],\n call: ({ client, projectId }, params) =>\n client.listPolicies({ ...params, project_id: projectId }),\n },\n get: {\n response: GetPolicyResponse,\n // An id names the policy; a catalogued operation resolves through the\n // list's filter, which answers with the operation's policy or nothing.\n // Anything else names no policy: sending it as the filter would be\n // refused as a malformed query rather than reported as not found.\n call: async ({ client, projectId }, ref) => {\n if (ref.startsWith(\"pol_\")) {\n return client.getPolicy(ref, { project_id: projectId });\n }\n const notFound = () =>\n new ZitadelError(\"E_NOT_FOUND\", `No policy for \"${ref}\"`, {\n hint: `Run \\`policies list\\` to see the project's policies. A policy is addressed by its id or its operation (${POLICY_OPERATIONS.join(\", \")}).`,\n });\n const operation = POLICY_OPERATIONS.find((known) => known === ref);\n if (operation === undefined) {\n throw notFound();\n }\n const page = await client.listPolicies({ project_id: projectId, operation, limit: 1 });\n const current = page.policies[0];\n if (!current) {\n throw notFound();\n }\n return current;\n },\n },\n },\n} satisfies ResourceRegistry<Platform>;\n\n/**\n * The `<resource> <verb>` commands, ready for the explicit command table. They\n * connect like every command that talks to a project (see\n * `EnvironmentCommand`), so they take `--env` and `--env-file` too.\n */\nexport const RESOURCE_COMMANDS = buildResourceCommands<Platform>(RESOURCES, {\n operations: FILTER_OPERATIONS,\n // A `${{ NAME }}` reference to a project variable (ADR 062) names a\n // credential without revealing it, and is the only form a connection's\n // `client_secret` takes, so it may stand on a command line.\n references: { matches: isVariableReference, example: \"'${{ NAME }}'\" },\n connect: async (open) => {\n const { client, projectId } = await open();\n return { client, projectId };\n },\n});\n","import { Flags } from \"@oclif/core\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { describeRegistry } from \"../lib/oclif/crud\";\nimport { renderList } from \"../lib/oclif/crud/table\";\nimport { listData } from \"../lib/oclif/envelope\";\nimport { CommandGroups } from \"../lib/oclif/groups\";\nimport { RESOURCES } from \"./resources\";\n\n/** The columns `resources` renders, in order. */\nconst COLUMNS = [\"topic\", \"verbs\", \"filters\"] as const;\n\n/**\n * `zitadel resources` — what the resource surface exposes, in one call.\n *\n * An agent's first questions are \"which resources exist, what can I do to\n * each, what can I filter on, and what does a body need\". Answering those from\n * `--help` means one invocation per topic and parsing prose; this answers all\n * of them from the registry at once, and `--json` makes it machine-readable.\n * The command talks to no server: it describes the CLI, not the project.\n */\nexport default class ResourcesList extends BaseCommand {\n static override id = \"resources\";\n static override group = CommandGroups.diagnostics;\n static override description =\n \"List the resources this CLI manages.\\n\\nShows what can be done to each.\";\n static override examples = [\n \"<%= config.bin %> resources\",\n \"<%= config.bin %> resources --json\",\n '<%= config.bin %> resources --json | jq -r \\'.data.items[] | \"\\\\(.topic): \\\\(.verbs | join(\", \"))\"\\'',\n ];\n static override flags = {\n plain: Flags.boolean({\n description:\n \"Tab-separated rows with no header, for piping. Implied when stdout is not a terminal.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(ResourcesList);\n // No server call, so no server resolution: the answer is the same offline.\n await this.toMeta(flags, { resolveServer: false });\n const resources = describeRegistry(RESOURCES);\n\n const rows = resources.map((resource) => ({\n topic: String(resource.topic),\n verbs: (resource.verbs as string[]).join(\", \"),\n // Every list shares one filter grammar now, so the column is simply the\n // fields `--filter` accepts. What each field accepts beyond that — its\n // operations, its closed values — is in `--json` and in `--help`, which\n // is where a reader goes once they know the field exists.\n filters: ((resource.filters as Array<{ field: string }> | undefined) ?? [])\n .map((filter) => filter.field)\n .join(\", \"),\n }));\n\n const plain = flags.plain || !process.stdout.isTTY;\n return this.emit({\n status: \"ok\",\n data: listData(resources),\n pretty: renderList(COLUMNS, rows, {\n plain,\n singular: \"resource\",\n empty: \"No resources.\",\n footer: [`Run \\`${this.config.bin} <resource> <verb> --help\\` for a command's flags.`],\n }),\n });\n }\n}\n","import { CSRF_HEADER } from \"@zitadel/api/runtime/fetch\";\n\nimport { createZitadelClient } from \"../api-client\";\nimport type { LocalAdmin } from \"./admin-credential\";\nimport { adminSessionCookie, localAdminRequest } from \"./sign-in\";\n\n/** The team a project was attached to, and when. */\nexport type ProjectOwner = { team_id: string; claimed_at: string };\n\n/**\n * Attaches a freshly created project to the local admin's team, through the\n * same endpoints `zitadel claim` and the console use: `claim/init` with the\n * project secret, then `claim/complete` with the admin's session cookie.\n */\nexport async function claimProjectAsAdmin(input: {\n serverUrl: string;\n projectId: string;\n projectSecret: string;\n admin: LocalAdmin;\n}): Promise<ProjectOwner> {\n const { serverUrl, projectId, projectSecret, admin } = input;\n\n const { challenge_id } = await createZitadelClient({\n baseUrl: serverUrl,\n token: projectSecret,\n }).initClaim(projectId, localAdminRequest(serverUrl));\n\n // claim/complete authenticates by the admin's session cookie, not a bearer\n // token, so this client carries none. As a cookie-authenticated write it\n // also needs the session's CSRF token (ADR 053 §5), which the same cookie\n // reads from GET /sessions/me/csrf.\n const cookie = await adminSessionCookie(serverUrl, admin);\n const session = createZitadelClient({ baseUrl: serverUrl });\n const { csrf_token } = await session.getMySessionCsrfToken(\n undefined,\n localAdminRequest(serverUrl, { cookie }),\n );\n const { team_id, claimed_at } = await session.completeClaim(\n projectId,\n { challenge_id },\n localAdminRequest(serverUrl, { cookie, [CSRF_HEADER]: csrf_token }),\n );\n return { team_id, claimed_at };\n}\n","import type { ScaffoldPosture } from \"../../sync/types\";\n\n/**\n * Frameworks whose patchers add route files without owning the app shell —\n * the only ones where a pre-existing app keeps a layout for the widget\n * posture to inherit (ADR 044). The SPA families write the app's root\n * component, so nothing survives for a widget to embed into; they keep the\n * page posture until a non-destructive route/layout insertion contract\n * exists for their routers.\n *\n * SvelteKit, SolidStart, Qwik Router and TanStack Start now skip the shell and\n * landing page on a pre-existing app too, but stay out of this set until their\n * page templates honour `ctx.posture`: Next and Nuxt render `variant=\"widget\"`\n * cards in a layout-neutral wrapper for the widget posture, whereas the four\n * ignore posture and always paint page chrome, so recording `widget` for them\n * would misdescribe what was written.\n */\nconst ROUTE_BASED_FRAMEWORKS: ReadonlySet<string> = new Set([\"next\", \"nuxt\"]);\n\n/**\n * The default embedding posture of the scaffolded auth/profile pages\n * (ADR 044), derived from the same hinge as the framework homepage: whether\n * setup created the app skeleton itself. A fresh scaffold has no design to\n * respect — full-page chrome is the strongest start. A pre-existing\n * route-based app has its own shell and theme, so the pages embed\n * `variant=\"widget\"` cards in a layout-neutral wrapper instead of painting\n * token-colored chrome underneath the host layout.\n *\n * Derived once at setup time and recorded in the scaffold manifest;\n * `doctor --fix` restores from the record rather than re-deriving (a\n * manifest-less legacy scaffold could not answer the hinge).\n */\nexport function derivePosture(frameworkId: string, scaffoldedFramework: boolean): ScaffoldPosture {\n if (!ROUTE_BASED_FRAMEWORKS.has(frameworkId)) {\n return \"page\";\n }\n return scaffoldedFramework ? \"page\" : \"widget\";\n}\n","import { access, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport type {\n CreateFlowDefinition201,\n CreateIdpBodyIdp,\n CreateSchema201,\n CreateSchemaBody,\n} from \"@zitadel/api/generated/model\";\nimport type { ZitadelClient } from \"@zitadel/api/client\";\nimport {\n DEFAULT_FLOW_CONFIG_PATH,\n DEFAULT_FLOW_SCHEMA_URI,\n DEFAULT_SCHEMA_CONFIG_PATH,\n DEFAULT_SETUP_PRESET,\n DEFAULT_SETUP_USE_CASE,\n flowsReadmeContent,\n getDefaultHumanUserSchema,\n getDefaultLoginFlow,\n policiesReadmeContent,\n schemasReadmeContent,\n type SetupPreset,\n type SetupUseCase,\n} from \"@zitadel/config/defaults\";\nimport {\n type ConnectionEndpoints,\n type ConnectionSlug,\n type ProviderSelection,\n providerOf,\n} from \"@zitadel/config/idp\";\nimport {\n normalizeFlowBody,\n normalizeIdpBody,\n normalizeSchemaBody,\n} from \"@zitadel/config/normalize\";\nimport { policyConfigSchema } from \"@zitadel/config/schemas\";\n\nimport { FLOWS_DIR } from \"./flows\";\nimport {\n PASSWORD_POLICY_OPERATION,\n PASSWORD_POLICY_PATH,\n type PasswordMinLength,\n POLICIES_DIR,\n type PolicyFile,\n passwordPolicyFile,\n toPolicyWireBody,\n} from \"./policies\";\nimport {\n applySsoToFlow,\n applySsoToSchema,\n authMethods,\n CONNECTION_SCHEMA_REF,\n SETUP_FLAG_NAMES,\n IDPS_DIR,\n planConnection,\n readConnectionFiles,\n ssoEnableArgs,\n} from \"./idp\";\nimport { stableStringify } from \"./json\";\nimport { normalizePublicCliProse } from \"./public-cli\";\nimport { hashForState } from \"./sync\";\nimport { updateState } from \"./sync/state\";\nimport { SCHEMAS_DIR } from \"./user-schema\";\nimport { isMissingEndpoint, ZitadelError } from \"./errors\";\nimport { type SuggestedCommand, unscopedCommand } from \"./suggestion\";\nimport { reportWarning } from \"./warnings\";\n\nexport type MaterializeSetupResourcesResult = {\n filesWritten: string[];\n /**\n * Whether the password policy setup published has a minimum length. A kept\n * policy file decides that as much as the answers do: one without\n * `min_length` keeps none when none was given. `false` when nothing was\n * published.\n */\n passwordMinLengthSet: boolean;\n};\n\n/**\n * Scaffolds the versioned local default resources for a new project, uploads\n * them through the schema/flow APIs, and seeds `.zitadel/state.json` with the\n * IDs, hashes, and flow metadata the sync engine expects. Setup calls this only\n * after the framework patcher has created `.zitadel/{flows,schemas}` and the\n * initial state file.\n *\n * The schema is uploaded without an `$id`: the server assigns an opaque id on\n * `POST /schemas`. The flow names the schema by its `objectType`, but is\n * published after it because the server refuses a flow naming no schema.\n */\nexport async function materializeSetupResources(opts: {\n cwd: string;\n client: ZitadelClient;\n projectId: string;\n force: boolean;\n /** Sign-in preset (flow + auth methods) to scaffold; defaults to password-first. */\n preset?: SetupPreset;\n /** Use case (schema field set) to scaffold; defaults to minimal. */\n useCase?: SetupUseCase;\n /**\n * Social provider to enable while scaffolding. Its connection is written\n * and created before the schema and flow that reference it, so the Project\n * is never published naming a provider the platform does not hold.\n */\n /**\n * The providers to enable, in the order they were chosen. One connection is\n * created per entry, and every slug is added to the schema and the flow.\n */\n sso?: readonly { selection: ProviderSelection; endpoints?: ConnectionEndpoints }[];\n /**\n * The minimum password length to put into the password policy: a number,\n * `null` for an explicit none, or `undefined` when none was given. The\n * policy is written and published either way. A new one gets the\n * recommended minimum when none was given, and an empty `config`, which\n * enforces nothing, for none; a kept file keeps its `min_length` only when\n * none was given.\n */\n passwordMinLength?: PasswordMinLength;\n /**\n * CLI version used to render `zitadel …` command mentions in the scaffolded\n * READMEs as runnable `npx @zitadel/cli@<version> …` commands — the CLI is\n * not a dependency of the generated app, so the bare command doesn't exist\n * there.\n */\n cliVersion: string;\n}): Promise<MaterializeSetupResourcesResult> {\n await mkdir(join(opts.cwd, FLOWS_DIR), { recursive: true });\n await mkdir(join(opts.cwd, SCHEMAS_DIR), { recursive: true });\n\n const filesWritten: string[] = [];\n const preset = opts.preset ?? DEFAULT_SETUP_PRESET;\n const useCase = opts.useCase ?? DEFAULT_SETUP_USE_CASE;\n const schemaTemplate = defaultSchemaTemplate(preset, useCase);\n\n // The connection goes first, and is created before the schema and flow that\n // name its slug: a Project should never be published claiming a provider the\n // platform does not hold. Its claim mapping reads the template's properties,\n // which enabling the provider does not change.\n // Every file is checked before the first create, the schema and flow too.\n // Checking as each one is written would refuse \"before anything is created\"\n // only for the first: a conflict later on would leave a connection created\n // on the platform, its file written and its state recorded, and setup does\n // not remove a connection file it wrote -- so the retry would then refuse\n // on that file too, with nothing but the developer able to clear it. One\n // pass to build and refuse, a second to create. Setup runs the same pass\n // before it creates the project, through assertNoSetupResourceConflicts.\n const planned = planConnections(schemaTemplate, opts.sso);\n await refuseResourceConflicts(opts.cwd, opts.force, planned);\n\n const slugs = planned.map((entry) => entry.slug);\n for (const { connectionPath, connection, selection } of planned) {\n // The create comes before the file. Setup does not remove a connection\n // file it wrote -- that rule is what keeps a developer's own file safe --\n // so writing first would leave one behind on any failure here and the\n // retry would then refuse on it, with nothing able to clear it but the\n // developer. Creating first means a failure leaves nothing to clear.\n //\n // `client_secret` travels as its `${{ NAME }}` reference: the platform\n // resolves it from the environment's variables, so no credential is sent\n // here and none is written to the file.\n const created = await opts.client.createIdp(\n { idp: connection as CreateIdpBodyIdp },\n { project_id: opts.projectId },\n );\n\n await mkdir(join(opts.cwd, IDPS_DIR), { recursive: true });\n // Still `wx` rather than `opts.force`: the check above is the early\n // refusal, this is the one that cannot be raced.\n if (\n await writeResourceFile(\n opts.cwd,\n connectionPath,\n connection,\n false,\n connectionExists(selection),\n )\n ) {\n filesWritten.push(join(opts.cwd, connectionPath));\n }\n // The file stays as written: the stored connection spells out defaults\n // the file leaves to the server, and `plan` reads those as no change.\n await updateState(opts.cwd, connectionPath, {\n id: requiredString(created.id, \"created identity provider connection id\"),\n hash: hashForState({ normalize: normalizeIdpBody }, connection),\n });\n }\n\n // Each slug in turn: the edits are additive and idempotent, so folding them\n // builds one schema that names every chosen provider.\n const schemaBody = slugs.reduce<Record<string, unknown>>(\n (document, slug) => applySsoToSchema(document, slug).document as Record<string, unknown>,\n schemaTemplate,\n );\n\n const schemaWritten = await writeResourceFile(\n opts.cwd,\n DEFAULT_SCHEMA_CONFIG_PATH,\n schemaBody,\n opts.force,\n );\n if (schemaWritten) {\n filesWritten.push(join(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH));\n }\n\n const schema = (await opts.client.createSchema(schemaBody as CreateSchemaBody, {\n project_id: opts.projectId,\n })) as CreateSchema201;\n await updateState(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH, {\n id: requiredString(schema.id, \"created schema id\"),\n hash: hashForState({ normalize: normalizeSchemaBody }, schemaBody),\n });\n\n const flowTemplate = getDefaultLoginFlow({ preset, useCase });\n // The conflict step the provider needs can only offer what this schema\n // actually enables, so the methods are read back off the composed document\n // rather than inferred from the preset.\n const flowBody = slugs.reduce<typeof flowTemplate>(\n (document, slug) =>\n applySsoToFlow(document, slug, authMethods(schemaBody)).document as typeof flowTemplate,\n flowTemplate,\n );\n\n const flowWritten = await writeResourceFile(\n opts.cwd,\n DEFAULT_FLOW_CONFIG_PATH,\n flowBody,\n opts.force,\n );\n if (flowWritten) {\n filesWritten.push(join(opts.cwd, DEFAULT_FLOW_CONFIG_PATH));\n }\n\n const flow = (await opts.client.createFlowDefinition({\n project_id: opts.projectId,\n schema_uri: DEFAULT_FLOW_SCHEMA_URI,\n flow_definition: flowBody,\n })) as CreateFlowDefinition201;\n\n await updateState(opts.cwd, DEFAULT_FLOW_CONFIG_PATH, {\n id: requiredString(flow.id, \"created flow definition id\"),\n hash: hashForState({ normalize: normalizeFlowBody }, flowBody),\n name: flowBody.name,\n status: flowBody.status,\n });\n\n // The password policy, created before its file like the connections. A new\n // one gets the recommended minimum unless the developer gave another or\n // none. A policy file already there (only with --force: without it the\n // conflict check refused it) holds a project's chosen rules, so it is kept\n // and published as it is; a minimum given now goes into it.\n const kept = opts.force ? await readPasswordPolicyFile(opts.cwd) : undefined;\n const policy =\n kept === undefined\n ? passwordPolicyFile(opts.passwordMinLength)\n : withMinLength(kept, opts.passwordMinLength);\n let published: { id?: unknown } | undefined;\n try {\n published = await opts.client.publishPolicy(toPolicyWireBody(policy), {\n project_id: opts.projectId,\n });\n } catch (error) {\n if (!isMissingEndpoint(error)) {\n throw error;\n }\n // A server from before operation policies: the project works without\n // one, so setup goes on without the file rather than failing.\n reportWarning(\n \"The server has no policy endpoints yet, so setup wrote no password policy. Upgrade the server, then add .zitadel/policies/ and run `zitadel deploy`.\",\n );\n }\n if (published !== undefined) {\n await mkdir(join(opts.cwd, POLICIES_DIR), { recursive: true });\n if (\n (kept === undefined || policy !== kept) &&\n (await writeResourceFile(opts.cwd, PASSWORD_POLICY_PATH, policy, opts.force))\n ) {\n filesWritten.push(join(opts.cwd, PASSWORD_POLICY_PATH));\n }\n await updateState(opts.cwd, PASSWORD_POLICY_PATH, {\n id: requiredString(published.id, \"published policy id\"),\n hash: hashForState({ normalize: (body) => toPolicyWireBody(body as PolicyFile) }, policy),\n });\n }\n\n const schemasReadme = join(SCHEMAS_DIR, \"README.md\");\n const flowsReadme = join(FLOWS_DIR, \"README.md\");\n const policiesReadme = join(POLICIES_DIR, \"README.md\");\n if (\n await writeReadmeFile(\n opts.cwd,\n schemasReadme,\n normalizePublicCliProse(schemasReadmeContent(), opts.cliVersion),\n )\n ) {\n filesWritten.push(join(opts.cwd, schemasReadme));\n }\n if (\n await writeReadmeFile(\n opts.cwd,\n flowsReadme,\n normalizePublicCliProse(flowsReadmeContent(), opts.cliVersion),\n )\n ) {\n filesWritten.push(join(opts.cwd, flowsReadme));\n }\n if (\n published !== undefined &&\n (await writeReadmeFile(\n opts.cwd,\n policiesReadme,\n normalizePublicCliProse(policiesReadmeContent(), opts.cliVersion),\n ))\n ) {\n filesWritten.push(join(opts.cwd, policiesReadme));\n }\n\n return {\n filesWritten,\n passwordMinLengthSet: published !== undefined && policy.config.min_length !== undefined,\n };\n}\n\n/**\n * Throws the `E_CONFLICT` {@link materializeSetupResources} would throw on a\n * file it refuses to write: the default schema or flow without `force`, or a\n * connection for one of the chosen providers, which it never replaces.\n *\n * Setup calls this before it creates the project. Those files are written\n * only once the project exists, so a conflict found there leaves the project\n * behind, and a rerun keeps its id and secret in `.env.local`: setup merges\n * only the keys that file is missing.\n */\nexport async function assertNoSetupResourceConflicts(opts: {\n cwd: string;\n force: boolean;\n preset?: SetupPreset;\n useCase?: SetupUseCase;\n sso?: readonly { selection: ProviderSelection; endpoints?: ConnectionEndpoints }[];\n}): Promise<void> {\n const schemaTemplate = defaultSchemaTemplate(\n opts.preset ?? DEFAULT_SETUP_PRESET,\n opts.useCase ?? DEFAULT_SETUP_USE_CASE,\n );\n await refuseResourceConflicts(opts.cwd, opts.force, planConnections(schemaTemplate, opts.sso));\n}\n\n/** The default human user schema for a preset and use case, without the template's `$id`. */\nfunction defaultSchemaTemplate(\n preset: SetupPreset,\n useCase: SetupUseCase,\n): Record<string, unknown> {\n const { $id: _templateId, ...schemaTemplate } = getDefaultHumanUserSchema({\n preset,\n useCase,\n }) as { $id?: string } & Record<string, unknown>;\n void _templateId;\n return schemaTemplate;\n}\n\ntype PlannedConnection = {\n slug: ConnectionSlug;\n connectionPath: string;\n connection: object;\n selection: ProviderSelection;\n};\n\n/** The connection each chosen provider gets, and the file it is written to. */\nfunction planConnections(\n schemaTemplate: Record<string, unknown>,\n sso: readonly { selection: ProviderSelection; endpoints?: ConnectionEndpoints }[] | undefined,\n): PlannedConnection[] {\n const planned: PlannedConnection[] = [];\n for (const chosen of sso ?? []) {\n const provider = providerOf(chosen.selection);\n const connection = provider.connection({\n endpoints: chosen.endpoints,\n schemaProperties: Object.keys((schemaTemplate.properties as object | undefined) ?? {}),\n schemaRef: CONNECTION_SCHEMA_REF,\n });\n planned.push({\n slug: provider.slug,\n connectionPath: `${IDPS_DIR}/${provider.slug}.json`,\n connection,\n selection: chosen.selection,\n });\n }\n return planned;\n}\n\n/**\n * Throws on the first file setup would refuse to write. A connection is\n * refused with or without `force`, for two reasons: the file is the\n * developer's (see {@link connectionExists}), and finding out after the\n * create would leave the project holding a connection no local file tracks.\n *\n * The same questions `auth-method sso enable` asks: which file holds the slug, and whose\n * variables would collide. A plan that throws names the conflict; one that\n * says reuse means a connection file already holds this provider.\n */\nasync function refuseResourceConflicts(\n cwd: string,\n force: boolean,\n connections: readonly PlannedConnection[],\n): Promise<void> {\n // Read only when a provider was chosen: a leftover file that does not parse\n // is no reason for a plain setup to fail.\n const files = connections.length > 0 ? await readConnectionFiles(cwd) : [];\n for (const { connectionPath, selection } of connections) {\n const existing = planConnection({ selection, files, slugFlag: SETUP_FLAG_NAMES.slug });\n if (existing.action === \"reuse\" || (await exists(join(cwd, connectionPath)))) {\n throw resourceExists(\n existing.action === \"reuse\" ? existing.file.path : connectionPath,\n connectionExists(selection),\n );\n }\n }\n if (force) {\n // --force keeps a policy file and publishes it, so a broken one is refused\n // here, before the project is created or anything is written.\n await readPasswordPolicyFile(cwd);\n return;\n }\n for (const path of [DEFAULT_SCHEMA_CONFIG_PATH, DEFAULT_FLOW_CONFIG_PATH]) {\n if (await exists(join(cwd, path))) {\n throw resourceExists(path);\n }\n }\n if (await exists(join(cwd, PASSWORD_POLICY_PATH))) {\n throw resourceExists(PASSWORD_POLICY_PATH, {\n hint: \"Rerun setup with --force to keep this policy and publish it to the new project, or move the file aside to start from an empty one.\",\n });\n }\n}\n\n/**\n * A kept policy file with the minimum setup was given: unchanged when none was\n * given, without `min_length` for an explicit \"none\", with the new value\n * otherwise. Its other settings stay as the project chose them.\n */\nfunction withMinLength(kept: PolicyFile, minLength: PasswordMinLength | undefined): PolicyFile {\n // Unchanged is the file as it is, so setup neither rewrites nor reports it.\n if (minLength === undefined || (minLength ?? undefined) === kept.config.min_length) {\n return kept;\n }\n const { min_length: _dropped, ...rest } = kept.config;\n void _dropped;\n return { ...kept, config: minLength === null ? rest : { ...rest, min_length: minLength } };\n}\n\n/**\n * The password policy file a project already has, or `undefined` when there is\n * none. It must be a valid policy for the password operation: setup publishes\n * it as it is, so a broken one is refused here, before it reaches the server.\n */\nasync function readPasswordPolicyFile(cwd: string): Promise<PolicyFile | undefined> {\n let raw: string;\n try {\n raw = await readFile(join(cwd, PASSWORD_POLICY_PATH), \"utf8\");\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return undefined;\n }\n throw error;\n }\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch {\n data = undefined;\n }\n const result = policyConfigSchema.safeParse(data);\n if (!result.success || result.data.operation !== PASSWORD_POLICY_OPERATION) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${PASSWORD_POLICY_PATH} is not a valid password policy`,\n {\n hint: \"Setup keeps an existing policy file and publishes it, so fix it against .zitadel/meta/policy.json or move it aside to start from an empty one.\",\n details: { file: PASSWORD_POLICY_PATH },\n },\n );\n }\n return data as PolicyFile;\n}\n\n/**\n * Write a README file, but never overwrite an existing one. A developer who\n * has edited the README should keep their edits when `setup --force` is\n * re-run.\n */\nasync function writeReadmeFile(cwd: string, relPath: string, content: string): Promise<boolean> {\n const dest = join(cwd, relPath);\n await mkdir(dirname(dest), { recursive: true });\n try {\n await writeFile(dest, content, { flag: \"wx\" });\n return true;\n } catch (error) {\n if (isErrno(error, \"EEXIST\")) {\n return false;\n }\n throw error;\n }\n}\n\n/**\n * What to do about a connection file setup will not touch.\n *\n * Setup neither replaces nor removes one, with or without `--force`: a\n * connection may hold a client id someone registered with the vendor and a slug\n * the schemas and flows already name, and the IdP contract makes these files\n * tenant-owned. So the one rule is that setup does not write there, and the\n * developer decides what happens to the file.\n */\nfunction connectionExists(selection: ProviderSelection): {\n hint: string;\n nextCommands: SuggestedCommand[];\n} {\n return {\n hint:\n \"A connection file is yours to keep, so setup never replaces or removes one. \" +\n \"Remove it and run setup again to scaffold a fresh one, or keep it and enable the \" +\n \"provider afterwards to reuse it.\",\n // Setup stopped before it created a project, so there is no environment\n // to carry: the retry is for after the developer reruns setup.\n nextCommands: [unscopedCommand(ssoEnableArgs(selection))],\n };\n}\n\n/** Whether a path is there, without caring why it is not. */\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function writeResourceFile(\n cwd: string,\n relPath: string,\n body: object,\n force: boolean,\n onExists?: { hint: string; nextCommands?: SuggestedCommand[] },\n): Promise<boolean> {\n const contents = `${stableStringify(body)}\\n`;\n try {\n await writeFile(join(cwd, relPath), contents, force ? undefined : { flag: \"wx\" });\n return true;\n } catch (error) {\n if (isErrno(error, \"EEXIST\")) {\n throw resourceExists(relPath, onExists);\n }\n throw error;\n }\n}\n\nfunction resourceExists(\n relPath: string,\n onExists?: { hint: string; nextCommands?: SuggestedCommand[] },\n): ZitadelError {\n return new ZitadelError(\"E_CONFLICT\", `${relPath} already exists`, {\n hint:\n onExists?.hint ??\n \"Move the file aside or rerun setup with --force if you want setup to replace it.\",\n nextCommands: onExists?.nextCommands,\n });\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value === \"string\" && value.length > 0) {\n return value;\n }\n throw new ZitadelError(\"E_VALIDATION\", `Missing ${label} in server response.`);\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 NodeJS.ErrnoException).code === code\n );\n}\n","import { consola } from \"consola\";\n\nimport type { BoxAction } from \"../../lib/box\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { customizeAndPublishActions, verifyLoginAction } from \"../../lib/journey-guidance\";\nimport {\n detectPackageManager,\n devCommandFor,\n installCommandFor,\n runPackageCommand,\n type PackageCommand,\n type PackageManager,\n} from \"../../lib/package-manager\";\nimport {\n type EnvironmentSelector,\n projectCommand,\n shellCommand,\n type SuggestedCommand,\n} from \"../../lib/suggestion\";\n\ntype InstallReason = \"dry-run\" | \"skip-install\" | \"no-dependency-changes\";\n\nexport type SetupInstall = {\n status: \"completed\" | \"skipped\" | \"not-needed\";\n package_manager: PackageManager;\n command: string;\n reason?: InstallReason;\n};\n\nexport type SetupInstallOutcome = {\n install: SetupInstall;\n devCommand: string;\n /**\n * Journey-staged subset for the human terminal box: the verify mission\n * plus one breadcrumb to `status`/README. Customize/publish guidance stays\n * out until login demonstrably works (Elina, alpha.15). Structured so the\n * box renderer can pull each command onto its own styled line; the envelope\n * strings below stay plain prose.\n */\n boxActions: BoxAction[];\n /** Complete journey for the JSON envelope — agents consume all of it. */\n nextActions: string[];\n nextCommands: SuggestedCommand[];\n};\n\nexport type SetupInstallInput = {\n cliVersion: string;\n cwd: string;\n depsAdded: ReadonlyArray<string>;\n dryRun: boolean;\n env: NodeJS.ProcessEnv;\n issuer: string;\n json: boolean;\n /**\n * The selector pinning the project setup just created, for the follow-ups\n * below. Without it a bare `status`/`deploy` resolves the environment as the\n * next shell does, where the process environment outranks the `.env` files:\n * in a shell holding production values the follow-up would read — or publish\n * to — another project.\n */\n selector: EnvironmentSelector;\n scaffoldedFramework: boolean;\n skipInstall: boolean;\n run?: typeof runPackageCommand;\n};\n\nexport async function installDependenciesForSetup(\n input: SetupInstallInput,\n): Promise<SetupInstallOutcome> {\n const packageManager = await detectPackageManager(input.cwd);\n const installCommand = installCommandFor(packageManager);\n const devCommand = devCommandFor(packageManager);\n const needsInstall = input.scaffoldedFramework || input.depsAdded.length > 0;\n\n if (!needsInstall) {\n return outcome({\n install: {\n status: \"not-needed\",\n package_manager: packageManager,\n command: installCommand.display,\n reason: \"no-dependency-changes\",\n },\n devCommand: devCommand.display,\n cliVersion: input.cliVersion,\n issuer: input.issuer,\n selector: input.selector,\n includeInstallCommand: false,\n });\n }\n\n if (input.dryRun || input.skipInstall) {\n return outcome({\n install: {\n status: \"skipped\",\n package_manager: packageManager,\n command: installCommand.display,\n reason: input.dryRun ? \"dry-run\" : \"skip-install\",\n },\n devCommand: devCommand.display,\n cliVersion: input.cliVersion,\n issuer: input.issuer,\n selector: input.selector,\n includeInstallCommand: true,\n });\n }\n\n consola.start(`Installing dependencies with ${installCommand.display}`);\n try {\n await (input.run ?? runPackageCommand)(installCommand, {\n cwd: input.cwd,\n env: input.env,\n redirectStdoutToStderr: input.json,\n });\n } catch (error) {\n throw installFailed(error, installCommand, devCommand, input.cwd);\n }\n consola.success(\"Installed dependencies\");\n\n return outcome({\n install: {\n status: \"completed\",\n package_manager: packageManager,\n command: installCommand.display,\n },\n devCommand: devCommand.display,\n cliVersion: input.cliVersion,\n issuer: input.issuer,\n selector: input.selector,\n includeInstallCommand: false,\n });\n}\n\nfunction outcome(input: {\n install: SetupInstall;\n devCommand: string;\n cliVersion: string;\n issuer: string;\n selector: EnvironmentSelector;\n includeInstallCommand: boolean;\n}): SetupInstallOutcome {\n const planCommand = projectCommand(\"deploy --dry-run\", input.selector, input.cliVersion);\n const statusCommand = projectCommand(\"status\", input.selector, input.cliVersion);\n const verifyActions = [\n ...(input.includeInstallCommand ? [`Install dependencies: ${input.install.command}`] : []),\n `Start your project: ${input.devCommand} (then open ${input.issuer}/login)`,\n verifyLoginAction(),\n ];\n const boxActions: BoxAction[] = [\n ...(input.includeInstallCommand\n ? [{ text: \"Install dependencies:\", command: input.install.command }]\n : []),\n { text: `Start your project (then open ${input.issuer}/login):`, command: input.devCommand },\n { text: verifyLoginAction() },\n // The dev server holds the terminal it starts in, and every later command\n // reads `.zitadel/` from this directory.\n {\n text: \"The dev server keeps its terminal busy. Open a second terminal in this directory for further commands.\",\n },\n {\n text: \"Once login works, this shows your next steps (customizing is covered in your README's Zitadel section):\",\n command: statusCommand,\n },\n ];\n return {\n install: input.install,\n devCommand: input.devCommand,\n boxActions,\n nextActions: [\n ...verifyActions,\n ...customizeAndPublishActions(input.cliVersion, input.selector),\n ],\n nextCommands: input.includeInstallCommand\n ? [shellCommand(input.install.command), shellCommand(input.devCommand), planCommand]\n : [shellCommand(input.devCommand), planCommand],\n };\n}\n\nfunction installFailed(\n error: unknown,\n installCommand: PackageCommand,\n devCommand: PackageCommand,\n cwd: string,\n): ZitadelError {\n return new ZitadelError(\"E_VALIDATION\", `Dependency install failed: ${installCommand.display}`, {\n hint: `Run ${installCommand.display} in ${cwd}, then start the app with ${devCommand.display}.`,\n nextCommands: [shellCommand(installCommand.display)],\n details: { command: installCommand.display, cwd, original: errorShape(error) },\n });\n}\n\nfunction errorShape(error: unknown): Record<string, unknown> {\n if (error instanceof Error) {\n return {\n name: error.name,\n message: error.message,\n code: (error as NodeJS.ErrnoException).code,\n };\n }\n return { message: String(error) };\n}\n","import { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { createZitadelClient } from \"../../lib/api-client\";\nimport { toZitadelError, ZitadelError } from \"../../lib/errors\";\nimport { IDPS_DIR } from \"../../lib/idp/connections\";\nimport { issuerFromPort, type Orca } from \"../../lib/orca\";\nimport { portFromIssuer } from \"../../lib/orca/detectors/port\";\nimport { replaceOrigin } from \"../../lib/orca/patchers/rule/dev-port-move\";\nimport type { PatchResult } from \"../../lib/orca/patchers/types\";\nimport { readZitadelSecret, writeZitadelSecret } from \"../../lib/project\";\nimport { readScaffoldManifest } from \"../../lib/scaffold-manifest\";\nimport { updateScaffold } from \"../../lib/sync/state\";\nimport { loadPatchContext } from \"../doctor/patch-context\";\n\n/** What {@link moveDevPort} changed. */\nexport type DevPortMove = Readonly<{\n previousIssuer: string;\n issuer: string;\n result: PatchResult;\n /** The provider slugs whose redirect URI still names the previous port. */\n ssoProviders: ReadonlyArray<string>;\n /** Set when the previous origin could not be removed from the project. */\n staleOrigin?: string;\n}>;\n\n/**\n * Moves an app setup already patched to another dev port, in one step: the\n * project's origin on the server, then the dev script or dev-server config,\n * `ZITADEL_ISSUER` in `.env.local`, `zitadel.json`, `.zitadel/secret` and the\n * README/AGENTS.md guidance. Backs `setup --dev-port` on an app that already\n * has a `zitadel.json`, which otherwise has nothing left to set up.\n *\n * The new origin is added before any file changes, so a server that refuses\n * leaves the app as it was. The previous origin is removed last; a failure\n * there is reported, not thrown, because the app already works on the new\n * port and the old pattern only admits a port nothing serves any more.\n */\nexport async function moveDevPort(opts: {\n cwd: string;\n devPort: number;\n source: string;\n orca: Orca;\n cliVersion: string;\n dryRun: boolean;\n}): Promise<DevPortMove> {\n const { cwd, devPort, source, orca, cliVersion, dryRun } = opts;\n const context = await loadPatchContext(cwd, orca, cliVersion);\n const previousIssuer = context.issuer;\n const issuer = issuerFromPort(devPort);\n const secret = await readZitadelSecret(cwd);\n const moving = previousIssuer !== issuer;\n\n const client = createZitadelClient({ baseUrl: source, token: secret.project_secret });\n if (!dryRun) {\n try {\n await client.addOrigin(secret.project_id, { pattern: issuer, kind: \"primary\" });\n } catch (error) {\n const normalized = toZitadelError(error);\n throw new ZitadelError(normalized.code, `Could not allow ${issuer} for this project`, {\n hint: `${normalized.message}. Nothing was changed; start the server this app uses (${source}) and retry.`,\n details: { original: normalized.details },\n });\n }\n }\n\n const ctx = {\n ...context,\n issuer,\n framework: { ...context.framework, devPort, url: issuer },\n };\n const patcher = orca.patcherFor(ctx.framework.id);\n const result = await patcher.moveDevPort(ctx, previousIssuer, { cwd, dryRun, force: false });\n\n let staleOrigin: string | undefined;\n if (!dryRun) {\n // The app's own origin is primary, so the move rewrites that list. An\n // older secret that still carries the issuer as a preview pattern is\n // rewritten too, so the stale URL is not left behind either way.\n const rewrite = (patterns: string[]): string[] =>\n replaceOrigin(patterns, previousIssuer, issuer).filter(\n (pattern) => typeof pattern === \"string\",\n );\n await writeZitadelSecret(cwd, {\n ...secret,\n primary_origins: rewrite(secret.primary_origins),\n preview_origins: rewrite(secret.preview_origins),\n });\n const manifest = await readScaffoldManifest(cwd);\n if (manifest !== undefined) {\n await updateScaffold(cwd, { ...manifest, dev_port: devPort });\n }\n if (moving && portFromIssuer(previousIssuer) !== undefined) {\n try {\n await client.removeOrigin(secret.project_id, { pattern: previousIssuer });\n } catch {\n staleOrigin = previousIssuer;\n }\n }\n }\n\n return {\n previousIssuer,\n issuer,\n result,\n ssoProviders: moving ? await connectionSlugs(cwd) : [],\n ...(staleOrigin === undefined ? {} : { staleOrigin }),\n };\n}\n\n/** The slugs of the connection files under `.zitadel/idps/`. */\nasync function connectionSlugs(cwd: string): Promise<string[]> {\n try {\n const entries = await readdir(join(cwd, IDPS_DIR));\n return entries\n .filter((name) => name.endsWith(\".json\"))\n .map((name) => name.slice(0, -\".json\".length))\n .sort();\n } catch {\n return [];\n }\n}\n","import type { Parsed } from \"@zitadel/config/idp\";\n\nimport { LocalServer } from \"../../../lib/local-server/server\";\nimport type { PromptContext, SetupAnswers, SetupPrompt } from \"./types\";\n\n/**\n * \"Port 3000 is in use. Which port should your app run on?\" — asked only when\n * something already holds the detected port. A free one is nearly always the\n * answer, and a question whose answer is Enter is one more step for nothing:\n * the summary shows the port, and `setup --dev-port` moves a set-up app later.\n * A taken one is worth the question, because setup pins the dev script to the\n * port and the dev server then fails to start on it.\n *\n * The suggestion is the next free port, so Enter, which the developer has\n * pressed at every question before this one, gives a port the dev server can\n * start on. If what holds the detected port is this app's own dev server, the\n * next one works as well, and the detected one can still be typed back. The\n * validated answer becomes the issuer URL (`http://localhost:<port>`) via\n * `issuerFromPort`.\n */\nexport class DevPortPrompt implements SetupPrompt {\n async ask(answers: SetupAnswers, ctx: PromptContext): Promise<SetupAnswers> {\n // `--dev-port <n>` is authoritative: skip the prompt so an interactive\n // answer can't override the explicit flag (the base command already folded\n // it into answers.devPort).\n if (ctx.devPortFromFlag || (await LocalServer.isPortFree(answers.devPort))) {\n return answers;\n }\n // With the next ones all taken too, the detected port is still the best guess.\n const suggested = String((await LocalServer.nextFreePort(answers.devPort)) ?? answers.devPort);\n const devPort = await ctx.input({\n kind: \"text\",\n name: \"dev server port\",\n message: `Port ${answers.devPort} is in use. Which port should your app run on?`,\n placeholder: suggested,\n initialValue: suggested,\n parse: (value): Parsed<number> => {\n const port = Number.parseInt(value, 10);\n return Number.isFinite(port) && port > 0 && port < 65536\n ? { ok: true, value: port }\n : { ok: false, problem: \"Must be a port number\" };\n },\n });\n return { ...answers, devPort };\n }\n}\n","import { ZitadelError } from \"../../../lib/errors\";\nimport type { PromptContext, SetupAnswers, SetupPrompt } from \"./types\";\n\n/**\n * \"Would you like to set up Zitadel in this `<framework>` app?\" — the\n * wizard's first question in an app setup found, asked before anything in it\n * changes. Accepting leaves answers unchanged.\n *\n * Declining throws `E_UNSUPPORTED_PROJECT_SHAPE`, and the hint points at the\n * one way to a different app: running setup in its directory. `--framework`\n * is no way out, because setup refuses a framework other than the one it\n * detects here (`E_CONFLICT`), so the hint does not offer it.\n *\n * Skipped when the developer already named the framework, by picking it to\n * scaffold or with `--framework`: detection then only read back their own\n * answer.\n */\nexport class FrameworkConfirmPrompt implements SetupPrompt {\n async ask(answers: SetupAnswers, ctx: PromptContext): Promise<SetupAnswers> {\n if (ctx.frameworkChosen) {\n return answers;\n }\n const ack = await ctx.input({\n kind: \"confirm\",\n name: \"confirm the framework\",\n message: `Would you like to set up Zitadel in this ${ctx.framework.displayName} app?`,\n initialValue: true,\n });\n if (ack === false) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n `Setup stopped before changing this ${ctx.framework.displayName} app`,\n {\n hint: \"To set up another app, run setup in its directory, or pass --cwd with that directory.\",\n },\n );\n }\n return answers;\n }\n}\n","import { type PasswordMinLength, RECOMMENDED_PASSWORD_MIN_LENGTH } from \"../../../lib/policies\";\nimport type { PromptContext, SetupAnswers, SetupPrompt } from \"./types\";\n\n/**\n * \"Which minimum length should passwords have?\" — a choice of 15\n * characters, 8 or none, with 15 preselected and marked recommended. Setup\n * always writes the password policy file; the answer goes into it, and \"none\"\n * leaves its `config` empty, which enforces nothing.\n *\n * The two lengths are NIST SP 800-63B-4's: at least 15 characters for a\n * password that is the only factor, at least 8 for one that is only ever part\n * of multi-factor sign-in. The developer still decides; the wizard only says\n * which answer is the safe one, and any other length goes into\n * `.zitadel/policies/` or `--password-min-length`. A run with nobody to ask\n * gets the same 15 unless the flag says otherwise (`passwordPolicyFile`).\n *\n * `--password-min-length` is authoritative and skips the question.\n */\nexport class PasswordPolicyPrompt implements SetupPrompt {\n async ask(answers: SetupAnswers, ctx: PromptContext): Promise<SetupAnswers> {\n if (ctx.passwordMinLengthFromFlag) {\n return answers;\n }\n const options: { value: PasswordMinLength; label: string; hint?: string }[] = [\n {\n value: RECOMMENDED_PASSWORD_MIN_LENGTH,\n // Not \"(recommended)\": the prompt puts the hint in parentheses too.\n label: `${RECOMMENDED_PASSWORD_MIN_LENGTH} characters — recommended`,\n hint: \"NIST minimum for password-only sign-in\",\n },\n { value: 8, label: \"8 characters\", hint: \"NIST minimum with a second factor\" },\n { value: null, label: \"No minimum\" },\n ];\n const passwordMinLength = await ctx.input({\n kind: \"select\",\n name: \"minimum password length\",\n message: \"Which minimum length should passwords have? You can change it later.\",\n initialValue: RECOMMENDED_PASSWORD_MIN_LENGTH,\n options,\n });\n return { ...answers, passwordMinLength };\n }\n}\n","import { spinner } from \"@clack/prompts\";\n\nimport type { Parsed } from \"@zitadel/config/idp\";\n\nimport { LocalServer } from \"../../../lib/local-server/server\";\nimport { DEFAULT_SERVER } from \"../../../lib/server\";\nimport type { PromptContext, SetupAnswers, SetupPrompt } from \"./types\";\n\n/** Sentinel returned by the choice select when the user picks \"Custom URL\". */\nconst CUSTOM = \"__custom__\";\n/** The value of the disabled local option, which can never be picked. */\nconst LOCAL_NOT_RUNNING = \"__local_not_running__\";\n\n/**\n * \"Which Zitadel server should your app use?\" — Zitadel Cloud, the managed\n * local server, or a custom URL. Setup creates the project there, so the\n * question names the server and not the file that records it.\n *\n * Before asking, it looks for a healthy local Zitadel server the same way the\n * rest of the CLI does (`LocalServer.detectUrl`: the server the runtime\n * metadata `zitadel start` wrote to `.zitadel/local/runtime.json` names, when\n * its own process answers a `/readyz` probe). A detected server becomes an\n * option *and* the preselected answer — a user who just ran `zitadel start`\n * almost certainly wants it, and `start`'s own next-step hint says\n * `setup --server local`. Without one, the local option is still listed,\n * disabled, saying how to get it, so the choice is visible before it is\n * available. Picking a server writes its URL directly to `answers.server`;\n * picking \"Custom URL\" still asks for a validated URL.\n */\nexport class ServerPrompt implements SetupPrompt {\n async ask(answers: SetupAnswers, ctx: PromptContext): Promise<SetupAnswers> {\n // `--server <url>` overrides the wizard entirely. The base command\n // already validated and resolved the URL into `answers.server`;\n // asking the user to re-pick from a fixed select list when their\n // flag isn't in the list (Cloud / detected / Custom) was a bug —\n // clack would silently default back to Cloud.\n if (ctx.serverFlag) {\n return answers;\n }\n const detected = await detectLocalServer(ctx.cwd);\n\n const choice = await ctx.input({\n kind: \"select\",\n name: \"server\",\n message: \"Which Zitadel server should your app use?\",\n options: [\n {\n value: DEFAULT_SERVER,\n label: `Zitadel Cloud (${new URL(DEFAULT_SERVER).host})`,\n },\n detected\n ? {\n value: detected,\n label: `Local server (${detected})`,\n hint: \"started with zitadel start\",\n }\n : {\n value: LOCAL_NOT_RUNNING,\n label: \"Local server\",\n hint: \"not running — run zitadel start first\",\n disabled: true,\n },\n { value: CUSTOM, label: \"Custom URL (self-hosted)\" },\n ],\n initialValue: detected ?? answers.server ?? DEFAULT_SERVER,\n });\n if (choice !== CUSTOM) {\n return { ...answers, server: choice };\n }\n const custom = await ctx.input({\n kind: \"text\",\n name: \"server URL\",\n message: \"What is the URL of your Zitadel server?\",\n placeholder: \"https://zitadel.internal\",\n parse: (value): Parsed<string> => {\n try {\n new URL(value);\n return { ok: true, value };\n } catch {\n return { ok: false, problem: \"Must be a valid URL\" };\n }\n },\n });\n return { ...answers, server: custom };\n }\n}\n\n/**\n * Wraps {@link LocalServer.detectUrl} in a spinner: the `/readyz` probe of a\n * server that does not answer takes up to 1.5s, long enough that the wizard\n * should say what it is doing. The spinner then clears instead of leaving a\n * line behind, because the options it decides already say what it found, and\n * it draws no guide line of its own, which clearing would leave behind.\n */\nasync function detectLocalServer(cwd: string): Promise<string | undefined> {\n const s = spinner({ withGuide: false });\n s.start(\"Checking for a local Zitadel server\");\n const detected = await LocalServer.detectUrl(cwd);\n s.clear();\n return detected;\n}\n","import { SETUP_PRESETS, type SetupPreset } from \"@zitadel/config/defaults\";\n\nimport type { PromptContext, SetupAnswers, SetupPrompt } from \"./types\";\n\n/**\n * \"Which sign-in method should your app offer first?\" — picks the schema+flow preset the scaffold\n * starts from (#448: app-type/preset selection before any `.zitadel/` file\n * is written). `--preset` is authoritative; non-interactive runs keep the\n * password-first default seeded by the command.\n */\nexport class SignInPresetPrompt implements SetupPrompt {\n async ask(answers: SetupAnswers, ctx: PromptContext): Promise<SetupAnswers> {\n if (ctx.presetFromFlag) {\n return answers;\n }\n // Each label names the method offered first and the other one, because\n // both presets enable password and passkey in the schema: the choice is\n // only which one the login flow leads with.\n const labels: Record<SetupPreset, string> = {\n \"password-first\": \"Email and password, with passkeys also available\",\n \"passkey-first\": \"Passkey, with email and password as the fallback\",\n };\n const preset = await ctx.input({\n kind: \"select\",\n name: \"sign-in preset\",\n message: \"Which sign-in method should your app offer first?\",\n initialValue: answers.preset,\n options: SETUP_PRESETS.map((preset) => ({ value: preset, label: labels[preset] })),\n });\n return { ...answers, preset };\n }\n}\n","import { log, note } from \"@clack/prompts\";\n\nimport {\n credentialVariables,\n CUSTOM_PROVIDER,\n type ClientId,\n type CustomOidcInput,\n DEFAULT_SCOPES,\n idpProvider,\n IDP_PROVIDERS,\n RESERVED_SLUGS,\n type IdpProvider,\n type Issuer,\n parseClientId,\n parseClientSecret,\n parseConnectionSlug,\n parseDisplayName,\n parseIssuer,\n parseScopes,\n type Parsed,\n type ProviderName,\n type ProviderSelection,\n providerOf,\n selectionName,\n validated,\n} from \"@zitadel/config/idp\";\n\nimport {\n askConnectionEndpoints,\n callbackUriFor,\n type CustomFlagValues,\n loopbackIssuerWarning,\n ssoEnableArgs,\n} from \"../../../lib/idp\";\nimport { reportWarning } from \"../../../lib/warnings\";\nimport type { Asker } from \"../../../lib/input\";\nimport { issuerFromPort } from \"../../../lib/orca\";\n\nimport type { PromptContext, SetupAnswers, SetupPrompt, SsoDraft } from \"./types\";\n\n/**\n * The settings of a custom connection, asking only for the ones not already\n * given — the way `--preset` skips its own question and no other. A given\n * value goes through the same parser as a typed one, so every setting comes\n * back checked against the contract the server enforces on apply, and a name\n * or issuer it would refuse is refused. The command line's own mistakes are\n * named under their flag before this runs (`checkGivenCustomFlags`), so a\n * given value that gets here has already passed.\n */\nexport async function askCustomSettings(\n given: CustomFlagValues,\n ask: Asker,\n): Promise<Required<CustomFlagValues>> {\n const slug = await ask({\n kind: \"text\",\n name: \"connection name\",\n message:\n \"What would you like to call this connection? It is used in your configuration, for example acme-sso.\",\n parse: (value) => parseConnectionSlug(value, RESERVED_SLUGS),\n given: given.slug,\n });\n const displayName = await ask({\n kind: \"text\",\n name: \"display name\",\n message: \"What name should the sign-in button show? For example Acme SSO.\",\n parse: parseDisplayName,\n given: given.displayName,\n });\n const issuer = await ask({\n kind: \"text\",\n name: \"issuer\",\n message: \"What is the issuer URL of the provider?\",\n parse: parseIssuer,\n given: given.issuer,\n });\n const scopes = await ask({\n kind: \"text\",\n name: \"scopes\",\n message: \"Which scopes should we request? Separate them with spaces.\",\n parse: parseScopes,\n given: given.scopes,\n initialValue: DEFAULT_SCOPES.join(\" \"),\n });\n // The settings carry the scopes as the one string a flag does.\n return { slug, displayName, issuer, scopes: scopes.join(\" \") };\n}\n\n/**\n * \"Which external sign-in providers would you like to add?\" — the one\n * onboarding question that needs something from outside the terminal, so it\n * asks last of the configuration questions and takes \"not now\" as a\n * first-class answer (#1081).\n *\n * Registering the OAuth application is the developer's to do and cannot be\n * automated, so the question announces what to register and where before\n * asking for anything back. Declining costs nothing: `auth-method sso enable`\n * performs exactly this journey on an existing Project, which is why this\n * prompt collects answers rather than doing any work — the scaffolding step\n * writes the connection, the schema and the flow in one place for both paths.\n * \"Not now\" stays an answer after a provider is ticked, too: the redirect URI\n * only shows once it is, and a developer who then finds they have no OAuth\n * application yet leaves the client id empty to drop that provider, rather\n * than cancelling setup and losing every answer.\n *\n * `--sso` skips only the parts it answers. A flagged run that could not\n * supply the secret — it is never a flag, and only a scripted run pipes it in\n * — is still asked for it here, the way `--preset` skips its own question and\n * no other. A flagged provider cannot be dropped: the command line asked for it.\n */\nexport class SocialSignInPrompt implements SetupPrompt {\n async ask(answers: SetupAnswers, ctx: PromptContext): Promise<SetupAnswers> {\n // `--sso` names the set; the wizard asks for it only when no flag did.\n const chosen = ctx.ssoFromFlag\n ? answers.sso.map((draft) => selectionName(draft.selection))\n : await this.chooseProviders(ctx.input);\n if (chosen.length === 0) {\n return { ...answers, sso: [] };\n }\n\n // Asked per provider rather than once: each registers its own OAuth\n // application, so each has its own console, its own client id and its own\n // secret. A flagged run still gets asked for whatever the flags left out.\n const collected: SsoDraft[] = [];\n for (const name of chosen) {\n const flagged = answers.sso.find((draft) => selectionName(draft.selection) === name);\n // A custom connection is described before anything else about it can be\n // said: the announcement names its issuer, and its slug names the secret.\n const selection: ProviderSelection =\n flagged?.selection ??\n (name === CUSTOM_PROVIDER\n ? { kind: \"custom\", connection: await this.askCustom(ctx.input) }\n : { kind: \"catalog\", id: name });\n // A custom connection typed in here has not been through the flag checks.\n const loopback = flagged === undefined ? loopbackIssuerWarning(selection) : undefined;\n if (loopback !== undefined) {\n reportWarning(loopback);\n }\n const entry = providerOf(selection);\n // Before the announcement, which names the vendor's console: on a\n // development run (ZITADEL_CLI_DEV) the provider may not be the vendor at\n // all. Not asked of a custom connection, whose issuer was just given.\n const endpoints =\n selection.kind === \"custom\"\n ? undefined\n : (flagged?.endpoints ??\n (await askConnectionEndpoints({\n provider: selection.id,\n developmentBuild: ctx.developmentBuild === true,\n ask: ctx.input,\n })));\n this.announce(entry, answers.devPort, endpoints?.issuer);\n\n const clientId = await ctx.input({\n kind: \"text\",\n name: \"client id\",\n // \"To skip\", not \"to add it later\": the line after it names the command\n // that adds it, and the shorter question fits an 80-column terminal.\n message:\n flagged === undefined\n ? `What is the client ID of your ${entry.displayName} OAuth app? Leave it empty to skip.`\n : `What is the client ID of your ${entry.displayName} OAuth app?`,\n parse: flagged === undefined ? clientIdOrSkip : parseClientId,\n given: flagged?.credentials.clientId,\n });\n if (clientId === undefined) {\n log.info(\n [\n `Skipped ${entry.displayName}. Once its OAuth application exists, add it with:`,\n ctx.suggest(ssoEnableArgs(selection)),\n ].join(\"\\n\"),\n );\n continue;\n }\n const secret = await ctx.input({\n kind: \"secret\",\n name: \"client secret\",\n message: `What is the client secret of your ${entry.displayName} OAuth app? It will be stored on the project as ${credentialVariables(providerOf(selection).slug).clientSecret}.`,\n parse: parseClientSecret,\n given: flagged?.credentials.secret,\n });\n collected.push({ selection, credentials: { clientId, secret }, endpoints });\n }\n return { ...answers, sso: collected };\n }\n\n /**\n * The providers to enable, empty when the developer wants none.\n *\n * A multi-select rather than one choice: a project may offer several at\n * once, and the schema and flow already carry `sso_providers` as a list.\n * `required: false` is what makes \"none\" an answer -- an explicit \"not now\"\n * option cannot coexist with ticking a provider beside it.\n */\n private async chooseProviders(ask: Asker): Promise<readonly ProviderName[]> {\n return ask({\n kind: \"multiselect\",\n name: \"external sign-in providers\",\n message: \"Which external sign-in providers would you like to add? Press Enter to skip.\",\n // Nothing preselected, and declining costs nothing:\n // `auth-method sso enable` performs this journey on an existing Project\n // later.\n required: false,\n options: [\n ...IDP_PROVIDERS.map((provider) => ({\n value: provider as ProviderName,\n label: `${idpProvider(provider).displayName} — requires a ${idpProvider(provider).displayName} OAuth app`,\n })),\n {\n value: CUSTOM_PROVIDER as ProviderName,\n label: \"Another OpenID Connect (OIDC) provider — requires provider configuration\",\n },\n ],\n });\n }\n\n /**\n * Say what to register and where. The redirect URI is settled by now — the\n * port question runs before this one and the issuer derives from it — so it\n * can be shown rather than left for the developer to work out, which\n * matters because the vendor matches it literally.\n */\n private announce(entry: IdpProvider, devPort: number, issuer?: Issuer): void {\n note(\n [\n // Where to register depends on who is actually answering: pointing a\n // developer at the vendor's console when the connection runs against\n // their own stand-in would be worse than saying nothing.\n ...(issuer === undefined\n ? [\n entry.consoleUrl === undefined\n ? `Register a client at ${entry.issuer}, as an OAuth application:`\n : \"Register an OAuth application at:\",\n ...(entry.consoleUrl === undefined ? [] : [entry.consoleUrl]),\n ]\n : [\"Register a client with the provider at:\", issuer]),\n \"\",\n \"Redirect URI:\",\n callbackUriFor(issuerFromPort(devPort), entry.slug),\n ].join(\"\\n\"),\n `${entry.displayName} sign-in`,\n );\n }\n\n /** Describe a custom connection from scratch: nothing was given on the command line. */\n private async askCustom(ask: Asker): Promise<CustomOidcInput> {\n const values = await askCustomSettings({}, ask);\n return {\n slug: validated(parseConnectionSlug(values.slug, RESERVED_SLUGS)),\n displayName: validated(parseDisplayName(values.displayName)),\n issuer: validated(parseIssuer(values.issuer)),\n scopes: validated(parseScopes(values.scopes)),\n };\n }\n}\n\n/**\n * A client id typed into the wizard, or `undefined` for an empty answer, which\n * drops the provider. A blank id is never a credential: the provider is\n * either configured with both values or not at all.\n */\nfunction clientIdOrSkip(value: string): Parsed<ClientId | undefined> {\n return value.trim() === \"\" ? { ok: true, value: undefined } : parseClientId(value);\n}\n","import { SETUP_USE_CASES, type SetupUseCase } from \"@zitadel/config/defaults\";\n\nimport type { PromptContext, SetupAnswers, SetupPrompt } from \"./types\";\n\n/**\n * \"Which fields should registration collect?\" — picks the use case,\n * which owns the schema field set the scaffold collects (#448). Orthogonal to\n * the sign-in preset, so this asks first: what a user *is* before *how* they\n * sign in.\n * `--use-case` is authoritative; non-interactive runs keep the minimal\n * default seeded by the command.\n */\nexport class UseCasePrompt implements SetupPrompt {\n async ask(answers: SetupAnswers, ctx: PromptContext): Promise<SetupAnswers> {\n if (ctx.useCaseFromFlag) {\n return answers;\n }\n // The labels are the field sets themselves, so all three stay comparable\n // whichever option is highlighted (a hint shows only for the highlighted\n // one). The internal use-case values are unchanged: the use case is\n // recorded in `zitadel.json`, and `--use-case` still names them. The\n // message notes the fields stay editable after setup — the scaffolded\n // schema/flow are the source of truth — and stays short enough for one\n // line of an 80-column terminal. That every set includes email, the\n // labels already say.\n const labels: Record<SetupUseCase, string> = {\n minimal: \"Email only\",\n consumer: \"Email, first name and last name\",\n business: \"Email, first name, last name and company name\",\n };\n const useCase = await ctx.input({\n kind: \"select\",\n name: \"use case\",\n message: \"Which fields should registration collect? You can change them later.\",\n initialValue: answers.useCase,\n options: SETUP_USE_CASES.map((useCase) => ({\n value: useCase,\n label: labels[useCase],\n })),\n });\n return { ...answers, useCase };\n }\n}\n","import type { PasswordMinLength } from \"../../../lib/policies\";\nimport type { SetupPreset, SetupUseCase } from \"@zitadel/config/defaults\";\nimport {\n type ConnectionEndpoints,\n type Credentials,\n type ProviderSelection,\n providerOf,\n} from \"@zitadel/config/idp\";\n\nimport type { Asker } from \"../../../lib/input\";\nimport type { FrameworkChoice } from \"../../../lib/orca\";\nimport type { SuggestedCommand } from \"../../../lib/suggestion\";\n\n/**\n * The collected wizard state, threaded through every {@link SetupPrompt}. A\n * prompt updates its own slice (returning a fresh object); the final shape is\n * what setup feeds into the patcher's `PatchContext` and, ultimately, the\n * generated `zitadel.json`.\n *\n * Pre-seeded by the Setup command from flags + framework detection so each\n * prompt can decide whether to ask (skip when its flag is already a valid\n * value, otherwise prompt and write).\n */\n/**\n * A social provider chosen during setup, with whatever of its application's\n * credentials is known so far.\n *\n * Flags seed a draft and the wizard completes it, so until then either\n * credential may be missing. {@link SsoAnswer} is a draft that has both, and\n * everything that publishes a credential takes that type: choosing a provider\n * and then withholding one scaffolds a sign-in button that cannot work, and it\n * should not be possible to write the code that lets it happen.\n */\nexport type SsoDraft = {\n readonly selection: ProviderSelection;\n readonly credentials: Partial<Credentials>;\n /**\n * Where the connection points, when not at the vendor. Asked for only on a\n * development run (ZITADEL_CLI_DEV), whose one job is standing the provider\n * up locally — see {@link import(\"./social-sign-in\").SocialSignInPrompt}.\n */\n readonly endpoints?: ConnectionEndpoints;\n};\n\n/**\n * A provider with both credentials. Both are required: the connection document\n * stores `${{ NAME }}` references, and the engine resolves them from the\n * project's variables, so a missing value fails at the provider with\n * `invalid_client` long after setup reported success. Declining the provider is\n * the answer for \"not now\" — `auth-method sso enable` adds it once the OAuth\n * application exists.\n *\n * Neither value is ever written to a `.zitadel/` file.\n */\nexport type SsoAnswer = SsoDraft & { readonly credentials: Credentials };\n\n/**\n * The drafts as answers, for a run that goes on to publish credentials.\n *\n * The wizard asks for whatever a flag left out, and a scripted run refuses\n * before this point without the client id or the secret on stdin, so a draft\n * that reaches here without one is a bug in setup and not something to ask\n * the developer about.\n */\nexport function completeSso(drafts: readonly SsoDraft[]): SsoAnswer[] {\n return drafts.map((draft) => {\n const { clientId, secret } = draft.credentials;\n if (clientId === undefined || secret === undefined) {\n throw new Error(`no credentials were collected for ${providerOf(draft.selection).slug}`);\n }\n return { ...draft, credentials: { clientId, secret } };\n });\n}\n\nexport type SetupAnswers = {\n server: string;\n devPort: number;\n /** Sign-in preset (flow + auth methods); see `SETUP_PRESETS` in @zitadel/config. */\n preset: SetupPreset;\n /** Use case (schema field set); see `SETUP_USE_CASES` in @zitadel/config. */\n useCase: SetupUseCase;\n /**\n * Social providers to enable while scaffolding, empty for email sign-in\n * only. Chosen by {@link import(\"./social-sign-in\").SocialSignInPrompt};\n * `auth-method sso enable` adds one to an existing Project later, so this is\n * never the only way in.\n *\n * A list because a project may offer several at once, and the schema and\n * flow already carry `sso_providers` as a list of slugs — one answer per\n * provider, each with its own credentials.\n */\n sso: readonly SsoDraft[];\n /**\n * The minimum password length to put into the password policy setup\n * writes: a number, `null` for an explicit \"none\", or `undefined` when none\n * was given, which writes the recommended minimum (`passwordPolicyFile`).\n * Chosen by {@link import(\"./password-policy\").PasswordPolicyPrompt} or\n * `--password-min-length`.\n */\n passwordMinLength?: PasswordMinLength;\n};\n\n/** Read-only facts a prompt may need. */\nexport type PromptContext = {\n /**\n * How a prompt asks its question: `input`, so every question the wizard\n * asks behaves like every other question the CLI asks.\n *\n * Deliberately not the command's `this.input`. That one answers a `confirm`\n * when the command's `--force` is given, and setup's `--force` means \"overwrite\n * files\", so with it a prompt such as \"Would you like to set up Zitadel in\n * this Next.js app?\" would be answered yes without asking. This one never is.\n */\n readonly input: Asker;\n /**\n * The framework of the app setup integrates: its id and the name a question\n * shows (\"Next.js\"). Nothing more: a new app does not exist while the wizard\n * asks, because setup creates it once it has every answer.\n */\n readonly framework: FrameworkChoice;\n /**\n * A command for this app's project, for a question that names what to run\n * once setup is done, such as adding a skipped provider. It carries the\n * selector setup's own recovery commands carry, so it reaches the project\n * setup creates and not one the shell's environment names.\n */\n readonly suggest: (args: string) => SuggestedCommand;\n /**\n * The app directory setup runs in. {@link import(\"./server\").ServerPrompt}\n * reads the local runtime metadata (`.zitadel/local/runtime.json`) under it\n * to detect a managed local server started here.\n */\n readonly cwd: string;\n /**\n * Whether the developer already named the framework: picked it to scaffold\n * an empty directory, or passed `--framework`. Then\n * {@link import(\"./framework-confirm\").FrameworkConfirmPrompt} has nothing\n * left to confirm and skips itself.\n */\n readonly frameworkChosen?: boolean;\n /**\n * The raw `--server` flag value as the user passed it, or `undefined`\n * when not provided. Prompts use this to skip themselves when the flag\n * already pinned the answer (the docstring on `SetupPrompt` says\n * prompts should return unchanged answers in that case). Distinct from\n * `answers.server`, which is *always* populated by the base command's\n * server-resolution chain — checking that alone can't distinguish \"user\n * passed a flag\" from \"we fell back to the cloud default\".\n */\n readonly serverFlag?: string;\n /**\n * Whether `--dev-port` was passed explicitly. When set, the flag is\n * authoritative and {@link import(\"./dev-port\").DevPortPrompt} skips itself so\n * an interactive answer can't override a scripted/flagged port.\n */\n readonly devPortFromFlag?: boolean;\n /**\n * Whether `--preset` was passed explicitly. When set, the flag is\n * authoritative and {@link import(\"./sign-in-preset\").SignInPresetPrompt}\n * skips itself.\n */\n readonly presetFromFlag?: boolean;\n /**\n * Whether `--use-case` was passed explicitly. When set, the flag is\n * authoritative and {@link import(\"./use-case\").UseCasePrompt} skips itself.\n */\n readonly useCaseFromFlag?: boolean;\n /**\n * Whether `--sso` was passed explicitly. When set, the flag answers the\n * provider question and {@link import(\"./social-sign-in\").SocialSignInPrompt}\n * does not ask it.\n *\n * The credential questions are a separate matter: the prompt still asks for\n * a client id or secret the invocation did not supply, because a connection\n * missing either is one that cannot work. Only a `--non-interactive` run has\n * nobody to ask, and that one is refused rather than left incomplete.\n */\n readonly ssoFromFlag?: boolean;\n /**\n * Whether `--password-min-length` was passed explicitly. When set, the flag\n * is authoritative and {@link import(\"./password-policy\").PasswordPolicyPrompt}\n * skips itself.\n */\n readonly passwordMinLengthFromFlag?: boolean;\n /**\n * Whether this is a development run (the ZITADEL_CLI_DEV opt-in). Only a\n * development run asks where a provider's endpoints are — see\n * {@link import(\"./social-sign-in\").SocialSignInPrompt}. Passed in rather\n * than read from the bundle so a test can drive both answers.\n */\n readonly developmentBuild?: boolean;\n};\n\n/**\n * One question (or one logically-grouped block of questions, e.g. server\n * choice + conditional custom URL) the setup wizard asks. Each implementation\n * is a small standalone class; the Setup command iterates every entry in\n * {@link import(\"./index\").SETUP_PROMPTS} in order. A prompt that has nothing\n * to do (its corresponding flag pre-filled a valid value) returns the answers\n * unchanged.\n */\nexport interface SetupPrompt {\n ask(answers: SetupAnswers, ctx: PromptContext): Promise<SetupAnswers>;\n}\n","import { intro } from \"@clack/prompts\";\n\nimport type { Asker } from \"../../../lib/input\";\n\n/**\n * \"Which framework would you like to scaffold?\" — the only prompt outside the main wizard.\n * Runs at the empty-directory branch (before any other detection), so it owns\n * its own `intro` heading. Returns the chosen framework id; choices come from\n * `Orca.availableFrameworks`.\n */\nexport class PickFrameworkPrompt {\n async ask(\n choices: ReadonlyArray<{ id: string; displayName: string }>,\n ask: Asker,\n ): Promise<string> {\n intro(\"Zitadel setup — new project\");\n return ask({\n kind: \"select\",\n name: \"framework\",\n message: \"Which framework would you like to scaffold?\",\n options: choices.map((choice) => ({ value: choice.id, label: choice.displayName })),\n });\n }\n}\n","/**\n * Public surface for the setup wizard prompts. The `setup` command imports\n * {@link SETUP_PROMPTS} and iterates every entry, threading the answers\n * through each prompt's `ask` so they decide whether to actually ask the\n * user. Add a new question by writing a class and appending an instance to\n * the registry below.\n *\n * {@link PickFrameworkPrompt} is intentionally **not** in {@link SETUP_PROMPTS}\n * — it runs at the empty-directory scaffold branch, before the main wizard\n * starts.\n */\nimport { DevPortPrompt } from \"./dev-port\";\nimport { FrameworkConfirmPrompt } from \"./framework-confirm\";\nimport { PasswordPolicyPrompt } from \"./password-policy\";\nimport { ServerPrompt } from \"./server\";\nimport { SignInPresetPrompt } from \"./sign-in-preset\";\nimport { SocialSignInPrompt } from \"./social-sign-in\";\nimport type { SetupPrompt } from \"./types\";\nimport { UseCasePrompt } from \"./use-case\";\n\nexport type { PromptContext, SetupAnswers, SetupPrompt, SsoAnswer, SsoDraft } from \"./types\";\nexport { completeSso } from \"./types\";\nexport { DevPortPrompt } from \"./dev-port\";\nexport { FrameworkConfirmPrompt } from \"./framework-confirm\";\nexport { PasswordPolicyPrompt } from \"./password-policy\";\nexport { ServerPrompt } from \"./server\";\nexport { SignInPresetPrompt } from \"./sign-in-preset\";\nexport { askCustomSettings, SocialSignInPrompt } from \"./social-sign-in\";\nexport { UseCasePrompt } from \"./use-case\";\nexport { PickFrameworkPrompt } from \"./pick-framework\";\n\n/** Every question the main setup wizard asks, in ask order. */\nexport const SETUP_PROMPTS: ReadonlyArray<SetupPrompt> = [\n new FrameworkConfirmPrompt(),\n new ServerPrompt(),\n new DevPortPrompt(),\n new UseCasePrompt(),\n new SignInPresetPrompt(),\n new PasswordPolicyPrompt(),\n new SocialSignInPrompt(),\n];\n","import { readFile, stat } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport type { SetupPreset } from \"@zitadel/config/defaults\";\nimport { type ProviderSelection, providerOf } from \"@zitadel/config/idp\";\nimport pc from \"picocolors\";\nimport semver from \"semver\";\n\nimport { detectors } from \"../../lib/orca/detectors\";\nimport type { Detector } from \"../../lib/orca/detectors/types\";\nimport { detectPackageManager, type PackageManager } from \"../../lib/package-manager\";\nimport { type PasswordMinLength, RECOMMENDED_PASSWORD_MIN_LENGTH } from \"../../lib/policies\";\n\n/**\n * Structured end-of-command summary, modelled on the report layout the\n * setup mock specifies: one line per fact, grouped under uppercase section\n * headers, with consistent `✓ label value` formatting. Each {@link Row}\n * carries the label, the primary value (already styled by the caller),\n * and an optional `secondary` shown after a dim `→` to mirror the\n * \"package → file\" lines in the mock.\n */\nexport type Row = {\n label: string;\n value: string;\n secondary?: string;\n};\n\nexport type Section = {\n title: string;\n rows: Row[];\n};\n\n/**\n * Renders a path under `cwd` with stable POSIX separators. Setup's summary\n * matches generated artifacts against repository-style suffixes such as\n * `.zitadel/schemas/default-human-user.json`; normalizing here keeps those\n * matches working when Node returns Windows paths with backslashes.\n */\nexport function relativeDisplayPath(cwd: string, absolute: string): string {\n const boundary = absolute[cwd.length];\n const withinCwd = absolute.startsWith(cwd) && (boundary === \"/\" || boundary === \"\\\\\");\n const display = withinCwd ? absolute.slice(cwd.length + 1) : absolute;\n return display.replaceAll(\"\\\\\", \"/\");\n}\n\n/**\n * Renders the section list as a single multi-line string. Labels are\n * padded to a common width per section so the `✓ label value` columns\n * line up, the title prints in dim gray, and `✓` is green. Values come\n * in pre-styled — use the helpers below ({@link path}, {@link url},\n * {@link id}, {@link dim}) to keep the colour palette consistent with\n * the mock.\n */\nexport function renderSummary(sections: Section[]): string {\n const lines: string[] = [];\n for (const section of sections) {\n if (section.rows.length === 0) continue;\n if (lines.length > 0) lines.push(\"\");\n lines.push(pc.dim(section.title.toUpperCase()));\n const labelWidth = Math.max(...section.rows.map((r) => r.label.length)) + 3;\n for (const row of section.rows) {\n const labelCol = row.label.padEnd(labelWidth);\n const secondary = row.secondary ? ` ${pc.dim(\"→\")} ${row.secondary}` : \"\";\n lines.push(`${pc.green(\"✓\")} ${labelCol}${row.value}${secondary}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n/** Cyan, for filesystem paths the user can open. */\nexport const path = (s: string): string => pc.cyan(s);\n/** Cyan, for URLs (browser-clickable in most terminals). */\nexport const url = (s: string): string => pc.cyan(s);\n/** Yellow, for opaque ids the user shouldn't try to read. */\nexport const id = (s: string): string => pc.yellow(s);\n/** Dim, for separators and secondary detail. */\nexport const dim = (s: string): string => pc.dim(s);\n\n/**\n * Detected facts about the user's project, surfaced in the `DETECTED`\n * section. {@link detectProjectFacts} reads the on-disk markers (lock\n * file, tsconfig, framework dep version) without any platform call.\n */\nexport type ProjectFacts = {\n framework: string;\n frameworkVersion?: string;\n typescript: boolean;\n packageManager: PackageManager;\n};\n\n/**\n * Reads the project root to identify the framework version, TS presence,\n * and which package manager the user runs. Returns safe defaults (npm\n * fallback, no version) on any error so summary rendering can always proceed.\n */\nexport async function detectProjectFacts(cwd: string, frameworkId: string): Promise<ProjectFacts> {\n const facts: ProjectFacts = {\n framework: frameworkId,\n typescript: await fileExists(join(cwd, \"tsconfig.json\")),\n packageManager: await detectPackageManager(cwd),\n };\n try {\n const raw = await readFile(join(cwd, \"package.json\"), \"utf8\");\n const pj = JSON.parse(raw) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const depPkg = depFromFramework(frameworkId);\n const range = pj.dependencies?.[depPkg] ?? pj.devDependencies?.[depPkg];\n const version = range ? stripRange(range) : undefined;\n if (version) {\n facts.frameworkVersion = version;\n }\n } catch {\n // Missing or unreadable package.json — version stays undefined; the\n // renderer skips that segment, which is the same as the user not\n // having declared the framework dep yet.\n }\n return facts;\n}\n\n/** Formats the project facts as the \"Next.js 15 · TypeScript · npm\" string the mock shows. */\nexport function formatFrameworkLine(facts: ProjectFacts): string {\n const segments: string[] = [];\n const pretty = prettyFramework(facts.framework);\n segments.push(facts.frameworkVersion ? `${pretty} ${facts.frameworkVersion}` : pretty);\n if (facts.typescript) segments.push(\"TypeScript\");\n segments.push(facts.packageManager);\n return segments.join(` ${pc.dim(\"·\")} `);\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction detectorFor(framework: string): Detector | undefined {\n return detectors.find((detector) => detector.framework === framework);\n}\n\nfunction depFromFramework(framework: string): string {\n return detectorFor(framework)?.versionPackage ?? framework;\n}\n\nfunction prettyFramework(framework: string): string {\n return detectorFor(framework)?.displayName ?? framework;\n}\n\n/**\n * Reduces a declared npm range to the version the summary shows: the lowest\n * version it admits (`semver.minVersion`), so `^15.0.0`, `>= 15.0.0`,\n * `=15.0.0`, `^15.0.0 || ^14.0.0` all read `15.0.0` and `20.1.x` reads\n * `20.1.0`. Returns `undefined` when the spec is not a valid semver range\n * (`catalog:`, `workspace:*`, `file:`, git URLs, dist-tags such as `latest`) or\n * names no version (`*`), because printing that as the framework version would\n * be wrong.\n */\nfunction stripRange(range: string): string | undefined {\n if (!/\\d/.test(range) || semver.validRange(range) === null) return undefined;\n return semver.minVersion(range)?.version;\n}\n\n/** Returns just the file name from a relative path, for the `→ filename` secondary detail in PACKAGE rows. */\nexport function fileNameOf(p: string): string {\n return basename(p);\n}\n\n/**\n * The sign-in configuration the wizard's answers add up to, said once so the\n * preset, the password policy and the providers need not be pieced together.\n * It describes what will be configured, not that sign-in works: an enabled\n * method is not a credential a user has registered. Both presets enable\n * password and passkey in the schema and differ in which the login flow starts\n * with.\n */\nexport function signInSummary(answers: {\n preset: SetupPreset;\n sso: ReadonlyArray<{ selection: ProviderSelection }>;\n passwordMinLength?: PasswordMinLength;\n}): string {\n const providers = answers.sso.map((draft) => providerOf(draft.selection).displayName);\n return [\n answers.preset === \"passkey-first\"\n ? \"Sign-in starts with a passkey, with email and password as the fallback.\"\n : \"Sign-in starts with email and password.\",\n \"Password and passkey are enabled in the user schema.\",\n // None given is the recommended minimum, which setup writes in its place.\n answers.passwordMinLength === null\n ? \"Passwords have no minimum length.\"\n : `Passwords need at least ${answers.passwordMinLength ?? RECOMMENDED_PASSWORD_MIN_LENGTH} characters.`,\n providers.length === 0\n ? \"No external providers will be added.\"\n : `External providers: ${providers.join(\", \")}.`,\n ].join(\"\\n\");\n}\n","import { readFile, rm, writeFile } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { intro, note, outro } from \"@clack/prompts\";\nimport { Flags } from \"@oclif/core\";\nimport type { CreateProject201 } from \"@zitadel/api/generated/model\";\nimport {\n DEFAULT_SETUP_PRESET,\n DEFAULT_SETUP_USE_CASE,\n SETUP_PRESETS,\n SETUP_USE_CASES,\n type SetupPreset,\n type SetupUseCase,\n} from \"@zitadel/config/defaults\";\nimport {\n credentialVariables,\n CUSTOM_PROVIDER,\n IDP_PROVIDERS,\n parseClientId,\n parseClientSecret,\n type ProviderSelection,\n providerOf,\n selectionName,\n type ConnectionSlug,\n} from \"@zitadel/config/idp\";\nimport { consola } from \"consola\";\nimport semver from \"semver\";\n\nimport { createZitadelClient } from \"../../lib/api-client\";\nimport { isDevelopmentBuild } from \"../../lib/build-channel\";\nimport { renderBoxActions, wrapForBox } from \"../../lib/box\";\nimport { setupDesignRemovedError } from \"../../lib/branding/designs\";\nimport {\n claimAction,\n claimBoxAction,\n claimCommand,\n claimState,\n claimWindowDeadline,\n} from \"../../lib/claim-state\";\nimport { isErrno, toZitadelError, ZitadelError } from \"../../lib/errors\";\nimport {\n callbackUriFor,\n customFlagText,\n checkGivenCustomFlags,\n customExample,\n customFlagValues,\n flagText,\n givenCustomFlags,\n loopbackIssuerWarning,\n publishClientId,\n type PublishState,\n selectionFromFlags,\n reportClientIdOutcome,\n reportSecretOutcome,\n republishCommands,\n SETUP_FLAG_KEYS,\n SETUP_FLAG_NAMES,\n ssoEnableArgs,\n storeClientSecret,\n type SecretOutcome,\n type SecretPublisher,\n} from \"../../lib/idp\";\nimport { brandingGuidanceAction, exploreAllCommands } from \"../../lib/journey-guidance\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope, nonBlankString } from \"../../lib/oclif\";\nimport { environmentSelectorSuffix } from \"../../lib/oclif/environment-flags\";\nimport { serverKind } from \"../../lib/oclif/server-kind\";\nimport { findLocalAdminFor } from \"../../lib/local-server/admin-credential\";\nimport { claimProjectAsAdmin } from \"../../lib/local-server/claim-as-admin\";\nimport { LocalServer } from \"../../lib/local-server/server\";\nimport { readNearestRuntimeMetadata, readPlatformRuntime } from \"../../lib/local-server/runtime\";\nimport {\n readProjectServer,\n readZitadelConfig,\n readZitadelSecret,\n writeZitadelSecret,\n} from \"../../lib/project\";\nimport {\n createOrca,\n inspectScaffoldTarget,\n issuerFromPort,\n type FrameworkFacts,\n type Orca,\n type ScaffoldTarget,\n type UndoableScaffold,\n} from \"../../lib/orca\";\nimport {\n AVAILABLE_RENDERER_IDS,\n RENDERER_IDS,\n} from \"../../lib/orca/patchers/rule/next/renderers/registry\";\nimport type { PatchContext } from \"../../lib/orca/patchers/types\";\nimport { type Asker, input } from \"../../lib/input\";\nimport { hasZitadelConfig, hasZitadelSecret } from \"../../lib/project\";\nimport {\n PASSWORD_POLICY_PATH,\n type PasswordMinLength,\n parsePasswordMinLength,\n} from \"../../lib/policies\";\nimport { derivePosture } from \"../../lib/orca/patchers/posture\";\nimport { writeScaffoldManifest } from \"../../lib/scaffold-manifest\";\nimport {\n assertNoSetupResourceConflicts,\n materializeSetupResources,\n type MaterializeSetupResourcesResult,\n} from \"../../lib/setup-resources\";\nimport { installDependenciesForSetup } from \"./install\";\nimport { moveDevPort } from \"./move-dev-port\";\nimport {\n askCustomSettings,\n PickFrameworkPrompt,\n SETUP_PROMPTS,\n type SetupAnswers,\n type SsoDraft,\n completeSso,\n} from \"./prompts\";\nimport {\n detectProjectFacts,\n fileNameOf,\n formatFrameworkLine,\n id as styleId,\n path as stylePath,\n relativeDisplayPath as relativeDisplay,\n renderSummary,\n signInSummary,\n url as styleUrl,\n type Row,\n type Section,\n} from \"./summary\";\nimport { shellOption } from \"../../lib/shell\";\nimport { showSkillsHint } from \"../../lib/skills-hint\";\nimport { reportWarning } from \"../../lib/warnings\";\nimport {\n type EnvironmentSelector,\n inShell,\n projectCommand,\n type SuggestedCommand,\n unscopedCommand,\n} from \"../../lib/suggestion\";\nimport { nextCommandsData } from \"../../lib/oclif/envelope\";\nimport { Promptable } from \"../../lib/oclif/promptable\";\n\n/**\n * The frameworks `--framework` accepts, derived from Orca's registry so the\n * flag can't drift from what the CLI can actually scaffold. `createOrca` is\n * pure (it only builds the in-memory registries), so this is safe at module\n * load.\n */\nconst FRAMEWORK_OPTIONS = createOrca()\n .availableFrameworks()\n .map((framework) => framework.id);\n\n/**\n * `--renderer` offers only ids `getRenderer` will resolve: a\n * declared-but-unpublished renderer (ADR 006) keeps its registry entry to\n * reserve the id, but is surfaced as unavailable in the flag description\n * instead of in `options`, so `--help` never advertises a value that is\n * guaranteed to fail and an explicit pass is rejected at parse time — before\n * any remote project is created.\n */\nconst UNAVAILABLE_RENDERER_IDS = RENDERER_IDS.filter((id) => !AVAILABLE_RENDERER_IDS.includes(id));\nconst RENDERER_FLAG_DESCRIPTION =\n UNAVAILABLE_RENDERER_IDS.length === 0\n ? \"Renderer (default: react).\"\n : `Renderer (default: react). Not yet available: ${UNAVAILABLE_RENDERER_IDS.join(\", \")}.`;\n\n/**\n * The selector appended to setup's credential-recovery commands. `variable set`\n * is an `EnvironmentCommand` that resolves the project and server from the\n * environment, where the process environment outranks the `.env` files — so a\n * bare retry in a shell holding production values would publish to the wrong\n * project. Pinning `--env-file .env.development.local` (the file setup wrote)\n * forces the local project the recovery is for, because `--env-file` outranks\n * the process environment (unlike `--env`); same reasoning as the SSO recovery.\n */\nfunction recoverySelector(cwd: string | undefined): EnvironmentSelector {\n // `--cwd` too, as typed: `--env-file` resolves against it, so a recovery\n // run from where setup was launched reads the file setup wrote.\n return environmentSelectorSuffix({ envFile: \".env.development.local\", cwd });\n}\n\n/**\n * {@link recoverySelector} plus `--server local`, for the recovery after a\n * local-server failure (see `ssoRecovery`).\n */\nfunction localRecoverySelector(cwd: string | undefined): EnvironmentSelector {\n return environmentSelectorSuffix({ envFile: \".env.development.local\", server: \"local\", cwd });\n}\n\n/** `zitadel setup` — create a project and scaffold local auth.\n *\n * Detects the framework (or, for an empty directory, picks the one to\n * scaffold), runs the wizard prompts to fill in any answers not pre-supplied\n * by flags, scaffolds the new app only then (never on a dry run), creates the\n * remote project without server fallback defaults, patches the local files via\n * `Orca`'s framework patcher, then scaffolds and uploads editable schema/flow\n * config from `.zitadel/**`.\n *\n * Every interactive question lives in {@link SETUP_PROMPTS} (the main wizard\n * — each entry is a small class) and {@link PickFrameworkPrompt} (the\n * empty-directory framework choice, before the main wizard).\n */\nexport default class Setup extends Promptable(BaseCommand) {\n static override description =\n \"Create a Zitadel project and scaffold local auth. An interactive setup ends with a note about the Zitadel agent skills, shown once per machine; set NO_SKILLS_PROMPT=1 to hide it.\";\n static override group = CommandGroups.gettingStarted;\n static override groupOrder = 1;\n static override examples = [\n \"<%= config.bin %> setup --framework next\",\n \"<%= config.bin %> setup --framework react --dev-port 3000\",\n ];\n static override flags = {\n force: Flags.boolean({\n char: \"f\",\n description:\n \"Overwrite managed files that already exist, and scaffold into a non-empty directory.\",\n }),\n framework: Flags.string({ description: \"Framework to target.\", options: FRAMEWORK_OPTIONS }),\n renderer: Flags.string({\n description: RENDERER_FLAG_DESCRIPTION,\n options: [...AVAILABLE_RENDERER_IDS],\n }),\n \"dev-port\": Flags.integer({\n description:\n \"Dev-server port; also the issuer origin registered with Zitadel. Defaults to the detected port. Use distinct ports to run several scaffolded apps side by side. In an app already set up, moves it to this port: the dev script, ZITADEL_ISSUER and the allowed origin.\",\n }),\n \"skip-install\": Flags.boolean({\n description: \"Do not install dependencies after setup updates package.json.\",\n }),\n preset: Flags.string({\n description:\n \"Sign-in preset for the scaffolded schema and login flow (default: password-first).\",\n options: [...SETUP_PRESETS],\n }),\n \"use-case\": Flags.string({\n description:\n \"Use case for the scaffolded schema fields: who signs in to the app (default: minimal).\",\n options: [...SETUP_USE_CASES],\n }),\n // Removed in #1039 — setup no longer applies a login template. Kept\n // hidden so scripts and agents still passing it get a targeted error\n // pointing at `branding eject` instead of oclif's unknown-flag error.\n design: nonBlankString({ hidden: true }),\n \"password-min-length\": nonBlankString({\n description:\n \"Minimum password length for the project's password policy, for example 12; 0 sets none. Without it, setup sets 15, the NIST minimum for password-only sign-in; change it in .zitadel/policies/ later.\",\n }),\n [SETUP_FLAG_KEYS.provider]: Flags.string({\n description:\n \"Social sign-in provider to enable while scaffolding, e.g. google. Skips the wizard's provider question; needs --sso-client-id, and the OAuth application must already be registered with the provider. Pipe the client secret in on stdin; never pass it as a flag.\",\n options: [...IDP_PROVIDERS, CUSTOM_PROVIDER],\n }),\n \"sso-client-id\": nonBlankString({\n description: \"Client id of the OAuth application registered with the --sso provider.\",\n }),\n [SETUP_FLAG_KEYS.slug]: nonBlankString({\n description: \"With --sso custom: the name of the connection. Schemas and flows refer to it.\",\n }),\n [SETUP_FLAG_KEYS.displayName]: nonBlankString({\n description: \"With --sso custom: the name shown on the sign-in button.\",\n }),\n [SETUP_FLAG_KEYS.issuer]: nonBlankString({\n description:\n \"With --sso custom: the provider's issuer URL. Its endpoints come from OIDC discovery.\",\n }),\n [SETUP_FLAG_KEYS.scopes]: nonBlankString({\n description:\n \"With --sso custom: the scopes to request, separated by spaces or commas. Must include openid. Default: openid profile email.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Setup);\n // Before toMeta and before anything touches the server or the disk.\n if (flags.design !== undefined) {\n throw setupDesignRemovedError(this.config.version);\n }\n // The command line's own mistakes come before anything that can fail for\n // another reason, so a slug the server would refuse is named even when the\n // server is down. A custom connection whose settings the wizard will ask for\n // is checked once they are all there.\n const customValues = customFlagValues(flags, SETUP_FLAG_KEYS);\n const settingsGiven =\n customValues.slug !== undefined &&\n customValues.displayName !== undefined &&\n customValues.issuer !== undefined;\n // A run with no terminal, or asked for JSON, has nobody to ask for what is\n // missing, so it is held to the full description.\n const scripted = Boolean(\n flags[\"non-interactive\"] || this.jsonEnabled() || !process.stdin.isTTY,\n );\n if (flags.sso === CUSTOM_PROVIDER) {\n checkGivenCustomFlags(customValues, SETUP_FLAG_NAMES);\n }\n if (flags.sso !== undefined && (flags.sso !== CUSTOM_PROVIDER || settingsGiven || scripted)) {\n selectionFromFlags(flags.sso, customValues, SETUP_FLAG_NAMES, SSO_CUSTOM_EXAMPLE);\n }\n try {\n await this.toMeta(flags);\n } catch (error) {\n throw localSetupHint(error, retryOptionsFromFlags(flags), this.config.version);\n }\n const { cwd, nonInteractive, dryRun, force } = this.meta;\n\n if (await hasZitadelConfig(cwd)) {\n // An app already set up has nothing left to scaffold, but an explicit\n // --dev-port is how it moves to another port.\n if (flags[\"dev-port\"] !== undefined) {\n return this.moveToDevPort(cwd, assertDevPort(flags[\"dev-port\"]), dryRun);\n }\n return this.emit({ status: \"skipped\", reason: \"already-initialized\" });\n }\n if (await hasZitadelSecret(cwd)) {\n throw new ZitadelError(\"E_CONFLICT\", \".zitadel/secret exists without zitadel.json\", {\n hint: \"Move the secret aside or restore zitadel.json before running setup.\",\n });\n }\n // Before anything is detected, created or written: a server another CLI\n // release left running fails setup halfway, after the project exists.\n await assertLocalServerVersion(\n cwd,\n this.meta.source,\n retryOptionsFromFlags(flags),\n this.config.version,\n );\n\n // Resolved before anything is detected, created or written: an\n // inconsistent set of --sso flags is a mistake in the command line, and\n // reporting it after a project has been created would leave the developer\n // to clean up.\n // Not `this.input`: that one answers a confirm when `--force` is given, and\n // here `--force` permits overwriting files, so it must never answer a\n // question. Interactive only when a person is there, which is also the only\n // time the wizard runs.\n const wizardInput: Asker = (question) =>\n input(question, { interactive: !nonInteractive, force: false });\n const ssoFromCommandLine = await ssoFromFlags(\n flags,\n nonInteractive,\n dryRun,\n wizardInput,\n this.config.version,\n );\n\n const orca = createOrca();\n\n consola.start(`Detecting framework in ${shortPath(cwd)}`);\n // The app the questions are about: the one detected here, or else a new\n // one. Setup creates a new app only once it has every answer, just before\n // it patches it, so cancelling a question leaves the directory as it was,\n // and a dry run never creates one. Until then only its framework and dev\n // port are known.\n let app: Readonly<{ framework: string; devPort: number }>;\n let detected: FrameworkFacts | undefined;\n // Whether `--force` scaffolds beside entries the directory already held,\n // other than the local runtime `start` leaves, which counts as empty.\n let scaffoldedBesideFiles = false;\n try {\n detected = await orca.detect(cwd, flags.framework);\n app = { framework: detected.id, devPort: detected.devPort };\n consola.success(\n `Detected ${orca.displayName(detected.id)}${detected.devPort ? ` (dev port ${detected.devPort})` : \"\"}`,\n );\n } catch (error) {\n if (error instanceof ZitadelError && error.code === \"E_FRAMEWORK_NOT_DETECTED\") {\n const target = await inspectScaffoldTarget(cwd);\n if (!target.scaffoldable && !force) {\n throw frameworkDetectionWithScaffoldTarget(error, cwd, target);\n }\n consola.info(\n target.scaffoldable\n ? \"Fresh app directory — setup scaffolds a new project\"\n : \"Non-empty directory with --force — setup scaffolds a new project\",\n );\n app = await orca.planScaffold(\n cwd,\n await resolveScaffoldFramework(flags.framework, nonInteractive, orca, {\n retry: retryOptionsFromFlags(flags),\n serverFlag: this.meta.serverFlag,\n cliVersion: this.config.version,\n ask: wizardInput,\n }),\n );\n scaffoldedBesideFiles = !target.scaffoldable;\n } else {\n throw error;\n }\n }\n // A new app, created below, or on a dry run only previewed.\n const scaffoldedFramework = detected === undefined;\n this.recordTelemetry({\n framework: app.framework,\n renderer: flags.renderer ?? \"react\",\n scaffolded_skeleton: scaffoldedFramework,\n skip_install: Boolean(flags[\"skip-install\"]),\n dev_port_explicit: flags[\"dev-port\"] !== undefined,\n preset: flags.preset ?? DEFAULT_SETUP_PRESET,\n use_case: flags[\"use-case\"] ?? DEFAULT_SETUP_USE_CASE,\n sso: flags.sso ?? \"none\",\n // Read from the raw flag: it is parsed below, so a bad value fails after\n // this step is recorded, like the other flags'. 0 sets none, and no\n // flag the recommended minimum.\n password_policy: setsMinLength(flags[\"password-min-length\"]) ? \"set\" : \"empty\",\n step: \"framework_resolved\",\n });\n // Read once: a bad value is refused here, before anything is created.\n const passwordMinLengthFlag = passwordMinLengthFromFlag(flags[\"password-min-length\"]);\n\n // An explicit --dev-port overrides the detected port for the whole run, so\n // the issuer and the registered origin track the requested port (and several\n // apps can be scaffolded on distinct ports). The config edits set the\n // dev-server port only when it is unset, so a project that already pins a\n // different port in vite.config.*/angular.json keeps it — pass --dev-port to\n // match that pin (or remove it) if the origin check rejects requests.\n if (flags[\"dev-port\"] !== undefined) {\n app = { ...app, devPort: assertDevPort(flags[\"dev-port\"]) };\n }\n\n let answers: SetupAnswers = {\n server: this.meta.source,\n devPort: app.devPort,\n preset: (flags.preset as SetupPreset | undefined) ?? DEFAULT_SETUP_PRESET,\n useCase: (flags[\"use-case\"] as SetupUseCase | undefined) ?? DEFAULT_SETUP_USE_CASE,\n sso: ssoFromCommandLine === undefined ? [] : [ssoFromCommandLine],\n passwordMinLength: passwordMinLengthFlag,\n };\n\n if (!nonInteractive && !dryRun) {\n // Asking which framework to scaffold opened the wizard already.\n if (!scaffoldedFramework || flags.framework !== undefined) {\n intro(\"Zitadel setup\");\n }\n const promptCtx = {\n input: wizardInput,\n framework: { id: app.framework, displayName: orca.displayName(app.framework) },\n suggest: (args: string) =>\n projectCommand(args, recoverySelector(flags.cwd), this.meta.cliVersion),\n cwd,\n frameworkChosen: scaffoldedFramework || flags.framework !== undefined,\n serverFlag: this.meta.serverFlag,\n devPortFromFlag: flags[\"dev-port\"] !== undefined,\n presetFromFlag: flags.preset !== undefined,\n useCaseFromFlag: flags[\"use-case\"] !== undefined,\n ssoFromFlag: flags.sso !== undefined,\n passwordMinLengthFromFlag: flags[\"password-min-length\"] !== undefined,\n developmentBuild: isDevelopmentBuild(),\n };\n for (const prompt of SETUP_PROMPTS) {\n answers = await prompt.ask(answers, promptCtx);\n }\n note(signInSummary(answers), \"Sign-in\");\n outro(\"Configuration captured\");\n } else if (\n flags[\"dev-port\"] === undefined &&\n !(await LocalServer.isPortFree(answers.devPort))\n ) {\n // The wizard asks for another port when the detected one is taken. A run\n // that asks nothing still pins the dev script to it, so it says so, with\n // the command that puts the app on a free one.\n reportWarning(\n portInUseWarning(answers.devPort, await LocalServer.nextFreePort(answers.devPort), (args) =>\n this.suggestUnscoped(args),\n ),\n );\n }\n\n // The interactive prompts can override the flag/default preset and use\n // case recorded at framework_resolved — re-record so\n // telemetry carries the values that actually scaffold.\n this.recordTelemetry({\n preset: answers.preset,\n use_case: answers.useCase,\n // One slug, \"none\", or \"multiple\" -- never a joined set. A dimension's\n // value space has to stay enumerable: comma-joining n providers makes it\n // combinatorial, and the question telemetry answers here is whether a\n // project enabled a provider at all, not which combination.\n sso:\n answers.sso.length === 0\n ? \"none\"\n : answers.sso.length === 1\n ? answers.sso[0]\n ? selectionName(answers.sso[0].selection)\n : \"none\"\n : \"multiple\",\n // Whether a minimum goes into the password policy, never the value. None\n // given is the recommended one (`passwordPolicyFile`), unless `--force`\n // keeps a policy file: `files_patched` records what was published.\n password_policy: answers.passwordMinLength === null ? \"empty\" : \"set\",\n });\n\n const issuer = issuerFromPort(answers.devPort);\n const rendererId = flags.renderer ?? \"react\";\n\n // Fresh scaffolds keep the widgets' full-page chrome; a pre-existing\n // route-based app gets embeddable cards inside its own layout (ADR 044).\n const posture = derivePosture(app.framework, scaffoldedFramework);\n const patchContext = (framework: FrameworkFacts, project: CreateProject201): PatchContext => ({\n framework,\n rendererId,\n project,\n issuer,\n server: answers.server,\n cliVersion: this.meta.cliVersion,\n scaffoldedFramework,\n posture,\n preset: answers.preset,\n useCase: answers.useCase,\n });\n const patcher = orca.patcherFor(app.framework);\n // The schema, flow and connection files setup writes only once the project\n // exists: a conflict on one of those left the project behind, and the\n // rerun's `.env.local` kept pointing at it. Checked before anything is\n // written, a new app included. Read-only, so a dry run reports them too.\n await assertNoSetupResourceConflicts({\n cwd,\n force,\n preset: answers.preset,\n useCase: answers.useCase,\n sso: answers.sso,\n });\n\n // A new app is created only now, with every answer in hand. A dry run\n // creates none, so it has no app to patch.\n let created = detected;\n let newApp: UndoableScaffold | undefined;\n if (created === undefined && dryRun) {\n consola.info(`Would scaffold a new ${app.framework} project (dry run)`);\n } else if (created === undefined) {\n consola.start(`Scaffolding a new ${app.framework} project`);\n newApp = await orca.scaffoldUndoably(cwd, app.framework, force);\n created = newApp.facts;\n consola.success(`Scaffolded ${created.id} skeleton`);\n }\n // The DevPortPrompt can change the port interactively, so fold the answer\n // back into the framework: the patched dev-server config reads\n // `framework.devPort`, and it must agree with the issuer and the registered\n // origin (both derived from `answers.devPort`).\n const framework =\n created === undefined ? undefined : { ...created, devPort: answers.devPort, url: issuer };\n\n // A new app is kept only once its default resources are in place. A\n // failure before that, Ctrl-C included, removes it again and puts back\n // what the directory held, so the rerun scaffolds a new app instead of\n // taking a half-set-up one for an app the developer brought.\n let project: CreateProject201;\n let result: Awaited<ReturnType<typeof patcher.patch>>;\n let resourceResult: MaterializeSetupResourcesResult;\n try {\n if (framework !== undefined && !dryRun) {\n // Patch as a dry run first, against a placeholder project: a file setup\n // would refuse to overwrite (E_CONFLICT), such as an existing app's own\n // root component, stops setup here, before it creates a project and\n // writes `zitadel.json`. Without this, the conflict surfaced after both,\n // and every rerun skipped the directory as already set up.\n await patcher.patch(patchContext(framework, dryRunProject(issuer)), {\n cwd,\n dryRun: true,\n force,\n });\n }\n\n // `POST /projects` is unauthenticated. CLI-managed projects opt out of\n // server fallback defaults, then setup uploads the local default schema and\n // flow files through the typed resource APIs and records the returned IDs.\n consola.start(`Creating project on ${answers.server}${dryRun ? \" (dry run)\" : \"\"}`);\n const unauthClient = createZitadelClient({ baseUrl: answers.server });\n const projectName = defaultProjectName(cwd, app.framework);\n // Register the app's own origin so the backend's origin check allows\n // requests the dev proxy forwards from it.\n project = dryRun\n ? dryRunProject(issuer)\n : await createProjectWithLocalHint(\n unauthClient,\n answers.server,\n this.meta.cliVersion,\n projectName,\n issuer,\n {\n // Resolved values, not raw flags: the wizard may have picked the\n // preset, use case, or dev port interactively, and the retry must\n // reproduce those choices — the issuer registered with the\n // project derives from the port.\n ...retryOptionsFromFlags(flags),\n framework: app.framework,\n preset: answers.preset,\n useCase: answers.useCase,\n devPort: answers.devPort,\n sso: answers.sso.map((answer) => answer.selection),\n passwordMinLength: answers.passwordMinLength,\n },\n );\n consola.success(`Created project ${project.id}`);\n this.recordTelemetry({ step: \"project_created\" });\n\n // `.env.local` as it is before the patch merges this project's id and\n // secret into it, so a failure below can put it back.\n const envFilesBefore = await readCredentialEnvFiles(cwd);\n if (framework === undefined) {\n // What the patch writes depends on the files the scaffold creates.\n consola.info(\"Would patch the new project (dry run): its files come from the scaffold\");\n result = { dryRun, files: [], filesWritten: [], filesSkipped: [], depsAdded: [] };\n } else {\n consola.start(`Patching project files${dryRun ? \" (dry run)\" : \"\"}`);\n try {\n result = await patcher.patch(patchContext(framework, project), { cwd, dryRun, force });\n } catch (error) {\n // The dry run above already ruled out conflicts, so this is an I/O\n // failure partway through. Remove the setup markers and put\n // `.env.local` back, as a failed resource upload does below, so a\n // rerun starts over.\n if (!dryRun) {\n await removeSetupMarkers(cwd);\n await restoreCredentialEnvFiles(cwd, envFilesBefore);\n }\n throw error;\n }\n }\n for (const file of result.filesWritten) {\n const sentence = describeWrittenFile(relativeDisplay(cwd, file), dryRun);\n if (sentence) consola.info(sentence);\n }\n for (const file of result.filesSkipped) {\n consola.info(`Left ${relativeDisplay(cwd, file)} unchanged (already matches target)`);\n }\n try {\n resourceResult = dryRun\n ? { filesWritten: [], passwordMinLengthSet: false }\n : await materializeSetupResources({\n cwd,\n // Verbatim: what setup reads back is stored in state, never printed.\n client: createZitadelClient(\n { baseUrl: answers.server, token: project.project_secret },\n { verbatim: true },\n ),\n projectId: project.id,\n force,\n preset: answers.preset,\n useCase: answers.useCase,\n sso: answers.sso,\n passwordMinLength: answers.passwordMinLength,\n cliVersion: this.meta.cliVersion,\n });\n } catch (error) {\n // Setup is not atomic: the patcher already wrote `zitadel.json` (the\n // marker the already-initialized guard skips on) and `.zitadel/secret`.\n // Remove both so a rerun starts a fresh setup instead of being skipped\n // forever with no default schema or login flow anywhere. The\n // half-provisioned project has no usable resources, so its credentials\n // are not worth keeping, and `.env.local`, where the patch merged them,\n // goes back to what it held before.\n // Only these, and never a connection file: those are tenant-owned, and\n // setup neither writes over nor removes one -- unless it is part of a\n // new app, which goes as a whole.\n await removeSetupMarkers(cwd);\n await restoreCredentialEnvFiles(cwd, envFilesBefore);\n const cause = toZitadelError(error);\n throw new ZitadelError(cause.code, `Default resource setup failed: ${cause.message}`, {\n // The cause knows its own remedy when it has one -- a file setup\n // declined to touch is fixed by deciding what to do with that file,\n // not by rerunning with --force.\n hint:\n cause.hint ??\n (newApp === undefined\n ? \"The project was created but its default resources (schema, login flow, \" +\n \"password policy) did not all upload. Re-run `zitadel setup` to start over; \" +\n \"--force overwrites the schema and flow files setup scaffolds and keeps an \" +\n \"existing password policy file. It does not cover a connection under .zitadel/idps/ -- those are \" +\n \"yours, so setup never replaces or removes one; delete it to scaffold a fresh \" +\n \"one, or keep it and enable the provider after setup to reuse it.\"\n : \"The project was created but its default resources (schema, login flow, \" +\n \"password policy) did not all upload, so setup removed the new app again. \" +\n \"Re-run setup as before to start over.\"),\n nextCommands:\n cause.nextCommands ??\n (newApp === undefined ? [this.suggestUnscoped(\"setup --force\")] : []),\n details: cause.details,\n });\n }\n } catch (error) {\n if (newApp !== undefined) {\n await removeNewApp(newApp, cwd);\n }\n throw error;\n }\n try {\n await newApp?.keep();\n } catch (error) {\n // Setup itself is done; only what the scaffold replaced is left behind.\n reportWarning(\n `Could not delete what the new app replaced, kept beside ${cwd}: ${toZitadelError(error).message}`,\n );\n }\n for (const file of resourceResult.filesWritten) {\n const sentence = describeWrittenFile(relativeDisplay(cwd, file), dryRun);\n if (sentence) consola.info(sentence);\n }\n const allFilesWritten = [...result.filesWritten, ...resourceResult.filesWritten];\n if (framework !== undefined) {\n consola.success(\n `Patched ${allFilesWritten.length} file${allFilesWritten.length === 1 ? \"\" : \"s\"}` +\n (result.filesSkipped.length > 0 ? ` (${result.filesSkipped.length} unchanged)` : \"\"),\n );\n }\n this.recordTelemetry({\n step: \"files_patched\",\n files_written_count: allFilesWritten.length,\n });\n if (!dryRun) {\n // What was published, which a policy file `--force` keeps decides as much\n // as the answers recorded before. A dry run publishes nothing and keeps\n // those.\n this.recordTelemetry({\n password_policy: resourceResult.passwordMinLengthSet ? \"set\" : \"empty\",\n });\n }\n\n // After the connection exists, not before: a credential published under a\n // name nothing references yet is an orphan in the project's variables, and\n // a setup that fails in between would leave one behind. Neither credential\n // reaches the filesystem — both go to the project's variables, which is\n // where the engine resolves the connection's `${{ NAME }}` from, against\n // Zitadel Cloud as much as against a local server. A refusal is reported\n // rather than failing setup: everything else is already provisioned, and\n // `variable set` publishes it later.\n // One outcome per provider, keyed by slug: the summary reports each\n // separately, because one provider's publish can land while another's does\n // not, and telling the developer \"the secret did not reach the project\"\n // without saying whose would leave them guessing.\n const ssoOutcomes = new Map<\n ConnectionSlug,\n { clientId: PublishState; secret: SecretOutcome }\n >();\n if (answers.sso.length > 0 && !dryRun) {\n const publish = ssoCredentialPublisher(answers.server, project);\n // Only here do both credentials have to exist, and the type says so.\n for (const answer of completeSso(answers.sso)) {\n const slug = providerOf(answer.selection).slug;\n const { clientId: idVariable, clientSecret: variable } = credentialVariables(slug);\n const clientId = await publishClientId({\n name: idVariable,\n value: answer.credentials.clientId,\n publish,\n });\n const secret = await storeClientSecret({\n name: variable,\n value: answer.credentials.secret,\n publish,\n });\n ssoOutcomes.set(slug, { clientId, secret });\n if (answer.endpoints?.issuer !== undefined) {\n // Said out loud: a connection pointing somewhere other than the\n // vendor is not what the developer will want in the end, and nothing\n // else in the summary would show it.\n reportWarning(\n `${providerOf(answer.selection).displayName} points at ` +\n `${answer.endpoints.issuer}, not the provider`,\n );\n }\n reportClientIdOutcome(\n idVariable,\n clientId,\n this.meta.cliVersion,\n recoverySelector(flags.cwd),\n );\n // The wizard refuses an empty secret, so a deferred publish here only\n // ever means there was no project to publish to.\n reportSecretOutcome(secret, this.meta.cliVersion, false, recoverySelector(flags.cwd));\n }\n }\n\n if (framework !== undefined && !dryRun) {\n // Record what was actually scaffolded so `doctor` can later verify the\n // app files without guessing from current templates (missing vs edited\n // vs user-adopted) and `doctor --fix` can restore exactly the missing\n // ones. Best-effort: a failure here only degrades doctor to its\n // template-derived fallback, it never breaks setup.\n try {\n await writeScaffoldManifest({\n cwd,\n actions: orca.patcherFor(framework.id).artifacts({ framework, rendererId }),\n written: [...result.filesWritten, ...result.filesSkipped],\n scaffoldedFramework,\n devPort: answers.devPort,\n posture,\n });\n } catch (error) {\n consola.debug(\"Failed to record the scaffold manifest\", error);\n }\n }\n\n const installOutcome = await installDependenciesForSetup({\n cliVersion: this.meta.cliVersion,\n cwd,\n depsAdded: result.depsAdded,\n dryRun,\n env: this.meta.env,\n issuer,\n json: this.jsonEnabled(),\n selector: recoverySelector(flags.cwd),\n scaffoldedFramework,\n skipInstall: Boolean(flags[\"skip-install\"]),\n });\n\n this.recordTelemetry({\n step: \"dependencies_installed\",\n package_manager: installOutcome.install.package_manager,\n });\n\n const writtenRel = allFilesWritten.map((file) => relativeDisplay(cwd, file));\n // The nudge rides both surfaces from one decision: the box for humans, the\n // envelope for agents.\n //\n // It joins `boxActions` rather than being held back from it. That list is\n // journey-staged by *omission* (customize/publish is absent until login\n // works, see `install.ts`), and this is not part of that journey: attaching\n // a team is orthogonal to whether login works yet, exactly as in `status`.\n // Position in the list carries no staging meaning, so appending is not a\n // way of deferring it.\n //\n // Nudged on the cloud, and on a local server that actually hosts the\n // platform plane: `claimState` is offline and gates local to\n // not-applicable, but setup is online anyway, so it asks the server's\n // runtime document (see localServerHostsPlatform). A dry run contacts no\n // platform, so it previews the nudge for local servers optimistically\n // instead of probing.\n // The deadline is concrete because the server enforces the claim window\n // at claim time and the project was created moments ago, so created_at\n // computes the same date the platform will hold the user to. A dry run\n // gets the generic wording: its stand-in project has a fixed past\n // created_at, and no real window started anyway.\n // On a CLI-managed local server the developer already exists as the local\n // admin, so the project is attached to their team right away and\n // `zitadel claim` has nothing left to do. Claiming an anonymous project\n // stays a cloud journey.\n let ownedByLocalAdmin: { email: string; team_id: string } | undefined;\n const isLocal = serverKind.value(answers.server) === \"local\";\n const hostsPlatform =\n !dryRun && isLocal ? await localServerHostsPlatform(answers.server) : false;\n if (hostsPlatform) {\n // The runtime document naming the platform project does not prove a\n // claim can complete (a deployment can pin that project without the\n // platform bootstrap, which leaves the admin without a personal team),\n // so attaching the project is best-effort: on failure the project stays\n // unclaimed and setup falls back to the usual claim nudge instead of\n // failing after it has already written the app files. Reading the admin\n // belongs inside the guard for the same reason — a malformed\n // `admin.json` must not fail a setup that already wrote the app.\n try {\n const admin = await findLocalAdminFor(cwd, answers.server);\n if (!admin) {\n // The console lists only projects the signed-in person can manage,\n // so an unattached project is one the local admin never sees. A\n // server started by hand has no local admin anywhere, hence the \"if\".\n reportWarning(\n `No local admin for ${answers.server} in ${cwd} or its parents, so the project is not attached to a team and the local console will not list it. If \\`zitadel start\\` started this server, run setup from the directory it ran in, or one inside it.`,\n );\n }\n if (admin) {\n const owner = await claimProjectAsAdmin({\n serverUrl: answers.server,\n projectId: project.id,\n projectSecret: project.project_secret,\n admin,\n });\n // The team is whichever one the platform attached the project to —\n // the admin's earliest active membership, which need not be the team\n // its bootstrap document named.\n const secret = await readZitadelSecret(cwd);\n await writeZitadelSecret(cwd, {\n ...secret,\n team_id: owner.team_id,\n claimed_at: owner.claimed_at,\n });\n ownedByLocalAdmin = { email: admin.email, team_id: owner.team_id };\n consola.success(`Project owned by ${admin.email} (team ${owner.team_id})`);\n }\n } catch (error) {\n reportWarning(\n `Could not attach the project to the local admin: ${toZitadelError(error).message}`,\n );\n }\n }\n\n const deadline = dryRun ? undefined : claimWindowDeadline(project.created_at);\n const nudgeClaim =\n !ownedByLocalAdmin &&\n (claimState({ secret: {}, server: answers.server }).kind === \"detached\" ||\n (isLocal && (dryRun || hostsPlatform)));\n const claimNudge = nudgeClaim\n ? {\n actions: [claimAction(this.meta.cliVersion, deadline, recoverySelector(flags.cwd))],\n boxActions: [claimBoxAction(this.meta.cliVersion, deadline, recoverySelector(flags.cwd))],\n commands: [claimCommand(this.meta.cliVersion, recoverySelector(flags.cwd))],\n }\n : { actions: [], boxActions: [], commands: [] as SuggestedCommand[] };\n // Only when the project is the local admin's: the console lists nothing\n // else for them, so the command would open an empty console otherwise.\n const consoleCommand = unscopedCommand(\"console\", this.meta.cliVersion);\n const consoleStep = ownedByLocalAdmin\n ? {\n actions: [\n `Manage the project in the local console as ${ownedByLocalAdmin.email}: ${consoleCommand}`,\n ],\n boxActions: [\n {\n text: `Manage the project in the local console, signed in as ${ownedByLocalAdmin.email}:`,\n command: consoleCommand,\n },\n ],\n commands: [consoleCommand],\n }\n : { actions: [], boxActions: [], commands: [] as SuggestedCommand[] };\n // The structured report is human-only. Under `--json` we let the\n // envelope returned from `this.emit(...)` be the sole stdout\n // payload (oclif requires single-doc JSON).\n if (!this.jsonEnabled()) {\n const projectFacts = await detectProjectFacts(cwd, app.framework);\n const sections = buildSummary({\n projectFacts,\n writtenRel,\n depsAdded: result.depsAdded,\n project,\n server: answers.server,\n issuer,\n scaffoldedFramework,\n scaffoldedBesideFiles,\n sso: answers.sso,\n });\n // Frame the report in a consola box so it reads as a distinct\n // status panel separate from the per-step narration above it.\n // `box` accepts ANSI-styled text in the message body, so our\n // pre-coloured rows (path/url/id helpers) survive intact.\n // `wrapForBox` caps the content at the terminal width: consola sizes\n // the frame to the longest line, so an unwrapped sentence wider than\n // the window would break the right border.\n consola.box({\n title: \"Zitadel is ready\",\n message: wrapForBox(\n [\n renderSummary(sections),\n \"\",\n renderBoxActions([\n ...installOutcome.boxActions,\n ...consoleStep.boxActions,\n ...claimNudge.boxActions,\n ]),\n ].join(\"\\n\"),\n ),\n style: { padding: 1, borderStyle: \"rounded\", borderColor: \"green\" },\n });\n // After the steps that start the app and test sign-in, outside the box so\n // the command can be copied without its border.\n consola.log(`\\n${exploreAllCommands(this.meta.cliVersion)}`);\n // Then the skills note, once per machine, as the last thing setup prints.\n // Only on a run that succeeded: a failed or cancelled setup never reaches here,\n // so it does not use up the once-per-machine note.\n await showSkillsHint({\n env: process.env,\n interactive:\n !dryRun &&\n !flags[\"non-interactive\"] &&\n Boolean(process.stdout.isTTY && process.stdin.isTTY),\n });\n }\n\n return this.emit({\n status: \"ok\",\n // Human-facing output was already shown via consola (box + per-step\n // narration). Pass an empty `pretty` so the base command's fallback\n // renderer doesn't duplicate the summary on stdout. The JSON envelope\n // still carries the full structured payload.\n pretty: \"\",\n data: {\n title: \"Zitadel is ready.\",\n project: { project_id: project.id, issuer },\n framework: app.framework,\n server: answers.server,\n files_written: allFilesWritten.map((file) => relativeDisplay(cwd, file)),\n // Typed per-artifact rows for the scaffolded app files (the sync\n // resources continue to report through files_written): one row per\n // touched path with kind (file/dir) and action (create/update), so\n // agents can verify what setup did without parsing narration.\n files: result.files.map((file) => ({\n path: relativeDisplay(cwd, file.path),\n kind: file.kind,\n action: file.action,\n })),\n files_skipped: result.filesSkipped.map((file) => relativeDisplay(cwd, file)),\n install: installOutcome.install,\n // The provider enabled during scaffolding, or null. `secret` reports\n // where the value went, never the value itself — `published` is the\n // one that decides whether the provider button works.\n // A list, one entry per provider enabled during scaffolding, empty\n // when none was. An agent reading this needs to know which provider a\n // deferred publish belongs to, so the outcomes stay per entry.\n sso: answers.sso.map((answer) => {\n const slug = providerOf(answer.selection).slug;\n const outcome = ssoOutcomes.get(slug);\n return {\n provider: selectionName(answer.selection),\n slug,\n client_id: answer.credentials.clientId ?? null,\n connection: `.zitadel/idps/${slug}.json`,\n // What the developer registers at the provider: the connection's\n // own route, as `auth-method sso enable` reports it.\n callback_uri: callbackUriFor(issuer, slug),\n client_id_variable: outcome\n ? { variable: credentialVariables(slug).clientId, published: outcome.clientId }\n : null,\n secret: outcome\n ? { variable: outcome.secret.name, published: outcome.secret.published }\n : null,\n };\n }),\n // Branding guidance before the claim nudge: make it yours, then\n // claim to keep it (the same order the manifesto's journey walks).\n next_actions: [\n ...installOutcome.nextActions,\n brandingGuidanceAction(this.meta.cliVersion),\n ...consoleStep.actions,\n ...claimNudge.actions,\n ],\n // A JSON run prints no warnings, so a credential the project never\n // received would otherwise appear only as a `published` status with\n // nothing to act on. `auth-method sso enable` reports the same recovery step.\n ...nextCommandsData([\n ...republishCommands(\n answers.sso.flatMap((answer) => {\n const slug = providerOf(answer.selection).slug;\n const outcome = ssoOutcomes.get(slug);\n return [\n {\n name: credentialVariables(slug).clientId,\n secret: false,\n published: outcome?.clientId,\n },\n {\n name: outcome?.secret.name,\n secret: true,\n published: outcome?.secret.published,\n },\n ];\n }),\n this.meta.cliVersion,\n recoverySelector(flags.cwd),\n ),\n ...installOutcome.nextCommands,\n ...consoleStep.commands,\n ...claimNudge.commands,\n ]),\n },\n });\n }\n\n /**\n * `setup --dev-port <n>` on an app setup already patched: moves the app to\n * the new port (see {@link moveDevPort}) instead of skipping the directory.\n */\n private async moveToDevPort(\n cwd: string,\n devPort: number,\n dryRun: boolean,\n ): Promise<JsonEnvelope> {\n const config = await readZitadelConfig(cwd);\n const server = readProjectServer(config);\n consola.start(`Moving the app to ${issuerFromPort(devPort)}${dryRun ? \" (dry run)\" : \"\"}`);\n const move = await moveDevPort({\n cwd,\n devPort,\n source: server,\n orca: createOrca(),\n cliVersion: this.meta.cliVersion,\n dryRun,\n });\n for (const file of move.result.filesWritten) {\n consola.info(`${dryRun ? \"Would update\" : \"Updated\"} ${relativeDisplay(cwd, file)}`);\n }\n if (move.staleOrigin !== undefined) {\n reportWarning(\n `Could not remove ${move.staleOrigin} from the project's origins; it admits a port nothing serves any more.`,\n );\n }\n for (const slug of move.ssoProviders) {\n reportWarning(\n `Social sign-in with ${slug} redirects to the old port: add ${callbackUriFor(move.issuer, slug)} as a redirect URI at the provider.`,\n );\n }\n const moved = move.previousIssuer !== move.issuer;\n if (moved) {\n consola.success(`Moved from ${move.previousIssuer} to ${move.issuer}`);\n } else {\n consola.success(`Already on ${move.issuer}`);\n }\n return this.emit({\n status: \"ok\",\n data: {\n title: moved ? `Moved the app to ${move.issuer}.` : `The app is already on ${move.issuer}.`,\n moved,\n previous_issuer: move.previousIssuer,\n issuer: move.issuer,\n dev_port: devPort,\n files_written: move.result.filesWritten.map((file) => relativeDisplay(cwd, file)),\n next_actions: [`Restart the dev server and open ${move.issuer}/login.`],\n },\n });\n }\n}\n\nfunction frameworkDetectionWithScaffoldTarget(\n error: ZitadelError,\n cwd: string,\n target: ScaffoldTarget,\n): ZitadelError {\n return new ZitadelError(\n error.code,\n \"Could not detect a supported app framework, and this directory is not empty\",\n {\n hint:\n `${target.reason ?? \"Directory is not empty.\"} ` +\n \"Pass --force to scaffold into this non-empty directory, run setup from an empty directory, or run setup from an existing supported app project.\",\n details: { cwd, entries: target.entries, reason: target.reason },\n },\n );\n}\n\n/**\n * Resolves which framework to scaffold into an empty directory: the explicit\n * `--framework`, else PickFrameworkPrompt, else a hard error in non-interactive\n * mode (an agent must pass `--framework`).\n */\nasync function resolveScaffoldFramework(\n framework: string | undefined,\n nonInteractive: boolean,\n orca: Orca,\n guidance: { retry: SetupRetryOptions; serverFlag?: string; cliVersion: string; ask: Asker },\n): Promise<string> {\n if (framework) {\n return framework;\n }\n if (nonInteractive) {\n // Most often a coding agent or CI: no terminal, and no flag saying so. So\n // the error names every choice instead of pointing at a prompt it can't\n // see, and for a local server hands over the exact rerun. Only then:\n // `setupRetryFlags` pins `--server local`.\n const choices = orca.availableFrameworks().map((choice) => choice.id);\n const suggested = choices.includes(\"next\") ? \"next\" : choices[0];\n throw new ZitadelError(\"E_FRAMEWORK_NOT_DETECTED\", \"Empty directory — pass --framework\", {\n hint: (\n \"Setup asks which framework to scaffold only in a terminal. Without one, or with \" +\n `--json or --non-interactive, pass --framework with one of: ${choices.join(\", \")}.`\n ).trimEnd(),\n nextCommands:\n guidance.serverFlag === \"local\" && suggested\n ? [\n unscopedCommand(\n `setup ${setupRetryFlags({ ...guidance.retry, framework: suggested })}`,\n guidance.cliVersion,\n ),\n ]\n : [],\n details: { frameworks: choices },\n });\n }\n return new PickFrameworkPrompt().ask(orca.availableFrameworks(), guidance.ask);\n}\n\n/**\n * Whether a local server hosts the platform plane, i.e. whether a claim\n * started against it can actually complete. `platform.bootstrap_project`\n * pins the deployment's default project to the well-known proj_platform, and\n * the console runtime document publishes that resolution, so one public GET\n * answers the question. Fail closed: an unreadable, absent, or hanging\n * document means no nudge, never a nudge into a flow that would 401 at\n * claim/complete — the timeout mirrors checkLocalServerHealth so a socket\n * that accepts and stalls cannot hang setup after the real work is done.\n * Exported so the fail-closed behavior is testable without a live server.\n */\nexport async function localServerHostsPlatform(server: string, timeoutMs = 1500): Promise<boolean> {\n return Boolean(await readPlatformRuntime(server, timeoutMs));\n}\n\n/**\n * Removes a new app setup scaffolded but could not finish setting up, and puts\n * back what the directory held. A failure to do so is reported, not thrown:\n * the error that stopped setup is the one the developer needs.\n */\nasync function removeNewApp(newApp: UndoableScaffold, cwd: string): Promise<void> {\n try {\n await newApp.undo();\n consola.info(`Removed the new app, so ${shortPath(cwd)} holds what it did before setup`);\n } catch (error) {\n reportWarning(\n `Could not remove the new app setup scaffolded in ${cwd}: ${toZitadelError(error).message}`,\n );\n }\n}\n\n/**\n * Removes `zitadel.json` (the marker the already-initialized guard skips on)\n * and `.zitadel/secret`, so a setup that failed after writing them can be rerun.\n */\nasync function removeSetupMarkers(cwd: string): Promise<void> {\n await rm(join(cwd, \"zitadel.json\"), { force: true });\n await rm(join(cwd, \".zitadel/secret\"), { force: true });\n}\n\n/** A deterministic stand-in project for `--dry-run`, so no remote call is made. */\nfunction dryRunProject(issuer: string): CreateProject201 {\n return {\n id: \"dry-run-0000\",\n name: \"dry-run\",\n project_secret: \"sk_proj_dry_run_full\",\n preview_secret: \"sk_proj_dry_run_preview\",\n origins: [{ pattern: issuer, kind: \"primary\" }],\n created_at: \"2026-04-21T14:03:11.000Z\",\n };\n}\n\n/** What a command line describing a custom connection looks like, for an error to show. */\nconst SSO_CUSTOM_EXAMPLE = customExample(SETUP_FLAG_NAMES);\n\n/**\n * The env files the patch merges a project's id and secrets into: `.env.local`\n * for the app, and `.env.development.local`, which the recovery commands pin\n * with `--env-file` and which therefore decides which project they target.\n */\nconst CREDENTIAL_ENV_FILES = [\".env.local\", \".env.development.local\"] as const;\n\n/**\n * What each credential env file holds, or `undefined` for a file that is not\n * there. Only a missing file counts as absent: any other read error is\n * rethrown, because reading it as \"absent\" would make the rollback delete a\n * pre-existing file it should have restored.\n */\nexport async function readCredentialEnvFiles(\n cwd: string,\n): Promise<Map<string, Buffer | undefined>> {\n const before = new Map<string, Buffer | undefined>();\n for (const file of CREDENTIAL_ENV_FILES) {\n try {\n before.set(file, await readFile(join(cwd, file)));\n } catch (error) {\n if (!isErrno(error, \"ENOENT\")) {\n throw error;\n }\n before.set(file, undefined);\n }\n }\n return before;\n}\n\n/**\n * Puts the credential env files back to what {@link readCredentialEnvFiles}\n * read before the patch, and removes one setup created. The patch merged the\n * failed setup's project id and secrets into them, and a merge only adds the\n * keys a file is missing, `--force` or not: left in place, they would survive\n * the rerun, and the app would talk to an abandoned project with no schema or\n * login flow. `.env.example` needs nothing: it gets the same empty values on\n * every run.\n *\n * A file that cannot be restored is reported as a warning rather than thrown:\n * this runs while setup is already failing, and the real error carries the\n * remedy the developer needs.\n */\nexport async function restoreCredentialEnvFiles(\n cwd: string,\n before: ReadonlyMap<string, Buffer | undefined>,\n): Promise<void> {\n for (const [file, content] of before) {\n const path = join(cwd, file);\n try {\n if (content === undefined) {\n await rm(path, { force: true });\n } else {\n await writeFile(path, content);\n }\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n reportWarning(\n `Could not restore ${file} after the failed setup (${reason}); it may still name the abandoned project.`,\n );\n }\n }\n}\n\n/**\n * The provider a scripted run asked for, or `undefined` when it asked for\n * none — in which case the wizard's question decides.\n *\n * The client id is required alongside the provider rather than prompted for:\n * a run that named a provider on the command line is scripted, and stopping\n * to ask would hang it.\n *\n * The secret is never a flag, following `variable set`: it cannot reach\n * shell history, a process listing or a CI log. Only a scripted run reads it\n * from stdin — an interactive one is asked, and consuming stdin there would\n * leave the wizard's own prompts reading a stream already at EOF. A terminal\n * on stdin means nothing was piped, and reading it would block forever, so\n * that case is treated as \"not supplied\".\n */\nexport async function ssoFromFlags(\n flags: {\n sso?: string;\n \"sso-client-id\"?: string;\n \"sso-slug\"?: string;\n \"sso-display-name\"?: string;\n \"sso-issuer\"?: string;\n \"sso-scopes\"?: string;\n },\n nonInteractive: boolean,\n dryRun: boolean,\n ask: Asker,\n cliVersion: string,\n): Promise<SsoDraft | undefined> {\n const customValues = customFlagValues(flags, SETUP_FLAG_KEYS);\n if (flags.sso === undefined) {\n if (flags[\"sso-client-id\"] !== undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"--sso-client-id needs --sso\", {\n hint: \"Name the provider with --sso, e.g. --sso google.\",\n });\n }\n const given = givenCustomFlags(customValues, SETUP_FLAG_NAMES);\n if (given.length > 0) {\n throw new ZitadelError(\"E_VALIDATION\", `${given.join(\", \")} needs --sso ${CUSTOM_PROVIDER}`, {\n hint: `Name the provider with --sso ${CUSTOM_PROVIDER}.`,\n });\n }\n return undefined;\n }\n // Described before the credentials are asked for, and before a Project is\n // created: a name or issuer the server would refuse is a mistake in the\n // command line.\n // An interactive run asks for the custom settings it was not given, the way\n // it asks for a client id: `--sso` skips the question it answers and no other.\n const selection = selectionFromFlags(\n flags.sso,\n flags.sso === CUSTOM_PROVIDER && !nonInteractive\n ? await askCustomSettings(customValues, ask)\n : customValues,\n SETUP_FLAG_NAMES,\n SSO_CUSTOM_EXAMPLE,\n );\n const loopback = loopbackIssuerWarning(selection);\n if (loopback !== undefined) {\n reportWarning(loopback);\n }\n const clientId =\n flags[\"sso-client-id\"] === undefined ? undefined : parseClientId(flags[\"sso-client-id\"]);\n if (clientId === undefined || !clientId.ok) {\n // Interactively the wizard asks for it — `--sso` skips the question it\n // answers and no other, the way `--preset` does. Only a scripted run has\n // nobody to ask.\n if (!nonInteractive) {\n return { selection, credentials: {} };\n }\n const entry = providerOf(selection);\n throw new ZitadelError(\"E_VALIDATION\", `--sso ${flags.sso} needs --sso-client-id`, {\n hint:\n entry.consoleUrl === undefined\n ? `Register a client at ${entry.issuer} and pass its client id.`\n : `Register an OAuth application at ${entry.consoleUrl} and pass its client id.`,\n });\n }\n if (!nonInteractive || dryRun) {\n // The wizard asks for the secret, the way it asks for a client id that\n // `--sso-client-id` did not answer. A preview publishes nothing and\n // materialises nothing, so demanding a real credential to see what setup\n // would do is a toll for no reason -- and `auth-method sso enable --dry-run`\n // returns before asking for one at all.\n return { selection, credentials: { clientId: clientId.value } };\n }\n // Required, not optional: scaffolding the connection without it writes a\n // sign-in button that fails at the provider with `invalid_client`, long\n // after setup reports success. It is never a flag — that would put it in\n // shell history, a process listing and CI logs.\n const secret = await ask({\n kind: \"secret\",\n name: \"client secret\",\n message: `What is the client secret of your ${providerOf(selection).displayName} OAuth app?`,\n parse: parseClientSecret,\n stdin: true,\n // A concrete rerun for an agent, never carrying the value: the secret is\n // piped from the caller's own environment.\n retry: inShell(\n unscopedCommand(`setup --sso ${flags.sso} --sso-client-id <id> ...`, cliVersion),\n { before: `printf '%s' \"$CLIENT_SECRET\" | ` },\n ),\n });\n return { selection, credentials: { clientId: clientId.value, secret } };\n}\n\n/**\n * The parts of a setup invocation that a retry suggestion must reproduce.\n * Suggested retries are followed verbatim (especially by agents), so dropping\n * a flag here silently changes what the retry scaffolds.\n */\nexport type SetupRetryOptions = {\n /**\n * The directory setup was pointed at, as typed. Every suggested rerun\n * carries it as `--cwd`, quoted for a shell, so it configures that project\n * from wherever it is run.\n */\n cwd?: string;\n framework?: string;\n preset?: SetupPreset;\n useCase?: SetupUseCase;\n renderer?: string;\n devPort?: number;\n nonInteractive?: boolean;\n /**\n * The `--sso` flags as typed, when they could not be resolved to a provider\n * yet: a custom connection described in part, which the wizard completes.\n * Dropping them would send the developer back without what they typed.\n */\n ssoTyped?: string;\n /**\n * The social provider and its client id. The secret is deliberately absent:\n * a retry asks for it again, or takes it on stdin, because putting a\n * credential in suggested command text is exactly what piping the secret\n * exists to avoid. It never reaches the filesystem either way — the value\n * goes to the project's variables, which is where the engine resolves the\n * connection's `${{ NAME }}` from.\n */\n sso?: readonly ProviderSelection[];\n /**\n * The minimum password length the run was given: a number, or `null` for\n * an explicit \"none\", carried as `--password-min-length 0` so a kept policy\n * file still loses its minimum on the retry.\n */\n passwordMinLength?: PasswordMinLength;\n};\n\n/**\n * Reconstructs the flag list of the current invocation for retry guidance,\n * ending in `--server local`. Flags whose resolved value equals the default\n * are omitted — the retry reproduces the same outcome without them.\n */\nexport function setupRetryFlags(opts: SetupRetryOptions): string {\n const parts: string[] = [];\n if (opts.framework) {\n parts.push(`--framework ${opts.framework}`);\n }\n if (opts.preset && opts.preset !== DEFAULT_SETUP_PRESET) {\n parts.push(`--preset ${opts.preset}`);\n }\n if (opts.useCase && opts.useCase !== DEFAULT_SETUP_USE_CASE) {\n parts.push(`--use-case ${opts.useCase}`);\n }\n if (opts.renderer && opts.renderer !== \"react\") {\n parts.push(`--renderer ${opts.renderer}`);\n }\n if (opts.devPort !== undefined) {\n parts.push(`--dev-port ${opts.devPort}`);\n }\n // Even the recommended one, unlike the defaults above: without the flag, a\n // policy file `--force` keeps keeps its own minimum.\n if (opts.passwordMinLength !== undefined) {\n parts.push(`--password-min-length ${opts.passwordMinLength ?? 0}`);\n }\n // Only the first: `--sso` takes one provider, and a scripted rerun can pipe\n // only one secret. A retry naming several would not be runnable, which is\n // the whole point of this line. The rest are not silently dropped -- the\n // guidance that uses this emits an `auth-method sso enable` command for each, because\n // `--sso` makes the rerun skip the multi-select, so a provider left out here\n // could not be reselected.\n const [firstSso] = opts.sso ?? [];\n if (firstSso === undefined && opts.ssoTyped !== undefined) {\n parts.push(opts.ssoTyped);\n }\n if (firstSso) {\n // Provider only. `--sso-client-id` would interpolate a value the wizard\n // accepted on emptiness alone into a command run verbatim, and nothing\n // here escapes it for a shell. The rerun asks for the id.\n parts.push(`--sso ${selectionName(firstSso)}`);\n // A custom connection is nothing without its description, and none of it is\n // a credential, so unlike the client id it travels in the command.\n if (firstSso.kind === \"custom\") {\n parts.push(customFlagText(firstSso.connection, SETUP_FLAG_NAMES));\n }\n }\n // `--non-interactive` is dropped when a provider is being configured: that\n // combination reads the client secret from stdin, and a command handed over\n // as text has no stdin to read. Offering it would advertise a retry that\n // fails the moment it is run. Interactively the rerun asks for the secret,\n // which is the one way a plain command can obtain it -- putting it in the\n // command text is never an option.\n if (opts.nonInteractive && firstSso === undefined && opts.ssoTyped === undefined) {\n parts.push(\"--non-interactive\");\n }\n parts.push(\"--server local\");\n return `${parts.join(\" \")}${cwdArg(opts)}`;\n}\n\n/** Whether `--sso` names a provider this CLI offers. */\nconst isKnownSsoName = (name: string): boolean =>\n name === CUSTOM_PROVIDER || (IDP_PROVIDERS as readonly string[]).includes(name);\n\n/**\n * Retry options straight from parsed flags, for failures before the wizard\n * resolves answers. `--non-interactive` is echoed only when explicitly passed\n * — TTY/JSON-inferred non-interactivity re-infers itself on the retry.\n */\n/**\n * The `--password-min-length` a retry carries: the value it means, or nothing\n * for one the parser refuses, which a retry would only be refused for again.\n */\nfunction retryMinLength(value: string | undefined): PasswordMinLength | undefined {\n if (value === undefined) {\n return undefined;\n }\n const parsed = parsePasswordMinLength(value);\n return parsed.ok ? parsed.value : undefined;\n}\n\nexport function retryOptionsFromFlags(flags: {\n cwd?: string;\n framework?: string;\n preset?: string;\n \"use-case\"?: string;\n renderer?: string;\n \"dev-port\"?: number;\n \"non-interactive\"?: boolean;\n \"password-min-length\"?: string;\n sso?: string;\n \"sso-client-id\"?: string;\n \"sso-slug\"?: string;\n \"sso-display-name\"?: string;\n \"sso-issuer\"?: string;\n \"sso-scopes\"?: string;\n}): SetupRetryOptions {\n // The provider survives on its own. A suggested retry carries `--sso`\n // without `--sso-client-id` -- the id is never put in command text -- so\n // requiring both here would drop the provider from the next suggestion if\n // that retry failed again before the wizard ran, and the developer would be\n // told to set up without the provider they asked for. An empty id means \"ask\n // for it\", which is what the wizard does with it.\n //\n // A custom connection is restated as typed, minus the credentials. One the\n // checks refuse is left out: it was refused, and a retry carrying it would be\n // refused again.\n let selection: ProviderSelection | undefined;\n if (flags.sso !== undefined) {\n try {\n selection = selectionFromFlags(\n flags.sso,\n customFlagValues(flags, SETUP_FLAG_KEYS),\n SETUP_FLAG_NAMES,\n \"\",\n );\n } catch {\n selection = undefined;\n }\n }\n // What was typed for a provider this run knows, kept when it cannot become a\n // selection yet, so a retry reproduces it.\n const typed =\n selection === undefined && flags.sso !== undefined && isKnownSsoName(flags.sso)\n ? [`--sso ${flags.sso}`, flagText(customFlagValues(flags, SETUP_FLAG_KEYS), SETUP_FLAG_NAMES)]\n .filter((part) => part !== \"\")\n .join(\" \")\n : undefined;\n return {\n ssoTyped: typed,\n framework: flags.framework,\n preset: flags.preset as SetupPreset | undefined,\n useCase: flags[\"use-case\"] as SetupUseCase | undefined,\n cwd: flags.cwd,\n renderer: flags.renderer,\n devPort: flags[\"dev-port\"],\n nonInteractive: Boolean(flags[\"non-interactive\"]),\n passwordMinLength: retryMinLength(flags[\"password-min-length\"]),\n // The provider survives on its own. A suggested retry carries `--sso`\n // without `--sso-client-id` -- the id is never put in command text -- so\n // requiring both here would drop the provider from the next suggestion if\n // that retry failed again before the wizard ran, and the developer would\n // be told to set up without the provider they asked for. An empty id\n // means \"ask for it\", which is what the wizard does with it.\n sso: selection === undefined ? undefined : [selection],\n };\n}\n\n/**\n * How the connection's credentials reach the project just created.\n *\n * `undefined` when there is no project behind the run — `--server mock`\n * answers from fixtures and has no variables to write. The freshly minted\n * project credentials are used directly: setup has them in hand and nothing\n * has been claimed yet, so there is no owner for the developer to name.\n */\nfunction ssoCredentialPublisher(\n server: string,\n project: CreateProject201,\n): SecretPublisher | undefined {\n if (server === \"mock\") {\n return undefined;\n }\n const client = createZitadelClient({ baseUrl: server, token: project.project_secret });\n return async (name, value, { secret }) => {\n await client.updateVariables({ [name]: { value, secret } }, { project_id: project.id });\n };\n}\n\n/**\n * The providers a setup retry cannot carry, and how to restore them.\n *\n * `--sso` names one provider and makes the rerun skip the multi-select, so\n * every other provider chosen would be lost unless it is restored explicitly.\n * Both recovery paths need this -- the one before the wizard and the one for a\n * failed project creation -- and the second was missed when this was written\n * inline, which is exactly the kind of thing one copy prevents.\n */\n/** `--cwd` for a suggested command, when setup was pointed at a directory. */\nfunction cwdArg(retry: SetupRetryOptions): string {\n return retry.cwd === undefined ? \"\" : ` ${shellOption(\"--cwd\", retry.cwd)}`;\n}\n\nfunction ssoRecovery(\n retry: SetupRetryOptions,\n cliVersion: string,\n): { hint: string; commands: SuggestedCommand[] } {\n const chosen = retry.sso ?? [];\n const remaining = chosen.slice(1);\n if (remaining.length === 0) {\n return { hint: \"\", commands: [] };\n }\n return {\n hint:\n `The rerun configures ${chosen[0] ? providerOf(chosen[0]).slug : \"\"} only; add the rest with the auth-method sso enable ` +\n \"commands below, which ask for each client id. \",\n // The client id is not interpolated into the command. These strings are\n // run verbatim, especially by agents, and nothing escapes them for a\n // shell: a value the wizard accepted -- it only refuses an empty one --\n // could split into two arguments or carry a metacharacter that changes\n // what the command does. `auth-method sso enable` asks for the id, exactly as it asks\n // for the secret, which was never put in command text for the same\n // reason.\n // localRecoverySelector carries `--server local`, as the setup retry\n // pins it. An unpinned `auth-method sso enable`\n // takes its server from `ZITADEL_URL`, so with that variable set to\n // another server it would publish the client id and secret there --\n // leaving the local provider unconfigured and the credentials somewhere\n // nobody asked for. Both callers of this are local-server failures, so\n // `local` is the server meant in every case.\n //\n // `--env-file .env.development.local` pins the project and credential too:\n // `auth-method sso enable` is an EnvironmentCommand that resolves those from the\n // environment, where the process environment outranks the `.env` files, so\n // in a shell holding production values `--server local` alone would send\n // the production token to the local server. `--env-file` outranks the\n // process environment (unlike `--env`), so it is the one that forces the\n // generated development credential the local project actually expects.\n commands: remaining.map((selection) =>\n projectCommand(ssoEnableArgs(selection), localRecoverySelector(retry.cwd), cliVersion),\n ),\n };\n}\n\nasync function createProjectWithLocalHint(\n client: ReturnType<typeof createZitadelClient>,\n server: string,\n cliVersion: string,\n projectName: string,\n issuer: string,\n retry: SetupRetryOptions,\n): Promise<CreateProject201> {\n try {\n // Register the app's own origin as primary: only a primary pattern admits\n // the requests the dev proxy forwards from it, and a deploy goes to the\n // project's primary origins. A preview pattern is for the URLs a\n // pull-request build deploys to, which this is not.\n return await client.createProject({\n name: projectName,\n origins: [{ pattern: issuer, kind: \"primary\" }],\n seed_defaults: false,\n });\n } catch (error) {\n const normalized = toZitadelError(error);\n const retryFlags = setupRetryFlags(retry);\n const sso = ssoRecovery(retry, cliVersion);\n throw new ZitadelError(normalized.code, normalized.message, {\n hint:\n `${normalized.hint ? `${normalized.hint} ` : \"\"}` +\n \"If you meant to use a local Zitadel server, start it first \" +\n `and retry setup with ${retryFlags}. ${sso.hint}`.trimEnd(),\n nextCommands: [\n unscopedCommand(`start${cwdArg(retry)}`, cliVersion),\n unscopedCommand(`setup ${retryFlags}`, cliVersion),\n ...sso.commands,\n ],\n details: {\n server,\n original: normalized.details,\n },\n });\n }\n}\n\n/** `--dev-port`, refused unless it is a TCP port. */\nfunction assertDevPort(devPort: number): number {\n if (!Number.isInteger(devPort) || devPort < 1 || devPort > 65535) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `--dev-port must be an integer in 1..65535, got ${devPort}`,\n );\n }\n return devPort;\n}\n\nfunction defaultProjectName(cwd: string, framework: string): string {\n const fromDirectory = basename(cwd).trim();\n return fromDirectory.length > 0 ? fromDirectory : `zitadel-${framework}-app`;\n}\n\n/**\n * Refuses a local server that another CLI release started. `start` restarts\n * such a server, but one left running stays that release's until `start` runs\n * again, and its API is that release's: setup would create the project, then\n * fail uploading the default schema and flow, and `--force` would not help.\n *\n * Only a binary runtime records the version it runs, and only release versions\n * are compared: an override records `override`, which says nothing about its\n * API. An unreadable `runtime.json` is doctor's to report, not setup's.\n */\nasync function assertLocalServerVersion(\n cwd: string,\n server: string,\n retry: SetupRetryOptions,\n cliVersion: string,\n): Promise<void> {\n let nearest: Awaited<ReturnType<typeof readNearestRuntimeMetadata>>;\n try {\n nearest = await readNearestRuntimeMetadata(cwd);\n } catch {\n return;\n }\n const runtime = nearest?.runtime;\n if (!nearest || runtime?.backend !== \"binary\" || runtime.server_url !== server) {\n return;\n }\n const expected = LocalServer.bundledVersion();\n if (\n expected === undefined ||\n !semver.valid(expected) ||\n !semver.valid(runtime.server_version) ||\n runtime.server_version === expected\n ) {\n return;\n }\n const where =\n nearest.dir === cwd ? \"\" : `Run start in ${nearest.dir}, where the server was started. `;\n throw new ZitadelError(\n \"E_CONFLICT\",\n `The local Zitadel server runs ${runtime.server_version}, but this CLI ships ${expected}`,\n {\n hint:\n \"A server another CLI release started serves that release's API, so setup would stop \" +\n `halfway. Run start to restart it on ${expected}; its data stays. ${where}` +\n \"Then rerun setup.\",\n nextCommands: [\n unscopedCommand(`start ${shellOption(\"--cwd\", nearest.dir)}`, cliVersion),\n unscopedCommand(`setup ${setupRetryFlags(retry)}`, cliVersion),\n ],\n details: {\n server_url: runtime.server_url,\n server_version: runtime.server_version,\n cli_server_version: expected,\n },\n },\n );\n}\n\nfunction localSetupHint(error: unknown, retry: SetupRetryOptions, cliVersion: string): unknown {\n const normalized = toZitadelError(error);\n if (normalized.code !== \"E_LOCAL_SERVER_NOT_RUNNING\") {\n return error;\n }\n\n const setupCommand = `setup ${setupRetryFlags(retry)}`;\n const sso = ssoRecovery(retry, cliVersion);\n\n return new ZitadelError(normalized.code, normalized.message, {\n hint:\n `${normalized.hint ? `${normalized.hint} ` : \"\"}` +\n \"Start local Zitadel first, then rerun setup. \" +\n (retry.sso && retry.sso.length > 0\n ? \"The rerun asks for the client id and secret, because a command carries neither. \" +\n \"To script it instead, add --sso-client-id and --non-interactive, and pipe the secret in. \"\n : \"\") +\n sso.hint +\n \"After setup succeeds, follow its next_commands to start the app and verify registration, logout, and login in the browser.\",\n nextCommands: [\n unscopedCommand(`start${cwdArg(retry)}`, cliVersion),\n unscopedCommand(setupCommand, cliVersion),\n ...sso.commands,\n ],\n details: normalized.details,\n });\n}\n\n/**\n * Replaces the user's `$HOME` with `~` in a path for compact terminal output.\n * Falls back to the raw path when `HOME` isn't set or doesn't match.\n */\nfunction shortPath(absolute: string): string {\n const home = process.env.HOME;\n if (home && absolute.startsWith(home)) {\n return `~${absolute.slice(home.length)}`;\n }\n return absolute;\n}\n\n/**\n * Picks one written file by suffix so the corresponding INSTALLED row can\n * reference it without hard-coding the path the patcher chose. Returns\n * the first match; falls back to `undefined` when the patcher didn't\n * write that artifact (e.g. a renderer without a register page).\n */\nfunction pickWrittenFile(written: string[], suffix: string): string | undefined {\n return written.find((file) => file.endsWith(suffix));\n}\n\n/**\n * Translates a patcher-written path into a single sentence the user can\n * read at narration speed. The patch result's `filesWritten` carries\n * deduplicated file paths only (directories stay in the typed `files`\n * rows), so no artefact filtering is needed here. The verb tense flips\n * for `--dry-run` so the user sees a preview (\"Would write ...\") instead\n * of a claim that something happened.\n */\nfunction describeWrittenFile(relPath: string, dryRun: boolean): string | null {\n const verb = dryRun ? \"Would write\" : \"Wrote\";\n const sentence = SENTENCE_BY_PATH[relPath];\n if (sentence) {\n return `${verb} ${sentence.subject} (${stylePath(relPath)})`;\n }\n return `${verb} ${stylePath(relPath)}`;\n}\n\n/**\n * What a run that cannot ask says about a taken app port, with the command\n * that moves the app to `free`. With no free port among the next ones it names\n * only the flag: a placeholder in a suggested command is a shell redirection.\n */\nexport function portInUseWarning(\n port: number,\n free: number | undefined,\n suggest: (args: string) => SuggestedCommand,\n): string {\n return free === undefined\n ? `Port ${port} and the ports after it are already in use. If that is not this app's dev server, run setup with --dev-port and a free port.`\n : `Port ${port} is already in use. If that is not this app's dev server, run setup with a free port: ${suggest(`setup --dev-port ${free}`)}`;\n}\n\n/**\n * Whether `--password-min-length` leaves a minimum in the policy: a value, or\n * no flag, which means the recommended one; not none, or a value the parser\n * refuses (setup fails on that just after).\n */\nfunction setsMinLength(value: string | undefined): boolean {\n if (value === undefined) {\n return true;\n }\n const parsed = parsePasswordMinLength(value);\n return parsed.ok && typeof parsed.value === \"number\";\n}\n\n/**\n * `--password-min-length`, read with the prompt's parser so the two cannot\n * disagree. Refused before anything is created.\n */\nfunction passwordMinLengthFromFlag(value: string | undefined): PasswordMinLength | undefined {\n if (value === undefined) {\n return undefined;\n }\n const parsed = parsePasswordMinLength(value);\n if (!parsed.ok) {\n throw new ZitadelError(\"E_VALIDATION\", `--password-min-length: ${parsed.problem}`);\n }\n return parsed.value;\n}\n\n/**\n * Map from the patcher's deterministic output paths to a short noun\n * phrase describing what the file is for. Anything not in the map falls\n * back to the bare path in the narration; add an entry here when a new\n * scaffolded file deserves a clearer label.\n */\nconst SENTENCE_BY_PATH: Record<string, { subject: string }> = {\n \".gitignore\": { subject: \"the project's .gitignore additions\" },\n \".zitadel/secret\": { subject: \"the local project secret\" },\n \"zitadel.json\": { subject: \"the Zitadel project configuration\" },\n \".env.example\": { subject: \"the .env example template\" },\n \".env.local\": { subject: \"the local development environment variables\" },\n \".env.development.local\": { subject: \"the environment variables the CLI reads\" },\n \".zitadel/state.json\": { subject: \"the sync state file\" },\n \".zitadel/flows/default-login.json\": { subject: \"the editable default login flow\" },\n \".zitadel/flows/README.md\": { subject: \"the flows folder README\" },\n \".zitadel/schemas/default-human-user.json\": {\n subject: \"the editable default human user schema\",\n },\n \".zitadel/schemas/README.md\": { subject: \"the schemas folder README\" },\n \".zitadel/policies/auth.factor.password.set.json\": { subject: \"the editable password policy\" },\n \".zitadel/policies/README.md\": { subject: \"the policies folder README\" },\n \".zitadel/meta/policy.json\": { subject: \"the policy dialect spec (editor $schema)\" },\n \".zitadel/meta/flow-definition.json\": { subject: \"the flow dialect spec (editor $schema)\" },\n \".zitadel/meta/user-schema.json\": { subject: \"the user-schema dialect spec\" },\n \".zitadel/meta/user-property.json\": { subject: \"the user-property dialect spec\" },\n \".zitadel/meta/branding.json\": { subject: \"the branding dialect spec\" },\n \".zitadel/meta/project.json\": { subject: \"the zitadel.json spec (editor $schema)\" },\n \"AGENTS.md\": { subject: \"the agent guidance (golden journey + config dialect)\" },\n \"README.md\": { subject: \"the README's Zitadel section\" },\n \"app/page.tsx\": { subject: \"the home page redirect\" },\n \"app/login/page.tsx\": { subject: \"the login page\" },\n \"app/register/page.tsx\": { subject: \"the registration page\" },\n \"app/profile/page.tsx\": { subject: \"the profile page\" },\n \"middleware.ts\": { subject: \"the Next.js middleware\" },\n \"proxy.ts\": { subject: \"the Next.js proxy\" },\n \"custom-elements.d.ts\": { subject: \"the web-component type declarations\" },\n \"package.json\": { subject: \"package.json with the SDK dependency\" },\n};\n\n/**\n * Builds the section list driving {@link renderSummary} for the setup command.\n * Exported so its wording is unit-tested.\n */\nexport function buildSummary(opts: {\n projectFacts: Awaited<ReturnType<typeof detectProjectFacts>>;\n writtenRel: string[];\n depsAdded: ReadonlyArray<string>;\n project: CreateProject201;\n server: string;\n issuer: string;\n scaffoldedFramework: boolean;\n scaffoldedBesideFiles: boolean;\n sso: readonly SsoDraft[];\n}): Section[] {\n const { projectFacts, writtenRel, depsAdded, project, server, issuer, scaffoldedFramework, sso } =\n opts;\n const packageJsonHit = pickWrittenFile(writtenRel, \"package.json\");\n\n const detected: Row[] = [{ label: \"Framework\", value: formatFrameworkLine(projectFacts) }];\n if (scaffoldedFramework) {\n detected.push({\n label: \"Scaffold\",\n value: opts.scaffoldedBesideFiles\n ? \"new project over existing files (--force)\"\n : \"new project\",\n });\n }\n\n const installedRows: Row[] = [];\n if (packageJsonHit && depsAdded.length > 0) {\n installedRows.push({\n label: \"Package\",\n value: depsAdded.join(\", \"),\n secondary: stylePath(fileNameOf(packageJsonHit)),\n });\n }\n // A union over every framework's scaffold artifacts: rows only render when\n // the patcher actually wrote the file, so entries for other frameworks are\n // inert. Suffixes are matched case-sensitively (src/App.tsx is React/Solid,\n // src/app.tsx is Qwik, app.vue is the Nuxt shell, src/App.vue is Vue).\n for (const [label, suffix] of [\n [\"Home redirect\", \"app/page.tsx\"],\n [\"Login page\", \"app/login/page.tsx\"],\n [\"Register page\", \"app/register/page.tsx\"],\n [\"Profile page\", \"app/profile/page.tsx\"],\n [\"Request proxy\", \"proxy.ts\"],\n [\"Middleware\", \"middleware.ts\"],\n [\"App entry\", \"src/App.tsx\"],\n [\"App entry\", \"src/app.tsx\"],\n [\"App entry\", \"src/App.vue\"],\n [\"App entry\", \"src/App.svelte\"],\n [\"App entry\", \"src/app/app.ts\"],\n [\"Routes\", \"src/app/app.routes.ts\"],\n [\"Request proxy\", \"proxy.conf.cjs\"],\n [\"App shell\", \"app.vue\"],\n [\"Home redirect\", \"pages/index.vue\"],\n [\"Login page\", \"pages/login.vue\"],\n [\"Register page\", \"pages/register.vue\"],\n [\"Profile page\", \"pages/profile.vue\"],\n [\"Env vars\", \".env.local\"],\n ] as const) {\n const hit = pickWrittenFile(writtenRel, suffix);\n if (hit) installedRows.push({ label, value: stylePath(hit) });\n }\n // The Vite config merge carries the /__nextgen dev proxy; the file name\n // varies (ts/js/mts/mjs), so it can't ride the suffix table above.\n const viteConfigHit = writtenRel.find((file) => /(^|\\/)vite\\.config\\.[cm]?[jt]s$/.test(file));\n if (viteConfigHit) {\n installedRows.push({ label: \"Dev proxy\", value: stylePath(viteConfigHit) });\n }\n\n // The login-customization entry points. These are what a user edits to\n // change what the login collects, how it authenticates and what it enforces —\n // burying them in the verbose per-file narration above the box means users\n // don't find them (each folder ships a README with the workflow).\n const customizeRows: Row[] = [];\n for (const [label, suffix, dir] of [\n [\"User schema\", \".zitadel/schemas/default-human-user.json\", \".zitadel/schemas/\"],\n [\"Login flow\", \".zitadel/flows/default-login.json\", \".zitadel/flows/\"],\n [\"Password policy\", PASSWORD_POLICY_PATH, \".zitadel/policies/\"],\n ] as const) {\n const hit = pickWrittenFile(writtenRel, suffix);\n if (hit) customizeRows.push({ label, value: stylePath(dir), secondary: \"see its README.md\" });\n }\n // One row per provider: each has its own connection file, and a developer\n // scanning the summary for where to edit needs the path that belongs to the\n // provider they are looking at.\n for (const answer of sso) {\n customizeRows.push({\n label: \"Social sign-in\",\n value: providerOf(answer.selection).displayName,\n secondary: stylePath(`.zitadel/idps/${providerOf(answer.selection).slug}.json`),\n });\n // A scripted `--sso` run asks nothing, so the prompt that announces the\n // URI never shows; the summary is where it reaches the developer then.\n customizeRows.push({\n label: \"Redirect URI\",\n value: styleUrl(callbackUriFor(issuer, providerOf(answer.selection).slug)),\n });\n }\n\n const projectRows: Row[] = [\n { label: \"Project id\", value: styleId(project.id) },\n { label: \"Server\", value: styleUrl(server) },\n { label: \"App will run\", value: styleUrl(issuer) },\n ];\n\n return [\n { title: \"Detected\", rows: detected },\n { title: \"Installed\", rows: installedRows },\n { title: \"Customize\", rows: customizeRows },\n { title: \"Project\", rows: projectRows },\n ];\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../lib/errors\";\nimport { serverLogAction } from \"../lib/journey-guidance\";\nimport { ensureLocalAdmin } from \"../lib/local-server/admin-credential\";\nimport { EMPTY_SUMMARY, loadProjectEnv } from \"../lib/local-server/env-vars\";\nimport {\n DEFAULT_LOCAL_SERVER_PORT,\n PLATFORM_PROJECT_ID,\n defaultLocalServerImageForCliVersion,\n ensureLocalState,\n localContainerName,\n localServerUrl,\n peekRuntimeMetadata,\n type RuntimeBackend,\n type RuntimeMetadata,\n} from \"../lib/local-server/runtime\";\nimport { LocalServer } from \"../lib/local-server/server\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope, nonBlankString } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\nimport { nextCommandsData } from \"../lib/oclif/envelope\";\nimport { unscopedCommand } from \"../lib/suggestion\";\n\nexport default class Start extends BaseCommand {\n static override description = \"Start a local Zitadel server.\";\n static override group = CommandGroups.gettingStarted;\n static override groupOrder = 2;\n static override flags = {\n image: nonBlankString({ description: \"Container image to run.\" }),\n port: Flags.integer({\n description:\n \"Local HTTP port. By default this directory keeps the port it had, or takes the first free one from 8080.\",\n }),\n runtime: Flags.string({\n description: \"Local runtime backend.\",\n options: [\"binary\", \"docker\"],\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Start);\n const requestedPort = flags.port;\n // Where the server will be, as far as is known before one is chosen: the\n // port asked for, else the one this directory already has.\n const recorded = await peekRuntimeMetadata(\n resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined),\n );\n const port = requestedPort ?? recorded?.port ?? DEFAULT_LOCAL_SERVER_PORT;\n const serverUrl = localServerUrl(port);\n await this.toMeta(flags, { resolveServer: false, source: serverUrl });\n\n validatePort(port);\n const runtimeBackend = resolveRuntimeBackend({\n image: flags.image,\n runtime: flags.runtime,\n envImage: this.meta.env.ZITADEL_LOCAL_IMAGE,\n });\n assertRuntimeFlags(runtimeBackend, flags.image);\n this.recordTelemetry({ runtime: runtimeBackend });\n const image =\n flags.image ??\n this.meta.env.ZITADEL_LOCAL_IMAGE ??\n defaultLocalServerImageForCliVersion(this.meta.cliVersion);\n const containerName = localContainerName(this.meta.cwd);\n if (this.meta.dryRun) {\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local Zitadel server start plan.\",\n runtime: {\n backend: runtimeBackend,\n ...(runtimeBackend === \"docker\"\n ? {\n container_name: containerName,\n image,\n }\n : {}),\n port,\n },\n urls: {\n api: serverUrl,\n console: `${serverUrl}/ui/console/`,\n },\n ...nextCommandsData([unscopedCommand(\"start\", this.meta.cliVersion)]),\n },\n });\n }\n\n await ensureLocalState(this.meta.cwd);\n // NEXTGEN_* variables from .env.local and .env are read before any runtime\n // is stopped and reach the new runtime through its environment only; see\n // env-vars.ts.\n const env = await loadProjectEnv(this.meta.cwd, this.meta.env);\n // The developer exists on their own server from the first start: the\n // server imports the local admin, and the console signs them in by link.\n // The admin is a user of the platform project, so the two travel together:\n // a caller that opts out of the platform bootstrap (a test harness wanting\n // a bare single-project server) gets neither. The opt-out is read from the\n // same merged environment the server receives — the project's env files\n // over the shell — so a `false` in `.env.local` turns both off rather than\n // being overridden by the user file forcing the bootstrap back on.\n const serverEnv = { ...this.meta.env, ...env.values };\n const local = platformBootstrapEnabled(serverEnv)\n ? await ensureLocalAdmin(this.meta.cwd, serverEnv.NEXTGEN_SCHEMA_BUILTIN_PUBLIC_BASE)\n : undefined;\n\n const { runtime, alreadyRunning } = await LocalServer.at(this.meta.cwd, {\n cliVersion: this.meta.cliVersion,\n }).start(\n runtimeBackend === \"docker\"\n ? { backend: \"docker\", image, env, userFile: local?.userFile }\n : { backend: \"binary\", env, userFile: local?.userFile },\n { port: requestedPort },\n );\n // The envelope's `source` named the port guessed before one was chosen; an\n // agent that follows it would target a different server than the one started.\n this.meta = { ...this.meta, source: runtime.server_url };\n return this.emit({\n status: \"ok\",\n data: readyData(runtime, alreadyRunning, this.meta.cliVersion),\n });\n }\n}\n\n/**\n * Whether this start boots the platform project, and with it the local admin.\n * On by default; an explicit `NEXTGEN_PLATFORM_BOOTSTRAP_PROJECT=false` opts\n * out, which is how a harness asks for a bare single-project instance.\n */\nfunction platformBootstrapEnabled(env: NodeJS.ProcessEnv): boolean {\n if ((env.NEXTGEN_PLATFORM_BOOTSTRAP_PROJECT ?? \"true\").toLowerCase() === \"false\") {\n return false;\n }\n // A server pinned to a project of its own cannot also bootstrap the platform\n // one — it refuses that combination at startup (cmd/server/config.go) — so the\n // pin wins and there is no local admin, rather than a start that cannot boot.\n const pinned = env.NEXTGEN_PLATFORM_PROJECT_ID;\n return !pinned || pinned === PLATFORM_PROJECT_ID;\n}\n\nfunction readyData(metadata: RuntimeMetadata, alreadyRunning: boolean, cliVersion: string) {\n return {\n title: alreadyRunning\n ? \"Local Zitadel server is already running.\"\n : \"Local Zitadel server is ready.\",\n runtime: {\n backend: metadata.backend,\n ...(metadata.backend === \"docker\"\n ? {\n container_name: metadata.container_name,\n container_id: metadata.container_id,\n image: metadata.image,\n }\n : {\n pid: metadata.pid,\n log_path: metadata.log_path,\n server_package: metadata.server_package,\n server_version: metadata.server_version,\n }),\n port: metadata.port,\n data_dir: metadata.data_dir,\n env: metadata.env ?? EMPTY_SUMMARY,\n },\n urls: {\n api: metadata.server_url,\n console: `${metadata.server_url}/ui/console/`,\n },\n next_actions: [\n \"Create an app with authentication. Run setup in this directory or a subdirectory.\",\n \"Setup asks for a framework and sign-in method, creates or updates your app, and installs its dependencies.\",\n serverLogAction(cliVersion),\n ],\n ...nextCommandsData([unscopedCommand(\"setup --server local\", cliVersion)]),\n };\n}\n\nfunction validatePort(port: number): void {\n if (!Number.isInteger(port) || port < 1 || port > 65_535) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid port ${String(port)}`, {\n hint: \"Use a TCP port between 1 and 65535.\",\n });\n }\n}\n\nfunction resolveRuntimeBackend(input: {\n runtime: unknown;\n image: string | undefined;\n envImage: string | undefined;\n}): RuntimeBackend {\n if (input.runtime === \"binary\" || input.runtime === \"docker\") {\n return input.runtime;\n }\n if (input.image || input.envImage) {\n return \"docker\";\n }\n return \"binary\";\n}\n\nfunction assertRuntimeFlags(runtime: RuntimeBackend, image: string | undefined): void {\n if (runtime === \"binary\" && image) {\n throw new ZitadelError(\"E_VALIDATION\", \"--image requires --runtime docker\", {\n hint: \"Use `zitadel start --runtime docker --image <tag>`, or omit --image for the npm binary runtime.\",\n });\n }\n}\n","import {\n claimAction,\n claimCommand,\n claimState,\n claimWindowClosedAction,\n type ClaimState,\n} from \"../lib/claim-state\";\nimport {\n customizeAndPublishActions,\n exploreAllCommands,\n verifyLoginAction,\n} from \"../lib/journey-guidance\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n readRuntimeMetadata,\n runtimeSummary,\n} from \"../lib/local-server/runtime\";\nimport { LocalServer } from \"../lib/local-server/server\";\nimport {\n type Connection,\n CommandGroups,\n EnvironmentCommand,\n type JsonEnvelope,\n} from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\nimport { shellArg, shellOption } from \"../lib/shell\";\nimport {\n hasZitadelConfig,\n hasZitadelSecret,\n readProjectServer,\n readZitadelConfig,\n readZitadelSecret,\n} from \"../lib/project\";\nimport {\n type EnvironmentSelector,\n projectCommand,\n type SuggestedCommand,\n unscopedCommand,\n} from \"../lib/suggestion\";\nimport { nextCommandsData } from \"../lib/oclif/envelope\";\nimport { DEPLOY_ARGS } from \"../lib/release\";\n\n/**\n * `zitadel status` — summarize the local server and project state.\n *\n * This is intentionally informational: a missing `zitadel.json`, stopped\n * local server, or orphaned config should be visible without making `status`\n * itself fail.\n */\nexport default class Status extends EnvironmentCommand {\n static override description = \"Summarize the local Zitadel server and project state.\";\n static override group = CommandGroups.gettingStarted;\n static override groupOrder = 3;\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Status);\n const cwd = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n const runtime = await readRuntimeMetadata(cwd);\n if (flags.server === \"local\") {\n await this.toMeta(flags, {\n resolveServer: false,\n source: runtime?.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n } else {\n await this.toMeta(flags);\n }\n const server = await LocalServer.at(this.meta.cwd, {\n cliVersion: this.meta.cliVersion,\n }).status();\n const serverLifecycle = server.lifecycle;\n\n const project = await projectStatus(\n this.meta.cwd,\n this.environment.values.ZITADEL_ISSUER?.value,\n this.environment.values.ZITADEL_PROJECT_ID?.value,\n this.environment.envFile !== undefined || this.environment.name.value !== \"development\"\n ? { name: this.environment.name.value, envFile: this.environment.envFile }\n : undefined,\n );\n const users =\n project.lifecycle === \"configured\"\n ? await detectUserPresence(() => this.connect({ quiet: true, prompt: false }))\n : \"unknown\";\n const nextCommands = nextCommandsFor(\n serverLifecycle,\n project,\n users,\n this.meta.cliVersion,\n this.environmentSelector(),\n // `--cwd` as typed, for the follow-ups the selector does not carry: the\n // runtime and the project files they act on live in that directory.\n typeof flags.cwd === \"string\" ? ` ${shellOption(\"--cwd\", flags.cwd)}` : \"\",\n );\n const nextActions = nextActionsFor(\n project,\n users,\n this.meta.cliVersion,\n this.environmentSelector(),\n );\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Zitadel status.\",\n server: {\n lifecycle: serverLifecycle,\n runtime: runtimeSummary(server.runtime),\n docker: server.docker,\n process: server.process,\n health: {\n healthy: server.healthy,\n url: server.runtime?.server_url,\n },\n },\n project,\n next_actions: nextActions,\n ...nextCommandsData(nextCommands),\n },\n footer: exploreAllCommands(this.meta.cliVersion),\n });\n }\n}\n\ntype ProjectStatus =\n | {\n lifecycle: \"not-configured\";\n message: string;\n /**\n * The environment that names no project, when it is not the default\n * development one: `setup` would not bind it, `env add` does.\n */\n environment?: string;\n /** The `--env-file` that names no project. */\n env_file?: string;\n }\n | {\n lifecycle: \"orphaned-config\";\n project_id?: string;\n message: string;\n }\n | {\n lifecycle: \"configured\";\n project_id: string;\n issuer?: string;\n /**\n * Whether the project is attached to a team, from the local\n * `.zitadel/secret`. Omitted entirely off the cloud, where there is\n * nothing to attach and the field would only invite agents to act on it.\n */\n claim?: ClaimState;\n };\n\n/**\n * `resolvedProjectId` is the project the environment resolved to — the same one\n * {@link detectUserPresence} probes through `connect()`. The displayed project\n * must be that one, not the id in `zitadel.json`, or `status --env` would name\n * one project while reporting another's users.\n */\nasync function projectStatus(\n cwd: string,\n issuer: string | undefined,\n resolvedProjectId: string | undefined,\n // Set when the run named an environment other than the default development\n // one, or a file: its project is whatever it resolves, never setup's.\n named: { name: string; envFile?: string } | undefined,\n): Promise<ProjectStatus> {\n if (!(await hasZitadelConfig(cwd))) {\n return {\n lifecycle: \"not-configured\",\n message: \"zitadel.json has not been created yet.\",\n };\n }\n // The local `zitadel.json` and `.zitadel/secret` describe the development\n // project. Reported under another environment's name, they would send every\n // suggested `--env` follow-up at a project that environment never binds.\n if (resolvedProjectId === undefined && named !== undefined) {\n return named.envFile === undefined\n ? {\n lifecycle: \"not-configured\",\n environment: named.name,\n message: `The ${named.name} environment names no project.`,\n }\n : {\n lifecycle: \"not-configured\",\n env_file: named.envFile,\n message: `${named.envFile} sets no ZITADEL_PROJECT_ID.`,\n };\n }\n\n const config = await readZitadelConfig(cwd);\n const secret = (await hasZitadelSecret(cwd)) ? await readZitadelSecret(cwd) : undefined;\n // The resolved environment decides the project when it names one — a\n // `status --env production` reads the project from `.env.production.local`,\n // which the local `.zitadel/secret` need not back. Only a config that\n // resolves to no project at all, with no local secret to fall back on, is\n // genuinely orphaned; derive the project first so the env wins over that\n // fallback.\n if (secret === undefined && resolvedProjectId === undefined) {\n return {\n lifecycle: \"orphaned-config\",\n project_id: typeof config.project === \"string\" ? config.project : undefined,\n message: \"zitadel.json exists but .zitadel/secret is missing.\",\n };\n }\n\n const projectId = resolvedProjectId ?? String(config.project ?? secret?.project_id ?? \"\");\n // The claim record lives in `.zitadel/secret`, which belongs to the local\n // project. It describes `projectId` only when the resolved environment points\n // at that same project; a `--env` aimed at another project has no local claim\n // record to show, so the block is omitted rather than shown against the wrong\n // project. Gated on the server in `zitadel.json`, not `this.meta.source`:\n // `status --server local` rewrites the source for the health probe but does\n // not move the project, so the source would answer the wrong question.\n const claim =\n secret !== undefined && projectId === secret.project_id\n ? claimState({ secret, server: readProjectServer(config) })\n : ({ kind: \"not-applicable\" } as const);\n return {\n lifecycle: \"configured\",\n project_id: projectId,\n issuer,\n ...(claim.kind === \"not-applicable\" ? {} : { claim }),\n };\n}\n\ntype UserPresence = \"none\" | \"some\" | \"unknown\";\n\nconst PRESENCE_PROBE_TIMEOUT_MS = 1500;\n\n/**\n * Whether the project has any users yet — the journey signal that stages the\n * guidance: before the first successful registration the next step is\n * verifying login, afterwards it is customizing and publishing config. Best\n * effort by design: any failure (server unreachable, stale secret, timeout)\n * reads as `unknown` and the caller keeps the lifecycle-only output.\n */\nasync function detectUserPresence(connect: () => Promise<Connection>): Promise<UserPresence> {\n try {\n const { client } = await connect();\n const probe = client\n .queryUsers({ limit: 1 }, undefined, {\n signal: AbortSignal.timeout(PRESENCE_PROBE_TIMEOUT_MS),\n })\n .then(({ users }): UserPresence => (users.length > 0 ? \"some\" : \"none\"))\n .catch((): UserPresence => \"unknown\");\n // The abort signal alone is not enough: DNS resolution can outlive it\n // (getaddrinfo runs on the threadpool and some environments take many\n // seconds to fail), and `status` must stay snappy. Race a detached timer\n // so the answer degrades to \"unknown\" at the deadline no matter what the\n // socket layer does; unref'd so it never keeps the CLI process alive.\n return await Promise.race([\n probe,\n new Promise<UserPresence>((resolve) => {\n setTimeout(() => resolve(\"unknown\"), PRESENCE_PROBE_TIMEOUT_MS + 250).unref();\n }),\n ]);\n } catch {\n return \"unknown\";\n }\n}\n\nfunction nextActionsFor(\n project: ProjectStatus,\n users: UserPresence,\n cliVersion: string,\n // Appended to the `claim` the prose nudge quotes: the action text is a\n // pasteable command, so it must carry the same environment selector the\n // machine `next_commands` do, or a reader copying it retargets the project.\n selector: EnvironmentSelector,\n): string[] {\n if (project.lifecycle === \"not-configured\") {\n return project.environment === undefined && project.env_file === undefined\n ? [\n \"From your app directory, run setup; the CLI will detect the framework or ask in an empty directory.\",\n ]\n : [];\n }\n if (project.lifecycle !== \"configured\") {\n return [];\n }\n // Additive to the journey staging rather than a stage of its own: attaching a\n // team is orthogonal to whether login works yet, so it appends to whichever\n // stage the user is in instead of displacing it. A closed window flips the\n // nudge to reconciliation wording, which still tells the user to run\n // `claim`: the local record may be stale (claimed from another machine\n // reads detached), and the server resolves the grant before the window,\n // so the command is the authoritative check, never a guaranteed failure.\n const claim =\n project.claim?.kind === \"detached\"\n ? project.claim.claimable\n ? [\n claimAction(\n cliVersion,\n project.claim.deadline === undefined ? undefined : new Date(project.claim.deadline),\n selector,\n ),\n ]\n : [claimWindowClosedAction(cliVersion, selector)]\n : [];\n if (users === \"none\") {\n return [verifyLoginAction(project.issuer), ...claim];\n }\n if (users === \"some\") {\n return [...customizeAndPublishActions(cliVersion, selector), ...claim];\n }\n return claim;\n}\n\nfunction nextCommandsFor(\n serverLifecycle: string,\n project: ProjectStatus,\n users: UserPresence,\n cliVersion: string,\n // The `--env`/`--env-file`/`--server` suffix this run was invoked with (empty\n // for the default environment). Carried into every project-scoped follow-up so\n // an agent running them stays on the environment `status` reported, rather than\n // silently falling back to the default development project.\n selector: EnvironmentSelector,\n cwdSuffix: string,\n): SuggestedCommand[] {\n const commands: SuggestedCommand[] = [];\n if (serverLifecycle !== \"running\") {\n commands.push(unscopedCommand(`start${cwdSuffix}`, cliVersion));\n }\n if (project.lifecycle === \"not-configured\" && project.environment !== undefined) {\n commands.push(\n unscopedCommand(`env add ${shellArg(project.environment)}${cwdSuffix}`, cliVersion),\n );\n } else if (project.lifecycle === \"not-configured\") {\n if (project.env_file === undefined) {\n commands.push(unscopedCommand(`setup --server local${cwdSuffix}`, cliVersion));\n }\n } else if (project.lifecycle === \"orphaned-config\") {\n commands.push(\n unscopedCommand(`setup --force${cwdSuffix}`, cliVersion),\n projectCommand(\"doctor --fix\", selector, cliVersion),\n );\n } else {\n commands.push(projectCommand(\"doctor\", selector, cliVersion));\n // Suggested even when the local record says the window has closed: the\n // record can be stale (claimed from another machine reads detached), and\n // `claim` is the safe reconciliation — the server checks the grant\n // before the window, so an attached project answers with a clean skip.\n if (project.claim?.kind === \"detached\") {\n commands.push(claimCommand(cliVersion, selector));\n }\n if (users === \"none\") {\n // Staged like next_actions: before the first login is proven in a\n // browser, publishing is premature — `deploy --dry-run` previews safely\n // and the verify mission lives in next_actions. A full `deploy` joins\n // once users exist (\"some\") or when the probe can't tell (\"unknown\"\n // keeps the lifecycle-only behavior rather than withholding on no signal).\n commands.push(projectCommand(\"deploy --dry-run\", selector, cliVersion));\n } else {\n commands.push(projectCommand(DEPLOY_ARGS, selector, cliVersion));\n }\n }\n return commands;\n}\n","import { Flags } from \"@oclif/core\";\n\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n localContainerName,\n readRuntimeMetadata,\n} from \"../lib/local-server/runtime\";\nimport { LocalServer } from \"../lib/local-server/server\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\nimport { nextCommandsData } from \"../lib/oclif/envelope\";\n\nexport default class Stop extends BaseCommand {\n static override description = \"Stop the local Zitadel server.\";\n static override group = CommandGroups.localDevelopment;\n static override groupOrder = 3;\n static override flags = {\n all: Flags.boolean({\n description: \"Stop all discovered CLI-managed local Zitadel runtime processes.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Stop);\n const cwd = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n const runtime = await readRuntimeMetadata(cwd);\n await this.toMeta(flags, {\n resolveServer: false,\n source: runtime?.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n\n if (flags.all) {\n return this.stopAllManagedRuntimes();\n }\n\n const containerName =\n runtime?.backend === \"docker\" ? runtime.container_name : localContainerName(this.meta.cwd);\n if (this.meta.dryRun) {\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local Zitadel server stop plan.\",\n runtime: {\n backend: runtime?.backend ?? \"missing\",\n ...(runtime?.backend === \"binary\"\n ? { pid: runtime.pid, log_path: runtime.log_path }\n : { container_name: containerName }),\n data_preserved: true,\n data_dir: runtime?.data_dir,\n },\n ...nextCommandsData([this.suggestUnscoped(\"stop\")]),\n },\n });\n }\n\n const { stopped, outcome } = await LocalServer.at(this.meta.cwd, {\n cliVersion: this.meta.cliVersion,\n }).stop();\n\n return this.emit({\n status: \"ok\",\n data: {\n title: stopped ? \"Local Zitadel server stopped.\" : \"Local Zitadel server was not running.\",\n runtime: {\n backend: runtime?.backend ?? \"missing\",\n ...(runtime?.backend === \"binary\"\n ? {\n pid: runtime.pid,\n log_path: runtime.log_path,\n stop_result: outcome,\n }\n : { container_name: containerName }),\n data_preserved: true,\n data_dir: runtime?.data_dir,\n },\n },\n });\n }\n\n private async stopAllManagedRuntimes(): Promise<JsonEnvelope> {\n const sweep = await LocalServer.stopAll(this.localServers());\n if (!sweep.supported) {\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Managed local runtime process discovery is unavailable.\",\n sweep: { supported: false, error: sweep.error, stopped: [] },\n },\n warnings: [\"managed-runtime-processes: discovery unavailable\"],\n });\n }\n\n return this.emit({\n status: \"ok\",\n data: {\n title:\n sweep.results.length === 0\n ? \"No host-wide managed local runtime processes found.\"\n : \"Host-wide managed local runtime processes stopped.\",\n sweep: {\n supported: true,\n scope: \"host\",\n count: sweep.results.length,\n results: sweep.results,\n },\n },\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../../lib/errors\";\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope, nonBlankArg } from \"../../lib/oclif\";\nimport { renderDetail } from \"../../lib/oclif/crud/table\";\nimport {\n assertVariableName,\n toVariableRow,\n variableCells,\n variableReadScope,\n} from \"../../lib/variables\";\n\n/**\n * `zitadel variable get NAME` — read one variable by name from the project.\n *\n * A name the project has not entered answers `var.not_found`. A secret is found\n * but not disclosed, so the answer says it is held and nothing more. Without\n * `--preview` it reads the primary value; with it, the preview value. A name with\n * no value of the kind asked for is a miss.\n */\nexport default class VariableGet extends EnvironmentCommand {\n static override description = \"Get one variable from the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variable get GOOGLE_CLIENT_ID\",\n \"<%= config.bin %> variable get API_URL --preview\",\n \"<%= config.bin %> variable get GOOGLE_CLIENT_ID --json\",\n ];\n static override args = {\n name: nonBlankArg({ required: true, description: \"Variable name to read.\" }),\n };\n static override flags = {\n preview: Flags.boolean({\n default: false,\n description: \"Read the preview value instead of the primary one.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(VariableGet);\n await this.toMeta(flags);\n const name = args.name;\n\n assertVariableName(name);\n const { client, projectId } = await this.connect();\n const scope = variableReadScope(projectId, flags.preview);\n\n // The single-name endpoint answers in the same two forms the collection\n // does, so the row projection is shared rather than duplicated.\n const value = (await client.getVariable(name, scope))[scope.kind];\n if (value === undefined) {\n throw new ZitadelError(\"E_NOT_FOUND\", `Variable ${name} has no ${scope.kind} value.`, {\n hint: flags.preview\n ? \"A name has a preview value only once one is set with `--preview`.\"\n : \"Set one with `variable set`.\",\n });\n }\n const row = toVariableRow(name, value);\n this.recordTelemetry({ is_secret: row.secret });\n\n const data = row;\n // The resource commands' `get`: a pipe receives the whole record, since a\n // script wants the record rather than a view of it. That is also what keeps\n // a secret from being mistaken for a value — it reads `\"secret\": true` and\n // carries no `value` at all.\n if (!process.stdout.isTTY) {\n return this.emit({ status: \"ok\", data, pretty: JSON.stringify(data, null, 2) });\n }\n const [cell] = variableCells([row]);\n return this.emit({\n status: \"ok\",\n data,\n pretty: renderDetail(name, [\"value\"], {\n // The detail view drops an empty field, which would hide a value that\n // is legitimately the empty string.\n value: cell?.value === \"\" ? '\"\"' : cell?.value,\n }),\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { renderList } from \"../../lib/oclif/crud/table\";\nimport { listData } from \"../../lib/oclif/envelope\";\nimport {\n toInventoryRows,\n toVariableRows,\n valuesOfKind,\n variableCells,\n variableInventoryCells,\n variableReadScope,\n} from \"../../lib/variables\";\n\n/** The columns `list` renders, in order; the inventory adds the preview kind. */\nconst COLUMNS = [\"name\", \"value\"] as const;\nconst INVENTORY_COLUMNS = [\"name\", \"value\", \"preview\"] as const;\n\n/**\n * `zitadel variable list` — show the variables entered on the project.\n *\n * The project's own set. A secret is reported as held without its value, because\n * the platform never discloses one. Without `--preview` it lists every name with\n * its primary value and whether a preview value exists beside it (#1617); with\n * `--preview` it lists the preview values alone, which are never merged with the\n * primary ones — only the names that hold one.\n */\nexport default class VariableList extends EnvironmentCommand {\n static override description = \"List the variables entered on the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variable list\",\n \"<%= config.bin %> variable list --preview\",\n \"<%= config.bin %> variable list --json\",\n ];\n static override flags = {\n preview: Flags.boolean({\n default: false,\n description: \"List the preview values instead of the primary ones.\",\n }),\n plain: Flags.boolean({\n description:\n \"Tab-separated rows with no header, for piping. Implied when stdout is not a terminal.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(VariableList);\n await this.toMeta(flags);\n const { client, projectId } = await this.connect();\n const scope = variableReadScope(projectId, flags.preview);\n\n // The inventory reads both kinds, which a read without a kind answers in\n // one request; `--preview` reads that kind alone.\n const rows = flags.preview\n ? toVariableRows(valuesOfKind(await client.getVariables(scope), scope.kind))\n : toInventoryRows(await client.getVariables({ project_id: projectId }));\n this.recordTelemetry({ variable_count: rows.length });\n\n // The resource commands' list rendering: a pipe (or `--plain`) gets one\n // tab-separated record per line, with no header and nothing at all when\n // empty, so `cut`, `awk` and `wc -l` work on it; a terminal gets a table.\n const cells = flags.preview ? variableCells(rows) : variableInventoryCells(rows);\n const plain = flags.plain || !process.stdout.isTTY;\n const empty = flags.preview\n ? \"No preview values on the project.\"\n : \"No variables on the project.\";\n return this.emit({\n status: \"ok\",\n data: listData(rows),\n pretty: renderList(flags.preview ? COLUMNS : INVENTORY_COLUMNS, cells as never, {\n plain,\n singular: \"variable\",\n empty,\n }),\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\nimport type { ZitadelClient } from \"@zitadel/api/client\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { renderRows, renderTable } from \"../../lib/oclif/crud/table\";\nimport { listData } from \"../../lib/oclif/envelope\";\nimport { DEPLOY_ARGS, listLiveDeployments, originMatchesPattern } from \"../../lib/release\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { shellArg } from \"../../lib/shell\";\nimport { toVariableRows, variableCells } from \"../../lib/variables\";\n\n/** The columns `resolve` renders, in order. */\nconst COLUMNS = [\"name\", \"value\"] as const;\n\n/**\n * `zitadel variable resolve` — show the variables a target actually runs.\n *\n * Not the store's current values but the map frozen onto the deployment that is\n * live on the target: what a later `variable set` has not reached. `--origin`\n * names one of the project's origins. Without it, resolving is unambiguous only\n * when a single deployment is live across the project; when several are — a\n * different release or frozen map on each origin — the live origins are named\n * and `--origin` is required rather than resolving from an arbitrary one\n * (#1617). A target with nothing deployed is a miss.\n */\nexport default class VariableResolve extends EnvironmentCommand {\n static override description = \"Show the variables the live deployment froze for a target.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variable resolve\",\n \"<%= config.bin %> variable resolve --origin https://app.acme.com\",\n \"<%= config.bin %> variable resolve --json\",\n ];\n static override flags = {\n origin: Flags.string({ description: \"The origin whose live deployment to read.\" }),\n plain: Flags.boolean({\n description:\n \"Tab-separated rows with no header, for piping. Implied when stdout is not a terminal.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(VariableResolve);\n await this.toMeta(flags);\n const { client, projectId } = await this.connect();\n const origin = flags.origin;\n\n // Every deployment live on the target now, newest first. `--origin` narrows\n // the read to one origin; without it the whole project's live set comes\n // back, so an ambiguous project can be named rather than resolved from an\n // arbitrary deployment.\n // Drained across pages, so a project with many live previews still names\n // every origin, primaries included.\n const deployments = await listLiveDeployments(\n client,\n projectId,\n origin === undefined ? {} : { origin },\n );\n\n // Without `--origin`, more than one live deployment means there is no single\n // frozen map to show: each origin may run a different one. The live origins\n // are named so the reader can pick one, rather than silently reading the\n // first (#1617).\n if (origin === undefined && deployments.length > 1) {\n const origins = [\n ...new Set(deployments.flatMap((deployment) => deployment.targets.map((t) => t.origin))),\n ].sort();\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"More than one deployment is live; name which origin to resolve with --origin.\",\n {\n hint: `Live origins: ${origins.join(\", \")}.`,\n nextCommands: origins.map((o) =>\n this.suggest(`variable resolve --origin ${shellArg(o)}`),\n ),\n },\n );\n }\n\n const live = deployments[0];\n if (live === undefined) {\n throw await this.nothingDeployed(client, projectId, origin);\n }\n // The live list narrows each deployment to the origins it still serves, so\n // this names exactly what the resolved map runs on — the chosen origin,\n // stated in the output.\n const servedOrigins = live.targets.map((target) => target.origin).sort();\n const where = servedOrigins.join(\", \");\n\n const rows = toVariableRows(\n await client.getDeploymentVariables(live.id, { project_id: projectId }),\n );\n this.recordTelemetry({ variable_count: rows.length });\n\n // The resource commands' list rendering: a pipe (or `--plain`) gets one\n // tab-separated record per line, with no header; a terminal gets a table.\n const cells = variableCells(rows);\n const plain = flags.plain || !process.stdout.isTTY;\n return this.emit({\n status: \"ok\",\n data: { deployment_id: live.id, origins: servedOrigins, ...listData(rows) },\n pretty: plain\n ? renderRows(COLUMNS, cells)\n : rows.length === 0\n ? `${live.id} froze no variables for ${where}.`\n : [\n renderTable(COLUMNS, cells),\n \"\",\n `${rows.length} ${rows.length === 1 ? \"variable\" : \"variables\"} frozen by ${live.id} for ${where}`,\n ].join(\"\\n\"),\n });\n }\n\n /**\n * The miss for an origin nothing is deployed to, with the fix that reaches\n * it: `deploy` goes to every primary origin, including one added since the\n * last deploy, and a preview origin is only ever served by a\n * pull-request build, never by `deploy`.\n */\n private async nothingDeployed(\n client: ZitadelClient,\n projectId: string,\n origin: string | undefined,\n ): Promise<ZitadelError> {\n if (origin === undefined) {\n return new ZitadelError(\"E_NOT_FOUND\", \"Nothing is deployed to the project.\", {\n hint: `Deploy first with \\`zitadel ${DEPLOY_ARGS}${this.environmentSelector()}\\`, then resolve its variables.`,\n nextCommands: [this.suggest(DEPLOY_ARGS)],\n });\n }\n const origins = (await client.getProject(projectId)).origins ?? [];\n if (origins.some((entry) => entry.kind === \"primary\" && entry.pattern === origin)) {\n return new ZitadelError(\"E_NOT_FOUND\", `Nothing is deployed to ${origin}.`, {\n hint: `Deploy to it first with \\`zitadel ${DEPLOY_ARGS}${this.environmentSelector()}\\`, then resolve its variables.`,\n nextCommands: [this.suggest(DEPLOY_ARGS)],\n });\n }\n if (\n origins.some(\n (entry) => entry.kind === \"preview\" && originMatchesPattern(entry.pattern, origin),\n )\n ) {\n return new ZitadelError(\"E_NOT_FOUND\", `Nothing is deployed to ${origin}.`, {\n hint: \"A preview URL is served by a pull-request build, not by `deploy`; resolve its variables once that build has deployed it.\",\n });\n }\n return new ZitadelError(\"E_NOT_FOUND\", `${origin} is not an origin of the project.`, {\n hint: \"Check the origin for a typo, or list the project's origins.\",\n nextCommands: [this.suggest(\"origin list\")],\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope, nonBlankArg } from \"../../lib/oclif\";\nimport { dryRunResult } from \"../../lib/oclif/crud/shared\";\nimport { deletedData } from \"../../lib/oclif/envelope\";\nimport { assertVariableName, variableScope } from \"../../lib/variables\";\nimport { Promptable } from \"../../lib/oclif/promptable\";\n\n/**\n * `zitadel variable rm NAME` — remove one variable from the project.\n *\n * `--preview` removes the preview value and leaves the primary one standing;\n * without it the variable is removed for both kinds. Destructive, so it takes the\n * same `--force`-or-confirm gate the resource commands' `rm` uses.\n */\nexport default class VariableRm extends Promptable(EnvironmentCommand) {\n static override description = \"Remove one variable from the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variable rm GOOGLE_CLIENT_ID\",\n \"<%= config.bin %> variable rm API_URL --preview\",\n \"<%= config.bin %> variable rm GOOGLE_CLIENT_ID --force\",\n ];\n static override args = {\n name: nonBlankArg({ required: true, description: \"Variable name to remove.\" }),\n };\n static override flags = {\n preview: Flags.boolean({\n default: false,\n description: \"Remove the preview value alone, leaving the primary one standing.\",\n }),\n // `--force` is per command, not global: here it permits a removal.\n force: Flags.boolean({\n char: \"f\",\n description:\n \"Remove the variable without the confirmation prompt. Required when non-interactive.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(VariableRm);\n await this.toMeta(flags);\n const { dryRun } = this.meta;\n const name = args.name;\n\n assertVariableName(name);\n\n const { client, projectId } = await this.connect();\n const scope = variableScope(projectId, flags.preview);\n const kinds = flags.preview ? [\"preview\"] : [\"primary\", \"preview\"];\n\n // A dry run makes no request, so it answers before the guard — the order\n // the resource commands' `rm` uses, which keeps `--dry-run\n // --non-interactive` usable.\n if (dryRun) {\n const preview = dryRunResult(\"remove\", \"variable\", name);\n return this.emit({\n ...preview,\n data: { ...(preview.data as object), kinds },\n pretty: `${preview.pretty} from the project${flags.preview ? \" (preview)\" : \"\"}`,\n });\n }\n\n const confirmed = await this.input({\n kind: \"confirm\",\n name: `remove ${name} from the project`,\n message: `Remove ${name} from the project?`,\n retry: this.suggest(`variable rm ${name}${flags.preview ? \" --preview\" : \"\"} --force`),\n });\n if (!confirmed) {\n return this.emit({ status: \"skipped\", reason: \"remove-cancelled\" });\n }\n\n await client.deleteVariable(name, scope);\n\n return this.emit({\n status: \"ok\",\n data: { ...deletedData({ name }), kinds },\n pretty: `Removed ${name} from the project${flags.preview ? \" (preview)\" : \"\"}`,\n });\n }\n}\n","import { Args, Flags } from \"@oclif/core\";\nimport { ApiError } from \"@zitadel/api/runtime/fetch\";\n\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope, nonBlankArg } from \"../../lib/oclif\";\nimport { dryRunResult } from \"../../lib/oclif/crud/shared\";\nimport { renderDetail } from \"../../lib/oclif/crud/table\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport {\n assertVariableName,\n parseVariableValue,\n toVariableRow,\n VARIABLE_TYPES,\n variableCells,\n type VariableRow,\n type VariableType,\n type VariableValue,\n type VariableKind,\n variableReadScope,\n variableScope,\n} from \"../../lib/variables\";\nimport { inShell } from \"../../lib/suggestion\";\nimport { Promptable } from \"../../lib/oclif/promptable\";\n\n/**\n * `zitadel variable set NAME [VALUE]` — enter or replace one variable on the\n * project.\n *\n * A plain value may be given on the command line; a secret never can. A secret\n * is prompted for, or read from stdin when scripting, so a credential cannot\n * land in shell history, a process listing, or CI logs. `--secret` stores it\n * encrypted under the project's own key, after which it can be replaced but\n * never read back (ADR 062 §7).\n *\n * Without `--preview` the platform's default applies: a plain value is stored\n * for both kinds, so primary and preview deploys both see it, and a secret for\n * the primary kind only, removing any preview value so a preview never keeps a\n * plaintext copy. `--preview` writes the preview kind alone.\n */\nexport default class VariableSet extends Promptable(EnvironmentCommand) {\n static override description = \"Set one variable on the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variable set GOOGLE_CLIENT_ID 1234.apps.googleusercontent.com\",\n \"<%= config.bin %> variable set GOOGLE_CLIENT_SECRET --secret < secret.txt\",\n \"<%= config.bin %> variable set SESSION_TTL 3600 --as number\",\n \"<%= config.bin %> variable set API_URL https://preview.acme.com --preview\",\n ];\n static override args = {\n name: nonBlankArg({\n required: true,\n description: \"Variable name (letters, digits and underscores).\",\n }),\n // A plain value may be given here; an empty string is a value the scalar\n // schema accepts, so this is not `nonBlankArg`. A secret refuses it below.\n // `ignoreStdin` keeps oclif from folding piped input into this arg — a\n // secret and a scripted plain value both arrive on stdin, which this command\n // reads itself through `input`.\n value: Args.string({\n required: false,\n ignoreStdin: true,\n description: \"The value, for a plain (non-secret) variable.\",\n }),\n };\n static override flags = {\n secret: Flags.boolean({\n default: false,\n description: \"Store the value encrypted. It can be replaced later but never read back.\",\n }),\n as: Flags.string({\n options: [...VARIABLE_TYPES],\n default: \"string\",\n description: \"Store the value as this JSON type.\",\n }),\n preview: Flags.boolean({\n default: false,\n description: \"Write the preview value alone, leaving the primary one as it is.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(VariableSet);\n await this.toMeta(flags);\n const { dryRun } = this.meta;\n const name = args.name;\n const type = flags.as as VariableType;\n\n assertVariableName(name);\n // A credential is a string: a numeric-looking key stored as a number could\n // lose digits, and one stored as a boolean is meaningless. Refused before\n // anything is asked for, so no secret is typed only to be turned away.\n if (flags.secret && type !== \"string\") {\n throw new ZitadelError(\"E_VALIDATION\", \"A secret is stored as a string.\", {\n hint: \"Drop --as, or drop --secret for a non-credential number or boolean.\",\n });\n }\n // A secret never comes from the command line: it would land in shell history\n // and a process listing. It is prompted for or piped instead.\n if (flags.secret && args.value !== undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"A secret value is not given on the command line.\", {\n hint: \"Drop the value and pipe it in, or let the prompt ask for it.\",\n });\n }\n\n const { client, projectId } = await this.connect();\n const scope = variableScope(projectId, flags.preview);\n // The kinds this write sets, as the platform's rule gives them: the preview\n // kind alone under `--preview`, otherwise both for a plain value and the\n // primary kind for a secret.\n const kinds = flags.preview ? [\"preview\"] : flags.secret ? [\"primary\"] : [\"primary\", \"preview\"];\n\n // A name whose primary value is a secret holds a credential, so its preview\n // value is one too: stored plain it would be readable, and a preview deploy\n // would freeze the credential in the clear. A token that may not read the\n // primary values leaves the check to whoever can.\n if (flags.preview && !flags.secret) {\n // Only a refusal is tolerated, and only because the check then belongs to\n // whoever can read the primary values. Any other failure leaves the\n // classification unknown, and writing on an unknown would be the one\n // outcome this guard exists to prevent: a credential stored in the clear.\n const held = await client\n .getVariables({ project_id: projectId, kind: \"primary\" })\n .then((body) => body[name]?.primary)\n .catch((error: unknown) => {\n if (error instanceof ApiError && error.status === 403) {\n return undefined;\n }\n throw error;\n });\n if (typeof held === \"object\" && held !== null) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${name} is a secret, so its preview value must be one too.`,\n {\n hint: \"Set the preview value with --secret, piped in or prompted for.\",\n nextCommands: [\n inShell(this.suggest(pipeArgs(name, true, \"string\", true)), {\n after: \" < value.txt\",\n }),\n ],\n },\n );\n }\n }\n\n if (dryRun) {\n // A value given on the command line is checked as the real run checks\n // it, so a preview never reports a write the run would refuse.\n const given = args.value === undefined ? undefined : parseVariableValue(args.value, type);\n if (given !== undefined && !given.ok) {\n throw new ZitadelError(\"E_VALIDATION\", given.problem);\n }\n // The resource commands' dry-run contract, plus what this write would\n // store. Never the value: it may be a credential.\n const preview = dryRunResult(\"set\", \"variable\", name);\n return this.emit({\n ...preview,\n data: {\n ...(preview.data as object),\n name,\n type,\n secret: flags.secret,\n kinds,\n },\n pretty: `${preview.pretty} on the project${flags.secret ? \" (secret)\" : \"\"}${type === \"string\" ? \"\" : ` as ${type}`}${flags.preview ? \" (preview)\" : \"\"}`,\n });\n }\n\n // A plain value given on the command line is used as it is. Otherwise the\n // value is prompted for, or piped in when scripting. The prompt is masked\n // when the value is to be stored as a secret, so it does not stay on screen\n // or in a scrollback buffer. An empty string is a value the scalar schema\n // accepts; only an absent input is an error.\n const value = await this.input({\n kind: flags.secret ? \"secret\" : \"text\",\n name: `value for ${name}`,\n message: `What should the value of ${name} be?`,\n ...(flags.secret || args.value === undefined ? {} : { given: args.value }),\n stdin: true,\n // The selector this.suggest appends must precede the stdin redirection.\n retry: inShell(this.suggest(pipeArgs(name, flags.secret, type, flags.preview)), {\n after: \" < value.txt\",\n }),\n parse: (raw: string) => parseVariableValue(raw, type),\n });\n\n // The write answers with the kind it wrote, so a secret says only that a\n // value is held (ADR 062 §7), never the value itself. The kind this write\n // did not touch is read in a separate call: the platform never merges the\n // two kinds in one answer.\n const written = (\n await client.updateVariables({ [name]: { value, secret: flags.secret } }, scope)\n )[name];\n this.recordTelemetry({ is_secret: flags.secret });\n const stateOfKind = async (kind: VariableKind): Promise<KindState> =>\n stateOf(\n written?.[kind] !== undefined\n ? written[kind]\n : (await client.getVariables(variableReadScope(projectId, kind === \"preview\")))[name]?.[\n kind\n ],\n );\n const primary = await stateOfKind(\"primary\");\n const previewState = await stateOfKind(\"preview\");\n\n return this.emit({\n status: \"ok\",\n data: { name, type, kinds, primary, preview: previewState },\n pretty: renderDetail(`Set ${name} on the project`, [\"primary\", \"preview\"], {\n primary: stateCell(primary),\n preview: stateCell(previewState),\n }),\n });\n }\n}\n\n/**\n * What the store holds for one name of one kind, as a read reports it. A kind\n * the name has no value for is `held: false` rather than omitted, so the output\n * tells an empty value apart from a withdrawn one. A secret is `held` without a\n * value: the platform never discloses one.\n */\ntype KindState =\n | { held: false }\n | { held: true; secret: true }\n | { held: true; secret: false; value: string | number | boolean };\n\nfunction stateOf(value: VariableValue | undefined): KindState {\n // A held kind always carries a value — a scalar, or `{secret:true}` for a\n // secret — so `undefined` is exactly the name not holding that kind.\n if (value === undefined) {\n return { held: false };\n }\n const row = toVariableRow(\"\", value);\n return row.secret\n ? { held: true, secret: true }\n : { held: true, secret: false, value: row.value as string | number | boolean };\n}\n\n/**\n * One kind rendered for a terminal. A held value goes through the same escaping\n * the tables use — a stored value is attacker-influenceable — and a secret\n * prints its marker rather than a value. A kind the name has no value for reads\n * as `(not set)` so it is not mistaken for an empty value.\n */\nfunction stateCell(state: KindState): string {\n if (!state.held) {\n return \"(not set)\";\n }\n const row: VariableRow = state.secret\n ? { name: \"\", secret: true }\n : { name: \"\", secret: false, value: state.value };\n const [cell] = variableCells([row]);\n return cell === undefined || cell.value === \"\" ? '\"\"' : cell.value;\n}\n\n/**\n * The scripted form to suggest when a run supplied no value.\n *\n * It carries the secret flag, the type and the preview flag the run actually\n * used. Dropping any of them would hand back a command that writes a credential\n * as a readable value, stores a number as a string, or writes the wrong kind.\n */\nfunction pipeArgs(name: string, secret: boolean, type: VariableType, preview: boolean): string {\n return [\n \"variable\",\n \"set\",\n name,\n ...(secret ? [\"--secret\"] : []),\n ...(type === \"string\" ? [] : [\"--as\", type]),\n ...(preview ? [\"--preview\"] : []),\n ].join(\" \");\n}\n","import type { Command } from \"@oclif/core\";\n\nimport Api from \"./commands/api/index\";\nimport ApiLs from \"./commands/api/ls\";\nimport AuthMethodPasskeyDisable from \"./commands/auth-method/passkey/disable\";\nimport AuthMethodPasskeyEnable from \"./commands/auth-method/passkey/enable\";\nimport AuthMethodPasswordDisable from \"./commands/auth-method/password/disable\";\nimport AuthMethodPasswordEnable from \"./commands/auth-method/password/enable\";\nimport AuthMethodSsoDisable from \"./commands/auth-method/sso/disable\";\nimport AuthMethodSsoEnable from \"./commands/auth-method/sso/enable\";\nimport BrandingEject from \"./commands/branding/eject\";\nimport Claim from \"./commands/claim\";\nimport Console from \"./commands/console\";\nimport Deploy from \"./commands/deploy\";\nimport DeploymentCreate from \"./commands/deployment/create\";\nimport DeploymentGet from \"./commands/deployment/get\";\nimport DeploymentList from \"./commands/deployment/list\";\nimport DeploymentRollback from \"./commands/deployment/rollback\";\nimport Doctor from \"./commands/doctor/index\";\nimport Eject from \"./commands/eject\";\nimport Env from \"./commands/env/index\";\nimport EnvAdd from \"./commands/env/add\";\nimport EnvList from \"./commands/env/list\";\nimport Logs from \"./commands/logs\";\nimport OriginAdd from \"./commands/origin/add\";\nimport OriginList from \"./commands/origin/list\";\nimport OriginRm from \"./commands/origin/rm\";\nimport Preview from \"./commands/preview/index\";\nimport PreviewList from \"./commands/preview/list\";\nimport PreviewRm from \"./commands/preview/rm\";\nimport Pull from \"./commands/pull\";\nimport ReleaseCreate from \"./commands/release/create\";\nimport ReleaseRevoke from \"./commands/release/revoke\";\nimport Reset from \"./commands/reset\";\nimport { RESOURCE_COMMANDS } from \"./commands/resources\";\nimport ResourcesList from \"./commands/resources-list\";\nimport Setup from \"./commands/setup/index\";\nimport Start from \"./commands/start\";\nimport Status from \"./commands/status\";\nimport Stop from \"./commands/stop\";\nimport VariableGet from \"./commands/variable/get\";\nimport VariableList from \"./commands/variable/list\";\nimport VariableResolve from \"./commands/variable/resolve\";\nimport VariableRm from \"./commands/variable/rm\";\nimport VariableSet from \"./commands/variable/set\";\n\n/**\n * The explicit oclif command table (`oclif.commands.strategy: \"explicit\"` in\n * `package.json`). Keys are command ids with `:` as the topic separator;\n * oclif renders them with the configured space separator (`users list`).\n *\n * Hand-written workflow commands are listed first; the resource commands\n * (`users`, `teams`, `sessions`, …) come from the registry in\n * `commands/resources.ts`, so a new backend resource is one registry entry.\n */\nexport const COMMANDS: Record<string, typeof Command> = {\n api: Api,\n claim: Claim,\n console: Console,\n deploy: Deploy,\n doctor: Doctor,\n eject: Eject,\n env: Env,\n logs: Logs,\n preview: Preview,\n pull: Pull,\n reset: Reset,\n resources: ResourcesList,\n setup: Setup,\n start: Start,\n status: Status,\n stop: Stop,\n \"auth-method:password:enable\": AuthMethodPasswordEnable,\n \"auth-method:password:disable\": AuthMethodPasswordDisable,\n \"auth-method:passkey:enable\": AuthMethodPasskeyEnable,\n \"auth-method:passkey:disable\": AuthMethodPasskeyDisable,\n \"auth-method:sso:enable\": AuthMethodSsoEnable,\n \"auth-method:sso:disable\": AuthMethodSsoDisable,\n \"api:ls\": ApiLs,\n \"branding:eject\": BrandingEject,\n \"deployment:create\": DeploymentCreate,\n \"deployment:get\": DeploymentGet,\n \"deployment:list\": DeploymentList,\n \"deployment:rollback\": DeploymentRollback,\n \"env:add\": EnvAdd,\n \"env:list\": EnvList,\n \"origin:add\": OriginAdd,\n \"origin:list\": OriginList,\n \"origin:rm\": OriginRm,\n \"preview:list\": PreviewList,\n \"preview:rm\": PreviewRm,\n \"release:create\": ReleaseCreate,\n \"release:revoke\": ReleaseRevoke,\n \"variable:set\": VariableSet,\n \"variable:get\": VariableGet,\n \"variable:list\": VariableList,\n \"variable:rm\": VariableRm,\n \"variable:resolve\": VariableResolve,\n ...RESOURCE_COMMANDS,\n};\n"],"mappings":"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"}