@zitadel/cli 0.1.0-alpha.8 → 0.1.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 (45) hide show
  1. package/README.md +2758 -210
  2. package/bin/run.js +8 -0
  3. package/dist/index.mjs +25199 -0
  4. package/dist/index.mjs.map +1 -0
  5. package/dist/lib/oclif/help.mjs +71 -0
  6. package/dist/lib/oclif/help.mjs.map +1 -0
  7. package/dist/skills-hint-BSspFzhr.mjs +173 -0
  8. package/dist/skills-hint-BSspFzhr.mjs.map +1 -0
  9. package/oclif.manifest.json +5846 -250
  10. package/package.json +73 -13
  11. package/skills/zitadel-cli/SKILL.md +442 -0
  12. package/skills/zitadel-cli/references/driving-login-ui.md +89 -0
  13. package/SKILLS.md +0 -152
  14. package/dist/commands/apply.mjs +0 -62
  15. package/dist/commands/apply.mjs.map +0 -1
  16. package/dist/commands/doctor.mjs +0 -490
  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 -71
  25. package/dist/commands/reset.mjs.map +0 -1
  26. package/dist/commands/setup.mjs +0 -916
  27. package/dist/commands/setup.mjs.map +0 -1
  28. package/dist/commands/start.mjs +0 -221
  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 -52
  33. package/dist/commands/stop.mjs.map +0 -1
  34. package/dist/docker-BA78SdC2.mjs +0 -383
  35. package/dist/docker-BA78SdC2.mjs.map +0 -1
  36. package/dist/docker-guidance-BvfpmsDj.mjs +0 -21
  37. package/dist/docker-guidance-BvfpmsDj.mjs.map +0 -1
  38. package/dist/oclif-VkCTGIEk.mjs +0 -818
  39. package/dist/oclif-VkCTGIEk.mjs.map +0 -1
  40. package/dist/orca-CfKDQRop.mjs +0 -2556
  41. package/dist/orca-CfKDQRop.mjs.map +0 -1
  42. package/dist/project-CKAHtHML.mjs +0 -87
  43. package/dist/project-CKAHtHML.mjs.map +0 -1
  44. package/dist/sync-B5lqgQO3.mjs +0 -733
  45. package/dist/sync-B5lqgQO3.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["errorMessage","isObject","isErrno","REQUEST_TIMEOUT_MS","createZitadelClient","createRawClient","isObject","isObject","valueAt","isObject","request","fetchWithPolicy","REQUEST_TIMEOUT_MS","text","errorMessage","isObject","isErrno","sleep","isErrno","unique","isErrno","isErrno","DISABLED_VALUES","delay","askInput","consola","isObject","exists","isObject","createZitadelClient","isObject","isObject","steps","isErrno","isObject","isObject","isErrno","isObject","isObject","isErrno","isObject","isPlainObject","isErrno","readJsonDir","createZitadelClient","createZitadelClient","isErrno","nodeSpawn","createZitadelClient","sleep","isObject","isObject","createZitadelClient","isObject","dirExists","isObject","readIfExists","isObject","exists","isObject","readTextIfExists","isObject","isFile","isObject","HOST_KEEPING_ENTRY","forwardAppOrigin","SDK_DEPENDENCY","ROOT","isObject","isObject","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","isObject","isObject","exists","resolveRuntimeBackend","createZitadelClient","isObject","isObject","fieldsOf","valueAt","isObject","createZitadelClient","createZitadelClient","createZitadelClient","createZitadelClient","relativeDisplay","isErrno","stylePath","styleUrl","styleId","createZitadelClient"],"sources":["../src/lib/errors.ts","../src/lib/interrupt.ts","../src/lib/api-client.ts","../src/lib/json.ts","../src/lib/oclif/crud/paging.ts","../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/variables.ts","../src/lib/input.ts","../src/lib/local-server/processes.ts","../src/lib/paths.ts","../src/lib/public-cli.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.ts","../src/lib/server.ts","../src/lib/telemetry/dimensions/env-flag.ts","../src/lib/telemetry/dimensions/ci-flag.ts","../src/lib/telemetry/config.ts","../src/lib/telemetry/consent.ts","../src/lib/telemetry/util.ts","../src/lib/telemetry/index.ts","../src/lib/telemetry/dimensions/ci-provider.ts","../src/lib/telemetry/dimensions/host-agent.ts","../src/lib/user-agent.ts","../src/lib/warnings.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/oclif/base.ts","../src/lib/project.ts","../src/lib/oclif/owner-command.ts","../src/lib/flows/env-refs.ts","../src/lib/flows/sign-in.ts","../src/lib/flows/index.ts","../src/lib/idp/connections.ts","../src/lib/idp/documents.ts","../src/lib/idp/custom.ts","../src/lib/idp/callback.ts","../src/lib/idp/endpoints.ts","../src/lib/idp/credentials.ts","../src/lib/user-schema/index.ts","../src/lib/idp/schemas.ts","../src/lib/auth-methods.ts","../src/lib/sync/state.ts","../src/lib/schema-flows.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/lib/local-files.ts","../src/lib/branding/index.ts","../src/lib/sync/types.ts","../src/lib/sync/syncers.ts","../src/lib/sync/asset-probe.ts","../src/lib/sync/flow-validation.ts","../src/lib/sync/plan-renderer.ts","../src/lib/sync/sso-validation.ts","../src/lib/sync/loop.ts","../src/commands/apply.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/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/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/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/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/project-match.ts","../src/lib/json-dir.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/logs.ts","../src/commands/plan.ts","../src/commands/reset.ts","../src/lib/oclif/crud/ops/command.ts","../src/lib/oclif/crud/secrets.ts","../src/lib/oclif/crud/shared.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/journey-guidance.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/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/variables/delete.ts","../src/commands/variables/get.ts","../src/commands/variables/list.ts","../src/commands/variables/set.ts","../src/index.ts"],"sourcesContent":["import { ApiError, apiErrorMessage, NetworkError } from \"@zitadel/api/runtime/fetch\";\n\n/**\n * Closed set of failure categories the CLI can surface. Every error the\n * user sees is funnelled into one of these so messaging, exit codes, and\n * machine-readable output stay consistent regardless of where the failure\n * originated.\n */\nexport type ZitadelErrorCode =\n | \"E_ALREADY_INIT\"\n | \"E_FRAMEWORK_NOT_DETECTED\"\n | \"E_UNSUPPORTED_PROJECT_SHAPE\"\n | \"E_NETWORK\"\n | \"E_AUTH\"\n | \"E_CONFLICT\"\n | \"E_LOCAL_SERVER_NOT_RUNNING\"\n | \"E_NOT_FOUND\"\n | \"E_PORT_IN_USE\"\n | \"E_VALIDATION\"\n | \"E_CREDENTIAL_MISSING\"\n | \"E_NOT_IMPLEMENTED\"\n | \"E_CANCELLED\";\n\n/**\n * Maps each {@link ZitadelErrorCode} to the process exit code the CLI\n * returns. The table is the single source of truth for exit semantics so\n * scripts and CI can branch on stable, documented numbers.\n */\nexport const EXIT_CODES: Record<ZitadelErrorCode, number> = {\n E_ALREADY_INIT: 0,\n E_FRAMEWORK_NOT_DETECTED: 3,\n E_UNSUPPORTED_PROJECT_SHAPE: 3,\n E_NETWORK: 4,\n E_AUTH: 1,\n E_CONFLICT: 5,\n E_LOCAL_SERVER_NOT_RUNNING: 4,\n E_NOT_FOUND: 4,\n E_PORT_IN_USE: 5,\n E_VALIDATION: 3,\n E_CREDENTIAL_MISSING: 3,\n E_NOT_IMPLEMENTED: 2,\n // 128 + SIGINT, what a shell reports for a command stopped by Ctrl-C.\n E_CANCELLED: 130,\n};\n\n/**\n * Optional, user-facing extras attached to a {@link ZitadelError}. Kept\n * separate from the message so the renderer can present a hint, suggested\n * follow-up commands, and structured details independently (e.g. as JSON\n * fields) rather than concatenating everything into one string.\n */\nexport type ZitadelErrorOptions = {\n hint?: string;\n nextCommands?: string[];\n details?: unknown;\n};\n\n/**\n * The CLI's single error type. Carries a {@link ZitadelErrorCode} so the\n * top-level handler can derive an exit code and structured output without\n * pattern-matching on messages. Throwing this anywhere guarantees the user\n * gets a categorised, hint-bearing failure instead of a raw stack trace.\n */\nexport class ZitadelError extends Error {\n readonly code: ZitadelErrorCode;\n readonly hint?: string;\n readonly nextCommands?: string[];\n readonly details?: unknown;\n\n constructor(code: ZitadelErrorCode, message: string, opts: ZitadelErrorOptions = {}) {\n super(message);\n this.name = \"ZitadelError\";\n this.code = code;\n this.hint = opts.hint;\n this.nextCommands = opts.nextCommands;\n this.details = opts.details;\n }\n\n get exitCode(): number {\n return EXIT_CODES[this.code] ?? 1;\n }\n}\n\n/**\n * Normalises any thrown value into a {@link ZitadelError}. Inspection is\n * ordered most-specific-first (already-normalised, HTTP status, then\n * errno/filesystem, no response, Zod-like, generic `Error`, then a\n * catch-all) so the most actionable category and hint win. A cancelled\n * request arrives already normalised, as the `E_CANCELLED` error that\n * `./interrupt` aborts it with. This is the boundary that lets the rest\n * of the CLI `throw` plain errors yet still produce consistent, categorised\n * output. The original error shape is preserved under `details` for\n * debugging without leaking it into the user-facing message.\n */\nexport function toZitadelError(error: unknown): ZitadelError {\n if (error instanceof ZitadelError) {\n return error;\n }\n\n if (error instanceof ApiError) {\n // `401`/`403` → bad or missing project secret; `404` → something is\n // missing (see below); `5xx` → transport or server fault; everything\n // else 4xx → the body the CLI sent was rejected (validation, conflict, …).\n const details = { status: error.status, url: error.url, body: error.body };\n if (error.status === 404) {\n // A 404 carrying the platform's error envelope (a `code` field) is a\n // domain-level miss from a real Zitadel API — an unknown schema or\n // project id. Without the envelope the endpoint itself is missing:\n // the CLI is pointed at a server that isn't a Zitadel platform API.\n const wrongServer = !isPlatformErrorEnvelope(error.body);\n const message = wrongServer\n ? `${apiErrorMessage(error)} — ${error.url} has no such endpoint; is this a Zitadel platform API?`\n : apiErrorMessage(error);\n return new ZitadelError(\"E_NOT_FOUND\", message, { details });\n }\n const code: ZitadelErrorCode =\n error.status === 401 || error.status === 403\n ? \"E_AUTH\"\n : error.status >= 500\n ? \"E_NETWORK\"\n : \"E_VALIDATION\";\n // The platform names the fields it rejected, and the message does not\n // repeat them: `idp.field_immutable` says only \"the field is fixed for the\n // life of the connection\", which leaves the reader to guess which of a\n // connection document's fields it meant. Promoting them to the hint puts\n // the answer where the failure is read, not only in `--json`. The same\n // goes for what a refusal says is missing: `idp.endpoints_partial` names\n // the endpoints a connection left out only in `missing`.\n const fields = listedInDetails(error.body, \"fields\");\n const missing = listedInDetails(error.body, \"missing\");\n const hint = [\n ...(fields.length > 0\n ? [\n `The server rejected ${fields.length === 1 ? \"this field\" : \"these fields\"}: ${fields.join(\", \")}.`,\n ]\n : []),\n ...(missing.length > 0\n ? [\n `The server reports ${missing.length === 1 ? \"this endpoint\" : \"these endpoints\"} missing: ${missing.join(\", \")}.`,\n ]\n : []),\n ].join(\" \");\n return new ZitadelError(code, apiErrorMessage(error), {\n ...(hint !== \"\" ? { hint } : {}),\n details,\n });\n }\n\n if (isErrnoException(error)) {\n const details = { original: pickErrorShape(error) };\n if (error.code === \"EACCES\" || error.code === \"EPERM\") {\n return new ZitadelError(\"E_AUTH\", `Permission denied: ${error.message}`, {\n hint: \"Check file permissions or run with the right user.\",\n details,\n });\n }\n if (error.code === \"EEXIST\") {\n return new ZitadelError(\"E_CONFLICT\", error.message, {\n hint: \"A file already exists. Use --force to overwrite or remove it first.\",\n details,\n });\n }\n if (error.code === \"ENOENT\") {\n return new ZitadelError(\"E_VALIDATION\", error.message, {\n hint: \"A required file or directory is missing.\",\n details,\n });\n }\n }\n\n if (error instanceof NetworkError) {\n return new ZitadelError(\"E_NETWORK\", error.message, {\n hint:\n error.reason === \"timeout\"\n ? \"The server accepted the connection but did not answer in time. Check that it is healthy, then retry.\"\n : \"Check your connection, ZITADEL_API_BASE, or the configured server URL.\",\n details: { url: error.url, reason: error.reason },\n });\n }\n\n if (isZodLikeError(error)) {\n return new ZitadelError(\"E_VALIDATION\", errorMessage(error), {\n details: { issues: (error as { issues: unknown }).issues },\n });\n }\n\n if (error instanceof Error) {\n return new ZitadelError(\"E_VALIDATION\", error.message, {\n details: { original: pickErrorShape(error) },\n });\n }\n\n return new ZitadelError(\"E_VALIDATION\", \"Unknown error\", { details: error });\n}\n\n/**\n * True when a response body looks like the platform's structured error\n * envelope (`{ code, message, … }`). Its presence proves the request reached\n * a real Zitadel platform API rather than an arbitrary HTTP server.\n */\n/**\n * The names a platform error envelope lists under `key`, if any: the dotted\n * field paths it blames (`fields`), or what it reports missing (`missing`).\n *\n * The envelope nests them under `details`, and the server wraps its own\n * `details` map in the response's `details` field, so the names arrive at\n * `body.details.details.<key>`. Both depths are read: the extra wrapper is\n * the serialiser's doing rather than part of the contract, and a reader that\n * insisted on it would go silent the day it goes away.\n */\nfunction listedInDetails(body: unknown, key: \"fields\" | \"missing\"): string[] {\n const seen = new Set<string>();\n let node: unknown = body;\n for (let depth = 0; depth < 4 && isObject(node); depth += 1) {\n const listed = (node as Record<string, unknown>)[key];\n if (Array.isArray(listed)) {\n for (const name of listed) {\n if (typeof name === \"string\" && name !== \"\") seen.add(name);\n }\n }\n node = (node as { details?: unknown }).details;\n }\n return [...seen];\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isPlatformErrorEnvelope(body: unknown): boolean {\n return (\n typeof body === \"object\" &&\n body !== null &&\n typeof (body as { code?: unknown }).code === \"string\"\n );\n}\n\nfunction isErrnoException(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && typeof (error as NodeJS.ErrnoException).code === \"string\";\n}\n\nfunction isZodLikeError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"issues\" in error &&\n Array.isArray((error as { issues: unknown }).issues)\n );\n}\n\n/** Whether a caught error is the given `errno` code. */\nexport function isErrno(error: unknown, code: string): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && error.code === code;\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === \"string\") {\n return error;\n }\n return String(error);\n}\n\nfunction pickErrorShape(error: Error): Record<string, unknown> {\n return {\n name: error.name,\n message: error.message,\n code: (error as NodeJS.ErrnoException).code,\n };\n}\n","import { ZitadelError } from \"./errors\";\n\n/**\n * Ctrl-C for the running command.\n *\n * Node exits on SIGINT only while nothing listens for it, and a spinner does\n * listen — clack's stops its animation and returns — so a request stalled\n * behind one used to outlive the keypress. Instead the command listens for\n * itself: the first Ctrl-C aborts {@link interruptSignal}, which every platform\n * request is bound to, so a waiting request rejects with `E_CANCELLED` and the\n * command unwinds through its normal error path.\n *\n * Work that is not a request does not see the signal, so the first Ctrl-C also\n * arms a short grace: a command still running when it lapses exits 130. A\n * second Ctrl-C exits at once. A command with its own handler (`logs --follow`\n * stops following) finishes inside the grace and exits as it always did.\n */\nconst GRACE_MS = 1_000;\n\nlet controller = new AbortController();\nlet grace: NodeJS.Timeout | undefined;\n\n/**\n * Aborted once Ctrl-C has been pressed in the current command, and stays\n * aborted, so a caller that swallows the first rejection cannot start another\n * request.\n */\nexport function interruptSignal(): AbortSignal {\n return controller.signal;\n}\n\nfunction onInterrupt(): void {\n if (controller.signal.aborted) {\n process.exit(130);\n }\n controller.abort(\n new ZitadelError(\"E_CANCELLED\", \"Cancelled\", {\n hint: \"The command was cancelled with Ctrl-C.\",\n }),\n );\n grace = setTimeout(() => process.exit(130), GRACE_MS);\n grace.unref();\n}\n\n/** Starts listening as a command begins, with a signal of its own. */\nexport function listenForInterrupt(): void {\n stopListeningForInterrupt();\n controller = new AbortController();\n process.on(\"SIGINT\", onInterrupt);\n}\n\n/**\n * Stops listening as the command ends. Only matters when commands share a\n * process, as specs do: the grace must not outlive the command that armed it.\n */\nexport function stopListeningForInterrupt(): void {\n process.off(\"SIGINT\", onInterrupt);\n clearTimeout(grace);\n grace = undefined;\n}\n","import {\n createZitadelClient as createRawClient,\n type ZitadelClient,\n type ZitadelClientOptions,\n} from \"@zitadel/api/client\";\nimport { ApiError } from \"@zitadel/api/runtime/fetch\";\n\nimport { interruptSignal } from \"./interrupt\";\n\n/**\n * How long one platform request may take, response body included, before it\n * fails as `E_NETWORK`. Without it a server that accepts the connection and\n * never answers holds the command for the runtime's own limit — minutes.\n */\nexport const REQUEST_TIMEOUT_MS = 30_000;\n\n/**\n * Characters that can drive a terminal rather than print on it: the C0\n * controls (ESC among them), DEL and the C1 controls (`\\p{Cc}`), the format\n * and bidi controls (`\\p{Cf}`), and the line and paragraph separators. Newline\n * and tab are left alone unless the caller asks otherwise, because they are\n * how a description or a multi-line value is written.\n */\nconst CONTROL = /[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}]/gu;\n\n/** Options for {@link escapeControlCharacters}. */\nexport type EscapeOptions = {\n /**\n * Keep `\\n` and `\\t` as they are. On by default; a renderer that must keep\n * a value on one line turns it off.\n */\n keepLayout?: boolean;\n};\n\n/**\n * Escape every character that could drive the reader's terminal to its\n * visible `\\xNN`/`\\uNNNN` spelling, or `\\u{NNNNN}` above the BMP so the\n * spelling cannot run into the character that follows it.\n *\n * Anything the server returns was written by someone — a user's name, a\n * branding value, a variable — and an ESC or OSC sequence in it would\n * otherwise clear the screen, set the window title, write the clipboard\n * through OSC 52, or disguise a link through OSC 8 when printed. Ordinary text\n * is unchanged, so readable values stay readable.\n */\nexport function escapeControlCharacters(text: string, opts: EscapeOptions = {}): string {\n const keepLayout = opts.keepLayout ?? true;\n return text.replace(CONTROL, (char) => {\n if (keepLayout && (char === \"\\n\" || char === \"\\t\")) {\n return char;\n }\n const code = char.codePointAt(0) ?? 0;\n if (code <= 0xff) {\n return `\\\\x${code.toString(16).padStart(2, \"0\")}`;\n }\n return code <= 0xffff\n ? `\\\\u${code.toString(16).padStart(4, \"0\")}`\n : `\\\\u{${code.toString(16)}}`;\n });\n}\n\n/**\n * Escape an object key. Unlike a value, a key must stay distinct from its\n * siblings: a key holding a raw ESC and one holding the literal text `\\x1b`\n * would otherwise both come out as `\\x1b`, and one of the two fields would be\n * lost. Doubling the backslash first makes the spelling unambiguous.\n */\nfunction escapeKey(key: string): string {\n return escapeControlCharacters(key.replaceAll(\"\\\\\", \"\\\\\\\\\"));\n}\n\n/** An array or object still to be copied, paired with the copy to fill. */\ntype Pending = { source: object; target: Record<string, unknown> | unknown[] };\n\n/**\n * Escape every string in a decoded JSON value, keys included, at any depth.\n * Numbers, booleans and `null` pass through untouched; the result has the\n * same shape as the input, with the same number of fields.\n *\n * The walk keeps its own work list rather than recursing. A user attribute\n * holds arbitrary JSON, and a few thousand levels of nesting — which\n * `JSON.parse` and `JSON.stringify` both accept — would otherwise exhaust the\n * call stack, letting one writer make `list` and `get` fail for every reader.\n */\nexport function sanitizeResponse<T>(value: T): T {\n const pending: Pending[] = [];\n const copy = (item: unknown): unknown => {\n if (typeof item === \"string\") {\n return escapeControlCharacters(item);\n }\n if (typeof item !== \"object\" || item === null) {\n return item;\n }\n const target = Array.isArray(item) ? [] : {};\n pending.push({ source: item, target });\n return target;\n };\n\n const root = copy(value);\n for (let next = pending.pop(); next; next = pending.pop()) {\n const { source, target } = next;\n if (Array.isArray(source)) {\n for (const item of source) {\n (target as unknown[]).push(copy(item));\n }\n continue;\n }\n for (const [key, item] of Object.entries(source)) {\n // Defined rather than assigned, so a `__proto__` key stays a field.\n Object.defineProperty(target, escapeKey(key), {\n value: copy(item),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n }\n return root as T;\n}\n\n/**\n * Rebuild a rejected call's {@link ApiError} with the server's text escaped.\n * The error envelope's `message` and `details` are printed as the failure, so\n * they are as attacker-influenceable as any response body. It stays an\n * `ApiError`, with the same status and URL, so `toZitadelError` classifies it\n * as before. Exported for `zitadel api`, which sends its requests itself.\n */\nexport function sanitizeRejection(error: unknown): never {\n if (!(error instanceof ApiError)) {\n throw error;\n }\n const sanitized = new ApiError(\n error.status,\n error.url,\n sanitizeResponse(error.body),\n escapeControlCharacters(error.message),\n );\n sanitized.stack = error.stack === undefined ? undefined : escapeControlCharacters(error.stack);\n throw sanitized;\n}\n\n/** Options for {@link createZitadelClient}. */\nexport type SanitizeOptions = {\n /**\n * Return response bodies exactly as the server sent them. Only for a\n * caller that stores or compares what it reads rather than printing it:\n * `plan` and `apply` compare the server's stored bodies against the\n * project's files, so an escaped `\\r` or zero-width joiner would read as a\n * change that is not there. Such a caller escapes at the point it prints.\n * Errors are escaped either way.\n */\n verbatim?: boolean;\n};\n\n/**\n * Build the typed Zitadel client the CLI talks to the server through.\n *\n * It is `@zitadel/api`'s client with every resolved response, and every\n * server-supplied error, passed through {@link sanitizeResponse} — the approach\n * the GitHub CLI takes with go-gh's `asciisanitizer`, widened to the format\n * and bidi controls that can disguise text. Doing it once here, rather than\n * in each renderer, covers every command, table, detail view and `--json`\n * envelope, including ones not yet written; only a caller that asks for\n * {@link SanitizeOptions.verbatim} bodies escapes for itself. The shared\n * package is left raw: the console renders into a DOM, which does not\n * interpret escape codes.\n *\n * Every request is also bounded by {@link REQUEST_TIMEOUT_MS} and cancelled by\n * Ctrl-C (see `./interrupt`), unless the caller sets its own `signal` or\n * `timeoutMs`.\n */\nexport function createZitadelClient(\n opts: ZitadelClientOptions,\n sanitize: SanitizeOptions = {},\n): ZitadelClient {\n const onResolve = sanitize.verbatim ? <T>(value: T): T => value : sanitizeResponse;\n const client = createRawClient({\n signal: interruptSignal(),\n timeoutMs: REQUEST_TIMEOUT_MS,\n ...opts,\n });\n return new Proxy(client, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver);\n if (typeof value !== \"function\") {\n return value;\n }\n return (...args: unknown[]) => {\n const result = (value as (...a: unknown[]) => unknown)(...args);\n return result instanceof Promise ? result.then(onResolve, sanitizeRejection) : result;\n };\n },\n });\n}\n\nexport type { ZitadelClient, ZitadelClientOptions };\n","import { stringify } from \"safe-stable-stringify\";\n\n/**\n * Serialise a value to pretty-printed JSON with object keys sorted at every\n * depth. Determinism is the point: managed files written by the CLI must be\n * byte-stable across runs so diffs stay clean and content hashes don't churn\n * when only key ordering would otherwise differ. Delegates the deterministic\n * sort to `safe-stable-stringify`, matching `JSON.stringify(value, null, 2)`\n * formatting. The `?? \"null\"` only applies to `undefined`/function inputs,\n * which the CLI never serialises.\n */\nexport function stableStringify(value: unknown): string {\n return stringify(value, null, 2) ?? \"null\";\n}\n\n/**\n * Replace (or insert) one top-level key's value in a JSON document by\n * splicing text, leaving every other byte of the source untouched. The\n * counterpart of {@link stableStringify} for files the CLI does *not* own\n * (the user's `package.json`): blank lines, inline nested objects, key\n * order, indentation style, line endings, and the trailing newline all\n * survive, because nothing outside the spliced value is reserialized. The\n * replaced value itself is rendered at the document's detected indent (a\n * compact document stays compact).\n *\n * Defensive by construction: the result is re-parsed and compared against\n * the expected mutation, so a splice that would corrupt the document throws\n * instead of writing it.\n */\nexport function setTopLevelJsonKey(\n source: string,\n path: string,\n key: string,\n value: unknown,\n): string {\n const parsed = parseJsonObject(source, path);\n const eol = source.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n const indent = detectIndent(source);\n const rendered = renderValueAtDepthOne(value, indent, eol);\n const layout = scanTopLevel(source);\n const member = layout.members.find((candidate) => candidate.key === key);\n\n let next: string;\n if (member) {\n next = `${source.slice(0, member.valueStart)}${rendered}${source.slice(member.valueEnd)}`;\n } else if (layout.members.length === 0) {\n const inner =\n indent === 0\n ? `${JSON.stringify(key)}:${rendered}`\n : `${eol}${indentString(indent)}${JSON.stringify(key)}: ${rendered}${eol}`;\n next = `${source.slice(0, layout.open + 1)}${inner}${source.slice(layout.close)}`;\n } else {\n const last = layout.members.at(-1);\n if (!last) throw new Error(`refusing to write ${path}: the JSON layout scan found no members`);\n const inner =\n indent === 0\n ? `,${JSON.stringify(key)}:${rendered}`\n : `,${eol}${indentString(indent)}${JSON.stringify(key)}: ${rendered}`;\n next = `${source.slice(0, last.valueEnd)}${inner}${source.slice(last.valueEnd)}`;\n }\n\n const verification = parseJsonObject(next, path);\n const expected = { ...parsed, [key]: value };\n if (JSON.stringify(verification) !== JSON.stringify(expected)) {\n throw new Error(`refusing to write ${path}: the targeted JSON edit did not verify`);\n }\n return next;\n}\n\n/**\n * Infers the indentation unit of a JSON document: the whitespace prefix of\n * its first indented line, a compact document stays compact (`0`), and\n * anything unrecognizable falls back to two spaces.\n */\nfunction detectIndent(source: string): string | number {\n const match = source.match(/\\n([ \\t]+)\\S/);\n if (match?.[1]) {\n return match[1];\n }\n return source.trimEnd().includes(\"\\n\") ? 2 : 0;\n}\n\nfunction indentString(indent: string | number): string {\n return typeof indent === \"number\" ? \" \".repeat(indent) : indent;\n}\n\n/** Serializes a value as it should appear as a top-level member's value. */\nfunction renderValueAtDepthOne(value: unknown, indent: string | number, eol: string): string {\n if (indent === 0) {\n return JSON.stringify(value);\n }\n const unit = indentString(indent);\n // Re-indent every continuation line one level deeper and re-join with the\n // document's own line endings.\n return JSON.stringify(value, null, unit).split(\"\\n\").join(`${eol}${unit}`);\n}\n\ntype TopLevelMember = { key: string; valueStart: number; valueEnd: number };\ntype TopLevelLayout = { open: number; close: number; members: TopLevelMember[] };\n\n/**\n * Single-pass, string-aware scan of a JSON object document, collecting the\n * exact text span of every top-level member's value plus the root braces.\n * Only structural understanding needed for the splice — the document has\n * already been validated by `JSON.parse`, so this can assume well-formed\n * input and does not re-validate.\n */\nfunction scanTopLevel(source: string): TopLevelLayout {\n const members: TopLevelMember[] = [];\n let open = -1;\n let close = -1;\n let depth = 0;\n let index = 0;\n\n while (index < source.length) {\n const char = source.charAt(index);\n if (char === '\"') {\n const start = index;\n index = skipString(source, index);\n if (depth === 1 && isKeyPosition(source, start)) {\n const key = JSON.parse(source.slice(start, index)) as string;\n // Skip to the value after the colon.\n while (source[index] !== \":\") index += 1;\n index += 1;\n while (index < source.length && isWhitespace(source.charAt(index))) index += 1;\n const valueStart = index;\n index = skipValue(source, index);\n members.push({ key, valueStart, valueEnd: index });\n }\n continue;\n }\n if (char === \"{\" || char === \"[\") {\n depth += 1;\n if (depth === 1 && open === -1) {\n open = index;\n }\n } else if (char === \"}\" || char === \"]\") {\n depth -= 1;\n if (depth === 0) {\n close = index;\n }\n }\n index += 1;\n }\n return { open, close, members };\n}\n\n/** True when the string starting at `start` is a top-level key, not a value. */\nfunction isKeyPosition(source: string, start: number): boolean {\n for (let index = start - 1; index >= 0; index -= 1) {\n const char = source.charAt(index);\n if (isWhitespace(char)) continue;\n return char === \"{\" || char === \",\";\n }\n return false;\n}\n\n/** Returns the index just past the value starting at `index`. */\nfunction skipValue(source: string, index: number): number {\n const char = source.charAt(index);\n if (char === '\"') {\n return skipString(source, index);\n }\n if (char === \"{\" || char === \"[\") {\n let depth = 0;\n let cursor = index;\n while (cursor < source.length) {\n const current = source.charAt(cursor);\n if (current === '\"') {\n cursor = skipString(source, cursor);\n continue;\n }\n if (current === \"{\" || current === \"[\") depth += 1;\n if (current === \"}\" || current === \"]\") {\n depth -= 1;\n if (depth === 0) return cursor + 1;\n }\n cursor += 1;\n }\n return cursor;\n }\n // Primitive: number, boolean, null — runs until a structural delimiter.\n let cursor = index;\n while (\n cursor < source.length &&\n !\",}]\".includes(source.charAt(cursor)) &&\n !isWhitespace(source.charAt(cursor))\n ) {\n cursor += 1;\n }\n return cursor;\n}\n\n/** Returns the index just past the closing quote of the string at `index`. */\nfunction skipString(source: string, index: number): number {\n let cursor = index + 1;\n while (cursor < source.length) {\n const char = source.charAt(cursor);\n if (char === \"\\\\\") {\n cursor += 2;\n continue;\n }\n if (char === '\"') {\n return cursor + 1;\n }\n cursor += 1;\n }\n return cursor;\n}\n\nfunction isWhitespace(char: string): boolean {\n return char === \" \" || char === \"\\t\" || char === \"\\n\" || char === \"\\r\";\n}\n\n/**\n * Parse `contents` as JSON and assert the root is a plain object (not an\n * array or scalar). The CLI's config and secret files are always objects, so\n * this guards callers from the `JSON.parse` return type of `any` and produces\n * a `path`-qualified error message pointing at the offending file.\n */\nexport function parseJsonObject(contents: string, path: string): Record<string, unknown> {\n const value = JSON.parse(contents) as unknown;\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`${path} must contain a JSON object`);\n }\n return value as Record<string, unknown>;\n}\n\n/**\n * Narrows an unknown value to a plain (non-array, non-null) object. Shared by\n * the commands and the file-writer that walk parsed JSON, so the predicate\n * isn't reimplemented per call site.\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { ZitadelError } from \"../../errors\";\nimport { isObject } from \"../../json\";\nimport type { Page } from \"./types\";\n\n/** How a command spells draining every page, and fetching one at a time, for its errors. */\nexport type PagingFlags = Readonly<{ all: string; onePage: string }>;\n\n/** The list commands' own: `--all`, and `--limit` with `--page-token`. */\nconst LIST_FLAGS: PagingFlags = { all: \"--all\", onePage: \"--limit and --page-token\" };\n\n/**\n * Walk a cursor-paginated endpoint. `request` performs one page; the\n * response must carry the items under `items` and, while more remain, a\n * the cursor property `nextPageToken` names. With `all` the pages are drained\n * in order and `next`\n * is `null`; otherwise one page is fetched and `next` is its token. `flags`\n * names the caller's own flags in the errors.\n */\nexport const collectPages = async (\n request: (token?: string) => Promise<unknown>,\n {\n items,\n all,\n token,\n nextPageToken,\n flags = LIST_FLAGS,\n }: Readonly<{\n items?: string;\n all: boolean;\n token?: string;\n nextPageToken: string;\n flags?: PagingFlags;\n }>,\n): Promise<Page> => {\n // Accumulated in one array rather than by concatenating each page onto the\n // last: these resources are unbounded, and a wide `--all` would otherwise\n // copy every record once per remaining page.\n const collected: unknown[] = [];\n // A server that returns a cursor it already issued — a bug, a cache — would\n // otherwise have the drain fetch the same page forever behind a spinner that\n // looks like progress.\n const seen = new Set<string>();\n let cursor = token;\n for (;;) {\n const response = await request(cursor);\n // A wrapped page names the array; an endpoint that answers with the\n // collection itself has nothing to name, and the body is the array.\n const page = items === undefined ? response : isObject(response) ? response[items] : undefined;\n if (!Array.isArray(page)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n items === undefined\n ? \"Unexpected list response: expected an array\"\n : `Unexpected list response: missing \"${items}\" array`,\n { details: { response } },\n );\n }\n collected.push(...(page as readonly unknown[]));\n const cursor_ = isObject(response) ? response[nextPageToken] : undefined;\n const next = typeof cursor_ === \"string\" ? cursor_ || null : null;\n if (!all) {\n return { items: collected, next };\n }\n if (!next) {\n return { items: collected, next: null };\n }\n if (seen.has(next)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `The server repeated a page cursor, so ${flags.all} would never finish`,\n {\n hint: `Fetch one page at a time with ${flags.onePage}, and report the repeated cursor.`,\n // Named for what it is rather than for the platform's spelling of\n // it, so the error shape does not vary with the wire vocabulary.\n details: { cursor: next, pages_fetched: seen.size + 1 },\n },\n );\n }\n seen.add(next);\n cursor = next;\n }\n};\n","/**\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 \"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\";\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 = \"zitadel 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 type { GetVariable200, GetVariables200 } from \"@zitadel/api/generated/model\";\n\nimport type { Parsed } from \"@zitadel/config/idp\";\n\nimport { escapeControlCharacters } from \"./api-client\";\nimport { ZitadelError } from \"./errors\";\n\n/**\n * A variable as the platform reports it. A non-secret carries its value; a\n * secret carries none, because a read answers `{\"secret\": true}` and never\n * discloses what is stored (ADR 062 §7).\n */\nexport type VariableRow = {\n name: string;\n secret: boolean;\n value?: string | number | boolean;\n};\n\n/** One value on the wire: a bare scalar, or `{\"secret\": true}` for a secret. */\nexport type VariableValue = NonNullable<GetVariable200[\"primary\"]>;\n\n/** The primary values of a read, keyed by name. */\nexport function primaryValues(body: GetVariables200): Record<string, VariableValue> {\n return Object.fromEntries(\n Object.entries(body).flatMap(([name, byKind]) =>\n byKind.primary === undefined ? [] : [[name, byKind.primary]],\n ),\n );\n}\n\n/**\n * Project one wire value into a row. Both endpoints answer in the same two\n * forms — a bare scalar for a non-secret, `{\"secret\": true}` for a secret — so\n * the collection and the single-name read share this.\n */\nexport function toVariableRow(name: string, value: VariableValue): VariableRow {\n return typeof value === \"object\" && value !== null\n ? { name, secret: true }\n : { name, secret: false, value };\n}\n\n/**\n * Project the values into rows, sorted by name so output is stable between\n * runs.\n */\nexport function toVariableRows(values: Record<string, VariableValue>): VariableRow[] {\n return Object.entries(values)\n .map(([name, value]) => toVariableRow(name, value))\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/** Stands in for a secret's value, which the platform never discloses. */\nconst SECRET_MARKER = \"(secret)\";\n\n/**\n * Render a stored scalar for a terminal.\n *\n * A value is attacker-influenceable — anyone holding `variable.write` chooses\n * it — so it is never interpolated raw. The client already escapes what could\n * drive the terminal; this also escapes a newline and a tab, which would\n * break the table out of its own row or split a tab-separated line.\n */\nexport function renderScalar(value: string | number | boolean | undefined): string {\n if (typeof value !== \"string\") {\n return String(value);\n }\n return escapeControlCharacters(value, { keepLayout: false });\n}\n\n/**\n * The rows as the cells the resource commands' renderers print, one per\n * column. Those renderers print a string verbatim, so every value is escaped\n * here first: a stored value is chosen by whoever holds `variable.write`, and a\n * newline or an ESC byte must not reach the reader's terminal. A secret prints\n * a marker rather than a value — there is none to print, and an empty cell would\n * read as an empty value rather than a withheld one.\n */\nexport function variableCells(\n rows: ReadonlyArray<VariableRow>,\n): Array<{ name: string; value: string }> {\n return rows.map((row) => ({\n name: row.name,\n value: row.secret ? SECRET_MARKER : renderScalar(row.value),\n }));\n}\n\n/**\n * Names the platform accepts, from `variable-name.yaml`: word characters only,\n * which is exactly what the `${{ NAME }}` reference syntax can address\n * (ADR 062 §2). Checked before the patch so one bad line in a `.env` file is\n * named locally rather than failing the whole transaction at the edge.\n */\nconst VARIABLE_NAME = /^\\w+$/;\n\n/** Longest name the same schema accepts. */\nconst VARIABLE_NAME_MAX = 255;\n\n/** Reject a name the platform would refuse, naming it. */\nexport function assertVariableName(name: string): void {\n if (!VARIABLE_NAME.test(name)) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid variable name ${JSON.stringify(name)}.`, {\n hint: \"A variable name contains only letters, digits and underscores.\",\n });\n }\n if (name.length > VARIABLE_NAME_MAX) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Variable name is ${name.length} characters; the limit is ${VARIABLE_NAME_MAX}.`,\n { hint: \"Shorten the name.\" },\n );\n }\n}\n\n/**\n * The scalar types a variable can hold — the API's JSON scalars (ADR 062 §1).\n * The server resolves `${{ NAME }}` only in an OIDC connection's `client_id`\n * and `client_secret` (`flow_sso_redirect_issuer.go`, `flow_sso_callback.go`),\n * and both must hold a string, so no reference resolves to a number or boolean\n * yet.\n */\nexport const VARIABLE_TYPES = [\"string\", \"number\", \"boolean\"] as const;\n\nexport type VariableType = (typeof VARIABLE_TYPES)[number];\n\n/**\n * A JSON number, spelled strictly. `Number()` alone would accept `0x10`, a\n * blank string, or surrounding whitespace, none of which is a number anyone\n * means when they type one.\n */\nconst JSON_NUMBER = /^-?(0|[1-9]\\d*)(\\.\\d+)?([eE][+-]?\\d+)?$/;\n\n/**\n * Turn what was typed or piped into the scalar to store, as the type asks, or\n * say what is wrong with it. The problem carries its hint, so a caller that\n * only has the problem to show loses nothing.\n *\n * The type is stated, never guessed: an integer past 2^53 has no exact JSON\n * number, so an ID or a numeric credential would be stored with different\n * digits than were entered. It is refused rather than silently rounded.\n */\nexport function parseVariableValue(\n raw: string,\n type: VariableType,\n): Parsed<string | number | boolean> {\n const refuse = (problem: string, hint: string): Parsed<never> => ({\n ok: false,\n problem: `${problem} ${hint}`,\n });\n switch (type) {\n case \"string\":\n return { ok: true, value: raw };\n case \"boolean\":\n if (raw === \"true\" || raw === \"false\") {\n return { ok: true, value: raw === \"true\" };\n }\n return refuse(\n `Expected true or false, got ${JSON.stringify(raw)}.`,\n \"A boolean variable is exactly `true` or `false`.\",\n );\n case \"number\": {\n const value = Number(raw);\n if (!JSON_NUMBER.test(raw) || !Number.isFinite(value)) {\n return refuse(\n `Expected a number, got ${JSON.stringify(raw)}.`,\n \"Write it as a JSON number, such as 5, -1.5 or 1e3.\",\n );\n }\n if (Number.isInteger(value) && !Number.isSafeInteger(value)) {\n return refuse(\n `${raw} is too large to store exactly as a number.`,\n \"Store it as a string, which keeps every digit.\",\n );\n }\n return { ok: true, value };\n }\n }\n}\n\n/**\n * Read a value from stdin, for the non-interactive path\n * (`variables set NAME --project-level --secret < secret.txt`).\n *\n * A single trailing newline is stripped — a here-doc or `echo` adds one and it\n * is not part of the credential — but nothing else is trimmed, because\n * whitespace inside a value is the caller's to decide.\n */\nexport async function readStdin(stream: NodeJS.ReadableStream): Promise<string> {\n // A local accumulator: `Array.fromAsync` would read better but is not on\n // every Node the package supports.\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n }\n return Buffer.concat(chunks)\n .toString(\"utf8\")\n .replace(/\\r?\\n$/, \"\");\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\";\n\n/** One option of a `select` or `multiselect`. */\ntype Choice<V> = { value: V; label: string; hint?: string };\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?: string;\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_VALIDATION` \"Cancelled by user\"\n * instead of returning a sentinel, so a command never carries on with a\n * missing answer.\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: \"Client ID\",\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_VALIDATION\", \"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 { 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","const CLI_PACKAGE_NAME = \"@zitadel/cli\";\n\nexport function npmDistTagForCliVersion(cliVersion: string): string {\n const normalized = cliVersion.trim().replace(/^v/, \"\");\n const match = normalized.match(/^\\d+\\.\\d+\\.\\d+-([0-9A-Za-z][0-9A-Za-z-]*)/);\n return match?.[1] ?? \"latest\";\n}\n\n/**\n * Whether a version is one the release train publishes: a release (`0.1.0`) or\n * an alpha prerelease (`1.0.0-alpha.25`). Any other prerelease (`1.0.0-beta.2`,\n * `0.0.0-test`) has only its dist-tag to point at.\n */\nexport function isTrainVersion(version: string): boolean {\n return /^\\d+\\.\\d+\\.\\d+(-alpha\\.\\d+)?$/.test(version.trim().replace(/^v/, \"\"));\n}\n\nexport function npmSelectorForCliVersion(cliVersion: string): string {\n const normalized = cliVersion.trim().replace(/^v/, \"\");\n if (isTrainVersion(normalized)) {\n return normalized;\n }\n return npmDistTagForCliVersion(normalized);\n}\n\n/**\n * The version a scaffold writes for the `@zitadel/*` packages it adds: the\n * CLI's own exact version on the train, else its dist-tag (`beta` for\n * `1.0.0-beta.2`). The packages publish as one lockstep train, so the exact pin\n * keeps the app on the SDK that matches the files this CLI wrote, and lets\n * doctor's `dependency-version` check compare it against the CLI.\n */\nexport function sdkVersionForCli(cliVersion: string): string {\n return npmSelectorForCliVersion(cliVersion);\n}\n\n/**\n * Whether a value can sit in a suggested command unquoted on every shell the\n * CLI runs under (POSIX shells, PowerShell and cmd.exe). Quoting differs\n * between them, so a value that needs quoting is not put in a suggested\n * command at all; callers hand it over as an argument list instead.\n */\nexport function isPortableShellWord(value: string): boolean {\n // `/` is included so a POSIX-style --cwd path can be suggested as written.\n return /^[A-Za-z0-9_./-]+$/.test(value);\n}\n\n/**\n * Suggested commands as strings, built from argument lists. Every argument\n * must be a portable shell word, or none of the commands is returned: a\n * caller then hands over the argument lists alone, which no shell interprets.\n */\nexport function portableCommands(argLists: readonly string[][], cliVersion: string): string[] {\n if (!argLists.every((args) => args.every(isPortableShellWord))) {\n return [];\n }\n return argLists.map((args) => publicCliCommand(args.join(\" \"), cliVersion));\n}\n\n/**\n * An option and its value as arguments for a suggested command. A value that\n * starts with `-` would be read as the next flag, so it is joined with `=`\n * instead. That token is not a portable shell word, so it also keeps the\n * string form out of {@link portableCommands}.\n *\n * @param option - The option, with its dashes, e.g. `--schema`.\n * @param value - The value it takes, as the user or a file name gave it.\n */\nexport function optionArgs(option: string, value: string): string[] {\n return value.startsWith(\"-\") ? [`${option}=${value}`] : [option, value];\n}\n\nexport function publicCliCommand(args: string, cliVersion: string): string {\n const prefix = `npx ${CLI_PACKAGE_NAME}@${npmSelectorForCliVersion(cliVersion)}`;\n return args.length > 0 ? `${prefix} ${args}` : prefix;\n}\n\nexport function normalizePublicCliCommand(command: string, cliVersion: string): string {\n if (command === \"zitadel\") {\n return publicCliCommand(\"\", cliVersion);\n }\n if (command.startsWith(\"zitadel \")) {\n return publicCliCommand(command.slice(\"zitadel \".length), cliVersion);\n }\n return command;\n}\n\nexport function normalizePublicCliCommands(\n commands: ReadonlyArray<string> | undefined,\n cliVersion: string,\n): string[] | undefined {\n return commands?.map((command) => normalizePublicCliCommand(command, cliVersion));\n}\n\n/**\n * Rewrites `zitadel …` command mentions in scaffolded prose (the\n * `.zitadel/**` READMEs) to the public `npx @zitadel/cli@<version> …` form.\n *\n * The checked-in README sources stay written with the bare `zitadel`\n * command — that is the canonical, readable spelling — but the CLI is not a\n * dependency of the scaffolded app, so the bare command does not exist on\n * the user's PATH (and `npx zitadel` would fetch an unrelated npm package).\n * Covers inline code spans (`` `zitadel plan` ``) and fenced-block lines\n * that start with `zitadel `; prose file names like `zitadel.json` and\n * `zitadel.db` don't match because the word must end the span or be\n * followed by a space.\n */\nexport function normalizePublicCliProse(content: string, cliVersion: string): string {\n const prefix = publicCliCommand(\"\", cliVersion);\n return rewriteCliCodeSpans(content, cliVersion).replace(\n /^(\\s*)zitadel (.*)$/gm,\n (_match, indent: string, rest: string) => `${indent}${prefix} ${rest}`,\n );\n}\n\n/** The inline-code-span half of {@link normalizePublicCliProse}. */\nfunction rewriteCliCodeSpans(content: string, cliVersion: string): string {\n const prefix = publicCliCommand(\"\", cliVersion);\n return content.replace(\n /`zitadel( [^`\\n]*)?`/g,\n (_match, args: string | undefined) => `\\`${prefix}${args ?? \"\"}\\``,\n );\n}\n\n/**\n * Rewrites `zitadel …` command mentions inside every string of a scaffolded\n * JSON document — today the `.zitadel/meta/*.json` dialect files — returning\n * a rewritten copy. The input is never mutated: the meta-schema bodies are\n * imported JSON modules shared across calls.\n *\n * Those files are generated copies of the meta-schemas the server embeds\n * (`api/openapi/endpoints/schemas/*.json`), where the bare `zitadel` spelling\n * is the correct one — the server documents the product command, not one\n * project's install. Their `description` strings surface as editor tooltips\n * on the scaffolded `.zitadel/**` files, where the bare command does not\n * exist on the user's PATH, so the copy is normalized on the way out instead\n * of the shared source being edited (same fix PR #872 made for the READMEs).\n *\n * Unlike {@link normalizePublicCliProse} this rewrites inline code spans\n * only: a JSON `description` is prose, so a value that merely begins with\n * the word `zitadel` is a sentence, not a command line.\n */\nexport function normalizePublicCliJson<T>(value: T, cliVersion: string): T {\n if (typeof value === \"string\") {\n return rewriteCliCodeSpans(value, cliVersion) as T;\n }\n if (Array.isArray(value)) {\n return value.map((item) => normalizePublicCliJson(item, cliVersion)) as T;\n }\n if (typeof value === \"object\" && value !== null) {\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => [key, normalizePublicCliJson(item, cliVersion)]),\n ) as T;\n }\n return value;\n}\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\";\n\nexport type DockerRuntimeGuidance = {\n hint: string;\n nextActions: string[];\n nextCommands: string[];\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: [\"docker version\", publicCliCommand(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 { 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\nexport async function checkLocalServerHealth(\n serverUrl: string,\n timeoutMs = 1500,\n): Promise<boolean> {\n try {\n const healthUrl = new URL(\"/healthz\", serverUrl);\n const response = await fetch(healthUrl, { 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: [\"zitadel 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: [\"zitadel reset --force\", \"zitadel 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 ? { nextCommands: [reset, start] } : {}),\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 wait(ms: number): Promise<void>;\n}\n\nexport const realClock: Clock = {\n now: () => Date.now(),\n wait: (ms) => sleep(ms),\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 {\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 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. `docker logs` replays the\n * container's two streams separately, and the server logs to stderr, so both\n * are returned; reading stdout alone gave an empty log.\n */\n static async readLogs(containerName: string, tail: number): 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 * Streams the container's log to the terminal until interrupted.\n */\n static async followLogs(containerName: string, tail: number): Promise<void> {\n await streamDocker([\"logs\", \"--tail\", String(tail), \"--follow\", containerName]);\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` with its output going straight to the terminal.\n */\nasync function streamDocker(args: string[]): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"docker\", args, {\n stdio: \"inherit\",\n env: process.env,\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`docker ${args.join(\" \")} exited with status ${code ?? 1}`));\n }\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: [\"zitadel doctor\"],\n details,\n });\n}\n","import { ZitadelError, toZitadelError } from \"../../errors\";\nimport { publicCliCommand } from \"../../public-cli\";\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 publicCliCommand(\"stop --all\", cliVersion),\n publicCliCommand(\"logs\", cliVersion),\n publicCliCommand(\"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 publicCliCommand(\"logs\", cliVersion),\n publicCliCommand(\"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: [publicCliCommand(\"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 publicCliCommand(\"stop --all\", cliVersion),\n publicCliCommand(`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 publicCliCommand(\"logs\", cliVersion),\n publicCliCommand(\"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(values: string[]): string[] {\n return [...new Set(values)];\n}\n","import { execFile, spawn } from \"node:child_process\";\nimport { createReadStream } from \"node:fs\";\nimport { mkdir, open, readFile, stat } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { basename, dirname } from \"node:path\";\n\nimport { resolveServerBinary, serverBinaryPath } from \"@zitadel/server/binary\";\n\nimport { ZitadelError, isErrno } from \"../../errors\";\nimport { EMPTY_ENV, type ResolvedEnv, envSummary } from \"../env-vars\";\nimport type { BinaryRuntimeMetadata } from \"../runtime\";\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;\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: [\"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 * The last `tail` lines of a server's log file, or an empty string if it has\n * none yet. Read from the file, not the process, so a stopped server's log is\n * still there.\n */\n static async readLogs(logPath: string, tail: number): Promise<string> {\n let content = \"\";\n try {\n content = await readFile(logPath, \"utf8\");\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return \"\";\n }\n throw error;\n }\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 * Writes the last `tail` lines to the terminal and then each line as it is\n * appended, until interrupted. The file is polled by size: it is appended to by\n * another process, and there is no event to wait on that works on every platform.\n */\n static async followLogs(logPath: string, tail: number): Promise<void> {\n process.stdout.write(await BinaryLauncher.readLogs(logPath, tail));\n let offset = await fileSize(logPath);\n await new Promise<void>((resolveFollow, reject) => {\n const interval = setInterval(() => {\n void (async () => {\n try {\n const size = await fileSize(logPath);\n if (size > offset) {\n const stream = createReadStream(logPath, { start: offset, end: size - 1 });\n stream.pipe(process.stdout, { end: false });\n offset = size;\n }\n } catch (error) {\n reject(error);\n }\n })();\n }, 1000);\n const stop = () => {\n clearInterval(interval);\n resolveFollow();\n };\n process.once(\"SIGINT\", stop);\n process.once(\"SIGTERM\", stop);\n });\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: [\"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/**\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 { join } from \"node:path\";\n\nimport consola from \"consola\";\n\nimport { ZitadelError } from \"../errors\";\nimport { publicCliCommand } from \"../public-cli\";\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\";\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 /** 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, or, with `follow`, the log streamed until\n * interrupted (then `logs` is empty: it was written to the terminal as it\n * came). The log is read by the record, so it works for a server that has\n * stopped, which is when the log is most wanted.\n */\n async logs(options: {\n tail: number;\n follow?: boolean;\n }): Promise<{ runtime: RuntimeMetadata; logs: string }> {\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: [publicCliCommand(\"start\", this.cliVersion)],\n });\n }\n if (options.follow) {\n if (runtime.backend === \"binary\") {\n await BinaryLauncher.followLogs(runtime.log_path, options.tail);\n } else {\n await DockerLauncher.followLogs(runtime.container_name, options.tail);\n }\n return { runtime, logs: \"\" };\n }\n const logs =\n runtime.backend === \"binary\"\n ? await BinaryLauncher.readLogs(runtime.log_path, options.tail)\n : await DockerLauncher.readLogs(runtime.container_name, options.tail);\n return { runtime, logs };\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 { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ZitadelError } from \"./errors\";\nimport { LocalServer } from \"./local-server/server\";\nimport { parseJsonObject } from \"./json\";\nimport type { FlagVariable } from \"./oclif/types\";\n\n/**\n * Server URL used when nothing else resolves. Also surfaced in hints and\n * the interactive setup prompt as the suggested value, so it is exported\n * rather than kept private.\n */\nexport const DEFAULT_SERVER = \"https://preview.zitadel.com\";\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 and so the precedence order stays auditable.\n */\nexport type ResolvedServer = {\n value: string;\n origin: \"flag\" | \"env\" | \"config-top\" | \"default\" | \"local\";\n};\n\n/**\n * Inputs to {@link resolveServer}. Passed explicitly (cwd, env) rather\n * than read from globals so resolution is pure and testable. `serverFlag`\n * comes from the parsed CLI invocation.\n */\nexport type ResolveServerInput = {\n cwd: string;\n env: NodeJS.ProcessEnv;\n serverFlag?: string;\n};\n\n/**\n * Resolves which server the CLI should target, applying a fixed\n * precedence: explicit `--server` flag, then `ZITADEL_API_BASE`, then the\n * `server` in `zitadel.json`, falling back to {@link DEFAULT_SERVER}. Every\n * candidate 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 validate(input.cwd, { value: input.serverFlag, origin: \"flag\" });\n }\n const envValue = input.env[SERVER_VARIABLE.name];\n if (envValue) {\n return validate(input.cwd, { value: envValue, origin: \"env\" });\n }\n\n const config = await readConfig(input.cwd);\n if (typeof config?.server === \"string\") {\n return validate(input.cwd, { value: config.server, origin: \"config-top\" });\n }\n\n return { value: DEFAULT_SERVER, origin: \"default\" };\n}\n\nasync function validate(cwd: string, resolved: ResolvedServer): Promise<ResolvedServer> {\n if (resolved.value === \"local\") {\n return { value: await LocalServer.resolveUrl(cwd), origin: \"local\" };\n }\n\n try {\n const url = new URL(resolved.value);\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n throw new ZitadelError(\"E_VALIDATION\", `Server URL must use http(s): ${resolved.value}`, {\n hint: `Set \"server\" in zitadel.json to a URL like ${DEFAULT_SERVER}.`,\n });\n }\n return { value: url.origin, origin: resolved.origin };\n } catch (error) {\n if (error instanceof ZitadelError) {\n throw error;\n }\n throw new ZitadelError(\"E_VALIDATION\", `Invalid server \"${resolved.value}\"`, {\n hint: `Use a URL like ${DEFAULT_SERVER}.`,\n details: { origin: resolved.origin },\n });\n }\n}\n\nasync function readConfig(cwd: string): Promise<Record<string, unknown> | undefined> {\n try {\n const contents = await readFile(join(cwd, \"zitadel.json\"), \"utf8\");\n return parseJsonObject(contents, \"zitadel.json\");\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 undefined;\n }\n throw error;\n }\n}\n","const DISABLED_VALUES = new Set([\"\", \"0\", \"false\", \"off\", \"no\"]);\n\n/**\n * Whether an environment variable is set to an enabled value. A present-but-\n * falsey string (`CI=false`, `CI=0`) counts as disabled — unlike a bare\n * `Boolean(env.CI)` check, which is true for any non-empty string.\n */\nexport function envEnabled(value: string | undefined): boolean {\n return value !== undefined && !DISABLED_VALUES.has(value.trim().toLowerCase());\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 API host for a CLI invocation.\n *\n * The token is a *write-only* project token: it can ingest events but cannot\n * read data back, so — unlike the project service-key — it is safe to ship\n * 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 * Dev and prod are separate Mixpanel projects (the skill's Phase 2 rule: never\n * track dev traffic into the production project). The CLI ships as one generic\n * build with no channel stamp, so by default events go to production (see\n * {@link resolveChannel}); development/CI/test runs stay out of prod by opting\n * out entirely (`DO_NOT_TRACK` / `ZITADEL_TELEMETRY=0`) or by selecting the dev\n * project with `ZITADEL_TELEMETRY_ENV=development`. `ZITADEL_TELEMETRY_TOKEN`\n * overrides the token outright.\n */\n\n/**\n * Development project token. Safe to commit (write-only ingestion key). Used\n * when running from source or any non-production build.\n */\nconst DEV_TELEMETRY_TOKEN = \"0fb432b08a9797b87b0eebcbee11706e\";\n\n/**\n * Production project token. The default for any run that has not opted out or\n * selected the dev project, so the published CLI uses it with no per-user env.\n * Write-only ingestion key, like the dev token — safe to commit.\n */\nconst PROD_TELEMETRY_TOKEN = \"f56fd7315ccd614fba8eecb2a8966152\";\n\n/** Mixpanel API hosts by data-residency region. */\nconst HOSTS = {\n us: \"api.mixpanel.com\",\n eu: \"api-eu.mixpanel.com\",\n} as const;\n\nexport type TelemetryRegion = keyof typeof HOSTS;\n\n/**\n * Decide which project the events belong to.\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) routes real user traffic to prod with\n * no per-user env — EXCEPT that an unattended CI/automation run routes to the\n * dev project 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 the production project.\n *\n * Ambient `NODE_ENV` is deliberately NOT consulted: a run with\n * `NODE_ENV=development` must not silently switch projects.\n */\nfunction 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 the prod project.\n if (ciFlag.value(env)) {\n return \"development\";\n }\n return \"production\";\n}\n\n/**\n * Resolve the ingestion token, or `undefined` when none is configured for the\n * active channel. A `ZITADEL_TELEMETRY_TOKEN` override wins outright; otherwise\n * the channel's baked token is used. An empty string (e.g. the unset prod\n * token) resolves to `undefined`, which the caller treats as \"telemetry off\".\n */\nexport function resolveTelemetryToken(env: NodeJS.ProcessEnv): string | undefined {\n const override = env.ZITADEL_TELEMETRY_TOKEN?.trim();\n if (override) {\n return override;\n }\n const token = resolveChannel(env) === \"production\" ? PROD_TELEMETRY_TOKEN : DEV_TELEMETRY_TOKEN;\n return token.length > 0 ? token : undefined;\n}\n\n/**\n * Resolve the Mixpanel API host from `ZITADEL_TELEMETRY_REGION`. Defaults to the\n * EU host, because the Zitadel Mixpanel projects live in the EU data-residency\n * region. Set `ZITADEL_TELEMETRY_REGION=us` for a US-hosted project — events\n * sent to the wrong host are silently dropped, so verify the first event lands\n * in Live View.\n */\nexport function resolveTelemetryHost(env: NodeJS.ProcessEnv): string {\n const region = (env.ZITADEL_TELEMETRY_REGION ?? \"eu\").trim().toLowerCase();\n return region === \"us\" ? HOSTS.us : HOSTS.eu;\n}\n","import type { FlagVariable } from \"../oclif/types\";\nimport { resolveTelemetryToken } from \"./config\";\n\n/**\n * Outcome of resolving whether telemetry may run for this invocation. `reason`\n * is a stable token (handy in tests and `--debug` logs) explaining the\n * decision; it is never sent anywhere.\n */\nexport type Consent = {\n readonly enabled: boolean;\n readonly reason:\n | \"enabled\"\n | \"no-token\"\n | \"do-not-track\"\n | \"env-opt-out\"\n | \"flag-opt-out\"\n | \"test-runner\";\n /** The resolved ingestion token, present only when `enabled` — so the caller never re-resolves it. */\n readonly token?: string;\n};\n\n/** Inputs that can disable telemetry, kept explicit so the matrix is testable. */\nexport type ConsentInput = {\n readonly env: NodeJS.ProcessEnv;\n /** The resolved `--telemetry/--no-telemetry` flag value (default true). */\n readonly flag?: boolean;\n};\n\n/** The cross-tool opt-out. */\nexport const DO_NOT_TRACK: FlagVariable = {\n name: \"DO_NOT_TRACK\",\n flag: \"telemetry\",\n description:\n \"Any value but `0` or an empty one turns telemetry off (https://consoledonottrack.com).\",\n precedence: \"Turns telemetry off even with `--telemetry`.\",\n};\n\n/** The values of {@link ZITADEL_TELEMETRY}, trimmed and lowercased, that turn telemetry off. */\nconst DISABLED_VALUES = new Set([\"\", \"0\", \"false\", \"off\", \"no\"]);\n\n/** The CLI's own opt-out. */\nexport const ZITADEL_TELEMETRY: FlagVariable = {\n name: \"ZITADEL_TELEMETRY\",\n flag: \"telemetry\",\n description: `An empty value or one of ${[...DISABLED_VALUES]\n .filter((value) => value !== \"\")\n .map((value) => `\\`${value}\\``)\n .join(\", \")} turns telemetry off.`,\n precedence: \"Turns telemetry off even with `--telemetry`.\",\n};\n\n/**\n * Resolve telemetry consent under an opt-out model: on by default, but any of\n * several explicit signals turns it off, in precedence order.\n *\n * 1. `--no-telemetry` on the command line — the most explicit, per-invocation.\n * 2. `DO_NOT_TRACK` — the cross-tool standard (https://consoledonottrack.com);\n * any value other than `0`/empty disables.\n * 3. `ZITADEL_TELEMETRY` set to a falsey token (`0`/`false`/`off`/`no`).\n * 4. An automated test run (`VITEST`/`NODE_ENV=test`) — never emit synthetic\n * traffic or pay the shutdown flush; spawned CLI subprocesses inherit it.\n * 5. No ingestion token configured for the active channel — nothing to send to,\n * so telemetry is inert regardless of consent.\n *\n * The user's own choices (1–3) come first so `reason` reports them even in a\n * test shell: the user agent reads it to decide whether to describe the\n * user's environment.\n *\n * Consent being enabled does not by itself send anything; the caller still\n * builds the client lazily and fails open on any transport error.\n */\nexport function resolveConsent(input: ConsentInput): Consent {\n if (input.flag === false) {\n return { enabled: false, reason: \"flag-opt-out\" };\n }\n\n const doNotTrack = input.env[DO_NOT_TRACK.name]?.trim();\n if (doNotTrack && doNotTrack !== \"0\") {\n return { enabled: false, reason: \"do-not-track\" };\n }\n\n const explicit = input.env[ZITADEL_TELEMETRY.name]?.trim().toLowerCase();\n if (explicit !== undefined && DISABLED_VALUES.has(explicit)) {\n return { enabled: false, reason: \"env-opt-out\" };\n }\n\n if (input.env.VITEST || input.env.NODE_ENV === \"test\") {\n return { enabled: false, reason: \"test-runner\" };\n }\n\n const token = resolveTelemetryToken(input.env);\n if (!token) {\n return { enabled: false, reason: \"no-token\" };\n }\n\n return { enabled: true, reason: \"enabled\", token };\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 { 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 { resolveTelemetryHost } from \"./config\";\nimport { resolveConsent } from \"./consent\";\nimport { type Identity, loadOrCreateIdentity } from \"./identity\";\nimport { compact } from \"./util\";\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 readonly initClient?: (token: string, host: string) => MixpanelClient;\n readonly loadIdentity?: (env: NodeJS.ProcessEnv) => Identity;\n readonly newId?: () => string;\n};\n\n/**\n * A generic, application-agnostic Mixpanel client wrapper for a single short\n * process. It knows nothing about commands, CLIs, or event names — callers\n * supply fully-built property bags. Its only opinions are operational, because\n * 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\n private constructor(\n client: MixpanelClient | undefined,\n distinctId: string,\n isFirstRun: boolean,\n debug: boolean,\n newId: () => string,\n ) {\n this.client = client;\n this.distinctId = distinctId;\n this.isFirstRun = isFirstRun;\n this.debug = debug;\n this.newId = newId;\n }\n\n /** Whether events will actually be sent (consent granted and a token configured). */\n get enabled(): boolean {\n return this.client !== undefined;\n }\n\n /**\n * Resolve consent, identity, token, and host, then build the Mixpanel client\n * lazily — only when consent is granted *and* a token is configured. Any\n * failure along the way yields an inert instance whose methods are no-ops.\n */\n static create(deps: TelemetryDeps): Telemetry {\n const newId = deps.newId ?? randomUUID;\n const debug = deps.debug ?? false;\n const inert = (firstRun: boolean): Telemetry =>\n new Telemetry(undefined, \"\", firstRun, debug, newId);\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 || !consent.token) {\n return inert(false);\n }\n\n const identity = (deps.loadIdentity ?? loadOrCreateIdentity)(deps.env);\n\n let client: MixpanelClient | undefined;\n try {\n client = (deps.initClient ?? defaultInit)(consent.token, resolveTelemetryHost(deps.env));\n } catch {\n return inert(identity.isFirstRun);\n }\n return new Telemetry(client, identity.distinctId, identity.isFirstRun, debug, newId);\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.client) {\n return;\n }\n const payload = compact({\n ...properties,\n distinct_id: this.distinctId,\n $insert_id: this.newId(),\n });\n if (this.debug) {\n process.stderr.write(`[telemetry] ${event} ${JSON.stringify(payload)}\\n`);\n }\n this.enqueue((client, done) => client.track(event, payload, done));\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: string): MixpanelClient {\n return mixpanelLib.init(token, { host, geolocate: false });\n}\n","import type { Property } from \"../property\";\nimport { envEnabled } from \"./env-flag\";\n\n/** Coarse CI provider name, or `undefined` when not running in CI. */\nclass CiProvider implements Property<NodeJS.ProcessEnv, string | undefined> {\n /** Provider-marker env var → reported name, in match order. */\n private static readonly providers = [\n [\"GITHUB_ACTIONS\", \"github_actions\"],\n [\"GITLAB_CI\", \"gitlab_ci\"],\n [\"CIRCLECI\", \"circleci\"],\n [\"BUILDKITE\", \"buildkite\"],\n [\"JENKINS_URL\", \"jenkins\"],\n ] as const satisfies ReadonlyArray<readonly [string, string]>;\n\n public value(env: NodeJS.ProcessEnv): string | undefined {\n const named = CiProvider.providers.find(([marker]) => envEnabled(env[marker]));\n if (named) {\n return named[1];\n }\n return envEnabled(env.CI) ? \"unknown\" : undefined;\n }\n}\n\nexport const ciProvider = new CiProvider();\n","import type { Property } from \"../property\";\n\n/** Fixed-enum identity of the agent or host driving the process. */\nclass HostAgent implements Property<NodeJS.ProcessEnv, string> {\n /** Predicate → reported name, in match order. */\n private static readonly agents: ReadonlyArray<\n readonly [(env: NodeJS.ProcessEnv) => boolean, string]\n > = [\n [(env) => Boolean(env.CLAUDECODE || env.CLAUDE_CODE_ENTRYPOINT), \"claude_code\"],\n [(env) => Boolean(env.CURSOR_TRACE_ID || env.CURSOR_AGENT), \"cursor\"],\n [(env) => env.TERM_PROGRAM === \"vscode\", \"vscode\"],\n ];\n\n public value(env: NodeJS.ProcessEnv): string {\n return HostAgent.agents.find(([matches]) => matches(env))?.[1] ?? \"unknown\";\n }\n}\n\nexport const hostAgent = new HostAgent();\n","/**\n * The `User-Agent` the CLI sends on every HTTP request it makes through\n * undici — the Zitadel API, local-server health checks, branding asset probes\n * — so a server (and its logs and session records) can tell CLI traffic apart\n * from any other Node client, and tell CLI versions apart. Node's `fetch`\n * otherwise sends the bare `node`.\n *\n * Space-separated `product/version` tokens (RFC 9110 §10.1.5), in the style of\n * npm and the AWS CLI, most significant first:\n *\n * zitadel-cli/1.0.0 node/v24.12.0 darwin/24.6.0 arch/arm64 ci/github_actions host/claude_code\n *\n * `ci/` and `host/` use the vocabulary of the telemetry `ci_provider` and\n * `host_agent` dimensions. They appear only when detected, and never once the\n * user has opted out of telemetry: they describe the user's environment, so\n * the same opt-out covers them.\n */\n\nimport { release } from \"node:os\";\n\nimport { type Dispatcher, getGlobalDispatcher, setGlobalDispatcher } from \"undici\";\n\nimport { type Consent, resolveConsent } from \"./telemetry/consent\";\nimport { ciProvider } from \"./telemetry/dimensions/ci-provider\";\nimport { hostAgent } from \"./telemetry/dimensions/host-agent\";\n\nconst USER_AGENT_HEADER = \"user-agent\";\n\n/**\n * Consent outcomes that are the user's own choice. A missing ingestion token\n * or a test run also disables telemetry, but says nothing about what the user\n * wants reported.\n */\nconst OPT_OUT_REASONS: ReadonlySet<Consent[\"reason\"]> = new Set([\n \"flag-opt-out\",\n \"do-not-track\",\n \"env-opt-out\",\n]);\n\n/** Process facts the user agent is built from, surfaced as data so it is testable. */\nexport type UserAgentFacts = {\n readonly cliVersion: string;\n readonly nodeVersion: string;\n readonly platform: NodeJS.Platform;\n readonly osRelease: string;\n readonly arch: string;\n readonly env: NodeJS.ProcessEnv;\n /** The `--telemetry/--no-telemetry` flag, when given. */\n readonly telemetryFlag?: boolean;\n};\n\n/** The {@link UserAgentFacts} of the running process. */\nexport function processUserAgentFacts(\n cliVersion: string,\n telemetryFlag: boolean | undefined,\n): UserAgentFacts {\n return {\n cliVersion,\n nodeVersion: process.version,\n platform: process.platform,\n osRelease: release(),\n arch: process.arch,\n env: process.env,\n telemetryFlag,\n };\n}\n\nexport function buildUserAgent(facts: UserAgentFacts): string {\n const tokens = [\n product(\"zitadel-cli\", facts.cliVersion),\n product(\"node\", facts.nodeVersion),\n product(facts.platform, facts.osRelease),\n product(\"arch\", facts.arch),\n ];\n const consent = resolveConsent({ env: facts.env, flag: facts.telemetryFlag });\n if (!OPT_OUT_REASONS.has(consent.reason)) {\n const ci = ciProvider.value(facts.env);\n if (ci !== undefined) {\n tokens.push(product(\"ci\", ci));\n }\n const host = hostAgent.value(facts.env);\n if (host !== \"unknown\") {\n tokens.push(product(\"host\", host));\n }\n }\n return tokens.join(\" \");\n}\n\n/**\n * One `name/version` product token. Characters outside the RFC 9110 `token`\n * set (an OS release string is free-form) become `_`, so a stray space or\n * slash can never split one token into two.\n */\nfunction product(name: string, version: string): string {\n return `${sanitizeToken(name)}/${sanitizeToken(version)}`;\n}\n\nfunction sanitizeToken(value: string): string {\n return value.replace(/[^!#$%&'*+\\-.^_`|~0-9A-Za-z]/g, \"_\") || \"unknown\";\n}\n\n/** The installed user agent and the global dispatcher that carries it. */\ntype UserAgentSlot = {\n userAgent?: string;\n dispatcher?: Dispatcher;\n};\n\n/**\n * Stored on `globalThis`, like the dispatcher it wraps, so every copy of this\n * module in the process shares one value: with module-local state, a second\n * copy would compose a second interceptor whose stale value overwrote the\n * first's on every request.\n */\nconst SLOT = Symbol.for(\"@zitadel/cli/user-agent\");\n\nfunction slot(): UserAgentSlot {\n const scope = globalThis as Record<symbol, UserAgentSlot | undefined>;\n scope[SLOT] ??= {};\n return scope[SLOT];\n}\n\n/**\n * undici interceptor that sets the installed user agent on every request,\n * replacing whatever the caller or `fetch` put there. Exported so a module\n * that builds its own dispatcher (and so bypasses the global one) can\n * compose it; a no-op until {@link installUserAgent} runs.\n */\nexport const userAgentInterceptor: Dispatcher.DispatcherComposeInterceptor =\n (dispatch) => (options, handler) => {\n const userAgent = slot().userAgent;\n return dispatch(\n userAgent === undefined\n ? options\n : { ...options, headers: withUserAgent(options.headers, userAgent) },\n handler,\n );\n };\n\n/**\n * Make every request through the global dispatcher — which is what `fetch`\n * uses, including the `@zitadel/api` client — carry `userAgent`. Composes\n * onto the existing global dispatcher, so a proxy agent installed before\n * (`NODE_USE_ENV_PROXY`) keeps working. Calling it again only replaces the\n * value, unless something has since swapped the global dispatcher out, in\n * which case the interceptor is composed onto the new one.\n *\n * Importing the `undici` package installs its own `Agent` as the global\n * dispatcher when none is set yet, so Node's bundled `fetch` dispatches\n * through the package's undici. Keep its major version on the one the\n * supported Node release bundles.\n */\nexport function installUserAgent(userAgent: string): void {\n const state = slot();\n state.userAgent = userAgent;\n const current = getGlobalDispatcher();\n if (current !== state.dispatcher) {\n state.dispatcher = current.compose(userAgentInterceptor);\n setGlobalDispatcher(state.dispatcher);\n }\n}\n\n/**\n * Forget the installed user agent. **Test-only**: it does not restore the\n * global dispatcher, which the caller saved and puts back itself.\n */\nexport function _resetUserAgentForTesting(): void {\n delete (globalThis as Record<symbol, unknown>)[SLOT];\n}\n\n/**\n * Rewrite `headers` — in any of the shapes undici accepts — as a flat\n * name/value list with every existing `user-agent` dropped and `userAgent`\n * appended. The flat list keeps repeated headers intact. A malformed\n * odd-length list is returned untouched, for undici to reject.\n */\nexport function withUserAgent(\n headers: Dispatcher.DispatchOptions[\"headers\"],\n userAgent: string,\n): Dispatcher.DispatchOptions[\"headers\"] {\n if (Array.isArray(headers) && headers.length % 2 !== 0) {\n return headers;\n }\n const flat: string[] = [];\n for (const [name, value] of headerEntries(headers)) {\n if (name.toLowerCase() === USER_AGENT_HEADER) {\n continue;\n }\n const values = value === undefined ? [] : Array.isArray(value) ? value : [value];\n for (const item of values) {\n flat.push(name, item);\n }\n }\n flat.push(USER_AGENT_HEADER, userAgent);\n return flat;\n}\n\ntype HeaderEntry = readonly [string, string | string[] | undefined];\n\nfunction headerEntries(headers: Dispatcher.DispatchOptions[\"headers\"]): Iterable<HeaderEntry> {\n if (headers == null) {\n return [];\n }\n if (Array.isArray(headers)) {\n const pairs: HeaderEntry[] = [];\n for (let index = 0; index < headers.length; index += 2) {\n // Even length is checked by the caller, so both indexes are in range.\n pairs.push([headers[index] as string, headers[index + 1]]);\n }\n return pairs;\n }\n if (Symbol.iterator in headers) {\n return headers as Iterable<HeaderEntry>;\n }\n return Object.entries(headers);\n}\n","import { consola } from \"consola\";\n\n/**\n * Warnings reported during this invocation. The CLI runs one command per\n * process, so a module-level list is the invocation's list; `BaseCommand`\n * clears it when a command starts and drains it into the envelope when the\n * command emits.\n */\nconst reported: string[] = [];\n\n/**\n * Report a warning. This is the only way the CLI warns: never call\n * `consola.warn` directly (see `apps/cli/AGENTS.md`).\n *\n * A terminal shows the warning at once, which matters when it comes before a\n * long wait. `--json` silences that output, so the warning is also kept for\n * the envelope's `warnings`, and both kinds of reader see it.\n */\nexport function reportWarning(message: string): void {\n consola.warn(message);\n reported.push(message);\n}\n\n/** Take every warning reported so far, leaving none behind. */\nexport function takeReportedWarnings(): string[] {\n return reported.splice(0);\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\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`. The allow-list: only enums, booleans, counts, and\n * versions cross the boundary — never URLs, project ids, file paths, emails, or\n * secrets. `extra` is spread first so the canonical base dimensions always win;\n * callers order their own extras so reserved lifecycle fields win over command\n * 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 ...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","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 { type Asker, input as askInput } from \"../input\";\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 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} 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\";\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 /** 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 * Asks for a value, a choice or a confirmation: the one way a command takes\n * input. It 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 */\n protected readonly input: Asker = (question) =>\n askInput(question, { interactive: !this.meta.nonInteractive, force: this.meta.force });\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, resolving the server\n * `source` by the documented precedence and storing the result on\n * `this.meta` so the error handler can render a complete envelope.\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 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, env: process.env, 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 / no-token /\n * test-runner) 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({ env: process.env, flag, debug: this.meta.debug });\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 // 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 {\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. the `apply` plan diff);\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 { chmod, readFile, rename, stat, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ZitadelError } from \"./errors\";\nimport { isObject, parseJsonObject, stableStringify } from \"./json\";\nimport { DEFAULT_SERVER } from \"./server\";\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: [\"zitadel 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: [\"zitadel setup\", \"zitadel 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 chmod(tmp, 0o600).catch(() => undefined);\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\n/** Reads `environments.development.issuer` from a parsed `zitadel.json`, if present. */\nexport function readDevelopmentIssuer(config: Record<string, unknown>): string | undefined {\n if (isObject(config.environments) && isObject(config.environments.development)) {\n const issuer = config.environments.development.issuer;\n return typeof issuer === \"string\" ? issuer : undefined;\n }\n return undefined;\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 { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient, type ZitadelClient } from \"../api-client\";\nimport { ZitadelError } from \"../errors\";\nimport { readZitadelSecret } from \"../project\";\nimport { BaseCommand } from \"./base\";\nimport type { GlobalOptions } from \"./types\";\n\n/**\n * A command that addresses a project's variables. The project is the only\n * owner, and it is named rather than assumed — `--project-level` is required —\n * so that if variables gain another owner, every command already written keeps\n * meaning exactly what it means now.\n */\nexport abstract class OwnerCommand extends BaseCommand {\n static override baseFlags = {\n ...BaseCommand.baseFlags,\n \"project-level\": Flags.boolean({\n description:\n \"Address the project level. Required: it is the only owner the CLI can address today.\",\n }),\n };\n\n /**\n * Refuse an invocation that names no owner, then build the invocation\n * context. The refusal is the same on a terminal and in a script: with one\n * owner available there is nothing to ask about, and a prompt offering a\n * single answer is a keystroke, not a choice.\n *\n * It comes before `super.toMeta`, which resolves the server — a run that\n * named no owner is refused whatever `--server` says, rather than answering\n * `E_LOCAL_SERVER_NOT_RUNNING` for a `--server local` with nothing running.\n */\n protected override async toMeta(\n flags: Record<string, unknown>,\n options: { resolveServer?: boolean; source?: string } = {},\n ): Promise<GlobalOptions> {\n if (flags[\"project-level\"] !== true) {\n throw new ZitadelError(\"E_VALIDATION\", \"Name the owner: --project-level\", {\n hint: \"The project level is the only owner the CLI can address.\",\n });\n }\n return super.toMeta(flags, options);\n }\n\n /**\n * Open the platform connection, the counterpart of the resource commands'\n * `connect`.\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.\n */\n protected async connect(): Promise<\n Readonly<{\n client: ZitadelClient;\n /** The query parameters every variables endpoint takes for this owner. */\n scope: Readonly<{ project_id: string }>;\n }>\n > {\n const { cwd, source } = this.meta;\n const secret = await readZitadelSecret(cwd);\n if (process.stdout.isTTY) {\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n }\n return {\n client: createZitadelClient({ baseUrl: source, token: secret.project_secret }),\n scope: { project_id: secret.project_id },\n };\n }\n}\n","import { isObject } from \"../json\";\n\n/**\n * Collects the environment variables a flows document depends on, sorted and\n * de-duplicated. Recognises two reference styles: inline `${VAR}` interpolations\n * inside string values, and keys ending in `_env` whose value names a single\n * variable. `apply`/`plan` use this to fail before contacting the platform when\n * a required variable is absent.\n */\nexport function flowEnvRefs(value: unknown): string[] {\n const refs = new Set<string>();\n const visit = (node: unknown): void => {\n if (typeof node === \"string\") {\n for (const match of node.matchAll(/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g)) {\n const ref = match[1];\n if (ref) {\n refs.add(ref);\n }\n }\n } else if (Array.isArray(node)) {\n node.forEach(visit);\n } else if (isObject(node)) {\n for (const [key, child] of Object.entries(node)) {\n if (\n key.endsWith(\"_env\") &&\n typeof child === \"string\" &&\n /^[A-Za-z_][A-Za-z0-9_]*$/.test(child)\n ) {\n refs.add(child);\n } else {\n visit(child);\n }\n }\n }\n };\n visit(value);\n return [...refs].sort();\n}\n","import { flowConfigSchema } from \"@zitadel/config/schemas\";\nimport {\n PURPOSE_FLIP_TARGETS,\n validateFlowDefinition,\n type FlowValidationIssue,\n} from \"@zitadel/config/validate\";\n\nimport { isObject } from \"../json\";\n\n/** What validating a flow against a schema change found. */\ntype FlowCheck =\n /**\n * The flow has a structural error, so the validator never reached the rules\n * that depend on the schema and cannot say whether the change breaks it.\n */\n | { readonly kind: \"unchecked\"; readonly issues: FlowValidationIssue[] }\n /** The errors the change introduces; empty when the flow is unaffected. */\n | { readonly kind: \"checked\"; readonly introduced: FlowValidationIssue[] };\n\n/**\n * Check what a schema change from `before` to `after` does to a flow.\n *\n * Only new errors count. A schema-rule error the flow already had is `plan`'s\n * to report, and refusing an unrelated change because of it would block the\n * developer from an edit that might be part of the fix.\n *\n * @param flow - The flow as it is on disk.\n * @param before - The schema as it is on disk.\n * @param after - The schema as the change leaves it.\n * @param flowAfter - The flow as the change leaves it. Password and passkey\n * never edit a flow, so it defaults to the flow itself; `auth-method sso\n * disable` removes the provider from it.\n */\nexport function checkFlow(\n flow: object,\n before: Record<string, unknown>,\n after: Record<string, unknown>,\n flowAfter: object = flow,\n): FlowCheck {\n // The semantic validator reads a malformed shape leniently (a string where\n // `fields` should be a list reads as no fields), so the raw file is checked\n // against the canonical flow schema first, as `plan` does.\n const shape = flowConfigSchema.safeParse(flowAfter);\n if (!shape.success) {\n return {\n kind: \"unchecked\",\n issues: shape.error.issues.map((issue) => ({\n severity: \"error\",\n rule: \"definition\",\n message: `${issue.path.join(\".\") || \"(root)\"}: ${issue.message}`,\n })),\n };\n }\n // The validator runs the schema rules only over a structurally sound flow,\n // so without this the change would always look harmless on a broken one.\n const structural = validateFlowDefinition(flowAfter);\n if (structural.length > 0) {\n return { kind: \"unchecked\", issues: structural };\n }\n const key = (issue: FlowValidationIssue) => `${issue.rule}\\u0000${issue.message}`;\n const existing = new Set(\n validateFlowDefinition(flow, before)\n .filter((issue) => issue.severity === \"error\")\n .map(key),\n );\n return {\n kind: \"checked\",\n introduced: validateFlowDefinition(flowAfter, after).filter(\n (issue) => issue.severity === \"error\" && !existing.has(key(issue)),\n ),\n };\n}\n\n/**\n * The sign-in methods (`password`, `passkey`, `sso`) that some active flow\n * lets an existing user sign in with.\n *\n * Only an active flow is served, so a draft offers nothing. Passkey counts\n * only through a `passkey` action: `passkey_register` enrols a new credential\n * and signs nobody in. SSO counts only through a step offering one of\n * `providers`.\n *\n * @param flows - The flows that run against the schema, whatever their status.\n * @param providers - The SSO providers the schema enables.\n */\nexport function offeredSignInMethods(\n flows: readonly Record<string, unknown>[],\n providers: readonly string[],\n): string[] {\n // Only the login journey signs anyone in: a register-only flow, or the\n // register steps of a combined one, can collect a password or offer a\n // passkey without letting an existing user back in.\n const journeys = flows.filter((flow) => flow.status === \"active\").map(loginJourney);\n const offered = (signsIn: (flow: Record<string, unknown>) => boolean) => journeys.some(signsIn);\n return [\n ...(offered(collectsPassword) ? [\"password\"] : []),\n ...(offered(signsInWithPasskey) ? [\"passkey\"] : []),\n ...(offered((flow) => offersSso(flow, providers)) ? [\"sso\"] : []),\n ];\n}\n\n/**\n * Outcomes the engine answers by switching from login to register without a\n * `purpose` on the transition: the validator's flip table, plus\n * `sso_user_not_found`, which it leaves out of that table on purpose but\n * which routes to registration the same way.\n */\nconst LOGIN_LEAVING_OUTCOMES = new Set([\n ...Object.keys(PURPOSE_FLIP_TARGETS.login ?? {}),\n \"sso_user_not_found\",\n]);\n\n/**\n * The flow cut down to the steps reachable from its `login` entry, following\n * transitions that stay in the login purpose. No `login` purpose means no\n * steps: such a flow signs nobody in.\n */\nfunction loginJourney(flow: Record<string, unknown>): Record<string, unknown> {\n const purposes = isObject(flow.purposes) ? flow.purposes : {};\n const entry = purposes.login;\n const byName = new Map(steps(flow).map((step) => [step.name, step]));\n const reached = new Set<string>();\n const queue = typeof entry === \"string\" ? [entry] : [];\n while (queue.length > 0) {\n const name = queue.shift() as string;\n const step = byName.get(name);\n if (reached.has(name) || step === undefined) {\n continue;\n }\n reached.add(name);\n const transitions = isObject(step.transitions) ? Object.entries(step.transitions) : [];\n for (const [outcome, transition] of transitions) {\n // Some outcomes switch the journey to registration on their own, with\n // no `purpose` on the transition: the steps after them register a new\n // user rather than sign one in.\n if (LOGIN_LEAVING_OUTCOMES.has(outcome)) {\n continue;\n }\n // Mirrors the validator's local adjacency: a transition with an\n // `action` goes to another flow, whose step names are not this flow's,\n // and one into another purpose (register, say) leaves the login\n // journey. A null `action` or `purpose` is the same as an absent one.\n if (\n isObject(transition) &&\n typeof transition.target === \"string\" &&\n (transition.action === undefined || transition.action === null) &&\n (transition.purpose === undefined ||\n transition.purpose === null ||\n transition.purpose === \"login\")\n ) {\n queue.push(transition.target);\n }\n }\n }\n return { ...flow, steps: steps(flow).filter((step) => reached.has(step.name as string)) };\n}\n\nfunction steps(flow: Record<string, unknown>): Record<string, unknown>[] {\n return Array.isArray(flow.steps) ? flow.steps.filter(isObject) : [];\n}\n\n/** Password is field-shaped: a step collects `x-auth-methods#password`. */\nfunction collectsPassword(flow: Record<string, unknown>): boolean {\n return steps(flow).some(\n (step) => Array.isArray(step.fields) && step.fields.includes(\"x-auth-methods#password\"),\n );\n}\n\nfunction signsInWithPasskey(flow: Record<string, unknown>): boolean {\n return steps(flow).some(\n (step) =>\n Array.isArray(step.actions) &&\n step.actions.some((action) => isObject(action) && action.kind === \"passkey\"),\n );\n}\n\nfunction offersSso(flow: Record<string, unknown>, providers: readonly string[]): boolean {\n return steps(flow).some(\n (step) =>\n Array.isArray(step.sso_providers) &&\n step.sso_providers.some((p) => typeof p === \"string\" && providers.includes(p)),\n );\n}\n","/**\n * Public surface for the flow domain. Every caller outside this module\n * imports from here (not from individual files) so the package\n * boundary stays observable.\n *\n * **Source of truth.** The wire shape lives in\n * `@zitadel/api/generated/model` (orval-generated from the\n * OpenAPI spec). Callers that need the type import\n * `CreateFlowDefinitionBodyFlowDefinition` from there directly;\n * callers that need the runtime validator import\n * `CreateFlowDefinitionBody` from\n * `@zitadel/api/generated/endpoints/zitadelNextGen.zod`. This\n * module owns only the CLI-specific concerns: the password-flow\n * builder, env-var reference scanning, the file-level\n * `validateFlows` helper that surfaces `E_VALIDATION` errors against\n * the generated Zod, and the sign-in analysis the `auth-method`\n * commands run over a flow (what a schema change breaks, and which\n * methods a flow lets a user sign in with).\n *\n * **Dependency rule.** No upward imports (`commands/`, `sync/`, etc.)\n * and no filesystem I/O. It depends sideways only on shared utilities\n * under `apps/cli/src/lib/` — today `lib/errors` (`ZitadelError`) and\n * `lib/json` (`isObject`).\n */\nexport { buildFlow } from \"./build\";\nexport { validateFlows } from \"./validate\";\nexport { flowEnvRefs } from \"./env-refs\";\nexport { checkFlow, offeredSignInMethods } from \"./sign-in\";\n\n/**\n * Relative directory (from the project root) where local flow files\n * live. Owned here so callers (`commands/*`, `sync/syncers.ts`) and\n * tests share a single source of truth for the path; the runtime\n * never depends on it directly because `lib/flows` does not touch\n * the filesystem.\n */\nexport const FLOWS_DIR = \".zitadel/flows\";\n","import { readdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport {\n type ClientId,\n type ClientIdVariable,\n type ClientSecretVariable,\n type ConnectionSlug,\n credentialVariables,\n type CustomOidcInput,\n idpProvider,\n isVariableReference,\n parseConnectionSlug,\n type ProviderSelection,\n referencedVariable,\n type IdpProvider,\n} from \"@zitadel/config/idp\";\n\nimport { isErrno, ZitadelError } from \"../errors\";\nimport { isObject } from \"../json\";\n\n/**\n * Relative directory (from the project root) where local connection files\n * live, one per provider. Owned here alongside the only reader of it, and\n * re-exported from `lib/idp` so callers and tests share one source of truth\n * for the path, as `FLOWS_DIR` and `SCHEMAS_DIR` do for their domains.\n */\nexport const IDPS_DIR = \".zitadel/idps\";\n\n/**\n * `$schema` pointer a scaffolded connection carries, relative to\n * {@link IDPS_DIR}: the meta-schema `zitadel setup` writes under\n * `.zitadel/meta/`, so an editor validates the file as it is typed.\n */\nexport const CONNECTION_SCHEMA_REF = \"../meta/idp-connection.json\";\n\n/** A connection file as it sits on disk, with the name needed to report it. */\nexport type ConnectionFile = {\n /** File name within {@link IDPS_DIR}, e.g. `google.json`. */\n readonly name: string;\n /** Project-relative path, for messages the developer has to act on. */\n readonly path: string;\n readonly body: Record<string, unknown>;\n};\n\n/**\n * Read every connection file under `.zitadel/idps/`, in lexical order so a\n * duplicate report is stable. A missing directory reads as no connections:\n * the first provider a Project enables creates it.\n *\n * Unlike `readJsonDir`, this keeps each file's name. Every decision below is\n * reported to the developer in terms of the file they have to look at.\n */\nexport async function readConnectionFiles(cwd: string): Promise<ConnectionFile[]> {\n const dir = join(cwd, IDPS_DIR);\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return [];\n }\n throw error;\n }\n const files: ConnectionFile[] = [];\n for (const name of entries.filter((e) => e.endsWith(\".json\")).sort()) {\n const path = `${IDPS_DIR}/${name}`;\n let body: unknown;\n try {\n body = JSON.parse(await readFile(join(dir, name), \"utf8\"));\n } catch (error) {\n throw new ZitadelError(\"E_VALIDATION\", `${path} is not valid JSON`, {\n hint: \"Fix or remove the file, then run the command again.\",\n details: { file: path, parse_error: describeParseError(error) },\n });\n }\n if (!isObject(body)) {\n throw new ZitadelError(\"E_VALIDATION\", `${path} does not contain a JSON object`, {\n details: { file: path },\n });\n }\n files.push({ name, path, body });\n }\n return files;\n}\n\n/**\n * What went wrong parsing a file, without the text of the file. V8 quotes the\n * source it choked on, and this file is where a pasted secret would be.\n */\nfunction describeParseError(error: unknown): string {\n const position = error instanceof Error ? /position (\\d+)/.exec(error.message)?.[1] : undefined;\n return position === undefined ? \"invalid JSON\" : `invalid JSON at position ${position}`;\n}\n\n/**\n * Whether a connection file describes the catalog entry's provider.\n *\n * `template` names the catalog entry the file was scaffolded from. When it was\n * edited away, the file still counts if it carries the catalog's own slug and\n * issuer. A different slug on the same issuer is a custom connection that\n * happens to point at the provider, which a Project may hold alongside the\n * catalog one, so the catalog provider does not claim it.\n */\nfunction describesProvider(file: ConnectionFile, entry: IdpProvider): boolean {\n if (file.body.template === entry.template) {\n return true;\n }\n const oidc = file.body.oidc;\n return (\n String(file.body.slug ?? \"\").trim() === entry.slug &&\n isObject(oidc) &&\n oidc.issuer === entry.issuer\n );\n}\n\n/** The client id a connection file carries. */\nfunction clientIdOf(file: ConnectionFile): string | undefined {\n return credentialOf(file, \"client_id\");\n}\n\n/** One credential field, from the file's `oidc` block. */\nfunction credentialOf(\n file: ConnectionFile,\n field: \"client_id\" | \"client_secret\",\n): string | undefined {\n const block = file.body.oidc;\n return isObject(block) && typeof block[field] === \"string\" ? block[field] : undefined;\n}\n\n/**\n * The variables a connection's credentials reference, falling back to the\n * names this CLI would have written.\n *\n * A connection is editable and may name its own variables, so publishing to a\n * slug-derived name would store the credential where the connection never\n * looks and report it as stored.\n */\nexport function credentialVariablesOf(\n file: ConnectionFile,\n slug: ConnectionSlug | undefined,\n): StoredVariables {\n const scaffolded = slug === undefined ? undefined : credentialVariables(slug);\n return {\n clientId: named(file, \"client_id\", scaffolded?.clientId),\n clientSecret: named(file, \"client_secret\", scaffolded?.clientSecret),\n };\n}\n\n/**\n * The variable a credential field names, as the type of its fallback.\n *\n * A field absent from the file is where this command would have pointed it and\n * will point it now, so it reads as `fallback`, which is `undefined` when the\n * caller has no slug to derive one from. A field holding a literal is the value\n * itself: there is no variable behind it, and naming one would publish where\n * the connection never looks. Whatever a `client_id` field references is a\n * client id's variable, whatever it is called, which is what the brand records;\n * the type parameter keeps the two credentials from being swapped.\n */\nfunction named<V extends string>(\n file: ConnectionFile,\n field: \"client_id\" | \"client_secret\",\n fallback: V | undefined,\n): V | undefined {\n const value = credentialOf(file, field);\n return value === undefined ? fallback : (referencedVariable(value) as V | undefined);\n}\n\n/**\n * The variables a connection on disk actually uses.\n *\n * `undefined` for a credential the file holds as a literal: an editable\n * connection may carry a real client id rather than a reference, and that value\n * is not read from anywhere, so there is nothing to publish to and nothing for\n * another connection to collide with.\n */\nexport type StoredVariables = {\n readonly clientId: ClientIdVariable | undefined;\n readonly clientSecret: ClientSecretVariable | undefined;\n};\n\n/**\n * Stop when a connection document hands back a credential value.\n *\n * `client_secret` is always a `${{ NAME }}` reference — the syncer refuses to\n * upload anything else — so a value here is the server having resolved the\n * reference. Every path that reaches this has somewhere worse to put it than a\n * log: a plan preview prints it, and a file written from it would commit it to\n * `.zitadel/idps/`, which is the one place the secret must never reach.\n */\nexport function refuseResolvedSecret(definition: object, id: string): void {\n const block = (definition as Record<string, unknown>).oidc;\n const stored = isObject(block) ? block.client_secret : undefined;\n if (typeof stored === \"string\" && !isVariableReference(stored)) {\n throw new ZitadelError(\"E_VALIDATION\", `${id} came back holding a client_secret value`, {\n hint:\n \"A stored connection must keep the ${{ NAME }} reference. Report this: the endpoint \" +\n \"is resolving secrets, and the value would be written to disk.\",\n details: { id, block: \"oidc\" },\n });\n }\n}\n\n/**\n * Stop when two connections' credentials would land in the same variable.\n *\n * Two ways that happens. A slug may hold `-` and `_`\n * (`^[a-z0-9][a-z0-9_-]*$`) and the variable name replaces every\n * non-alphanumeric with `_`, so `google-work` and `google_work` both read\n * `GOOGLE_WORK_CLIENT_SECRET`. And a connection is editable, so one may simply\n * point at a name another already uses, or point both of its own credentials\n * at one name. Either way a publish overwrites what the other credential put\n * there, and the loser signs in with the wrong application — a failure that\n * surfaces at the provider, not here.\n *\n * What an existing file *references* is what counts, not what its slug would\n * derive: an `okta` connection referencing `GOOGLE_CLIENT_SECRET` collides\n * with Google however its slug reads.\n *\n * The derivation stays legible on purpose — these names get typed into\n * `variables set` by hand — so the ambiguity is refused rather than encoded\n * around.\n *\n * @param ours - The variables this run will publish to.\n * @param except - The connection being reused, which is not its own collision.\n */\nfunction refuseCollidingVariables(\n ours: StoredVariables,\n slug: ConnectionSlug,\n files: readonly ConnectionFile[],\n except?: ConnectionFile,\n): void {\n // The one place the two kinds of name are compared on purpose: both credentials\n // pointing at the same variable.\n if (ours.clientId !== undefined && (ours.clientId as string) === ours.clientSecret) {\n throw new ZitadelError(\n \"E_CONFLICT\",\n `This connection points both credentials at ${ours.clientId}`,\n {\n hint: \"Give client_id and client_secret separate ${{ NAME }} references, then run the command again.\",\n details: { slug, variable: ours.clientId },\n },\n );\n }\n for (const file of files) {\n if (file === except) {\n continue;\n }\n // A file with no usable slug has no derived names, but what it references\n // explicitly is still read, however its slug reads.\n const theirSlug = parseConnectionSlug(String(file.body.slug ?? \"\"));\n const theirs = credentialVariablesOf(file, theirSlug.ok ? theirSlug.value : undefined);\n // A literal on either side names no variable, so it cannot collide.\n const shared = [ours.clientId, ours.clientSecret].find(\n (name) => name !== undefined && (name === theirs.clientId || name === theirs.clientSecret),\n );\n if (shared === undefined) {\n continue;\n }\n throw new ZitadelError(\"E_CONFLICT\", `${file.path} and ${slug} both use ${shared}`, {\n hint: \"Point one of them at a variable of its own, then run the command again.\",\n details: {\n file: file.path,\n slug,\n other_slug: theirSlug.ok ? theirSlug.value : String(file.body.slug ?? \"\"),\n variable: shared,\n },\n });\n }\n}\n\n/** What the caller should do with the provider's connection. */\nexport type ConnectionPlan =\n | {\n readonly action: \"reuse\";\n readonly file: ConnectionFile;\n readonly slug: ConnectionSlug;\n /** Settings the developer gave that the existing file does not have, and so were not applied. */\n readonly notApplied?: readonly (\"display name\" | \"scopes\")[];\n }\n | {\n readonly action: \"create\";\n readonly name: string;\n readonly path: string;\n readonly slug: ConnectionSlug;\n /** Files that already connect to this provider's issuer under another slug. */\n readonly alsoUsesIssuer?: readonly string[];\n };\n\n/**\n * Decide whether a catalog provider already has a connection in this Project.\n *\n * Reuse is the default: a Project has one connection per provider, and a\n * second one for the same provider is nearly always an accident. Anything\n * ambiguous stops instead of guessing, because both alternatives — editing\n * the wrong connection, or silently adding a duplicate — are worse than\n * asking the developer which they meant.\n *\n * @param clientId - When given, a single match whose client id differs is a\n * conflict rather than a reuse: the developer is pointing at a different\n * OAuth application than the one already configured.\n */\nfunction planCatalogConnection(options: {\n readonly provider: IdpProvider;\n readonly files: readonly ConnectionFile[];\n readonly clientId?: ClientId;\n /** How the calling command spells the slug flag, for the hints. */\n readonly slugFlag: string;\n}): ConnectionPlan {\n const entry = options.provider;\n const slug = entry.slug;\n const matches = options.files.filter((file) => describesProvider(file, entry));\n\n if (matches.length > 1) {\n const names = matches.map((m) => m.path).join(\", \");\n throw new ZitadelError(\n \"E_CONFLICT\",\n `More than one ${entry.displayName} connection exists: ${names}`,\n {\n hint: \"Keep the one this Project should use and remove the others, then run the command again.\",\n details: { provider: slug, files: matches.map((m) => m.path) },\n },\n );\n }\n\n const [match] = matches;\n if (match !== undefined) {\n refuseDifferentClientId(match, options.clientId);\n // A file can match on template or issuer while carrying no slug of its\n // own. Inventing the provider's would point the schema and every flow at\n // an identity the connection does not declare, and the server rejects the\n // connection on the next apply for want of it.\n const matchSlug = parseConnectionSlug(String(match.body.slug ?? \"\"));\n if (!matchSlug.ok) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${match.path} is a ${entry.displayName} connection with no usable slug`,\n {\n hint: \"Give the connection file a slug -- the schemas and flows reference it by that name.\",\n details: { file: match.path, problem: matchSlug.problem },\n },\n );\n }\n refuseCollidingVariables(\n credentialVariablesOf(match, matchSlug.value),\n matchSlug.value,\n options.files,\n match,\n );\n return { action: \"reuse\", file: match, slug: matchSlug.value };\n }\n\n // No match. The scaffolded name is the slug, so an unrelated file already\n // sitting there would be overwritten — refuse rather than replace it.\n const name = `${slug}.json`;\n const path = `${IDPS_DIR}/${name}`;\n const occupied = options.files.find((file) => file.name === name);\n if (occupied !== undefined) {\n const theirSlug = String(occupied.body.slug ?? \"\").trim();\n // The same name on a connection to somewhere else is not the provider's.\n throw new ZitadelError(\n \"E_CONFLICT\",\n theirSlug === slug\n ? `${path} is a connection called ${slug}, but not to ${entry.displayName}: its issuer is not ${entry.issuer}`\n : `${path} already exists and its slug is ${theirSlug === \"\" ? \"missing\" : theirSlug}, not ${slug}`,\n {\n hint:\n theirSlug === slug\n ? `Point it at ${entry.displayName} if it is that connection. Otherwise change its slug, in the file and in the schemas and flows that name it, then run the command again.`\n : `Rename or remove that file, or give it the slug ${slug} if it is the ${entry.displayName} connection, then run the command again.`,\n details: { file: path, slug: occupied.body.slug ?? null },\n },\n );\n }\n refuseCollidingVariables(credentialVariables(slug), slug, options.files);\n // A hand-written connection to the same issuer under another slug is not\n // claimed, so this adds a second button for the provider. Say so.\n const alsoUsesIssuer = options.files\n .filter((file) => isObject(file.body.oidc) && file.body.oidc.issuer === entry.issuer)\n .map((file) => file.path);\n return {\n action: \"create\",\n name,\n path,\n slug,\n ...(alsoUsesIssuer.length > 0 ? { alsoUsesIssuer } : {}),\n };\n}\n\n/**\n * Stop when the developer names a client id other than the one a connection\n * already holds.\n *\n * A scaffolded connection stores `${{ NAME }}`, not an id, so there is no\n * identity in the file to disagree with and the command stays idempotent.\n * A hand-written connection may still hold a literal, and that one is\n * worth refusing: rerunning with a different id would otherwise reuse a\n * file configured for another client.\n */\nfunction refuseDifferentClientId(match: ConnectionFile, clientId: ClientId | undefined): void {\n const existing = clientIdOf(match);\n const literal = existing !== undefined && !isVariableReference(existing);\n if (clientId !== undefined && literal && existing !== clientId) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${match.path} already uses client id ${existing}, not ${clientId}`,\n {\n hint: \"Edit the connection file to change its client id, or run the command without one to reuse it.\",\n details: {\n file: match.path,\n stored_client_id: existing,\n supplied_client_id: clientId,\n },\n },\n );\n }\n}\n\n/**\n * Decide what to do with a custom connection, identified by the slug the\n * developer supplied.\n *\n * Unlike {@link planConnection} this never looks at the template or the\n * issuer to find a connection: a Project may hold several connections to one\n * issuer, with different credentials or mappings, and what tells them apart\n * is the name. The slug is also what schemas and flows reference, so it is\n * the only thing that can say \"the same connection\".\n *\n * A slug already in use is reused only when it is the same provider — the\n * same issuer — so that repeating a command changes nothing. The same name on\n * a connection to somewhere else is somebody else's, and replacing it would\n * repoint every schema and flow that names it.\n */\nfunction planCustomConnection(options: {\n readonly input: CustomOidcInput;\n readonly files: readonly ConnectionFile[];\n readonly clientId?: ClientId;\n /** Whether `--scopes` was passed: a default nobody asked for has not been contradicted. */\n readonly scopesGiven?: boolean;\n /** How the calling command spells the slug flag, for the hints. */\n readonly slugFlag: string;\n}): ConnectionPlan {\n const { slug, issuer } = options.input;\n const name = `${slug}.json`;\n const path = `${IDPS_DIR}/${name}`;\n const holders = options.files.filter((file) => String(file.body.slug ?? \"\").trim() === slug);\n\n if (holders.length > 1) {\n throw new ZitadelError(\n \"E_CONFLICT\",\n `More than one connection is named ${slug}: ${holders.map((h) => h.path).join(\", \")}`,\n {\n hint: \"A slug names one connection. Remove or rename all but one, then run the command again.\",\n details: { slug, files: holders.map((h) => h.path) },\n },\n );\n }\n\n const [match] = holders;\n if (match === undefined) {\n // Nothing declares the slug, but the file name is where this one would go.\n if (options.files.some((file) => file.name === name)) {\n throw new ZitadelError(\n \"E_CONFLICT\",\n `${path} already exists and is not the ${slug} connection`,\n {\n hint: `Rename or remove that file, or choose another ${options.slugFlag}, then run the command again.`,\n details: { file: path, slug },\n },\n );\n }\n refuseCollidingVariables(credentialVariables(slug), slug, options.files);\n return { action: \"create\", name, path, slug };\n }\n\n const oidc = match.body.oidc;\n const existingIssuer =\n isObject(oidc) && typeof oidc.issuer === \"string\" ? oidc.issuer : undefined;\n if (existingIssuer !== issuer) {\n throw new ZitadelError(\n \"E_CONFLICT\",\n existingIssuer === undefined\n ? `${match.path} is already named ${slug} and is not an OIDC connection to ${issuer}`\n : `${match.path} is already named ${slug} and connects to ${existingIssuer}, not ${issuer}`,\n {\n hint: `An applied connection keeps its issuer, and the server compares it exactly, so even a trailing slash names another provider. Choose another ${options.slugFlag} for this connection, then move the schemas and flows that name the old one to it.`,\n details: { file: match.path, slug, issuer, existing_issuer: existingIssuer ?? null },\n },\n );\n }\n refuseDifferentClientId(match, options.clientId);\n refuseCollidingVariables(credentialVariablesOf(match, slug), slug, options.files, match);\n const storedScopes = isObject(oidc) && Array.isArray(oidc.scopes) ? oidc.scopes.join(\" \") : \"\";\n const notApplied = [\n ...(match.body.display_name === options.input.displayName ? [] : ([\"display name\"] as const)),\n ...(options.scopesGiven !== true || storedScopes === options.input.scopes.join(\" \")\n ? []\n : ([\"scopes\"] as const)),\n ];\n return { action: \"reuse\", file: match, slug, ...(notApplied.length > 0 ? { notApplied } : {}) };\n}\n\n/**\n * Decide what to do with the connection for a provider in this Project.\n *\n * A catalog provider has one connection, found by what it is. Reuse is the\n * default: a second one for the same provider is nearly always an accident.\n * A custom connection is found by the slug the developer gave it, because a\n * Project may hold several connections to one issuer and the name is the only\n * thing that tells them apart.\n *\n * Anything ambiguous stops instead of guessing, because both alternatives —\n * editing the wrong connection, or silently adding a duplicate — are worse\n * than asking the developer which they meant.\n *\n * @param clientId - When given, a single match whose client id differs is a\n * conflict rather than a reuse: the developer is pointing at a different\n * OAuth application than the one already configured.\n */\nexport function planConnection(options: {\n readonly selection: ProviderSelection;\n readonly files: readonly ConnectionFile[];\n readonly clientId?: ClientId;\n readonly scopesGiven?: boolean;\n /** How the calling command spells the slug flag, for the hints. */\n readonly slugFlag: string;\n}): ConnectionPlan {\n const { selection, files, clientId, scopesGiven, slugFlag } = options;\n return selection.kind === \"custom\"\n ? planCustomConnection({ input: selection.connection, files, clientId, scopesGiven, slugFlag })\n : planCatalogConnection({ provider: idpProvider(selection.id), files, clientId, slugFlag });\n}\n","/**\n * Enabling a provider on an existing Project edits two files: the user schema\n * gains an `sso` authentication method, and the login flow gains the steps and\n * routes a provider round trip needs.\n *\n * Both functions are pure — they take parsed documents and return new ones, so\n * the caller owns reading, writing and reporting. Both are idempotent: running\n * them again on their own output changes nothing.\n *\n * Only the regions below are ever written. Anything a developer has edited by\n * hand is left exactly as it stands and reported back, because silently\n * rewriting it would discard deliberate work.\n */\n\nimport { getDefaultLoginFlow, SETUP_PRESETS } from \"@zitadel/config/defaults\";\nimport type { ConnectionSlug } from \"@zitadel/config/idp\";\n\nimport { ZitadelError } from \"../errors\";\n\n/**\n * Steps a flow starts at, by purpose, plus the steps that collect an\n * identifier. The provider button belongs on all of them: a developer landing\n * on the first screen expects it there, and someone who has already gone to\n * the email screen should not have to go back for it.\n *\n * On the shipped password-first flow the login entry *is* `identifier`, so\n * this is exactly `identifier` and `register` — which is what the design's\n * reference flow shows. On passkey-first it also picks up the passkey entry\n * screen, which the reference never considered.\n */\nfunction providerSteps(flow: Json): string[] {\n const purposes = isObject(flow.purposes) ? flow.purposes : {};\n const names = [purposes.login, purposes.register, \"identifier\", \"register\"];\n const wanted: string[] = [];\n for (const name of names) {\n if (typeof name === \"string\" && !wanted.includes(name) && stepNamed(flow, name) !== undefined) {\n wanted.push(name);\n }\n }\n return wanted;\n}\n\n/**\n * The step a flow starts its login purpose at, which a transition that\n * re-purposes to `login` must target.\n *\n * The engine rejects a `purpose: \"login\"` transition pointing anywhere else,\n * so this cannot be hardcoded: `identifier` is only the password-first flow's\n * entry, and a passkey-first flow starts at its passkey screen.\n */\nfunction loginEntry(flow: Json): string | undefined {\n const purposes = isObject(flow.purposes) ? flow.purposes : {};\n const named = purposes.login;\n if (typeof named === \"string\" && stepNamed(flow, named) !== undefined) {\n return named;\n }\n // A flow that does not serve the login purpose has nowhere to send someone\n // who wants to sign in instead, and the validator rejects a transition that\n // re-purposes to a purpose the definition does not serve. Falling back to\n // `identifier` would write exactly that.\n return stepNamed(flow, \"identifier\") !== undefined && purposes.login !== undefined\n ? \"identifier\"\n : undefined;\n}\n\n/** Step the engine sends a new external identity to. */\nconst REGISTER_SSO = \"register-sso\";\n/** Step shown when the provider's email already has an account. */\nconst SSO_CONFLICT = \"sso-conflict\";\n/** The step that asks the identified user for a password. */\nconst PASSWORD_STEP = \"password\";\n\n/** Outcomes the engine fires after a provider returns, and where they go. */\nfunction providerOutcomes(terminal: string): Record<string, string> {\n return {\n sso_authenticated: terminal,\n sso_user_not_found: REGISTER_SSO,\n user_already_exists: SSO_CONFLICT,\n };\n}\n\n/**\n * The step a completed sign-in ends at.\n *\n * Derived, not assumed to be called `done`. Step names are not fixed by the\n * contract — `purposes` names entry points, not terminals — and what marks a\n * terminal is the `complete` property, which both shipped flows carry. A flow\n * whose terminal is called something else was valid before this edit, and\n * writing `done` into the generated routes would point them at a step that\n * does not exist: `validateFlowDefinition` rejects that on the next `plan`\n * (\"transition ... targets unknown step\"), so enabling a provider would break\n * a flow that worked.\n *\n * `undefined` when the flow has no single terminal to route to, which the\n * caller refuses rather than guesses at.\n */\nfunction terminalStep(flow: Json): string | undefined {\n const complete = steps(flow).filter(\n (step) => step.complete !== undefined && typeof step.name === \"string\",\n );\n if (complete.length === 1) {\n return complete[0]?.name as string;\n }\n // A flow that marks no terminal, or several: fall back to the scaffolded\n // name if it is there, so an older hand-written flow still works.\n return stepNamed(flow, \"done\") === undefined ? undefined : \"done\";\n}\n\ntype Json = Record<string, unknown>;\ntype Step = Json & { name?: unknown };\n\n/** What a generator left alone, so the caller can say so. */\nexport type SsoSkipped = {\n /** The step that was left alone, e.g. `sso-conflict`. */\n readonly step: string;\n /** File-relative description, e.g. `steps.sso-conflict`. */\n readonly region: string;\n readonly reason: \"hand-edited\";\n};\n\nexport type SsoResult<T> = {\n readonly document: T;\n /** True when the document changed; false makes a rerun a no-op. */\n readonly changed: boolean;\n readonly skipped: SsoSkipped[];\n};\n\nfunction clone<T>(value: T): T {\n return structuredClone(value);\n}\n\nfunction isObject(value: unknown): value is Json {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction steps(flow: Json): Step[] {\n return Array.isArray(flow.steps) ? (flow.steps as Step[]) : [];\n}\n\n/** Which document a refusal is about, for the region names it reports. */\nexport type SsoEditTarget = \"flow\" | \"schema\";\n\n/**\n * Why this document cannot be edited for SSO, or `undefined` when it can.\n *\n * The editors below read a missing region as empty and write the generated one\n * in its place. That is right for a document that has simply not got there yet,\n * and wrong for one whose region holds something else: that value was put there\n * by hand, and replacing it is the one thing these functions promise not to do.\n * A flow whose `steps` is a string, for instance, would otherwise be read as\n * having no steps and written back with two — the hand-written value gone, and\n * nothing said about it.\n *\n * Reported rather than skipped: unlike a hand-edited step, which the caller can\n * leave alone and still produce a working flow, none of the edits can proceed\n * here, so a partial success would be a misleading thing to report.\n */\nexport function ssoEditRefusal(document: object, target: SsoEditTarget): string | undefined {\n const body = document as Json;\n return target === \"flow\" ? flowRefusal(body) : schemaRefusal(body);\n}\n\nfunction flowRefusal(flow: Json): string | undefined {\n const providers = ssoProvidersRefusal(flow);\n if (providers !== undefined) {\n return providers;\n }\n // Last, because it is about where the generated routes point rather than\n // whether the document can be read at all.\n if (terminalStep(flow) === undefined) {\n return \"no step marks where a completed sign-in ends\";\n }\n return undefined;\n}\n\n/**\n * Why a flow's steps cannot be read for their provider lists, or `undefined`\n * when they can. This is all removing a provider needs\n * (`auth-method sso disable`): unlike enabling, it writes no route, so it does\n * not care where a completed sign-in ends.\n */\nexport function ssoProvidersRefusal(document: object): string | undefined {\n const flow = document as Json;\n if (flow.steps !== undefined && !Array.isArray(flow.steps)) {\n return \"steps is not a list\";\n }\n for (const [index, step] of steps(flow).entries()) {\n if (!isObject(step)) {\n return `steps[${index}] is not a step`;\n }\n const name = typeof step.name === \"string\" ? step.name : String(index);\n if (step.transitions !== undefined && !isObject(step.transitions)) {\n return `steps.${name}.transitions is not an object`;\n }\n // Owned like transitions are: `addProvider` reads a non-list as empty and\n // writes the generated list over it, so `sso_providers: \"github\"` would\n // become `[\"google\"]` with nothing said about the provider it replaced.\n if (step.sso_providers !== undefined && !Array.isArray(step.sso_providers)) {\n return `steps.${name}.sso_providers is not a list`;\n }\n }\n return undefined;\n}\n\nfunction schemaRefusal(schema: Json): 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 if (methods.sso === undefined) {\n return undefined;\n }\n if (!isObject(methods.sso)) {\n return \"x-auth-methods.sso 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.\n if (typeof methods.sso.enabled !== \"boolean\") {\n return \"x-auth-methods.sso.enabled is not a boolean\";\n }\n const providers = methods.sso.providers;\n if (providers !== undefined && !Array.isArray(providers)) {\n return \"x-auth-methods.sso.providers is not a list\";\n }\n return undefined;\n}\n\nfunction stepNamed(flow: Json, name: string): Step | undefined {\n return steps(flow).find((step) => step.name === name);\n}\n\n/**\n * Enable the provider on a user schema.\n *\n * Only `x-auth-methods.sso` is touched: password and passkey configuration\n * belongs to whoever set it, and a provider is added to the list rather than\n * replacing it, so enabling a second one later keeps the first.\n */\nexport function applySsoToSchema(schema: object, slug: ConnectionSlug): SsoResult<object> {\n const document = clone(schema) as Json;\n const methods = isObject(document[\"x-auth-methods\"]) ? { ...document[\"x-auth-methods\"] } : {};\n const existing = isObject(methods.sso) ? methods.sso : undefined;\n const providers = Array.isArray(existing?.providers)\n ? [...(existing.providers as unknown[])]\n : [];\n\n if (existing?.enabled === true && providers.includes(slug)) {\n return { document: schema, changed: false, skipped: [] };\n }\n if (!providers.includes(slug)) {\n providers.push(slug);\n }\n methods.sso = { ...existing, enabled: true, providers };\n document[\"x-auth-methods\"] = methods;\n return { document, changed: true, skipped: [] };\n}\n\n/**\n * The properties this project collects when someone registers.\n *\n * Read from the register purpose's own entry step rather than from the schema:\n * that step is where the project decided what to ask for, and the use case\n * chosen at setup already shaped it (`minimal` asks for an email, `business`\n * also for names and a company). Taking the schema instead would collect every\n * property it defines, including ones the project deliberately does not ask\n * about.\n *\n * Credential fields are dropped. The provider is the proof for an account\n * `create_user_with_sso` creates, so the scaffold asks for no password. An\n * author who adds a password field gets it stored with the user.\n *\n * Falls back to the identifier-collecting step, and then to nothing, so a flow\n * shaped unlike the shipped one still produces a step that can collect the one\n * property the mutation cannot do without.\n */\nfunction registrationFields(flow: Json): string[] {\n const purposes = isObject(flow.purposes) ? flow.purposes : {};\n const named = typeof purposes.register === \"string\" ? purposes.register : \"register\";\n for (const name of [named, \"register\", \"identifier\"]) {\n const step = stepNamed(flow, name);\n const fields = isObject(step) && Array.isArray(step.fields) ? step.fields : [];\n const collected = fields.filter(\n (field): field is string => typeof field === \"string\" && !field.startsWith(\"x-auth-methods#\"),\n );\n if (collected.length > 0) {\n return collected;\n }\n }\n return [];\n}\n\n/**\n * The step that collects what the provider did not supply.\n *\n * It asks for everything registration asks for, because a provider is not\n * obliged to supply any of it: the engine creates the account outright when\n * the claims satisfy the schema and shows this step when they do not, and a\n * step that can only collect the identifier is a dead end for every property\n * beyond it.\n */\nfunction registerSsoStep(fields: string[], terminal: string): Step {\n return {\n name: REGISTER_SSO,\n fields,\n actions: [\n { name: \"submit\", kind: \"submit\", primary: true, text_key: `${REGISTER_SSO}.action.submit` },\n ],\n on_success: \"create_user_with_sso\",\n transitions: {\n submit: { target: terminal },\n user_already_exists: { target: SSO_CONFLICT },\n },\n };\n}\n\n/**\n * The step shown when the provider's email already has an account. It offers\n * only the methods the schema actually enables — a password box on a schema\n * without passwords is a dead end.\n */\nfunction ssoConflictStep(\n slug: ConnectionSlug,\n methods: { password: boolean; passkey: boolean },\n loginStep: string | undefined,\n terminal: string,\n): Step {\n const actions: Json[] = [];\n const fields: string[] = [];\n if (methods.password) {\n fields.push(\"x-auth-methods#password\");\n actions.push({\n name: \"submit\",\n kind: \"submit\",\n primary: true,\n text_key: `${SSO_CONFLICT}.action.submit`,\n });\n }\n if (methods.passkey) {\n actions.push({\n name: \"passkey\",\n kind: \"passkey\",\n primary: false,\n text_key: `${SSO_CONFLICT}.action.passkey`,\n });\n }\n if (loginStep !== undefined) {\n actions.push({\n name: \"sign_in\",\n kind: \"navigate\",\n primary: false,\n text_key: `${SSO_CONFLICT}.action.sign_in`,\n });\n }\n\n const transitions: Json = {};\n if (methods.password) {\n transitions.submit = { target: terminal };\n }\n if (methods.passkey) {\n transitions.passkey = { target: terminal };\n }\n transitions.sso_authenticated = { target: terminal };\n transitions.user_already_exists = { target: SSO_CONFLICT };\n if (loginStep !== undefined) {\n transitions.sign_in = { target: loginStep, purpose: \"login\" };\n }\n transitions.sso_user_not_found = { target: REGISTER_SSO };\n\n return { name: SSO_CONFLICT, fields, actions, sso_providers: [slug], transitions };\n}\n\n/**\n * Whether a step is still what this generator would write for it.\n *\n * Compared key-sorted at every depth: the CLI writes its managed files with a\n * stable serialiser, so a step that has been through `setup` or any `apply`\n * has its keys in a different order from the object built here while being\n * the same step. Comparing the raw JSON would report the generator's own\n * output as hand-edited.\n */\nfunction matches(step: Step, expected: Step): boolean {\n return canonical(withoutServerDefaults(step)) === canonical(withoutServerDefaults(expected));\n}\n\n/**\n * A step without what the platform leaves out when it answers.\n *\n * The server omits an action's `primary: false` (a default), an empty `fields`\n * list, and an empty `gates` map, and a file that took the server's\n * definition (as `apply` once wrote it back) is not byte for byte what this\n * generator wrote though it is the same step. Reading it as hand-edited would\n * skip the step on the next provider.\n */\nfunction withoutServerDefaults(step: Step): Step {\n const copy: Step = { ...step };\n for (const key of [\"fields\", \"gates\"]) {\n const value = copy[key];\n const empty = Array.isArray(value)\n ? value.length === 0\n : isObject(value) && Object.keys(value).length === 0;\n if (empty) {\n delete copy[key];\n }\n }\n if (Array.isArray(copy.actions)) {\n copy.actions = copy.actions.map((action) => {\n if (!isObject(action) || action.primary !== false) {\n return action;\n }\n const { primary: _default, ...rest } = action;\n return rest;\n });\n }\n return copy;\n}\n\nlet shippedPasswordForms: string[] | undefined;\n\n/**\n * The password steps the shipped flows carry, one per preset, in the form\n * {@link withoutSsoRoutes} reduces any password step to. A step that reduces to\n * one of these is the one `setup` wrote, however many providers it offers.\n * The shipped steps carry no provider routes, so the terminal does not matter.\n */\nfunction shippedPasswordSteps(): string[] {\n shippedPasswordForms ??= SETUP_PRESETS.flatMap((preset) => {\n const flow = getDefaultLoginFlow({ preset }) as unknown as Json;\n const step = stepNamed(flow, PASSWORD_STEP);\n return step === undefined ? [] : [canonical(withoutSsoRoutes(step, \"done\"))];\n });\n return shippedPasswordForms;\n}\n\n/**\n * A password step without what offering providers adds to it: the provider\n * list, and the routes this generator writes for what comes back from one.\n *\n * A route that goes somewhere else is the developer's and stays, which is what\n * makes the step read as edited. The platform's own rewrite is not an edit\n * ({@link withoutServerDefaults}).\n */\nfunction withoutSsoRoutes(step: Step, terminal: string): Step {\n const copy: Step = { ...withoutServerDefaults(step) };\n delete copy.sso_providers;\n if (isObject(copy.transitions)) {\n const written = providerOutcomes(terminal);\n copy.transitions = Object.fromEntries(\n Object.entries(copy.transitions).filter(\n ([outcome, route]) =>\n !(\n outcome in written &&\n isObject(route) &&\n route.target === written[outcome] &&\n Object.keys(route).length === 1\n ),\n ),\n );\n }\n return copy;\n}\n\n/**\n * Whether a password step already lists the provider and carries the routes the\n * generator writes, whatever else it has been edited to say.\n */\nfunction offersAlready(step: Step, slug: string, terminal: string): boolean {\n if (!Array.isArray(step.sso_providers) || !step.sso_providers.includes(slug)) {\n return false;\n }\n const transitions = isObject(step.transitions) ? step.transitions : {};\n return Object.entries(providerOutcomes(terminal)).every(([outcome, target]) => {\n const route = transitions[outcome];\n return isObject(route) && route.target === target;\n });\n}\n\n/** The provider list a step should end up with: what it has, plus this slug. */\nfunction mergedProviders(step: Step, slug: ConnectionSlug): unknown[] {\n const providers = Array.isArray(step.sso_providers) ? [...(step.sso_providers as unknown[])] : [];\n return providers.includes(slug) ? providers : [...providers, slug];\n}\n\n/**\n * Offer a provider on a step, keeping any already there. Returns whether the\n * step changed, so a rerun is a no-op.\n */\nfunction addProvider(step: Step, slug: string): boolean {\n const providers = Array.isArray(step.sso_providers) ? [...(step.sso_providers as unknown[])] : [];\n if (providers.includes(slug)) {\n return false;\n }\n providers.push(slug);\n step.sso_providers = providers;\n return true;\n}\n\n/** Stable JSON: object keys sorted at every depth, arrays left in order. */\nfunction canonical(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(sortKeys);\n }\n if (isObject(value)) {\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, sortKeys(value[key])]),\n );\n }\n return value;\n}\n\n/** Outcome keys the previous CLI wrote, and the names the engine now raises. */\nconst LEGACY_OUTCOMES: ReadonlyArray<readonly [string, string]> = [\n [\"callback\", \"sso_authenticated\"],\n [\"identity_unknown\", \"sso_user_not_found\"],\n];\n\n/**\n * Rename the previous outcome keys on every step, in place. The validator\n * rejects the old keys, so leaving them would make `auth-method sso enable`\n * write an invalid flow. Where a step already has the new key, that one wins. A\n * key that is also one of the step's action names is the action's transition\n * and stays. A new key that is an action name is refused: the old route would\n * be dropped for the action's. A legacy key with `purpose` or `action` is\n * refused: the new keys may declare neither, and dropping them would change the\n * author's routing.\n */\nfunction migrateLegacyOutcomes(document: Json): boolean {\n let changed = false;\n for (const step of steps(document)) {\n if (!isObject(step.transitions)) {\n continue;\n }\n const transitions = step.transitions;\n const actions = Array.isArray(step.actions) ? step.actions : [];\n const actionNames = new Set(\n actions.map((action) => (isObject(action) ? action.name : undefined)),\n );\n for (const [old, next] of LEGACY_OUTCOMES) {\n if (!(old in transitions) || actionNames.has(old)) {\n continue;\n }\n if (actionNames.has(next)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `steps.${String(step.name)}: transition \"${old}\" is renamed to \"${next}\", which is an action on this step`,\n {\n hint: `Rename the action \"${next}\" on step \"${String(step.name)}\" (and its transition), then run auth-method sso enable again.`,\n details: { step: step.name, action: next },\n },\n );\n }\n if (!(next in transitions)) {\n const transition = transitions[old];\n if (\n isObject(transition) &&\n ((transition.purpose ?? null) !== null || (transition.action ?? null) !== null)\n ) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `steps.${String(step.name)}: transition \"${old}\" declares purpose or action, which \"${next}\" cannot`,\n {\n hint: `Remove purpose and action from the transition \"${old}\" on step \"${String(step.name)}\", then run auth-method sso enable again.`,\n details: { step: step.name, transition: old },\n },\n );\n }\n transitions[next] = transition;\n }\n delete transitions[old];\n changed = true;\n }\n }\n return changed;\n}\n\n/**\n * Refuse a flow where a step this command writes declares an action named like\n * an outcome key the generator writes on that step. Those names were free\n * before the rename; the generated route would silently replace the action's.\n */\nfunction refuseOutcomeActionCollision(document: Json): void {\n const outcomes = [\"sso_authenticated\", \"sso_user_not_found\", \"user_already_exists\"];\n const entries: Array<[string, string[]]> = [\n ...providerSteps(document).map((name) => [name, outcomes] as [string, string[]]),\n [SSO_CONFLICT, outcomes],\n [REGISTER_SSO, [\"user_already_exists\"]],\n [\"register-password\", [\"user_already_exists\"]],\n ];\n // A step can be listed twice (a provider step named `register-password`), so\n // its keys are the union of every entry, never just the last one.\n const written = new Map<string, Set<string>>();\n for (const [name, keys] of entries) {\n written.set(name, new Set([...(written.get(name) ?? []), ...keys]));\n }\n for (const [name, keys] of written) {\n const step = stepNamed(document, name);\n const actions = step !== undefined && Array.isArray(step.actions) ? step.actions : [];\n for (const action of actions) {\n if (isObject(action) && typeof action.name === \"string\" && keys.has(action.name)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `steps.${name}: action \"${action.name}\" uses a name auth-method sso enable writes as an outcome on this step`,\n {\n hint: `Rename the action \"${action.name}\" on step \"${name}\" (and its transition), then run auth-method sso enable again.`,\n details: { step: name, action: action.name },\n },\n );\n }\n }\n }\n}\n\n/**\n * Add the provider to a login flow.\n *\n * @param enabled - The authentication methods the target schema enables,\n * which decide what the conflict step may offer.\n */\nexport function applySsoToFlow(\n flow: object,\n slug: ConnectionSlug,\n enabled: { password: boolean; passkey: boolean },\n): SsoResult<object> {\n const document = clone(flow) as Json;\n // Before any rewrite, so a refused flow is never half edited.\n refuseOutcomeActionCollision(document);\n const skipped: SsoSkipped[] = [];\n let changed = false;\n // `ssoEditRefusal` has already refused a flow with no terminal to route to,\n // so the caller never reaches here without one.\n const terminal = terminalStep(document) ?? \"done\";\n // First, so a step the previous CLI wrote matches today's template below.\n if (migrateLegacyOutcomes(document)) {\n changed = true;\n }\n\n for (const name of providerSteps(document)) {\n const step = stepNamed(document, name);\n if (step === undefined) {\n continue;\n }\n if (addProvider(step, slug)) {\n changed = true;\n }\n const transitions = isObject(step.transitions) ? { ...step.transitions } : {};\n for (const [outcome, target] of Object.entries(providerOutcomes(terminal))) {\n const current = transitions[outcome];\n // `user_already_exists` already points at the password step on a\n // register flow. Retargeting it is the point: the same outcome now also\n // fires for a provider return, and the conflict step offers everything\n // the password step did.\n if (isObject(current) && current.target === target) {\n continue;\n }\n transitions[outcome] = { target };\n changed = true;\n }\n step.transitions = transitions;\n }\n\n // The password step is where someone lands who typed their email rather than\n // clicking a provider. A user who signed up with a provider has no password,\n // so a step with only a password field is a dead end for them. It offers the\n // providers too, unless it has been edited by hand: it is a step the\n // developer is likely to have changed, and the editors only write into what\n // they recognise.\n const password = stepNamed(document, PASSWORD_STEP);\n if (password !== undefined && !providerSteps(document).includes(PASSWORD_STEP)) {\n if (offersAlready(password, slug, terminal)) {\n // Edited by hand and already carrying the provider and its routes, which\n // is what the warning asks for: there is nothing left to say.\n } else if (!shippedPasswordSteps().includes(canonical(withoutSsoRoutes(password, terminal)))) {\n skipped.push({\n step: PASSWORD_STEP,\n region: `steps.${PASSWORD_STEP}`,\n reason: \"hand-edited\",\n });\n } else {\n // Every provider the entry steps carry, not only the one named: a project\n // enabled before the password step offered providers has several to catch up.\n const offered = providerSteps(document).flatMap((name) => {\n const entry = stepNamed(document, name);\n return entry !== undefined && Array.isArray(entry.sso_providers)\n ? (entry.sso_providers as unknown[])\n : [];\n });\n for (const provider of new Set([...offered, slug])) {\n if (typeof provider === \"string\" && addProvider(password, provider)) {\n changed = true;\n }\n }\n const transitions = isObject(password.transitions) ? { ...password.transitions } : {};\n // The same routes as the entry steps. A collision here binds to the\n // identified user either way, and the conflict step says why they are\n // back and offers the other ways in; sending them to this step again\n // would show an unchanged form and a Back that shows it twice.\n for (const [outcome, target] of Object.entries(providerOutcomes(terminal))) {\n const current = transitions[outcome];\n if (!isObject(current) || current.target !== target) {\n transitions[outcome] = { target };\n changed = true;\n }\n }\n password.transitions = transitions;\n }\n }\n\n // The password registration step shares the outcome, so it has to route to\n // the same place or a taken email dead-ends there.\n const registerPassword = stepNamed(document, \"register-password\");\n if (registerPassword !== undefined) {\n const transitions = isObject(registerPassword.transitions)\n ? { ...registerPassword.transitions }\n : {};\n const current = transitions.user_already_exists;\n if (!isObject(current) || current.target !== SSO_CONFLICT) {\n transitions.user_already_exists = { target: SSO_CONFLICT };\n registerPassword.transitions = transitions;\n changed = true;\n }\n }\n\n const list = steps(document);\n const terminalIndex = list.findIndex((step) => step.name === terminal);\n const insertAt = terminalIndex === -1 ? list.length : terminalIndex;\n // Each step with every form the generator may have written it in before. The\n // conflict step follows the methods enabled, so one written when passkey was\n // off is still the generator's own output once passkey is on. `register-sso`\n // and the password step do not depend on the methods, so they have one form.\n const wanted: Array<{ step: Step; earlier: Step[] }> = [\n { step: registerSsoStep(registrationFields(document), terminal), earlier: [] },\n {\n step: ssoConflictStep(slug, enabled, loginEntry(document), terminal),\n earlier: [true, false].flatMap((password) =>\n [true, false].map((passkey) =>\n ssoConflictStep(slug, { password, passkey }, loginEntry(document), terminal),\n ),\n ),\n },\n ];\n let offset = 0;\n for (const { step, earlier } of wanted) {\n const name = step.name as string;\n const existing = stepNamed(document, name);\n if (existing === undefined) {\n list.splice(insertAt + offset, 0, step);\n offset += 1;\n changed = true;\n continue;\n }\n // The conflict step carries a provider list of its own, so a second\n // provider is added to it rather than replacing the first — otherwise the\n // generator would report its own output as hand-edited and leave the\n // screen offering only the provider that was enabled first. `register-sso`\n // declares none, so it is compared as written.\n const merged = step.sso_providers === undefined ? undefined : mergedProviders(existing, slug);\n const expected = merged === undefined ? step : { ...step, sso_providers: merged };\n // Compared as if the list were already merged, but without merging it. The\n // list is the generator's to extend; the rest of the step is not. Adding\n // the provider first and comparing afterwards reported a hand-edited step\n // as left alone while having already changed it -- the one thing the\n // report promises it did not do.\n const candidate = merged === undefined ? existing : { ...existing, sso_providers: merged };\n if (matches(candidate, expected)) {\n if (merged !== undefined && addProvider(existing, slug)) {\n changed = true;\n }\n } else if (\n merged !== undefined &&\n earlier.some((form) => matches(candidate, { ...form, sso_providers: merged }))\n ) {\n // What the generator wrote for other methods: bring it up to today's, in\n // the place it already has, keeping the providers it lists.\n list[list.indexOf(existing)] = expected;\n changed = true;\n } else {\n skipped.push({ step: name, region: `steps.${name}`, reason: \"hand-edited\" });\n }\n }\n document.steps = list;\n\n return changed || skipped.length > 0\n ? { document, changed, skipped }\n : { document: flow, changed: false, skipped };\n}\n\n/**\n * Remove a provider from a user schema (`auth-method sso disable`, ADR 070).\n *\n * Only `x-auth-methods.sso` is touched. The provider leaves the list, and when\n * none is left `sso` becomes `{ \"enabled\": false }`: the meta-schema requires\n * at least one provider whenever the list is present. A provider the schema\n * does not offer is a no-op.\n */\nexport function removeSsoFromSchema(schema: object, slug: string): SsoResult<object> {\n const document = clone(schema) as Json;\n const methods = isObject(document[\"x-auth-methods\"]) ? { ...document[\"x-auth-methods\"] } : {};\n const sso = methods.sso;\n if (!isObject(sso) || !Array.isArray(sso.providers) || !sso.providers.includes(slug)) {\n return { document: schema, changed: false, skipped: [] };\n }\n const providers = sso.providers.filter((provider) => provider !== slug);\n methods.sso = providers.length === 0 ? { enabled: false } : { ...sso, providers };\n document[\"x-auth-methods\"] = methods;\n return { document, changed: true, skipped: [] };\n}\n\n/**\n * Remove a provider from every step of a login flow that offers it.\n *\n * Only the `sso_providers` lists change; a list left empty is dropped. The\n * routes and steps `auth-method sso enable` added stay: without a provider they\n * are never reached, they validate as they are, and enabling a provider again\n * uses them as they stand rather than rebuilding them.\n */\nexport function removeSsoFromFlow(flow: object, slug: string): SsoResult<object> {\n const document = clone(flow) as Json;\n let changed = false;\n for (const step of steps(document)) {\n if (!Array.isArray(step.sso_providers) || !step.sso_providers.includes(slug)) {\n continue;\n }\n const providers = (step.sso_providers as unknown[]).filter((provider) => provider !== slug);\n if (providers.length === 0) {\n delete step.sso_providers;\n } else {\n step.sso_providers = providers;\n }\n changed = true;\n }\n return changed\n ? { document, changed, skipped: [] }\n : { document: flow, changed: false, skipped: [] };\n}\n","import {\n CUSTOM_PROVIDER,\n type CustomOidcInput,\n IDP_PROVIDERS,\n isLoopbackIssuer,\n RESERVED_SLUGS,\n parseConnectionSlug,\n parseDisplayName,\n parseIssuer,\n parseProviderSelection,\n parseScopes,\n type Parsed,\n type ProviderSelection,\n} from \"@zitadel/config/idp\";\n\nimport { ZitadelError } from \"../errors\";\n\n/** What the developer typed for a custom connection, before it is checked. */\nexport type CustomFlagValues = {\n readonly slug?: string;\n readonly displayName?: string;\n readonly issuer?: string;\n readonly scopes?: string;\n};\n\n/** How a setting is spelled on the command line, so a message names the flag to fix. */\nexport type CustomFlagNames = {\n readonly provider: string;\n readonly slug: string;\n readonly displayName: string;\n readonly issuer: string;\n readonly scopes: string;\n};\n\n/**\n * The flag keys the two commands define for a custom connection, once. Each\n * command builds its flag definitions from these, reads its parsed flags\n * through them, and the names a message suggests come from them, so renaming\n * one renames the flag, what is read from it, and what is suggested.\n */\nexport const ENABLE_FLAG_KEYS = {\n provider: \"provider\",\n slug: \"slug\",\n displayName: \"display-name\",\n issuer: \"issuer\",\n scopes: \"scopes\",\n} as const;\n\n/** The `--sso-*` flags on `setup` that describe the same settings. */\nexport const SETUP_FLAG_KEYS = {\n provider: \"sso\",\n slug: \"sso-slug\",\n displayName: \"sso-display-name\",\n issuer: \"sso-issuer\",\n scopes: \"sso-scopes\",\n} as const;\n\ntype FlagKeys = {\n readonly provider: string;\n readonly slug: string;\n readonly displayName: string;\n readonly issuer: string;\n readonly scopes: string;\n};\n\nconst flagNamesOf = (keys: FlagKeys): CustomFlagNames => ({\n provider: `--${keys.provider}`,\n slug: `--${keys.slug}`,\n displayName: `--${keys.displayName}`,\n issuer: `--${keys.issuer}`,\n scopes: `--${keys.scopes}`,\n});\n\n/** The flags on `auth-method sso enable`, which a failed setup suggests running instead. */\nexport const ENABLE_FLAG_NAMES: CustomFlagNames = flagNamesOf(ENABLE_FLAG_KEYS);\n\n/** The `--sso-*` flags on `setup` that describe the same settings. */\nexport const SETUP_FLAG_NAMES: CustomFlagNames = flagNamesOf(SETUP_FLAG_KEYS);\n\n/**\n * What a command's parsed flags say about a custom connection. Typed by the\n * keys, so the flags a command parsed must carry them.\n */\nexport function customFlagValues<K extends FlagKeys>(\n flags: { readonly [P in K[\"slug\" | \"displayName\" | \"issuer\" | \"scopes\"]]?: string },\n keys: K,\n): CustomFlagValues {\n const read = (key: string) => (flags as Readonly<Record<string, string | undefined>>)[key];\n return {\n slug: read(keys.slug),\n displayName: read(keys.displayName),\n issuer: read(keys.issuer),\n scopes: read(keys.scopes),\n };\n}\n\n/**\n * How the target server reaches this machine's loopback: `allowed` for a\n * server `zitadel start` runs as a process with the loopback allow list,\n * `container` for one it runs in Docker, `unknown` for any other.\n */\nexport type LoopbackReach = \"allowed\" | \"container\" | \"unknown\";\n\n/** The warning a loopback issuer earns on a server that cannot reach it, or `undefined`. */\nexport function loopbackIssuerWarning(\n selection: ProviderSelection,\n reach: LoopbackReach = \"unknown\",\n): string | undefined {\n if (\n selection.kind !== \"custom\" ||\n !isLoopbackIssuer(selection.connection.issuer) ||\n reach === \"allowed\"\n ) {\n return undefined;\n }\n const { issuer } = selection.connection;\n return reach === \"container\"\n ? `${issuer} is on this machine, but the local server runs in Docker, where localhost is the container itself, so sign-in will fail. Start the server with \\`zitadel start --runtime binary\\` instead.`\n : `${issuer} is on this machine, and a server blocks requests to localhost unless NEXTGEN_HTTPCLIENT_ALLOW_LIST allows it, so sign-in will fail until it does. A server \\`zitadel start\\` runs allows it by default.`;\n}\n\n/**\n * What a command line describing a custom connection looks like, spelled with\n * the flags the command defines, for an error or a help example to show.\n */\nexport function customExample(flag: CustomFlagNames, withScopes = false): string {\n return [\n `${flag.provider} ${CUSTOM_PROVIDER}`,\n `${flag.slug} acme-sso`,\n `${flag.displayName} 'Acme SSO'`,\n `${flag.issuer} https://sso.acme.example`,\n ...(withScopes ? [`${flag.scopes} 'openid profile email groups'`] : []),\n ].join(\" \");\n}\n\n/** The names of the custom settings that were given, as the command spells them. */\nexport function givenCustomFlags(values: CustomFlagValues, flag: CustomFlagNames): string[] {\n return [\n [flag.slug, values.slug],\n [flag.displayName, values.displayName],\n [flag.issuer, values.issuer],\n [flag.scopes, values.scopes],\n ]\n .filter(([, value]) => value !== undefined)\n .map(([name]) => name as string);\n}\n\n/** One setting's complaint, under the flag that carried it. */\nfunction checkedUnder<T>(name: string, parsed: Parsed<T>): T {\n if (!parsed.ok) {\n throw new ZitadelError(\"E_VALIDATION\", `${name}: ${parsed.problem}`, {\n hint: `Fix ${name} and run the command again.`,\n details: { flag: name },\n });\n }\n return parsed.value;\n}\n\n/**\n * Check the settings that were given, and only those, naming the flag that\n * carried a bad one. For a run that will ask for the rest: a slug the server\n * would refuse is refused before the first question, as a missing client id is.\n */\nexport function checkGivenCustomFlags(values: CustomFlagValues, flag: CustomFlagNames): void {\n if (values.slug !== undefined) {\n checkedUnder(flag.slug, parseConnectionSlug(values.slug, RESERVED_SLUGS));\n }\n if (values.displayName !== undefined) {\n checkedUnder(flag.displayName, parseDisplayName(values.displayName));\n }\n if (values.issuer !== undefined) {\n checkedUnder(flag.issuer, parseIssuer(values.issuer));\n }\n if (values.scopes !== undefined) {\n checkedUnder(flag.scopes, parseScopes(values.scopes));\n }\n}\n\n/**\n * The provider a command line names, checked before anything else happens.\n *\n * A catalog provider is just its name. A custom one is described by the\n * settings that follow it, each checked against the contract the server\n * enforces on apply. Every complaint is raised here, before a Project is read\n * or a secret asked for: being turned away after typing a credential would\n * mean typing it again. The settings are flags on purpose — a name, issuer and\n * scopes are what a script or an agent supplies, and what a person can read\n * back from their shell history.\n */\nexport function selectionFromFlags(\n provider: string,\n values: CustomFlagValues,\n flag: CustomFlagNames,\n example: string,\n): ProviderSelection {\n const given = givenCustomFlags(values, flag);\n\n if (provider !== CUSTOM_PROVIDER) {\n // A catalog provider knows its own name, issuer and scopes, so a setting\n // given alongside it would be ignored, and an ignored flag reads as honoured.\n if (given.length > 0) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${given.join(\", \")} only applies to a custom connection`,\n {\n hint: `Add ${flag.provider} ${CUSTOM_PROVIDER}, or remove ${given.length === 1 ? \"it\" : \"them\"}.`,\n details: { flags: given },\n },\n );\n }\n const selection = parseProviderSelection(provider);\n if (selection === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", `Unknown provider ${provider}`, {\n hint: `Use one of ${[...IDP_PROVIDERS, CUSTOM_PROVIDER].join(\", \")}.`,\n });\n }\n return selection;\n }\n\n const { slug, displayName, issuer } = values;\n if (slug === undefined || displayName === undefined || issuer === undefined) {\n const missing = [flag.slug, flag.displayName, flag.issuer].filter(\n (name) => !given.includes(name),\n );\n throw new ZitadelError(\"E_VALIDATION\", `A custom connection needs ${missing.join(\", \")}`, {\n hint: `Describe the connection, e.g. ${example}`,\n details: { missing },\n });\n }\n const checked = checkedUnder;\n return {\n kind: \"custom\",\n connection: {\n slug: checked(flag.slug, parseConnectionSlug(slug, RESERVED_SLUGS)),\n displayName: checked(flag.displayName, parseDisplayName(displayName)),\n issuer: checked(flag.issuer, parseIssuer(issuer)),\n scopes: checked(flag.scopes, parseScopes(values.scopes)),\n },\n };\n}\n\n/**\n * The flags that restate a custom connection, for a command offered as text.\n *\n * Suggested commands are run verbatim, so a display name with a space or a\n * metacharacter in it must arrive as one argument. Nothing here is a\n * credential: the name, issuer and scopes are the developer's own settings.\n */\nexport function customFlagText(custom: CustomOidcInput, flag: CustomFlagNames): string {\n return flagText(\n {\n slug: custom.slug,\n displayName: custom.displayName,\n issuer: custom.issuer,\n scopes: custom.scopes.join(\" \"),\n },\n flag,\n );\n}\n\n/** The same for whichever settings were given, each as one shell word. */\nexport function flagText(values: CustomFlagValues, flag: CustomFlagNames): string {\n const word = (value: string) =>\n /^[A-Za-z0-9_@%+=:,./-]+$/.test(value) ? value : `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n return [\n [flag.slug, values.slug],\n [flag.displayName, values.displayName],\n [flag.issuer, values.issuer],\n [flag.scopes, values.scopes],\n ]\n .flatMap(([name, value]) => (value === undefined ? [] : [`${name} ${word(value)}`]))\n .join(\" \");\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 {\n type CatalogProviderId,\n type ConnectionEndpoints,\n idpProvider,\n parseIssuer,\n} from \"@zitadel/config/idp\";\n\nimport type { Asker } from \"../input\";\n\n/**\n * Ask where a provider lives, on a development run only.\n *\n * Someone working on the CLI runs it against a local stand-in constantly, and\n * before this the connection document had to be hand-edited afterwards and\n * re-applied. Someone who installed the CLI is configuring the real vendor and\n * must never meet the question — so it is gated on `developmentBuild`\n * (`isDevelopmentBuild()`, the explicit `ZITADEL_CLI_DEV` opt-in). A published\n * CLI never sets it, so the question stays out of its `--help` and prompts.\n *\n * Returns `undefined` for a normal run and for a scripted run, and the\n * catalog's own issuer is dropped when written, so an ordinary run produces\n * the document it would if none of this existed.\n */\nexport async function askConnectionEndpoints(options: {\n readonly provider: CatalogProviderId;\n readonly developmentBuild: boolean;\n /** How the question is asked: the running command's `input`. */\n readonly ask: Asker;\n}): Promise<ConnectionEndpoints | undefined> {\n const { provider, developmentBuild, ask } = options;\n if (!developmentBuild) {\n return undefined;\n }\n // Only the issuer is asked for, and only the issuer is written. The engine\n // accepts a connection that names every endpoint or none at all\n // (`requireAllOrNoEndpoints`): naming two of the four it needs -- it also\n // wants `jwks_uri`, and `userinfo_endpoint` unless id_token mapping is on --\n // is rejected as `idp.endpoints_partial`. Asking for four URLs to satisfy\n // that would be a worse question than asking for none, and a stand-in\n // serves its own discovery document just as the vendor does.\n // Validated against the connection contract rather than merely parsed: `new\n // URL` accepts `http://idp.internal:9100` and `file:///tmp/idp`, which would\n // be written to a connection that then fails on apply. Refusing at the prompt\n // puts the complaint where the value was typed.\n return {\n issuer: await ask({\n kind: \"text\",\n name: \"issuer\",\n message: \"Issuer\",\n parse: parseIssuer,\n initialValue: idpProvider(provider).issuer,\n }),\n };\n}\n","import type {\n ClientId,\n ClientIdVariable,\n ClientSecret,\n ClientSecretVariable,\n} from \"@zitadel/config/idp\";\nimport { consola } from \"consola\";\n\nimport { publicCliCommand } from \"../public-cli\";\nimport { reportWarning } from \"../warnings\";\n\n/**\n * Publishes one variable to the project.\n *\n * Injected rather than built here: this module decides what becomes of a\n * captured credential, and giving it an API client as well would tie that\n * decision to the whole platform surface. Both callers already hold a\n * connection to the project they just addressed.\n */\nexport type SecretPublisher = (\n name: ClientIdVariable | ClientSecretVariable,\n value: ClientId | ClientSecret,\n options: { readonly secret: boolean },\n) => Promise<void>;\n\n/** Whether a value reached the project's variables. */\nexport type PublishState = \"stored\" | \"deferred\" | \"failed\";\n\n/** Where a captured client secret ended up, for the command's summary. */\nexport type SecretOutcome = {\n readonly name: ClientSecretVariable;\n\n /**\n * The project's variables — the only place a credential is written. The\n * connection document references it as `${{ NAME }}` and the engine resolves\n * that from the project's variables and from nowhere else, so a local server\n * and Zitadel Cloud both need the value here.\n *\n * `deferred` when there was no value to publish or no project to publish to;\n * `failed` when the platform refused the call. Neither is fatal — the\n * connection is written either way and `variables set` publishes it later.\n */\n readonly published: PublishState;\n};\n\n/**\n * Publish a client secret to the project.\n *\n * Nothing is written to disk. The value is a credential, the project stores it\n * encrypted under the project's own key (ADR 029), and no runtime reads it\n * from the environment — the token exchange happens on the server. A copy in\n * `.env.local` would be a credential sitting in the working tree for the\n * convenience of nobody, and one `git add -A` away from being published.\n *\n * Passing no value publishes nothing and is not an error: the developer may\n * intend to publish it themselves.\n */\nexport async function storeClientSecret(options: {\n readonly name: ClientSecretVariable;\n readonly value?: ClientSecret;\n readonly publish?: SecretPublisher;\n}): Promise<SecretOutcome> {\n const { name, value, publish } = options;\n if (value === undefined) {\n return { name, published: \"deferred\" };\n }\n return { name, published: await publishSecret(publish, name, value) };\n}\n\n/**\n * Publish the connection's client id.\n *\n * An ordinary variable, not a secret: the id travels in the browser's\n * authorize URL, so it is public by construction and hiding it would only cost\n * the developer the ability to read back what was configured.\n */\nexport async function publishClientId(options: {\n readonly name: ClientIdVariable;\n readonly value: ClientId;\n readonly publish?: SecretPublisher;\n}): Promise<PublishState> {\n return publishSecret(options.publish, options.name, options.value, false);\n}\n\n/**\n * Send the value to the project, reporting a refusal instead of raising it.\n *\n * By the time this runs the connection document is already on disk and, in\n * `setup`, the whole project is provisioned. Failing the command there would\n * leave the developer with a half-written Project to clean up over something\n * one later command fixes, so the caller warns and points at `variables set`.\n */\nasync function publishSecret(\n publish: SecretPublisher | undefined,\n name: ClientIdVariable | ClientSecretVariable,\n value: ClientId | ClientSecret,\n secret = true,\n): Promise<PublishState> {\n if (publish === undefined) {\n return \"deferred\";\n }\n try {\n await publish(name, value, { secret });\n return \"stored\";\n } catch (error) {\n consola.debug(`Publishing ${name} to the project failed`, error);\n return \"failed\";\n }\n}\n\n/**\n * The `variables set` arguments that publish one credential to the project.\n *\n * `--project-level` is not optional: every `variables` command refuses with\n * \"Name the owner\" without an owner, so a command missing it would fail\n * before it reached the API and repair nothing. The project level is also the\n * right owner, because the engine resolves a connection's `${{ NAME }}` from\n * the project's own variables.\n */\nfunction republishArgsFor(\n name: ClientIdVariable | ClientSecretVariable,\n secret: boolean,\n): string[] {\n return [\"variables\", \"set\", name, \"--project-level\", ...(secret ? [\"--secret\"] : [])];\n}\n\n/**\n * The command that puts a credential the project never received where the\n * connection looks for it.\n *\n * Shared so the warning printed to a terminal and the `next_commands` a JSON\n * run reports cannot drift apart — a JSON run prints no warnings at all, so\n * that list is the only place the recovery step appears.\n */\nexport function republishCommand(\n name: ClientIdVariable | ClientSecretVariable,\n secret: boolean,\n cliVersion: string,\n): string {\n return publicCliCommand(republishArgsFor(name, secret).join(\" \"), cliVersion);\n}\n\n/** A credential, and whether the project ended up holding it. */\nexport type CredentialRecovery = {\n /** `undefined` when there is no such credential in this run at all. */\n readonly name: ClientIdVariable | ClientSecretVariable | undefined;\n readonly secret: boolean;\n readonly published: PublishState | undefined;\n};\n\n/**\n * The arguments that finish the job for every credential the project did not\n * receive — empty in the ordinary case, where both were stored.\n *\n * Argument lists rather than command strings, for a caller that also reports\n * them as `next_args`; {@link republishCommands} is built from this, so the\n * two forms list the same commands.\n *\n * @param credentials - Each credential of the run and what became of it.\n * @param extraArgs - Appended to every command, such as the `--cwd` the run\n * was given, so the recovery reaches the same Project.\n */\nexport function republishArgs(\n credentials: readonly CredentialRecovery[],\n extraArgs: readonly string[] = [],\n): string[][] {\n return credentials.flatMap(({ name, secret, published }) =>\n name !== undefined && published !== undefined && published !== \"stored\"\n ? [[...republishArgsFor(name, secret), ...extraArgs]]\n : [],\n );\n}\n\n/**\n * {@link republishArgs} as commands to run.\n *\n * Built for a run that prints nothing: with `--json` consola is disabled, so\n * the warnings above never appear and this list is the only place the recovery\n * step is stated.\n */\nexport function republishCommands(\n credentials: readonly CredentialRecovery[],\n cliVersion: string,\n): string[] {\n return republishArgs(credentials).map((args) => publicCliCommand(args.join(\" \"), cliVersion));\n}\n\n/**\n * Say whether the project received a credential, and how to retry when it did\n * not. Shared by both credentials, because the project is the destination that\n * decides whether sign-in works and the wording should not drift between them.\n *\n * `noValue` separates the two ways a publish can be deferred: nothing was\n * supplied, or there was no project to publish to. They read the same to the\n * code and call for different things from the developer.\n */\nfunction reportPublished(\n name: ClientIdVariable | ClientSecretVariable,\n state: PublishState,\n republish: string,\n noValue: boolean,\n): void {\n switch (state) {\n case \"stored\":\n consola.success(`Published ${name} to the project`);\n break;\n case \"deferred\":\n reportWarning(\n noValue\n ? `${name} has no value yet. Publish it with: ${republish}`\n : `${name} was not published to the project. Publish it with: ${republish}`,\n );\n break;\n case \"failed\":\n reportWarning(`${name} could not be published. Sign-in fails until it is: ${republish}`);\n break;\n }\n}\n\n/** Tell the developer what became of the secret. */\nexport function reportSecretOutcome(\n outcome: SecretOutcome,\n cliVersion: string,\n noValue: boolean,\n): void {\n reportPublished(\n outcome.name,\n outcome.published,\n republishCommand(outcome.name, true, cliVersion),\n noValue,\n );\n}\n\n/**\n * Tell the developer what became of the client id.\n *\n * A missing one is never \"no value yet\": the command refuses without a client\n * id, so the only way here is a project it could not reach.\n */\nexport function reportClientIdOutcome(\n name: ClientIdVariable,\n state: PublishState,\n cliVersion: string,\n): void {\n reportPublished(name, state, republishCommand(name, false, cliVersion), false);\n}\n","/**\n * Public surface for the user-schema domain. Every caller outside this\n * module imports from here (not from individual files), the same\n * discipline as `lib/flows/`.\n *\n * **Source of truth.** The wire shape lives in\n * `@zitadel/api/generated/model` (orval-generated from the\n * OpenAPI spec). Callers that need the type import `CreateSchemaBody`\n * from there directly; callers that need the runtime validator import\n * the matching Zod schema from\n * `@zitadel/api/generated/endpoints/zitadelNextGen.zod`. The default\n * schema/flow bodies the CLI scaffolds are composed in\n * `@zitadel/config/defaults` (`getDefaultHumanUserSchema`) — the single\n * source of field defaults.\n *\n * **Dependency rule.** No upward imports (`commands/`, `sync/`, etc.)\n * and no filesystem I/O. Reading and writing local files is the\n * caller's responsibility, served by `apps/cli/src/lib/json-dir.ts`\n * plus this module's {@link SCHEMAS_DIR} constant.\n */\n\n/**\n * Relative directory (from the project root) where local user-schema\n * files live. Owned here so callers (`commands/*`, `sync/syncers.ts`)\n * and tests share a single source of truth for the path; the runtime\n * never depends on it directly because `lib/user-schema` does not touch\n * the filesystem. The counterpart of `lib/flows`' `FLOWS_DIR`.\n */\nexport const SCHEMAS_DIR = \".zitadel/schemas\";\n","import { readdir, readFile } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { FLOWS_DIR } from \"../flows\";\nimport { SCHEMAS_DIR } from \"../user-schema\";\nimport { isErrno, ZitadelError } from \"../errors\";\nimport { isObject } from \"../json\";\n\n/** A user-schema file, with what the command has to show about it. */\nexport type SchemaFile = {\n /** File name without `.json`, which is what `--schema` takes. */\n readonly name: string;\n /** Project-relative path, for the summary. */\n readonly path: string;\n /** Property names the schema defines, used to build the claim mapping. */\n readonly properties: string[];\n /** Authentication methods the schema enables today, for the summary. */\n readonly methods: string[];\n readonly body: Record<string, unknown>;\n};\n\n/**\n * The authentication methods a schema document enables, sorted: every entry\n * under `x-auth-methods` whose `enabled` is `true`. What the login engine can\n * actually serve is narrower, and is the caller's to decide.\n */\nexport function methodsOf(body: Record<string, unknown>): string[] {\n const methods = body[\"x-auth-methods\"];\n if (!isObject(methods)) {\n return [];\n }\n return Object.entries(methods)\n .filter(([, value]) => isObject(value) && value.enabled === true)\n .map(([name]) => name)\n .sort();\n}\n\n/**\n * Read the Project's user schemas.\n *\n * READMEs sit in the same directory, so only `.json` files count. A schema\n * that cannot be parsed stops the command: enabling a provider edits these\n * files, and editing one we could not read is how a working setup gets\n * corrupted.\n */\nexport async function readSchemaFiles(cwd: string): Promise<SchemaFile[]> {\n const dir = join(cwd, SCHEMAS_DIR);\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch (error) {\n // Only an absent directory means the Project has none. A permission or\n // I/O failure reported as \"no user schema\" would send the developer\n // looking for a missing file that is sitting right there.\n if (isErrno(error, \"ENOENT\")) {\n return [];\n }\n throw error;\n }\n const files: SchemaFile[] = [];\n for (const entry of entries.filter((e) => e.endsWith(\".json\")).sort()) {\n const path = `${SCHEMAS_DIR}/${entry}`;\n let body: unknown;\n try {\n body = JSON.parse(await readFile(join(dir, entry), \"utf8\"));\n } catch (error) {\n throw new ZitadelError(\"E_VALIDATION\", `${path} is not valid JSON`, {\n hint: \"Fix the file, then run the command again.\",\n details: { file: path, parse_error: String(error) },\n });\n }\n if (!isObject(body)) {\n throw new ZitadelError(\"E_VALIDATION\", `${path} does not contain a JSON object`, {\n details: { file: path },\n });\n }\n files.push({\n name: basename(entry, \".json\"),\n path,\n properties: isObject(body.properties) ? Object.keys(body.properties) : [],\n methods: methodsOf(body),\n body,\n });\n }\n return files;\n}\n\n/**\n * Pick the schema to change.\n *\n * One schema is the common case and is chosen without asking. Several is\n * ambiguous, and picking silently would edit the wrong user type, so the name\n * has to be given — the interactive picker is the caller's, because this\n * module does not prompt.\n */\nexport function selectSchema(files: readonly SchemaFile[], requested?: string): SchemaFile {\n if (files.length === 0) {\n throw new ZitadelError(\"E_NOT_FOUND\", `This Project has no user schema under ${SCHEMAS_DIR}`, {\n hint: \"Run `zitadel setup` first.\",\n });\n }\n if (requested !== undefined) {\n const wanted = requested.endsWith(\".json\") ? basename(requested, \".json\") : requested;\n const match = files.find((file) => file.name === wanted);\n if (match === undefined) {\n throw new ZitadelError(\"E_NOT_FOUND\", `This Project has no user schema named ${wanted}`, {\n hint: `Known schemas: ${files.map((f) => f.name).join(\", \")}`,\n details: { requested: wanted, known: files.map((f) => f.name) },\n });\n }\n return match;\n }\n const [only, ...rest] = files;\n if (rest.length > 0 || only === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"This Project has more than one user schema\", {\n hint: `Name the one to change with --schema. Known schemas: ${files.map((f) => f.name).join(\", \")}`,\n details: { known: files.map((f) => f.name) },\n });\n }\n return only;\n}\n\n/** The login flow files a Project holds, with the names to report them by. */\nexport type FlowFile = {\n readonly name: string;\n readonly path: string;\n readonly body: Record<string, unknown>;\n};\n\n/**\n * Read the Project's flow files.\n *\n * A flow names the schema it runs against, so the caller can pick the ones\n * belonging to the schema being changed rather than editing every flow.\n */\nexport async function readFlowFiles(cwd: string): Promise<FlowFile[]> {\n const dir = join(cwd, FLOWS_DIR);\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch (error) {\n // Only an absent directory means the Project has none. A permission or\n // I/O failure reported as \"no user schema\" would send the developer\n // looking for a missing file that is sitting right there.\n if (isErrno(error, \"ENOENT\")) {\n return [];\n }\n throw error;\n }\n const files: FlowFile[] = [];\n for (const entry of entries.filter((e) => e.endsWith(\".json\")).sort()) {\n const path = `${FLOWS_DIR}/${entry}`;\n let body: unknown;\n try {\n body = JSON.parse(await readFile(join(dir, entry), \"utf8\"));\n } catch (error) {\n throw new ZitadelError(\"E_VALIDATION\", `${path} is not valid JSON`, {\n hint: \"Fix the file, then run the command again.\",\n details: { file: path, parse_error: String(error) },\n });\n }\n if (!isObject(body)) {\n throw new ZitadelError(\"E_VALIDATION\", `${path} does not contain a JSON object`, {\n details: { file: path },\n });\n }\n files.push({ name: basename(entry, \".json\"), path, body });\n }\n return files;\n}\n\n/** The authentication methods a schema document enables. */\nexport type AuthMethods = { password: boolean; passkey: boolean };\n\n/**\n * Read the enabled methods straight off a schema document.\n *\n * Setup composes its schema in memory and never reads it back from disk, so\n * it needs this before a {@link SchemaFile} exists.\n */\nexport function authMethods(body: Record<string, unknown>): AuthMethods {\n const enabled = methodsOf(body);\n return { password: enabled.includes(\"password\"), passkey: enabled.includes(\"passkey\") };\n}\n\n/** Whether a schema file enables a given authentication method. */\nexport function enabledMethods(schema: SchemaFile): AuthMethods {\n return {\n password: schema.methods.includes(\"password\"),\n passkey: schema.methods.includes(\"passkey\"),\n };\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. `plan`\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 plan` 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\n/**\n * Remove an entry from the state file. No-op if the key is absent.\n */\nexport async function removeFromState(cwd: string, key: string): Promise<void> {\n const current = await readState(cwd);\n const { [key]: _removed, ...rest } = current.resources;\n const updated: ZitadelState = { ...current, resources: rest };\n await writeFile(join(cwd, \".zitadel/state.json\"), JSON.stringify(updated, null, 2));\n}\n\n/**\n * Track a resource under a new path and stop tracking the old one, in one\n * write: a process that stops between two writes would leave either both paths\n * or neither, and a leftover old path comes back as a kept removal that, if\n * restored, leaves two tracked files for one resource.\n */\nexport async function moveInState(\n cwd: string,\n from: string,\n to: string,\n entry: ResourceEntry,\n): Promise<void> {\n const current = await readState(cwd);\n const { [from]: _old, ...rest } = current.resources;\n const updated: ZitadelState = {\n ...current,\n resources: { ...rest, [to]: { ...current.resources[to], ...entry } },\n };\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 `plan` and `apply` resolve a flow's schema in\n // (`pinnedSchemaPath` in lib/sync/sso-validation.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. `apply` records the\n * replaced id before it re-pins the flows, so a flow left behind by an\n * interrupted run still names it, and must still count as this schema's flow.\n * Absent before the first `apply`, 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 and run `zitadel apply`, then run this command again.\",\n details: { file: \".zitadel/state.json\" },\n },\n );\n }\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, portableCommands } from \"../public-cli\";\nimport { flowsForSchema } from \"../schema-flows\";\nimport { reportWarning } from \"../warnings\";\nimport { BaseCommand } from \"./base\";\nimport { nonBlankString } from \"./flags\";\nimport type { JsonEnvelope } from \"./types\";\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 `plan` and `apply` publish it\n * like any configuration change.\n */\nexport abstract class AuthMethodCommand extends BaseCommand {\n static override baseFlags = {\n ...BaseCommand.baseFlags,\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 `apply`.\n * @param options.preflight - Checks that must answer before the schema is\n * read, with whatever they read handed back as `preflight`.\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, { resolveServer: options.resolveServer ?? false });\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 `variables delete`'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: portableCommands([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 `plan` and `apply` then\n * publish.\n * @param cwdArgs - `--cwd` for `plan` and `apply`, 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: string[]; next_args: string[][] } {\n const args = [\n ...leading,\n ...(changed\n ? [\n [\"plan\", ...cwdArgs],\n [\"apply\", ...cwdArgs],\n ]\n : []),\n ];\n return { next_commands: portableCommands(args, this.meta.cliVersion), next_args: args };\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 `plan` 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: portableCommands(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\";\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 BaseCommand {\n static override group = CommandGroups.resources;\n static override groupOrder = 1;\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 = \"zitadel api ls --json\";\n const tag = await this.input({\n kind: \"select\",\n name: \"operation\",\n message: \"Which part of the API?\",\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?\",\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: name,\n retry: `zitadel api ${target.operation.id} ${missing.map((each) => `<${each}>`).join(\" \")}`,\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/** 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.resources;\n static override groupOrder = 1;\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","/**\n * Local file references in `.zitadel/` resource files.\n *\n * Wherever the OpenAPI YAML marks a string field `x-local: file`, the\n * generated editor meta-schema accepts `{ \"$file\": \"<path>\" }` in its place,\n * so a long value such as a login template lives in its own file instead of a\n * JSON-escaped string. The API never sees a reference: before upload every\n * one is replaced by the referenced file's content.\n *\n * Resolution is generic. Nothing here knows which fields may carry a\n * reference; the Zod gate and the editor schema decide that.\n *\n * Paths are relative to the directory of the resource file that holds them\n * and must stay inside the project, because upload reads them. The check\n * applies to the real target: a symlink, or a symlinked directory on the way,\n * that leads outside the project is refused.\n */\nimport { lstatSync, readFileSync, realpathSync } from \"node:fs\";\nimport { basename, dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\n\nimport { ZitadelError } from \"./errors\";\n\nexport const FILE_REFERENCE_KEY = \"$file\";\n\nexport type FileReference = { readonly [FILE_REFERENCE_KEY]: string };\n\n/**\n * Where references resolve: the project root, and the directory (relative to\n * it) of the resource file holding them.\n */\nexport type FileReferenceContext = { readonly cwd: string; readonly baseDir: string };\n\n/** The keys and indexes that lead from a document's root to one value. */\ntype Path = ReadonlyArray<string | number>;\n\nconst omittedReference = Symbol(\"omittedReference\");\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nfunction isErrno(error: unknown, code: string): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && error.code === code;\n}\n\n/** A file's content, or undefined when it is absent. */\nfunction readIfPresent(path: string): string | undefined {\n try {\n return readFileSync(path, \"utf8\");\n } catch (error) {\n if (isErrno(error, \"ENOENT\") || isErrno(error, \"ENOTDIR\")) {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction readFileReference(\n path: string,\n ref: string,\n options: { readonly onMissing: \"throw\" | \"omit\" },\n): string | typeof omittedReference {\n let content: string | undefined;\n try {\n content = readIfPresent(path);\n } catch {\n throw new ZitadelError(\"E_VALIDATION\", `$file ${JSON.stringify(ref)} cannot be read`, {\n hint: \"Create the referenced file or fix the path.\",\n });\n }\n if (content !== undefined) {\n return content;\n }\n if (options.onMissing === \"omit\") {\n return omittedReference;\n }\n throw new ZitadelError(\"E_VALIDATION\", `$file ${JSON.stringify(ref)} cannot be read`, {\n hint: \"Create the referenced file or fix the path.\",\n });\n}\n\n/** Whether `path` is `root` itself or lies beneath it. */\nfunction isWithin(root: string, path: string): boolean {\n const rel = relative(root, path);\n return !(rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel));\n}\n\n/** Whether `path` itself is a symlink, without following it. */\nfunction isSymlink(path: string): boolean {\n try {\n return lstatSync(path).isSymbolicLink();\n } catch {\n return false;\n }\n}\n\n/**\n * `path` with every symlink resolved, symlinked parent directories included,\n * even when its last segments do not exist yet. Undefined when a segment is a\n * symlink that resolves nowhere, since what it names could be anywhere.\n */\nfunction realTarget(path: string): string | undefined {\n const missing: string[] = [];\n let current = path;\n for (;;) {\n try {\n return join(realpathSync(current), ...missing);\n } catch (error) {\n if (!isErrno(error, \"ENOENT\") && !isErrno(error, \"ENOTDIR\")) {\n throw error;\n }\n if (isSymlink(current)) {\n return undefined;\n }\n const parent = dirname(current);\n if (parent === current) {\n return path;\n }\n missing.unshift(basename(current));\n current = parent;\n }\n }\n}\n\n/** A `{ \"$file\": \"<path>\" }` object and nothing else. */\nexport function isFileReference(value: unknown): value is FileReference {\n return (\n isPlainObject(value) &&\n Object.keys(value).length === 1 &&\n typeof value[FILE_REFERENCE_KEY] === \"string\"\n );\n}\n\n/**\n * The absolute path a reference points at. E_VALIDATION when the path, or the\n * real target behind any symlink on the way, leaves the project.\n */\nexport function resolveFileReference(context: FileReferenceContext, ref: string): string {\n const absolute = resolve(context.cwd, context.baseDir, ref);\n const root = realTarget(resolve(context.cwd));\n const target = realTarget(absolute);\n const inside =\n isWithin(resolve(context.cwd), absolute) &&\n root !== undefined &&\n target !== undefined &&\n isWithin(root, target);\n if (!inside) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `$file ${JSON.stringify(ref)} points outside the project`,\n {\n hint:\n \"Keep referenced files inside the project, next to the file that references them; \" +\n \"a symlink on the way must resolve inside the project too.\",\n },\n );\n }\n return absolute;\n}\n\n/** Every reference in `document`, with the path that leads to it. */\nexport function findFileReferences(document: unknown): Array<{ path: Path; ref: string }> {\n const found: Array<{ path: Path; ref: string }> = [];\n const walk = (node: unknown, path: Path): void => {\n if (isFileReference(node)) {\n found.push({ path, ref: node[FILE_REFERENCE_KEY] });\n } else if (Array.isArray(node)) {\n node.forEach((item, index) => {\n walk(item, [...path, index]);\n });\n } else if (isPlainObject(node)) {\n for (const [key, value] of Object.entries(node)) {\n walk(value, [...path, key]);\n }\n }\n };\n walk(document, []);\n return found;\n}\n\n/**\n * Returns a copy of `document` with every reference replaced by the content\n * of the file it points at. With `onMissing: \"throw\"` an unreadable file is\n * E_VALIDATION, which is what plan's gate wants; with `\"omit\"` the value is\n * dropped instead (the key from an object, the element from an array), so\n * normalizing and hashing stay total. A path leaving the project is always\n * E_VALIDATION.\n */\nexport function inlineFileReferences<T>(\n document: T,\n context: FileReferenceContext,\n options: { readonly onMissing: \"throw\" | \"omit\" },\n): T {\n const inline = (node: unknown): unknown => {\n if (isFileReference(node)) {\n const ref = node[FILE_REFERENCE_KEY];\n return readFileReference(resolveFileReference(context, ref), ref, options);\n }\n if (Array.isArray(node)) {\n return node.map(inline).filter((item) => item !== omittedReference);\n }\n if (isPlainObject(node)) {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n const inlined = inline(value);\n if (inlined !== omittedReference) {\n out[key] = inlined;\n }\n }\n return out;\n }\n return node;\n };\n return inline(document) as T;\n}\n","import { ZitadelError } from \"../errors\";\nimport { type FileReferenceContext, inlineFileReferences } from \"../local-files\";\n\n/**\n * Relative directory (from the project root) where local branding files live:\n * the `branding.json` descriptor plus the sibling `.liquid` template it\n * references. Owned here so commands, syncers, and tests share one source of\n * truth; only `*.json` files are sync-discovered, the template rides along as\n * a `$file` reference in `liquid_template`.\n */\nexport const BRANDING_DIR = \".zitadel/branding\";\n\n/**\n * The key descriptors used before `$file` references. It is still recognised\n * so plan can say how to migrate instead of reporting an unknown key.\n */\nconst LEGACY_TEMPLATE_FILE_KEY = \"liquid_template_file\";\n\n/**\n * References in a descriptor resolve against its directory; all descriptors\n * live flat in {@link BRANDING_DIR}.\n */\nconst referenceContext = (cwd: string): FileReferenceContext => ({ cwd, baseDir: BRANDING_DIR });\n\n/** E_VALIDATION with a migration hint when a descriptor still carries `liquid_template_file`. */\nexport function assertNoLegacyTemplateKey(data: object): void {\n const legacy = (data as Record<string, unknown>)[LEGACY_TEMPLATE_FILE_KEY];\n if (legacy === undefined) {\n return;\n }\n const path = typeof legacy === \"string\" ? legacy : \"./login.liquid\";\n throw new ZitadelError(\"E_VALIDATION\", `${LEGACY_TEMPLATE_FILE_KEY} is no longer supported`, {\n hint: `Replace it with \"liquid_template\": { \"$file\": ${JSON.stringify(path)} }.`,\n });\n}\n\n/**\n * Returns the template string a descriptor carries, inline or behind a\n * `$file` reference. Undefined when it has none (a legal descriptor that only\n * sets layout or asset URLs); E_VALIDATION when a reference cannot be read.\n */\nexport function readDescriptorTemplate(cwd: string, data: object): string | undefined {\n const { liquid_template } = inlineFileReferences(\n data as { liquid_template?: unknown },\n referenceContext(cwd),\n { onMissing: \"throw\" },\n );\n return typeof liquid_template === \"string\" ? liquid_template : undefined;\n}\n\n/**\n * Converts a local descriptor to the wire body of `POST /branding`: strips the\n * editor `$schema` affordance and inlines every `$file` reference. Non-throwing\n * on an unreadable file (the field is left out) so normalizing and hashing stay\n * total; `validate` reports that case with a hint before any planning happens.\n */\nexport function toBrandingWireBody(cwd: string, data: object): object {\n const { $schema, ...rest } = data as { $schema?: unknown };\n void $schema;\n return inlineFileReferences(rest, referenceContext(cwd), { onMissing: \"omit\" });\n}\n","/**\n * One row in the local state file: the platform `id` returned at create time\n * and the content `hash` last successfully synced. Both fields are optional so\n * the engine can recover from partial writes. For revisioned resources,\n * `previousId` records the revision the current `id` superseded — the planner\n * uses it to recover flow re-pins when a run died between publishing the\n * revision and rewriting the pinned flows.\n */\nexport type ResourceEntry = {\n id?: string;\n hash?: string;\n name?: string;\n status?: string;\n previousId?: string;\n};\n\n/**\n * Ownership class of one scaffolded app file, recorded in the scaffold\n * manifest. `infrastructure` files (the request boundary, the provider, the\n * custom-elements declarations) are load-bearing for the auth integration —\n * a missing one fails `doctor`. `presentation` files (the generated pages)\n * are released to the user as a starting point — a missing one only warns.\n */\nexport type ScaffoldFileClass = \"infrastructure\" | \"presentation\";\n\n/**\n * Embedding posture of the scaffolded auth/profile pages (ADR 044). `page`\n * pins the widgets to their full-page chrome — the fresh-scaffold default.\n * `widget` embeds the cards in a layout-neutral wrapper inside the app's own\n * shell — the default when setup meets a pre-existing route-based app (Next,\n * Nuxt). Recorded in the scaffold manifest so `doctor --fix` restores the\n * posture setup actually emitted; absence restores `page` (every scaffold\n * before this record existed was full-page).\n */\nexport type ScaffoldPosture = \"page\" | \"widget\";\n\n/**\n * One scaffolded app file as recorded at `zitadel setup` time: the sha256 of\n * the bytes the CLI wrote (or found already matching), plus its ownership\n * class. Keys of the containing record are project-root-relative posix paths.\n */\nexport type ScaffoldFileEntry = {\n hash: string;\n class: ScaffoldFileClass;\n};\n\n/**\n * The scaffold manifest: which app files `zitadel setup` actually wrote, so\n * `doctor` can distinguish missing/edited/adopted files without guessing from\n * current templates. `scaffolded_framework` records whether setup created the\n * app skeleton itself (fresh directory) — repair needs it to know whether the\n * framework home page is CLI-managed. `dev_port` preserves the issuer port for\n * context reconstruction. `posture` records the emitted embedding posture of\n * the auth/profile pages (ADR 044) so restoration reproduces it. Absent on\n * apps scaffolded by older CLI versions; consumers fall back to\n * template-derived expectations.\n */\nexport type ScaffoldManifest = {\n files: Record<string, ScaffoldFileEntry>;\n scaffolded_framework?: boolean;\n dev_port?: number;\n posture?: ScaffoldPosture;\n};\n\n/**\n * The persisted contents of `.zitadel/state.json`. Maps each managed file path\n * (relative to the project root) to its sync entry, plus the framework id\n * captured during `zitadel setup` and, since the manifest was introduced, the\n * scaffold manifest of generated app files.\n */\nexport type ZitadelState = {\n framework: string;\n resources: Record<string, ResourceEntry>;\n scaffold?: ScaffoldManifest;\n};\n\n/**\n * The contract each per-resource adapter implements. `directory` is the\n * project-root-relative path the sync loop scans; `mutable` controls whether\n * file-content changes trigger an update or get skipped; `revisioned` opts\n * into \"publish a new immutable revision on hash change\" instead of update\n * or skip. `revisioned` implies immutability of the previous state on the\n * platform; the previous row keeps existing under a stable id (see ADR 009).\n * Concrete syncers call the orval-generated operations directly; bearer auth\n * and base URL come from `@zitadel/api/runtime/{auth,base-url}` module-globals\n * the command layer sets at boot.\n */\n/**\n * A fetch failure the planner must not degrade into \"no diff\".\n *\n * Fetching old content is best effort: a resource the server cannot hand back\n * just plans without a before/after, which is right for a timeout, a 404, or an\n * endpoint that does not exist yet. It is wrong for a refusal that exists to\n * protect the developer — a syncer that stopped because the response would have\n * put a credential in the preview must stop the plan, not quietly lose the\n * diff and leave the server's behaviour unreported.\n *\n * Wrapping rather than flagging: the planner cannot otherwise tell this apart\n * from the ordinary failures it is right to swallow, and a `ZitadelError` alone\n * does not say which it is.\n */\nexport class FatalFetchError extends Error {\n readonly reason: Error;\n\n constructor(reason: Error) {\n super(reason.message);\n this.name = \"FatalFetchError\";\n this.reason = reason;\n }\n}\n\nexport interface ResourceSyncer {\n readonly kind: string;\n readonly directory: string;\n readonly mutable: boolean;\n readonly revisioned: boolean;\n /**\n * When set, this syncer owns exactly one descriptor file with this\n * basename inside `directory`, and the scan fails (`E_VALIDATION`) on any\n * other `*.json` found there. For a revisioned singleton like branding, a\n * stray descriptor copy would otherwise be treated as one more resource\n * and published as its own revision — last upload wins the live slot.\n */\n readonly singletonFile?: string;\n /**\n * Assert that a single on-disk file body is valid for this resource.\n * Throws `E_VALIDATION` (a `ZitadelError`) on the first invalid input.\n * The sync engine calls this for every file it reads, so a malformed\n * schema or flow fails the run before any platform mutation — `plan`\n * and `apply` both go through here. `path` is the file's project-relative\n * path, for messages that name it.\n */\n validate(data: object, path?: string): void;\n /**\n * Create the resource on the platform, answering with its id. What the\n * server stored is not returned: the sync loop never writes it back, and\n * the local file stays as written.\n */\n create(data: object): Promise<{ id: string }>;\n /**\n * Apply the local body to the tracked resource.\n *\n * `id` in the result is the resource the write actually landed on, for a\n * syncer whose write is addressed by something in the document rather than by\n * the tracked id — a connection is addressed by its `slug`, so editing that\n * slug names a different connection and the server answers with a different\n * id. Reporting it keeps state describing what the server did rather than\n * what the caller assumed. Omit it when the write cannot change identity.\n */\n update(id: string, data: object): Promise<{ id?: string }>;\n delete(id: string): Promise<void>;\n /**\n * `\"unsupported\"` when the platform cannot delete this resource yet. A file\n * removed locally is then reported by `plan` and `apply` and never sent, and\n * its state entry stays so the report repeats until the file is restored.\n */\n readonly deletion?: \"unsupported\";\n /**\n * Checks that need the platform, run for every create and update before any\n * mutation, given the file `path`. It answers with the id of the resource a create would revise, when one already holds its identity, so the planner can tell a moved file from a new one. `old` is the stored body of an update (null for a create, or\n * when it could not be read). Throws to stop the plan.\n */\n /** What names a stored resource, for matching a removed file to the resource it kept. */\n identityOf?(stored: object): string | undefined;\n preflight?(\n path: string,\n data: object,\n old: object | null,\n ): Promise<{ id: string; definition: object } | undefined>;\n fetch?(id: string): Promise<object>;\n /**\n * Reduce a body to its canonical comparison form: strip server-echoed\n * noise (empty `audience`) and spelled-out meta-schema defaults\n * (`x-audit`, a connection's `pkce_enabled` et al) so hashing and diff\n * rendering treat semantically identical bodies as identical, and a field\n * the file leaves out reads as the server's default rather than as a\n * change — the server applies those defaults itself. Comparison only:\n * uploads send the file as written.\n */\n normalize?(data: object): object;\n}\n\n/**\n * Counts of the non-`skip` actions in a sync plan, used for the `plan` /\n * `apply --dry-run` JSON payload. Produced by `summarizePlan`.\n */\nexport type SyncPlanSummary = {\n creates: number;\n updates: number;\n revisions: number;\n deletes: number;\n /** Files that moved: the same resource, under a new file name. */\n moves: number;\n /** Removed files whose resource cannot be deleted yet; not part of `total`. */\n unsupported_deletions: number;\n total: number;\n};\n\n/**\n * One unit of work in a sync plan. The engine emits exactly one `SyncAction`\n * per resource file (or per state-only entry, for deletes). Discriminated by\n * `kind`; `oldContent` carries the platform's current value for diff rendering.\n *\n * `revise` is the new-immutable-revision path used by revisioned syncers. The\n * platform assigns a new id per revision; the previous row keeps validating\n * anything it was pinned to. `affectedPaths` names the local files that are\n * currently pinned to `previousId` and would need re-pinning to adopt the\n * new revision (see `.zitadel/flows/README.md`).\n */\n/**\n * Present on flow create/update/revise actions whose `user_schema` pins a\n * schema revision that is superseded in the same run (a pending `revise`) or\n * was superseded by an interrupted earlier run. The executor rewrites\n * `user_schema` to the new revision id — `newId` when the revision already\n * exists (crash recovery), otherwise the id minted by this run's revise.\n */\nexport type FlowRepin = { previousId: string; schemaPath: string; newId?: string };\n\n/**\n * A non-blocking plan-time finding: a flow-validation issue of severity\n * `warning` (`@zitadel/config/validate`), or a branding asset URL the\n * probe could not fetch (`asset-probe.ts`). Rendered as `# warning:`\n * comment lines in the plan and `consola.warn`ed during apply; never\n * fails the run.\n */\nexport type SyncActionWarning = { rule: string; message: string };\n\nexport type SyncAction =\n | {\n kind: \"create\";\n path: string;\n syncer: ResourceSyncer;\n content: object;\n hash: string;\n repin?: FlowRepin;\n warnings?: ReadonlyArray<SyncActionWarning>;\n /**\n * The removed file this one replaces: the platform already holds the\n * resource, so the write revises it rather than creating another.\n */\n movedFrom?: string;\n /** For a move: what the platform stores, so the plan can show what changes. */\n oldContent?: object;\n }\n | {\n kind: \"update\";\n path: string;\n syncer: ResourceSyncer;\n id: string;\n content: object;\n hash: string;\n oldContent: object | null;\n repin?: FlowRepin;\n warnings?: ReadonlyArray<SyncActionWarning>;\n }\n | {\n kind: \"revise\";\n path: string;\n syncer: ResourceSyncer;\n content: object;\n hash: string;\n previousId: string;\n oldContent: object | null;\n affectedPaths: ReadonlyArray<string>;\n repin?: FlowRepin;\n warnings?: ReadonlyArray<SyncActionWarning>;\n }\n | { kind: \"delete\"; path: string; syncer: ResourceSyncer; id: string; oldContent: object | null }\n | { kind: \"skip\"; path: string; reason: \"immutable\" | \"no-change\" }\n | {\n kind: \"skip\";\n path: string;\n reason: \"unsupported-deletion\";\n syncer: ResourceSyncer;\n id: string;\n };\n","import type {\n CreateBranding201,\n CreateBrandingBody,\n CreateFlowDefinition201,\n CreateFlowDefinitionBodyFlowDefinition,\n CreateIdpBodyIdp,\n CreateSchemaBody,\n} from \"@zitadel/api/generated/model\";\n\nimport type { ZitadelClient } from \"@zitadel/api/client\";\nimport { DEFAULT_FLOW_SCHEMA_URI } from \"@zitadel/config/defaults\";\nimport { isVariableReference, missingEndpoints, referencedVariable } from \"@zitadel/config/idp\";\nimport {\n normalizeFlowBody,\n normalizeIdpBody,\n normalizeSchemaBody,\n} from \"@zitadel/config/normalize\";\nimport {\n brandingConfigSchema,\n flowConfigSchema,\n idpConnectionConfigSchema,\n schemaConfigSchema,\n} from \"@zitadel/config/schemas\";\nimport { validateLoginTemplate } from \"@zitadel/config/template\";\n\nimport {\n BRANDING_DIR,\n assertNoLegacyTemplateKey,\n readDescriptorTemplate,\n toBrandingWireBody,\n} from \"../branding\";\nimport { FLOWS_DIR, flowEnvRefs } from \"../flows\";\nimport { IDPS_DIR, refuseResolvedSecret } from \"../idp\";\nimport { SCHEMAS_DIR } from \"../user-schema\";\nimport { primaryValues } from \"../variables\";\nimport { ZitadelError } from \"../errors\";\nimport { FatalFetchError } from \"./types.js\";\nimport type { ResourceSyncer } from \"./types.js\";\n\nexport type { ResourceSyncer } from \"./types.js\";\n\n/** Runtime environment lookup used to resolve `${VAR}` / `*_env` references. */\ntype EnvLookup = Record<string, string | undefined>;\n\n/**\n * Build the syncer list with the context every syncer needs: the\n * `project_id` flow creates carry, and the runtime `env` against which\n * each file's `${VAR}` / `*_env` references are checked. Callers (apply /\n * plan / setup) read `project_id` from `.zitadel/secret` and pass the\n * process environment. The returned array is treated as read-only by the\n * sync loop.\n */\nexport function makeSyncers(opts: {\n client: ZitadelClient;\n projectId: string;\n env: EnvLookup;\n /**\n * Project root. The branding syncer resolves `$file` references against it\n * when inlining templates for hashing and upload.\n */\n cwd: string;\n}): readonly [SchemaSyncer, IdpConnectionSyncer, FlowDefinitionSyncer, BrandingSyncer] {\n return [\n new SchemaSyncer(opts.client, opts.projectId, opts.env),\n // Before flows: a flow step naming a connection slug is only valid once\n // that connection exists on the platform.\n new IdpConnectionSyncer(opts.client, opts.projectId),\n new FlowDefinitionSyncer(opts.client, opts.projectId, opts.env),\n new BrandingSyncer(opts.client, opts.projectId, opts.env, opts.cwd),\n ];\n}\n\n/** The value a Zod issue path points at, or `undefined` when it is absent. */\nfunction valueAt(data: object, path: ReadonlyArray<PropertyKey>): unknown {\n let current: unknown = data;\n for (const key of path) {\n if (typeof current !== \"object\" || current === null) {\n return undefined;\n }\n current = (current as Record<PropertyKey, unknown>)[key];\n }\n return current;\n}\n\n/**\n * Assert that every env var a resource references — `${VAR}` placeholders and\n * the `*_env` convention — is present in `env`, throwing `E_VALIDATION` listing\n * the missing names. Shared by every syncer so the check is identical for\n * schemas and flows, and runs in the sync engine before any platform call.\n */\nfunction assertEnvRefs(data: object, env: EnvLookup): void {\n const missing = flowEnvRefs(data).filter((name) => !env[name]);\n if (missing.length > 0) {\n throw new ZitadelError(\"E_VALIDATION\", `Missing environment variables: ${missing.join(\", \")}`);\n }\n}\n\ntype ConnectionBody = {\n slug?: string;\n protocol?: string;\n subject_claim?: string;\n oidc?: {\n issuer?: string;\n client_id?: string;\n client_secret?: string;\n };\n};\n\n/** The fields that make a connection the one its linked users came through. */\nconst IDENTITY_FIELDS = [\n { name: \"slug\", read: (body: ConnectionBody) => body.slug },\n { name: \"protocol\", read: (body: ConnectionBody) => body.protocol },\n { name: \"oidc.issuer\", read: (body: ConnectionBody) => body.oidc?.issuer },\n {\n name: \"subject_claim\",\n // The engine reads an absent subject claim as `sub`, so a file that\n // leaves it out and one that says `sub` are the same connection.\n read: (body: ConnectionBody) => body.subject_claim ?? \"sub\",\n },\n] as const;\n\n/**\n * Syncs `.zitadel/idps/*.json`, one identity provider connection per file.\n *\n * `mutable` with `revisioned: false`: the connection keeps one id for life and\n * the server files each edit as a revision beneath it, so an edit is an update\n * here rather than a new resource, and nothing that references the slug has to\n * be re-pinned.\n *\n * Deletion is not supported yet (#1013): what should happen to users already\n * linked to a connection is undesigned, so a removed file is reported by plan\n * and apply and no deletion is sent.\n *\n * `fetch` reads the stored connection so an update plans with a field-level\n * diff, as every other resource does. It refuses a body whose `client_secret`\n * is a value rather than a `${{ NAME }}` reference: previews must never print\n * a credential (area 4), and the CLI's own `validate` makes a literal secret\n * unuploadable, so one coming back from a read means the server resolved it\n * and the plan must stop rather than render it.\n */\nclass IdpConnectionSyncer implements ResourceSyncer {\n readonly kind = \"idp\";\n readonly directory = IDPS_DIR;\n readonly mutable = true;\n readonly revisioned = false;\n readonly deletion = \"unsupported\";\n /**\n * The server stores a connection with the meta-schema's defaults spelled\n * out (`pkce_enabled`, `token_endpoint_auth_method`, `id_token_mapping`), so\n * the file that leaves them to the server and the stored copy compare equal\n * only with them stripped.\n */\n readonly normalize = normalizeIdpBody;\n\n private readonly client: ZitadelClient;\n private readonly projectId: string;\n private variables: Promise<ReadonlyMap<string, boolean>> | undefined;\n\n constructor(client: ZitadelClient, projectId: string) {\n this.client = client;\n this.projectId = projectId;\n }\n\n /**\n * Parse against the generated `CreateIdpBody.idp` Zod, the orval-emitted\n * equivalent of `idp-connection.json`. A literal `client_secret` fails that\n * pattern, so it is caught here and named plainly: it is the one mistake\n * that would publish a credential.\n *\n * A valid document is then held to the server's endpoint rule: an `oidc`\n * block names no endpoint or every one it needs. The server refuses anything\n * in between, so it is refused here, before an apply could stop part-way.\n */\n validate(data: object, path = \"Connection file\"): void {\n const result = idpConnectionConfigSchema.safeParse(data);\n if (result.success) {\n const missing = missingEndpoints((data as ConnectionBody).oidc);\n if (missing.length > 0) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${path}: oidc names some endpoints but not ${missing.join(\", \")}`,\n {\n hint:\n \"Name every endpoint (authorization_endpoint, jwks_uri, token_endpoint, and \" +\n \"userinfo_endpoint unless id_token_mapping is true), or none to read them from \" +\n \"the issuer's discovery document.\",\n details: { file: path, missing },\n },\n );\n }\n return;\n }\n // Only a stored value that is not a reference is the mistake this names.\n // A missing or wrongly-typed `client_secret` fails at the same path, and\n // telling someone to replace a value with a reference when the field is\n // not there sends them looking for something that does not exist.\n const literalSecret = result.error.issues.some((issue) => {\n if (issue.path.length <= 1 || issue.path[issue.path.length - 1] !== \"client_secret\") {\n return false;\n }\n const stored = valueAt(data, issue.path);\n return typeof stored === \"string\" && !isVariableReference(stored);\n });\n throw new ZitadelError(\n \"E_VALIDATION\",\n literalSecret\n ? \"Connection file's client_secret must reference a variable, not hold a value\"\n : \"Connection file is not a valid identity provider connection\",\n {\n hint: literalSecret\n ? 'Use \"client_secret\": \"${{ NAME }}\" and publish the value with `variables set NAME --project-level --secret`.'\n : undefined,\n details: { issues: result.error.issues },\n },\n );\n }\n\n /** `POST /idps` creates the connection when its slug is new to the project. */\n async create(data: object): Promise<{ id: string }> {\n const result = await this.client.createIdp(\n { idp: data as CreateIdpBodyIdp },\n { project_id: this.projectId },\n );\n return { id: result.id };\n }\n\n /**\n * The same call: a document whose slug already exists revises that\n * connection, keeping its id. The id is passed for the sync loop's benefit\n * and deliberately unused — the slug inside the document addresses the row.\n */\n async update(_id: string, data: object): Promise<{ id?: string }> {\n const result = await this.client.createIdp(\n { idp: data as CreateIdpBodyIdp },\n { project_id: this.projectId },\n );\n // The id comes back because the slug decides which connection the write\n // landed on: editing it names a different connection, and the server\n // creates one. Returning the id keeps state pointing at that connection\n // rather than the one the slug used to name.\n return { id: typeof result.id === \"string\" ? result.id : undefined };\n }\n\n /**\n * The stored connection, for the plan's before/after.\n *\n * Comparison-only: the result is rendered, never written back or uploaded,\n * so it is returned as the server states it apart from the secret guard.\n */\n async fetch(id: string): Promise<object> {\n const body = await this.client.getIdpById(id, { project_id: this.projectId });\n const definition = (body.definition ?? {}) as object;\n try {\n refuseResolvedSecret(definition, id);\n } catch (err) {\n // Fatal rather than a fetch that failed: the planner swallows an ordinary\n // failure and plans without a diff, which would turn a server resolving\n // secrets into a silently missing before/after.\n throw new FatalFetchError(err as Error);\n }\n return definition;\n }\n\n /** Never reached: `deletion` is unsupported, so the loop reports a removed file and sends nothing. */\n async delete(_id: string): Promise<void> {\n throw new ZitadelError(\n \"E_NOT_IMPLEMENTED\",\n \"Deleting an identity provider connection is not supported yet\",\n { hint: \"Restore the file (#1013).\" },\n );\n }\n\n identityOf(stored: object): string | undefined {\n return (stored as ConnectionBody).slug;\n }\n\n /**\n * What the files alone cannot say. An edit may not change what the\n * connection is: its `slug`, `issuer` or `subject_claim` would re-key the\n * users already linked to it, so it is refused naming the field. And a\n * `client_secret` naming a variable the project does not hold would\n * publish a connection that cannot sign anyone in.\n */\n async preflight(\n path: string,\n data: object,\n old: object | null,\n ): Promise<{ id: string; definition: object } | undefined> {\n const next = data as ConnectionBody;\n // A file the platform does not track yet may still name a connection it\n // holds, such as one moved here from a removed file, so the stored copy is\n // looked up by slug and judged the same way.\n const found = old === null ? await this.findBySlug(next.slug) : undefined;\n const previous = old ?? found?.definition ?? null;\n if (previous !== null) {\n const stored = previous as ConnectionBody;\n const changed = IDENTITY_FIELDS.filter(\n ({ read }) =>\n read(stored) !== undefined && read(next) !== undefined && read(stored) !== read(next),\n );\n if (changed.length > 0) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${path}: ${changed.map(({ name }) => name).join(\", \")} of the connection ${JSON.stringify(stored.slug)} cannot be edited`,\n {\n hint:\n \"These fields identify the connection and the users linked through it. \" +\n \"Restore the stored value, or add a new connection file with its own slug.\",\n details: {\n fields: changed.map(({ name, read }) => ({\n name,\n stored: read(stored),\n local: read(next),\n })),\n },\n },\n );\n }\n }\n\n await this.checkVariables(path, next);\n return found;\n }\n\n /** The stored connection with this slug, which a create would revise. */\n private async findBySlug(\n slug: string | undefined,\n ): Promise<{ id: string; definition: object } | undefined> {\n if (slug === undefined) {\n return undefined;\n }\n const { idps } = await this.client.queryIdps(\n { filter: [{ field: \"slug\", operation: \"equals\", value: slug }], limit: 1 },\n { project_id: this.projectId },\n );\n const [match] = idps;\n return match === undefined ? undefined : { id: match.id, definition: match.definition };\n }\n\n /**\n * What the engine needs from the variables a connection names: they exist,\n * the client id is a plain one it can put in the authorize URL, and the\n * client secret is a secret one. A variable that cannot be read stops the\n * run, like a stored copy that cannot be.\n */\n private async checkVariables(path: string, next: ConnectionBody): Promise<void> {\n const block = next.oidc;\n const named = [\n { field: \"client_id\", secret: false, name: referencedVariable(block?.client_id ?? \"\") },\n {\n field: \"client_secret\",\n secret: true,\n name: referencedVariable(block?.client_secret ?? \"\"),\n },\n ].flatMap((credential) =>\n credential.name === undefined ? [] : [{ ...credential, name: credential.name }],\n );\n if (named.length === 0) {\n return;\n }\n this.variables ??= this.client\n .getVariables({ project_id: this.projectId, kind: \"primary\" })\n .then(\n (held) =>\n new Map(\n Object.entries(primaryValues(held)).map(([name, value]) => [\n name,\n typeof value === \"object\",\n ]),\n ),\n );\n const held = await this.variables;\n const [id, secret] = named;\n if (id !== undefined && secret !== undefined && id.name === secret.name) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${path}: client_id and client_secret both name the variable ${id.name}`,\n {\n hint: \"Give each its own variable: a plain one for the client id, a secret one for the client secret.\",\n details: { variable: id.name, file: path },\n },\n );\n }\n for (const { field, secret: wantsSecret, name } of named) {\n const isSecret = held.get(name);\n if (isSecret === undefined) {\n throw new ZitadelError(\n \"E_CREDENTIAL_MISSING\",\n `${path}: ${field} names the variable ${name}, which the project does not have`,\n {\n hint: `Publish it with \\`variables set ${name} --project-level${wantsSecret ? \" --secret\" : \"\"}\\`, then re-run.`,\n details: { variable: name, field, file: path },\n },\n );\n }\n if (isSecret !== wantsSecret) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${path}: ${field} names the variable ${name}, which is ${isSecret ? \"a secret\" : \"not a secret\"}`,\n {\n hint: wantsSecret\n ? `The client secret must be a secret variable: publish it with \\`variables set ${name} --project-level --secret\\`.`\n : `The client id must be a plain variable the engine can read back: publish it with \\`variables set ${name} --project-level\\`, without --secret.`,\n details: { variable: name, field, file: path, secret: isSecret },\n },\n );\n }\n }\n }\n}\n\nclass SchemaSyncer implements ResourceSyncer {\n readonly kind = \"schema\";\n readonly directory = SCHEMAS_DIR;\n readonly mutable = false;\n readonly revisioned = true;\n readonly normalize = normalizeSchemaBody;\n\n private readonly client: ZitadelClient;\n private readonly projectId: string;\n private readonly env: EnvLookup;\n\n constructor(client: ZitadelClient, projectId: string, env: EnvLookup) {\n this.client = client;\n this.projectId = projectId;\n this.env = env;\n }\n\n /**\n * Parse against the generated `CreateSchemaBody` Zod (the orval-emitted\n * equivalent of `api/openapi/endpoints/schemas/user-schema.yaml`). The\n * generated schema is a union of `user-schema` and `schema-url`\n * discriminated on `kind`; both are valid on-disk bodies.\n */\n validate(data: object): void {\n const result = schemaConfigSchema.safeParse(data);\n if (!result.success) {\n throw new ZitadelError(\"E_VALIDATION\", \"Schema file is not a valid Zitadel schema body\", {\n details: { issues: result.error.issues },\n });\n }\n assertEnvRefs(data, this.env);\n }\n\n /**\n * `POST /schemas` mints a new immutable row. The server allocates the\n * opaque id; the CLI records it in state and re-pins flows against it.\n */\n async create(data: object): Promise<{ id: string }> {\n const result = await this.client.createSchema(data as CreateSchemaBody, {\n project_id: this.projectId,\n });\n return { id: result.id };\n }\n\n /**\n * Not called by the sync loop: schemas are `revisioned`, so a hash change\n * publishes a new immutable revision through {@link create} rather than\n * mutating an existing row. Kept as a required interface member; throws\n * loudly if a caller reaches it.\n */\n async update(_id: string, _data: object): Promise<{ id?: string }> {\n throw new ZitadelError(\n \"E_NOT_IMPLEMENTED\",\n \"schemas are revisioned — edit publishes a new revision, not an update\",\n );\n }\n\n async delete(id: string): Promise<void> {\n // Schemas are immutable on the platform: no PATCH, no DELETE in the\n // generated client. The sync loop's delete branch (`loop.ts`) still\n // schedules a delete action when a state entry exists and the\n // on-disk file is gone — `mutable` only gates updates, not deletes.\n // We deliberately fail loud here so the user notices that removing\n // a schema file is not a supported way to retire it.\n throw new ZitadelError(\"E_NOT_IMPLEMENTED\", `schema delete is not supported (${id})`);\n }\n\n async fetch(id: string): Promise<object> {\n // Flat-by-id: authz resolves the project from RSI; no project_id query.\n // The response is the `{id, schema, metadata}` envelope; only the\n // customer-authored document is compared with `.zitadel/schemas/`.\n const body = await this.client.getSchemaById(id);\n return body.schema;\n }\n}\n\n/**\n * Flow definitions are revisioned like schemas: every edit publishes a new\n * immutable revision via `POST /flow_definitions`, no update or delete. The\n * revisions of one flow share its `name`; the runtime serves the newest.\n */\nclass FlowDefinitionSyncer implements ResourceSyncer {\n readonly kind = \"flow\";\n readonly directory = FLOWS_DIR;\n readonly mutable = false;\n readonly revisioned = true;\n readonly normalize = normalizeFlowBody;\n\n private readonly client: ZitadelClient;\n private readonly projectId: string;\n private readonly env: EnvLookup;\n\n constructor(client: ZitadelClient, projectId: string, env: EnvLookup) {\n this.client = client;\n this.projectId = projectId;\n this.env = env;\n }\n\n /**\n * Validates one flow file against the canonical `flowConfigSchema` (the\n * same Zod `validateFlows` and doctor use), then checks env references.\n */\n validate(data: object): void {\n const result = flowConfigSchema.safeParse(data);\n if (!result.success) {\n throw new ZitadelError(\"E_VALIDATION\", \"Flow file is not a valid Zitadel flow body\", {\n details: { issues: result.error.issues },\n });\n }\n assertEnvRefs(data, this.env);\n }\n\n /**\n * `POST /flow_definitions` publishes a new immutable revision and returns\n * its id. Wraps the bare on-disk flow body in the spec's create-envelope\n * (`api/openapi/components/flows/flow-definition-create-request.yaml`)\n * before sending. The file on disk stays bare so it is human-editable;\n * only the wire request carries `project_id` and the surrounding\n * envelope.\n */\n async create(data: object): Promise<{ id: string }> {\n const result = (await this.client.createFlowDefinition({\n project_id: this.projectId,\n schema_uri: DEFAULT_FLOW_SCHEMA_URI,\n flow_definition: data as CreateFlowDefinitionBodyFlowDefinition,\n })) as CreateFlowDefinition201;\n return { id: result.id };\n }\n\n async update(_id: string, _data: object): Promise<{ id?: string }> {\n throw new ZitadelError(\n \"E_NOT_IMPLEMENTED\",\n \"flows are revisioned — edit publishes a new revision, not an update\",\n );\n }\n\n async delete(id: string): Promise<void> {\n // Flow revisions are immutable on the platform; removing the local file\n // does not retire them. The newest revision of the name keeps being\n // served — publish a new revision to change what users see.\n throw new ZitadelError(\"E_NOT_IMPLEMENTED\", `flow delete is not supported (${id})`);\n }\n\n /**\n * `GET /flow_definitions/:id` returns a response envelope with metadata\n * (`id`, `project_id`, `created_at`, `updated_at`) plus `flow_definition`.\n * Return only `flow_definition` so diffs compare with the on-disk bare body.\n * Flat-by-id: no `project_id` query — authz resolves the project from RSI.\n */\n async fetch(id: string): Promise<object> {\n const envelope = await this.client.getFlowDefinition(id);\n\n return envelope.flow_definition as object;\n }\n}\n\n/**\n * Branding revisions (ADR 040): schema-style immutable semantics — every\n * edit publishes a new revision via `POST /branding`, no update or delete.\n * Unlike schemas, nothing references branding revisions, so a revise never\n * triggers re-pinning. The descriptor keeps the template in a sibling\n * `.liquid` file behind a `$file` reference; this syncer inlines it for\n * hashing and upload.\n */\nclass BrandingSyncer implements ResourceSyncer {\n readonly kind = \"branding\";\n readonly directory = BRANDING_DIR;\n readonly mutable = false;\n readonly revisioned = true;\n /** One project, one branding descriptor — extra .json files fail the scan. */\n readonly singletonFile = \"branding.json\";\n\n private readonly client: ZitadelClient;\n private readonly projectId: string;\n private readonly env: EnvLookup;\n private readonly cwd: string;\n\n constructor(client: ZitadelClient, projectId: string, env: EnvLookup, cwd: string) {\n this.client = client;\n this.projectId = projectId;\n this.env = env;\n this.cwd = cwd;\n }\n\n /**\n * The comparison form is the wire body with the template inlined, so an\n * edit to the referenced `.liquid` file changes the state hash and plans\n * a `revise` even though the descriptor JSON is untouched.\n */\n readonly normalize = (data: object): object => toBrandingWireBody(this.cwd, data);\n\n /**\n * Zod shape + env refs, then the authoritative template validation from\n * `@zitadel/config/template` — the LiquidJS-dialect check the Go server\n * cannot run (its save gate is lexical; see ADR 040).\n */\n validate(data: object): void {\n assertNoLegacyTemplateKey(data);\n const result = brandingConfigSchema.safeParse(data);\n if (!result.success) {\n throw new ZitadelError(\"E_VALIDATION\", \"Branding file is not a valid branding descriptor\", {\n details: { issues: result.error.issues },\n });\n }\n assertEnvRefs(data, this.env);\n const template = readDescriptorTemplate(this.cwd, data);\n if (template === undefined) {\n return;\n }\n const issues = validateLoginTemplate(template).filter((issue) => issue.severity === \"error\");\n if (issues.length > 0) {\n throw new ZitadelError(\"E_VALIDATION\", \"Login template failed validation\", {\n details: { issues },\n hint: \"Fix the template issues; the rules live in docs/design/flowengine/template-security.md.\",\n });\n }\n }\n\n /** `POST /branding` publishes a new immutable revision. */\n async create(data: object): Promise<{ id: string }> {\n const wire = toBrandingWireBody(this.cwd, data) as CreateBrandingBody;\n const result = (await this.client.createBranding(wire, {\n project_id: this.projectId,\n })) as CreateBranding201;\n return { id: result.id };\n }\n\n async update(_id: string, _data: object): Promise<{ id?: string }> {\n throw new ZitadelError(\n \"E_NOT_IMPLEMENTED\",\n \"branding is revisioned — edit publishes a new revision, not an update\",\n );\n }\n\n async delete(id: string): Promise<void> {\n // Branding revisions are immutable on the platform; removing the local\n // descriptor does not retire them. The newest revision keeps being\n // served — publish a new revision to change what users see.\n throw new ZitadelError(\"E_NOT_IMPLEMENTED\", `branding delete is not supported (${id})`);\n }\n\n /** Wire form (template inlined); diffs compare in the normalized form. Flat-by-id: no project_id query. */\n async fetch(id: string): Promise<object> {\n const envelope = await this.client.getBrandingById(id);\n return envelope.branding as object;\n }\n}\n","import type { LookupAddress } from \"node:dns\";\nimport { lookup } from \"node:dns/promises\";\nimport type { RequestOptions } from \"node:https\";\nimport { BlockList, isIP } from \"node:net\";\n\nimport { consola } from \"consola\";\nimport { Agent, type Dispatcher } from \"undici\";\n\nimport { userAgentInterceptor } from \"../user-agent\";\nimport type { SyncAction, SyncActionWarning } from \"./types.js\";\n\n/**\n * Branding descriptor fields whose value is a URL the login page fetches as\n * an image. Both are optional and both fail the same invisible way when the\n * URL is well-formed but dead.\n */\nconst ASSET_FIELDS = [\"logo_url\", \"hero_url\"] as const;\n\n/**\n * Per-URL probe budget. Short on purpose: this runs on the critical path of\n * every `plan` and `apply`, and a dead host that never answers must cost a\n * couple of seconds, not a hung command.\n */\nconst DEFAULT_TIMEOUT_MS = 2500;\n\n/** Keep redirect chains bounded and re-validate every destination ourselves. */\nconst MAX_REDIRECTS = 5;\n\n/**\n * Addresses an untrusted descriptor must never make the planning host contact.\n * The browser-side render gate still supports canonical loopback HTTP for local\n * development; the CLI probe deliberately leaves those URLs inconclusive\n * instead of turning `plan` over repo content into a localhost/network scanner.\n */\nconst UNSAFE_IPV4_ADDRESSES = new BlockList();\nfor (const [network, prefix] of [\n [\"0.0.0.0\", 8],\n [\"10.0.0.0\", 8],\n [\"100.64.0.0\", 10],\n [\"127.0.0.0\", 8],\n [\"169.254.0.0\", 16],\n [\"172.16.0.0\", 12],\n [\"192.0.0.0\", 24],\n [\"192.0.2.0\", 24],\n [\"192.88.99.0\", 24],\n [\"192.168.0.0\", 16],\n [\"198.18.0.0\", 15],\n [\"198.51.100.0\", 24],\n [\"203.0.113.0\", 24],\n [\"224.0.0.0\", 4],\n [\"240.0.0.0\", 4],\n] as const) {\n UNSAFE_IPV4_ADDRESSES.addSubnet(network, prefix, \"ipv4\");\n}\nconst UNSAFE_IPV6_ADDRESSES = new BlockList();\nfor (const [network, prefix] of [\n // Global unicast currently lives in 2000::/3. Excluding everything outside\n // it also covers mapped IPv4, translation, ULA, link-local, and multicast.\n [\"::\", 3],\n [\"4000::\", 2],\n [\"8000::\", 1],\n // Special-purpose ranges inside 2000::/3 are not public asset hosts.\n [\"2001::\", 23],\n [\"2001:db8::\", 32],\n [\"2002::\", 16],\n [\"3fff::\", 20],\n] as const) {\n UNSAFE_IPV6_ADDRESSES.addSubnet(network, prefix, \"ipv6\");\n}\n\n/** Content types that are images despite not being `image/*`. */\nconst EXTRA_IMAGE_TYPES = new Set([\"application/octet-stream\"]);\n\nexport type AssetProbeVerdict =\n | { kind: \"ok\" }\n /** The probe could not decide — no warning is worth a false alarm. */\n | { kind: \"inconclusive\" }\n | { kind: \"unreachable\"; detail: string }\n | { kind: \"status\"; status: number }\n | { kind: \"empty\"; status: number }\n | { kind: \"content-type\"; contentType: string };\n\n/**\n * Annotate every branding action in a plan with warnings for asset URLs that\n * are well-formed but will not render: an unreachable host, a non-2xx status,\n * or a response that is not an image.\n *\n * Why the CLI probes at all: a bad `logo_url` clears every gate on the way in\n * (the CLI's Zod shape check, the server's save gate) and then fails silently\n * in the browser as a 0×0 `<img>` — no plan output, no apply output, no\n * console error. The probe is the only place in the pipeline that can see it.\n *\n * Deliberately non-fatal and best-effort. A developer on a plane, behind a\n * proxy, or pointing at a CDN that only resolves from production gets a\n * warning, never a failed plan — the machine running `plan` is not\n * necessarily the machine that renders the login page. Set\n * `ZITADEL_SKIP_ASSET_PROBE` to turn it off entirely, and\n * `ZITADEL_ASSET_PROBE_TIMEOUT_MS` to retune the per-URL budget. Only public\n * HTTPS destinations are contacted: loopback/private/internal targets and\n * redirects to them stay inconclusive so repo config cannot scan the planning\n * host's network.\n *\n * Mutates `actions` in place, like {@link validatePlannedFlows} — the caller\n * (`buildSyncPlan`) owns the array it just built.\n */\nexport async function annotateAssetWarnings(actions: SyncAction[]): Promise<void> {\n if (process.env.ZITADEL_SKIP_ASSET_PROBE) {\n consola.debug(\"Branding asset probe skipped (ZITADEL_SKIP_ASSET_PROBE is set)\");\n return;\n }\n\n const targets = actions.filter(\n (action): action is Extract<SyncAction, { kind: \"create\" | \"update\" | \"revise\" }> =>\n (action.kind === \"create\" || action.kind === \"update\" || action.kind === \"revise\") &&\n action.syncer.kind === \"branding\",\n );\n if (targets.length === 0) {\n return;\n }\n\n // One probe per distinct URL: the same logo referenced twice is one request.\n const urls = new Set<string>();\n for (const action of targets) {\n for (const { url } of assetUrlsOf(action.content)) {\n urls.add(url);\n }\n }\n if (urls.size === 0) {\n return;\n }\n\n const timeoutMs = probeTimeoutMs();\n const verdicts = new Map(\n await Promise.all(\n [...urls].map(\n async (url): Promise<[string, AssetProbeVerdict]> => [\n url,\n await probeAsset(url, timeoutMs),\n ],\n ),\n ),\n );\n\n for (const action of targets) {\n const warnings: SyncActionWarning[] = [];\n for (const { field, url } of assetUrlsOf(action.content)) {\n const warning = describeVerdict(field, url, verdicts.get(url) ?? { kind: \"inconclusive\" });\n if (warning) {\n warnings.push(warning);\n }\n }\n if (warnings.length > 0) {\n action.warnings = [...(action.warnings ?? []), ...warnings];\n }\n }\n}\n\n/**\n * The probe itself: a HEAD request bounded by an abort timeout. HEAD keeps a\n * multi-megabyte hero image off the wire — we only need the status line and\n * the content type.\n */\nexport async function probeAsset(url: string, timeoutMs: number): Promise<AssetProbeVerdict> {\n let current: URL;\n try {\n current = new URL(url);\n } catch {\n // Shape is the schema's job; an unparseable URL never reaches here.\n return { kind: \"inconclusive\" };\n }\n const signal = AbortSignal.timeout(timeoutMs);\n try {\n for (let redirects = 0; ; redirects += 1) {\n if (!isSafeProbeUrl(current)) {\n consola.debug(`asset probe ${url} skipped unsafe/private target: ${current.href}`);\n return { kind: \"inconclusive\" };\n }\n\n const response = await requestHead(current, signal);\n\n if (isRedirect(response.status)) {\n const location = response.location;\n if (!location) {\n return { kind: \"status\", status: response.status };\n }\n if (redirects >= MAX_REDIRECTS) {\n return { kind: \"unreachable\", detail: `more than ${MAX_REDIRECTS} redirects` };\n }\n current = new URL(location, current);\n continue;\n }\n\n // Some origins refuse HEAD outright. That says nothing about the asset,\n // and a false \"your logo is broken\" is worse than staying quiet.\n if (response.status === 405 || response.status === 501) {\n return { kind: \"inconclusive\" };\n }\n if (response.status < 200 || response.status >= 300) {\n return { kind: \"status\", status: response.status };\n }\n // These successful statuses are explicitly bodyless. Treating them as\n // healthy because they also omit Content-Type recreates the exact\n // \"well-formed URL that serves nothing\" failure this probe exists for.\n if (response.status === 204 || response.status === 205) {\n return { kind: \"empty\", status: response.status };\n }\n\n const contentType = response.contentType?.split(\";\")[0]?.trim().toLowerCase();\n if (!contentType) {\n return { kind: \"ok\" };\n }\n if (contentType.startsWith(\"image/\") || EXTRA_IMAGE_TYPES.has(contentType)) {\n return { kind: \"ok\" };\n }\n return { kind: \"content-type\", contentType };\n }\n } catch (error) {\n if (isUnsafeProbeTargetError(error)) {\n consola.debug(`asset probe ${url} skipped unsafe/private target`);\n return { kind: \"inconclusive\" };\n }\n consola.debug(`asset probe ${url} failed:`, error);\n return { kind: \"unreachable\", detail: describeProbeError(error, timeoutMs) };\n }\n}\n\nfunction isRedirect(status: number): boolean {\n return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;\n}\n\n/**\n * Reject targets whose URL alone proves they are unsafe. Hostname resolution\n * happens inside the connector lookup below so validation and connection use\n * the same DNS answer, without a rebinding window.\n */\nfunction isSafeProbeUrl(url: URL): boolean {\n if (url.protocol !== \"https:\" || url.username !== \"\" || url.password !== \"\") {\n return false;\n }\n\n const hostname = url.hostname\n .replace(/^\\[|\\]$/g, \"\")\n .replace(/\\.$/, \"\")\n .toLowerCase();\n if (\n hostname === \"localhost\" ||\n !hostname.includes(\".\") ||\n hostname.endsWith(\".localhost\") ||\n hostname.endsWith(\".local\") ||\n hostname.endsWith(\".internal\") ||\n hostname.endsWith(\".lan\") ||\n hostname.endsWith(\".home.arpa\")\n ) {\n return false;\n }\n\n const literalFamily = isIP(hostname);\n return literalFamily === 0 || !isUnsafeAddress(hostname, literalFamily);\n}\n\n/** Resolve once and accept the answer only when every address is public. */\nexport async function resolvePublicAddresses(\n hostname: string,\n): Promise<LookupAddress[] | undefined> {\n const addresses = await lookup(hostname, { all: true, verbatim: true });\n return addresses.length > 0 &&\n addresses.every(({ address, family }) => !isUnsafeAddress(address, family))\n ? addresses\n : undefined;\n}\n\nfunction isUnsafeAddress(address: string, family: number): boolean {\n return family === 6\n ? UNSAFE_IPV6_ADDRESSES.check(address, \"ipv6\")\n : UNSAFE_IPV4_ADDRESSES.check(address, \"ipv4\");\n}\n\ninterface HeadResponse {\n status: number;\n location?: string;\n contentType?: string;\n}\n\nconst UNSAFE_PROBE_TARGET_CODE = \"ERR_ZITADEL_UNSAFE_ASSET_TARGET\";\n\nfunction unsafeProbeTargetError(hostname: string): NodeJS.ErrnoException {\n return Object.assign(new Error(`asset target ${hostname} resolves to a non-public address`), {\n code: UNSAFE_PROBE_TARGET_CODE,\n });\n}\n\n/**\n * Validate DNS in the connector's own lookup and return only approved\n * addresses. The socket cannot perform a second lookup, which closes the DNS\n * rebinding gap while preserving the hostname for TLS SNI/certificate checks.\n */\nasync function requestHead(url: URL, signal: AbortSignal): Promise<HeadResponse> {\n const safeLookup: NonNullable<RequestOptions[\"lookup\"]> = (hostname, options, callback) => {\n resolvePublicAddresses(hostname).then(\n (addresses) => {\n if (!addresses) {\n callback(unsafeProbeTargetError(hostname), \"\", 0);\n return;\n }\n const candidates =\n options.family === 4 || options.family === 6\n ? addresses.filter(({ family }) => family === options.family)\n : addresses;\n const candidate = candidates[0];\n if (!candidate) {\n callback(unsafeProbeTargetError(hostname), \"\", 0);\n return;\n }\n if (options.all) {\n callback(null, candidates);\n return;\n }\n callback(null, candidate.address, candidate.family);\n },\n (error: NodeJS.ErrnoException) => callback(error, \"\", 0),\n );\n };\n\n // A private agent bypasses the global dispatcher, so it composes the user\n // agent itself.\n const dispatcher = new Agent({ connect: { lookup: safeLookup } }).compose(userAgentInterceptor);\n try {\n const response = await fetch(url, {\n method: \"HEAD\",\n redirect: \"manual\",\n signal,\n dispatcher,\n } as RequestInit & { dispatcher: Dispatcher });\n return {\n status: response.status,\n location: response.headers.get(\"location\") ?? undefined,\n contentType: response.headers.get(\"content-type\") ?? undefined,\n };\n } finally {\n await dispatcher.destroy();\n }\n}\n\nfunction isUnsafeProbeTargetError(error: unknown): boolean {\n let current = error;\n for (let depth = 0; depth < 4 && current instanceof Error; depth += 1) {\n if ((current as NodeJS.ErrnoException).code === UNSAFE_PROBE_TARGET_CODE) {\n return true;\n }\n current = current.cause;\n }\n return false;\n}\n\nfunction describeVerdict(\n field: string,\n url: string,\n verdict: AssetProbeVerdict,\n): SyncActionWarning | undefined {\n switch (verdict.kind) {\n case \"ok\":\n case \"inconclusive\":\n return undefined;\n case \"status\":\n return {\n rule: \"warn/asset-unreachable\",\n message:\n `${field} ${url} returned HTTP ${verdict.status} — the login page renders a ` +\n `well-formed URL that serves nothing as a 0×0 image, with no error anywhere.`,\n };\n case \"empty\":\n return {\n rule: \"warn/asset-unreachable\",\n message:\n `${field} ${url} returned HTTP ${verdict.status} with no representation — the login ` +\n `page has no image bytes to render.`,\n };\n case \"unreachable\":\n return {\n rule: \"warn/asset-unreachable\",\n message:\n `${field} ${url} could not be reached (${verdict.detail}) — the login page renders ` +\n `an unreachable URL as a 0×0 image. Ignore this if the host is only reachable from ` +\n `where the login page renders; set ZITADEL_SKIP_ASSET_PROBE to stop checking.`,\n };\n case \"content-type\":\n return {\n rule: \"warn/asset-content-type\",\n message:\n `${field} ${url} responded with content-type \"${verdict.contentType}\", not an image — ` +\n `the login page renders a non-image response as a 0×0 image.`,\n };\n }\n}\n\n/** The `logo_url` / `hero_url` values a descriptor actually sets. */\nfunction assetUrlsOf(content: object): Array<{ field: string; url: string }> {\n const body = content as Record<string, unknown>;\n const out: Array<{ field: string; url: string }> = [];\n for (const field of ASSET_FIELDS) {\n const value = body[field];\n if (typeof value === \"string\" && value !== \"\") {\n out.push({ field, url: value });\n }\n }\n return out;\n}\n\nfunction probeTimeoutMs(): number {\n const raw = Number(process.env.ZITADEL_ASSET_PROBE_TIMEOUT_MS);\n return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_TIMEOUT_MS;\n}\n\nfunction describeProbeError(error: unknown, timeoutMs: number): string {\n if (\n error instanceof Error &&\n (error.name === \"TimeoutError\" ||\n (error.cause instanceof Error && error.cause.name === \"TimeoutError\"))\n ) {\n return `no response within ${timeoutMs}ms`;\n }\n if (error instanceof Error) {\n const cause = error.cause;\n const detail = cause instanceof Error ? cause.message : error.message;\n return detail || error.name;\n }\n return String(error);\n}\n","import { consola } from \"consola\";\n\nimport { validateFlowDefinition, type FlowValidationIssue } from \"@zitadel/config/validate\";\n\nimport { ZitadelError } from \"../errors\";\nimport { FLOWS_DIR } from \"../flows\";\nimport type { ResourceEntry, SyncAction } from \"./types.js\";\nimport { reportWarning } from \"../warnings\";\n\n/**\n * Pre-flight semantic validation for every flow this plan uploads,\n * mirroring the server-side `ValidateFlowDefinition` (see\n * `@zitadel/config/validate`). Runs inside `buildSyncPlan`, so `plan`\n * reports the violations the server would only reveal on apply — and\n * `apply` fails before any platform mutation instead of half-applied\n * (a schema revision would otherwise publish before the flow update\n * fails).\n *\n * Only actions that upload a flow (create/update/revise, including repin-forced\n * revisions) are validated: an unchanged flow is never re-judged, so a\n * validator behavior change cannot break an already-applied project.\n *\n * Warning-severity issues ANNOTATE the actions in place (`action.warnings`)\n * for plan rendering — `actions` is deliberately typed mutable because the\n * caller (`buildSyncPlan`, which owns the array it just built) expects the\n * annotations. Error-severity issues aggregate into one E_VALIDATION\n * carrying every violation.\n *\n * Escape hatch: setting `ZITADEL_SKIP_FLOW_VALIDATION` skips the check —\n * insurance against a port bug rejecting something the server accepts.\n */\nexport function validatePlannedFlows(opts: {\n actions: SyncAction[];\n scannedContents: ReadonlyMap<string, object>;\n stateResources: Readonly<Record<string, ResourceEntry>>;\n}): void {\n if (process.env.ZITADEL_SKIP_FLOW_VALIDATION) {\n reportWarning(\"Flow and SSO validation skipped (ZITADEL_SKIP_FLOW_VALIDATION is set)\");\n return;\n }\n\n const failures: Array<{ path: string; issue: FlowValidationIssue }> = [];\n let anyRepin = false;\n\n // The default-swap warning needs plan-wide context: a project's very\n // first flow becoming the default is expected, an additional one\n // silently taking over /login is the footgun.\n const flowCreatePaths = opts.actions\n .filter((a) => a.kind === \"create\" && a.syncer.kind === \"flow\")\n .map((a) => a.path);\n const trackedFlowPaths = Object.keys(opts.stateResources).filter((path) =>\n path.startsWith(`${FLOWS_DIR}/`),\n );\n\n for (const action of opts.actions) {\n if (action.kind !== \"create\" && action.kind !== \"update\" && action.kind !== \"revise\") {\n continue;\n }\n if (action.syncer.kind !== \"flow\") {\n continue;\n }\n\n const issues = validateFlowDefinition(\n action.content,\n resolveSchemaContent(action, opts.scannedContents, opts.stateResources),\n );\n const warnings = issues.filter((issue) => issue.severity === \"warning\");\n if (warnings.length > 0) {\n action.warnings = warnings.map(({ rule, message }) => ({ rule, message }));\n }\n for (const issue of issues) {\n if (issue.severity === \"error\") {\n failures.push({ path: action.path, issue });\n anyRepin ||= action.repin !== undefined;\n }\n }\n\n const swapWarning = defaultSwapWarning(action, flowCreatePaths, trackedFlowPaths);\n if (swapWarning !== undefined) {\n action.warnings = [...(action.warnings ?? []), swapWarning];\n }\n }\n\n if (failures.length === 0) {\n return;\n }\n\n const noun = failures.length === 1 ? \"issue\" : \"issues\";\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Flow validation failed (${failures.length} ${noun}):\\n` +\n failures.map(({ path, issue }) => ` - ${path}: ${issue.message}`).join(\"\\n\"),\n {\n hint:\n \"These are the same rules the server enforces on apply. Fix the flow definition(s) and re-run plan.\" +\n (anyRepin\n ? \" A failing flow is adopting an edited schema revision — update its steps[].fields to match the edited schema (or restore the removed/renamed properties).\"\n : \"\"),\n details: {\n issues: failures.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\n/**\n * Warn when uploading an active, unscoped flow into a project that has\n * other flows: the engine's default selection is the newest active\n * unscoped flow across the whole project (created_at, then id), not per\n * name, so the uploaded row silently becomes what `<zitadel-login>`\n * renders for its purposes unless the widget pins a `flow-name`. A new\n * revision moves the default exactly like a new flow does — and a schema\n * edit re-publishes every flow pinned to it in scan order, so each repin\n * revision is warned about too. Deliberately engine-level rather than a\n * validator rule: the verdict depends on the action kind and the rest of\n * the plan/state, which `validateFlowDefinition` never sees. A project's\n * only flow is exempt — being the default is the point of it.\n */\nfunction defaultSwapWarning(\n action: Extract<SyncAction, { kind: \"create\" | \"update\" | \"revise\" }>,\n flowCreatePaths: readonly string[],\n trackedFlowPaths: readonly string[],\n): { rule: string; message: string } | undefined {\n const body = action.content as {\n status?: unknown;\n purposes?: Record<string, unknown>;\n audience?: { team_ids?: unknown[]; app_ids?: unknown[] };\n };\n if (body.status !== \"active\") {\n return undefined;\n }\n const scoped =\n (body.audience?.team_ids?.length ?? 0) > 0 || (body.audience?.app_ids?.length ?? 0) > 0;\n if (scoped) {\n return undefined;\n }\n const purposes = Object.keys(body.purposes ?? {});\n if (purposes.length === 0) {\n return undefined;\n }\n const otherFlows =\n trackedFlowPaths.filter((path) => path !== action.path).length +\n flowCreatePaths.filter((path) => path !== action.path).length;\n if (otherFlows === 0) {\n return undefined;\n }\n const subject =\n action.kind === \"create\"\n ? \"this flow definition becomes the project default\"\n : \"this revision becomes the newest active flow definition and the project default\";\n return {\n rule: \"warn/default-flow-swap\",\n message:\n `once applied, ${subject} for ${humanList(purposes)}: ` +\n `pages that do not explicitly set flow-name on <zitadel-login> will start rendering it. ` +\n `If that is not intended, give the flow definition an \"audience\" before its first apply and select it by flowName, ` +\n `or pin flow-name on the pages that should keep the current project default.`,\n };\n}\n\n/** [\"login\", \"register\"] → \"login and register\" (Oxford-free prose list). */\nfunction humanList(items: readonly string[]): string {\n if (items.length <= 1) return items[0] ?? \"\";\n return `${items.slice(0, -1).join(\", \")} and ${items[items.length - 1]}`;\n}\n\n/**\n * Locate the local content of the schema a flow's `user_schema` names: the\n * repin's schema file, a scanned schema with that `objectType`, or the file\n * state maps a schema id to. Unresolvable refs return undefined, so only\n * flow-local rules run.\n */\nfunction resolveSchemaContent(\n action: Extract<SyncAction, { kind: \"create\" | \"update\" | \"revise\" }>,\n scannedContents: ReadonlyMap<string, object>,\n stateResources: Readonly<Record<string, ResourceEntry>>,\n): object | undefined {\n if (action.repin) {\n return scannedContents.get(action.repin.schemaPath);\n }\n const ref = (action.content as { user_schema?: unknown }).user_schema;\n if (typeof ref !== \"string\" || ref === \"\") {\n return undefined;\n }\n for (const content of scannedContents.values()) {\n const { kind, objectType } = content as { kind?: unknown; objectType?: unknown };\n if (kind === \"user-schema\" && objectType === ref) {\n return content;\n }\n }\n for (const [path, entry] of Object.entries(stateResources)) {\n if (entry.id === ref) {\n return scannedContents.get(path);\n }\n }\n consola.debug(`flow validation: no local schema for user_schema ${ref}; flow-local rules only`);\n return undefined;\n}\n","import { createHash } from \"node:crypto\";\n\nimport { escapeControlCharacters } from \"../api-client\";\nimport { stableStringify } from \"../json\";\nimport type { ResourceSyncer, SyncAction, SyncActionWarning, SyncPlanSummary } from \"./types.js\";\n\n/**\n * Count the non-`skip` actions in a {@link buildSyncPlan} result. Pure; the\n * single source of truth for the plan counts shared by the `plan` /\n * `apply --dry-run` JSON payload and {@link renderPlan}'s summary line.\n */\nexport function summarizePlan(actions: ReadonlyArray<SyncAction>): SyncPlanSummary {\n const active = actions.filter((a) => a.kind !== \"skip\");\n const moved = (a: SyncAction) => a.kind === \"create\" && a.movedFrom !== undefined;\n return {\n creates: active.filter((a) => a.kind === \"create\" && !moved(a)).length,\n updates: active.filter((a) => a.kind === \"update\").length,\n revisions: active.filter((a) => a.kind === \"revise\").length,\n deletes: active.filter((a) => a.kind === \"delete\").length,\n moves: active.filter(moved).length,\n unsupported_deletions: actions.filter(isUnsupportedDeletion).length,\n total: active.length,\n };\n}\n\n/** A removed file whose resource the platform cannot delete yet; planned as a skip. */\nexport type UnsupportedDeletion = Extract<\n SyncAction,\n { kind: \"skip\"; reason: \"unsupported-deletion\" }\n>;\n\n/** Whether an action is a removed file that will be kept on the platform. */\nexport function isUnsupportedDeletion(action: SyncAction): action is UnsupportedDeletion {\n return action.kind === \"skip\" && action.reason === \"unsupported-deletion\";\n}\n\n/** What to tell the developer about one removed file, in a plan and in an apply. */\nexport function unsupportedDeletionNote(action: UnsupportedDeletion): string {\n return (\n `${action.path} was removed, but deleting ${action.syncer.kind} resources is not supported yet (#1013), ` +\n `so nothing was deleted on the platform. Restore the file if you did not mean to remove it.`\n );\n}\n\n/**\n * Collect the plan-time validation warnings across all actions, tagged\n * with the file they belong to. Feeds the `plan` / `apply --dry-run`\n * `--json` payload so agents can read warnings structurally.\n */\nexport function collectPlanWarnings(\n actions: ReadonlyArray<SyncAction>,\n): Array<{ path: string; rule: string; message: string }> {\n const out: Array<{ path: string; rule: string; message: string }> = [];\n for (const action of actions) {\n for (const warning of warningsOf(action)) {\n out.push({ path: action.path, rule: warning.rule, message: warning.message });\n }\n if (isUnsupportedDeletion(action)) {\n out.push({\n path: action.path,\n rule: \"unsupported-deletion\",\n message: unsupportedDeletionNote(action),\n });\n }\n }\n return out;\n}\n\n/**\n * The warnings an action carries. Only the three kinds that upload a body can\n * have any: a `delete` has no content to judge, and a `skip` was never judged.\n */\nfunction warningsOf(action: SyncAction): ReadonlyArray<SyncActionWarning> {\n return action.kind === \"create\" || action.kind === \"update\" || action.kind === \"revise\"\n ? (action.warnings ?? [])\n : [];\n}\n\n/**\n * One entry of the `changes` array in the `plan` / `apply` `--json`\n * payloads: which resource an action touches and how. `action` speaks the\n * envelope's public vocabulary (`revision`, matching the `revisions`\n * counter, not the internal `revise`). `id` is the platform id an\n * update/delete targets; `previous_id` is the revision being superseded.\n * The file path is the resource identity, mirroring {@link renderPlan}.\n */\nexport type PlanResourceChange = {\n kind: ResourceSyncer[\"kind\"];\n action: \"create\" | \"update\" | \"revision\" | \"delete\" | \"move\";\n file: string;\n id?: string;\n previous_id?: string;\n /** For a move: the removed file the resource used to be in. */\n moved_from?: string;\n};\n\n/**\n * Enumerate the non-`skip` actions of a {@link buildSyncPlan} result as\n * envelope-ready {@link PlanResourceChange} rows. Pure; the structural\n * counterpart of {@link summarizePlan} — counts and rows always agree.\n */\nexport function enumeratePlanResources(actions: ReadonlyArray<SyncAction>): PlanResourceChange[] {\n const out: PlanResourceChange[] = [];\n for (const action of actions) {\n switch (action.kind) {\n case \"create\":\n out.push(\n action.movedFrom === undefined\n ? { kind: action.syncer.kind, action: \"create\", file: action.path }\n : {\n kind: action.syncer.kind,\n action: \"move\",\n file: action.path,\n moved_from: action.movedFrom,\n },\n );\n break;\n case \"update\":\n out.push({ kind: action.syncer.kind, action: \"update\", file: action.path, id: action.id });\n break;\n case \"revise\":\n out.push({\n kind: action.syncer.kind,\n action: \"revision\",\n file: action.path,\n previous_id: action.previousId,\n });\n break;\n case \"delete\":\n out.push({ kind: action.syncer.kind, action: \"delete\", file: action.path, id: action.id });\n break;\n case \"skip\":\n break;\n }\n }\n return out;\n}\n\n/**\n * Render a {@link buildSyncPlan} result as a human-readable Terraform-style\n * plan. TTY-aware: colors and bold are emitted only when `tty` is true.\n * Returns the empty-state message when every action is `skip`.\n *\n * @param actions - The action list produced by `buildSyncPlan`. Read-only;\n * the function never mutates the input.\n * @param tty - True when stdout is a TTY; controls ANSI emission.\n */\nexport function renderPlan(actions: ReadonlyArray<SyncAction>, tty: boolean): string {\n const active = actions.filter((a) => a.kind !== \"skip\");\n\n const unsupported = actions.filter(isUnsupportedDeletion);\n const unsupportedNote = unsupported.map((a) =>\n paint(`# ${unsupportedDeletionNote(a)}`, A.yellow, tty),\n );\n\n if (active.length === 0) {\n const headline =\n unsupported.length === 0\n ? \"No changes. Your Zitadel configuration matches the current state.\"\n : `Nothing to apply, but ${unsupported.length} removed file${unsupported.length === 1 ? \"\" : \"s\"} cannot be deleted from the platform yet.`;\n return [paint(headline, A.bold, tty), ...unsupportedNote].join(\"\\n\");\n }\n\n const out: string[] = [];\n out.push(paint(\"Zitadel will perform the following actions:\", A.bold, tty));\n\n for (const action of active) {\n out.push(\"\");\n out.push(...renderBlock(action, tty));\n }\n\n out.push(\"\");\n\n const { creates, updates, revisions, deletes, moves } = summarizePlan(actions);\n\n const parts: string[] = [];\n if (creates > 0) {\n parts.push(`${creates} to add`);\n }\n if (updates > 0) {\n parts.push(`${updates} to change`);\n }\n if (revisions > 0) {\n parts.push(`${revisions} new revision${revisions === 1 ? \"\" : \"s\"}`);\n }\n if (moves > 0) {\n parts.push(`${moves} moved`);\n }\n if (deletes > 0) {\n parts.push(`${deletes} to destroy`);\n }\n\n out.push(paint(`Plan: ${parts.join(\", \")}.`, A.bold, tty));\n\n const warningCount = active.reduce((count, action) => count + warningsOf(action).length, 0);\n if (warningCount > 0) {\n out.push(\n paint(\n `Warnings: ${warningCount} (non-blocking — see the # warning lines above).`,\n A.yellow,\n tty,\n ),\n );\n }\n\n out.push(...unsupportedNote);\n return out.join(\"\\n\");\n}\n\nconst A = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n green: \"\\x1b[32m\",\n red: \"\\x1b[31m\",\n yellow: \"\\x1b[33m\",\n} as const;\n\nfunction paint(text: string, code: string, tty: boolean): string {\n return tty ? `${code}${text}${A.reset}` : text;\n}\n\nfunction isPrimitive(v: unknown): v is string | number | boolean | null {\n return v === null || typeof v === \"string\" || typeof v === \"number\" || typeof v === \"boolean\";\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nconst KNOWN_AFTER_APPLY = \"(known after apply)\";\n\n/**\n * Quote-escape a string value, then escape whatever could still drive the\n * terminal. The plan prints what the server stores, and `plan` and `apply`\n * read it verbatim so the diff sees the real bytes; this is\n * where it is made safe to print.\n */\nfunction escapeString(s: string): string {\n return escapeControlCharacters(\n s\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\"),\n );\n}\n\n/**\n * A field name as printed: a server-side key is as untrusted as a value.\n * Backslashes are doubled first, as `sanitizeResponse` does for keys, so a key\n * holding a raw ESC and one holding the literal text `\\x1b` get two labels.\n */\nfunction fieldLabel(key: string): string {\n return escapeControlCharacters(key.replaceAll(\"\\\\\", \"\\\\\\\\\"), { keepLayout: false });\n}\n\nfunction fmtPrimitive(v: string | number | boolean | null): string {\n if (v === null) {\n return \"null\";\n }\n if (typeof v === \"string\" && v === KNOWN_AFTER_APPLY) {\n return KNOWN_AFTER_APPLY;\n }\n if (typeof v === \"string\") {\n return `\"${escapeString(v)}\"`;\n }\n return String(v);\n}\n\n/**\n * A multi-line string is a document, not a scalar: branding inlines a whole\n * `login.liquid` into `liquid_template`, and escaping 200 lines onto one\n * `\"…\\n…\\n…\"` line buries every real change in the same block. Such values\n * render as a summary (and, when they changed, as a line diff) instead.\n */\nfunction isBlockString(v: unknown): v is string {\n return typeof v === \"string\" && v !== KNOWN_AFTER_APPLY && v.includes(\"\\n\");\n}\n\n/** Trailing-newline-insensitive line count: `\"a\\nb\\n\"` is two lines, not three. */\nfunction lineCount(value: string): number {\n const lines = value.split(\"\\n\");\n return lines.length > 1 && lines[lines.length - 1] === \"\" ? lines.length - 1 : lines.length;\n}\n\n/** Short content fingerprint, so two summarised blocks can be told apart. */\nfunction shortHash(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 8);\n}\n\nfunction plural(count: number, noun: string): string {\n return `${count} ${noun}${count === 1 ? \"\" : \"s\"}`;\n}\n\nfunction blockSummary(value: string): string {\n return `(${plural(lineCount(value), \"line\")}, sha256:${shortHash(value)})`;\n}\n\nfunction unchangedBlockSummary(value: string): string {\n return `(unchanged, ${plural(lineCount(value), \"line\")}, sha256:${shortHash(value)})`;\n}\n\n/** {@link fmtPrimitive}, with multi-line strings summarised. */\nfunction fmtScalar(v: string | number | boolean | null): string {\n return isBlockString(v) ? blockSummary(v) : fmtPrimitive(v);\n}\n\n/**\n * Indentation contract (matches Terraform exactly):\n * prefixCol = column index of the +/-/~ character\n * field content starts at prefixCol + 2 (one space gap after prefix)\n * nested object/array content: prefixCol + 4 for the child prefixCol\n * closing } or ] : prefixCol + 2 columns of plain spaces, no prefix\n */\ntype ChangePrefix = \"+\" | \"-\" | \"~\" | \" \";\n\nfunction prefixAnsi(p: ChangePrefix): string {\n if (p === \"+\") {\n return A.green;\n }\n if (p === \"-\") {\n return A.red;\n }\n if (p === \"~\") {\n return A.yellow;\n }\n return \"\";\n}\n\ninterface RenderCtx {\n tty: boolean;\n deleteMode: boolean;\n}\n\nfunction renderFields(\n obj: Record<string, unknown>,\n prefix: ChangePrefix,\n prefixCol: number,\n ctx: RenderCtx,\n lines: string[],\n): void {\n const pad = \" \".repeat(prefixCol);\n const ansi = prefixAnsi(prefix);\n const col = (s: string) => paint(s, ansi, ctx.tty);\n\n const keys = Object.keys(obj).sort();\n const maxLen = keys.reduce((m, k) => Math.max(m, fieldLabel(k).length), 0);\n\n for (const key of keys) {\n const val = obj[key];\n const pk = fieldLabel(key).padEnd(maxLen);\n\n if (isPrimitive(val)) {\n const formatted = fmtScalar(val);\n const suffix = ctx.deleteMode ? \" -> null\" : \"\";\n lines.push(col(`${pad}${prefix} ${pk} = ${formatted}${suffix}`));\n } else if (Array.isArray(val)) {\n if (val.length === 0) {\n lines.push(col(`${pad}${prefix} ${pk} = []`));\n } else {\n lines.push(col(`${pad}${prefix} ${pk} = [`));\n renderArrayItems(val, prefix, prefixCol + 4, ctx, lines);\n lines.push(col(`${\" \".repeat(prefixCol + 2)}]`));\n }\n } else if (isPlainObject(val)) {\n if (Object.keys(val).length === 0) {\n lines.push(col(`${pad}${prefix} ${pk} = {}`));\n } else {\n lines.push(col(`${pad}${prefix} ${pk} = {`));\n renderFields(val, prefix, prefixCol + 4, ctx, lines);\n lines.push(col(`${\" \".repeat(prefixCol + 2)}}`));\n }\n }\n }\n}\n\n/**\n * Renders the items of an array. Unlike {@link renderFields}, primitive\n * elements never get a trailing ` -> null` suffix even under `deleteMode` —\n * Terraform only annotates scalar object-field removals that way, not array\n * items.\n */\nfunction renderArrayItems(\n arr: ReadonlyArray<unknown>,\n prefix: ChangePrefix,\n prefixCol: number,\n ctx: RenderCtx,\n lines: string[],\n): void {\n const pad = \" \".repeat(prefixCol);\n const ansi = prefixAnsi(prefix);\n const col = (s: string) => paint(s, ansi, ctx.tty);\n\n for (const item of arr) {\n if (isPrimitive(item)) {\n const formatted = fmtScalar(item);\n lines.push(col(`${pad}${prefix} ${formatted},`));\n } else if (Array.isArray(item)) {\n if (item.length === 0) {\n lines.push(col(`${pad}${prefix} [],`));\n } else {\n lines.push(col(`${pad}${prefix} [`));\n renderArrayItems(item, prefix, prefixCol + 4, ctx, lines);\n lines.push(col(`${\" \".repeat(prefixCol + 2)}],`));\n }\n } else if (isPlainObject(item)) {\n if (Object.keys(item).length === 0) {\n lines.push(col(`${pad}${prefix} {},`));\n } else {\n lines.push(col(`${pad}${prefix} {`));\n renderFields(item, prefix, prefixCol + 4, ctx, lines);\n lines.push(col(`${\" \".repeat(prefixCol + 2)}},`));\n }\n }\n }\n}\n\n/** Changed-line budget for one block-string diff, before the \"more\" trailer. */\nconst MAX_BLOCK_DIFF_LINES = 20;\n\n/**\n * LCS cell budget (500 × 500 changed lines). Above it the middle section\n * renders as one remove/add block instead — quadratic DP over a pathological\n * template is not worth the memory, and a whole-block replace is still an\n * honest rendering. The shipped designs are under 200 lines *before* the\n * prefix/suffix trim, so real templates never come close.\n */\nconst MAX_LCS_CELLS = 250_000;\n\ntype LineOp = { kind: \"same\" | \"del\" | \"add\"; line: string };\n\nfunction asLines(v: string | number | boolean | null): string[] {\n return typeof v === \"string\" ? v.split(\"\\n\") : [fmtPrimitive(v)];\n}\n\n/**\n * Line-level diff of two block strings. Common prefix and suffix are trimmed\n * first — a template edit touches one region, so this alone usually reduces\n * the problem to a handful of lines — and the remaining middle goes through\n * an LCS pass (or, past {@link MAX_LCS_CELLS}, renders as a wholesale\n * replacement).\n */\nfunction diffLines(oldLines: readonly string[], newLines: readonly string[]): LineOp[] {\n let start = 0;\n while (\n start < oldLines.length &&\n start < newLines.length &&\n oldLines[start] === newLines[start]\n ) {\n start += 1;\n }\n let endOld = oldLines.length;\n let endNew = newLines.length;\n while (endOld > start && endNew > start && oldLines[endOld - 1] === newLines[endNew - 1]) {\n endOld -= 1;\n endNew -= 1;\n }\n\n const midOld = oldLines.slice(start, endOld);\n const midNew = newLines.slice(start, endNew);\n if (midOld.length * midNew.length > MAX_LCS_CELLS) {\n return [\n ...midOld.map((line): LineOp => ({ kind: \"del\", line })),\n ...midNew.map((line): LineOp => ({ kind: \"add\", line })),\n ];\n }\n return lcsDiff(midOld, midNew);\n}\n\n/** Classic LCS-length DP, walked back into an op list. */\nfunction lcsDiff(a: readonly string[], b: readonly string[]): LineOp[] {\n const table: number[][] = [];\n // Reads past the filled edge are the recurrence's base case: an empty suffix, length 0.\n const cell = (i: number, j: number): number => table[i]?.[j] ?? 0;\n\n for (let i = a.length - 1; i >= 0; i -= 1) {\n const row = new Array<number>(b.length + 1).fill(0);\n table[i] = row;\n for (let j = b.length - 1; j >= 0; j -= 1) {\n row[j] = a[i] === b[j] ? cell(i + 1, j + 1) + 1 : Math.max(cell(i + 1, j), cell(i, j + 1));\n }\n }\n\n const ops: LineOp[] = [];\n let i = 0;\n let j = 0;\n while (i < a.length && j < b.length) {\n const left = a[i];\n const right = b[j];\n if (left === undefined || right === undefined) break;\n if (left === right) {\n ops.push({ kind: \"same\", line: left });\n i += 1;\n j += 1;\n } else if (cell(i + 1, j) >= cell(i, j + 1)) {\n ops.push({ kind: \"del\", line: left });\n i += 1;\n } else {\n ops.push({ kind: \"add\", line: right });\n j += 1;\n }\n }\n for (const line of a.slice(i)) ops.push({ kind: \"del\", line });\n for (const line of b.slice(j)) ops.push({ kind: \"add\", line });\n return ops;\n}\n\n/**\n * Render a changed block string as a header plus its changed lines. Context\n * lines are deliberately omitted: the file is on disk, and the plan's job is\n * to name what moved, not to reproduce the template.\n */\nfunction renderBlockStringDiff(\n paddedKey: string,\n oldVal: string | number | boolean | null,\n newVal: string | number | boolean | null,\n prefixCol: number,\n tty: boolean,\n lines: string[],\n): void {\n const pad = \" \".repeat(prefixCol);\n const bodyPad = \" \".repeat(prefixCol + 4);\n const changed = diffLines(asLines(oldVal), asLines(newVal)).filter((op) => op.kind !== \"same\");\n const total = typeof newVal === \"string\" ? lineCount(newVal) : 1;\n const fingerprints =\n typeof oldVal === \"string\" && typeof newVal === \"string\"\n ? `, sha256:${shortHash(oldVal)} -> sha256:${shortHash(newVal)}`\n : \"\";\n\n lines.push(\n paint(\n `${pad}~ ${paddedKey} = (${plural(changed.length, \"line\")} changed of ${total}${fingerprints})`,\n A.yellow,\n tty,\n ),\n );\n for (const op of changed.slice(0, MAX_BLOCK_DIFF_LINES)) {\n const del = op.kind === \"del\";\n const line = escapeControlCharacters(op.line);\n lines.push(paint(`${bodyPad}${del ? \"-\" : \"+\"} ${line}`, del ? A.red : A.green, tty));\n }\n const omitted = changed.length - MAX_BLOCK_DIFF_LINES;\n if (omitted > 0) {\n lines.push(`${bodyPad} # (${plural(omitted, \"more changed line\")} not shown)`);\n }\n}\n\n/**\n * The keys that name an element of an array of objects. A flow's `steps` and\n * each step's `actions` are named by `name`, which the dialect requires to be\n * unique within its list; the others cover any later list of named objects.\n */\nconst ELEMENT_IDENTITY_KEYS = [\"name\", \"id\", \"slug\"] as const;\n\n/**\n * The key that identifies every element of both arrays, or undefined when\n * there is none: every element must be an object carrying that key as a\n * string, unique within its array. Without one, elements can only be matched\n * by position, and a changed array renders as a whole remove + add.\n */\nfunction elementIdentityKey(\n oldArr: ReadonlyArray<unknown>,\n newArr: ReadonlyArray<unknown>,\n): string | undefined {\n const all = [...oldArr, ...newArr];\n if (all.length === 0 || !all.every(isPlainObject)) {\n return undefined;\n }\n return ELEMENT_IDENTITY_KEYS.find((key) =>\n [oldArr, newArr].every((arr) => {\n const ids = arr.map((item) => (item as Record<string, unknown>)[key]);\n return ids.every((id) => typeof id === \"string\") && new Set(ids).size === ids.length;\n }),\n );\n}\n\nfunction sameValue(a: unknown, b: unknown): boolean {\n return stableStringify(a) === stableStringify(b);\n}\n\nfunction hiddenNote(count: number, noun: string): string {\n return `# (${plural(count, `unchanged ${noun}`)} hidden)`;\n}\n\n/**\n * Render a changed array element by element, so one edit inside a long list\n * reads as one change rather than the whole list removed and added again.\n *\n * - Arrays of named objects (a flow's `steps`, a step's `actions`) are matched\n * by {@link elementIdentityKey}. A changed element renders as `~ {` with only\n * what changed in it, plus its name; added and removed elements render\n * whole; unchanged ones collapse into a `# (N unchanged elements hidden)`\n * line. An element that moved renders as removed and added.\n * - Arrays of scalars (`fields`, `required`, `scopes`) render every item, with\n * `+` / `-` on the ones added or removed.\n * - Anything else (objects with no shared identity, nested arrays) falls back\n * to a whole remove + add.\n */\nfunction renderArrayDiff(\n paddedKey: string,\n oldArr: ReadonlyArray<unknown>,\n newArr: ReadonlyArray<unknown>,\n prefixCol: number,\n tty: boolean,\n lines: string[],\n): void {\n const pad = \" \".repeat(prefixCol);\n const itemCol = prefixCol + 4;\n const itemPad = \" \".repeat(itemCol);\n const closePad = \" \".repeat(prefixCol + 2);\n const yellow = (s: string) => paint(s, A.yellow, tty);\n const green = (s: string) => paint(s, A.green, tty);\n const red = (s: string) => paint(s, A.red, tty);\n const identity = elementIdentityKey(oldArr, newArr);\n\n const withinBudget = oldArr.length * newArr.length <= MAX_LCS_CELLS;\n\n if (identity !== undefined && withinBudget) {\n const idOf = (item: unknown) => (item as Record<string, string>)[identity] as string;\n const oldById = new Map(oldArr.map((item) => [idOf(item), item]));\n const newById = new Map(newArr.map((item) => [idOf(item), item]));\n\n lines.push(yellow(`${pad}~ ${paddedKey} = [`));\n let hidden = 0;\n const flushHidden = () => {\n if (hidden > 0) {\n lines.push(`${itemPad} ${hiddenNote(hidden, \"element\")}`);\n hidden = 0;\n }\n };\n for (const op of lcsDiff(oldArr.map(idOf), newArr.map(idOf))) {\n const before = oldById.get(op.line) as Record<string, unknown>;\n const after = newById.get(op.line) as Record<string, unknown>;\n if (op.kind === \"same\" && sameValue(before, after)) {\n hidden += 1;\n continue;\n }\n flushHidden();\n if (op.kind === \"same\") {\n lines.push(yellow(`${itemPad}~ {`));\n renderDiff(before, after, itemCol + 4, tty, lines, { compact: true, identity });\n lines.push(yellow(`${\" \".repeat(itemCol + 2)}},`));\n } else {\n const removed = op.kind === \"del\";\n renderArrayItems(\n [removed ? before : after],\n removed ? \"-\" : \"+\",\n itemCol,\n { tty, deleteMode: false },\n lines,\n );\n }\n }\n flushHidden();\n lines.push(yellow(`${closePad}]`));\n return;\n }\n\n if (withinBudget && [...oldArr, ...newArr].every(isPrimitive)) {\n const label = (item: unknown) => fmtScalar(item as string | number | boolean | null);\n lines.push(yellow(`${pad}~ ${paddedKey} = [`));\n for (const op of lcsDiff(oldArr.map(label), newArr.map(label))) {\n if (op.kind === \"same\") {\n lines.push(`${itemPad} ${op.line},`);\n } else if (op.kind === \"add\") {\n lines.push(green(`${itemPad}+ ${op.line},`));\n } else {\n lines.push(red(`${itemPad}- ${op.line},`));\n }\n }\n lines.push(yellow(`${closePad}]`));\n return;\n }\n\n if (oldArr.length === 0) {\n lines.push(red(`${pad}- ${paddedKey} = []`));\n } else {\n lines.push(red(`${pad}- ${paddedKey} = [`));\n renderArrayItems(oldArr, \"-\", itemCol, { tty, deleteMode: false }, lines);\n lines.push(red(`${closePad}]`));\n }\n if (newArr.length === 0) {\n lines.push(green(`${pad}+ ${paddedKey} = []`));\n } else {\n lines.push(green(`${pad}+ ${paddedKey} = [`));\n renderArrayItems(newArr, \"+\", itemCol, { tty, deleteMode: false }, lines);\n lines.push(green(`${closePad}]`));\n }\n}\n\n/**\n * How {@link renderDiff} renders what did not change.\n *\n * `compact` hides unchanged attributes behind one `# (N unchanged attributes\n * hidden)` line, for the inside of a changed array element: there the point is\n * which element changed and how, and its untouched rest is noise. `identity`\n * names the attribute that is shown anyway, so the element can be recognised.\n */\ntype DiffOptions = { compact?: boolean; identity?: string };\n\n/**\n * Walks both old and new objects, emitting Terraform-style change lines.\n * Returns true if any actual change line (+ / - / ~) was emitted.\n *\n * Edge cases:\n * - Changed arrays render element by element ({@link renderArrayDiff}).\n * - An unchanged array that holds objects collapses to a hidden-elements\n * line: a flow's whole `steps` list is not context for a top-level edit.\n * - Nested objects recurse, and the outer key is only marked `~` if a child\n * actually changed; unchanged children render with the neutral prefix.\n * - A value whose type changed (e.g. string → object) also renders as a\n * remove + add pair.\n */\nfunction renderDiff(\n oldObj: Record<string, unknown>,\n newObj: Record<string, unknown>,\n prefixCol: number,\n tty: boolean,\n lines: string[],\n options: DiffOptions = {},\n): boolean {\n const allKeys = [...new Set([...Object.keys(oldObj), ...Object.keys(newObj)])].sort();\n const unchanged = (key: string) =>\n Object.hasOwn(oldObj, key) && Object.hasOwn(newObj, key) && sameValue(oldObj[key], newObj[key]);\n const shown = options.compact\n ? allKeys.filter((key) => key === options.identity || !unchanged(key))\n : allKeys;\n const maxLen = shown.reduce((m, k) => Math.max(m, fieldLabel(k).length), 0);\n const pad = \" \".repeat(prefixCol);\n let hasChanges = false;\n\n for (const key of shown) {\n const pk = fieldLabel(key).padEnd(maxLen);\n const hasOld = Object.hasOwn(oldObj, key);\n const hasNew = Object.hasOwn(newObj, key);\n const oldVal = oldObj[key];\n const newVal = newObj[key];\n\n if (!hasOld) {\n hasChanges = true;\n const col = (s: string) => paint(s, A.green, tty);\n if (isPrimitive(newVal)) {\n lines.push(col(`${pad}+ ${pk} = ${fmtScalar(newVal)}`));\n } else if (Array.isArray(newVal)) {\n lines.push(col(`${pad}+ ${pk} = [`));\n renderArrayItems(newVal, \"+\", prefixCol + 4, { tty, deleteMode: false }, lines);\n lines.push(col(`${\" \".repeat(prefixCol + 2)}]`));\n } else if (isPlainObject(newVal)) {\n lines.push(col(`${pad}+ ${pk} = {`));\n renderFields(newVal, \"+\", prefixCol + 4, { tty, deleteMode: false }, lines);\n lines.push(col(`${\" \".repeat(prefixCol + 2)}}`));\n }\n } else if (!hasNew) {\n hasChanges = true;\n const col = (s: string) => paint(s, A.red, tty);\n if (isPrimitive(oldVal)) {\n lines.push(col(`${pad}- ${pk} = ${fmtScalar(oldVal)} -> null`));\n } else if (Array.isArray(oldVal)) {\n lines.push(col(`${pad}- ${pk} = [`));\n renderArrayItems(oldVal, \"-\", prefixCol + 4, { tty, deleteMode: false }, lines);\n lines.push(col(`${\" \".repeat(prefixCol + 2)}]`));\n } else if (isPlainObject(oldVal)) {\n lines.push(col(`${pad}- ${pk} = {`));\n renderFields(oldVal, \"-\", prefixCol + 4, { tty, deleteMode: true }, lines);\n lines.push(col(`${\" \".repeat(prefixCol + 2)}}`));\n }\n } else if (isPrimitive(oldVal) && isPrimitive(newVal)) {\n if (oldVal === newVal) {\n lines.push(\n isBlockString(newVal)\n ? `${pad} ${pk} = ${unchangedBlockSummary(newVal)}`\n : `${pad} ${pk} = ${fmtPrimitive(newVal)}`,\n );\n } else if (isBlockString(oldVal) || isBlockString(newVal)) {\n hasChanges = true;\n renderBlockStringDiff(pk, oldVal, newVal, prefixCol, tty, lines);\n } else {\n hasChanges = true;\n const col = (s: string) => paint(s, A.yellow, tty);\n lines.push(col(`${pad}~ ${pk} = ${fmtPrimitive(oldVal)} -> ${fmtPrimitive(newVal)}`));\n }\n } else if (Array.isArray(oldVal) && Array.isArray(newVal)) {\n // Key-order-insensitive equality: the server echoes objects in its own\n // field order while local files are stably sorted — that difference is\n // not a change.\n if (sameValue(oldVal, newVal)) {\n if (newVal.length === 0) {\n lines.push(`${pad} ${pk} = []`);\n } else if (newVal.every(isPrimitive)) {\n lines.push(`${pad} ${pk} = [`);\n renderArrayItems(newVal, \" \", prefixCol + 4, { tty, deleteMode: false }, lines);\n lines.push(`${\" \".repeat(prefixCol + 2)}]`);\n } else {\n lines.push(`${pad} ${pk} = [`);\n lines.push(`${\" \".repeat(prefixCol + 4)} ${hiddenNote(newVal.length, \"element\")}`);\n lines.push(`${\" \".repeat(prefixCol + 2)}]`);\n }\n } else {\n hasChanges = true;\n renderArrayDiff(pk, oldVal, newVal, prefixCol, tty, lines);\n }\n } else if (isPlainObject(oldVal) && isPlainObject(newVal)) {\n const childLines: string[] = [];\n const childHasChanges = renderDiff(\n oldVal,\n newVal,\n prefixCol + 4,\n tty,\n childLines,\n options.compact ? { compact: true } : {},\n );\n if (childHasChanges) {\n hasChanges = true;\n const col = (s: string) => paint(s, A.yellow, tty);\n lines.push(col(`${pad}~ ${pk} = {`));\n lines.push(...childLines);\n lines.push(col(`${\" \".repeat(prefixCol + 2)}}`));\n } else if (childLines.length > 0) {\n lines.push(`${pad} ${pk} = {`);\n lines.push(...childLines);\n lines.push(`${\" \".repeat(prefixCol + 2)}}`);\n } else {\n lines.push(`${pad} ${pk} = {}`);\n }\n } else {\n hasChanges = true;\n const colR = (s: string) => paint(s, A.red, tty);\n const colA = (s: string) => paint(s, A.green, tty);\n if (isPrimitive(oldVal)) {\n lines.push(colR(`${pad}- ${pk} = ${fmtScalar(oldVal)} -> null`));\n }\n if (isPrimitive(newVal)) {\n lines.push(colA(`${pad}+ ${pk} = ${fmtScalar(newVal)}`));\n }\n }\n }\n\n const hidden = allKeys.length - shown.length;\n if (hidden > 0) {\n lines.push(`${pad} ${hiddenNote(hidden, \"attribute\")}`);\n }\n return hasChanges;\n}\n\n/**\n * Column layout (matches Terraform's per-block format):\n * BLOCK_COL = 2 — where the +/-/~ sits on the resource opening line\n * FIELD_COL = 6 — where the +/-/~ sits on first-level field lines\n * closing } — at BLOCK_COL + 2 = 4, no prefix\n */\nconst BLOCK_COL = 2;\nconst FIELD_COL = 6;\n\nfunction resourceName(path: string): string {\n return path.split(\"/\").pop() ?? path;\n}\n\n/**\n * Diff both sides in the syncer's canonical form so server-echoed noise\n * (empty `audience`, spelled-out meta-schema defaults) never renders as a\n * change the author didn't make. Rendering only — upload payloads stay raw.\n */\nfunction normalized(\n syncer: Pick<ResourceSyncer, \"normalize\">,\n content: object,\n): Record<string, unknown> {\n return (syncer.normalize?.(content) ?? content) as Record<string, unknown>;\n}\n\n/**\n * Renders one Terraform-style resource block for a single `SyncAction`.\n *\n * Per-case notes:\n * - **create**: a synthetic `id = (known after apply)` is injected into the\n * rendered fields so it sorts alphabetically alongside the real keys.\n * - **delete**: when `oldContent` is null (the fetch failed), the body\n * collapses to a single `- id = \"<id>\" -> null` line.\n * - **update**: when `oldContent` is null (no read endpoint for this\n * resource kind), the field diff is replaced with a placeholder\n * \"field diff unavailable\" line.\n * - **skip**: omitted from the output entirely, matching Terraform's\n * default of not showing no-change resources.\n */\nfunction renderBlock(action: SyncAction, tty: boolean): string[] {\n const lines: string[] = [];\n const blkPad = \" \".repeat(BLOCK_COL);\n const closePad = \" \".repeat(BLOCK_COL + 2);\n\n switch (action.kind) {\n case \"create\": {\n if (action.movedFrom !== undefined && action.oldContent !== undefined) {\n // The platform already holds the resource, so show what changes in it\n // the way an update does, under a header that says where it came from.\n const [, ...diff] = renderBlock(\n {\n kind: \"update\",\n path: action.path,\n syncer: action.syncer,\n id: \"\",\n content: action.content,\n hash: action.hash,\n oldContent: action.oldContent,\n ...(action.warnings ? { warnings: action.warnings } : {}),\n },\n tty,\n );\n return [\n paint(\n `${blkPad}# ${action.path} will take over the ${action.syncer.kind} that was in ${action.movedFrom}`,\n A.bold,\n tty,\n ),\n ...diff,\n ];\n }\n const header =\n action.movedFrom === undefined\n ? `${blkPad}# ${action.path} will be created`\n : `${blkPad}# ${action.path} will take over the ${action.syncer.kind} that was in ${action.movedFrom}`;\n const opening = `${blkPad}+ resource \"${action.syncer.kind}\" \"${resourceName(action.path)}\" {`;\n lines.push(paint(header, A.bold, tty));\n lines.push(paint(opening, A.green, tty));\n\n const display: Record<string, unknown> = {\n id: KNOWN_AFTER_APPLY,\n ...(action.content as Record<string, unknown>),\n };\n if (action.repin) {\n // The executor POSTs this flow with the new revision id, not the\n // stale pin still in the file — render what will actually be sent.\n display.user_schema = action.repin.newId ?? KNOWN_AFTER_APPLY;\n }\n renderFields(display, \"+\", FIELD_COL, { tty, deleteMode: false }, lines);\n lines.push(`${closePad}}`);\n renderWarnings(action.warnings, blkPad, tty, lines);\n break;\n }\n\n case \"delete\": {\n const header = `${blkPad}# ${action.path} will be destroyed`;\n const opening = `${blkPad}- resource \"${action.syncer.kind}\" \"${resourceName(action.path)}\" {`;\n lines.push(paint(header, A.bold, tty));\n lines.push(paint(opening, A.red, tty));\n\n if (action.oldContent) {\n const display: Record<string, unknown> = {\n id: action.id,\n ...(action.oldContent as Record<string, unknown>),\n };\n renderFields(display, \"-\", FIELD_COL, { tty, deleteMode: true }, lines);\n } else {\n lines.push(paint(`${\" \".repeat(FIELD_COL)}- id = \"${action.id}\" -> null`, A.red, tty));\n }\n lines.push(`${closePad}}`);\n break;\n }\n\n case \"update\": {\n const headerSuffix = action.repin ? \" (re-pin user_schema)\" : \"\";\n const header = `${blkPad}# ${action.path} will be updated in-place${headerSuffix}`;\n const opening = `${blkPad}~ resource \"${action.syncer.kind}\" \"${resourceName(action.path)}\" {`;\n lines.push(paint(header, A.bold, tty));\n lines.push(paint(opening, A.yellow, tty));\n\n // A repin update ships with `user_schema` rewritten to the revision id\n // the revise mints (or already minted, for crash recovery) — render the\n // content the executor will actually PUT.\n const newContent = action.repin\n ? {\n ...normalized(action.syncer, action.content),\n user_schema: action.repin.newId ?? KNOWN_AFTER_APPLY,\n }\n : normalized(action.syncer, action.content);\n\n if (action.oldContent) {\n renderDiff(normalized(action.syncer, action.oldContent), newContent, FIELD_COL, tty, lines);\n } else if (action.repin) {\n lines.push(\n paint(\n `${\" \".repeat(FIELD_COL)}~ user_schema = \"${action.repin.previousId}\" -> ${action.repin.newId ? `\"${action.repin.newId}\"` : KNOWN_AFTER_APPLY}`,\n A.yellow,\n tty,\n ),\n );\n } else {\n lines.push(\n `${\" \".repeat(FIELD_COL)} # (field diff unavailable — no read endpoint for ${action.syncer.kind})`,\n );\n }\n lines.push(`${closePad}}`);\n renderWarnings(action.warnings, blkPad, tty, lines);\n break;\n }\n\n case \"revise\": {\n const headerSuffix = action.repin ? \" (re-pin user_schema)\" : \"\";\n const header = `${blkPad}# ${action.path} will publish a new revision${headerSuffix}`;\n const opening = `${blkPad}~ resource \"${action.syncer.kind}\" \"${resourceName(action.path)}\" {`;\n lines.push(paint(header, A.bold, tty));\n lines.push(paint(opening, A.yellow, tty));\n\n // A repin revision ships with `user_schema` rewritten to the revision\n // id the schema revise mints (or already minted, for crash recovery) —\n // render the content the executor will actually POST.\n const newWithId: Record<string, unknown> = {\n id: KNOWN_AFTER_APPLY,\n ...normalized(action.syncer, action.content),\n ...(action.repin ? { user_schema: action.repin.newId ?? KNOWN_AFTER_APPLY } : {}),\n };\n if (action.oldContent) {\n const oldWithId: Record<string, unknown> = {\n id: action.previousId,\n ...normalized(action.syncer, action.oldContent),\n };\n renderDiff(oldWithId, newWithId, FIELD_COL, tty, lines);\n } else if (action.repin) {\n lines.push(\n paint(\n `${\" \".repeat(FIELD_COL)}~ user_schema = \"${action.repin.previousId}\" -> ${action.repin.newId ? `\"${action.repin.newId}\"` : KNOWN_AFTER_APPLY}`,\n A.yellow,\n tty,\n ),\n );\n } else {\n lines.push(\n `${\" \".repeat(FIELD_COL)} # (field diff unavailable — no read endpoint for ${action.syncer.kind})`,\n );\n }\n lines.push(`${closePad}}`);\n renderWarnings(action.warnings, blkPad, tty, lines);\n if (action.affectedPaths.length > 0) {\n lines.push(\n paint(\n `${blkPad}# user_schema will be re-pinned to the new revision ${KNOWN_AFTER_APPLY} in:`,\n A.yellow,\n tty,\n ),\n );\n for (const path of action.affectedPaths) {\n lines.push(paint(`${blkPad}# - ${path}`, A.yellow, tty));\n }\n }\n break;\n }\n\n case \"skip\":\n break;\n }\n\n return lines;\n}\n\n/**\n * Emit one yellow `# warning:` comment line per plan-time validation\n * warning, below the action's closing brace (same channel as the revise\n * re-pin announcement). Warnings never block the plan.\n */\nfunction renderWarnings(\n warnings: ReadonlyArray<{ message: string }> | undefined,\n blkPad: string,\n tty: boolean,\n lines: string[],\n): void {\n for (const warning of warnings ?? []) {\n lines.push(paint(`${blkPad}# warning: ${warning.message}`, A.yellow, tty));\n }\n}\n","import { basename } from \"node:path\";\n\nimport { type ProjectTree, validateProject } from \"@zitadel/config/validate\";\n\nimport { ZitadelError } from \"../errors\";\nimport { FLOWS_DIR } from \"../flows\";\nimport { IDPS_DIR } from \"../idp\";\nimport { SCHEMAS_DIR } from \"../user-schema\";\nimport { reportWarning } from \"../warnings\";\nimport { isUnsupportedDeletion, type UnsupportedDeletion } from \"./plan-renderer.js\";\nimport type { ResourceEntry, SyncAction } from \"./types.js\";\n\n/**\n * Cross-file checks on the SSO configuration, before anything is sent.\n *\n * A flow that offers a provider its schema does not list, or a schema that\n * lists a provider with no connection file, is only visible when the files are\n * read together, and the server would reveal it mid-apply or not at all. This\n * reads the whole working tree, so the rules can see what each file points at,\n * and throws one E_VALIDATION naming every problem it reports, so `plan` and\n * `apply` both stop before any request.\n *\n * It reports only what this plan touches: the files it writes and the files\n * those reference or are referenced by. An applied project is never re-judged\n * for a file nobody edited, so a rule added later cannot stop an unrelated\n * connection edit, and a plan with no edits does not fail on a rule change.\n *\n * A removed file whose resource the platform keeps is the one exception to\n * \"touches\": a schema that still lists a connection with no file is\n * inconsistent however it got there, and stays reported until it is fixed.\n */\nexport async function validatePlannedSso(opts: {\n actions: SyncAction[];\n scannedContents: ReadonlyMap<string, object>;\n stateResources: Readonly<Record<string, ResourceEntry>>;\n /** What names the resource a kept removal left on the platform, read only when it is needed. */\n slugOfKept?: (kept: UnsupportedDeletion) => Promise<string | undefined>;\n}): Promise<void> {\n // Already announced once by flow validation, which runs first.\n if (process.env.ZITADEL_SKIP_FLOW_VALIDATION) {\n return;\n }\n const writes = opts.actions.filter(\n (action) =>\n (action.kind === \"create\" || action.kind === \"update\" || action.kind === \"revise\") &&\n [\"schema\", \"flow\", \"idp\"].includes(action.syncer.kind),\n );\n const keptRemovals = opts.actions.filter(\n (action): action is UnsupportedDeletion =>\n isUnsupportedDeletion(action) && action.syncer.kind === \"idp\",\n );\n if (writes.length === 0 && keptRemovals.length === 0) {\n return;\n }\n\n const inDir = (dir: string) =>\n new Map([...opts.scannedContents].filter(([path]) => path.startsWith(`${dir}/`)));\n const schemas = inDir(SCHEMAS_DIR);\n const repins = new Map(\n writes.flatMap((action) =>\n \"repin\" in action && action.repin ? [[action.path, action.repin.schemaPath] as const] : [],\n ),\n );\n\n const flows = new Map(\n [...inDir(FLOWS_DIR)].map(([path, body]) => {\n const schemaPath = pinnedSchemaPath(path, body, schemas, repins, opts.stateResources);\n // Said aloud, because the alternative is a flow that passes by not being\n // checked: its schema may be one this project does not keep locally.\n if (schemaPath === undefined && offeredProviders(body).length > 0) {\n reportWarning(\n `${path}: could not tell which local schema this flow pins, so its provider rules were not checked against a schema`,\n );\n }\n return [path, { body, schemaPath }];\n }),\n );\n const tree: ProjectTree = { schemas, flows, connections: inDir(IDPS_DIR) };\n\n const written = writes.map((action) => action.path);\n const relevant = touchedFiles(written, tree);\n const connectionEdited = written.some((path) => tree.connections.has(path));\n const found = validateProject(tree);\n // A connection stands against every other one only where they collide.\n const collisions = new Set<string>([\"sso/duplicate-slug\", \"sso/shared-variable\"]);\n // A kept removal leaves its connection on the platform: a schema or flow that\n // still names that slug with no file is inconsistent however it got there.\n const keptSlugs =\n keptRemovals.length > 0 && found.some((issue) => issue.rule === \"sso/connection-resolves\")\n ? new Set(await Promise.all(keptRemovals.map((kept) => opts.slugOfKept?.(kept))))\n : new Set<string | undefined>();\n const issues = found.filter(\n (issue) =>\n relevant.has(issue.file) ||\n (connectionEdited && collisions.has(issue.rule) && tree.connections.has(issue.file)) ||\n (issue.rule === \"sso/connection-resolves\" && keptSlugs.has(issue.slug)),\n );\n if (issues.length === 0) {\n return;\n }\n const noun = issues.length === 1 ? \"issue\" : \"issues\";\n throw new ZitadelError(\n \"E_VALIDATION\",\n `SSO configuration is not consistent (${issues.length} ${noun}):\\n` +\n issues.map((issue) => ` - ${issue.file}: ${issue.message}`).join(\"\\n\"),\n {\n hint:\n \"These checks read the schemas, flows and connection files together. \" +\n \"Fix the files named above and re-run plan; no changes were made. \" +\n \"Only the CLI makes these checks. Setting ZITADEL_SKIP_FLOW_VALIDATION skips them, \" +\n \"along with flow validation.\",\n details: {\n issues: issues.map(({ rule, file, steps, message }) => ({\n rule,\n path: file,\n ...(steps === undefined ? {} : { steps }),\n message,\n })),\n },\n },\n );\n}\n\n/**\n * The files a plan touches and the files they point at or are pointed at by:\n * a connection and the schemas and flows that name its slug, a schema and the\n * connections it lists and the flows pinned to it, a flow and its schema and the\n * connections it offers.\n */\nfunction touchedFiles(written: readonly string[], tree: ProjectTree): Set<string> {\n const related = new Set(written);\n const slugOf = (body: object) => (body as { slug?: unknown }).slug;\n const connectionsListing = (slugs: readonly string[]) =>\n [...tree.connections].filter(([, body]) => slugs.includes(slugOf(body) as string));\n for (const path of written) {\n if (tree.connections.has(path)) {\n const slug = slugOf(tree.connections.get(path) as object);\n for (const [schemaPath, schema] of tree.schemas) {\n if (schemaProviders(schema).includes(slug as string)) {\n related.add(schemaPath);\n }\n }\n for (const [flowPath, { body }] of tree.flows) {\n if (offeredProviders(body).includes(slug as string)) {\n related.add(flowPath);\n }\n }\n }\n const schema = tree.schemas.get(path);\n if (schema !== undefined) {\n for (const [connectionPath] of connectionsListing(schemaProviders(schema))) {\n related.add(connectionPath);\n }\n for (const [flowPath, flow] of tree.flows) {\n if (flow.schemaPath === path) {\n related.add(flowPath);\n }\n }\n }\n const flow = tree.flows.get(path);\n if (flow !== undefined) {\n if (flow.schemaPath !== undefined) {\n related.add(flow.schemaPath);\n }\n for (const [connectionPath] of connectionsListing(offeredProviders(flow.body))) {\n related.add(connectionPath);\n }\n }\n }\n return related;\n}\n\n/** The provider slugs a schema lists in `x-auth-methods.sso.providers`. */\nfunction schemaProviders(schema: object): string[] {\n const methods = (schema as { \"x-auth-methods\"?: { sso?: { providers?: unknown } } })[\n \"x-auth-methods\"\n ];\n const providers = methods?.sso?.providers;\n return Array.isArray(providers)\n ? providers.filter((item): item is string => typeof item === \"string\")\n : [];\n}\n\n/** The provider slugs the steps of a flow offer. */\nfunction offeredProviders(flow: object): string[] {\n const steps = (flow as { steps?: unknown }).steps;\n if (!Array.isArray(steps)) {\n return [];\n }\n return steps.flatMap((step) => {\n const providers =\n typeof step === \"object\" && step !== null\n ? (step as { sso_providers?: unknown }).sso_providers\n : undefined;\n return Array.isArray(providers)\n ? providers.filter((item): item is string => typeof item === \"string\")\n : [];\n });\n}\n\n/**\n * The local schema a flow's `user_schema` pins, or `undefined` when it cannot\n * be told. A flow names its schema by `objectType`, by the id the platform\n * assigned, or by the URL an older setup wrote, and a re-pin in this plan names\n * the file outright.\n */\nfunction pinnedSchemaPath(\n flowPath: string,\n flow: object,\n schemas: ReadonlyMap<string, object>,\n repins: ReadonlyMap<string, string>,\n stateResources: Readonly<Record<string, ResourceEntry>>,\n): string | undefined {\n const repinned = repins.get(flowPath);\n if (repinned !== undefined) {\n return repinned;\n }\n const ref = (flow as { user_schema?: unknown }).user_schema;\n if (typeof ref !== \"string\" || ref === \"\") {\n return undefined;\n }\n for (const [path, schema] of schemas) {\n const { $id, objectType } = schema as { $id?: unknown; objectType?: unknown };\n if (stateResources[path]?.id === ref || $id === ref || objectType === ref) {\n return path;\n }\n }\n // The URL setup wrote names the schema by file, and only until it is applied.\n // Once the platform has given a schema an id, flows pin that id, so a URL\n // that merely ends in the same file name is another schema (a server-side\n // one this project does not keep) and must not be judged as this one.\n const named = [...schemas.keys()].filter(\n (path) => stateResources[path]?.id === undefined && ref.endsWith(`/${basename(path)}`),\n );\n return named.length === 1 ? named[0] : undefined;\n}\n","import { createHash } from \"node:crypto\";\nimport { readdir, readFile, writeFile } from \"node:fs/promises\";\nimport { basename, join, sep } from \"node:path\";\n\nimport { ApiError } from \"@zitadel/api/runtime/fetch\";\nimport { consola } from \"consola\";\n\nimport { ZitadelError } from \"../errors\";\nimport { FLOWS_DIR } from \"../flows\";\nimport { stableStringify } from \"../json\";\nimport { annotateAssetWarnings } from \"./asset-probe.js\";\nimport { validatePlannedFlows } from \"./flow-validation.js\";\nimport { validatePlannedSso } from \"./sso-validation.js\";\nimport {\n isUnsupportedDeletion,\n type PlanResourceChange,\n unsupportedDeletionNote,\n type UnsupportedDeletion,\n} from \"./plan-renderer.js\";\nimport { moveInState, readState, removeFromState, updateState } from \"./state.js\";\nimport { FatalFetchError } from \"./types.js\";\nimport type { FlowRepin, ResourceEntry, ResourceSyncer, SyncAction } from \"./types.js\";\nimport { reportWarning } from \"../warnings\";\n\n/**\n * Compute the sync plan for `cwd` against the state file and (when\n * `fetchOld` is true) the platform API. The plan is read-only: it\n * decides what create/update/revise/delete operations need to happen but\n * performs none of them. Pass it to {@link runSyncLoop} to execute.\n *\n * Validates every on-disk file (via `syncer.validate`) before planning any\n * work — a single malformed schema or flow aborts the whole run with\n * `E_VALIDATION` before any platform mutation. Both `plan` and `apply`\n * reach this code path.\n *\n * Bearer auth + base URL live in the api package's runtime registries\n * (`runtime/{auth,base-url}`). Callers set them once at command boot;\n * the sync engine doesn't carry a client.\n *\n * @param cwd - Project root.\n * @param syncers - Per-resource adapters. Order is preserved in the output.\n * @param fetchOld - When true, the planner fetches each delete/update target\n * from the platform to populate `oldContent` for diff rendering.\n */\nexport async function buildSyncPlan(\n cwd: string,\n syncers: ReadonlyArray<ResourceSyncer>,\n fetchOld = false,\n): Promise<ReadonlyArray<SyncAction>> {\n const state = await readState(cwd);\n const actions: SyncAction[] = [];\n\n // Walk local flow files once, up front: revisioned schemas need to name every\n // flow whose `user_schema` currently pins the previous revision, so the\n // executor can re-pin those flows after the new revision is published.\n const localFlows = await readLocalFlowUserSchemas(cwd);\n\n // Revisions this plan will publish, keyed by the superseded id. Schema\n // syncers run before the flow syncer (makeSyncers order), so every pending\n // revise is known by the time flow files are planned.\n const pendingRevisions = new Map<string, { schemaPath: string }>();\n\n // Revisions an interrupted earlier run already published (state advanced,\n // `previousId` recorded) whose flows were never rewritten: superseded id →\n // the concrete new id. Lets a rerun finish the re-pin with no new revise.\n const recoveredRevisions = new Map<string, { schemaPath: string; newId: string }>();\n for (const [schemaPath, entry] of Object.entries(state.resources)) {\n if (entry.previousId && entry.id && entry.previousId !== entry.id) {\n recoveredRevisions.set(entry.previousId, { schemaPath, newId: entry.id });\n }\n }\n\n // Every scanned file body, keyed by project-relative path. Schema syncers\n // run before the flow syncer, so by the time a re-pin is planned the new\n // schema revision's content is available for the pre-flight field check.\n const scannedContents = new Map<string, object>();\n\n for (const syncer of syncers) {\n const dirPath = join(cwd, syncer.directory);\n consola.debug(`scanning ${syncer.directory}`);\n const onDisk = await readJsonDir(dirPath);\n\n // A singleton syncer owns exactly one descriptor file. Failing on extras\n // beats scanning them: a stray copy (branding.backup.json) would\n // otherwise be published as one more live revision.\n if (syncer.singletonFile) {\n for (const absPath of onDisk.keys()) {\n const name = basename(absPath);\n if (name !== syncer.singletonFile) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `unexpected file in ${syncer.directory}: ${name}`,\n {\n hint:\n `${syncer.kind} is a singleton resource — keep exactly one descriptor at ` +\n `${syncer.directory}/${syncer.singletonFile} and move other .json files ` +\n `out of the directory (each scanned descriptor would publish as its own revision).`,\n },\n );\n }\n }\n }\n\n for (const [absPath, content] of onDisk.entries()) {\n syncer.validate(content, toStatePath(absPath, cwd));\n }\n\n for (const [filePath, entry] of Object.entries(state.resources)) {\n if (!filePath.startsWith(syncer.directory)) {\n continue;\n }\n if (onDisk.has(join(cwd, filePath)) || !entry.id) {\n continue;\n }\n\n if (syncer.deletion === \"unsupported\") {\n actions.push({\n kind: \"skip\",\n path: filePath,\n reason: \"unsupported-deletion\",\n syncer,\n id: entry.id,\n });\n continue;\n }\n\n let oldContent: object | null = null;\n if (fetchOld && syncer.fetch) {\n try {\n oldContent = await syncer.fetch(entry.id);\n } catch (err) {\n if (err instanceof FatalFetchError) {\n throw err.reason;\n }\n consola.debug(`fetch ${syncer.kind} ${entry.id} failed:`, err);\n }\n }\n actions.push({ kind: \"delete\", path: filePath, syncer, id: entry.id, oldContent });\n }\n\n for (const [absPath, content] of onDisk.entries()) {\n const relPath = toStatePath(absPath, cwd);\n scannedContents.set(relPath, content);\n const entry = state.resources[relPath];\n const hash = hashForState(syncer, content);\n\n // A flow pinned to a schema revision superseded in this plan (or by an\n // interrupted earlier run) needs its `user_schema` rewritten — whether\n // the flow is untouched, edited, or brand new (a create in the same\n // run as the revise must not POST the stale id).\n const flowRef = localFlows.get(relPath);\n const pending = flowRef ? pendingRevisions.get(flowRef) : undefined;\n const recovered = flowRef ? recoveredRevisions.get(flowRef) : undefined;\n const repin = pending\n ? { previousId: flowRef as string, schemaPath: pending.schemaPath }\n : recovered\n ? {\n previousId: flowRef as string,\n schemaPath: recovered.schemaPath,\n newId: recovered.newId,\n }\n : undefined;\n\n if (!entry?.id) {\n actions.push({\n kind: \"create\",\n path: relPath,\n syncer,\n content,\n hash,\n ...(repin ? { repin } : {}),\n });\n continue;\n }\n\n // State files written before normalized hashing hold legacy hashes\n // (order-sensitive, un-normalized). Accepting the legacy format —\n // both over the raw file and over its stably-sorted form, since\n // setup-era hashes were computed on sorted keys — keeps an untouched\n // or merely reordered file a skip; a spurious mismatch here would\n // publish a garbage schema revision. Writes always store the new\n // format, so state converges on the next real change.\n //\n // Only the two pre-normalization formats are accepted, not earlier\n // generations of a normalizer. Widening a normalizer changes this\n // hash for the bodies it newly touches, which costs one no-op\n // revision on the next apply; keeping a copy of every past\n // normalizer to avoid that would outlast the state files it serves.\n //\n // A syncer that gained its first normalizer (connections, which read a\n // left-out default as the server's) also accepts the hash of the\n // un-normalized body, which is what its state entries hold. The file has\n // to be byte-for-byte what was hashed for that to match, so it is the\n // same file.\n const unchanged =\n entry.hash === hash ||\n entry.hash === hashResourceContent(content) ||\n entry.hash === hashResourceContent(JSON.parse(stableStringify(content)) as object) ||\n (syncer.normalize !== undefined && entry.hash === hashForState({}, content));\n // A re-pin is an upload of an otherwise unchanged file, so it needs a\n // syncer that can upload: an update for a mutable one, a new revision\n // for a revisioned one (flows).\n const canRepin = syncer.mutable || syncer.revisioned;\n if (unchanged && !(repin && canRepin)) {\n actions.push({ kind: \"skip\", path: relPath, reason: \"no-change\" });\n continue;\n }\n\n if (syncer.revisioned) {\n const oldContent = await fetchOldIfAsked(syncer, entry.id, fetchOld);\n pendingRevisions.set(entry.id, { schemaPath: relPath });\n actions.push({\n kind: \"revise\",\n path: relPath,\n syncer,\n content,\n hash,\n previousId: entry.id,\n oldContent,\n affectedPaths: findFlowsPinnedTo(entry.id, localFlows),\n ...(repin ? { repin } : {}),\n });\n continue;\n }\n\n if (!syncer.mutable) {\n actions.push({ kind: \"skip\", path: relPath, reason: \"immutable\" });\n continue;\n }\n\n const oldContent = await fetchOldIfAsked(syncer, entry.id, fetchOld);\n actions.push({\n kind: \"update\",\n path: relPath,\n syncer,\n id: entry.id,\n content,\n hash,\n oldContent,\n ...(repin ? { repin } : {}),\n });\n }\n }\n\n // Semantic pre-flight over every flow this plan uploads — the rules the\n // server would otherwise enforce mid-apply, after the schema revision\n // already published. Throws E_VALIDATION before any mutation.\n validatePlannedFlows({ actions, scannedContents, stateResources: state.resources });\n // The rules that read schemas, flows and connections together.\n await validatePlannedSso({\n actions,\n scannedContents,\n stateResources: state.resources,\n slugOfKept: async (kept) => {\n const stored = await readStored(kept.syncer, kept.id);\n return stored === null ? undefined : kept.syncer.identityOf?.(stored);\n },\n });\n\n // What only the platform can answer, for every file this plan writes. After\n // the local checks, so a mistake that needs no request is never hidden behind one.\n for (const action of [...actions]) {\n if ((action.kind === \"create\" || action.kind === \"update\") && action.syncer.preflight) {\n const old = action.kind === \"update\" ? await storedBody(action) : null;\n const existing = await action.syncer.preflight(action.path, action.content, old);\n if (action.kind === \"create\" && existing !== undefined) {\n // The platform already holds this resource, and a removed file the plan\n // declines to delete is where it used to live: that is a move, not a new\n // resource, and the removal is no longer a loose end.\n const declined = actions.find(\n (other): other is UnsupportedDeletion =>\n isUnsupportedDeletion(other) &&\n other.syncer === action.syncer &&\n other.id === existing.id,\n );\n if (declined !== undefined) {\n action.movedFrom = declined.path;\n action.oldContent = existing.definition;\n actions.splice(actions.indexOf(declined), 1);\n }\n }\n }\n }\n\n // Reachability pre-flight for branding asset URLs. Annotates warnings only:\n // the machine planning is not necessarily the machine rendering the login\n // page, so a URL this host cannot fetch is never a reason to fail.\n await annotateAssetWarnings(actions);\n\n return actions;\n}\n\n/** Result of {@link runSyncLoop}: what changed on the platform and locally. */\nexport type SyncLoopResult = {\n /**\n * Project-relative paths of the flow files whose `user_schema` was re-pinned\n * from a superseded schema revision id to the new one. Apply rewrites no\n * other file: the rest stay as written. Surfaced in human and `--json`\n * output so a local rewrite is never silent.\n */\n filesUpdated: string[];\n /**\n * The platform resources this run touched, in execution order. Unlike a\n * plan-time enumeration, `id` carries the resulting platform id (the\n * created id, the newly published revision id, or the id updated or\n * deleted). Feeds the `apply` `--json` `changes` array.\n */\n applied: PlanResourceChange[];\n /** Removed files whose resource was kept, because it cannot be deleted yet. */\n unsupported: string[];\n};\n\n/**\n * Execute every action returned by {@link buildSyncPlan} against the\n * platform. Updates the local state file (`.zitadel/state.json`) as\n * each action completes so an interrupted run can resume, recording the\n * hash of what was uploaded, so the next `plan` is empty.\n *\n * The files stay as written. The server's answer is not written back: it\n * spells out defaults the author left to the server (a connection's\n * `pkce_enabled`) and leaves out others (an action's `primary: false`), and\n * `plan` reads both as no change through the syncer's `normalize`. The one\n * rewrite is a flow's `user_schema` that pins a schema revision id this run\n * (or an interrupted one) superseded: the file must carry the server-minted\n * id of the new revision, or the next upload would pin the old one.\n *\n * The platform target (base URL + bearer auth) lives in the api\n * package's runtime registries; callers set them before invoking this.\n *\n * @param cwd - Project root.\n * @param syncers - Per-resource adapters; same list passed to\n * `buildSyncPlan`.\n */\nexport async function runSyncLoop(\n cwd: string,\n syncers: ReadonlyArray<ResourceSyncer>,\n): Promise<SyncLoopResult> {\n const actions = await buildSyncPlan(cwd, syncers);\n for (const action of actions) {\n if (action.kind === \"create\" || action.kind === \"update\" || action.kind === \"revise\") {\n for (const warning of action.warnings ?? []) {\n reportWarning(`${action.path}: ${warning.message}`);\n }\n }\n }\n const filesUpdated: string[] = [];\n const applied: PlanResourceChange[] = [];\n // Revisions published by this run: superseded id → new id. Flow actions\n // carrying a `repin` patch their `user_schema` from here.\n const repinned = new Map<string, string>();\n\n // The revision id a flow's `user_schema` must adopt: the one this run's\n // revise minted, else the one an interrupted earlier run recorded in state.\n const repinTarget = (repin: FlowRepin | undefined): string | undefined =>\n repin ? (repinned.get(repin.previousId) ?? repin.newId) : undefined;\n\n // Patch the pin in memory so the wire request adopts the new revision\n // without re-reading disk, and rewrite the file. The rewrite is a no-op\n // when this run's schema revise already re-pinned it — it matters for\n // crash recovery, where no revise ran this time.\n const adoptRepin = async (\n path: string,\n content: object,\n repin: FlowRepin,\n newId: string,\n ): Promise<object> => {\n if (await repinFlowFile(cwd, path, repin.previousId, newId)) {\n filesUpdated.push(path);\n consola.info(`Re-pinned user_schema in ${path} to ${newId}`);\n }\n return { ...(content as Record<string, unknown>), user_schema: newId };\n };\n\n for (const action of actions) {\n switch (action.kind) {\n case \"create\": {\n const newId = repinTarget(action.repin);\n // A flow created in the same run as (or after an interrupted) schema\n // revise must adopt the new revision — POSTing the stale pin would\n // fail validation.\n const content =\n newId && action.repin\n ? await adoptRepin(action.path, action.content, action.repin, newId)\n : action.content;\n const { id } = await action.syncer.create(content);\n const hash = newId ? hashForState(action.syncer, content) : action.hash;\n const entry: ResourceEntry = { id, hash };\n if (action.movedFrom === undefined) {\n await updateState(cwd, action.path, entry);\n } else {\n await moveInState(cwd, action.movedFrom, action.path, entry);\n }\n if (action.movedFrom === undefined) {\n consola.info(\n `Created a new ${action.syncer.kind} on Zitadel from ${action.path} (id ${id})`,\n );\n applied.push({ kind: action.syncer.kind, action: \"create\", file: action.path, id });\n } else {\n consola.info(\n `Moved the ${action.syncer.kind} from ${action.movedFrom} to ${action.path} (id ${id})`,\n );\n applied.push({\n kind: action.syncer.kind,\n action: \"move\",\n file: action.path,\n id,\n moved_from: action.movedFrom,\n });\n }\n break;\n }\n case \"revise\": {\n const newId = repinTarget(action.repin);\n const content =\n newId && action.repin\n ? await adoptRepin(action.path, action.content, action.repin, newId)\n : action.content;\n const { id } = await action.syncer.create(content);\n // `previousId` lands in state before the flow files are rewritten:\n // if the process dies in between, the next plan recovers the re-pin\n // from state instead of publishing a duplicate revision.\n const entry: ResourceEntry = {\n id,\n hash: newId ? hashForState(action.syncer, content) : action.hash,\n previousId: action.previousId,\n };\n await updateState(cwd, action.path, entry);\n repinned.set(action.previousId, id);\n consola.info(\n `Published a new ${action.syncer.kind} revision on Zitadel from ${action.path} (id ${id})`,\n );\n for (const flowPath of action.affectedPaths) {\n if (await repinFlowFile(cwd, flowPath, action.previousId, id)) {\n filesUpdated.push(flowPath);\n consola.info(`Re-pinned user_schema in ${flowPath} to ${id}`);\n }\n }\n applied.push({\n kind: action.syncer.kind,\n action: \"revision\",\n file: action.path,\n id,\n previous_id: action.previousId,\n });\n break;\n }\n case \"update\": {\n const newId = repinTarget(action.repin);\n const content =\n newId && action.repin\n ? await adoptRepin(action.path, action.content, action.repin, newId)\n : action.content;\n const { id: landedOn } = await action.syncer.update(action.id, content);\n // The id the write reported, not the one it was given: a write\n // addressed by document content can land on a different resource than\n // the tracked one, and state has to follow it or the next plan reads\n // the resource the file no longer describes.\n const trackedId = landedOn ?? action.id;\n await updateState(cwd, action.path, {\n id: trackedId,\n hash: newId ? hashForState(action.syncer, content) : action.hash,\n });\n consola.info(`Updated the ${action.syncer.kind} on Zitadel from ${action.path}`);\n applied.push({\n kind: action.syncer.kind,\n action: \"update\",\n file: action.path,\n id: trackedId,\n });\n break;\n }\n case \"delete\": {\n await action.syncer.delete(action.id);\n await removeFromState(cwd, action.path);\n consola.info(\n `Deleted the ${action.syncer.kind} on Zitadel because ${action.path} was removed locally`,\n );\n applied.push({\n kind: action.syncer.kind,\n action: \"delete\",\n file: action.path,\n id: action.id,\n });\n break;\n }\n case \"skip\": {\n if (isUnsupportedDeletion(action)) {\n reportWarning(unsupportedDeletionNote(action));\n }\n consola.debug(`Skipped ${action.path} (${action.reason})`);\n break;\n }\n }\n }\n\n // `previousId` exists to recover interrupted re-pins; once no local flow\n // pins the superseded revision, drop it — otherwise a developer who later\n // pins that old revision on purpose would get force-bumped by recovery.\n const remainingPins = new Set((await readLocalFlowUserSchemas(cwd)).values());\n const finalState = await readState(cwd);\n for (const [path, entry] of Object.entries(finalState.resources)) {\n if (entry.previousId && !remainingPins.has(entry.previousId)) {\n await updateState(cwd, path, { previousId: undefined });\n }\n }\n\n return {\n filesUpdated: [...new Set(filesUpdated)],\n applied,\n unsupported: actions.filter(isUnsupportedDeletion).map((action) => action.path),\n };\n}\n\n/**\n * Rewrite a flow file's `user_schema` pin from `previousId` to `newId`,\n * lockfile-style. Prefers a targeted text replacement so the author's\n * formatting survives a one-string change; falls back to parse +\n * `stableStringify` when the raw text doesn't contain exactly one pin.\n * Returns false when the file doesn't pin `previousId` (already re-pinned\n * or hand-edited) — never throws for an unreadable file.\n */\nasync function repinFlowFile(\n cwd: string,\n relPath: string,\n previousId: string,\n newId: string,\n): Promise<boolean> {\n const absPath = join(cwd, relPath);\n let raw: string;\n try {\n raw = await readFile(absPath, \"utf8\");\n } catch (err) {\n consola.debug(`read ${relPath} for re-pin failed:`, err);\n return false;\n }\n\n const pinPattern = new RegExp(\n `(\"user_schema\"\\\\s*:\\\\s*)${escapeRegExp(JSON.stringify(previousId))}`,\n \"g\",\n );\n if (raw.match(pinPattern)?.length === 1) {\n await writeFile(\n absPath,\n raw.replace(pinPattern, (_match, prefix: string) => `${prefix}${JSON.stringify(newId)}`),\n );\n return true;\n }\n\n try {\n const doc = JSON.parse(raw) as Record<string, unknown>;\n if (doc.user_schema !== previousId) {\n return false;\n }\n doc.user_schema = newId;\n await writeFile(absPath, `${stableStringify(doc)}\\n`);\n return true;\n } catch (err) {\n consola.debug(`re-pin ${relPath} failed:`, err);\n return false;\n }\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * The stored body an update is checked against. Unlike a plan's diff, a check\n * cannot proceed on a body it failed to read, so a failure stops the run; only\n * a resource gone from the platform reads as nothing stored.\n */\nasync function storedBody(action: Extract<SyncAction, { kind: \"update\" }>): Promise<object | null> {\n return action.oldContent ?? (await readStored(action.syncer, action.id));\n}\n\n/**\n * The project-relative path a file is tracked under: always forward slashes,\n * which is how state is written, whatever separator the platform uses.\n */\nexport function toStatePath(absolute: string, root: string, separator: string = sep): string {\n return absolute\n .slice(root.length + 1)\n .split(separator)\n .join(\"/\");\n}\n\nasync function readStored(syncer: ResourceSyncer, id: string): Promise<object | null> {\n try {\n return (await syncer.fetch?.(id)) ?? null;\n } catch (err) {\n if (err instanceof FatalFetchError) {\n throw err.reason;\n }\n if (err instanceof ApiError && err.status === 404) {\n return null;\n }\n throw err;\n }\n}\n\nasync function fetchOldIfAsked(\n syncer: ResourceSyncer,\n id: string,\n fetchOld: boolean,\n): Promise<object | null> {\n if (!fetchOld || !syncer.fetch) {\n return null;\n }\n try {\n return await syncer.fetch(id);\n } catch (err) {\n // A syncer that refused on purpose is not a fetch that merely failed.\n if (err instanceof FatalFetchError) {\n throw err.reason;\n }\n // Nor is one the developer cancelled with Ctrl-C: previewing offline\n // instead would carry on after being told to stop.\n if (err instanceof ZitadelError && err.code === \"E_CANCELLED\") {\n throw err;\n }\n consola.debug(`fetch ${syncer.kind} ${id} failed:`, err);\n return null;\n }\n}\n\nasync function readJsonDir(dirPath: string): Promise<Map<string, object>> {\n const result = new Map<string, object>();\n let entries: string[];\n try {\n entries = await readdir(dirPath);\n } catch (err) {\n if (typeof err === \"object\" && err !== null && \"code\" in err && err.code === \"ENOENT\") {\n return result;\n }\n throw err;\n }\n for (const entry of entries.filter((e) => e.endsWith(\".json\"))) {\n const filePath = join(dirPath, entry);\n const raw = await readFile(filePath, \"utf8\");\n result.set(filePath, JSON.parse(raw) as object);\n }\n return result;\n}\n\n/**\n * Walk `.zitadel/flows/*.json` once and return each flow's `user_schema` value\n * keyed by project-root-relative path. A flow file without a `user_schema` (or\n * with a non-string one) is skipped: it does not pin a schema revision, so it\n * cannot be affected by one.\n */\nexport async function readLocalFlowUserSchemas(\n cwd: string,\n separator: string = sep,\n): Promise<Map<string, string>> {\n const result = new Map<string, string>();\n const flows = await readJsonDir(join(cwd, FLOWS_DIR));\n for (const [absPath, content] of flows.entries()) {\n const relPath = toStatePath(absPath, cwd, separator);\n if (\n typeof content === \"object\" &&\n content !== null &&\n \"user_schema\" in content &&\n typeof (content as { user_schema: unknown }).user_schema === \"string\"\n ) {\n result.set(relPath, (content as { user_schema: string }).user_schema);\n }\n }\n return result;\n}\n\nfunction findFlowsPinnedTo(\n previousId: string,\n localFlows: Map<string, string>,\n): ReadonlyArray<string> {\n const affected: string[] = [];\n for (const [relPath, ref] of localFlows.entries()) {\n if (ref === previousId) {\n affected.push(relPath);\n }\n }\n return affected;\n}\n\n/**\n * Legacy content hash: order-sensitive and normalization-blind. Kept only\n * so state entries written by older CLI versions still match; new hashes\n * come from {@link hashForState}.\n */\nexport function hashResourceContent(data: object): string {\n return createHash(\"sha256\").update(JSON.stringify(data)).digest(\"hex\");\n}\n\n/**\n * The content hash stored in `.zitadel/state.json`: key-order-insensitive\n * (via `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<ResourceSyncer, \"normalize\">, data: object): string {\n const normalized = syncer.normalize?.(data) ?? data;\n return createHash(\"sha256\").update(stableStringify(normalized)).digest(\"hex\");\n}\n","import { consola } from \"consola\";\n\nimport { reportWarning } from \"../lib/warnings\";\n\nimport { createZitadelClient } from \"../lib/api-client\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport {\n buildSyncPlan,\n collectPlanWarnings,\n enumeratePlanResources,\n makeSyncers,\n renderPlan,\n runSyncLoop,\n summarizePlan,\n} from \"../lib/sync\";\nimport { readZitadelSecret } from \"../lib/project\";\nimport { publicCliCommand } from \"../lib/public-cli\";\n\n/**\n * `zitadel apply` — validate and upload repo config to the platform.\n *\n * Runs the sync loop to convergence, or (with `--dry-run`) previews the diff\n * without mutating. All validation — structural shape and `${VAR}` / `*_env`\n * reference presence — happens inside the sync engine ({@link buildSyncPlan}),\n * so an invalid or under-configured file fails with `E_VALIDATION` before any\n * platform call.\n */\nexport default class Apply extends BaseCommand {\n static override description = \"Validate and upload repo config to the platform.\";\n static override group = CommandGroups.configuration;\n static override groupOrder = 2;\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Apply);\n await this.toMeta(flags);\n const { cwd, source, env, dryRun, isTTY } = this.meta;\n\n const secret = await readZitadelSecret(cwd);\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n // Verbatim: the sync loop compares what it reads against the files.\n const client = createZitadelClient(\n { baseUrl: source, token: secret.project_secret },\n { verbatim: true },\n );\n const syncers = makeSyncers({\n client,\n projectId: secret.project_id,\n env,\n cwd,\n });\n\n if (!dryRun) {\n consola.start(\"Syncing schemas and flows to Zitadel\");\n const { filesUpdated, applied, unsupported } = await runSyncLoop(cwd, syncers);\n if (applied.length === 0 && unsupported.length > 0) {\n reportWarning(\n `Nothing was applied: ${unsupported.length} removed file${unsupported.length === 1 ? \"\" : \"s\"} cannot be deleted from the platform yet.`,\n );\n } else {\n consola.success(\"Sync complete\");\n }\n return this.emit({\n status: \"ok\",\n data: {\n synced: true,\n // Platform resources this run touched (with resulting ids);\n // `files_updated` lists the local rewrites only: re-pinned flows.\n changes: applied,\n files_updated: filesUpdated,\n unsupported_deletions: unsupported.length,\n unsupported_deletion_files: unsupported,\n next_actions:\n applied.length === 0\n ? [\n unsupported.length > 0\n ? `${unsupported.length} removed file${unsupported.length === 1 ? \" was\" : \"s were\"} not deleted from the platform: deleting is not supported yet (#1013). Restore ${unsupported.length === 1 ? \"it\" : \"them\"} if that was a mistake.`\n : \"Everything is already in sync — no changes were applied.\",\n ]\n : [\n \"Changes are live — reload your app to see them.\",\n \"Re-run plan to confirm local config and platform are in sync.\",\n ],\n next_commands: [publicCliCommand(\"plan\", this.meta.cliVersion)],\n },\n });\n }\n\n consola.start(\"Building plan (dry run)\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n this.recordTelemetry({\n creates: summary.creates,\n updates: summary.updates,\n revisions: summary.revisions,\n deletes: summary.deletes,\n total: summary.total,\n });\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.revisions} new revision${summary.revisions === 1 ? \"\" : \"s\"}, ` +\n `${summary.moves} moved, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}` +\n (summary.unsupported_deletions > 0\n ? `, ${summary.unsupported_deletions} removed but kept (cannot be deleted yet)`\n : \"\"),\n );\n return this.emit({\n status: \"ok\",\n data: {\n ...summary,\n changes: enumeratePlanResources(plan),\n warnings: collectPlanWarnings(plan),\n },\n pretty: renderPlan(plan, isTTY),\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.configuration;\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.configuration;\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.configuration;\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.configuration;\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.configuration;\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 type IdpProvider,\n IDP_PROVIDERS,\n parseClientId,\n parseClientSecret,\n type ProviderName,\n type ProviderSelection,\n providerOf,\n selectionName,\n validated,\n} from \"@zitadel/config/idp\";\n\nimport { createZitadelClient } 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 CONNECTION_SCHEMA_REF,\n enabledMethods,\n type ConnectionPlan,\n type FlowFile,\n credentialVariablesOf,\n customExample,\n customFlagValues,\n ENABLE_FLAG_KEYS,\n ENABLE_FLAG_NAMES,\n loopbackIssuerWarning,\n planConnection,\n publishClientId,\n type PublishState,\n readConnectionFiles,\n reportClientIdOutcome,\n republishArgs,\n selectionFromFlags,\n type StoredVariables,\n ssoEditRefusal,\n type SsoResult,\n type SsoSkipped,\n reportSecretOutcome,\n storeClientSecret,\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 {\n readDevelopmentIssuer,\n readZitadelConfig,\n readZitadelSecret,\n type ZitadelSecret,\n} from \"../../../lib/project\";\nimport { portableCommands, publicCliCommand } from \"../../../lib/public-cli\";\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 `variables 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.configuration;\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 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 any other OpenID Connect 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 cwdArgs,\n schema,\n flows: candidates,\n preflight: { selection, entry, secretFile, issuer },\n } = await this.target(flags, {\n // The credentials are published to the project, so the server is\n // resolved, unlike for the other auth-method commands.\n resolveServer: true,\n preflight: (cwd) => readProject(cwd, flags),\n });\n const { nonInteractive, dryRun, cliVersion, source } = 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, source));\n if (loopback !== undefined) {\n reportWarning(loopback);\n }\n const provider = selectionName(selection);\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 // `--cwd` only when it can be written unquoted on every shell.\n const cwdText = portableCommands([cwdArgs], cliVersion).length > 0 ? cwdArgs : [];\n const retryFor = (clientId: string, pipe = \"\"): string | undefined =>\n selection.kind === \"catalog\"\n ? `${pipe}${publicCliCommand(\n [\n \"auth-method sso enable --provider\",\n provider,\n \"--client-id\",\n clientId,\n ...cwdText,\n ].join(\" \"),\n cliVersion,\n )}`\n : undefined;\n\n const connections = await readConnectionFiles(cwd);\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 // Before the dry-run return: a Project whose flows all name another\n // schema must fail identically either way, or the preview says \"would\n // create\" for a run that cannot succeed.\n const flows = targetFlows(schema, candidates);\n // The schema and flow edits are worked out now, before the dry-run return\n // and before the connection is written or a credential published, so a\n // refusal (an edit the editors cannot make, or a flow `plan` would then\n // reject) stops the run with nothing changed (ADR 070 §3).\n const edits = planEdits(schema, plan.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 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 ${secretFile.project_id}`);\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: secretFile.project_id,\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(secretFile);\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: \"Client secret\",\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: \"Client ID\",\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: `Client secret (published to 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(secretFile);\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 `plan` 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 }\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(idVariable, clientIdState, this.meta.cliVersion);\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);\n }\n this.reportOutcome(outcome);\n // `variables 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 plan and apply, 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 cwdArgs,\n );\n\n return this.emit({\n status: \"ok\",\n data: {\n ...this.payload({\n projectId: secretFile.project_id,\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(!reusing || written.length > 0, cwdArgs, recovery),\n },\n pretty: `Enabled ${entry.displayName} for ${schema.name}`,\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. The connection is built here rather than\n * taken from `OwnerCommand.connect` because this command addresses the local\n * Project it was pointed at, not an owner the developer named.\n */\n private publisher(secret: ZitadelSecret): SecretPublisher | undefined {\n const { source } = this.meta;\n if (source === \"mock\") {\n return undefined;\n }\n const client = createZitadelClient({ baseUrl: source, token: secret.project_secret });\n return async (name, value, { secret: isSecret }) => {\n await client.updateVariables(\n { [name]: { value, secret: isSecret } },\n { project_id: secret.project_id },\n );\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 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/** What the run needs from the Project before the schema is read. */\ntype ProjectContext = {\n readonly selection: ProviderSelection;\n readonly entry: IdpProvider;\n readonly secretFile: ZitadelSecret;\n readonly issuer: string;\n};\n\n/**\n * The provider to enable and the Project it is enabled for, or a refusal.\n *\n * The provider and a custom connection's settings are checked first, before\n * the Project is read: a name or issuer the server would refuse on apply is\n * refused here, where it was typed. The Project is read before anything is\n * asked for: being turned away after typing a secret would mean typing it\n * again.\n *\n * @param cwd - The Project directory.\n * @param flags - `--provider`, which is named rather than prompted for, and\n * the custom connection's settings.\n */\nasync function readProject(\n cwd: string,\n flags: { readonly [K in (typeof ENABLE_FLAG_KEYS)[keyof typeof ENABLE_FLAG_KEYS]]?: string },\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 // (the same reasoning `OwnerCommand` gives for requiring an owner).\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 selection = selectionFromFlags(\n provider,\n customFlagValues(flags, ENABLE_FLAG_KEYS),\n ENABLE_FLAG_NAMES,\n customExample(ENABLE_FLAG_NAMES),\n );\n const entry = providerOf(selection);\n const config = await readZitadelConfig(cwd);\n const secretFile = await readZitadelSecret(cwd);\n const issuer = readDevelopmentIssuer(config);\n if (issuer === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"This Project has no development issuer\", {\n hint: \"Run `zitadel setup` first, or add environments.development.issuer to zitadel.json.\",\n });\n }\n return { selection, entry, secretFile, issuer };\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: `plan` and `apply` both succeed and the sign-in screen simply never\n * offers the provider. Failing afterwards would leave a connection file and\n * two 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 the flow's user_schema, or run `zitadel apply` first so the \" +\n \"schema's published id is recorded in .zitadel/state.json.\",\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","import { BRANDING_DESIGNS, type BrandingDesign } from \"@zitadel/config/defaults\";\n\nimport { ZitadelError } from \"../errors\";\nimport { publicCliCommand } from \"../public-cli\";\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: [publicCliCommand(\"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: [publicCliCommand(\"branding eject\", cliVersion)],\n },\n );\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 {\n BRANDING_FILE_SCHEMA_REF,\n META_SCHEMA_DIR,\n metaSchemaFiles,\n} 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 {\n normalizePublicCliJson,\n normalizePublicCliProse,\n publicCliCommand,\n} from \"../../lib/public-cli\";\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 (for projects set up before it existed).\n * Purely local — nothing is uploaded; the first `zitadel apply` 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 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 groupOrder = 4;\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);\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: [publicCliCommand(\"setup\", this.meta.cliVersion)],\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; setups from before the branding\n // dialect also miss the meta-schema, so materialize it when absent.\n await write(\n join(BRANDING_DIR, \"README.md\"),\n normalizePublicCliProse(brandingReadmeContent(), this.meta.cliVersion),\n false,\n ).catch(swallowConflict);\n const brandingMeta = metaSchemaFiles().find((f) => f.name === \"branding.json\");\n if (brandingMeta) {\n await write(\n join(META_SCHEMA_DIR, brandingMeta.name),\n `${stableStringify(normalizePublicCliJson(brandingMeta.body, this.meta.cliVersion))}\\n`,\n false,\n ).catch(swallowConflict);\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 \"Plan validates the template and shows the pending revision; apply publishes it.\",\n ],\n next_commands: [\n publicCliCommand(\"plan\", this.meta.cliVersion),\n publicCliCommand(\"apply\", this.meta.cliVersion),\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 do you want 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\";\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/** The nudge for `next_actions`, quoting the command in prose. */\nexport function claimAction(cliVersion: string, deadline?: Date): string {\n return `${claimSentence(deadline)} Run ${publicCliCommand(\"claim\", cliVersion)}.`;\n}\n\n/** The same nudge for the human box, with the command on its own styled line. */\nexport function claimBoxAction(cliVersion: string, deadline?: Date): BoxAction {\n return {\n text: claimSentence(deadline),\n command: publicCliCommand(\"claim\", cliVersion),\n };\n}\n\n/** The command for `next_commands`. */\nexport function claimCommand(cliVersion: string): string {\n return publicCliCommand(\"claim\", 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): string {\n return (\n `The local record says this project's ${CLAIM_WINDOW_DAYS}-day claim window has ` +\n `closed. Run ${publicCliCommand(\"claim\", cliVersion)} 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 { ApiError } from \"@zitadel/api/runtime/fetch\";\nimport consola from \"consola\";\n\nimport { createZitadelClient } from \"../lib/api-client\";\nimport { wrapForBox } from \"../lib/box\";\nimport { openInBrowser } from \"../lib/browser\";\nimport { CLAIM_WINDOW_DAYS, isAttached } from \"../lib/claim-state\";\nimport { ZitadelError } from \"../lib/errors\";\nimport { isObject } from \"../lib/json\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport { readZitadelSecret, writeZitadelSecret, type ZitadelSecret } from \"../lib/project\";\nimport { reportWarning } from \"../lib/warnings\";\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. Exported so that fallback is testable without\n * waiting out a real TTL.\n */\nexport function claimDeadline(input: {\n expiresAt: string;\n timeoutSeconds?: number;\n now: number;\n}): number {\n const parsed = 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 */\nexport default class Claim extends BaseCommand {\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.project;\n static override groupOrder = 2;\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 ];\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 };\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\n const secret = await readZitadelSecret(cwd);\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.\n if (isAttached(secret)) {\n return this.alreadyClaimed({\n project_id: secret.project_id,\n team_id: secret.team_id,\n claimed_at: secret.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 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: secret.project_id,\n would:\n \"Open a browser to claim this project, then record the owning team in .zitadel/secret.\",\n },\n nextCommands: [\"zitadel claim\"],\n });\n }\n\n const client = createZitadelClient({\n baseUrl: this.meta.source,\n token: secret.project_secret,\n });\n\n let challenge: Awaited<ReturnType<typeof client.initClaim>>;\n try {\n challenge = await client.initClaim(secret.project_id);\n } catch (error) {\n const claimed = alreadyClaimedDetails(error);\n if (claimed) {\n return this.alreadyClaimed({ project_id: secret.project_id, ...claimed });\n }\n if (isClaimWindowExpired(error)) {\n this.recordTelemetry({ claim_outcome: \"window_expired\" });\n throw claimWindowExpiredError();\n }\n throw error;\n }\n\n const deadline = claimDeadline({\n expiresAt: challenge.expires_at,\n timeoutSeconds: flags.timeout,\n now: Date.now(),\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 const skipLaunch = flags[\"no-open\"] || nonInteractive;\n const opened = skipLaunch ? false : (await openInBrowser(challenge.claim_url)).opened;\n if (!opened) {\n consola.info(\"Open the link above to continue.\");\n }\n consola.start(\"Waiting for the browser step to finish\");\n\n const completed = await this.poll(client, secret.project_id, challenge.challenge_id, deadline);\n\n const next: ZitadelSecret = {\n ...secret,\n claimed_at: completed.claimed_at,\n team_id: completed.team_id,\n };\n // Unconditional: `--dry-run` never reaches here (it returns above), so a\n // claim that got this far really happened on the platform and the local\n // record must follow it.\n await writeZitadelSecret(cwd, next);\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: secret.project_id,\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.\n */\n private async poll(\n client: ReturnType<typeof createZitadelClient>,\n projectId: string,\n challengeId: string,\n deadline: number,\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.\");\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.\");\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\nfunction expiredError(message: string): ZitadelError {\n return new ZitadelError(\"E_VALIDATION\", message, {\n hint: \"Links are valid for 10 minutes. Start a new one.\",\n nextCommands: [\"zitadel claim\"],\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\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 */\nfunction 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 { pbkdf2Sync, randomBytes } from \"node:crypto\";\nimport { chmod, 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 { isObject } from \"../json\";\nimport {\n findUpward,\n LOCAL_RUNTIME_DIR,\n PLATFORM_PROJECT_ID,\n readRuntimeMetadata,\n sameLocalServer,\n} from \"./runtime\";\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: [`rm ${LOCAL_ADMIN_FILE}`, \"zitadel reset --force\", \"zitadel start\"],\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 chmod(staging, 0o644).catch(() => undefined);\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 chmod(path, 0o600).catch(() => undefined);\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\";\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 `/healthz`, 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: [\"zitadel stop\", \"zitadel 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: [\"zitadel 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\";\nimport { publicCliCommand } from \"../lib/public-cli\";\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 created by `zitadel start`.\\n\\nRun it 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.localServer;\n static override groupOrder = 6;\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: [publicCliCommand(\"start\", this.meta.cliVersion)],\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","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 */\nexport class SvelteKitDetector implements Detector {\n readonly framework = \"sveltekit\";\n readonly displayName = \"SvelteKit\";\n readonly versionPackage = \"@sveltejs/kit\";\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, \"@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 { chmod, mkdir, readFile, rename, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { ZitadelError } from \"../../../../errors\";\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(abs(opts.cwd, op.path), op.entries, op.comment ?? [], opts.dryRun, result);\n break;\n case \"merge-json\":\n await mergeJson(abs(opts.cwd, op.path), op.patch, opts.dryRun, result);\n break;\n case \"append-gitignore\":\n await appendGitignore(abs(opts.cwd, \".gitignore\"), op.entries, opts.dryRun, result);\n break;\n case \"add-dep\":\n await addDependency(abs(opts.cwd, \"package.json\"), op, opts.dryRun, result);\n break;\n case \"edit\":\n await editFile(opts.cwd, op.path, op.edit, opts.dryRun, result);\n break;\n }\n}\n\n/**\n * Generic content edit: read the file, run the patcher-supplied transform, write\n * the result. Framework knowledge lives entirely in `edit` (next to its\n * patcher); this executor only owns candidate resolution, idempotency, dry-run,\n * and the atomic write. `pathOrPaths` may be a single path or a priority list of\n * candidates — the first that exists wins, else the first candidate.\n */\nasync function editFile(\n cwd: string,\n pathOrPaths: string | ReadonlyArray<string>,\n edit: (source: string | undefined) => string,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const candidates = (typeof pathOrPaths === \"string\" ? [pathOrPaths] : pathOrPaths).map((p) =>\n abs(cwd, p),\n );\n 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 chmod(tmp, mode).catch(() => undefined);\n }\n await rename(tmp, path);\n record(result, path, \"file\", action);\n}\n\nasync function ensureDir(\n path: string,\n mode: number | undefined,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n // An already-existing directory is a skip — unless its permissions drifted\n // from the requested mode, in which case the chmod below repairs them and\n // the report says so (an \"update\" row, not a silent skip). Windows does not\n // implement POSIX permission classes (only the write bit is changeable), so\n // there the mode comparison is meaningless and healing is never reported —\n // otherwise every rerun would flag `.zitadel` as an update forever.\n const pre = await stat(path).catch(() => undefined);\n const existed = pre?.isDirectory() ?? false;\n const healsMode =\n existed &&\n mode !== undefined &&\n process.platform !== \"win32\" &&\n ((pre?.mode ?? 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 chmod(path, mode).catch(() => undefined);\n }\n if (!existed) {\n record(result, path, \"dir\", \"create\");\n } else if (healsMode) {\n record(result, path, \"dir\", \"update\");\n } else {\n result.filesSkipped.push(path);\n }\n}\n\nasync function writeText(\n path: string,\n contents: string,\n opts: { mode?: number; force: boolean; dryRun: boolean },\n result: ScaffoldAccumulator,\n): Promise<void> {\n const existing = await readIfExists(path);\n if (existing === contents) {\n result.filesSkipped.push(path);\n return;\n }\n\n if (existing !== undefined && !opts.force) {\n throw new ZitadelError(\"E_CONFLICT\", `Refusing to overwrite ${path}`, {\n hint: \"Re-run with --force if you want the CLI to replace this file.\",\n details: { path },\n });\n }\n\n const action = existing === undefined ? \"create\" : \"update\";\n if (opts.dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n\n await mkdir(dirname(path), { recursive: true });\n const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;\n await writeFile(tmp, contents, { mode: opts.mode });\n if (opts.mode) {\n await chmod(tmp, opts.mode).catch(() => undefined);\n }\n await rename(tmp, path);\n record(result, path, \"file\", action);\n}\n\nasync function appendText(\n path: string,\n contents: string,\n ifMissing: string | undefined,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const raw = await readIfExists(path);\n const existing = raw ?? \"\";\n if (ifMissing && existing.includes(ifMissing)) {\n result.filesSkipped.push(path);\n return;\n }\n\n const next = `${existing}${existing && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\"}${contents}`;\n if (next === existing) {\n result.filesSkipped.push(path);\n return;\n }\n\n const action = raw === undefined ? \"create\" : \"update\";\n if (dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, next);\n record(result, path, \"file\", action);\n}\n\nasync function mergeEnv(\n path: string,\n entries: Readonly<Record<string, string>>,\n comment: ReadonlyArray<string>,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const raw = await readIfExists(path);\n const existing = raw ?? \"\";\n const present = new Set(\n existing\n .split(/\\r?\\n/g)\n .map((line) => line.match(/^\\s*([A-Za-z_][A-Za-z0-9_]*)=/)?.[1])\n .filter((value): value is string => Boolean(value)),\n );\n const additions = Object.entries(entries).filter(([key]) => !present.has(key));\n if (additions.length === 0) {\n result.filesSkipped.push(path);\n return;\n }\n\n const 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]) => `${key}=${value}`)].join(\"\\n\");\n const next = `${existing}${existing && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\"}${block}\\n`;\n const action = raw === undefined ? \"create\" : \"update\";\n if (dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, next);\n record(result, path, \"file\", action);\n}\n\nasync function mergeJson(\n path: string,\n patch: Readonly<Record<string, unknown>>,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const existing = await readIfExists(path);\n const current = existing ? parseJsonObject(existing, path) : {};\n const next = deepMerge(current, patch);\n const contents = `${stableStringify(next)}\\n`;\n if (existing === contents) {\n result.filesSkipped.push(path);\n return;\n }\n const action = existing === undefined ? \"create\" : \"update\";\n if (dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, contents);\n record(result, path, \"file\", action);\n}\n\nasync function appendGitignore(\n path: string,\n entries: ReadonlyArray<string>,\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const raw = await readIfExists(path);\n const existing = raw ?? \"\";\n const lines = new Set(existing.split(/\\r?\\n/g).map((line) => line.trim()));\n const missing = entries.filter((entry) => !lines.has(entry));\n if (missing.length === 0) {\n result.filesSkipped.push(path);\n return;\n }\n const next = `${existing}${existing && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\"}${missing.join(\"\\n\")}\\n`;\n const action = raw === undefined ? \"create\" : \"update\";\n if (dryRun) {\n record(result, path, \"file\", action);\n return;\n }\n await writeFile(path, next);\n record(result, path, \"file\", action);\n}\n\nasync function addDependency(\n path: string,\n op: { name: string; version: string; dev?: boolean },\n dryRun: boolean,\n result: ScaffoldAccumulator,\n): Promise<void> {\n const existing = await readIfExists(path);\n if (!existing) {\n throw new ZitadelError(\"E_VALIDATION\", \"package.json is required to add Zitadel dependencies\");\n }\n const current = parseJsonObject(existing, path);\n const key = op.dev ? \"devDependencies\" : \"dependencies\";\n const deps = isObject(current[key]) ? (current[key] as Record<string, unknown>) : {};\n // 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 plan = publicCliCommand(\"plan\", ctx.cliVersion);\n const apply = publicCliCommand(\"apply\", 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 token bridge is the highest-leverage embedding lever and lives\n // nowhere an integrator would otherwise look (component source). Keep the\n // knob list here in sync with the documented public tokens.\n const themingParagraph =\n \"Theming the widgets from your app: `--zl-*` design-token custom properties set on the element in your own stylesheet pierce the widgets' shadow DOM. The bridge covers your fonts (`--zl-font-family-heading`, `--zl-font-family-sans`), radii (`--zl-radius-md`/`-lg`/`-xl`), the primary CTA pair (`--zl-primary` / `--zl-primary-foreground`), and the link color (`--zl-link`). When your page already carries the heading, set the `suppress-header` attribute on `<zitadel-login>` / `<zitadel-session>` (SDK wrappers: `suppressHeader`) to visually hide the widget's own heading block — it stays in the accessibility tree. 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 on routes covered by the request-boundary `matcher`, `auth()` from `@zitadel/sdk-next/server` works too — extend the `matcher` in the request boundary to cover your public routes when you want server-rendered, flash-free session state in shared chrome (the trade: the middleware then runs on those routes). Sign-in and sign-out navigate (`post-sign-in-url` / `post-sign-out-url`), so chrome re-reads on the next page load without extra wiring.\"\n : ctx.framework.id === \"nuxt\"\n ? \"Your app's own chrome (header navigation, account menus) reads session state with the auto-imported `useAuth()` composable — seeded from the server on every render by the scaffolded auth plugin. Sign-in and sign-out navigate (`post-sign-in-url` / `post-sign-out-url`), so the state is fresh on every page load.\"\n : 'Your app\\'s own chrome (header navigation, account menus) can read session state from the same-origin `/__nextgen/sessions/me?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; never change auth behavior by editing generated route files.\n\nThe golden path:\n\n1. Start the dev server and open ${ctx.issuer}/login — **exactly this origin, not 127.0.0.1**. Passkeys and the origin allowlist are bound to it. (Freshly scaffolded apps also redirect / there; pre-existing apps keep their homepage.)\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 - \\`${plan}\\`\n - \\`${apply}\\`\n - Agents: append \\`--non-interactive --json\\` to both. \\`plan\\` validates flow invariants with the server's own rules **before** anything uploads — fix what it reports and re-run.\n\n${presentationParagraph}${jsxTypesNote}\n\n${themingParagraph}\n\n${sessionStateParagraph}\n\nMachine-readable dialect (read these before authoring flow or schema edits):\n\n- \\`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- Worked flow examples: https://github.com/zitadel/nextgen/tree/main/api/openapi/endpoints/flow_definitions/examples\n\nNever edit \\`.zitadel/state.json\\` (sync bookkeeping) or \\`.zitadel/secret\\` (credentials, git-ignored). Keep \\`.zitadel/local/\\` out of source control.`;\n}\n\n/** The human-facing summary appended to the app `README.md`. */\nexport function readmeGuidanceSection(ctx: PatchContext): string {\n const plan = publicCliCommand(\"plan\", ctx.cliVersion);\n const apply = publicCliCommand(\"apply\", ctx.cliVersion);\n 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${plan}\n${apply}\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 synced by `apply`, so `--fix` must not clobber them.\n *\n * Pure: filters a freshly-allocated list; the input plan is not mutated.\n */\nexport function reclaimableOps(plan: ScaffoldPlan): FileOp[] {\n return plan.ops.filter(\n (op) =>\n op.kind === \"merge-env\" ||\n op.kind === \"append-gitignore\" ||\n op.kind === \"add-dep\" ||\n op.kind === \"edit\" ||\n (op.kind === \"write\" && op.contents.includes(MANAGED_MARKER)),\n );\n}\n\n/**\n * Narrow a reclaimable op list to what a missing-only repair may replay:\n * content ops (`write`, and `edit` marked `overwrites`) survive only when\n * their target file does not exist, so the repair can restore a deleted\n * managed file but can never touch an edited or user-adopted one. Merging\n * `edit` transforms and the additive kinds (`merge-env`, `append-gitignore`)\n * pass through — they are idempotent and only add what is missing. `add-dep`\n * is additive only while the dependency is absent: `addDependency` replaces\n * a differing existing version, so under missing-only semantics the op is\n * dropped whenever the dependency is already declared at *any* version —\n * repairing an unrelated missing file must never rewrite a user-pinned\n * range. Reads the filesystem; paths resolve against `cwd` like the\n * file-writer's.\n */\nexport async function withoutExistingTargets(\n ops: ReadonlyArray<FileOp>,\n cwd: string,\n): Promise<FileOp[]> {\n const kept: FileOp[] = [];\n for (const op of ops) {\n if (op.kind === \"write\") {\n if (!(await exists(join(cwd, op.path)))) {\n kept.push(op);\n }\n continue;\n }\n if (op.kind === \"edit\" && op.overwrites) {\n const candidates = typeof op.path === \"string\" ? [op.path] : op.path;\n const present = await Promise.all(\n candidates.map((candidate) => exists(join(cwd, candidate))),\n );\n if (!present.includes(true)) {\n kept.push(op);\n }\n continue;\n }\n if (op.kind === \"add-dep\") {\n if (!(await dependencyDeclared(cwd, op.name))) {\n kept.push(op);\n }\n continue;\n }\n kept.push(op);\n }\n return kept;\n}\n\n/**\n * Whether `package.json` already declares `name` in dependencies or\n * devDependencies, at any version. A missing or unparsable `package.json`\n * counts as \"not declared\" so the op is kept and the file-writer's own\n * error handling reports the real problem.\n */\nasync function dependencyDeclared(cwd: string, name: string): Promise<boolean> {\n let contents: string;\n try {\n contents = await readFile(join(cwd, \"package.json\"), \"utf8\");\n } catch {\n return false;\n }\n try {\n const pkg = JSON.parse(contents) as unknown;\n if (!isObject(pkg)) {\n return false;\n }\n const declared = (key: string): boolean => isObject(pkg[key]) && name in (pkg[key] as object);\n return declared(\"dependencies\") || declared(\"devDependencies\");\n } catch {\n return false;\n }\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport {\n metaSchemaFiles,\n META_SCHEMA_DIR,\n PROJECT_FILE_SCHEMA_REF,\n} from \"@zitadel/config/meta-schemas\";\n\nimport { stableStringify } from \"../../../json\";\nimport { normalizePublicCliJson } from \"../../../public-cli\";\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\"],\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 {\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 ...metaSchemaFiles().map(\n (file): FileOp => ({\n kind: \"write\",\n path: `${META_SCHEMA_DIR}/${file.name}`,\n contents: `${JSON.stringify(normalizePublicCliJson(file.body, ctx.cliVersion), null, 2)}\\n`,\n }),\n ),\n ...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 const environments: Record<string, unknown> = { development: { issuer: ctx.issuer } };\n const previewPatterns = ctx.project.origins\n .filter((origin) => origin.kind === \"preview\")\n .map((origin) => origin.pattern);\n if (previewPatterns.length > 0) {\n // Preview patterns are already full origins (scheme://host[:port]); don't\n // prepend a scheme or it doubles up (https://http://localhost:3000).\n environments.preview = {\n issuer_pattern: [...previewPatterns],\n };\n }\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 environments,\n ...(ctx.preset === undefined ? {} : { preset: ctx.preset }),\n ...(ctx.useCase === undefined ? {} : { useCase: ctx.useCase }),\n };\n}\n\n/** Normalizes a server URL to its origin, falling back to {@link DEFAULT_SERVER}. */\nfunction resolveServerOrigin(source: string): string {\n try {\n return new URL(source).origin;\n } catch {\n return DEFAULT_SERVER;\n }\n}\n","import { 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","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.`\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 { getRenderer } from \"./renderers/registry\";\nimport type { RendererSpec } from \"./renderers/types\";\n\n/**\n * Next.js request-boundary file at the project root. Wires `nextgenMiddleware` so the\n * generated project config's `/__nextgen` proxy path is same-origin proxied\n * to `ZITADEL_URL` and `/profile` is gated. Next 16 renamed this convention to\n * `proxy.ts`; older projects keep `middleware.ts`.\n * Carries the managed marker so `doctor --fix` reclaims it and `eject` removes it.\n */\nfunction requestBoundaryTemplate(functionName: \"middleware\" | \"proxy\"): string {\n return `${MANAGED_MARKER}\nimport { nextgenMiddleware } from \"@zitadel/sdk-next/middleware\";\nimport type { NextRequest } from \"next/server\";\n\nexport function ${functionName}(req: NextRequest) {\n return nextgenMiddleware(req, {\n url: process.env.ZITADEL_URL,\n protectedRoutes: [\"/profile\"],\n loginPath: \"/login\",\n });\n}\n\nexport const config = {\n matcher: [\"/__nextgen/:path*\", \"/profile/:path*\"],\n};\n`;\n}\n\n/**\n * Rule-based patcher for the Next.js App Router. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * Next routes and request boundary whose templates come from the chosen renderer.\n */\nexport class NextPatcher extends AbstractRulePatcher {\n /** Returns true for Next.js projects. */\n canPatch(framework: string): boolean {\n return framework === \"next\";\n }\n\n /**\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: { NEXT_PUBLIC_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { NEXT_PUBLIC_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: renderer.dependency.name,\n version: 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 { 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 { kind: \"merge-env\", path: \".env.example\", entries: { NUXT_PUBLIC_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { NUXT_PUBLIC_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: 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 { 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 { 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 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 { 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 { 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 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 { 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 { 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 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 { 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 { 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 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 { 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.\n *\n * The server config is read from `process.env`, not SvelteKit's `$env` modules:\n * their import path moved between major versions (`$env/dynamic/private` in\n * SvelteKit 2 is deprecated for `$app/env/private` in SvelteKit 3, and returns\n * empty values there), so a single template cannot use them and support both.\n * SvelteKit/Vite do not surface `.env` on `process.env`, so Node loads\n * `.env.local` here. The backend URL is baked as the fallback (the known\n * server from setup); in production the platform provides `ZITADEL_URL`. The\n * managed marker sits in a JS comment.\n */\nexport function hooksServerTemplate(ctx: PatchContext): string {\n return `${MANAGED_MARKER}\nimport { createNextgenHandle } from \"@zitadel/sdk-sveltekit/server\";\n\n// Load .env.local into process.env (SvelteKit's $env modules differ across major\n// versions; process.env is version-independent). Absent in production, where the\n// platform provides the real environment.\ntry {\n process.loadEnvFile?.(\".env.local\");\n} catch {\n // .env.local is optional — ignore when it does not exist.\n}\n\nexport const handle = createNextgenHandle({\n url: process.env.ZITADEL_URL ?? ${JSON.stringify(ctx.server)},\n projectSecret: process.env.ZITADEL_PROJECT_SECRET,\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 2 and 3 both expose to the browser, rather\n * than from an `$env` module: those moved between the majors\n * (`$env/static/public` is deprecated in SvelteKit 3 for `$app/env/public`), so a\n * single template could not import them on both. Setup seeds the variable in\n * `.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 {\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(ctx) },\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 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: \"SvelteKit integration\",\n detail:\n \"Wrote src/hooks.server.ts (@zitadel/sdk-sveltekit handle) 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 { 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 { 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 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 * What every scaffolder that runs `create-vite` (React, Vue, Solid, Svelte and\n * Qwik) declares. `create-vite` never checks the Node itself, so setup only\n * warns.\n */\nexport const CREATE_VITE_NODE_ENGINES: NodeEngines = {\n label: \"create-vite\",\n spec: \"create-vite@latest\",\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 } 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\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"qwik-ts\"], cwd);\n await rm(join(cwd, \"src/app.tsx\"), { force: true });\n await rm(join(cwd, \"src/app.css\"), { force: true });\n 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 } 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\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"react-ts\"], cwd);\n await rm(join(cwd, \"src/App.tsx\"), { force: true });\n await rm(join(cwd, \"src/App.css\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\nimport { CREATE_VITE_NODE_ENGINES } 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\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"solid-ts\"], cwd);\n await rm(join(cwd, \"src/App.tsx\"), { force: true });\n await rm(join(cwd, \"src/App.css\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\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 } 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\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"svelte-ts\"], cwd);\n await rm(join(cwd, \"src/App.svelte\"), { force: true });\n await rm(join(cwd, \"src/lib/Counter.svelte\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\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 } 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\n protected async create(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"vue-ts\"], cwd);\n await rm(join(cwd, \"src/App.vue\"), { force: true });\n await rm(join(cwd, \"src/components/HelloWorld.vue\"), { force: true });\n }\n}\n","import { AngularScaffolder } from \"./angular\";\nimport { NextScaffolder } from \"./next\";\nimport { NuxtScaffolder } from \"./nuxt\";\nimport { QwikScaffolder } from \"./qwik\";\nimport { 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 /** `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) =>\n this.availableFrameworks().find((framework) => framework.id === id)?.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 { issuerFromPort, type FrameworkFacts, type Orca } from \"../../lib/orca\";\nimport type { PatchContext } from \"../../lib/orca/patchers/types\";\nimport {\n readDevelopmentIssuer,\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, config, 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\nasync function resolveIssuer(\n cwd: string,\n config: Record<string, unknown>,\n facts: FrameworkFacts,\n): Promise<string> {\n const fromConfig = readDevelopmentIssuer(config);\n if (fromConfig && fromConfig.length > 0) {\n return fromConfig;\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 let pkg: { dependencies?: Record<string, string>; devDependencies?: Record<string, string> };\n try {\n pkg = JSON.parse(await readFile(join(ctx.cwd, \"package.json\"), \"utf8\")) as typeof pkg;\n } catch {\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 declared = Object.entries({\n ...(pkg.dependencies ?? {}),\n ...(pkg.devDependencies ?? {}),\n }).filter(([name]) => name.startsWith(\"@zitadel/\"));\n const exact = declared.filter(([, version]) => semver.valid(version.trim()) !== null);\n const mismatched = exact.filter(([, version]) => !semver.eq(version.trim(), 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","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 { readdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ZitadelError } from \"./errors\";\n\n/**\n * Read every `*.json` file under `absDir` and return each body as a plain\n * object. Files are read in lexical filename order so the result is\n * deterministic for downstream hashing and diffs. Each file is parsed by\n * `JSON.parse`; this function does **not** apply any schema validation —\n * unknown keys, forward-compatible fields, and `${VAR}` placeholders survive\n * intact. Callers that need a typed shape pass the result through their\n * resource's Zod schema.\n *\n * Returns an empty array when the directory is missing. Throws `E_VALIDATION`\n * `ZitadelError` on invalid JSON or when a file's root value is not an object.\n *\n * @param absDir - Absolute path to the directory to scan.\n */\nexport async function readJsonDir(absDir: string): Promise<ReadonlyArray<Record<string, unknown>>> {\n let entries: string[];\n try {\n entries = await readdir(absDir);\n } catch (error) {\n if (typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\") {\n return [];\n }\n throw error;\n }\n const result: Record<string, unknown>[] = [];\n for (const entry of entries.filter((name) => name.endsWith(\".json\")).sort()) {\n const abs = join(absDir, entry);\n let raw: unknown;\n try {\n raw = JSON.parse(await readFile(abs, \"utf8\"));\n } catch {\n throw new ZitadelError(\"E_VALIDATION\", `${entry} is not valid JSON`);\n }\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n throw new ZitadelError(\"E_VALIDATION\", `${entry} must contain a JSON object at the root`);\n }\n result.push(raw as Record<string, unknown>);\n }\n return result;\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 * sync engine validates with, so doctor and `apply` 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 { ProjectMatchCheck } from \"./project-match\";\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 { ProjectMatchCheck } from \"./project-match\";\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 ProjectMatchCheck(),\n new ClaimCheck(),\n];\n","import { Flags } from \"@oclif/core\";\nimport consola from \"consola\";\n\nimport { claimAction, claimCommand, claimWindowClosedAction } from \"../../lib/claim-state\";\nimport { ZitadelError } from \"../../lib/errors\";\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 assertLocalStateWritable,\n checkLocalServerHealth,\n defaultLocalServerImageForCliVersion,\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 { createOrca } from \"../../lib/orca\";\nimport { resolveCwd } from \"../../lib/paths\";\nimport { hasZitadelConfig } from \"../../lib/project\";\nimport { listenersForPort } from \"../../lib/prober/ports\";\nimport { portableCommands, publicCliCommand } from \"../../lib/public-cli\";\nimport { SANITY_CHECKS, type CheckContext, type CheckOutcome } from \"./checks\";\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.project;\n static override groupOrder = 3;\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 };\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 await this.toMeta(flags, { resolveServer: false, source: localServerUrl(port) });\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 = await runLocalRuntimeChecks(\n nearest?.dir ?? cwd,\n existingRuntime,\n runtimeBackend,\n image,\n port,\n this.localServers(),\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 checks = [...runtimeChecks, ...projectChecks];\n const failed = checks.filter((check) => check.status === \"fail\");\n const warnings = checks.filter((check) => check.status === \"warn\");\n const warningAdvice = advisoryForWarnings(warnings, this.meta.cliVersion);\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 runtime: runtimeBackend,\n ...(runtimeBackend === \"docker\" ? { image } : {}),\n port,\n project: {\n lifecycle: hasConfig ? \"configured\" : \"not-configured\",\n },\n checks,\n ...(warningAdvice\n ? {\n next_actions: warningAdvice.nextActions,\n next_commands: warningAdvice.nextCommands,\n }\n : {}),\n };\n\n if (failed.length > 0) {\n const advice = failureAdvice(\n failed,\n image,\n port,\n this.meta.cliVersion,\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 runtimeDir?: string,\n): { hint: string; nextCommands: string[]; 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: [publicCliCommand(\"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: [`docker pull ${image}`, publicCliCommand(\"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: [publicCliCommand(\"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 = publicCliCommand(\"stop --all\", cliVersion);\n const retryCommand = publicCliCommand(\"doctor\", cliVersion);\n const alternatePortCommand = publicCliCommand(\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 = portableCommands(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: [publicCliCommand(\"doctor\", cliVersion)] };\n }\n\n const hasProjectFailure = failed.some((check) => !LOCAL_RUNTIME_CHECK_NAMES.has(check.name));\n if (hasProjectFailure) {\n return {\n hint: `Run \\`${publicCliCommand(\"doctor --fix\", cliVersion)}\\` to re-apply missing managed files.`,\n nextCommands: [publicCliCommand(\"doctor --fix\", cliVersion)],\n };\n }\n\n return {\n hint: \"Fix the reported checks, then rerun `zitadel doctor`.\",\n nextCommands: [publicCliCommand(\"doctor\", cliVersion)],\n };\n}\n\nfunction advisoryForWarnings(\n warnings: CheckOutcome[],\n cliVersion: string,\n): { nextActions: string[]; nextCommands: string[] } | undefined {\n const nextActions: string[] = [];\n const nextCommands: string[] = [];\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 nextActions.push(\n claimWindowClosed(claimWarning)\n ? claimWindowClosedAction(cliVersion)\n : claimAction(cliVersion),\n );\n nextCommands.push(claimCommand(cliVersion));\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(publicCliCommand(\"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 (nextActions.length === 0 && nextCommands.length === 0) {\n return undefined;\n }\n return { nextActions: unique(nextActions), nextCommands: unique(nextCommands) };\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} did not respond to /healthz`);\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): string | 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 ? 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\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(values: string[]): string[] {\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","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 { publicCliCommand } from \"../lib/public-cli\";\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\";\n\n/**\n * Asks the framework patcher which artifacts it owns. Falls back to the\n * framework-agnostic set (`zitadel.json`, `.zitadel/`, `.env.local`) when the\n * framework or its patcher cannot be resolved, so an orphaned/partial project\n * 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\"],\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.local.ejected-*` backups it created\n * (only when some were made), and uninstalling the SDK packages the patcher\n * added (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<unknown>,\n dependencies: ReadonlyArray<string>,\n): ReadonlyArray<string> {\n const commands: string[] = [];\n if (backedUp.length > 0) {\n commands.push(\"rm -f .env.local.ejected-*\");\n }\n for (const dep of dependencies) {\n commands.push(`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 BaseCommand {\n static override description = \"Remove managed files and local Zitadel state.\";\n static override group = CommandGroups.project;\n static override groupOrder = 4;\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);\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: publicCliCommand(\"eject --force\", this.meta.cliVersion),\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(backedUp, actions.dependencies);\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 next_commands: nextCommands,\n manual_steps: manualSteps,\n },\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../lib/errors\";\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\";\nimport { publicCliCommand } from \"../lib/public-cli\";\n\nexport default class Logs extends BaseCommand {\n static override description = \"Show local Zitadel server logs.\";\n static override group = CommandGroups.localServer;\n static override groupOrder = 4;\n static override flags = {\n follow: Flags.boolean({ description: \"Follow logs.\" }),\n tail: Flags.integer({ description: \"Number of lines to show.\", default: 200 }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Logs);\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 (!runtime) {\n throw new ZitadelError(\"E_VALIDATION\", \"Local Zitadel runtime has not been started\", {\n hint: \"Run `zitadel start` first.\",\n nextCommands: [publicCliCommand(\"start\", this.meta.cliVersion)],\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 server = LocalServer.at(this.meta.cwd, { 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.logs({ tail, follow: true });\n return this.emit({\n status: \"ok\",\n data: { title: \"Stopped following local Zitadel logs.\" },\n });\n }\n\n const { logs } = await server.logs({ tail });\n return this.emit({\n status: \"ok\",\n pretty: logs.trimEnd(),\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,\n },\n });\n }\n}\n","import { consola } from \"consola\";\n\nimport { createZitadelClient } from \"../lib/api-client\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport {\n buildSyncPlan,\n collectPlanWarnings,\n enumeratePlanResources,\n isUnsupportedDeletion,\n makeSyncers,\n renderPlan,\n summarizePlan,\n} from \"../lib/sync\";\nimport { readZitadelSecret } from \"../lib/project\";\n\n/**\n * `zitadel plan` — validate config and preview the sync diff without mutating.\n *\n * The read-only counterpart of `apply`: it builds and renders the diff instead\n * of running the sync loop. All validation (structural shape and env-ref\n * presence) happens in the sync engine, so an invalid file fails the same way\n * `apply` would.\n */\nexport default class Plan extends BaseCommand {\n static override description = \"Validate config without mutation and preview the sync diff.\";\n static override group = CommandGroups.configuration;\n static override groupOrder = 1;\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Plan);\n await this.toMeta(flags);\n const { cwd, source, env, isTTY } = this.meta;\n\n const secret = await readZitadelSecret(cwd);\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n // Verbatim: the plan diffs what it reads against the project's files.\n const client = createZitadelClient(\n { baseUrl: source, token: secret.project_secret },\n { verbatim: true },\n );\n const syncers = makeSyncers({\n client,\n projectId: secret.project_id,\n env,\n cwd,\n });\n\n consola.start(\"Building plan\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n this.recordTelemetry({\n creates: summary.creates,\n updates: summary.updates,\n revisions: summary.revisions,\n deletes: summary.deletes,\n total: summary.total,\n });\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.revisions} new revision${summary.revisions === 1 ? \"\" : \"s\"}, ` +\n `${summary.moves} moved, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}, ` +\n `${plan.filter((action) => action.kind === \"skip\" && !isUnsupportedDeletion(action)).length} unchanged` +\n (summary.unsupported_deletions > 0\n ? `, ${summary.unsupported_deletions} removed but kept (cannot be deleted yet)`\n : \"\"),\n );\n return this.emit({\n status: \"ok\",\n data: {\n ...summary,\n changes: enumeratePlanResources(plan),\n warnings: collectPlanWarnings(plan),\n },\n pretty: renderPlan(plan, isTTY),\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 { publicCliCommand } from \"../lib/public-cli\";\n\nexport default class Reset extends BaseCommand {\n static override description = \"Delete the local Zitadel server runtime and data.\";\n static override group = CommandGroups.localServer;\n static override groupOrder = 5;\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 next_commands: [publicCliCommand(\"reset --force\", this.meta.cliVersion)],\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: publicCliCommand(\"reset --force\", this.meta.cliVersion),\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 { BaseCommand } from \"../../base\";\nimport type { CommandResult, GlobalOptions, JsonEnvelope } from \"../../types\";\nimport type { Json, ResourceCommandOptions, ResourceDescriptor } from \"../types\";\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 BaseCommand {\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 connect(meta: GlobalOptions): Promise<Ctx> {\n return this.definition.options.connect(meta);\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 };\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 { 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 { publicCliCommand } from \"../../../public-cli\";\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: publicCliCommand(`${topic} ${verb} ${id} --force`, meta.cliVersion),\n });\n if (!confirmed) {\n return { status: \"skipped\", reason: `${verb}-cancelled` };\n }\n await spec.call(await this.connect(meta), id);\n return {\n status: \"ok\",\n data: { id, [past]: true },\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 { publicCliCommand } from \"../../../public-cli\";\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 { 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\";\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.connect(meta);\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 publicCliCommand(\n [\n `${topic} list`,\n ...repeatedFlags(flags),\n `--page-token ${shellArg(next)}`,\n \"--json\",\n ].join(\" \"),\n meta.cliVersion,\n ),\n ]\n : [];\n return {\n status: \"ok\",\n data: {\n items,\n count: items.length,\n [wire.nextPageToken]: next,\n ...(nextCommands.length > 0 ? { next_commands: 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: --page-token ${shellArg(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\" ? [`--sort ${shellArg(flags.sort)}`] : [];\n const filters = (Array.isArray(flags.filter) ? flags.filter : []).map(\n (filter) => `--filter ${shellArg(String(filter))}`,\n );\n return [...limit, ...sort, ...filters];\n};\n\n/** Quote a value that a shell would otherwise split or interpret. */\nconst shellArg = (value: string): string =>\n /^[A-Za-z0-9_.:@/=+-]+$/.test(value) ? value : `'${value.replaceAll(\"'\", `'\\\\''`)}'`;\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, idValue } from \"../shared\";\nimport { renderDetail } from \"../table\";\nimport type { GetSpec } from \"../types\";\nimport type { CommandResult, GlobalOptions } 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 description: `Get one ${resource.singular} by id.`,\n examples: [\n `<%= config.bin %> ${topic} get <id>`,\n `<%= config.bin %> ${topic} get <id> --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(\n { flags, args }: OperationInput,\n meta: GlobalOptions,\n ): 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.connect(meta), 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 { publicCliCommand } from \"../../../public-cli\";\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\";\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.connect(meta), body, id);\n const resultId = isObject(result) ? result[resource.idField] : undefined;\n const nextCommands =\n typeof resultId === \"string\" && resource.get\n ? [publicCliCommand(`${topic} get ${resultId} --json`, meta.cliVersion)]\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, next_commands: 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 GetTeamResponse,\n GetUserByIDResponse,\n ListBrandingResponse,\n ListEventsResponse,\n ListFlowDefinitionsResponse,\n ListReleasesResponse,\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\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient, 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\";\nimport { readZitadelSecret } from \"../lib/project\";\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 in\n * `.zitadel/secret` 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/**\n * The runtime resources the CLI manages imperatively — one entry per topic.\n * Config resources (schemas, flows, branding, releases) are deliberately\n * absent: they reconcile from `.zitadel/**` through `plan` / `apply`\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.resources,\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.resources,\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.resources,\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.resources,\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.resources,\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.resources,\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.resources,\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 releases: {\n group: CommandGroups.configuration,\n singular: \"release\",\n idField: \"id\",\n columns: [\"id\", \"metadata.message\", \"metadata.git_sha\"],\n heading: \"id\",\n detail: [\"id\", \"project_id\", \"metadata.message\", \"metadata.git_sha\", \"metadata.git_dirty\"],\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} satisfies ResourceRegistry<Platform>;\n\n/**\n * The `<resource> <verb>` commands, ready for the explicit command table.\n * Connecting mirrors `schemas list` and `apply`: the project secret from\n * `.zitadel/secret` becomes the bearer, so a missing secret fails the same\n * way (`E_VALIDATION` pointing at `zitadel setup`).\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 ({ cwd, source }) => {\n const secret = await readZitadelSecret(cwd);\n // Which project and server a verb is about is worth stating to a human, and\n // is the \"make boundary-crossing visible\" rule from the CLI guidelines. It\n // shares stdout with the result, though, so a piped run would feed those\n // lines to whatever consumes the output — a piped `users list` would have\n // them counted as rows by `wc -l`. On a pipe the result travels alone;\n // `--json` silences them either way.\n if (process.stdout.isTTY) {\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n }\n return {\n client: createZitadelClient({ baseUrl: source, token: secret.project_secret }),\n projectId: secret.project_id,\n };\n },\n});\n","import { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { describeRegistry } from \"../lib/oclif/crud\";\nimport { CommandGroups } from \"../lib/oclif/groups\";\nimport { RESOURCES } from \"./resources\";\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.resources;\n static override groupOrder = 0;\n static override description = \"List the resources this CLI manages and 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.resources[] | \"\\\\(.topic): \\\\(.verbs | join(\", \"))\"\\'',\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 const width = (key: keyof (typeof rows)[number]) =>\n Math.max(key.length, ...rows.map((row) => row[key].length));\n const widths = { topic: width(\"topic\"), verbs: width(\"verbs\"), filters: width(\"filters\") };\n const line = (topic: string, verbs: string, filters: string) =>\n `${topic.padEnd(widths.topic)} ${verbs.padEnd(widths.verbs)} ${filters}`.trimEnd();\n\n return this.emit({\n status: \"ok\",\n data: { resources, count: resources.length },\n pretty: [\n line(\"resource\", \"verbs\", \"filter on\"),\n line(\"-\".repeat(widths.topic), \"-\".repeat(widths.verbs), \"-\".repeat(widths.filters)),\n ...rows.map((row) => line(row.topic, row.verbs, row.filters)),\n \"\",\n `${resources.length} resources. Run \\`${this.config.bin} <resource> <verb> --help\\` for a command's flags.`,\n ].join(\"\\n\"),\n });\n }\n}\n","import { publicCliCommand } from \"./public-cli\";\n\n/**\n * Journey-staged guidance copy shared by `setup` and `status`.\n *\n * The staging exists because of alpha tester feedback (Elina, alpha.15):\n * printing customize/publish steps before the user has logged in once reads\n * as noise, but dropping them entirely recreates the round-1 dead end where\n * nothing pointed to the next step. So the guidance tracks journey position —\n * verify first, customize/publish once login demonstrably works — and both\n * commands quote the same copy so the story doesn't fork.\n */\n\n/**\n * The verify mission: prove the scaffolded auth round-trips before touching\n * config. `openUrl` prefixes the browser destination for callers that have\n * not already narrated it (setup's box has a separate \"Start your project\"\n * line; status has only the issuer).\n */\nexport function verifyLoginAction(openUrl?: string): string {\n const open = openUrl ? `open ${openUrl}, ` : \"\";\n return (\n `Verify auth in the browser: ${open}register a user, log out, ` +\n \"log in again with the same user, and confirm /profile shows Signed in.\"\n );\n}\n\n/** The customize/publish pair, in Elina's tested wording. */\nexport function customizeAndPublishActions(cliVersion: string): string[] {\n return [\n \"Customize what you ask for and how people sign in: edit .zitadel/schemas/ to change \" +\n \"the information you collect, and .zitadel/flows/ to change the sign-up/sign-in \" +\n \"experience. Each folder has a README with examples.\",\n `See your changes before they go live: ${publicCliCommand(\"plan\", cliVersion)} to preview, ` +\n `then ${publicCliCommand(\"apply\", cliVersion)} to publish.`,\n ];\n}\n\n/**\n * How to change the login's look after setup. Setup never ejects a template\n * or publishes a branding revision (#1039): the app embeds the maintained\n * `<zitadel-login>`, so its look is the app's own CSS (`--zl-*` tokens) and\n * layout around it. Taking ownership of the widget's structure stays the\n * opt-in `branding eject`, surfaced here so it remains discoverable.\n */\nexport function brandingGuidanceAction(cliVersion: string): string {\n return (\n \"Change how the login looks: it is a component in your app, so theme it with `--zl-*` \" +\n \"custom properties in your own stylesheet and build any page layout around it in your \" +\n \"code. To change the widget's structure, \" +\n `${publicCliCommand(\"branding eject\", cliVersion)} scaffolds an editable template ` +\n \"in .zitadel/branding/.\"\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, 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 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 selectionName,\n} from \"@zitadel/config/idp\";\nimport {\n normalizeFlowBody,\n normalizeIdpBody,\n normalizeSchemaBody,\n} from \"@zitadel/config/normalize\";\n\nimport { FLOWS_DIR } from \"./flows\";\nimport {\n applySsoToFlow,\n applySsoToSchema,\n authMethods,\n CONNECTION_SCHEMA_REF,\n customFlagText,\n ENABLE_FLAG_NAMES,\n SETUP_FLAG_NAMES,\n IDPS_DIR,\n planConnection,\n readConnectionFiles,\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 { ZitadelError } from \"./errors\";\n\nexport type MaterializeSetupResourcesResult = {\n filesWritten: string[];\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 * 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 const schemasReadme = join(SCHEMAS_DIR, \"README.md\");\n const flowsReadme = join(FLOWS_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\n return { filesWritten };\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 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}\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): { hint: string; nextCommands: string[] } {\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 nextCommands: [\n `zitadel auth-method sso enable --provider ${selectionName(selection)}${\n selection.kind === \"custom\"\n ? ` ${customFlagText(selection.connection, ENABLE_FLAG_NAMES)}`\n : \"\"\n }`,\n ],\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?: string[] },\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?: string[] },\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 { publicCliCommand } from \"../../lib/public-cli\";\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: string[];\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 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 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 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 includeInstallCommand: false,\n });\n}\n\nfunction outcome(input: {\n install: SetupInstall;\n devCommand: string;\n cliVersion: string;\n issuer: string;\n includeInstallCommand: boolean;\n}): SetupInstallOutcome {\n const planCommand = publicCliCommand(\"plan\", input.cliVersion);\n const statusCommand = publicCliCommand(\"status\", 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: [...verifyActions, ...customizeAndPublishActions(input.cliVersion)],\n nextCommands: input.includeInstallCommand\n ? [input.install.command, input.devCommand, planCommand]\n : [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: [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: \"preview\" });\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 const previewOrigins = replaceOrigin(secret.preview_origins, previousIssuer, issuer);\n await writeZitadelSecret(cwd, {\n ...secret,\n preview_origins: previewOrigins.filter((pattern) => typeof pattern === \"string\"),\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 type { PromptContext, SetupAnswers, SetupPrompt } from \"./types\";\n\n/**\n * \"Dev server port\" — defaults to the detected port. The validated answer\n * becomes the issuer URL (`http://localhost:<port>`) via `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) {\n return answers;\n }\n const devPort = await ctx.input({\n kind: \"text\",\n name: \"dev server port\",\n message: \"Dev server port\",\n placeholder: String(answers.devPort),\n initialValue: String(answers.devPort),\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 * \"Detected `<framework>`. Proceed?\" — the wizard's first question. Accepting\n * leaves answers unchanged; declining throws `E_UNSUPPORTED_PROJECT_SHAPE`\n * (the user should re-run with an explicit `--framework`). Skipped when the\n * developer already named the framework, by picking it to scaffold or with\n * `--framework`: detection then only read back their own 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: `Detected ${ctx.framework.id}. Proceed?`,\n initialValue: true,\n });\n if (ack === false) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n \"Setup stopped — the detected framework was declined\",\n { hint: `Re-run with --framework ${ctx.framework.id} when ready.` },\n );\n }\n return answers;\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\n/**\n * \"Which server should `zitadel.json` point to?\" — Zitadel Cloud, the managed\n * local server we detected, or a custom URL.\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 runtime metadata that\n * `zitadel start` wrote to `.zitadel/local/runtime.json`, falling back to a\n * `/healthz` probe on the default localhost port). A detected server becomes\n * an extra option in the choice list *and* the preselected answer — a user\n * who just ran `zitadel start` almost certainly wants it, and `start`'s own\n * next-step hint says `setup --server local`. Picking it writes the URL\n * directly to `answers.server`; picking \"Custom URL\" still asks for a\n * validated URL exactly as before.\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 server should zitadel.json point to?\",\n options: [\n {\n value: DEFAULT_SERVER,\n label: `Zitadel Cloud (${new URL(DEFAULT_SERVER).host})`,\n hint: \"recommended for real projects\",\n },\n ...(detected\n ? [\n {\n value: detected,\n label: `Local Zitadel server (${detected})`,\n hint: \"detected — started with zitadel start\",\n },\n ]\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: \"Server URL\",\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 unhealthy paths\n * block on up to two 1.5s `/healthz` probes, long enough that the wizard\n * should say what it is doing.\n */\nasync function detectLocalServer(cwd: string): Promise<string | undefined> {\n const s = spinner();\n s.start(\"Checking for a local Zitadel server\");\n const detected = await LocalServer.detectUrl(cwd);\n s.stop(\n detected ? `Found local Zitadel server at ${detected}.` : \"No local Zitadel server detected.\",\n );\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 * \"How should users sign in?\" — 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 const labels: Record<SetupPreset, string> = {\n \"password-first\": \"Password first — email + password\",\n \"passkey-first\": \"Passkey first — one-tap passkey up front, email + password fallback\",\n };\n const preset = await ctx.input({\n kind: \"select\",\n name: \"sign-in preset\",\n message: \"How should users sign in?\",\n initialValue: answers.preset,\n options: SETUP_PRESETS.map((preset) => ({ value: preset, label: labels[preset] })),\n });\n return { ...answers, preset };\n }\n}\n","import { note } from \"@clack/prompts\";\n\nimport {\n credentialVariables,\n CUSTOM_PROVIDER,\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 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} 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: \"Name for this connection (used in your configuration, e.g. 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: \"Name shown on the sign-in button (e.g. Acme SSO)\",\n parse: parseDisplayName,\n given: given.displayName,\n });\n const issuer = await ask({\n kind: \"text\",\n name: \"issuer\",\n message: \"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: \"Scopes to request\",\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 * \"Add social sign-in providers?\" — the one onboarding question that needs\n * something from outside the terminal, so it asks last of the configuration\n * questions and takes \"not now\" as a 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 *\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.\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 message: `Client ID (${entry.displayName})`,\n parse: parseClientId,\n given: flagged?.credentials.clientId,\n });\n const secret = await ctx.input({\n kind: \"secret\",\n name: \"client secret\",\n message: `Client secret (published to 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: \"social sign-in providers\",\n message: \"Add social sign-in providers?\",\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: `Continue with ${idpProvider(provider).displayName}`,\n hint: \"needs an OAuth app you register with the provider\",\n })),\n {\n value: CUSTOM_PROVIDER as ProviderName,\n label: \"Continue with another OpenID Connect provider\",\n hint: \"you name it and give its issuer\",\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","import { SETUP_USE_CASES, type SetupUseCase } from \"@zitadel/config/defaults\";\n\nimport type { PromptContext, SetupAnswers, SetupPrompt } from \"./types\";\n\n/**\n * \"Who will sign in to your app?\" — picks the use case, which owns the\n * schema field set the scaffold collects (#448). Orthogonal to the sign-in\n * preset, so this asks first: what a user *is* before *how* they 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 // Audience-first labels (the use case is recorded in `zitadel.json` and may\n // inform guidance/status beyond the schema, so it stays generic), with the\n // collected fields as a dimmed per-option hint. The message notes the fields\n // stay editable after setup — the scaffolded schema/flow are the source of\n // truth.\n const options: Record<SetupUseCase, { label: string; hint: string }> = {\n minimal: { label: \"Just me or a small group\", hint: \"collects email\" },\n consumer: { label: \"Consumers\", hint: \"collects email, given & family name\" },\n business: { label: \"Business\", hint: \"collects email, given & family name, company\" },\n };\n const useCase = await ctx.input({\n kind: \"select\",\n name: \"use case\",\n message: \"Who will sign in to your app? Collected fields stay editable after setup.\",\n initialValue: answers.useCase,\n options: SETUP_USE_CASES.map((useCase) => ({\n value: useCase,\n label: options[useCase].label,\n hint: options[useCase].hint,\n })),\n });\n return { ...answers, useCase };\n }\n}\n","import 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 { FrameworkFacts } from \"../../../lib/orca\";\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\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 \"Detected next. Proceed?\" would be\n * answered yes without asking. This one never is.\n */\n readonly input: Asker;\n /**\n * The framework of the app setup integrates. Only its id: a new app does not\n * exist while the wizard asks, because setup creates it once it has every\n * answer.\n */\n readonly framework: Pick<FrameworkFacts, \"id\">;\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 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 * \"Choose a framework 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: \"Choose a framework 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 { 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 { 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 SocialSignInPrompt(),\n];\n","import { readFile, stat } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\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\";\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","import { readFile, rm, writeFile } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { intro, 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 ENABLE_FLAG_NAMES,\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 storeClientSecret,\n type SecretOutcome,\n type SecretPublisher,\n} from \"../../lib/idp\";\nimport { brandingGuidanceAction } from \"../../lib/journey-guidance\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope, nonBlankString } from \"../../lib/oclif\";\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 { publicCliCommand } from \"../../lib/public-cli\";\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 url as styleUrl,\n type Row,\n type Section,\n} from \"./summary\";\nimport { showSkillsHint } from \"../../lib/skills-hint\";\nimport { reportWarning } from \"../../lib/warnings\";\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/** `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 BaseCommand {\n static override description = \"Create a Zitadel project and scaffold local auth.\";\n static override group = CommandGroups.project;\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 [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 // First thing `setup` prints, so ahead of `toMeta`, which opens telemetry\n // (its first-run notice goes to stderr) and can throw on server resolution.\n await showSkillsHint({\n env: process.env,\n interactive:\n !this.jsonEnabled() &&\n !flags[\"non-interactive\"] &&\n Boolean(process.stdout.isTTY && process.stdin.isTTY),\n });\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 ${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\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 step: \"framework_resolved\",\n });\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 };\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 },\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 developmentBuild: isDevelopmentBuild(),\n };\n for (const prompt of SETUP_PROMPTS) {\n answers = await prompt.ask(answers, promptCtx);\n }\n outro(\"Configuration captured\");\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 });\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 },\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 envLocalBefore = await readEnvLocal(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 restoreEnvLocal(cwd, envLocalBefore);\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: [] }\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 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 restoreEnvLocal(cwd, envLocalBefore);\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 schema/flow upload did not finish. \" +\n \"Re-run `zitadel setup` to start over; --force overwrites the files setup \" +\n \"scaffolds. 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 schema/flow upload did not finish, \" +\n \"so setup removed the new app again. Re-run setup as before to start over.\"),\n nextCommands:\n cause.nextCommands ?? (newApp === undefined ? [\"zitadel 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\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 // `variables 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(idVariable, clientId, this.meta.cliVersion);\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);\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 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)],\n boxActions: [claimBoxAction(this.meta.cliVersion, deadline)],\n commands: [claimCommand(this.meta.cliVersion)],\n }\n : { actions: [], boxActions: [], commands: [] };\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 = publicCliCommand(\"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: [] };\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 }\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 `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\n // step.\n next_commands: [\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 ),\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 runFromHint(guidance.retry)\n ).trimEnd(),\n nextCommands:\n guidance.serverFlag === \"local\" && suggested\n ? [\n publicCliCommand(\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: \"preview\" }],\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/** What `.env.local` holds, or `undefined` when there is no such file. */\nasync function readEnvLocal(cwd: string): Promise<Buffer | undefined> {\n try {\n return await readFile(join(cwd, \".env.local\"));\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return undefined;\n }\n throw error;\n }\n}\n\n/**\n * Puts `.env.local` back to what {@link readEnvLocal} read before the patch,\n * and removes it when there was none. The patch merged the failed setup's\n * project id and secret into it, and a merge only adds the keys a file is\n * missing, `--force` or not: left in place, they would survive the rerun, and\n * the app would talk to an abandoned project with no schema or login flow.\n * `.env.example` needs nothing: it gets the same empty values on every run.\n */\nasync function restoreEnvLocal(cwd: string, before: Buffer | undefined): Promise<void> {\n const path = join(cwd, \".env.local\");\n if (before === undefined) {\n await rm(path, { force: true });\n return;\n }\n await writeFile(path, before);\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 `variables 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: \"Client secret\",\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: `printf '%s' \"$CLIENT_SECRET\" | ${publicCliCommand(`setup --sso ${flags.sso} --sso-client-id <id> ...`, cliVersion)}`,\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, when it was not the shell's own.\n * Named in the guidance rather than passed as `--cwd` in the command text:\n * a path can carry spaces and metacharacters, and nothing escapes a\n * suggested command for a shell -- the same reason the client id is not\n * interpolated either. Prose the developer reads, not an argument a shell\n * splits.\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\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 // 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(\" \");\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 */\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 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 // 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 */\nfunction runFromHint(retry: SetupRetryOptions): string {\n if (retry.cwd === undefined || retry.cwd === process.cwd()) {\n return \"\";\n }\n return `Run these from ${retry.cwd}, which is the project they configure. `;\n}\n\nfunction ssoRecovery(\n retry: SetupRetryOptions,\n cliVersion: string,\n): { hint: string; commands: string[] } {\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 // `--server local`, as the setup retry pins it. Server resolution prefers\n // `ZITADEL_API_BASE` over the project's own `zitadel.json`, so an\n // unpinned `auth-method sso enable` run with that variable set would publish the\n // client id and secret to whatever it names, using the local project's\n // token -- leaving the local provider unconfigured and the credentials\n // somewhere nobody asked for. Both callers of this are local-server\n // failures, so `local` is the server meant in every case.\n commands: remaining.map((selection) =>\n publicCliCommand(\n `auth-method sso enable --provider ${selectionName(selection)}${\n selection.kind === \"custom\"\n ? ` ${customFlagText(selection.connection, ENABLE_FLAG_NAMES)}`\n : \"\"\n } --server local`,\n cliVersion,\n ),\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 so the backend's origin check allows the\n // requests the dev proxy forwards from it.\n return await client.createProject({\n name: projectName,\n origins: [{ pattern: issuer, kind: \"preview\" }],\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}. ${runFromHint(retry)}${sso.hint}`.trimEnd(),\n nextCommands: [\n publicCliCommand(\"start\", cliVersion),\n publicCliCommand(`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. ${runFromHint(retry)}`.trimEnd(),\n nextCommands: [\n publicCliCommand(\"start\", cliVersion),\n publicCliCommand(`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 runFromHint(retry) +\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 publicCliCommand(\"start\", cliVersion),\n publicCliCommand(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 * 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 \".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/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 and how it authenticates —\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 ] 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 consola from \"consola\";\n\nimport { ZitadelError, toZitadelError } from \"../lib/errors\";\nimport { ensureLocalAdmin, type LocalAdmin } 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 { consoleSignInUrl } from \"../lib/local-server/sign-in\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope, nonBlankString } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\nimport { publicCliCommand } from \"../lib/public-cli\";\nimport { reportWarning } from \"../lib/warnings\";\n\nexport default class Start extends BaseCommand {\n static override description = \"Start a local Zitadel server.\";\n static override group = CommandGroups.localServer;\n static override groupOrder = 1;\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 login: `${serverUrl}/ui/login/`,\n },\n next_commands: [publicCliCommand(\"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(\n runtime,\n alreadyRunning,\n this.meta.cliVersion,\n await consoleLoginFor(runtime.server_url, local?.admin),\n ),\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\n/**\n * Mints a console sign-in link for the local admin. A failure (for\n * example a data directory from before the local admin existed) must not fail\n * the start itself, so it degrades to a warning with the fix. Without a local\n * admin there is nothing to sign in as, and the result carries no console.\n */\nasync function consoleLoginFor(\n serverUrl: string,\n admin: LocalAdmin | undefined,\n): Promise<ConsoleLogin | undefined> {\n if (!admin) {\n return undefined;\n }\n try {\n const url = await consoleSignInUrl(serverUrl, admin);\n consola.log(`Console: signed in as ${admin.email}. Open this link (works once):`);\n consola.log(url);\n return { signed_in_as: admin.email, sign_in_url: url };\n } catch (error) {\n const reason = toZitadelError(error);\n reportWarning(`Could not create a console sign-in link: ${reason.message}`);\n return { signed_in_as: admin.email, error: reason.message, hint: reason.hint };\n }\n}\n\ntype ConsoleLogin = {\n signed_in_as: string;\n sign_in_url?: string;\n error?: string;\n hint?: string;\n};\n\nfunction readyData(\n metadata: RuntimeMetadata,\n alreadyRunning: boolean,\n cliVersion: string,\n console: ConsoleLogin | undefined,\n) {\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 login: `${metadata.server_url}/ui/login/`,\n },\n ...(console ? { console } : {}),\n next_actions: [\n ...(console?.sign_in_url\n ? [`Console: you are ${console.signed_in_as}. Open ${console.sign_in_url} (works once).`]\n : []),\n \"Run setup in this directory or one inside it, so it finds this server's local admin; the CLI will detect the framework or ask when needed.\",\n \"Setup installs dependencies when needed; then start your app dev server.\",\n ],\n next_commands: [\n publicCliCommand(\"setup --server local\", cliVersion),\n // Only when a link could actually be minted: `zitadel console` mints\n // the same way, so suggesting it after a failure sends the caller at a\n // command that fails again.\n ...(console?.sign_in_url ? [publicCliCommand(\"console\", cliVersion)] : []),\n ],\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 { createZitadelClient } from \"../lib/api-client\";\nimport {\n claimAction,\n claimCommand,\n claimState,\n claimWindowClosedAction,\n type ClaimState,\n} from \"../lib/claim-state\";\nimport { customizeAndPublishActions, verifyLoginAction } 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 { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\nimport {\n hasZitadelConfig,\n hasZitadelSecret,\n readDevelopmentIssuer,\n readProjectServer,\n readZitadelConfig,\n readZitadelSecret,\n} from \"../lib/project\";\nimport { publicCliCommand } from \"../lib/public-cli\";\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 BaseCommand {\n static override description = \"Summarize the local Zitadel server and project state.\";\n static override group = CommandGroups.localServer;\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(this.meta.cwd);\n const users =\n project.lifecycle === \"configured\"\n ? await detectUserPresence(this.meta.cwd, this.meta.source)\n : \"unknown\";\n const nextCommands = nextCommandsFor(serverLifecycle, project, users, this.meta.cliVersion);\n const nextActions = nextActionsFor(project, users, this.meta.cliVersion);\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 next_commands: nextCommands,\n },\n });\n }\n}\n\ntype ProjectStatus =\n | {\n lifecycle: \"not-configured\";\n message: 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\nasync function projectStatus(cwd: string): 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\n const config = await readZitadelConfig(cwd);\n if (!(await hasZitadelSecret(cwd))) {\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 secret = await readZitadelSecret(cwd);\n // Gated on the server recorded in `zitadel.json`, not `this.meta.source`:\n // `status --server local` rewrites the source for the health probe, but it\n // does not move the project, so the source would answer the wrong question.\n const claim = claimState({ secret, server: readProjectServer(config) });\n return {\n lifecycle: \"configured\",\n project_id: String(config.project ?? secret.project_id ?? \"\"),\n issuer: readDevelopmentIssuer(config),\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(cwd: string, source: string): Promise<UserPresence> {\n try {\n const secret = await readZitadelSecret(cwd);\n const client = createZitadelClient({\n baseUrl: source,\n token: secret.project_secret,\n });\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(project: ProjectStatus, users: UserPresence, cliVersion: string): string[] {\n if (project.lifecycle === \"not-configured\") {\n return [\n \"From your app directory, run setup; the CLI will detect the framework or ask in an empty directory.\",\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 ),\n ]\n : [claimWindowClosedAction(cliVersion)]\n : [];\n if (users === \"none\") {\n return [verifyLoginAction(project.issuer), ...claim];\n }\n if (users === \"some\") {\n return [...customizeAndPublishActions(cliVersion), ...claim];\n }\n return claim;\n}\n\nfunction nextCommandsFor(\n serverLifecycle: string,\n project: ProjectStatus,\n users: UserPresence,\n cliVersion: string,\n): string[] {\n const commands: string[] = [];\n if (serverLifecycle !== \"running\") {\n commands.push(publicCliCommand(\"start\", cliVersion));\n }\n if (project.lifecycle === \"not-configured\") {\n commands.push(publicCliCommand(\"setup --server local\", cliVersion));\n } else if (project.lifecycle === \"orphaned-config\") {\n commands.push(\n publicCliCommand(\"setup --force\", cliVersion),\n publicCliCommand(\"doctor --fix\", cliVersion),\n );\n } else {\n commands.push(publicCliCommand(\"doctor\", 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));\n }\n if (users === \"none\") {\n // Staged like next_actions: before the first login is proven in a\n // browser, publishing is premature — `plan` previews safely and the\n // verify mission lives in next_actions. `apply` joins once users\n // exist (\"some\") or when the probe can't tell (\"unknown\" keeps the\n // lifecycle-only behavior rather than withholding on no signal).\n commands.push(publicCliCommand(\"plan\", cliVersion));\n } else {\n commands.push(publicCliCommand(\"apply\", 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 { publicCliCommand } from \"../lib/public-cli\";\n\nexport default class Stop extends BaseCommand {\n static override description = \"Stop the local Zitadel server.\";\n static override group = CommandGroups.localServer;\n static override groupOrder = 2;\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 next_commands: [publicCliCommand(\"stop\", this.meta.cliVersion)],\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 { CommandGroups, type JsonEnvelope, nonBlankArg, OwnerCommand } from \"../../lib/oclif\";\nimport { dryRunResult } from \"../../lib/oclif/crud/shared\";\nimport { assertVariableName } from \"../../lib/variables\";\nimport { publicCliCommand } from \"../../lib/public-cli\";\n\n/**\n * The `variables delete` topic command — remove one variable from the project\n * level.\n *\n * Deleting a name the project does not hold answers `var.not_found`.\n * Destructive, so it takes the same `--force`-or-confirm gate the resource\n * commands' `delete` uses.\n */\nexport default class VariablesDelete extends OwnerCommand {\n static override description = \"Delete one variable from the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variables delete GOOGLE_CLIENT_ID --project-level\",\n \"<%= config.bin %> variables delete GOOGLE_CLIENT_ID --project-level --force\",\n ];\n static override args = {\n name: nonBlankArg({ required: true, description: \"Variable name to delete.\" }),\n };\n static override flags = {\n // `--force` is per command, not global: here it permits a deletion.\n force: Flags.boolean({\n char: \"f\",\n description:\n \"Delete 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(VariablesDelete);\n await this.toMeta(flags);\n const { dryRun, cliVersion } = this.meta;\n const name = args.name;\n\n assertVariableName(name);\n\n const { client, scope } = await this.connect();\n\n // A dry run makes no request, so it answers before the guard — the order\n // the resource commands' `delete` uses, which keeps\n // `--dry-run --non-interactive` usable.\n if (dryRun) {\n // The resource commands' dry-run contract, so an agent reads one shape\n // for every preview; `deleted` is reserved for a deletion that happened.\n const preview = dryRunResult(\"delete\", \"variables\", name);\n return this.emit({ ...preview, pretty: `${preview.pretty} from the project` });\n }\n\n const confirmed = await this.input({\n kind: \"confirm\",\n name: `delete ${name} from the project`,\n message: `Delete ${name} from the project?`,\n retry: publicCliCommand(`variables delete ${name} --project-level --force`, cliVersion),\n });\n if (!confirmed) {\n return this.emit({ status: \"skipped\", reason: \"delete-cancelled\" });\n }\n\n await client.deleteVariable(name, scope);\n\n return this.emit({\n status: \"ok\",\n data: { name, deleted: true },\n pretty: `Deleted ${name} from the project`,\n });\n }\n}\n","import { CommandGroups, type JsonEnvelope, nonBlankArg, OwnerCommand } from \"../../lib/oclif\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { renderDetail } from \"../../lib/oclif/crud/table\";\nimport { assertVariableName, toVariableRow, variableCells } from \"../../lib/variables\";\n\n/**\n * The `variables get` topic command — read one variable by name at the project\n * level.\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.\n */\nexport default class VariablesGet extends OwnerCommand {\n static override description = \"Get one variable from the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variables get GOOGLE_CLIENT_ID --project-level\",\n \"<%= config.bin %> variables get GOOGLE_CLIENT_ID --project-level --json\",\n ];\n static override args = {\n name: nonBlankArg({ required: true, description: \"Variable name to read.\" }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(VariablesGet);\n await this.toMeta(flags);\n const name = args.name;\n\n assertVariableName(name);\n const { client, scope } = await this.connect();\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 { primary } = await client.getVariable(name, { ...scope, kind: \"primary\" });\n if (primary === undefined) {\n throw new ZitadelError(\"E_NOT_FOUND\", `Variable ${name} has no primary value.`);\n }\n const row = toVariableRow(name, primary);\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, OwnerCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { renderRows, renderTable } from \"../../lib/oclif/crud/table\";\nimport { primaryValues, toVariableRows, variableCells } from \"../../lib/variables\";\n\n/** The columns `list` renders, in order. */\nconst COLUMNS = [\"name\", \"value\"] as const;\n\n/**\n * The `variables list` topic command — show the variables entered at the\n * project level.\n *\n * A secret is reported as held without its value, because the platform never\n * discloses one.\n */\nexport default class VariablesList extends OwnerCommand {\n static override description = \"List the variables entered on the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variables list --project-level\",\n \"<%= config.bin %> variables list --project-level --json\",\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(VariablesList);\n await this.toMeta(flags);\n const { client, scope } = await this.connect();\n\n const body = await client.getVariables({ ...scope, kind: \"primary\" });\n const rows = toVariableRows(primaryValues(body));\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 = variableCells(rows);\n const plain = flags.plain || !process.stdout.isTTY;\n return this.emit({\n status: \"ok\",\n data: {\n variables: rows,\n count: rows.length,\n },\n pretty: plain\n ? renderRows(COLUMNS, cells)\n : rows.length === 0\n ? \"No variables on the project.\"\n : [\n renderTable(COLUMNS, cells),\n \"\",\n `${rows.length} ${rows.length === 1 ? \"variable\" : \"variables\"}`,\n ].join(\"\\n\"),\n });\n }\n}\n","import { Flags } from \"@oclif/core\";\n\nimport { CommandGroups, type JsonEnvelope, nonBlankArg, OwnerCommand } from \"../../lib/oclif\";\nimport { dryRunResult } from \"../../lib/oclif/crud/shared\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport {\n assertVariableName,\n parseVariableValue,\n VARIABLE_TYPES,\n type VariableType,\n} from \"../../lib/variables\";\nimport { publicCliCommand } from \"../../lib/public-cli\";\n\n/**\n * The `variables set` topic command — enter or replace one variable at the\n * project level.\n *\n * The value never comes from a flag. It is prompted for, or read from stdin\n * when scripting, so a credential cannot land in shell history, a process\n * listing, or CI logs. `--secret` stores it encrypted under the project's own\n * key, after which it can be replaced but never read back (ADR 062 §7).\n */\nexport default class VariablesSet extends OwnerCommand {\n static override description = \"Set one variable on the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variables set GOOGLE_CLIENT_ID --project-level\",\n \"<%= config.bin %> variables set GOOGLE_CLIENT_SECRET --project-level --secret < secret.txt\",\n \"<%= config.bin %> variables set SESSION_TTL --project-level --as number\",\n ];\n static override args = {\n name: nonBlankArg({\n required: true,\n description: \"Variable name (letters, digits and underscores).\",\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 };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(VariablesSet);\n await this.toMeta(flags);\n const { dryRun, cliVersion } = 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\n const { client, scope } = await this.connect();\n\n if (dryRun) {\n // The resource commands' dry-run contract, plus what this write would\n // store. Never the value: a dry run has not read it, and it may be a\n // credential.\n const preview = dryRunResult(\"set\", \"variables\", name);\n return this.emit({\n ...preview,\n data: { ...(preview.data as object), secret: flags.secret, as: type },\n pretty: `${preview.pretty} on the project${flags.secret ? \" (secret)\" : \"\"}${type === \"string\" ? \"\" : ` as ${type}`}`,\n });\n }\n\n // A value never comes from a flag, so a scripted run has to pipe one in.\n // The prompt is masked when the value is to be stored as a secret, so it\n // does not stay on screen or in a scrollback buffer. An empty string is a\n // value the scalar schema 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: `Value for ${name}`,\n stdin: true,\n retry: pipeHint(name, flags.secret, type, cliVersion),\n parse: (raw) => parseVariableValue(raw, type),\n });\n\n await client.updateVariables({ [name]: { value, secret: flags.secret } }, scope);\n this.recordTelemetry({ is_secret: flags.secret });\n\n return this.emit({\n status: \"ok\",\n data: { name, secret: flags.secret, type },\n pretty: `Set ${name} on the project${flags.secret ? \" (secret)\" : \"\"}`,\n });\n }\n}\n\n/**\n * The scripted form to suggest when a run supplied no value.\n *\n * It carries the owner, the secret flag and the type the run actually used.\n * Dropping any of them would hand back a command that writes a credential as a\n * readable value, or stores a number as a string.\n */\nfunction pipeHint(name: string, secret: boolean, type: VariableType, cliVersion: string): string {\n const args = [\n \"variables\",\n \"set\",\n name,\n \"--project-level\",\n ...(secret ? [\"--secret\"] : []),\n ...(type === \"string\" ? [] : [\"--as\", type]),\n ].join(\" \");\n return `${publicCliCommand(args, cliVersion)} < value.txt`;\n}\n","import type { Command } from \"@oclif/core\";\n\nimport Api from \"./commands/api/index\";\nimport ApiLs from \"./commands/api/ls\";\nimport Apply from \"./commands/apply\";\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 Doctor from \"./commands/doctor/index\";\nimport Eject from \"./commands/eject\";\nimport Logs from \"./commands/logs\";\nimport Plan from \"./commands/plan\";\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 VariablesDelete from \"./commands/variables/delete\";\nimport VariablesGet from \"./commands/variables/get\";\nimport VariablesList from \"./commands/variables/list\";\nimport VariablesSet from \"./commands/variables/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 apply: Apply,\n claim: Claim,\n console: Console,\n doctor: Doctor,\n eject: Eject,\n logs: Logs,\n plan: Plan,\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 \"variables:list\": VariablesList,\n \"variables:get\": VariablesGet,\n \"variables:set\": VariablesSet,\n \"variables:delete\": VariablesDelete,\n ...RESOURCE_COMMANDS,\n};\n"],"mappings":"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"}