@zitadel/cli 1.0.0-alpha.22 → 1.0.0-alpha.23
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.
- package/README.md +2248 -227
- package/SKILLS.md +237 -65
- package/dist/groups-CMB0fMzE.mjs +22 -0
- package/dist/groups-CMB0fMzE.mjs.map +1 -0
- package/dist/index.mjs +16027 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/oclif/help.mjs +67 -0
- package/dist/lib/oclif/help.mjs.map +1 -0
- package/oclif.manifest.json +4577 -185
- package/package.json +40 -8
- package/dist/box-B_mwKole.mjs +0 -35
- package/dist/box-B_mwKole.mjs.map +0 -1
- package/dist/branding-DvoH8e0D.mjs +0 -79
- package/dist/branding-DvoH8e0D.mjs.map +0 -1
- package/dist/claim-state-B6ZSKmhW.mjs +0 -125
- package/dist/claim-state-B6ZSKmhW.mjs.map +0 -1
- package/dist/commands/apply.mjs +0 -81
- package/dist/commands/apply.mjs.map +0 -1
- package/dist/commands/branding/eject.mjs +0 -104
- package/dist/commands/branding/eject.mjs.map +0 -1
- package/dist/commands/claim.mjs +0 -445
- package/dist/commands/claim.mjs.map +0 -1
- package/dist/commands/doctor.mjs +0 -1138
- package/dist/commands/doctor.mjs.map +0 -1
- package/dist/commands/eject.mjs +0 -157
- package/dist/commands/eject.mjs.map +0 -1
- package/dist/commands/logs.mjs +0 -58
- package/dist/commands/logs.mjs.map +0 -1
- package/dist/commands/plan.mjs +0 -65
- package/dist/commands/plan.mjs.map +0 -1
- package/dist/commands/reset.mjs +0 -79
- package/dist/commands/reset.mjs.map +0 -1
- package/dist/commands/schemas/list.mjs +0 -146
- package/dist/commands/schemas/list.mjs.map +0 -1
- package/dist/commands/setup.mjs +0 -1309
- package/dist/commands/setup.mjs.map +0 -1
- package/dist/commands/start.mjs +0 -288
- package/dist/commands/start.mjs.map +0 -1
- package/dist/commands/status.mjs +0 -151
- package/dist/commands/status.mjs.map +0 -1
- package/dist/commands/stop.mjs +0 -105
- package/dist/commands/stop.mjs.map +0 -1
- package/dist/designs-Ckz18Dpo.mjs +0 -38
- package/dist/designs-Ckz18Dpo.mjs.map +0 -1
- package/dist/docker-B1MjOMFo.mjs +0 -436
- package/dist/docker-B1MjOMFo.mjs.map +0 -1
- package/dist/environment-fibXmzM8.mjs +0 -17
- package/dist/environment-fibXmzM8.mjs.map +0 -1
- package/dist/journey-guidance-C9MxJNTg.mjs +0 -40
- package/dist/journey-guidance-C9MxJNTg.mjs.map +0 -1
- package/dist/oclif-JlsN1lfO.mjs +0 -1769
- package/dist/oclif-JlsN1lfO.mjs.map +0 -1
- package/dist/orca-CPMHzmg3.mjs +0 -3917
- package/dist/orca-CPMHzmg3.mjs.map +0 -1
- package/dist/package-manager-CDUsoGBy.mjs +0 -194
- package/dist/package-manager-CDUsoGBy.mjs.map +0 -1
- package/dist/ports-hidBnSW-.mjs +0 -116
- package/dist/ports-hidBnSW-.mjs.map +0 -1
- package/dist/processes-Cv19mJ2I.mjs +0 -120
- package/dist/processes-Cv19mJ2I.mjs.map +0 -1
- package/dist/project-Ba0nriNm.mjs +0 -140
- package/dist/project-Ba0nriNm.mjs.map +0 -1
- package/dist/sync-ChlLQ4vZ.mjs +0 -1633
- package/dist/sync-ChlLQ4vZ.mjs.map +0 -1
- package/dist/user-schema-C2mC-JTN.mjs +0 -91
- package/dist/user-schema-C2mC-JTN.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["createZitadelClient","createRawClient","errorMessage","appendGitignoreEntry","isErrno","DISABLED_VALUES","delay","exists","createZitadelClient","isPlainObject","isErrno","readJsonDir","createZitadelClient","isErrno","command","nodeSpawn","createZitadelClient","sleep","isErrno","errorMessage","dirExists","readIfExists","exists","SDK_DEPENDENCY","SDK_DEPENDENCY","appTemplate","SDK_DEPENDENCY","appTemplate","appTemplate","SDK_DEPENDENCY","appTemplate","appTemplate","SDK_DEPENDENCY","appTemplate","appTemplate","SDK_DEPENDENCY","appTemplate","isErrno","resolveRuntimeBackend","unique","createZitadelClient","text","createZitadelClient","createZitadelClient","relativeDisplay","stylePath","styleId","styleUrl","styleDim","sleep","createZitadelClient"],"sources":["../src/lib/api-client.ts","../src/lib/errors.ts","../src/lib/json.ts","../src/lib/paths.ts","../src/lib/public-cli.ts","../src/lib/local-server/env-vars.ts","../src/lib/local-server/runtime.ts","../src/lib/server.ts","../src/lib/telemetry/config.ts","../src/lib/telemetry/consent.ts","../src/lib/telemetry/identity.ts","../src/lib/telemetry/util.ts","../src/lib/telemetry/index.ts","../src/lib/telemetry/dimensions/env-flag.ts","../src/lib/telemetry/dimensions/ci-provider.ts","../src/lib/telemetry/dimensions/host-agent.ts","../src/lib/user-agent.ts","../src/lib/telemetry/dimensions/ci-flag.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/environment.ts","../src/lib/project.ts","../src/lib/oclif/environment-command.ts","../src/lib/local-files.ts","../src/lib/branding/index.ts","../src/lib/flows/env-refs.ts","../src/lib/flows/index.ts","../src/lib/user-schema/index.ts","../src/lib/sync/syncers.ts","../src/lib/sync/asset-probe.ts","../src/lib/sync/flow-validation.ts","../src/lib/sync/state.ts","../src/lib/sync/loop.ts","../src/lib/sync/plan-renderer.ts","../src/commands/apply.ts","../src/lib/branding/designs.ts","../src/commands/branding/eject.ts","../src/lib/box.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/local-server/binary.ts","../src/lib/local-server/docker.ts","../src/lib/local-server/docker-guidance.ts","../src/lib/local-server/processes.ts","../src/lib/orca/detectors/package-json.ts","../src/lib/orca/detectors/port.ts","../src/lib/orca/detectors/angular.ts","../src/lib/orca/detectors/next.ts","../src/lib/orca/detectors/nuxt.ts","../src/lib/orca/detectors/qwik.ts","../src/lib/orca/detectors/react.ts","../src/lib/orca/detectors/solid.ts","../src/lib/orca/detectors/svelte.ts","../src/lib/orca/detectors/vue.ts","../src/lib/orca/detectors/index.ts","../src/lib/orca/patchers/rule/file-writer/index.ts","../src/lib/orca/patchers/rule/guidance.ts","../src/lib/orca/patchers/rule/reclaim.ts","../src/lib/orca/patchers/rule/base.ts","../src/lib/orca/patchers/rule/angular/angular-json.ts","../src/lib/orca/patchers/rule/utils/magicast.ts","../src/lib/orca/patchers/rule/angular/angular-routes.ts","../src/lib/orca/patchers/rule/proxy.ts","../src/lib/orca/patchers/rule/proxy-credential-policy.ts","../src/lib/orca/patchers/rule/angular/templates.ts","../src/lib/orca/patchers/rule/angular/index.ts","../src/lib/orca/patchers/rule/dev-script-port.ts","../src/lib/orca/patchers/rule/next/renderers/lit/index.ts","../src/lib/orca/patchers/rule/next/renderers/react/index.ts","../src/lib/orca/patchers/rule/next/renderers/registry.ts","../src/lib/orca/patchers/rule/next/index.ts","../src/lib/orca/patchers/rule/config-paths.ts","../src/lib/orca/patchers/rule/nuxt/nuxt-config.ts","../src/lib/orca/patchers/rule/nuxt/templates.ts","../src/lib/orca/patchers/rule/nuxt/index.ts","../src/lib/orca/patchers/rule/vite-support.ts","../src/lib/orca/patchers/rule/qwik/templates.ts","../src/lib/orca/patchers/rule/qwik/index.ts","../src/lib/orca/patchers/rule/react/templates.ts","../src/lib/orca/patchers/rule/react/index.ts","../src/lib/orca/patchers/rule/solid/templates.ts","../src/lib/orca/patchers/rule/solid/index.ts","../src/lib/orca/patchers/rule/svelte/templates.ts","../src/lib/orca/patchers/rule/svelte/index.ts","../src/lib/orca/patchers/rule/vue/templates.ts","../src/lib/orca/patchers/rule/vue/index.ts","../src/lib/orca/patchers/index.ts","../src/lib/orca/scaffolders/cli.ts","../src/lib/orca/scaffolders/angular.ts","../src/lib/orca/scaffolders/next.ts","../src/lib/orca/scaffolders/nuxt.ts","../src/lib/orca/scaffolders/qwik.ts","../src/lib/orca/scaffolders/react.ts","../src/lib/orca/scaffolders/solid.ts","../src/lib/orca/scaffolders/svelte.ts","../src/lib/orca/scaffolders/vue.ts","../src/lib/orca/scaffolders/index.ts","../src/lib/orca/index.ts","../src/lib/prober/ports.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/dependency.ts","../src/lib/package-manager.ts","../src/commands/doctor/checks/dependency-version.ts","../src/commands/doctor/checks/managed-files.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/paging.ts","../src/lib/oclif/crud/wire.ts","../src/lib/oclif/crud/query.ts","../src/lib/oclif/crud/zod.ts","../src/lib/oclif/crud/paths.ts","../src/lib/oclif/crud/columns.ts","../src/lib/oclif/crud/table.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/fields.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/prompts/cancel.ts","../src/commands/setup/prompts/design.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/use-case.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/lib/variables.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 {\n createZitadelClient as createRawClient,\n type ZitadelClient,\n type ZitadelClientOptions,\n} from \"@zitadel/api/client\";\nimport { ApiError } from \"@zitadel/api/runtime/fetch\";\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.\n */\nfunction 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 * `apply` and `setup` write the server's canonical body back to the\n * project's files, and `plan` diffs it against them, so an escaped\n * `\\r` or zero-width joiner would be written to disk as literal text and\n * published as a change. 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 */\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(opts);\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 { ApiError, apiErrorMessage } 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_NOT_IMPLEMENTED\";\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_NOT_IMPLEMENTED: 2,\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, then errno/filesystem,\n * network, Zod-like, generic `Error`, then a catch-all) so the most\n * actionable category and hint win. 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 return new ZitadelError(code, apiErrorMessage(error), { details });\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 (isNetworkError(error)) {\n return new ZitadelError(\"E_NETWORK\", errorMessage(error), {\n hint: \"Check your connection, ZITADEL_API_BASE, or the configured server URL.\",\n details: { original: pickErrorShape(error as Error) },\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 */\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 isNetworkError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n if (\n error.name === \"TypeError\" &&\n /fetch failed|network|ECONNREFUSED|ENOTFOUND/i.test(error.message)\n ) {\n return true;\n }\n const cause = (error as { cause?: unknown }).cause;\n if (cause && typeof cause === \"object\" && \"code\" in cause) {\n const code = String((cause as { code: unknown }).code);\n return /^(ECONNREFUSED|ECONNRESET|ENOTFOUND|ETIMEDOUT|EAI_AGAIN|UND_ERR)/i.test(code);\n }\n return false;\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\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 { 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[layout.members.length - 1]!;\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[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[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[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[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[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 (cursor < source.length && !\",}]\".includes(source[cursor]!) && !isWhitespace(source[cursor]!)) {\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[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 { 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\nexport function npmSelectorForCliVersion(cliVersion: string): string {\n const normalized = cliVersion.trim().replace(/^v/, \"\");\n if (/^\\d+\\.\\d+\\.\\d+-alpha\\.\\d+$/.test(normalized)) {\n return normalized;\n }\n return npmDistTagForCliVersion(normalized);\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","/**\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 * 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/** 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) => ({ ...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, 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 (cwd: string): Promise<ResolvedEnv> => {\n const values = Object.fromEntries(\n Object.entries(await loadEnvFiles(cwd)).filter(\n ([name, value]) => name.startsWith(ENV_PREFIX) && !CLI_OWNED.has(name) && value !== \"\",\n ),\n );\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 { dirname, join, resolve } from \"node:path\";\n\nimport { ZitadelError } from \"../errors\";\nimport { isObject, parseJsonObject } from \"../json\";\nimport { EMPTY_SUMMARY, type EnvSummary, isEnvSummary } 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 (/^\\d+\\.\\d+\\.\\d+-alpha\\.\\d+$/.test(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 [\n \"root:x:0:\",\n \"nonroot:x:65532:\",\n `zitadel-local:x:${String(gid)}:`,\n \"\",\n ].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\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(serverUrl: string, timeoutMs = 1500): 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 * Best-effort local-server detection for optional UI (the setup wizard's\n * server choice). Same sources as {@link resolveLocalServer} — the runtime\n * metadata written by `zitadel start`, then the default localhost URL — but\n * never throws: a malformed `runtime.json` or an unhealthy server yields\n * `undefined` (doctor owns diagnosing those states), and an unhealthy\n * metadata URL still falls back to the default-port probe so a server\n * started from a different directory is found.\n */\nexport async function detectHealthyLocalServer(cwd: string): Promise<string | undefined> {\n let runtime: RuntimeMetadata | undefined;\n try {\n runtime = await readRuntimeMetadata(cwd);\n } catch {\n runtime = undefined;\n }\n if (runtime && (await checkLocalServerHealth(runtime.server_url))) {\n return runtime.server_url;\n }\n const alreadyProbedDefault = runtime?.server_url === DEFAULT_LOCAL_SERVER_URL;\n if (!alreadyProbedDefault && (await checkLocalServerHealth(DEFAULT_LOCAL_SERVER_URL))) {\n return DEFAULT_LOCAL_SERVER_URL;\n }\n return undefined;\n}\n\nexport async function resolveLocalServer(cwd: string): Promise<string> {\n const runtime = await readRuntimeMetadata(cwd);\n if (runtime) {\n if (await checkLocalServerHealth(runtime.server_url)) {\n return runtime.server_url;\n }\n throw localServerNotRunning(runtime.server_url);\n }\n\n if (await checkLocalServerHealth(DEFAULT_LOCAL_SERVER_URL)) {\n return DEFAULT_LOCAL_SERVER_URL;\n }\n throw localServerNotRunning(DEFAULT_LOCAL_SERVER_URL);\n}\n\nexport function localServerNotRunning(serverUrl: string): ZitadelError {\n return new ZitadelError(\"E_LOCAL_SERVER_NOT_RUNNING\", \"Local Zitadel server is not running\", {\n hint: `No healthy local server responded at ${serverUrl}.`,\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\nexport async function assertWritableDirectory(path: string): Promise<void> {\n await mkdir(path, { recursive: true, mode: 0o700 });\n await access(path, constants.W_OK);\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\nfunction isErrno(error: unknown, code: string): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === code\n );\n}\n\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\nexport function isRuntimeObject(value: unknown): value is RuntimeMetadata {\n return isObject(value) && value.schema_version === 1;\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","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ZitadelError } from \"./errors\";\nimport { resolveLocalServer } from \"./local-server/runtime\";\nimport { isObject, parseJsonObject } from \"./json\";\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://api.zitadel.cloud\";\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-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 * and `environment` come from the parsed CLI invocation.\n */\nexport type ResolveServerInput = {\n cwd: string;\n env: NodeJS.ProcessEnv;\n serverFlag?: string;\n environment?: 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 * selected environment block in `zitadel.json`, then the config's\n * top-level `server`, 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.ZITADEL_API_BASE;\n if (envValue) {\n return validate(input.cwd, { value: envValue, origin: \"env\" });\n }\n\n const config = await readConfig(input.cwd);\n if (config) {\n const envBranch = readEnvServer(config, input.environment);\n if (envBranch) {\n return validate(input.cwd, { value: envBranch, origin: \"config-env\" });\n }\n if (typeof config.server === \"string\") {\n return validate(input.cwd, { value: config.server, origin: \"config-top\" });\n }\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 resolveLocalServer(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\nfunction readEnvServer(\n config: Record<string, unknown>,\n environment: string | undefined,\n): string | undefined {\n if (!environment) {\n return undefined;\n }\n const envs = config.environments;\n if (!isObject(envs)) {\n return undefined;\n }\n const branch = envs[environment];\n if (!isObject(branch)) {\n return undefined;\n }\n return typeof branch.server === \"string\" ? branch.server : undefined;\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). By default the channel comes\n * from a build-time stamp (see {@link resolveChannel}), so the published CLI\n * routes real user traffic to production without any per-user env var while\n * source/test runs stay on dev — but a runtime `ZITADEL_TELEMETRY_ENV` or\n * `ZITADEL_TELEMETRY_BUILD_CHANNEL` overrides the stamp, and\n * `ZITADEL_TELEMETRY_TOKEN` 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. Used by the published CLI (the build stamps the\n * production channel) and any `ZITADEL_TELEMETRY_ENV=production` run. Write-only\n * 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\ndeclare const __ZITADEL_TELEMETRY_CHANNEL__: string | undefined;\n\n/**\n * Channel stamped into the bundle at build time. tsdown's `define` always\n * replaces the bare `__ZITADEL_TELEMETRY_CHANNEL__` identifier — with\n * `\"development\"` by default and `\"production\"` only in the release build — so\n * the shipped CLI routes to the right project with no per-user env var. The\n * identifier is undefined only in unbundled runs (e.g. unit tests importing this\n * module directly); the `typeof` guard returns `\"\"` there so those runs fall\n * through to the dev default without a ReferenceError.\n */\nfunction buildStampedChannel(): string {\n return typeof __ZITADEL_TELEMETRY_CHANNEL__ === \"string\"\n ? __ZITADEL_TELEMETRY_CHANNEL__.trim().toLowerCase()\n : \"\";\n}\n\n/**\n * Decide which project the events belong to. Precedence: an explicit\n * `ZITADEL_TELEMETRY_ENV`, then a `ZITADEL_TELEMETRY_BUILD_CHANNEL` env override\n * (handy for CI/release), then the build-time channel stamp. The default —\n * source/dev/test — is the dev project. Ambient `NODE_ENV` is deliberately NOT\n * consulted: a source build with `NODE_ENV=production` must not route dev\n * traffic to prod, nor a published run with `NODE_ENV=development` to dev.\n */\nfunction resolveChannel(env: NodeJS.ProcessEnv): \"development\" | \"production\" {\n const explicit = (env.ZITADEL_TELEMETRY_ENV ?? \"\").trim().toLowerCase();\n if (explicit === \"production\") {\n return \"production\";\n }\n if (explicit === \"development\") {\n return \"development\";\n }\n const stamp = (env.ZITADEL_TELEMETRY_BUILD_CHANNEL ?? buildStampedChannel()).trim().toLowerCase();\n return stamp === \"production\" ? \"production\" : \"development\";\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 =\n 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 { 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\nconst DISABLED_VALUES = new Set([\"\", \"0\", \"false\", \"off\", \"no\"]);\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?.trim();\n if (doNotTrack && doNotTrack !== \"0\") {\n return { enabled: false, reason: \"do-not-track\" };\n }\n\n const explicit = input.env.ZITADEL_TELEMETRY?.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 { randomUUID } from \"node:crypto\";\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n/**\n * A stable, anonymous identifier for this install. It is a random UUID tied to\n * no account, email, or machine fingerprint — its only job is to let Mixpanel\n * group events from the same install into a funnel. `isFirstRun` is true the\n * one time we mint and persist the id, which drives the one-time consent notice.\n */\nexport type Identity = {\n readonly distinctId: string;\n readonly isFirstRun: boolean;\n};\n\ntype StoredIdentity = { distinctId: string };\n\n/**\n * Resolve the directory the CLI persists cross-invocation state in, honoring\n * the platform conventions: `XDG_CONFIG_HOME` then `~/.config` on Unix, and\n * `%APPDATA%` on Windows. The anonymous id lives here so it survives between\n * runs without touching the user's project tree.\n */\nexport function telemetryConfigDir(env: NodeJS.ProcessEnv): string {\n if (process.platform === \"win32\" && env.APPDATA) {\n return join(env.APPDATA, \"zitadel\", \"cli\");\n }\n const base = env.XDG_CONFIG_HOME?.trim() || join(homedir(), \".config\");\n return join(base, \"zitadel\", \"cli\");\n}\n\n/**\n * Load the persisted anonymous id, minting and storing a new one on first run.\n *\n * Fail-open: if the config dir cannot be resolved, read, or written — including\n * an `os.homedir()` throw in a restricted/containerized environment, a\n * read-only home, a CI sandbox, or a permissions error — fall back to an\n * ephemeral per-process id and report `isFirstRun: false` so we neither crash\n * nor nag the user with the notice on every run. Telemetry is best-effort,\n * never load-bearing.\n */\nexport function loadOrCreateIdentity(env: NodeJS.ProcessEnv): Identity {\n let dir: string;\n try {\n dir = telemetryConfigDir(env);\n } catch {\n return { distinctId: randomUUID(), isFirstRun: false };\n }\n const file = join(dir, \"telemetry.json\");\n\n try {\n const parsed = JSON.parse(readFileSync(file, \"utf8\")) as StoredIdentity;\n if (typeof parsed.distinctId === \"string\" && parsed.distinctId.length > 0) {\n return { distinctId: parsed.distinctId, isFirstRun: false };\n }\n } catch {\n /* fall through to mint a fresh id */\n }\n\n const distinctId = randomUUID();\n try {\n mkdirSync(dir, { recursive: true });\n writeFileSync(file, `${JSON.stringify({ distinctId } satisfies StoredIdentity)}\\n`, {\n mode: 0o600,\n });\n return { distinctId, isFirstRun: true };\n } catch {\n return { distinctId, isFirstRun: false };\n }\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 constructor(\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\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(\n send: (client: MixpanelClient, done: () => void) => void,\n ): 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","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/** 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 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 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 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 (hostname === \"zitadel.cloud\" || hostname.endsWith(\".zitadel.cloud\")) {\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\";\nimport consola from \"consola\";\n\nimport { toZitadelError, type ZitadelError } from \"../errors\";\nimport { isObject } from \"../json\";\nimport { resolveCwd } from \"../paths\";\nimport { normalizePublicCliCommand, normalizePublicCliCommands } from \"../public-cli\";\nimport { resolveServer } from \"../server\";\nimport { type Properties, Telemetry, type TelemetryDeps } from \"../telemetry\";\nimport { buildUserAgent, installUserAgent, processUserAgentFacts } from \"../user-agent\";\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 GlobalOptions,\n JsonEnvelope,\n} from \"./types\";\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: Flags.string({ char: \"c\", description: \"Project directory to operate on.\" }),\n server: Flags.string({ 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 verbose: Flags.boolean({ description: \"Verbose logging.\" }),\n debug: Flags.boolean({ description: \"Debug logging.\" }),\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 await super.init();\n const telemetryFlag = this.argv.includes(\"--no-telemetry\") ? false : undefined;\n installUserAgent(buildUserAgent(processUserAgentFacts(this.config.version, telemetryFlag)));\n }\n\n /**\n * Merge command-specific dimensions into {@link telemetryProps} immutably: a\n * new frozen bag replaces the previous one, so no shared object is ever\n * mutated. `step` advances by re-recording it at each milestone.\n */\n protected recordTelemetry(patch: Properties): void {\n this.telemetryProps = Object.freeze({ ...this.telemetryProps, ...patch });\n }\n\n /**\n * Builds {@link GlobalOptions} from parsed flags, 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 environment = typeof flags.environment === \"string\" ? flags.environment : \"development\";\n const source =\n options.resolveServer === false\n ? { value: options.source ?? \"\", origin: \"default\" as const }\n : await resolveServer({ cwd, env: process.env, serverFlag, environment });\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 // 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: true,\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 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 (\n argv.includes(\"--json\") ||\n argv.includes(\"--non-interactive\") ||\n argv.includes(\"-n\")\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 return toEnvelope(normalized, this.meta);\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(toErrorEnvelope(zitadelError, meta));\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 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/** 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 return result.pretty;\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 === \"api.zitadel.cloud\") {\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 { z } from \"zod\";\n\nimport type { ZitadelClient } from \"@zitadel/api/client\";\n\nimport { ZitadelError } from \"./errors\";\n\n/**\n * CLI-side deployment environment. Not an API model — it gates which\n * `zitadel.json` environment block and server the commands target.\n * Project request/response shapes live in `@zitadel/api`\n * (generated from the OpenAPI spec).\n *\n * This is the older of the CLI's two meanings of \"environment\", used by\n * `plan`, `apply` and the resource commands to pick a server. It does not match\n * the platform's environments, which are open DNS-style names seeded as `dev`,\n * `staging` and `prod`; {@link assertEnvironmentName} is the grammar for those.\n */\nexport const environmentSchema = z.enum([\"development\", \"preview\", \"production\"]);\n\n/**\n * The platform's environment-name grammar, from `environment-name.yaml`: a\n * lowercase DNS-style label. Checked before any request so a malformed name\n * fails with the CLI's own message instead of a 400 from the edge.\n */\nconst ENVIRONMENT_NAME = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;\n\n/** Longest name the platform accepts, from the same schema. */\nconst ENVIRONMENT_NAME_MAX = 63;\n\n/** How an owner is named in output: an environment, or the project level. */\nexport function ownerLabel(environment?: string): string {\n return environment ?? \"the project\";\n}\n\n/** Reject a name the platform would refuse, naming it. */\nexport function assertEnvironmentName(name: string): void {\n if (!ENVIRONMENT_NAME.test(name) || name.length > ENVIRONMENT_NAME_MAX) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid environment name ${JSON.stringify(name)}.`, {\n hint: \"An environment name is a lowercase DNS-style label: letters, digits, and hyphens between them.\",\n });\n }\n}\n\n/**\n * Every environment of a project, by name, in the platform's order. The list is\n * paginated, so it is drained; a project holds a handful, so this is one call in\n * practice.\n */\nexport async function listEnvironmentNames(\n client: ZitadelClient,\n projectId: string,\n): Promise<string[]> {\n const drain = async (pageToken?: string): Promise<string[]> => {\n const page = await client.listEnvironments({\n project_id: projectId,\n limit: 100,\n page_token: pageToken,\n });\n const names = page.environments.map((environment) => environment.name);\n return page.next_page_token ? [...names, ...(await drain(page.next_page_token))] : names;\n };\n return drain();\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 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 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, unlike `resolveServer`, which prefers the selected\n * environment's `server` before falling back here. That is the point: an\n * environment override says where one invocation should talk, not where the\n * project lives. No practical difference today, since setup always writes a\n * concrete top-level `server`.\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 { cancel, isCancel, select } from \"@clack/prompts\";\nimport { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient, type ZitadelClient } from \"../api-client\";\nimport { assertEnvironmentName, listEnvironmentNames } from \"../environment\";\nimport { ZitadelError } from \"../errors\";\nimport { readZitadelSecret } from \"../project\";\nimport { BaseCommand } from \"./base\";\nimport type { GlobalOptions } from \"./types\";\n\n/**\n * The prompt's answer for the project level. Parentheses fall outside the\n * environment-name grammar, so no environment can ever be named this — and a\n * string, unlike a symbol, survives `isCancel`'s narrowing, which types every\n * symbol as the cancel signal.\n */\nconst PROJECT_LEVEL = \"(project-level)\";\n\n/**\n * A command that addresses one owner on the platform: an environment, or the\n * project level. Owners are separate rather than a ladder — nothing an owner\n * holds reaches another (ADR 062 §4) — so a value meant for `prod` has to be\n * written on `prod`, and the target must never be picked by accident.\n *\n * The owner is therefore never defaulted. `--environment` names one and\n * `--project-level` names the project; with neither, a person is asked and an\n * agent or CI run is refused, the rule ADR 035 sets for `deploy`. Leaving the\n * flag off cannot quietly land a value where no environment will read it.\n */\nexport abstract class EnvironmentCommand extends BaseCommand {\n static override baseFlags = {\n ...BaseCommand.baseFlags,\n environment: Flags.string({\n char: \"e\",\n aliases: [\"env\"],\n description: \"Environment to address, by name.\",\n exclusive: [\"project-level\"],\n }),\n \"project-level\": Flags.boolean({\n description:\n \"Address the project level instead of an environment. Environments do not inherit project-level values.\",\n exclusive: [\"environment\"],\n }),\n };\n\n /** The `--environment` value, validated; `undefined` when none was passed. */\n private requestedEnvironment?: string;\n\n /** Whether `--project-level` was passed. */\n private projectLevel = false;\n\n /**\n * Validate the owner flags, then build the invocation context without them.\n *\n * `--environment` names an owner on the one instance the CLI talks to; it is\n * not a `zitadel.json` block. `BaseCommand.toMeta` passes a\n * `flags.environment` to the server resolver, where a matching\n * `environments.<name>.server` would redirect the request, so it is withheld\n * and the server resolves as it does for a command with no such flag.\n */\n protected override async toMeta(\n flags: Record<string, unknown>,\n options: { resolveServer?: boolean; source?: string } = {},\n ): Promise<GlobalOptions> {\n if (typeof flags.environment === \"string\") {\n assertEnvironmentName(flags.environment);\n this.requestedEnvironment = flags.environment;\n }\n this.projectLevel = flags[\"project-level\"] === true;\n return super.toMeta({ ...flags, environment: undefined }, options);\n }\n\n /**\n * Open the platform connection and settle the owner, the counterpart of the\n * resource commands' `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; environment_name?: string }>;\n /** The environment addressed, or `undefined` for the project level. */\n environment: string | undefined;\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 const client = createZitadelClient({ baseUrl: source, token: secret.project_secret });\n const environment = await this.resolveOwner(client, secret.project_id);\n return {\n client,\n environment,\n scope: {\n project_id: secret.project_id,\n ...(environment === undefined ? {} : { environment_name: environment }),\n },\n };\n }\n\n /**\n * The owner this invocation addresses: an environment's name, or `undefined`\n * for the project level. Asks a person when neither flag was passed, and\n * refuses a non-interactive run, naming the environments the project has.\n */\n protected async resolveOwner(\n client: ZitadelClient,\n projectId: string,\n ): Promise<string | undefined> {\n if (this.projectLevel) {\n return undefined;\n }\n if (this.requestedEnvironment !== undefined) {\n return this.requestedEnvironment;\n }\n if (this.meta.nonInteractive) {\n // The names only enrich the refusal. If listing them fails, the refusal\n // still has to be about the missing owner — not a network error that\n // hides it.\n const environments = await listEnvironmentNames(client, projectId).catch(() => []);\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"Name the owner: --environment <name>, or --project-level\",\n {\n hint:\n environments.length > 0\n ? `Environments do not inherit project-level values. This project's environments: ${environments.join(\", \")}.`\n : \"Environments do not inherit project-level values.\",\n },\n );\n }\n const environments = await listEnvironmentNames(client, projectId);\n const choice = await select<string>({\n message: \"Which environment?\",\n options: [\n ...environments.map((name) => ({ value: name, label: name })),\n {\n value: PROJECT_LEVEL,\n label: \"The project level\",\n hint: \"not inherited by any environment\",\n },\n ],\n });\n if (isCancel(choice)) {\n cancel(\"Cancelled.\");\n throw new ZitadelError(\"E_VALIDATION\", \"No owner chosen\");\n }\n return choice === PROJECT_LEVEL ? undefined : choice;\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, and after a write the\n * server's canonical value goes back into that file while the JSON keeps the\n * reference.\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 and write-back\n * writes to them. The check applies to the real target: a symlink, or a\n * symlinked directory on the way, that leads outside the project is refused.\n */\nimport { lstatSync, readFileSync, realpathSync, writeFileSync } 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\ntype Container = Record<string, unknown> | unknown[];\nconst omittedReference = Symbol(\"omittedReference\");\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isContainer = (value: unknown): value is Container =>\n Array.isArray(value) || isPlainObject(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/** The value under `key` in an object or array; undefined when there is none. */\nfunction childOf(node: unknown, key: string | number): unknown {\n if (Array.isArray(node)) {\n return typeof key === \"number\" ? node[key] : undefined;\n }\n return isPlainObject(node) && typeof key === \"string\" ? node[key] : undefined;\n}\n\n/** Replaces the value under `key` in an object or array. */\nfunction setChild(node: Container, key: string | number, value: unknown): void {\n if (Array.isArray(node)) {\n if (typeof key === \"number\") {\n node[key] = value;\n }\n } else if (typeof key === \"string\") {\n node[key] = value;\n }\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 (write-back may create the\n * file). Undefined when a segment is a symlink that resolves nowhere, since a\n * write through it would land wherever the link names.\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) => walk(item, [...path, index]));\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\n/**\n * Converts a canonical server document back to the local form. Wherever the\n * local document holds a reference and the canonical value at the same place\n * is a string, that string is written to the referenced file when it differs,\n * and the returned document carries the reference instead of the string.\n * `written` lists the references whose files changed.\n */\nexport function restoreFileReferences<T>(\n canonical: T,\n local: unknown,\n context: FileReferenceContext,\n): { document: T; written: string[] } {\n const document = structuredClone(canonical);\n const written: string[] = [];\n for (const { path, ref } of findFileReferences(local)) {\n const key = path.at(-1);\n const parent = path.slice(0, -1).reduce<unknown>(childOf, document);\n if (key === undefined || !isContainer(parent)) {\n continue;\n }\n const value = childOf(parent, key);\n if (typeof value !== \"string\") {\n continue;\n }\n const file = resolveFileReference(context, ref);\n if (readIfPresent(file) !== value) {\n writeFileSync(file, value);\n written.push(ref);\n }\n setChild(parent, key, { [FILE_REFERENCE_KEY]: ref });\n }\n return { document, written };\n}\n","import { ZitadelError } from \"../errors\";\nimport {\n type FileReferenceContext,\n inlineFileReferences,\n restoreFileReferences,\n} 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/**\n * Converts the server's canonical wire body back to the local descriptor form:\n * wherever the local descriptor holds a `$file` reference, the canonical value\n * is written to that file when it differs and the JSON keeps the reference.\n */\nexport function toLocalBrandingBody(\n cwd: string,\n canonicalWire: object,\n localData: object,\n): { document: object; written: string[] } {\n return restoreFileReferences(canonicalWire, localData, referenceContext(cwd));\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 (key.endsWith(\"_env\") && typeof child === \"string\" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(child)) {\n refs.add(child);\n } else {\n visit(child);\n }\n }\n }\n };\n visit(value);\n return [...refs].sort();\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, and the file-level\n * `validateFlows` helper that surfaces `E_VALIDATION` errors against\n * the generated Zod.\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`).\n */\nexport { buildFlow } from \"./build\";\nexport { validateFlows } from \"./validate\";\nexport { flowEnvRefs } from \"./env-refs\";\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","/**\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 type {\n CreateBranding201,\n CreateBrandingBody,\n CreateFlowDefinition201,\n CreateFlowDefinitionBodyFlowDefinition,\n GetBrandingById200,\n CreateSchemaBody,\n GetSchemaById200,\n GetFlowDefinition200,\n} from \"@zitadel/api/generated/model\";\nimport { consola } from \"consola\";\n\nimport type { ZitadelClient } from \"@zitadel/api/client\";\nimport { DEFAULT_FLOW_SCHEMA_URI } from \"@zitadel/config/defaults\";\nimport { normalizeFlowBody, normalizeSchemaBody } from \"@zitadel/config/normalize\";\nimport { brandingConfigSchema, flowConfigSchema, schemaConfigSchema } from \"@zitadel/config/schemas\";\nimport { validateLoginTemplate } from \"@zitadel/config/template\";\n\nimport {\n BRANDING_DIR,\n assertNoLegacyTemplateKey,\n readDescriptorTemplate,\n toBrandingWireBody,\n toLocalBrandingBody,\n} from \"../branding\";\nimport { FLOWS_DIR, flowEnvRefs } from \"../flows\";\nimport { SCHEMAS_DIR } from \"../user-schema\";\nimport { ZitadelError } from \"../errors\";\nimport 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}): ReadonlyArray<ResourceSyncer> {\n return [\n new SchemaSyncer(opts.client, opts.projectId, opts.env),\n new FlowDefinitionSyncer(opts.client, opts.projectId, opts.env),\n new BrandingSyncer(opts.client, opts.projectId, opts.env, opts.cwd),\n ];\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\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 // Deliberately no `normalizeWrite`: the server stores schema bytes\n // verbatim, so stripping spelled-out x-* defaults from the local file\n // would drop them from the next published revision. Canonical schema\n // bodies are written back as-is; `normalize` is comparison-only.\n\n constructor(\n private readonly client: ZitadelClient,\n private readonly projectId: string,\n private readonly env: EnvLookup,\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 * The create response carries only the id, so the canonical stored body\n * comes from a follow-up fetch; a fetch failure degrades to no\n * write-back rather than failing the create.\n */\n async create(data: object): Promise<{ id: string; canonical?: object }> {\n const result = await this.client.createSchema(data as CreateSchemaBody, {\n project_id: this.projectId,\n });\n try {\n return { id: result.id, canonical: await this.fetch(result.id) };\n } catch (err) {\n consola.debug(`fetch created schema ${result.id} failed:`, err);\n return { id: result.id };\n }\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<{ canonical?: object }> {\n throw new ZitadelError(\"E_NOT_IMPLEMENTED\", \"schemas are revisioned — edit publishes a new revision, not an update\");\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 written back to `.zitadel/schemas/`.\n const body = (await this.client.getSchemaById(\n encodeURIComponent(id),\n )) as unknown as GetSchemaById200;\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 // For flows the comparison form doubles as the file form: everything it\n // strips (envelope keys, the empty `audience` echo) is transport noise.\n readonly normalizeWrite = normalizeFlowBody;\n\n constructor(\n private readonly client: ZitadelClient,\n private readonly projectId: string,\n private readonly env: EnvLookup,\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; canonical?: object }> {\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, canonical: result.flow_definition as object };\n }\n\n async update(_id: string, _data: object): Promise<{ canonical?: object }> {\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)) as GetFlowDefinition200;\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 and splits it back out on write-back.\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 constructor(\n private readonly client: ZitadelClient,\n private readonly projectId: string,\n private readonly env: EnvLookup,\n private readonly cwd: string,\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 /**\n * `POST /branding` publishes a new immutable revision. The canonical body\n * is converted back to descriptor form: the stored template is written to\n * the referenced `.liquid` file (when it differs) and the JSON keeps the\n * file reference, so `writeBackResource` stays pure-JSON.\n */\n async create(data: object): Promise<{ id: string; canonical?: object }> {\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, canonical: this.canonicalToLocal(result.branding as object, data) };\n }\n\n async update(_id: string, _data: object): Promise<{ canonical?: object }> {\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)) as GetBrandingById200;\n return envelope.branding as object;\n }\n\n private canonicalToLocal(canonicalWire: object, localData: object): object {\n const { document, written } = toLocalBrandingBody(this.cwd, canonicalWire, localData);\n for (const ref of written) {\n consola.info(`Updated ${ref} from the server's canonical response`);\n }\n return document;\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\";\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 consola.warn(\"Flow 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 becomes the new default\"\n : \"this revision becomes the newest active flow and the 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, scope it with \"audience\" or set flow-name on the pages that should use it.`,\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` pins.\n * A repin action already names the schema file (the pin is adopting that\n * file's next/new revision); otherwise the pinned id is looked up in\n * state and its file body taken from this scan. Unresolvable refs (e.g.\n * an un-substituted `${USER_SCHEMA_URL}` placeholder or a server-side\n * schema not tracked locally) return undefined — flow-local rules still\n * run, schema-dependent rules are skipped.\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 [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 { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport type { ResourceEntry, ScaffoldManifest, 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(\n cwd: string,\n key: string,\n entry: ResourceEntry,\n): 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","import { createHash } from \"node:crypto\";\nimport { readdir, readFile, writeFile } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\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 type { PlanResourceChange } from \"./plan-renderer.js\";\nimport { readState, removeFromState, updateState } from \"./state.js\";\nimport type { FlowRepin, ResourceEntry, ResourceSyncer, SyncAction } from \"./types.js\";\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 content of onDisk.values()) {\n syncer.validate(content);\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 let oldContent: object | null = null;\n if (fetchOld && syncer.fetch) {\n try {\n oldContent = await syncer.fetch(entry.id);\n } catch (err) {\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 = absPath.slice(cwd.length + 1);\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 const unchanged =\n entry.hash === hash ||\n entry.hash === hashResourceContent(content) ||\n entry.hash === hashResourceContent(JSON.parse(stableStringify(content)) as object);\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\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 files updated from the server's canonical\n * responses (write-back). Surfaced in human and `--json` output so a\n * 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};\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. After each\n * mutation, the server's canonical body is written back to the local\n * file (when it differs in normalized form), so repo config matches\n * live state by construction and the next `plan` is empty.\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 consola.warn(`${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 const writeBack = async (\n action: Extract<SyncAction, { kind: \"create\" | \"revise\" | \"update\" }>,\n canonical: object | undefined,\n fallbackHash: string,\n ): Promise<string> => {\n if (!canonical) {\n return fallbackHash;\n }\n const { hash, changed } = await writeBackResource(cwd, action.path, action.syncer, canonical);\n if (changed) {\n filesUpdated.push(action.path);\n consola.info(`Updated ${action.path} from the server's canonical response`);\n }\n return hash;\n };\n\n for (const action of actions) {\n switch (action.kind) {\n case \"create\": {\n let content = action.content;\n const newId = repinTarget(action.repin);\n if (newId) {\n // A flow created in the same run as (or after an interrupted)\n // schema revise must adopt the new revision — POSTing the stale\n // pin would fail validation, and its canonical echo would revert\n // the re-pinned local file.\n content = { ...(content as Record<string, unknown>), user_schema: newId };\n }\n const { id, canonical } = await action.syncer.create(content);\n const fallbackHash = newId ? hashForState(action.syncer, content) : action.hash;\n const entry: ResourceEntry = { id, hash: await writeBack(action, canonical, fallbackHash) };\n await updateState(cwd, action.path, entry);\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 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, canonical } = await action.syncer.create(content);\n const fallbackHash = newId ? hashForState(action.syncer, content) : action.hash;\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: await writeBack(action, canonical, fallbackHash),\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 { canonical } = await action.syncer.update(action.id, content);\n const fallbackHash = newId ? hashForState(action.syncer, content) : action.hash;\n await updateState(cwd, action.path, {\n hash: await writeBack(action, canonical, fallbackHash),\n });\n consola.info(`Updated the ${action.syncer.kind} on Zitadel from ${action.path}`);\n applied.push({ kind: action.syncer.kind, action: \"update\", file: action.path, id: action.id });\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({ kind: action.syncer.kind, action: \"delete\", file: action.path, id: action.id });\n break;\n }\n case \"skip\": {\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 { filesUpdated: [...new Set(filesUpdated)], applied };\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 * Reconcile a local file with the server's canonical body. What gets\n * written is the `normalizeWrite` form (strips pure transport noise like\n * the empty `audience` echo; for schemas the canonical body verbatim —\n * spelled-out x-* defaults must survive, or the next apply would publish\n * a revision without them). Equality is judged in the `normalize`\n * comparison form, so the file is rewritten only when it materially\n * differs from live state; hand-formatted files stay untouched otherwise.\n * Returns the state hash of the written form.\n */\nexport async function writeBackResource(\n cwd: string,\n relPath: string,\n syncer: Pick<ResourceSyncer, \"normalize\" | \"normalizeWrite\">,\n canonical: object,\n): Promise<{ hash: string; changed: boolean }> {\n let writeBody = syncer.normalizeWrite?.(canonical) ?? canonical;\n const compare = (body: object) => stableStringify(syncer.normalize?.(body) ?? body);\n const absPath = join(cwd, relPath);\n let changed = true;\n try {\n const onDisk = JSON.parse(await readFile(absPath, \"utf8\")) as Record<string, unknown>;\n changed = compare(writeBody) !== compare(onDisk);\n // `$schema` is a local editor affordance (points at the dialect spec in\n // .zitadel/meta/); the server never echoes it, so a rewrite would drop\n // it. Carry the on-disk pointer over unless the canonical body has its\n // own (user-schema documents do).\n if (typeof onDisk.$schema === \"string\" && !(\"$schema\" in writeBody)) {\n writeBody = { ...writeBody, $schema: onDisk.$schema };\n }\n } catch (err) {\n consola.debug(`read ${relPath} for write-back failed:`, err);\n }\n if (changed) {\n await writeFile(absPath, `${stableStringify(writeBody)}\\n`);\n }\n return { hash: hashForState(syncer, writeBody), changed };\n}\n\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 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 */\nasync function readLocalFlowUserSchemas(cwd: string): 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 = absPath.slice(cwd.length + 1);\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(\n syncer: Pick<ResourceSyncer, \"normalize\">,\n data: object,\n): string {\n const normalized = syncer.normalize?.(data) ?? data;\n return createHash(\"sha256\").update(stableStringify(normalized)).digest(\"hex\");\n}\n","import { createHash } from \"node:crypto\";\n\nimport { escapeControlCharacters } from \"../api-client\";\nimport { stableStringify } from \"../json\";\nimport type {\n ResourceSyncer,\n SyncAction,\n SyncActionWarning,\n SyncPlanSummary,\n} 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 return {\n creates: active.filter((a) => a.kind === \"create\").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 total: active.length,\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 }\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\";\n file: string;\n id?: string;\n previous_id?: 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(\n actions: ReadonlyArray<SyncAction>,\n): PlanResourceChange[] {\n const out: PlanResourceChange[] = [];\n for (const action of actions) {\n switch (action.kind) {\n case \"create\":\n out.push({ kind: action.syncer.kind, action: \"create\", file: action.path });\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 if (active.length === 0) {\n return paint(\n \"No changes. Your Zitadel configuration matches the current state.\",\n A.bold,\n tty,\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 } = 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 (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 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 and the write-back see 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 * 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 as a full remove + full add (no LCS diff).\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): boolean {\n const allKeys = [...new Set([...Object.keys(oldObj), ...Object.keys(newObj)])].sort();\n const maxLen = allKeys.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 allKeys) {\n const pk = fieldLabel(key).padEnd(maxLen);\n const hasOld = Object.prototype.hasOwnProperty.call(oldObj, key);\n const hasNew = Object.prototype.hasOwnProperty.call(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 (stableStringify(oldVal) === stableStringify(newVal)) {\n if (newVal.length === 0) {\n lines.push(`${pad} ${pk} = []`);\n } else {\n lines.push(`${pad} ${pk} = [`);\n renderArrayItems(newVal, \" \", prefixCol + 4, { tty, deleteMode: false }, lines);\n lines.push(`${\" \".repeat(prefixCol + 2)}]`);\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 (oldVal.length === 0) {\n lines.push(colR(`${pad}- ${pk} = []`));\n } else {\n lines.push(colR(`${pad}- ${pk} = [`));\n renderArrayItems(oldVal, \"-\", prefixCol + 4, { tty, deleteMode: false }, lines);\n lines.push(colR(`${\" \".repeat(prefixCol + 2)}]`));\n }\n if (newVal.length === 0) {\n lines.push(colA(`${pad}+ ${pk} = []`));\n } else {\n lines.push(colA(`${pad}+ ${pk} = [`));\n renderArrayItems(newVal, \"+\", prefixCol + 4, { tty, deleteMode: false }, lines);\n lines.push(colA(`${\" \".repeat(prefixCol + 2)}]`));\n }\n }\n } else if (isPlainObject(oldVal) && isPlainObject(newVal)) {\n const childLines: string[] = [];\n const childHasChanges = renderDiff(oldVal, newVal, prefixCol + 4, tty, childLines);\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 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 const header = `${blkPad}# ${action.path} will be created`;\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 { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"../lib/api-client\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport { environmentSchema } from \"../lib/environment\";\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 static override flags = {\n environment: Flags.string({\n char: \"e\",\n description: \"Target environment (default: development).\",\n options: [...environmentSchema.options],\n }),\n };\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 diffs and writes back what it reads.\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 } = await runSyncLoop(cwd, syncers);\n consola.success(\"Sync complete\");\n return this.emit({\n status: \"ok\",\n data: {\n synced: true,\n // Platform resources this run touched (with resulting ids);\n // `files_updated` stays the local write-backs only.\n changes: applied,\n files_updated: filesUpdated,\n next_actions:\n applied.length === 0\n ? [\"Everything is already in sync — no changes were applied.\"]\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.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}`,\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 type { BrandingDesign } from \"@zitadel/config/defaults\";\n\n/**\n * Human-facing name and one-line hint for each shipped login design. Shared\n * by the setup wizard, `branding eject`, and the setup summary so the label a\n * user picks (\"Split (reversed)\") and the slug the machine records\n * (`split-right`) stay visibly paired everywhere — the summary echoing a slug\n * the prompt never showed reads as \"did my selection apply?\".\n */\nexport const BRANDING_DESIGN_INFO: Record<BrandingDesign, { label: string; hint: string }> = {\n centered: {\n label: \"Centered\",\n hint: \"the built-in look, forked as an editable template\",\n },\n split: {\n label: \"Split\",\n hint: \"brand panel left, form right; narrow containers show a compact brand mark\",\n },\n \"split-right\": {\n label: \"Split (reversed)\",\n hint: \"form left, brand panel right; narrow containers show a compact brand mark\",\n },\n hero: {\n label: \"Hero\",\n hint: \"landing-style brand pane left, form right; editable text fallback when narrow\",\n },\n minimal: {\n label: \"Minimal\",\n hint: \"no card chrome, fields straight on the page\",\n },\n};\n\n/** The prompt label for a design slug, falling back to the slug itself. */\nexport function brandingDesignLabel(design: string): string {\n return (BRANDING_DESIGN_INFO as Record<string, { label: string }>)[design]?.label ?? design;\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { cancel, isCancel, select } from \"@clack/prompts\";\nimport { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport {\n BRANDING_DESIGNS,\n DEFAULT_BRANDING_CONFIG_PATH,\n DEFAULT_BRANDING_DESIGN,\n DEFAULT_BRANDING_TEMPLATE_PATH,\n brandingReadmeContent,\n getDefaultBrandingConfig,\n} from \"@zitadel/config/defaults\";\nimport { BRANDING_FILE_SCHEMA_REF, META_SCHEMA_DIR, metaSchemaFiles } from \"@zitadel/config/meta-schemas\";\n\nimport { BRANDING_DIR } from \"../../lib/branding\";\nimport { BRANDING_DESIGN_INFO } from \"../../lib/branding/designs\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { stableStringify } from \"../../lib/json\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } 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 design: Flags.string({\n description: `Design to start from (default: ${DEFAULT_BRANDING_DESIGN}).`,\n options: [...BRANDING_DESIGNS],\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\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 = flags.design ?? (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 const choice = await select({\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 if (isCancel(choice)) {\n cancel(\"Eject cancelled.\");\n throw new ZitadelError(\"E_VALIDATION\", \"Eject cancelled by user\");\n }\n return choice;\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 pc from \"picocolors\";\nimport wrapAnsi from \"wrap-ansi\";\n\n/**\n * Frame overhead of a `consola.box` with `padding: 1`: two border columns,\n * the padding columns, and consola's left margin. Content wrapped to the\n * terminal width minus this stays inside the frame instead of soft-wrapping\n * under the right border.\n */\nconst BOX_OVERHEAD = 8;\nconst MIN_CONTENT_WIDTH = 20;\nconst MAX_TERMINAL_WIDTH = 80;\n\n/** Bold cyan, for commands the user should run (URLs/paths stay plain cyan). */\nexport const command = (s: string): string => pc.bold(pc.cyan(s));\n\n/**\n * Wraps box content to the terminal (capped at 80 columns) so consola's\n * frame, which sizes itself to the longest content line, never exceeds the\n * window. ANSI-aware, preserves hard line breaks and indentation, and never\n * splits a token: URLs and commands stay whole for clicking, copying, and the\n * journey e2e scrape (claim.spec.ts), even when such a token alone is wider\n * than a very narrow window.\n */\nexport function wrapForBox(message: string, columns = process.stdout.columns): string {\n const width = Math.max(\n MIN_CONTENT_WIDTH,\n Math.min(columns ?? MAX_TERMINAL_WIDTH, MAX_TERMINAL_WIDTH) - BOX_OVERHEAD,\n );\n return wrapAnsi(message, width, { hard: false, trim: false });\n}\n\n/**\n * A next-step line for the human box: prose plus, when the step is literally\n * a command to run, that command pulled out of the sentence. The JSON\n * envelope keeps its own plain `next_actions`/`next_commands` strings; this\n * shape exists only so {@link renderBoxActions} can put the command alone on\n * an indented styled line, where it stands out and a drag-select copies it\n * without surrounding prose. (Line selection such as triple-click still\n * includes the box border and padding — commands that must copy as a whole\n * physical line belong outside a frame, like the claim URL.)\n */\nexport type BoxAction = { text: string; command?: string };\n\nexport function renderBoxActions(actions: BoxAction[]): string {\n return actions\n .map((action) =>\n action.command ? `${action.text}\\n\\n ${command(action.command)}` : action.text,\n )\n .join(\"\\n\\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 !== undefined && version.toLowerCase().includes(\"microsoft\");\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 continue;\n }\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/**\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\";\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: \"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;\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 consola.warn(\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 { join } from \"node:path\";\n\nimport { defaultHumanUserSchemaUrl } from \"@zitadel/config\";\n\nimport { ZitadelError } from \"../errors\";\nimport { isObject } from \"../json\";\nimport { LOCAL_RUNTIME_DIR, PLATFORM_PROJECT_ID } 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/** 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 ? { details: { cause: cause instanceof Error ? cause.message : String(cause) } } : {}),\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(staging, `${JSON.stringify(bootstrapUserDocument(admin, schemaUrl), null, 2)}\\n`, {\n mode: 0o644,\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 { createZitadelClient } from \"@zitadel/api/client\";\nimport type { VerifyChallengeProofBody } from \"@zitadel/api/generated/model\";\nimport { ApiError } from \"@zitadel/api/runtime/fetch\";\n\nimport { ZitadelError } from \"../errors\";\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 with fetch directly: the session comes back only as a\n // Set-Cookie header, which the generated client does not expose.\n const res = await fetch(\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 );\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 { readLocalAdmin } from \"../lib/local-server/admin-credential\";\nimport { consoleSignInUrl } from \"../lib/local-server/sign-in\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n readRuntimeMetadata,\n resolveLocalServer,\n} from \"../lib/local-server/runtime\";\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 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({ description: \"Print the sign-in link instead of opening a browser.\" }),\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 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 admin = await readLocalAdmin(cwd);\n if (!admin) {\n throw new ZitadelError(\"E_VALIDATION\", \"No local admin in this directory\", {\n hint: \"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 resolveLocalServer(cwd);\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: [\n \"The link signs you in once. Run `zitadel console` again for a fresh one.\",\n ],\n },\n });\n }\n}\n","import { 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 { dirname, join } from \"node:path\";\n\nimport { ZitadelError } from \"../errors\";\nimport { EMPTY_ENV, type ResolvedEnv, envSummary } from \"./env-vars\";\nimport {\n type BinaryRuntimeMetadata,\n type RuntimeMetadata,\n checkLocalServerHealth,\n} from \"./runtime\";\n\nexport const SERVER_NPM_PACKAGE = \"@zitadel/server\";\nconst START_COMMAND_ENV = \"ZITADEL_SERVER_BINARY\";\nconst START_COMMAND_VERSION_ENV = \"ZITADEL_SERVER_BINARY_VERSION\";\nconst STOP_TIMEOUT_MS = 10_000;\nconst STOP_KILL_TIMEOUT_MS = 2_000;\n\nconst require = createRequire(import.meta.url);\n\nexport type BinaryRunSpec = {\n cliVersion: string;\n dataDir: string;\n logPath: string;\n port: number;\n serverUrl: 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 function resolveServerCommand(env: NodeJS.ProcessEnv = process.env): {\n command: string;\n args: string[];\n serverPackage: string;\n serverVersion: string;\n} {\n if (env[START_COMMAND_ENV]) {\n return {\n command: env[START_COMMAND_ENV],\n args: [],\n serverPackage: SERVER_NPM_PACKAGE,\n serverVersion: env[START_COMMAND_VERSION_ENV]?.trim() || \"override\",\n };\n }\n\n const manifestPath = resolveServerPackageManifest();\n const manifest = require(manifestPath) as { version?: unknown };\n return {\n command: process.execPath,\n args: [join(dirname(manifestPath), \"bin\", \"zitadel-server.js\")],\n serverPackage: SERVER_NPM_PACKAGE,\n serverVersion: typeof manifest.version === \"string\" ? manifest.version : \"unknown\",\n };\n}\n\nexport async function startBinaryRuntime(spec: BinaryRunSpec): Promise<BinaryRuntimeMetadata> {\n const command = resolveServerCommand();\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 env: {\n ...process.env,\n // Declared project variables ride the child's environment, never argv.\n ...env.values,\n NEXTGEN_SERVER_ADDRESS: `:${String(spec.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: spec.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 child.unref();\n if (!child.pid) {\n throw new Error(\"server process did not expose a pid\");\n }\n return {\n schema_version: 1,\n backend: \"binary\",\n pid: child.pid,\n command: [command.command, ...args].join(\" \"),\n log_path: spec.logPath,\n server_package: command.serverPackage,\n server_version: command.serverVersion,\n port: spec.port,\n server_url: spec.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\nexport async function stopBinaryRuntime(pid: number): Promise<StopBinaryRuntimeResult> {\n if (!isProcessRunning(pid)) {\n return { pid, status: \"stale\", target: \"process\" };\n }\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 (isProcessRunning(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\nexport function isProcessRunning(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return isErrno(error, \"EPERM\");\n }\n}\n\nexport async function binaryLogs(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\nexport async function followBinaryLogs(logPath: string, tail: number): Promise<void> {\n process.stdout.write(await binaryLogs(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\nexport async function assertServerPackageAvailable(): Promise<string> {\n try {\n const command = resolveServerCommand();\n return command.serverVersion;\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@alpha\"],\n details: { package: SERVER_NPM_PACKAGE, message: errorMessage(error) },\n });\n }\n}\n\nexport async function binaryRuntimeHealthy(runtime: RuntimeMetadata): Promise<boolean> {\n return (\n runtime.backend === \"binary\" &&\n isProcessRunning(runtime.pid) &&\n (await checkLocalServerHealth(runtime.server_url))\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\nfunction isErrno(error: unknown, code: string): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === code\n );\n}\n\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\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\nasync function waitForExit(pid: number, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (!isProcessRunning(pid)) {\n return true;\n }\n await delay(200);\n }\n return !isProcessRunning(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\nconst MIGRATE_FLAG = \"--migrate\";\n\nfunction withMigrateFlag(args: string[]): string[] {\n return args.includes(MIGRATE_FLAG) ? args : [...args, MIGRATE_FLAG];\n}\n","import { spawn } from \"node:child_process\";\n\nimport { ZitadelError } 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 RuntimeMetadata,\n} from \"./runtime\";\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 DockerRunSpec = {\n containerName: string;\n image: string;\n port: number;\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\nexport function dockerRunArgs(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\nexport async 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\nexport async 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\nexport async function dockerAvailable(): Promise<DockerResult> {\n return runDocker([\"version\", \"--format\", \"{{.Server.Version}}\"]);\n}\n\nexport async function pullImage(image: string): Promise<void> {\n await requireDocker([\"pull\", \"--quiet\", image], `Pull Docker image ${image}`);\n}\n\nexport async 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\nexport async function 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\nexport async function ensureImage(image: string): Promise<\"local\" | \"pulled\"> {\n if (await imageExists(image)) {\n return \"local\";\n }\n await pullImage(image);\n return \"pulled\";\n}\n\nexport async function inspectContainer(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\nexport async function startContainer(\n spec: DockerRunSpec,\n): Promise<{ containerId: string; env: EnvSummary }> {\n const env = spec.env ?? EMPTY_ENV;\n const args = dockerRunArgs(spec, env.injected);\n const result = await requireDocker(args, \"Start local Zitadel container\", env.values);\n return { containerId: result.stdout.trim(), env: envSummary(env) };\n}\n\nexport async function stopAndRemoveContainer(containerName: string): Promise<void> {\n const inspect = await inspectContainer(containerName);\n if (!inspect.exists) {\n return;\n }\n if (inspect.running) {\n await requireDocker([\"stop\", containerName], `Stop ${containerName}`);\n }\n await requireDocker([\"rm\", containerName], `Remove ${containerName}`);\n}\n\nexport async function containerLogs(containerName: string, tail: number): Promise<string> {\n const result = await requireDocker([\"logs\", \"--tail\", String(tail), containerName], \"Read logs\");\n return result.stdout;\n}\n\nexport async function followContainerLogs(containerName: string, tail: number): Promise<void> {\n await streamDocker([\"logs\", \"--tail\", String(tail), \"--follow\", containerName]);\n}\n\nexport function 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\nexport function metadataFromStart(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}): RuntimeMetadata {\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\nexport async 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\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 { 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:\n \"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","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\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 { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport semver from \"semver\";\n\n/**\n * Minimal shape of the `package.json` fields detectors read. Intentionally\n * partial: only the keys detection logic depends on are modeled, all optional\n * since a project may omit any of them.\n */\nexport type PackageJson = {\n name?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n};\n\n/**\n * Reads and parses the `package.json` at `cwd`. Rejects if the file is absent\n * or malformed; callers that treat those as \"not a project\" are expected to\n * catch and fall back rather than have detection swallow the error here.\n */\nexport async function readPackageJson(cwd: string): Promise<PackageJson> {\n const contents = await readFile(join(cwd, \"package.json\"), \"utf8\");\n return JSON.parse(contents) as PackageJson;\n}\n\n/**\n * Reports whether `name` appears in either `dependencies` or `devDependencies`.\n * Both are checked because framework packages may legitimately live in either.\n */\nexport function hasDependency(pkg: PackageJson, name: string): boolean {\n return Boolean(pkg.dependencies?.[name] ?? pkg.devDependencies?.[name]);\n}\n\n/**\n * Best-effort major version of a declared dependency: the first number in the\n * spec. A heuristic for scaffold decisions (e.g. which Next request-boundary\n * convention to emit), NOT for support gating — range semantics like `<16`\n * are beyond it. Floors use {@link dependencySpecProvablyBelowMajor}.\n */\nexport function dependencyVersionMajor(pkg: PackageJson, name: string): number | undefined {\n const spec = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name];\n if (!spec) {\n return undefined;\n }\n const match = spec.match(/\\d+/);\n return match ? Number(match[0]) : undefined;\n}\n\n/**\n * Returns the declared spec for `name` when that spec provably cannot resolve\n * to `floorMajor` or newer: a valid semver range with no overlap with\n * `>=floorMajor.0.0-0`. Everything unprovable returns `undefined` — protocol\n * specs (`file:`, `link:`, `workspace:`, git URLs), dist-tags (`latest`,\n * `canary`), absent deps, and ranges that also admit a compliant version\n * (`>=14`, `14 || 16`). The floor comparator includes prereleases so a\n * `15.0.0-rc` user is not rejected by the 15 floor.\n */\nexport function dependencySpecProvablyBelowMajor(\n pkg: PackageJson,\n name: string,\n floorMajor: number,\n): string | undefined {\n const spec = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name];\n if (!spec || semver.validRange(spec) === null) {\n return undefined;\n }\n const atOrAboveFloor = `>=${String(floorMajor)}.0.0-0`;\n return semver.intersects(spec, atOrAboveFloor, { includePrerelease: true }) ? undefined : spec;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport type { PackageJson } from \"./package-json\";\n\n/**\n * Port assumed when no explicit dev port can be discovered. Matches Next.js's\n * own default so the inferred issuer URL lines up with `next dev`.\n */\nexport const DEFAULT_DEV_PORT = 3000;\n\n/**\n * Determines the local dev-server port for `cwd`. The `dev` script is the most\n * authoritative source, then a `PORT` declaration in an env file, falling back\n * to {@link DEFAULT_DEV_PORT}. Used to derive the local issuer URL.\n */\nexport async function detectDevPort(cwd: string, pkg: PackageJson): Promise<number> {\n const dev = pkg.scripts?.dev;\n const fromScript = typeof dev === \"string\" ? extractPort(dev) : undefined;\n if (fromScript) {\n return fromScript;\n }\n\n const fromEnvFile = await portFromEnvFile(cwd);\n if (fromEnvFile) {\n return fromEnvFile;\n }\n\n return DEFAULT_DEV_PORT;\n}\n\nasync function portFromEnvFile(cwd: string): Promise<number | undefined> {\n for (const candidate of [\".env.local\", \".env\"]) {\n try {\n const contents = await readFile(join(cwd, candidate), \"utf8\");\n const match = contents.match(/^\\s*PORT\\s*=\\s*(\\d+)/m);\n const rawPort = match?.[1];\n if (rawPort) {\n return Number.parseInt(rawPort, 10);\n }\n } catch {\n continue;\n }\n }\n return undefined;\n}\n\n/**\n * Parses a dev port out of an npm `dev` script string, recognizing both flag\n * forms (`-p`/`--port`) and a leading `PORT=` env assignment. Returns\n * `undefined` when no valid positive port is present so callers can fall back.\n */\nexport function extractPort(script: string): number | undefined {\n const inline = script.match(/-p\\s+(\\d+)|--port[=\\s]+(\\d+)/);\n if (inline) {\n const raw = inline[1] ?? inline[2];\n if (!raw) {\n return undefined;\n }\n const value = Number.parseInt(raw, 10);\n if (Number.isFinite(value) && value > 0) {\n return value;\n }\n }\n const env = script.match(/(?:^|\\s)PORT=(\\d+)/);\n const rawEnvPort = env?.[1];\n if (rawEnvPort) {\n return Number.parseInt(rawEnvPort, 10);\n }\n return undefined;\n}\n\n/**\n * Rewrites a `dev` script so it explicitly runs on `port`.\n *\n * Setup registers `http://localhost:<port>` as the project's only allowed\n * origin, so the dev server has to land on exactly that port — a bare\n * `next dev` does not: it defaults to 3000 and, when 3000 is taken, silently\n * falls back to 3001. Either way the flow API then rejects the app's origin\n * mid-login. An explicit `--port` removes both failure modes: the port\n * matches what setup registered, and a busy port fails loudly with\n * `EADDRINUSE` instead of drifting to one the project does not allow.\n *\n * `--port <n>` is the one spelling every framework this CLI scaffolds\n * accepts (`next dev`, `nuxt dev`, `vite`, `vinxi dev`, `ng serve`), so an\n * appended declaration stays framework-agnostic. An existing declaration is\n * rewritten in its own form instead — a `PORT=` env assignment keeps the\n * `PORT=` form — so the script keeps whichever mechanism its author chose and\n * only the number changes.\n */\nexport function withDevPort(script: string, port: number): string {\n // Test for a declaration rather than comparing before/after: a script that\n // already names the target port rewrites to itself, and treating that\n // \"unchanged\" as \"no port found\" would append a second, duplicate flag on\n // every re-run of setup.\n const flagPattern = /(-p\\s+|--port[=\\s]+)\\d+/;\n if (flagPattern.test(script)) {\n return script.replace(flagPattern, (_match, prefix: string) => `${prefix}${String(port)}`);\n }\n const envPattern = /((?:^|\\s)PORT=)\\d+/;\n if (envPattern.test(script)) {\n return script.replace(envPattern, (_match, prefix: string) => `${prefix}${String(port)}`);\n }\n return `${script.trimEnd()} --port ${String(port)}`;\n}\n\n/**\n * Builds the local OIDC issuer URL for a given dev port. Centralized so the\n * `localhost` origin convention is defined in exactly one place.\n */\nexport function issuerFromPort(port: number): string {\n return `http://localhost:${port}`;\n}\n\n/**\n * The port an issuer URL names, or `undefined` when it names none.\n *\n * The inverse of {@link issuerFromPort}, and the authoritative way to learn\n * which port a project *registered* — as opposed to {@link detectDevPort},\n * which reports the port the app would start on right now. The two agree\n * during setup and diverge afterwards, which is exactly when it matters: a\n * dev script edited to another port must be read as a mismatch against the\n * registered origin, not as the new truth.\n */\nexport function portFromIssuer(issuer: string): number | undefined {\n try {\n // Validity gate only. `.port` cannot be read off this: WHATWG drops a\n // port matching the scheme's default, so `http://localhost:80` — a port\n // `--dev-port` accepts — would come back portless and silently disable\n // the dev-script pinning, reintroducing the very mismatch it prevents.\n new URL(issuer);\n } catch {\n return undefined;\n }\n // Re-parse under a scheme the URL standard treats as non-special. Those\n // have no default port, so an explicitly written 80/443 survives, while\n // host parsing (IPv6 brackets, userinfo) stays the standard's job.\n let probe: URL;\n try {\n probe = new URL(issuer.replace(/^[a-zA-Z][a-zA-Z0-9+.-]*:/, \"zl-issuer-probe:\"));\n } catch {\n return undefined;\n }\n const port = Number.parseInt(probe.port, 10);\n return Number.isFinite(port) && port > 0 ? port : undefined;\n}\n","import { ZitadelError } from \"../../errors\";\nimport { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/** The lowest Angular major the generated templates compile on. */\nconst MIN_ANGULAR_MAJOR = 17;\n\n/** Best-effort major version from a dependency range (`^17.3.0` → 17). */\nfunction angularMajor(spec: string): number | undefined {\n const match = spec.match(/\\d+/);\n return match ? Number.parseInt(match[0], 10) : undefined;\n}\n\n/**\n * Detects an Angular project by its `@angular/core` dependency. The app dir is\n * `src/app` (where the patcher writes `app.ts`/`app.html`), the dev port comes\n * from the project (else the default), and the issuer is derived from it.\n * Angular's dev server (`@angular/build:dev-server`)\n * is Vite-based but configured via `angular.json` + a `proxy.conf.cjs`, not a\n * `vite.config.ts` — handled by the Angular patcher.\n *\n * The managed templates use Angular 17+ control flow (`@if`), so a clearly\n * older project fails fast with `E_VALIDATION` instead of scaffolding files\n * that won't compile.\n */\nexport class AngularDetector implements Detector {\n readonly framework = \"angular\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, \"@angular/core\")) {\n return null;\n }\n\n const spec = pkg.dependencies?.[\"@angular/core\"] ?? pkg.devDependencies?.[\"@angular/core\"];\n const major = spec ? angularMajor(spec) : undefined;\n if (major !== undefined && major < MIN_ANGULAR_MAJOR) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Angular ${major} is unsupported — the generated auth templates use Angular ${MIN_ANGULAR_MAJOR}+ control flow (@if).`,\n {\n hint: `Upgrade to Angular ${MIN_ANGULAR_MAJOR} or newer before running setup, or add the Zitadel components to your templates manually.`,\n },\n );\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"angular\", appDir: \"src/app\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ZitadelError } from \"../../errors\";\nimport {\n dependencySpecProvablyBelowMajor,\n dependencyVersionMajor,\n hasDependency,\n readPackageJson,\n} from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Next.js App Router project and extracts its facts: the App Router\n * directory (`app` vs `src/app`), the dev-server port (parsed from the `dev`\n * script / env file, else 3000), and the derived local issuer URL. Owns every\n * Next-specific assumption so the orchestrator and commands stay generic.\n */\nexport class NextDetector implements Detector {\n readonly framework = \"next\";\n\n /**\n * Returns `null` when `cwd` is not a Next.js project (no `next` dependency),\n * so the orchestrator can try other detectors. Throws\n * `E_UNSUPPORTED_PROJECT_SHAPE` when it is Next.js but lacks an App Router\n * directory (e.g. a Pages Router project), which is a hard error rather than\n * an empty directory to scaffold.\n */\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, \"next\")) {\n return null;\n }\n\n // Supported floor (ADR 043): the scaffolded templates target Next 15+\n // (current App Router and request-boundary conventions). The floor is\n // enforced here so setup and doctor share one loud gate instead of\n // degrading silently; only a spec that provably cannot resolve to 15+\n // is rejected — protocol specs and dist-tags pass.\n const belowFloor = dependencySpecProvablyBelowMajor(pkg, \"next\", 15);\n if (belowFloor !== undefined) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n `Next.js \"${belowFloor}\" is below the supported floor — the CLI integrates Next.js 15 and newer`,\n { hint: \"Upgrade the app to Next 15+ (e.g. `npx @next/codemod@latest upgrade`) and rerun.\" },\n );\n }\n\n const appDir = (await dirExists(join(cwd, \"app\")))\n ? \"app\"\n : (await dirExists(join(cwd, \"src/app\")))\n ? \"src/app\"\n : undefined;\n if (!appDir) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n \"Next.js Pages Router projects are not supported in v1\",\n { hint: \"Create an App Router project with an app/ or src/app/ directory.\" },\n );\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n const versionMajor = dependencyVersionMajor(pkg, \"next\");\n return {\n id: \"next\",\n appDir,\n devPort,\n url: issuerFromPort(devPort),\n ...(versionMajor === undefined ? {} : { versionMajor }),\n };\n }\n}\n\nasync function dirExists(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isDirectory();\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: string }).code === \"ENOENT\"\n ) {\n return false;\n }\n throw error;\n }\n}\n","import { stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Nuxt project by its `nuxt` dependency. Like Next.js, Nuxt proxies\n * the auth backend through server middleware (`@zitadel/sdk-nuxt`), not a Vite\n * dev-server proxy — so the patcher wires the module + a `nuxt.config.ts` edit.\n * Runs before the Vue detector (which excludes Nuxt) since Nuxt ships Vue.\n *\n * `appDir` tracks the Nuxt srcDir: Nuxt 4 (what `nuxi init` now scaffolds) keeps\n * `app.vue`/`pages/`/`plugins/` under `app/`, while Nuxt 3 keeps them at the\n * root — so the patcher writes its files relative to whichever this project uses.\n */\nexport class NuxtDetector implements Detector {\n readonly framework = \"nuxt\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (!pkg || !hasDependency(pkg, \"nuxt\")) {\n return null;\n }\n\n const appDir = (await dirExists(join(cwd, \"app\"))) ? \"app\" : \".\";\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"nuxt\", appDir, devPort, url: issuerFromPort(devPort) };\n }\n}\n\nasync function dirExists(path: string): Promise<boolean> {\n return stat(path).then(\n (s) => s.isDirectory(),\n () => false,\n );\n}\n","import { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Vite + Qwik single-page app: depends on `@builder.io/qwik` and\n * `vite` but NOT `@builder.io/qwik-city` (Qwik City is its own meta-framework\n * and ships Qwik). The source dir is `src`, the dev port comes from the\n * project, and the issuer is derived from it.\n */\nexport class QwikDetector implements Detector {\n readonly framework = \"qwik\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"@builder.io/qwik-city\") ||\n !hasDependency(pkg, \"@builder.io/qwik\") ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"qwik\", appDir: \"src\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { ZitadelError } from \"../../errors\";\nimport {\n dependencySpecProvablyBelowMajor,\n dependencyVersionMajor,\n hasDependency,\n readPackageJson,\n} from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Vite + React single-page app and extracts its facts: the source\n * directory (`src`), the dev-server port (parsed from the `dev` script / env\n * file, else the framework default), and the derived local issuer URL.\n *\n * Recognises a project that depends on both `react` and `vite` but NOT `next`\n * — Next.js ships React too, so the {@link import(\"./next\").NextDetector} must\n * run first (and does, by registry order) and this detector excludes it.\n */\nexport class ReactDetector implements Detector {\n readonly framework = \"react\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"next\") ||\n !hasDependency(pkg, \"react\") ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n // Supported floor (ADR 043): the SDK wrappers and scaffolded templates\n // target React 18+. Enforced here so setup and doctor share one loud\n // gate; only a spec that provably cannot resolve to 18+ is rejected —\n // protocol specs and dist-tags pass.\n const belowFloor = dependencySpecProvablyBelowMajor(pkg, \"react\", 18);\n if (belowFloor !== undefined) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n `React \"${belowFloor}\" is below the supported floor — the CLI integrates React 18 and newer`,\n { hint: \"Upgrade the app to React 18+ and rerun.\" },\n );\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n const versionMajor = dependencyVersionMajor(pkg, \"react\");\n return {\n id: \"react\",\n appDir: \"src\",\n devPort,\n url: issuerFromPort(devPort),\n ...(versionMajor === undefined ? {} : { versionMajor }),\n };\n }\n}\n","import { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Vite + Solid single-page app: depends on `solid-js` and `vite` but\n * NOT `@solidjs/start` (SolidStart is its own meta-framework and ships Solid).\n * The source dir is `src`, the dev port comes from the project, and the issuer\n * is derived from it.\n */\nexport class SolidDetector implements Detector {\n readonly framework = \"solid\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"@solidjs/start\") ||\n !hasDependency(pkg, \"solid-js\") ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"solid\", appDir: \"src\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Vite + Svelte single-page app: depends on `svelte` and `vite` but\n * NOT `@sveltejs/kit` (SvelteKit is its own meta-framework and ships Svelte).\n * The source dir is `src`, the dev port comes from the project, and the issuer\n * is derived from it.\n */\nexport class SvelteDetector implements Detector {\n readonly framework = \"svelte\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"@sveltejs/kit\") ||\n !hasDependency(pkg, \"svelte\") ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"svelte\", appDir: \"src\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { hasDependency, readPackageJson } from \"./package-json\";\nimport { detectDevPort, issuerFromPort } from \"./port\";\nimport type { Detector, FrameworkFacts } from \"./types\";\n\n/**\n * Detects a Vite + Vue single-page app: depends on `vue` and `vite` but NOT\n * `nuxt` (Nuxt is its own meta-framework and ships Vue) — so the source dir is\n * `src`, the dev port comes from the project, and the issuer is derived from it.\n */\nexport class VueDetector implements Detector {\n readonly framework = \"vue\";\n\n async detect(cwd: string): Promise<FrameworkFacts | null> {\n const pkg = await readPackageJson(cwd).catch(() => undefined);\n if (\n !pkg ||\n hasDependency(pkg, \"nuxt\") ||\n !hasDependency(pkg, \"vue\") ||\n !hasDependency(pkg, \"vite\")\n ) {\n return null;\n }\n\n const devPort = await detectDevPort(cwd, pkg);\n return { id: \"vue\", appDir: \"src\", devPort, url: issuerFromPort(devPort) };\n }\n}\n","import { AngularDetector } from \"./angular\";\nimport { NextDetector } from \"./next\";\nimport { NuxtDetector } from \"./nuxt\";\nimport { QwikDetector } from \"./qwik\";\nimport { ReactDetector } from \"./react\";\nimport { SolidDetector } from \"./solid\";\nimport { SvelteDetector } from \"./svelte\";\nimport { VueDetector } from \"./vue\";\nimport type { Detector } from \"./types\";\n\n/**\n * Active detectors, in probe order. The orchestrator tries each until one\n * recognises the project. Add a framework by appending its detector here — no\n * orchestrator changes needed. Meta-frameworks run before their base: Next\n * before React (Next ships React), and the Vue detector excludes Nuxt — so a\n * Next/Nuxt project is never mistaken for a bare React/Vue SPA.\n */\nexport const detectors = [\n new NextDetector(),\n new NuxtDetector(),\n new ReactDetector(),\n new VueDetector(),\n new SolidDetector(),\n new SvelteDetector(),\n new QwikDetector(),\n new AngularDetector(),\n] as const satisfies ReadonlyArray<Detector>;\n","import { chmod, mkdir, readFile, rename, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { ZitadelError } from \"../../../../errors\";\nimport {\n isObject,\n parseJsonObject,\n setTopLevelJsonKey,\n stableStringify,\n} from \"../../../../json\";\nimport type { PatchedFile } from \"../../types\";\nimport type { FileOp, ScaffoldPlan, ScaffoldResult } from \"./types\";\n\n/**\n * The executor's private, mutable accumulator. Handlers record each touched\n * artifact as a typed row; {@link scaffold} derives the readonly\n * {@link ScaffoldResult} from it so the public result stays immutable.\n */\ntype ScaffoldAccumulator = {\n dryRun: boolean;\n files: PatchedFile[];\n filesSkipped: string[];\n depsAdded: string[];\n};\n\n/**\n * Records one touched artifact, deduplicating by path: several plan ops can\n * legitimately hit the same file (the base and framework op lists both merge\n * into `.env.local`, for example), but the report should carry it once, with\n * the first action as the net one — a file created and then extended in the\n * same run was created by the run.\n */\nfunction record(\n result: ScaffoldAccumulator,\n path: string,\n kind: PatchedFile[\"kind\"],\n action: PatchedFile[\"action\"],\n): void {\n if (result.files.some((file) => file.path === path)) {\n return;\n }\n result.files.push({ path, kind, action });\n}\n\n/**\n * Applies a {@link ScaffoldPlan} to disk, executing its operations in order.\n *\n * Operations are idempotent: writes whose target already matches the desired\n * contents are recorded as skipped rather than rewritten, so re-running setup\n * is safe. With `dryRun` no filesystem changes are made but the result still\n * reflects what would have been written. Existing files are only overwritten\n * when `force` is set; otherwise an `E_CONFLICT` is thrown to protect\n * user-authored content. Paths in the plan are resolved relative to `cwd`.\n */\nexport async function scaffold(\n plan: ScaffoldPlan,\n opts: { cwd: string; dryRun: boolean; force: boolean },\n): Promise<ScaffoldResult> {\n const result: ScaffoldAccumulator = {\n dryRun: opts.dryRun,\n files: [],\n filesSkipped: [],\n depsAdded: [],\n };\n\n for (const op of plan.ops) {\n await applyOp(op, opts, result);\n }\n\n const written = new Set(result.files.map((file) => file.path));\n return {\n dryRun: result.dryRun,\n files: result.files,\n // Legacy flat list: deduplicated file paths only. Directories stay in\n // `files` rows (kind \"dir\"); a path both written and later skipped as\n // already-matching reports as written.\n filesWritten: result.files.filter((file) => file.kind === \"file\").map((file) => file.path),\n filesSkipped: [...new Set(result.filesSkipped)].filter((path) => !written.has(path)),\n depsAdded: result.depsAdded,\n };\n}\n\nasync function applyOp(\n op: FileOp,\n opts: { cwd: string; dryRun: boolean; force: boolean },\n result: ScaffoldAccumulator,\n): Promise<void> {\n switch (op.kind) {\n case \"mkdir\":\n await ensureDir(abs(opts.cwd, op.path), op.mode, opts.dryRun, result);\n break;\n case \"write\":\n await writeText(\n abs(opts.cwd, op.path),\n op.contents,\n { mode: op.mode, force: opts.force, dryRun: opts.dryRun },\n result,\n );\n break;\n case \"append\":\n await appendText(abs(opts.cwd, op.path), op.contents, op.ifMissing, opts.dryRun, result);\n break;\n case \"merge-env\":\n await mergeEnv(abs(opts.cwd, op.path), op.entries, 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 & 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 if (deps[op.name] === op.version) {\n result.filesSkipped.push(path);\n return;\n }\n // package.json is user-owned: splice only the dependency map's value into\n // the document. Every byte outside it — key order, blank lines, inline\n // objects, line endings — stays untouched; the touched map itself is\n // name-sorted, matching what a package manager writes.\n const contents = setTopLevelJsonKey(\n existing,\n path,\n key,\n sortByKey({ ...deps, [op.name]: op.version }),\n );\n if (dryRun) {\n record(result, path, \"file\", \"update\");\n result.depsAdded.push(op.name);\n return;\n }\n await writeFile(path, contents);\n record(result, path, \"file\", \"update\");\n result.depsAdded.push(op.name);\n}\n\n/** Rebuilds an object with lexicographically sorted keys (dependency maps). */\nfunction sortByKey(value: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(value).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)),\n );\n}\n\nasync function readIfExists(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if (typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction abs(cwd: string, path: string): string {\n return join(cwd, path);\n}\n\nfunction deepMerge(\n target: Record<string, unknown>,\n patch: Readonly<Record<string, unknown>>,\n): Record<string, unknown> {\n const out = { ...target };\n for (const [key, value] of Object.entries(patch)) {\n if (isObject(value) && isObject(out[key])) {\n out[key] = deepMerge(out[key] as Record<string, unknown>, value);\n } else {\n out[key] = value;\n }\n }\n return out;\n}\n","/**\n * Scaffolded guidance for humans (`README.md`) and agents (`AGENTS.md`):\n * the golden journey from a fresh scaffold to a customized, published\n * login — so the project explains its own next step without the docs\n * site. Both files are edited via a marker-fenced managed section, so\n * setup never clobbers what a developer (or another tool) wrote and a\n * rerun replaces only its own section.\n */\nimport { publicCliCommand } from \"../../../public-cli\";\nimport type { PatchContext } from \"../types\";\n\nconst MARKER_BEGIN = \"<!-- zitadel:guidance:begin -->\";\nconst MARKER_END = \"<!-- zitadel:guidance:end -->\";\n\n/**\n * Insert or replace the managed guidance section in `source`. A missing\n * file becomes `header` + section; an existing section (marker pair) is\n * replaced in place; anything else gets the section appended. Pure and\n * idempotent — the file-writer skips the write when output equals input.\n */\nexport function upsertGuidanceSection(\n source: string | undefined,\n section: string,\n header: string,\n): string {\n const block = `${MARKER_BEGIN}\\n${section}\\n${MARKER_END}\\n`;\n if (source === undefined || source.trim() === \"\") {\n return `${header}${block}`;\n }\n const begin = source.indexOf(MARKER_BEGIN);\n const end = source.indexOf(MARKER_END);\n if (begin !== -1 && end > begin) {\n return `${source.slice(0, begin)}${block}${source.slice(end + MARKER_END.length).replace(/^\\n/, \"\")}`;\n }\n return `${source.replace(/\\n*$/, \"\\n\\n\")}${block}`;\n}\n\n/**\n * Remove the managed guidance section (markers inclusive) from `source` —\n * the inverse of {@link upsertGuidanceSection}, for `eject`. Content outside\n * the markers is preserved byte-for-byte; a missing or malformed marker pair\n * returns `source` unchanged.\n */\nexport function removeGuidanceSection(source: string): string {\n const begin = source.indexOf(MARKER_BEGIN);\n const end = source.indexOf(MARKER_END);\n if (begin === -1 || end <= begin) {\n return source;\n }\n return `${source.slice(0, begin)}${source.slice(end + MARKER_END.length).replace(/^\\n/, \"\")}`;\n}\n\n/** The agent-facing golden path, written into `AGENTS.md`. */\nexport function agentsGuidanceSection(ctx: PatchContext): string {\n const plan = publicCliCommand(\"plan\", ctx.cliVersion);\n const apply = publicCliCommand(\"apply\", ctx.cliVersion);\n // WebAuthn ceremonies need an OS-level authenticator, so an agent driving\n // an automated browser stalls on the primary action of a passkey-first\n // flow unless told how to verify around it.\n const passkeyVerifyNote =\n ctx.preset === \"passkey-first\"\n ? \" Agents: automated browsers can't complete passkey ceremonies — verify the loop via the email/password fallback actions, or attach a CDP WebAuthn virtual authenticator.\"\n : \"\";\n // JSX typing is a Next/React concern; other frameworks type the elements\n // through their own SDK wrappers, so the pointer would be misleading there.\n const jsxTypesNote =\n ctx.framework.id === \"next\"\n ? \" React JSX types for the `<zitadel-*>` elements ship with the SDK — `custom-elements.d.ts` references `@zitadel/sdk-next/jsx`.\"\n : \"\";\n // Describe the posture the pages were actually emitted with (ADR 044), so\n // the guidance never claims full-page chrome an embedded card doesn't have.\n const presentationParagraph =\n ctx.posture === \"widget\"\n ? 'Presentation, by contrast, is edited in the generated pages: this app pre-dates setup, so they embed the sign-in widgets as `variant=\"widget\"` cards (with `theme=\"auto\"`) inside your existing layout; switch to `variant=\"page\"` for the widget\\'s own full-page chrome, and set `theme` (`light` | `dark` | `auto`) to pick the color scheme — `auto` follows the OS `prefers-color-scheme`, not this app\\'s own theme, so pin `light` or `dark` when the app fixes its scheme.'\n : 'Presentation, by contrast, is edited in the generated pages: they pin the sign-in widgets to `variant=\"page\"` (full-page chrome); switch to `variant=\"widget\"` to embed a card inside your own layout, and set `theme` (`light` | `dark` | `auto`) to pick the color scheme — `auto` follows the OS `prefers-color-scheme`, not this app\\'s own theme, so pin `light` or `dark` when the app fixes its scheme.';\n // The token bridge is the highest-leverage embedding lever and lives\n // nowhere an integrator would otherwise look (component source). Keep the\n // knob list here in sync with the documented public tokens.\n const themingParagraph =\n \"Theming the widgets from your app: `--zl-*` design-token custom properties set on the element in your own stylesheet pierce the widgets' shadow DOM. The bridge covers your fonts (`--zl-font-family-heading`, `--zl-font-family-sans`), radii (`--zl-radius-md`/`-lg`/`-xl`), the primary CTA pair (`--zl-primary` / `--zl-primary-foreground`), and the link color (`--zl-link`). When your page already carries the heading, set the `suppress-header` attribute on `<zitadel-login>` / `<zitadel-session>` (SDK wrappers: `suppressHeader`) to visually hide the widget's own heading block — it stays in the accessibility tree. Starter designs from `.zitadel/branding/` collapse their brand pane by container width, not viewport: an embedded card usually renders the compact brand mark instead (`logo_url`, else `hero_url`, from `branding.json`; the `hero` design falls back to editable text).\";\n // The app's own chrome (header nav, account menus) needs a session read of\n // its own — the widgets render their surfaces but never tell the host page\n // whether someone is signed in. Name the framework's supported read path;\n // the contract details live with each helper's own docs.\n const sessionStateParagraph =\n ctx.framework.id === \"next\"\n ? \"Your app's own chrome (header navigation, account menus) reads session state with `getSession()` from `@zitadel/sdk-next/session` — a no-store client read of the same-origin `/__nextgen/sessions/me` that the session card itself uses. It returns identity only for 200 with a non-empty `user_id`, and signed-out only for the backend's canonical `401/auth.unauthorized` or `404/sess.not_found`; any other response is unknown/error, never signed-out. In Server Components on routes covered by the request-boundary `matcher`, `auth()` from `@zitadel/sdk-next/server` works too — extend the `matcher` in the request boundary to cover your public routes when you want server-rendered, flash-free session state in shared chrome (the trade: the middleware then runs on those routes). Sign-in and sign-out navigate (`post-sign-in-url` / `post-sign-out-url`), so chrome re-reads on the next page load without extra wiring.\"\n : ctx.framework.id === \"nuxt\"\n ? \"Your app's own chrome (header navigation, account menus) reads session state with the auto-imported `useAuth()` composable — seeded from the server on every render by the scaffolded auth plugin. Sign-in and sign-out navigate (`post-sign-in-url` / `post-sign-out-url`), so the state is fresh on every page load.\"\n : 'Your app\\'s own chrome (header navigation, account menus) can read session state from the same-origin `/__nextgen/sessions/me` — the same server-answered read the session card performs. Fetch with `credentials: \"include\"`, `cache: \"no-store\"`, and `Accept: application/json`; treat 200 as signed-in only with a non-empty `user_id`, and signed-out only for the canonical error envelope `401/auth.unauthorized` or `404/sess.not_found`. Any other response is unknown/error, never signed-out. Sign-in and sign-out navigate (`post-sign-in-url` / `post-sign-out-url`), so chrome re-reads on the next page load.';\n return `## Authentication (Zitadel)\n\nThis app's login is managed by Zitadel. Local config is the source of truth; never change auth behavior by editing generated route files.\n\nThe golden path:\n\n1. Start the dev server and open ${ctx.issuer}/login — **exactly this origin, not 127.0.0.1**. Passkeys and the origin allowlist are bound to it. (Freshly scaffolded apps also redirect / there; pre-existing apps keep their homepage.)\n2. Prove the loop in a real browser: register a user → sign out → sign in → /profile shows signed in.${passkeyVerifyNote}\n3. Customize by editing local config:\n - \\`.zitadel/schemas/*.json\\` — what a user is (fields, required, auth methods). See \\`.zitadel/schemas/README.md\\`.\n - \\`.zitadel/flows/*.json\\` — which screen collects which field/credential and how steps transition. See \\`.zitadel/flows/README.md\\`.\n4. Preview, then publish:\n - \\`${plan}\\`\n - \\`${apply}\\`\n - Agents: append \\`--non-interactive --json\\` to both. \\`plan\\` validates flow invariants with the server's own rules **before** anything uploads — fix what it reports and re-run.\n\n${presentationParagraph}${jsxTypesNote}\n\n${themingParagraph}\n\n${sessionStateParagraph}\n\nMachine-readable dialect (read these before authoring flow or schema edits):\n\n- Flow files carry \\`\"$schema\": \"../meta/flow-definition.json\"\\` — the flow dialect spec (steps, actions and their kinds, transitions, reserved outcomes like \\`user_not_found\\`). Editors validate against it.\n- \\`.zitadel/meta/user-schema.json\\` (with its companions \\`user-property.json\\`, \\`auth-methods.json\\`, \\`auth-method.json\\`, \\`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 return `## Authentication (Zitadel)\n\nLogin for this app is managed by [Zitadel](https://zitadel.com). Try it: start the dev server, open ${ctx.issuer}/login (use this exact origin — passkeys are bound to it), register a user, sign out, and sign in again.\n\nTo change what the login collects or how sign-in works, edit the files under \\`.zitadel/schemas/\\` and \\`.zitadel/flows/\\` (each folder has a README), then:\n\n\\`\\`\\`sh\n${plan}\n${apply}\n\\`\\`\\``;\n}\n\n/** Full-file header used when `AGENTS.md` does not exist yet. */\nexport const AGENTS_HEADER = `# AGENTS.md\n\nGuidance for AI agents working in this repository.\n\n`;\n\n/** Full-file header used when `README.md` does not exist yet. */\nexport const README_HEADER = \"\";\n","import { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { isObject } from \"../../../json\";\nimport { MANAGED_MARKER } from \"../../../paths\";\nimport type { FileOp, ScaffoldPlan } from \"./file-writer/types\";\n\n/**\n * The subset of a patcher plan's operations that `doctor --fix` re-applies:\n * env merges, gitignore entries, dependency additions, marker-bearing managed\n * files (framework routes/middleware), and the `edit` transforms — the\n * `/__nextgen` dev proxy merged into `vite.config`/`nuxt.config`/`angular.json`\n * and the Angular `dev` script added to `package.json`. Every `edit` transform\n * is idempotent and only adds what is missing (an existing value is left as-is,\n * the transform returning the source unchanged), so replaying one restores a\n * removed managed block without clobbering the user's own edits. Deliberately\n * excludes the unmarked `.zitadel/` resource writes and `zitadel.json` — those\n * are user-editable and synced by `apply`, so `--fix` must not clobber them.\n *\n * Pure: filters a freshly-allocated list; the input plan is not mutated.\n */\nexport function reclaimableOps(plan: ScaffoldPlan): FileOp[] {\n return plan.ops.filter(\n (op) =>\n op.kind === \"merge-env\" ||\n op.kind === \"append-gitignore\" ||\n op.kind === \"add-dep\" ||\n op.kind === \"edit\" ||\n (op.kind === \"write\" && op.contents.includes(MANAGED_MARKER)),\n );\n}\n\n/**\n * Narrow a reclaimable op list to what a missing-only repair may replay:\n * content ops (`write`, and `edit` marked `overwrites`) survive only when\n * their target file does not exist, so the repair can restore a deleted\n * managed file but can never touch an edited or user-adopted one. Merging\n * `edit` transforms and the additive kinds (`merge-env`, `append-gitignore`)\n * pass through — they are idempotent and only add what is missing. `add-dep`\n * is additive only while the dependency is absent: `addDependency` replaces\n * a differing existing version, so under missing-only semantics the op is\n * dropped whenever the dependency is already declared at *any* version —\n * repairing an unrelated missing file must never rewrite a user-pinned\n * range. Reads the filesystem; paths resolve against `cwd` like the\n * file-writer's.\n */\nexport async function withoutExistingTargets(\n ops: ReadonlyArray<FileOp>,\n cwd: string,\n): Promise<FileOp[]> {\n const kept: FileOp[] = [];\n for (const op of ops) {\n if (op.kind === \"write\") {\n if (!(await exists(join(cwd, op.path)))) {\n kept.push(op);\n }\n continue;\n }\n if (op.kind === \"edit\" && op.overwrites) {\n const candidates = typeof op.path === \"string\" ? [op.path] : op.path;\n const present = await Promise.all(\n candidates.map((candidate) => exists(join(cwd, candidate))),\n );\n if (!present.includes(true)) {\n kept.push(op);\n }\n continue;\n }\n if (op.kind === \"add-dep\") {\n if (!(await dependencyDeclared(cwd, op.name))) {\n kept.push(op);\n }\n continue;\n }\n kept.push(op);\n }\n return kept;\n}\n\n/**\n * Whether `package.json` already declares `name` in dependencies or\n * devDependencies, at any version. A missing or unparsable `package.json`\n * counts as \"not declared\" so the op is kept and the file-writer's own\n * error handling reports the real problem.\n */\nasync function dependencyDeclared(cwd: string, name: string): Promise<boolean> {\n let contents: string;\n try {\n contents = await readFile(join(cwd, \"package.json\"), \"utf8\");\n } catch {\n return false;\n }\n try {\n const pkg = JSON.parse(contents) as unknown;\n if (!isObject(pkg)) {\n return false;\n }\n const declared = (key: string): boolean => isObject(pkg[key]) && name in (pkg[key] as object);\n return declared(\"dependencies\") || declared(\"devDependencies\");\n } catch {\n return false;\n }\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { metaSchemaFiles, META_SCHEMA_DIR } from \"@zitadel/config/meta-schemas\";\n\nimport { stableStringify } from \"../../../json\";\nimport { normalizePublicCliJson } from \"../../../public-cli\";\nimport { DEFAULT_SERVER } from \"../../../server\";\nimport { scaffold } from \"./file-writer\";\nimport type { FileOp, ScaffoldPlan } from \"./file-writer/types\";\nimport {\n AGENTS_HEADER,\n agentsGuidanceSection,\n README_HEADER,\n readmeGuidanceSection,\n upsertGuidanceSection,\n} from \"./guidance\";\nimport type {\n ConfigWiringStatus,\n EjectActions,\n Patcher,\n PatchContext,\n PatchExecOptions,\n PatchResult,\n PatchView,\n} from \"../types\";\nimport { reclaimableOps, withoutExistingTargets } from \"./reclaim\";\n\n/**\n * Base for rule-based (deterministic, template-driven) patchers, as opposed to\n * a future LLM-driven family. It applies the integration by building a\n * file-operation plan and running the file-writer — that strategy stays\n * entirely inside this family, so callers only ever see the family-neutral\n * {@link Patcher} surface. Owns the framework-agnostic `.zitadel/` base files\n * and the shared eject classification; subclasses contribute only their\n * framework-specific routes/middleware.\n */\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 return scaffold(this.plan(ctx), opts);\n }\n\n /**\n * Re-apply only the reclaimable subset — env files, gitignore, the SDK\n * dependency, and marker-bearing routes — leaving the user-editable\n * `.zitadel/` resources untouched. Backs `doctor --fix`. With\n * `opts.missingOnly` the content ops are further narrowed to files that do\n * not exist (see {@link withoutExistingTargets}) and the writer runs without\n * `force`, so the repair restores deleted managed files and can never\n * overwrite an edited or user-adopted one.\n */\n async repair(ctx: PatchContext, opts: PatchExecOptions): Promise<PatchResult> {\n const plan = this.plan(ctx);\n let ops = opts.missingOnly\n ? await withoutExistingTargets(reclaimableOps(plan), opts.cwd)\n : reclaimableOps(plan);\n const excluded = new Set(opts.excludePaths ?? []);\n if (excluded.size > 0) {\n ops = ops.filter((op) => {\n if (op.kind === \"write\") {\n return !excluded.has(op.path);\n }\n if (op.kind === \"edit\" && op.overwrites) {\n const candidates = typeof op.path === \"string\" ? [op.path] : op.path;\n return !candidates.some((candidate) => excluded.has(candidate));\n }\n return true;\n });\n }\n const execOpts = opts.missingOnly ? { ...opts, force: false } : opts;\n return scaffold({ ops, summary: plan.summary }, execOpts);\n }\n\n /**\n * Probe whether the labelled config wirings are still applied, using each\n * merge transform's own idempotency: the transforms only add what is\n * missing and return the source unchanged when everything they manage is\n * present, so a changed output means the wiring is absent from the user's\n * config. Every labelled wiring gets a verdict: a missing host file is\n * `detached` (the wiring cannot be applied in a file that does not exist),\n * and a transform that throws on restructured content yields `unknown` —\n * surfaced rather than silently dropped, so a deleted `angular.json` can\n * never read as healthy. Read-only.\n */\n async verify(\n ctx: PatchContext,\n opts: { cwd: string },\n ): Promise<ReadonlyArray<ConfigWiringStatus>> {\n const statuses: ConfigWiringStatus[] = [];\n for (const op of this.plan(ctx).ops) {\n if (op.kind !== \"edit\" || !op.wiring) {\n continue;\n }\n const candidates = typeof op.path === \"string\" ? [op.path] : op.path;\n let path = candidates[0]!;\n let source: string | undefined;\n for (const candidate of candidates) {\n const contents = await readTextIfExists(join(opts.cwd, candidate));\n if (contents !== undefined) {\n path = candidate;\n source = contents;\n break;\n }\n }\n if (source === undefined) {\n statuses.push({ path, wiring: op.wiring, state: \"detached\" });\n continue;\n }\n try {\n statuses.push({\n path,\n wiring: op.wiring,\n state: op.edit(source) === source ? \"applied\" : \"detached\",\n });\n } catch (error) {\n statuses.push({\n path,\n wiring: op.wiring,\n state: \"unknown\",\n reason: error instanceof Error ? error.message : \"verification failed\",\n });\n }\n }\n return statuses;\n }\n\n /** Shared base artifacts plus the subclass's marker-bearing route files. */\n artifacts(view: PatchView): EjectActions {\n const infrastructure = new Set(this.infrastructureFiles(view));\n const markedFiles = this.routeFiles(view);\n return {\n markedFiles,\n rootConfigFiles: [\"zitadel.json\"],\n directories: [\".zitadel\"],\n envBackups: [\".env.local\"],\n dependencies: this.routeDeps(view),\n configEdits: this.routeConfigEdits(view),\n guidanceFiles: [\"AGENTS.md\", \"README.md\"],\n fileClasses: Object.fromEntries(\n markedFiles.map((path) => [path, infrastructure.has(path) ? \"infrastructure\" : \"presentation\"]),\n ),\n conditionalFiles: this.conditionallyScaffoldedFiles(view),\n retiredAlternates: this.retiredAlternateFiles(view),\n };\n }\n\n /**\n * Current marked files mapped to sibling paths that older templates wrote\n * in their place and the framework rejects alongside them. Drives the\n * managed-files boundary migration. Defaults to none; Next overrides it\n * for the `middleware.ts`/`proxy.ts` pair.\n */\n protected retiredAlternateFiles(\n _view: PatchView,\n ): Readonly<Record<string, ReadonlyArray<string>>> {\n return {};\n }\n\n /**\n * The subset of {@link routeFiles} that is load-bearing for the integration\n * (request boundary, proxies, plugins, type declarations). The `doctor`\n * managed-files check fails when one is missing; everything else is a\n * presentation starting point and only warns. Every patcher whose marked\n * files include plumbing must override this — Next (boundary/provider/dts),\n * Angular (proxy.conf.cjs), and Nuxt (plugins) do. The Vite SPAs' only\n * marked file is the root component (presentation); their plumbing lives in\n * `vite.config.*`, which is a config-edit merge into a user file and out of\n * the file check's reach. Defaults to none.\n */\n protected infrastructureFiles(_view: PatchView): ReadonlyArray<string> {\n return [];\n }\n\n /**\n * Marked files only written on some scaffolds (e.g. a framework home page\n * that setup replaces only when it created the app skeleton itself). The\n * managed-files check excludes them when no scaffold manifest recorded what\n * was actually written. Defaults to none.\n */\n protected conditionallyScaffoldedFiles(_view: PatchView): ReadonlyArray<string> {\n return [];\n }\n\n /**\n * User config files this patcher merges into via an `edit` op (e.g.\n * `vite.config.ts`). `eject` can't reverse an in-place merge, so it lists\n * these as manual cleanup steps. Defaults to none; patchers that edit a config\n * (React/Vue/Angular/Nuxt) override it. Next writes whole marker-bearing files\n * instead, so it has none.\n */\n protected routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [];\n }\n\n /**\n * The full file-operation plan this patcher would apply. Public so rule-family\n * unit tests can assert the planned ops directly; the generic {@link Patcher}\n * interface deliberately does not expose it (an LLM patcher has no such plan).\n */\n plan(ctx: PatchContext): ScaffoldPlan {\n return {\n ops: [...this.baseOps(ctx), ...this.routeOps(ctx)],\n summary: [this.summary(ctx)],\n };\n }\n\n /**\n * The framework-agnostic `.zitadel/` base files every rule patcher writes:\n * the project secret, `zitadel.json`, env templates, and an empty sync\n * state. The `schemas/` and `flows/` directories are created empty here;\n * setup fills them from versioned local defaults after patching.\n * Pure: no filesystem or network.\n */\n private baseOps(ctx: PatchContext): ReadonlyArray<FileOp> {\n return [\n { kind: \"mkdir\", path: \".zitadel\", mode: 0o700 },\n { kind: \"mkdir\", path: \".zitadel/flows\" },\n { kind: \"mkdir\", path: \".zitadel/schemas\" },\n { kind: \"append-gitignore\", entries: [\".zitadel/secret\", \".env*\", \"!.env.example\"] },\n {\n kind: \"write\",\n path: \".zitadel/secret\",\n mode: 0o600,\n contents: `${stableStringify({\n project_id: ctx.project.id,\n project_secret: ctx.project.project_secret,\n preview_secret: ctx.project.preview_secret,\n preview_origins: ctx.project.preview_origins,\n created_at: ctx.project.created_at,\n })}\\n`,\n },\n { kind: \"write\", path: \"zitadel.json\", contents: `${stableStringify(projectConfig(ctx))}\\n` },\n {\n kind: \"merge-env\",\n path: \".env.example\",\n 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 flow files'\n // relative `$schema` pointers resolve offline (editor validation) and\n // agents can read the flow/schema dialect without the docs site. Their\n // descriptions become editor tooltips inside the generated app, so the\n // `zitadel …` mentions are rewritten to the runnable public form on the\n // way out — the shared source keeps the bare spelling the server wants.\n { kind: \"mkdir\", path: META_SCHEMA_DIR },\n ...metaSchemaFiles().map(\n (file): FileOp => ({\n kind: \"write\",\n path: `${META_SCHEMA_DIR}/${file.name}`,\n contents: `${JSON.stringify(normalizePublicCliJson(file.body, ctx.cliVersion), null, 2)}\\n`,\n }),\n ),\n // Guidance for humans (README) and agents (AGENTS.md): the golden\n // journey and the customize→plan→apply loop. Marker-fenced managed\n // sections — existing content is never clobbered.\n {\n kind: \"edit\",\n path: \"AGENTS.md\",\n edit: (source) => upsertGuidanceSection(source, agentsGuidanceSection(ctx), AGENTS_HEADER),\n },\n {\n kind: \"edit\",\n path: \"README.md\",\n edit: (source) => upsertGuidanceSection(source, readmeGuidanceSection(ctx), README_HEADER),\n },\n ];\n }\n\n /** Framework-specific route/middleware write ops plus the SDK dependency. */\n protected abstract routeOps(ctx: PatchContext): ReadonlyArray<FileOp>;\n /** Framework-specific managed (marker-bearing) file paths, for ejection. */\n protected abstract routeFiles(view: PatchView): ReadonlyArray<string>;\n /**\n * The package-manager dependencies the integration added, surfaced in\n * `eject`'s `next_commands` so the user can uninstall them themselves.\n */\n protected abstract routeDeps(view: PatchView): ReadonlyArray<string>;\n /** One-line summary of what the integration scaffolded. */\n protected abstract summary(ctx: PatchContext): { title: string; detail: string };\n}\n\n/** Reads a text file, mapping every failure to `undefined`. */\nasync function readTextIfExists(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return undefined;\n }\n}\n\n/** Builds the `zitadel.json` body persisted at the project root. */\nfunction projectConfig(ctx: PatchContext): Record<string, unknown> {\n const environments: Record<string, unknown> = { development: { issuer: ctx.issuer } };\n if (ctx.project.preview_origins.length > 0) {\n // preview_origins are already full origins (scheme://host[:port]); don't\n // prepend a scheme or it doubles up (https://http://localhost:3000).\n environments.preview = {\n issuer_pattern: [...ctx.project.preview_origins],\n };\n }\n return {\n $schema: \"https://schemas.zitadel.com/v2/project.schema.json\",\n project: ctx.project.id,\n server: resolveServerOrigin(ctx.server),\n framework: { id: ctx.framework.id },\n branding: { renderer: ctx.rendererId, attribution: \"visible\" },\n environments,\n ...(ctx.preset === undefined ? {} : { preset: ctx.preset }),\n ...(ctx.useCase === undefined ? {} : { useCase: ctx.useCase }),\n };\n}\n\n/** Normalizes a server URL to its origin, falling back to {@link DEFAULT_SERVER}. */\nfunction resolveServerOrigin(source: string): string {\n try {\n return new URL(source).origin;\n } catch {\n return DEFAULT_SERVER;\n }\n}\n","import { ZitadelError } from \"../../../../errors\";\nimport { isObject, parseJsonObject } from \"../../../../json\";\n\n/**\n * Builds the pure `edit` transform the file-writer applies to `angular.json`:\n * wires a dev-server `proxyConfig` (and optional `port`) into the project's\n * `serve` target. The project name is discovered from the file (`defaultProject`,\n * else the sole project) rather than hardcoded, since it varies per app.\n * Idempotent — already-set values are left as-is. Throws `E_VALIDATION` when the\n * file is absent, the project/serve target cannot be located, or the workspace\n * has several projects with no `defaultProject` to disambiguate (rather than\n * guessing and wiring the proxy into an arbitrary one).\n */\nexport function angularProxyEdit(opts: {\n proxyConfig: string;\n port?: number;\n}): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"Cannot wire Angular proxy: angular.json not found\", {\n hint: \"Run setup from an Angular project.\",\n });\n }\n const root = parseJsonObject(source, \"angular.json\");\n const projects = isObject(root.projects)\n ? (root.projects as Record<string, unknown>)\n : undefined;\n const projectNames = Object.keys(projects ?? {});\n let projectName: string | undefined;\n if (typeof root.defaultProject === \"string\") {\n projectName = root.defaultProject;\n } else if (projectNames.length === 1) {\n projectName = projectNames[0];\n } else if (projectNames.length > 1) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"angular.json has multiple projects and no defaultProject to choose from\",\n {\n hint: `Set \"defaultProject\" in angular.json, or add \"proxyConfig\" to the right project's serve target manually. Projects: ${projectNames.join(\", \")}.`,\n },\n );\n }\n const project = projects && projectName ? projects[projectName] : undefined;\n if (!isObject(project)) {\n throw new ZitadelError(\"E_VALIDATION\", \"No project found in angular.json\", {\n hint: 'Add \"proxyConfig\" to your serve target manually.',\n });\n }\n // Angular CLI has used both \"architect\" and \"targets\" for the target map.\n const targets = isObject(project.architect)\n ? (project.architect as Record<string, unknown>)\n : isObject(project.targets)\n ? (project.targets as Record<string, unknown>)\n : undefined;\n const serve =\n targets && isObject(targets.serve) ? (targets.serve as Record<string, unknown>) : undefined;\n if (!serve) {\n throw new ZitadelError(\"E_VALIDATION\", \"No serve target in angular.json\", {\n hint: 'Add \"proxyConfig\" to your serve options manually.',\n });\n }\n const options = isObject(serve.options) ? (serve.options as Record<string, unknown>) : {};\n let changed = false;\n if (options.proxyConfig === undefined) {\n options.proxyConfig = opts.proxyConfig;\n changed = true;\n }\n if (opts.port !== undefined && options.port === undefined) {\n options.port = opts.port;\n changed = true;\n }\n // Nothing to add — return the source untouched so the edit op skips it\n // instead of reformatting (re-indenting) the user's angular.json.\n if (!changed) {\n return source;\n }\n serve.options = options;\n // Preserve the user's key order (JSON, no comments) instead of sorting.\n return `${JSON.stringify(root, null, 2)}\\n`;\n };\n}\n","import { parseModule } from \"magicast\";\n\nimport { ZitadelError } from \"../../../../errors\";\n\n/**\n * Generic magicast helpers shared by the config-editing patchers (Vite, Nuxt).\n * They navigate a module's default export — they carry no framework knowledge\n * beyond \"find the config object literal\" and \"is this import present\".\n */\n\n/**\n * Parses a config file with magicast, throwing a clean `E_VALIDATION` (instead\n * of a raw parse error) when the source is missing or unparseable. `filename` is\n * only used in the error message, so each patcher can name its own config file.\n */\nexport function parseConfigModule(\n source: string | undefined,\n filename: string,\n): ReturnType<typeof parseModule> {\n if (source === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", `Cannot edit ${filename}: file not found`, {\n hint: `Run setup from a project that has ${filename}.`,\n });\n }\n let mod: ReturnType<typeof parseModule>;\n try {\n mod = parseModule(source);\n } catch (error) {\n throw new ZitadelError(\"E_VALIDATION\", `Could not parse ${filename}`, {\n hint: `Ensure ${filename} is valid, or apply the Zitadel changes manually.`,\n details: { cause: error instanceof Error ? error.message : String(error) },\n });\n }\n // A CommonJS config (e.g. a `*.cjs` file or a `*.js` with `module.exports`)\n // can't evaluate the ESM `import`/`import.meta.url` these edits inject, so\n // reject it with a clear message instead of producing a broken config. Check\n // the parsed AST for a real `module.exports`/`exports.x` assignment — scanning\n // raw text would false-positive on the same string in a comment or literal.\n if (hasCommonJsExport(mod)) {\n throw new ZitadelError(\"E_VALIDATION\", `${filename} is a CommonJS module, which can't be edited`, {\n hint: `The Zitadel edits use ESM imports. Convert the config to ESM (a .ts/.mts file, or set \"type\": \"module\"), or add the Zitadel block manually.`,\n });\n }\n return mod;\n}\n\n/**\n * Whether the module has a top-level CommonJS export assignment —\n * `module.exports = …`, `module.exports.x = …`, or `exports.x = …` — read from\n * the parsed AST so comments and string literals can't trigger a false match.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction hasCommonJsExport(mod: any): boolean {\n // magicast's `$ast` may be a babel `File` (with `.program.body`) or the\n // `Program` node itself (`.body`) — handle both.\n const program = mod?.$ast?.program ?? mod?.$ast;\n const body = program?.body ?? [];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return body.some((node: any) => {\n if (node?.type !== \"ExpressionStatement\" || node.expression?.type !== \"AssignmentExpression\") {\n return false;\n }\n const left = node.expression.left;\n if (left?.type !== \"MemberExpression\") {\n return false;\n }\n const object = left.object;\n // `exports.x = …`\n if (object?.type === \"Identifier\" && object.name === \"exports\") {\n return true;\n }\n // `module.exports = …`\n if (object?.type === \"Identifier\" && object.name === \"module\" && left.property?.name === \"exports\") {\n return true;\n }\n // `module.exports.x = …`\n return (\n object?.type === \"MemberExpression\" &&\n object.object?.name === \"module\" &&\n object.property?.name === \"exports\"\n );\n });\n}\n\n/**\n * Reaches the object literal of a module's default export — the argument of\n * `export default <call>({...})` (e.g. `defineConfig`/`defineNuxtConfig`) or a\n * bare `export default {...}`. Throws `E_VALIDATION` for shapes magicast cannot\n * safely edit (function-form, configs built elsewhere) so the caller can fall\n * back to manual steps.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function resolveDefaultExportObject(mod: any, filename: string): any {\n const def = mod.exports?.default;\n const unreachable = () =>\n new ZitadelError(\"E_VALIDATION\", `Could not locate the config object in ${filename}`, {\n hint: `Add the Zitadel configuration to ${filename} manually (see the SDK README).`,\n });\n if (!def) {\n throw unreachable();\n }\n if (def.$type === \"function-call\") {\n const arg = def.$args?.[0];\n if (!arg || arg.$type !== \"object\") {\n throw unreachable();\n }\n return arg;\n }\n if (def.$type === \"object\") {\n return def;\n }\n throw unreachable();\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function importIsPresent(mod: any, local: string, from?: string): boolean {\n try {\n const items: ReadonlyArray<{ local?: string; from?: string }> = mod.imports?.$items ?? [];\n // Match the source module too when given, so a same-named local imported\n // from a different module isn't mistaken for the one we need.\n return items.some((item) => item.local === local && (from === undefined || item.from === from));\n } catch {\n return false;\n }\n}\n\n/**\n * Appends `item` to a string array at `parent[key]`, creating the array when\n * absent and skipping it when already present. Reads the proxified array by\n * index so primitive elements compare as plain values. Returns `true` when it\n * actually added the item, so callers can tell whether the edit changed\n * anything (and skip rewriting an already-complete config).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function ensureArrayItem(parent: any, key: string, item: string): boolean {\n if (parent[key] === undefined) {\n parent[key] = [item];\n return true;\n }\n const arr = parent[key];\n // The existing value is something other than an array literal (e.g. an\n // identifier or spread), which magicast cannot safely append to. Surface a\n // clean E_VALIDATION instead of letting `arr.push` throw a raw TypeError.\n if (typeof arr?.push !== \"function\" || typeof arr?.length !== \"number\") {\n throw new ZitadelError(\"E_VALIDATION\", `Could not add \"${item}\" to \"${key}\"`, {\n hint: `Add \"${item}\" to \"${key}\" in your config manually.`,\n });\n }\n const present = Array.from({ length: arr.length as number }, (_unused, i) => arr[i]).includes(\n item,\n );\n if (!present) {\n arr.push(item);\n return true;\n }\n return false;\n}\n\n/**\n * Returns the object literal at `parent[key]`, creating an empty one when\n * absent, so callers can safely descend into it. Throws `E_VALIDATION` when the\n * key already holds something that is not an inline object literal (an\n * identifier, spread, or function call) — magicast cannot edit those, and\n * assigning into them otherwise throws a raw proxy `TypeError`. The object\n * sibling of {@link ensureArrayItem}.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function ensureEditableObject(parent: any, key: string): any {\n if (parent[key] === undefined) {\n parent[key] = {};\n }\n const value = parent[key];\n if (value?.$type !== \"object\") {\n throw new ZitadelError(\"E_VALIDATION\", `Could not edit \"${key}\" in the config`, {\n hint: `Set \"${key}\" to an inline object literal, or add the Zitadel settings manually.`,\n });\n }\n return value;\n}\n","import { builders, generateCode } from \"magicast\";\n\nimport { ZitadelError } from \"../../../../errors\";\nimport { parseConfigModule } from \"../utils/magicast\";\n\nconst AUTH_ROUTE_PATHS = [\"login\", \"register\", \"profile\"] as const;\n\n/** 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","import { MANAGED_MARKER } from \"../../../../paths\";\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\nimport {\n assertNoUnreviewedProjectSecretProxy,\n PROXY_CREDENTIAL_POLICY_MARKER,\n} from \"../proxy-credential-policy\";\n\n/**\n * The managed root component `src/app/app.ts`: a standalone component that\n * renders the `@zitadel/sdk-angular` widgets based on the current path. The\n * project id (public, not secret) is inlined; the dev proxy in `proxy.conf.cjs`\n * attaches the project service-key secret as the bearer server-side only to\n * `POST /sessions/exchange` (read from `.env.local`), and no secret reaches\n * the browser.\n *\n * Projects set up with the business use case additionally expose the SDK's\n * `businessLocales` overlay as a class property, which `app.html` binds to the\n * login widgets via `[locales]` — restoring work-email copy on top of the\n * widget's neutral built-in dictionaries.\n */\nexport function appComponentTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? `\n ZitadelLoginComponent,\n ZitadelSessionComponent,\n businessLocales,\n configureZitadel,\n`\n : `\n ZitadelLoginComponent,\n ZitadelSessionComponent,\n configureZitadel,\n`;\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesProperty = business\n ? `\n // Set up for a business audience: businessLocales overlays work-email copy\n // on the login widget's neutral built-in dictionaries. Remove it (and the\n // [locales] binding in app.html) to fall back to the neutral wording.\n protected readonly locales = businessLocales;`\n : \"\";\n return `${MANAGED_MARKER}\nimport { Component, OnInit } from \"@angular/core\";\nimport {${importNames}} from \"@zitadel/sdk-angular\";\n\n@Component({\n selector: \"app-root\",\n standalone: true,\n imports: [ZitadelLoginComponent, ZitadelSessionComponent],\n templateUrl: \"./app.html\",\n})\nexport class App implements OnInit {\n protected readonly project = configureZitadel({\n projectId: ${JSON.stringify(ctx.project.id)},\n proxyPath: \"${PROXY_PATH}\",\n });\n protected readonly path = window.location.pathname;${localesProperty}\n\n ngOnInit(): void {\n if (this.path === \"/\") {\n window.location.replace(\"/login\");\n }\n }\n}\n`;\n}\n\n/**\n * The managed `src/app/app.html`. The marker lives in an HTML comment that still\n * contains the literal managed-marker text, so eject/doctor stay marker-aware.\n * Business-use-case scaffolds bind the component's `locales` overlay property\n * onto the login widgets.\n */\nexport function appTemplateHtml(ctx: PatchContext): string {\n const localesBinding = ctx.useCase === \"business\" ? `\\n [locales]=\"locales\"` : \"\";\n return `<!-- ${MANAGED_MARKER} -->\n@if (path.startsWith('/profile')) {\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <zitadel-auth-session\n [project]=\"project\"\n [postSignOutUrl]=\"'/login'\"\n ></zitadel-auth-session>\n </div>\n} @else if (path.startsWith('/register')) {\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <zitadel-auth-login\n [project]=\"project\"${localesBinding}\n purpose=\"register\"\n [postSignInUrl]=\"'/profile'\"\n ></zitadel-auth-login>\n </div>\n} @else {\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <zitadel-auth-login\n [project]=\"project\"${localesBinding}\n purpose=\"login\"\n [postSignInUrl]=\"'/profile'\"\n ></zitadel-auth-login>\n </div>\n}\n`;\n}\n\n/**\n * The managed `proxy.conf.cjs` for `ng serve`: forwards `/__nextgen/*` to the\n * backend and attaches the project's service-key secret only to the current\n * app-plane `POST /sessions/exchange` request. Both the backend URL\n * (`ZITADEL_URL`) and the secret\n * (`ZITADEL_PROJECT_SECRET`) are read from `.env.local`, which `zitadel setup`\n * writes and `.gitignore` excludes — Angular's CLI does not auto-load env files\n * into the dev-server process, so this file does it itself with a small inline\n * parser. The prefix strip and the bearer are each provided in both the\n * http-proxy-middleware form (`pathRewrite`/`onProxyReq`) and the Vite form\n * (`rewrite`/`configure`), so both fire whichever proxy layer Angular's\n * dev server uses.\n */\nexport function proxyConfTemplate(): string {\n return `${MANAGED_MARKER}\nconst { readFileSync, existsSync } = require(\"node:fs\");\n\nfunction loadEnvLocal() {\n if (!existsSync(\".env.local\")) return {};\n const out = {};\n for (const line of readFileSync(\".env.local\", \"utf8\").split(/\\\\r?\\\\n/)) {\n const m = line.match(/^\\\\s*(?:export\\\\s+)?([A-Z_][A-Z0-9_]*)\\\\s*=\\\\s*(.*)$/);\n if (m) {\n const raw = m[2].trim();\n const quoted = raw.match(/^(['\"])(.*)\\\\1\\\\s*(?:#.*)?$/);\n out[m[1]] = quoted ? quoted[2] : raw.replace(/\\\\s+#.*$/, \"\").trim();\n }\n }\n return out;\n}\n\nconst env = loadEnvLocal();\nconst server = process.env.ZITADEL_URL ?? env.ZITADEL_URL;\nconst secret = process.env.ZITADEL_PROJECT_SECRET ?? env.ZITADEL_PROJECT_SECRET;\nif (!server) {\n throw new Error(\"ZITADEL_URL is not set; add it to .env.local (zitadel setup writes it).\");\n}\nif (!secret) {\n throw new Error(\"ZITADEL_PROJECT_SECRET is not set; add it to .env.local (zitadel setup writes it).\");\n}\nconst bearer = \\`Bearer \\${secret}\\`;\n\n${EXCHANGE_ONLY_BEARER}\n\nfunction stripPrefix(path) {\n return path.replace(/^\\\\${PROXY_PATH}/, \"\").replace(/^(?!\\\\/)/, \"/\");\n}\n\nmodule.exports = {\n \"${PROXY_PATH}\": {\n target: server,\n changeOrigin: false,\n pathRewrite: stripPrefix,\n rewrite: stripPrefix,\n onProxyReq: setBearer,\n configure: (proxy) => proxy.on(\"proxyReq\", setBearer),\n },\n};\n`;\n}\n\nconst LEGACY_UNCONDITIONAL_BEARER = `function setBearer(proxyReq) {\n proxyReq.setHeader(\"authorization\", bearer);\n}`;\n\nconst EXCHANGE_ONLY_BEARER = `/* ${PROXY_CREDENTIAL_POLICY_MARKER} */\nfunction setBearer(proxyReq) {\n const pathname = new URL(proxyReq.path, \"http://zitadel.local\").pathname;\n if (\n proxyReq.method === \"POST\" &&\n pathname === \"/sessions/exchange\" &&\n !proxyReq.getHeader(\"authorization\")\n ) {\n proxyReq.setHeader(\"authorization\", bearer);\n }\n}`;\n\n/**\n * Creates the managed Angular proxy and upgrades the exact insecure hook the\n * CLI emitted before the exchange-only policy. Other edits are preserved; a\n * safe custom proxy is left untouched, while an unrecognized proxy that may\n * still over-forward the project secret is surfaced for manual review.\n */\nexport function proxyConfEdit(): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n return proxyConfTemplate();\n }\n if (source.includes(MANAGED_MARKER) && source.includes(LEGACY_UNCONDITIONAL_BEARER)) {\n return source.replace(LEGACY_UNCONDITIONAL_BEARER, EXCHANGE_ONLY_BEARER);\n }\n assertNoUnreviewedProjectSecretProxy(source, \"proxy.conf.cjs\");\n return source;\n };\n}\n","import { ZitadelError } from \"../../../../errors\";\nimport { isObject, parseJsonObject, setTopLevelJsonKey } from \"../../../../json\";\nimport { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { angularProxyEdit } from \"./angular-json\";\nimport { angularRoutesEdit } from \"./angular-routes\";\nimport { appComponentTemplate, appTemplateHtml, proxyConfEdit } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-angular\";\n\n/**\n * Adds a `dev: \"ng serve\"` script only when the project does not already define\n * one. `ng new` ships only a `start` script, but the CLI tells every framework\n * to run `npm run dev` (and `ng serve` reads the proxy + port from\n * `angular.json`). Non-destructive: an existing `dev` script is preserved, so\n * patching a project that already wires its own `dev` leaves it untouched.\n */\nfunction ensureDevScript(source: string | undefined): string {\n if (source === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"package.json is required to add the dev script\", {\n hint: \"Run setup from a project that has a package.json.\",\n });\n }\n const pkg = parseJsonObject(source, \"package.json\");\n const scripts = isObject(pkg.scripts) ? pkg.scripts : undefined;\n // Leave an existing dev script untouched, returning the source unchanged so\n // the edit op skips the file instead of reformatting the user's package.json.\n if (scripts?.dev !== undefined) {\n return source;\n }\n // package.json is user-owned: splice only the scripts value; every byte\n // outside it stays untouched.\n return setTopLevelJsonKey(source, \"package.json\", \"scripts\", {\n ...(scripts ?? {}),\n dev: \"ng serve\",\n });\n}\n\n/**\n * Rule-based patcher for an Angular app. Inherits the shared `.zitadel/` base\n * files from {@link AbstractRulePatcher} and contributes the managed root\n * component (`app.ts`/`app.html`) that renders the `@zitadel/sdk-angular`\n * widgets, a `proxy.conf.cjs` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`) wired into `angular.json`,\n * and the SDK dep.\n *\n * Unlike React/Vue (whose dev proxy lives in `vite.config.ts`), Angular owns its\n * Vite config, so the proxy is a separate `proxy.conf.cjs` referenced from the\n * `serve` target. In production the same-origin path comes from a platform\n * rewrite or minimal worker (ADR 036); CLI scaffolding for it is tracked in\n * issue #560.\n */\nexport class AngularPatcher extends AbstractRulePatcher {\n canPatch(framework: string): boolean {\n return framework === \"angular\";\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n {\n kind: \"write\",\n path: \"src/app/app.ts\",\n contents: appComponentTemplate(ctx),\n },\n { kind: \"write\", path: \"src/app/app.html\", contents: appTemplateHtml(ctx) },\n {\n kind: \"edit\",\n path: \"src/app/app.routes.ts\",\n edit: angularRoutesEdit(),\n // Without the auth routes the router bounces /login back to /.\n wiring: \"infrastructure\",\n },\n {\n kind: \"edit\",\n path: \"proxy.conf.cjs\",\n edit: proxyConfEdit(),\n // The transform creates the managed proxy when absent and safely\n // migrates the exact unconditional bearer hook emitted by older CLIs.\n wiring: \"infrastructure\",\n },\n {\n kind: \"edit\",\n path: \"angular.json\",\n edit: angularProxyEdit({ proxyConfig: \"proxy.conf.cjs\", port: ctx.framework.devPort }),\n // The serve target's proxyConfig is what attaches proxy.conf.cjs —\n // without it the proxy file is inert and auth requests fail.\n wiring: \"infrastructure\",\n },\n {\n kind: \"edit\",\n path: \"package.json\",\n edit: ensureDevScript,\n // Golden-path convenience (`npm run dev`); its absence only warns.\n wiring: \"convenience\",\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/app/app.ts\", \"src/app/app.html\", \"proxy.conf.cjs\"];\n }\n\n protected override infrastructureFiles(_view: PatchView): ReadonlyArray<string> {\n // The dev proxy is the auth request path (it also attaches the project\n // secret); the root component pair is the user's customization surface.\n return [\"proxy.conf.cjs\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n // These files are touched via `edit` ops eject can't auto-revert: the proxy\n // wired into angular.json, auth paths added to app.routes.ts, and the `dev`\n // script added to package.json.\n return [\"angular.json\", \"src/app/app.routes.ts\", \"package.json\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Angular integration\",\n detail:\n \"Wrote the app root component + proxy.conf.cjs, added auth routes, and wired the /__nextgen dev proxy into angular.json.\",\n };\n }\n}\n","import { ZitadelError } from \"../../../errors\";\nimport { isObject, parseJsonObject, setTopLevelJsonKey } from \"../../../json\";\nimport { extractPort, portFromIssuer, withDevPort } from \"../../detectors/port\";\nimport type { FileOp } from \"./file-writer/types\";\n\n/**\n * Pins the `dev` script to the port setup registered as the project's origin.\n *\n * Setup allows exactly one origin, `http://localhost:<devPort>`, so the dev\n * server has to land on that port or the flow API rejects the app mid-login\n * (the first step renders, the first submit 400s with `origin ... is not\n * allowed for this project`). Every other framework this CLI patches already\n * guarantees that in its own dev-server config — Vite gets `server.port` plus\n * `strictPort`, Angular gets `serve.options.port` — but `next dev` and\n * `nuxt dev` take their port from the command line, so nothing held them to\n * it: they default to 3000 regardless of the port setup registered.\n *\n * For Next the flag also restores the guarantee `strictPort` gives Vite: bare\n * `next dev` silently serves 3001 when 3000 is taken (measured), while\n * `next dev --port N` exits with `EADDRINUSE` instead of drifting onto a port\n * the project does not allow.\n *\n * Non-destructive: a script already on the right port is returned unchanged\n * (so the op skips the file rather than reformatting a user's package.json),\n * and a project without a `dev` script is left alone because there is no\n * command to pin.\n *\n * Takes the project's registered `issuer` rather than a port, because the\n * expected value has to survive the app drifting away from it. `doctor`\n * rebuilds this plan from `loadPatchContext`, whose `framework.devPort` is\n * freshly *detected* from the current script — deriving the target from that\n * would make any edited script verify against itself (always \"applied\") and\n * would make `doctor --fix` write back the detected fallback instead of the\n * port the project actually allows. The issuer comes from `zitadel.json`\n * (falling back to the scaffold manifest), so it still says 3456 after\n * someone edits the script to 4000. An issuer that names no port yields no\n * expectation and the op becomes a no-op.\n */\nexport function devScriptPortEdit(issuer: string): (source: string | undefined) => string {\n return (source) => {\n if (source === undefined) {\n throw new ZitadelError(\"E_VALIDATION\", \"package.json is required to pin the dev port\", {\n hint: \"Run setup from a project that has a package.json.\",\n });\n }\n const devPort = portFromIssuer(issuer);\n if (devPort === undefined) {\n return source;\n }\n const pkg = parseJsonObject(source, \"package.json\");\n const scripts = isObject(pkg.scripts) ? pkg.scripts : undefined;\n const dev = scripts?.dev;\n if (typeof dev !== \"string\" || dev.trim() === \"\") {\n return source;\n }\n if (extractPort(dev) === devPort) {\n return source;\n }\n // package.json is user-owned: splice only the scripts value; every byte\n // outside it stays untouched.\n return setTopLevelJsonKey(source, \"package.json\", \"scripts\", {\n ...scripts,\n dev: withDevPort(dev, devPort),\n });\n };\n}\n\n/**\n * The `package.json` op pinning the dev script's port. Marked as managed\n * wiring so `doctor` reports a dev script that drifted off the registered\n * origin — `convenience` (warn, not fail) because the script is only one of\n * the ways a dev server picks its port: `npm run dev -- --port 4000` still\n * moves it without touching the file, so a hard failure here would promise a\n * guarantee the check cannot make.\n */\nexport function devScriptPortOp(issuer: string): FileOp {\n return {\n kind: \"edit\",\n path: \"package.json\",\n edit: devScriptPortEdit(issuer),\n wiring: \"convenience\",\n };\n}\n","import { MANAGED_MARKER } from \"../../../../../../paths\";\nimport type { RendererSpec } from \"../types\";\n\n/**\n * Placeholder renderer for the `<zitadel-flow>` Lit web component. Declared\n * so the `web-component` renderer id resolves and surfaces a clear\n * \"not yet published\" error, while reserving the integration shape for when\n * `@zitadel/ui-lit` ships. The `authPage` template emits an illustrative\n * page only; this renderer is never selected for real scaffolding because\n * `getRenderer` rejects any `status: \"not-implemented\"` spec.\n */\nexport const litRenderer: RendererSpec = {\n id: \"web-component\",\n displayName: \"Web component (<zitadel-flow>)\",\n status: \"not-implemented\",\n frameworks: [\"next\", \"astro\", \"remix\", \"sveltekit\", \"nuxt\", \"vanilla\"],\n dependency: { name: \"@zitadel/ui-lit\", version: \"workspace:*\" },\n templates: {\n authPage(mode) {\n const purpose = mode === \"login\" ? \"login\" : \"register\";\n return {\n mode,\n contents: `${MANAGED_MARKER}\n// The web component renderer ships a <zitadel-flow> element. Until\n// @zitadel/ui-lit is published, this template only declares the\n// intended integration point. See docs/design/cli/bdui-renderer.md.\nimport \"@zitadel/ui-lit\";\n\nconst environment =\n process.env.ZITADEL_ENVIRONMENT ??\n (process.env.NODE_ENV === \"production\" ? \"production\" : \"development\");\n\nexport default function ${mode === \"login\" ? \"LoginPage\" : \"RegisterPage\"}() {\n return (\n <zitadel-flow\n purpose=\"${purpose}\"\n project-id={process.env.ZITADEL_PROJECT_ID}\n issuer={process.env.ZITADEL_ISSUER}\n environment={environment}\n />\n );\n}\n`,\n };\n },\n },\n};\n","import { MANAGED_MARKER } from \"../../../../../../paths\";\nimport type { RendererSpec } from \"../types\";\n\n/**\n * The Next.js App Router renderer scaffolds `/login`, `/register`, and\n * `/profile` pages that drive the `<zitadel-login>` and `<zitadel-session>`\n * Lit web components. `/profile` is the post-sign-in \"signed in as\" card.\n *\n * Each page is a single client component (`\"use client\"`) that, inside a\n * `next/dynamic({ ssr: false })` loader, builds the SDK project handle with\n * `configureZitadel({ projectId, proxyPath: \"/__nextgen\" })` and passes it to\n * the widget via `project={...}`. It also imports\n * `@zitadel/sdk-next/client` for its `customElements.define`\n * side-effect — importing `@zitadel/components` directly would fail on\n * strict-resolution package managers (pnpm, yarn PnP) because the app only\n * declares `sdk-next` as a direct dep. SSR is disabled because Lit's element\n * registration needs a browser.\n *\n * The handle is passed as the `project` DOM property, which relies on React\n * 19's custom-element property binding (the scaffold targets the latest Next /\n * React). The backend URL never reaches the browser: the client talks to the\n * same-origin `/__nextgen` proxy path, and the scaffolded Next request boundary\n * forwards it to `ZITADEL_URL` server-side. `NEXT_PUBLIC_ZITADEL_PROJECT_ID` is\n * public — the project id is not sensitive and the widget needs it to start a\n * flow.\n *\n * Projects set up with the business use case additionally wire the SDK's\n * `businessLocales` overlay onto the auth pages, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. The overlay is assigned\n * via a ref callback, not a JSX prop: sdk-next supports React >=18, and only\n * React 19 binds non-primitive custom-element props as properties — on 18 a\n * `locales={...}` prop would decay to a useless attribute and silently keep\n * the neutral copy (the `project` prop tolerates this because\n * `configureZitadel()` registers a global fallback; `locales` has none).\n */\nexport const reactRenderer: RendererSpec = {\n id: \"react\",\n displayName: \"React (Next.js App Router)\",\n status: \"available\",\n frameworks: [\"next\"],\n dependency: { name: \"@zitadel/sdk-next\", version: \"latest\" },\n templates: {\n authPage(mode, context) {\n const componentName = mode === \"login\" ? \"LoginPage\" : \"RegisterPage\";\n const elementName = mode === \"login\" ? \"ZitadelLogin\" : \"ZitadelRegister\";\n // The business use case restores the work-email framing the widget's\n // neutral built-in copy dropped; the overlay ships with the SDK, so the\n // generated page only wires it up (and stays plain otherwise).\n const business = context.useCase === \"business\";\n const importNames = business ? \"businessLocales, configureZitadel\" : \"configureZitadel\";\n const localesComment = business\n ? `\n // Set up for a business audience: businessLocales overlays work-email\n // copy on the widget's neutral built-in dictionaries. It is assigned\n // through the ref because React binds non-primitive custom-element\n // props as properties only from v19 — the ref works on React 18 too.\n // Remove the assignment to fall back to the neutral wording.`\n : \"\";\n const localesAttr = business\n ? `\n ref={(element) => {\n if (element) {\n element.locales = businessLocales;\n }\n }}`\n : \"\";\n // Pre-existing apps embed the card in their own layout (ADR 044); a\n // fresh scaffold keeps the widget's full-page chrome.\n const widget = context.posture === \"widget\";\n const variantAttrs = widget ? `variant=\"widget\"\\n theme=\"auto\"` : `variant=\"page\"`;\n const postureComment = widget\n ? ` // variant=\"widget\" embeds the sign-in card in this app's existing layout.\n // theme=\"auto\" follows the OS light/dark preference (prefers-color-scheme),\n // not this app's own theme — set theme=\"light\" or theme=\"dark\" to match an\n // app that pins its scheme. The wrapper below only centers the card —\n // restyle or replace it freely. Switch to variant=\"page\" for the widget's\n // own full-page chrome (viewport height, surface background from design\n // tokens).\n // If this page already carries its own heading, add suppress-header to the\n // element to visually hide the widget's heading block — it stays in the\n // accessibility tree, and the card keeps no blank header band.`\n : ` // variant=\"page\" makes the widget paint the full-page chrome itself\n // (viewport height, surface background) from design tokens; switch to\n // variant=\"widget\" to embed the sign-in card inside a layout you own.`;\n const wrapperOpen = widget\n ? `<div style={{ display: \"flex\", justifyContent: \"center\", padding: \"4rem 1rem\" }}>`\n : `<main style={{ colorScheme: \"dark\" }}>`;\n const wrapperClose = widget ? `</div>` : `</main>`;\n return {\n mode,\n contents: `${MANAGED_MARKER}\n\"use client\";\n\nimport dynamic from \"next/dynamic\";\n\nconst ${elementName} = dynamic(\n async () => {\n const { ${importNames} } = await import(\"@zitadel/sdk-next/client\");\n // Build the SDK project handle and pass it to the component via the\n // \\`project\\` prop. The component reads config from this prop directly, so\n // it works regardless of how the SDK packages are bundled. The backend URL\n // stays server-side: requests go through the proxy path \"/__nextgen\",\n // which the scaffolded request boundary forwards to the Zitadel server.\n const project = configureZitadel({\n projectId: process.env.NEXT_PUBLIC_ZITADEL_PROJECT_ID ?? \"\",\n proxyPath: \"/__nextgen\",\n });\n return function ${elementName}Element() {${localesComment}\n return (\n <zitadel-login\n ${variantAttrs}${localesAttr}\n project={project}\n purpose=\"${mode}\"\n post-sign-in-url=\"/profile\"\n />\n );\n };\n },\n { ssr: false },\n);\n\nexport default function ${componentName}() {\n${postureComment}\n return (\n ${wrapperOpen}\n <${elementName} />\n ${wrapperClose}\n );\n}\n`,\n };\n },\n profilePage(context) {\n // Same posture hinge as the auth pages (ADR 044): a pre-existing app\n // gets the session card embedded in its own layout.\n const widget = context.posture === \"widget\";\n const variantAttrs = widget ? `variant=\"widget\"\\n theme=\"auto\"` : `variant=\"page\"`;\n const postureComment = widget\n ? ` // variant=\"widget\" embeds the session card in this app's existing layout.\n // theme=\"auto\" follows the OS light/dark preference (prefers-color-scheme),\n // not this app's own theme — set theme=\"light\" or theme=\"dark\" to match an\n // app that pins its scheme. The wrapper below only centers the card —\n // restyle or replace it freely. Switch to variant=\"page\" for the card's\n // own full-page chrome (viewport height, surface background from design\n // tokens).\n // If this page already carries its own heading, add suppress-header to the\n // element to visually hide the widget's heading block — it stays in the\n // accessibility tree, and the card keeps no blank header band.`\n : ` // variant=\"page\" makes the session card paint the full-page chrome itself\n // (viewport height, surface background) from design tokens; switch to\n // variant=\"widget\" to embed the card inside a layout you own.`;\n const wrapperOpen = widget\n ? `<div style={{ display: \"flex\", justifyContent: \"center\", padding: \"4rem 1rem\" }}>`\n : `<main style={{ colorScheme: \"dark\" }}>`;\n const wrapperClose = widget ? `</div>` : `</main>`;\n return {\n contents: `${MANAGED_MARKER}\n\"use client\";\n\nimport dynamic from \"next/dynamic\";\n\nconst ZitadelSession = dynamic(\n async () => {\n const { configureZitadel } = await import(\"@zitadel/sdk-next/client\");\n // Build the SDK project handle and pass it to the session card via the\n // \\`project\\` prop. The card reads identity from \"/__nextgen/sessions/me\"\n // and exposes a Sign out action. Your own components (a header, an\n // account menu) can make the same read with getSession() from\n // \"@zitadel/sdk-next/session\" to swap sign-in CTAs for account chrome.\n const project = configureZitadel({\n projectId: process.env.NEXT_PUBLIC_ZITADEL_PROJECT_ID ?? \"\",\n proxyPath: \"/__nextgen\",\n });\n return function ZitadelSessionElement() {\n return (\n <zitadel-session\n ${variantAttrs}\n project={project}\n post-sign-out-url=\"/login\"\n />\n );\n };\n },\n { ssr: false },\n);\n\nexport default function ProfilePage() {\n${postureComment}\n return (\n ${wrapperOpen}\n <ZitadelSession />\n ${wrapperClose}\n );\n}\n`,\n };\n },\n customElementsDts() {\n return {\n contents: `${MANAGED_MARKER}\n// React JSX declarations for the <zitadel-*> custom elements ship with the\n// SDK, so the scaffold stays aligned with the real element surface instead\n// of carrying a hand-maintained copy that drifts.\n/// <reference types=\"@zitadel/sdk-next/jsx\" />\n`,\n };\n },\n },\n};\n","import { ZitadelError } from \"../../../../../errors\";\nimport { litRenderer } from \"./lit\";\nimport { reactRenderer } from \"./react\";\nimport type { RendererId, RendererSpec } from \"./types\";\n\n/**\n * Runtime mirror of the {@link RendererId} union, used by {@link isRendererId}\n * to validate untrusted strings (a TS union has no runtime presence). Must stay\n * in sync with the {@link RendererId} type.\n */\nexport const RENDERER_IDS: RendererId[] = [\"react\", \"web-component\"];\n\n/**\n * Type guard narrowing an arbitrary value to a {@link RendererId}, used to\n * validate renderer ids read from config before indexing {@link RENDERERS}.\n */\nexport function isRendererId(value: unknown): value is RendererId {\n return typeof value === \"string\" && (RENDERER_IDS as string[]).includes(value);\n}\n\n/**\n * The single source of truth mapping each {@link RendererId} to its spec.\n * Keyed by id so {@link getRenderer} can look up and validate a renderer\n * chosen from persisted config (an arbitrary string) at runtime.\n */\nexport const RENDERERS: Record<RendererId, RendererSpec> = {\n react: reactRenderer,\n \"web-component\": litRenderer,\n};\n\n/**\n * The subset of {@link RENDERER_IDS} that {@link getRenderer} resolves rather\n * than rejects (`status: \"available\"`). Anything advertising renderer choices\n * — flag options, error hints — must derive from this list, not\n * {@link RENDERER_IDS}: a declared-but-unpublished renderer (ADR 006) keeps\n * its registry entry to reserve the id, but must never be offered as a usable\n * value.\n */\nexport const AVAILABLE_RENDERER_IDS: RendererId[] = RENDERER_IDS.filter(\n (id) => RENDERERS[id].status === \"available\",\n);\n\n/**\n * Resolves a renderer id (an untrusted string from config) to its spec,\n * throwing a typed {@link ZitadelError} rather than returning `undefined`\n * so callers get an actionable message. Rejects ids that are unknown\n * (`E_VALIDATION`) or declared-but-unpublished (`E_NOT_IMPLEMENTED`),\n * guaranteeing the returned spec is safe to scaffold from.\n */\nexport function getRenderer(id: string): RendererSpec {\n if (!isRendererId(id)) {\n throw new ZitadelError(\"E_VALIDATION\", `Unknown renderer \"${id}\"`, {\n hint: `Available renderers: ${AVAILABLE_RENDERER_IDS.join(\", \")}`,\n });\n }\n const renderer = RENDERERS[id];\n if (renderer.status === \"not-implemented\") {\n throw new ZitadelError(\n \"E_NOT_IMPLEMENTED\",\n `Renderer \"${id}\" is declared but not yet published`,\n {\n hint: \"Use --renderer react for now; the <zitadel-flow> web component ships in a later package.\",\n },\n );\n }\n return renderer;\n}\n","import { join } from \"node:path\";\n\nimport { MANAGED_MARKER } from \"../../../../paths\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { devScriptPortOp } from \"../dev-script-port\";\nimport { getRenderer } from \"./renderers/registry\";\nimport type { RendererSpec } from \"./renderers/types\";\n\n/**\n * Next.js request-boundary file at the project root. Wires `nextgenMiddleware` so the\n * generated project config's `/__nextgen` proxy path is same-origin proxied\n * to `ZITADEL_URL` and `/profile` is gated. Next 16 renamed this convention to\n * `proxy.ts`; older projects keep `middleware.ts`.\n * Carries the managed marker so `doctor --fix` reclaims it and `eject` removes it.\n */\nfunction requestBoundaryTemplate(functionName: \"middleware\" | \"proxy\"): string {\n return `${MANAGED_MARKER}\nimport { nextgenMiddleware } from \"@zitadel/sdk-next/middleware\";\nimport type { NextRequest } from \"next/server\";\n\nexport function ${functionName}(req: NextRequest) {\n return nextgenMiddleware(req, {\n url: process.env.ZITADEL_URL,\n protectedRoutes: [\"/profile\"],\n loginPath: \"/login\",\n });\n}\n\nexport const config = {\n matcher: [\"/__nextgen/:path*\", \"/profile/:path*\"],\n};\n`;\n}\n\n/**\n * Rule-based patcher for the Next.js App Router. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * Next routes and request boundary whose templates come from the chosen renderer.\n */\nexport class NextPatcher extends AbstractRulePatcher {\n /** Returns true for Next.js projects. */\n canPatch(framework: string): boolean {\n return framework === \"next\";\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return nextCodeOps(ctx, getRenderer(ctx.rendererId));\n }\n\n protected routeFiles(view: PatchView): ReadonlyArray<string> {\n return nextCodeFilePaths(view.framework, getRenderer(view.rendererId));\n }\n\n protected override infrastructureFiles(view: PatchView): ReadonlyArray<string> {\n return nextInfrastructureFilePaths(view.framework, getRenderer(view.rendererId));\n }\n\n protected override conditionallyScaffoldedFiles(view: PatchView): ReadonlyArray<string> {\n // Written only when setup created the app skeleton itself; on a\n // pre-existing app the homepage stays user-owned (see nextCodeOps).\n return [join(view.framework.appDir, \"page.tsx\")];\n }\n\n protected override retiredAlternateFiles(\n view: PatchView,\n ): Readonly<Record<string, ReadonlyArray<string>>> {\n // Next renamed the request boundary in v16 (middleware.ts → proxy.ts)\n // and throws at build time when both exist — but only in the ≥16\n // direction. On Next 15, proxy.ts was not a reserved convention, so a\n // root proxy.ts there is the user's own file, never a conflicting\n // boundary. Declaring the alternate one-way keeps a healthy Next 15 app\n // with an unrelated proxy.ts passing.\n const current = requestBoundaryFile(view.framework).filename;\n if (current !== \"proxy.ts\") {\n return {};\n }\n return {\n [join(view.framework.appDir, \"../proxy.ts\")]: [\n join(view.framework.appDir, \"../middleware.ts\"),\n ],\n };\n }\n\n protected routeDeps(view: PatchView): ReadonlyArray<string> {\n return [getRenderer(view.rendererId).dependency.name];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n // The `dev` script gets the project's dev-server port pinned into it via\n // an `edit` op eject can't auto-revert, so it has to be surfaced as a\n // manual cleanup step like any other in-place config merge.\n return [\"package.json\"];\n }\n\n protected summary(ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Next.js integration\",\n detail: `Scaffolded login/register/profile routes with renderer \"${ctx.rendererId}\".`,\n };\n }\n}\n\n/**\n * Ordered paths of the framework code files the patcher writes. All carry the\n * managed marker. Shared by {@link NextPatcher.routeOps} (which adds contents)\n * and {@link NextPatcher.routeFiles} (which only needs the paths) so the two\n * cannot drift.\n */\nfunction nextCodeFilePaths(\n framework: PatchView[\"framework\"],\n renderer: RendererSpec,\n): ReadonlyArray<string> {\n const appDir = framework.appDir;\n const paths = [\n join(appDir, \"page.tsx\"),\n join(appDir, \"login/page.tsx\"),\n join(appDir, \"register/page.tsx\"),\n ];\n if (renderer.templates.profilePage) {\n paths.push(join(appDir, \"profile/page.tsx\"));\n }\n paths.push(join(appDir, `../${requestBoundaryFile(framework).filename}`));\n if (renderer.templates.provider) {\n paths.push(join(appDir, renderer.templates.provider.filename));\n }\n if (renderer.templates.customElementsDts) {\n paths.push(join(appDir, \"../custom-elements.d.ts\"));\n }\n return paths;\n}\n\n/**\n * The subset of {@link nextCodeFilePaths} that is load-bearing for the auth\n * integration rather than a presentation starting point: the request boundary\n * (proxy/middleware), the provider file, and the custom-elements declarations.\n * Shares path construction with {@link nextCodeFilePaths} so the two cannot\n * drift; the `doctor` managed-files check fails when one of these is missing.\n */\nfunction nextInfrastructureFilePaths(\n framework: PatchView[\"framework\"],\n renderer: RendererSpec,\n): ReadonlyArray<string> {\n const appDir = framework.appDir;\n const paths = [join(appDir, `../${requestBoundaryFile(framework).filename}`)];\n if (renderer.templates.provider) {\n paths.push(join(appDir, renderer.templates.provider.filename));\n }\n if (renderer.templates.customElementsDts) {\n paths.push(join(appDir, \"../custom-elements.d.ts\"));\n }\n return paths;\n}\n\n/** The Next route/request-boundary write ops plus the SDK dependency. */\nfunction nextCodeOps(ctx: PatchContext, renderer: RendererSpec): FileOp[] {\n const appDir = ctx.framework.appDir;\n const pageContext = { useCase: ctx.useCase, posture: ctx.posture };\n const profile = renderer.templates.profilePage?.(pageContext);\n const provider = renderer.templates.provider;\n const dts = renderer.templates.customElementsDts?.();\n const boundary = requestBoundaryFile(ctx.framework);\n return [\n ctx.scaffoldedFramework\n ? {\n kind: \"edit\",\n path: join(appDir, \"page.tsx\"),\n edit: () => homePageTemplate(),\n // Replaces create-next-app's default homepage wholesale; the\n // missing-only repair path must not replay it over user content.\n overwrites: true,\n }\n : undefined,\n {\n kind: \"write\",\n path: join(appDir, \"login/page.tsx\"),\n contents: renderer.templates.authPage(\"login\", pageContext).contents,\n },\n {\n kind: \"write\",\n path: join(appDir, \"register/page.tsx\"),\n contents: renderer.templates.authPage(\"register\", pageContext).contents,\n },\n profile\n ? { kind: \"write\", path: join(appDir, \"profile/page.tsx\"), contents: profile.contents }\n : undefined,\n {\n kind: \"write\",\n path: join(appDir, `../${boundary.filename}`),\n contents: requestBoundaryTemplate(boundary.functionName),\n },\n provider\n ? { kind: \"write\", path: join(appDir, provider.filename), contents: provider.contents }\n : undefined,\n dts\n ? { kind: \"write\", path: join(appDir, \"../custom-elements.d.ts\"), contents: dts.contents }\n : undefined,\n // Next.js exposes NEXT_PUBLIC_-prefixed vars to client code.\n { kind: \"merge-env\", path: \".env.example\", entries: { NEXT_PUBLIC_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { NEXT_PUBLIC_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: renderer.dependency.name,\n version: dependencyVersionForCli(ctx.cliVersion, renderer.dependency.version),\n },\n // `next dev` takes its port from the command line only, so without this\n // the app can serve a port the project does not allow as an origin.\n devScriptPortOp(ctx.issuer),\n ].filter((op): op is FileOp => op !== undefined);\n}\n\nfunction homePageTemplate(): string {\n return `${MANAGED_MARKER}\nimport { redirect } from \"next/navigation\";\n\nexport default function Home() {\n redirect(\"/login\");\n}\n`;\n}\n\nfunction requestBoundaryFile(framework: PatchContext[\"framework\"]): {\n filename: \"middleware.ts\" | \"proxy.ts\";\n functionName: \"middleware\" | \"proxy\";\n} {\n if ((framework.versionMajor ?? 0) >= 16) {\n return { filename: \"proxy.ts\", functionName: \"proxy\" };\n }\n return { filename: \"middleware.ts\", functionName: \"middleware\" };\n}\n\nfunction dependencyVersionForCli(cliVersion: string, fallback: string): string {\n const normalized = cliVersion.trim().replace(/^v/, \"\");\n if (/^\\d+\\.\\d+\\.\\d+-alpha\\.\\d+$/.test(normalized)) {\n return normalized;\n }\n const prerelease = normalized.match(/^\\d+\\.\\d+\\.\\d+-([0-9A-Za-z]+)(?:[.-]|$)/)?.[1];\n return prerelease ?? fallback;\n}\n","/**\n * The module extensions the config edits can actually write, in resolution\n * priority. magicast injects ESM `import`/`import.meta.url`, so only ESM-capable\n * extensions are editable; CommonJS (`cts`/`cjs`) is not.\n */\nconst CONFIG_EXTENSIONS = [\"ts\", \"mts\", \"js\", \"mjs\"] as const;\n\n/**\n * The CommonJS extensions we still *probe* (after the ESM ones) so a project\n * whose only config is `*.cjs`/`*.cts` is found and rejected with a targeted\n * \"CommonJS is unsupported\" error, rather than a misleading \"file not found\".\n * {@link parseConfigModule} surfaces that error when it sees CommonJS source.\n */\nconst COMMONJS_EXTENSIONS = [\"cts\", \"cjs\"] as const;\n\n/**\n * Candidate config filenames for `basename`, ESM extensions first then the\n * CommonJS ones, e.g. `configCandidates(\"vite.config\")` → `[\"vite.config.ts\",\n * \"vite.config.mts\", \"vite.config.js\", \"vite.config.mjs\", \"vite.config.cts\",\n * \"vite.config.cjs\"]`. Handed to the\n * generic `edit` file-op, which patches the first one that exists — an ESM\n * config wins, and a CommonJS-only project is still read so the edit can emit a\n * clear unsupported-format error.\n */\nexport function configCandidates(basename: string): string[] {\n return [...CONFIG_EXTENSIONS, ...COMMONJS_EXTENSIONS].map((ext) => `${basename}.${ext}`);\n}\n","import { builders, generateCode } from \"magicast\";\n\nimport {\n ensureArrayItem,\n ensureEditableObject,\n parseConfigModule,\n resolveDefaultExportObject,\n} from \"../utils/magicast\";\nimport { PROXY_PATH } from \"../proxy\";\n\nconst NUXT_MODULE = \"@zitadel/sdk-nuxt/module\";\n\n/**\n * Builds the pure `edit` transform the file-writer applies to the project's Nuxt\n * config (`nuxt.config.*`): registers the `@zitadel/sdk-nuxt` module (which wires\n * the server-side proxy + session middleware), sets the login path, seeds\n * `runtimeConfig` with the backend URL, the proxy path, and the project id, and\n * marks the `zitadel-*` Lit elements as custom elements for the Vue compiler —\n * preserving the user's existing config via magicast. Idempotent. Throws\n * `E_VALIDATION` when the file is absent or `defineNuxtConfig` cannot be reached.\n */\nexport function nuxtConfigEdit(opts: {\n projectId: string;\n server: string;\n}): (source: string | undefined) => string {\n return (source) => {\n const label = \"the Nuxt config (nuxt.config.*)\";\n const mod = parseConfigModule(source, label);\n const config = resolveDefaultExportObject(mod, label);\n\n let changed = ensureArrayItem(config, \"modules\", NUXT_MODULE);\n\n const nextgen = ensureEditableObject(config, \"nextgen\");\n if (nextgen.url === undefined) {\n nextgen.url = builders.raw(\n `process.env.ZITADEL_URL ?? ${JSON.stringify(opts.server)}`,\n );\n changed = true;\n }\n if (nextgen.loginPath === undefined) {\n nextgen.loginPath = \"/login\";\n changed = true;\n }\n if (nextgen.protectedRoutes === undefined) {\n nextgen.protectedRoutes = [\"/profile\"];\n changed = true;\n }\n\n const runtimeConfig = ensureEditableObject(config, \"runtimeConfig\");\n if (runtimeConfig.zitadelUrl === undefined) {\n runtimeConfig.zitadelUrl = builders.raw(\n `process.env.ZITADEL_URL ?? ${JSON.stringify(opts.server)}`,\n );\n changed = true;\n }\n const publicConfig = ensureEditableObject(runtimeConfig, \"public\");\n if (publicConfig.nextgenProxyPath === undefined) {\n publicConfig.nextgenProxyPath = PROXY_PATH;\n changed = true;\n }\n if (publicConfig.zitadelProjectId === undefined) {\n publicConfig.zitadelProjectId = builders.raw(\n `process.env.NUXT_PUBLIC_ZITADEL_PROJECT_ID ?? ${JSON.stringify(opts.projectId)}`,\n );\n changed = true;\n }\n\n // The Lit components and their style/token deps must be transpiled for SSR\n // (matching the repo's own demo-nuxt config) or the build fails on the\n // untranspiled ESM those transitive packages ship.\n const build = ensureEditableObject(config, \"build\");\n for (const dep of [\n \"@zitadel/api\",\n \"@zitadel/components\",\n \"@zitadel/design-tokens\",\n ]) {\n if (ensureArrayItem(build, \"transpile\", dep)) {\n changed = true;\n }\n }\n\n // Tell Vue's template compiler the `zitadel-*` Lit elements are custom\n // elements, not Vue components, so it renders them as native elements\n // instead of logging \"Failed to resolve component\" and mis-binding props.\n const vue = ensureEditableObject(config, \"vue\");\n const compilerOptions = ensureEditableObject(vue, \"compilerOptions\");\n if (compilerOptions.isCustomElement === undefined) {\n compilerOptions.isCustomElement = builders.raw(`(tag) => tag.startsWith(\"zitadel-\")`);\n changed = true;\n }\n\n // Nothing was missing — return the source untouched so the file-writer skips\n // it instead of letting magicast reformat an already-patched config.\n if (!changed && source !== undefined) {\n return source;\n }\n const code = generateCode(mod).code;\n return code.endsWith(\"\\n\") ? code : `${code}\\n`;\n };\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\nimport type { PatchContext } from \"../../types\";\n\n/** `app.vue` — renders the page router. Marker in an HTML comment. */\nexport function appVueTemplate(): string {\n return `<!-- ${MANAGED_MARKER} -->\n<template>\n <NuxtPage />\n</template>\n\n<style>\n:root {\n color-scheme: dark;\n}\nbody {\n margin: 0;\n background: #0f0f11;\n color: #f4f4f6;\n font-family: sans-serif;\n}\n</style>\n`;\n}\n\n/** `pages/index.vue` — redirects the app root to `/login`. */\nexport function indexPageTemplate(): string {\n return `<script setup lang=\"ts\">\n${MANAGED_MARKER}\nawait navigateTo(\"/login\", { replace: true });\n</script>\n`;\n}\n\n/**\n * A login/register page rendering `<zitadel-login>` inside `<ClientOnly>`.\n * Business-use-case projects additionally bind the SDK's `businessLocales`\n * overlay, restoring work-email copy on top of the widget's neutral built-in\n * dictionaries. A plain `:locales` binding suffices even on the raw custom\n * element: Vue sets bindings whose key exists on the element as DOM\n * properties (unlike React 18, which is why the Next template needs a ref).\n */\nfunction authPage(purpose: \"login\" | \"register\", ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business ? \"businessLocales, useZitadelProject\" : \"useZitadelProject\";\n // The overlay ships with the SDK, so the generated page only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the :locales\n// binding to fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? '\\n :locales=\"businessLocales\"' : \"\";\n const purposeAttr = purpose === \"register\" ? '\\n purpose=\"register\"' : \"\";\n // Posture (ADR 044): page posture paints the widget's full-page chrome and\n // pins the color scheme via the <main> wrapper; widget posture embeds the\n // card in the host app's own layout inside a layout-neutral centered <div>.\n const widget = ctx.posture === \"widget\";\n const variantAttrs = widget ? 'variant=\"widget\"\\n theme=\"auto\"' : 'variant=\"page\"';\n const postureComment = widget\n ? `<!-- variant=\"widget\" embeds the card in this app's own layout.\n theme=\"auto\" follows the OS light/dark preference\n (prefers-color-scheme), not the app's own theme — set\n theme=\"light\" or theme=\"dark\" to match an app that pins its\n scheme. variant=\"page\" would paint the widget's full-page\n chrome instead. -->`\n : `<!-- variant=\"page\" paints the widget's full-page chrome from design\n tokens; variant=\"widget\" embeds the card inside a layout you own. -->`;\n const wrapperOpen = widget\n ? '<div style=\"display: flex; justify-content: center; padding: 4rem 1rem\">'\n : '<main style=\"color-scheme: dark\">';\n const wrapperClose = widget ? \"</div>\" : \"</main>\";\n return `<script setup lang=\"ts\">\n${MANAGED_MARKER}\nimport { ${importNames} } from \"@zitadel/sdk-nuxt\";${localesComment}\n\nconst project = useZitadelProject();\n</script>\n\n<template>\n ${wrapperOpen}\n <ClientOnly>\n ${postureComment}\n <zitadel-login\n ${variantAttrs}\n :project=\"project\"${localesAttr}${purposeAttr}\n post-sign-in-url=\"/profile\"\n />\n </ClientOnly>\n ${wrapperClose}\n</template>\n`;\n}\n\nexport function loginPageTemplate(ctx: PatchContext): string {\n return authPage(\"login\", ctx);\n}\n\nexport function registerPageTemplate(ctx: PatchContext): string {\n return authPage(\"register\", ctx);\n}\n\n/** `pages/profile.vue` — the post-sign-in \"signed in as\" session card. */\nexport function profilePageTemplate(ctx: PatchContext): string {\n // Same posture hinge as the auth pages (ADR 044).\n const widget = ctx.posture === \"widget\";\n const variantAttrs = widget ? 'variant=\"widget\"\\n theme=\"auto\"' : 'variant=\"page\"';\n const postureComment = widget\n ? `<!-- variant=\"widget\" embeds the session card in this app's own layout.\n theme=\"auto\" follows the OS light/dark preference\n (prefers-color-scheme), not the app's own theme — set\n theme=\"light\" or theme=\"dark\" to match an app that pins its\n scheme. variant=\"page\" would paint the card's full-page chrome\n instead. Your own components (a header, an account menu) read\n the same session state with the auto-imported useAuth()\n composable. -->`\n : `<!-- variant=\"page\" paints the session card's full-page chrome from design\n tokens; variant=\"widget\" embeds the card inside a layout you own.\n Your own components (a header, an account menu) read the same session\n state with the auto-imported useAuth() composable. -->`;\n const wrapperOpen = widget\n ? '<div style=\"display: flex; justify-content: center; padding: 4rem 1rem\">'\n : '<main style=\"color-scheme: dark\">';\n const wrapperClose = widget ? \"</div>\" : \"</main>\";\n const element = widget\n ? `<zitadel-session\n ${variantAttrs}\n :project=\"project\"\n post-sign-out-url=\"/login\"\n />`\n : `<zitadel-session variant=\"page\" :project=\"project\" post-sign-out-url=\"/login\" />`;\n return `<script setup lang=\"ts\">\n${MANAGED_MARKER}\nimport { useZitadelProject } from \"@zitadel/sdk-nuxt\";\n\nconst project = useZitadelProject();\n</script>\n\n<template>\n ${wrapperOpen}\n <ClientOnly>\n ${postureComment}\n ${element}\n </ClientOnly>\n ${wrapperClose}\n</template>\n`;\n}\n\n/** `plugins/zitadel-components.client.ts` — register the Lit elements client-side. */\nexport function componentsPluginTemplate(): string {\n return `${MANAGED_MARKER}\n// Register Lit custom elements on the client only. Importing @zitadel/components\n// from a page <script setup> would run during SSR and break the widgets.\nimport \"@zitadel/components\";\n\nexport default defineNuxtPlugin(() => {});\n`;\n}\n\n/** `plugins/auth.server.ts` — seed the client auth state from the server context. */\nexport function authPluginTemplate(): string {\n return `${MANAGED_MARKER}\nimport { defineNuxtPlugin, useRequestEvent, useState } from \"#imports\";\nimport type { ClientAuthResult } from \"@zitadel/sdk-nuxt\";\n\nexport default defineNuxtPlugin(() => {\n const event = useRequestEvent();\n const auth = event?.context.nextgenAuth ?? {\n isAuthenticated: false as const,\n session: null,\n };\n\n // Strip the raw JWT before seeding useState — it must not appear in the SSR\n // payload where client-side scripts could read it.\n const clientAuth: ClientAuthResult = auth.isAuthenticated\n ? {\n isAuthenticated: true,\n session: {\n userId: auth.session.userId,\n identifier: auth.session.identifier,\n identifierProperty: auth.session.identifierProperty,\n display: auth.session.display,\n },\n }\n : { isAuthenticated: false, session: null };\n\n useState<ClientAuthResult>(\"nextgen-auth\", () => clientAuth);\n});\n`;\n}\n","import { join } from \"node:path\";\n\nimport { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport { configCandidates } from \"../config-paths\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { devScriptPortOp } from \"../dev-script-port\";\nimport { nuxtConfigEdit } from \"./nuxt-config\";\nimport {\n appVueTemplate,\n authPluginTemplate,\n componentsPluginTemplate,\n indexPageTemplate,\n loginPageTemplate,\n profilePageTemplate,\n registerPageTemplate,\n} from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-nuxt\";\n\nconst NUXT_CONFIG_PATHS = configCandidates(\"nuxt.config\");\n\n/**\n * Rule-based patcher for a Nuxt app. Like Next.js, Nuxt proxies the backend and\n * verifies the session through server middleware — here the `@zitadel/sdk-nuxt`\n * module, registered via a non-destructive `nuxt.config.*` edit. Contributes\n * the login/register/profile pages (the raw `<zitadel-login>`/`<zitadel-logout>`\n * elements), the client/server plugins, the `app.vue` router, and the SDK dep.\n */\nexport class NuxtPatcher extends AbstractRulePatcher {\n canPatch(framework: string): boolean {\n return framework === \"nuxt\";\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n const src = (rel: string) => join(ctx.framework.appDir, rel);\n return [\n // app.vue/pages/plugins live under the Nuxt srcDir (`app/` on Nuxt 4, the\n // root on Nuxt 3); nuxt.config, env, and the dep stay at the project root.\n // The app shell and homepage redirect are written only when setup created\n // the skeleton itself — a pre-existing app keeps its own shell, theme,\n // and landing page (ADR 044), same as the Next homepage.\n ...(ctx.scaffoldedFramework\n ? ([\n { kind: \"write\", path: src(\"app.vue\"), contents: appVueTemplate() },\n { kind: \"write\", path: src(\"pages/index.vue\"), contents: indexPageTemplate() },\n ] satisfies FileOp[])\n : []),\n { kind: \"write\", path: src(\"pages/login.vue\"), contents: loginPageTemplate(ctx) },\n { kind: \"write\", path: src(\"pages/register.vue\"), contents: registerPageTemplate(ctx) },\n { kind: \"write\", path: src(\"pages/profile.vue\"), contents: profilePageTemplate(ctx) },\n {\n kind: \"write\",\n path: src(\"plugins/zitadel-components.client.ts\"),\n contents: componentsPluginTemplate(),\n },\n { kind: \"write\", path: src(\"plugins/auth.server.ts\"), contents: authPluginTemplate() },\n {\n kind: \"edit\",\n path: [...NUXT_CONFIG_PATHS],\n edit: nuxtConfigEdit({ projectId: ctx.project.id, server: ctx.server }),\n // Runtime config + proxy wiring: auth breaks without it.\n wiring: \"infrastructure\",\n },\n { kind: \"merge-env\", path: \".env.example\", entries: { NUXT_PUBLIC_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { NUXT_PUBLIC_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n // `nuxt dev` takes its port from the command line only, so without this\n // the app can serve a port the project does not allow as an origin.\n devScriptPortOp(ctx.issuer),\n ];\n }\n\n protected routeFiles(view: PatchView): ReadonlyArray<string> {\n const src = (rel: string) => join(view.framework.appDir, rel);\n return [\n src(\"app.vue\"),\n src(\"pages/index.vue\"),\n src(\"pages/login.vue\"),\n src(\"pages/register.vue\"),\n src(\"pages/profile.vue\"),\n src(\"plugins/zitadel-components.client.ts\"),\n src(\"plugins/auth.server.ts\"),\n ];\n }\n\n protected override infrastructureFiles(view: PatchView): ReadonlyArray<string> {\n const src = (rel: string) => join(view.framework.appDir, rel);\n // The plugins are the auth plumbing: component registration on the\n // client and the server-side auth/session hook. The pages and app shell\n // are the user's customization surface.\n return [src(\"plugins/zitadel-components.client.ts\"), src(\"plugins/auth.server.ts\")];\n }\n\n protected override conditionallyScaffoldedFiles(view: PatchView): ReadonlyArray<string> {\n // Written only when setup created the app skeleton itself; on a\n // pre-existing app the shell and homepage stay user-owned (see routeOps).\n const src = (rel: string) => join(view.framework.appDir, rel);\n return [src(\"app.vue\"), src(\"pages/index.vue\")];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n // package.json: the `dev` script gets the project's dev-server port\n // pinned into it, another in-place edit eject can't auto-revert.\n return [\"nuxt.config.*\", \"package.json\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Nuxt integration\",\n detail:\n \"Wrote login/register/profile pages + plugins and registered @zitadel/sdk-nuxt in nuxt.config.*.\",\n };\n }\n}\n","import { builders, generateCode } from \"magicast\";\n\nimport { configCandidates } from \"./config-paths\";\nimport type { FileOp } from \"./file-writer/types\";\nimport { PROXY_PATH } from \"./proxy\";\nimport {\n assertNoUnreviewedProjectSecretProxy,\n PROXY_CREDENTIAL_POLICY_MARKER,\n} from \"./proxy-credential-policy\";\nimport {\n ensureEditableObject,\n importIsPresent,\n parseConfigModule,\n resolveDefaultExportObject,\n} from \"./utils/magicast\";\n\n/**\n * Shared Vite dev-server proxy merged into the project's Vite config for the SPA\n * frameworks (React, Vue, Solid, Svelte, Qwik). It forwards same-origin\n * `/__nextgen/*` calls to the\n * backend, strips the prefix, and attaches the project's service-key secret\n * (read from `ZITADEL_PROJECT_SECRET` in `.env.local`) only to the current\n * app-plane `POST /sessions/exchange` operation. The secret stays server-side:\n * Vite only exposes vars with the configured `envPrefix` (default `VITE_`) to\n * client bundles, so this server-only key never leaks into the browser.\n */\nfunction proxyEntryCode(server: string): string {\n return `/* ${PROXY_CREDENTIAL_POLICY_MARKER} */ {\n target: ${JSON.stringify(server)},\n changeOrigin: false,\n rewrite: (path) => path.replace(/^\\\\${PROXY_PATH}/, \"\").replace(/^(?!\\\\/)/, \"/\"),\n configure: (proxy) => {\n const secret = loadEnv(\"development\", process.cwd(), \"ZITADEL_\").ZITADEL_PROJECT_SECRET;\n if (!secret) {\n throw new Error(\"ZITADEL_PROJECT_SECRET is not set; add it to .env.local (zitadel setup writes it).\");\n }\n const bearer = \\`Bearer \\${secret}\\`;\n proxy.on(\"proxyReq\", (proxyReq) => {\n const pathname = new URL(proxyReq.path, \"http://zitadel.local\").pathname;\n if (\n proxyReq.method === \"POST\" &&\n pathname === \"/sessions/exchange\" &&\n !proxyReq.getHeader(\"authorization\")\n ) {\n proxyReq.setHeader(\"authorization\", bearer);\n }\n });\n },\n}`;\n}\n\nconst LEGACY_PROXY_REQUEST_LISTENER =\n /(^[\\t ]*)proxy\\.on\\(\"proxyReq\", \\(proxyReq\\) => \\{\\r?\\n\\1 {2}proxyReq\\.setHeader\\(\"authorization\", bearer\\);\\r?\\n\\1\\}\\);/m;\n\nfunction exchangeOnlyProxyRequestListener(indent: string): string {\n return `${indent}/* ${PROXY_CREDENTIAL_POLICY_MARKER} */\n${indent}proxy.on(\"proxyReq\", (proxyReq) => {\n${indent} const pathname = new URL(proxyReq.path, \"http://zitadel.local\").pathname;\n${indent} if (\n${indent} proxyReq.method === \"POST\" &&\n${indent} pathname === \"/sessions/exchange\" &&\n${indent} !proxyReq.getHeader(\"authorization\")\n${indent} ) {\n${indent} proxyReq.setHeader(\"authorization\", bearer);\n${indent} }\n${indent}});`;\n}\n\n/**\n * Identifies the exact proxy shape emitted before the exchange-only credential\n * policy. Setup may replace that generated listener, but must preserve the\n * surrounding `/__nextgen` proxy and any user changes elsewhere in the entry.\n */\nfunction isLegacyManagedProxy(source: string): boolean {\n if (source.includes(PROXY_CREDENTIAL_POLICY_MARKER)) {\n return false;\n }\n return [\n 'loadEnv(\"development\", process.cwd(), \"ZITADEL_\").ZITADEL_PROJECT_SECRET',\n 'throw new Error(\"ZITADEL_PROJECT_SECRET is not set; add it to .env.local (zitadel setup writes it).\")',\n \"const bearer = `Bearer ${secret}`;\",\n ].every((fingerprint) => source.includes(fingerprint)) && LEGACY_PROXY_REQUEST_LISTENER.test(source);\n}\n\n/** The imports that the injected proxy entry depends on. */\nconst PROXY_IMPORTS = [{ from: \"vite\", imported: \"loadEnv\", local: \"loadEnv\" }] as const;\n\n/**\n * Builds the pure `edit` transform the file-writer applies to the project's Vite\n * config (`vite.config.*`): a non-destructive magicast merge that adds the\n * `/__nextgen` proxy and sets `server.port`/`strictPort` when they are unset,\n * preserving the user's plugins, options, and formatting. Leaves `server.host`\n * alone so the user can still opt into network binding (`--host`/`host: true`);\n * the issuer/origin requirement is about the port, not the bind host. Idempotent\n * — entries already present are left as-is. Throws `E_VALIDATION` when the file\n * is absent or the config object cannot be reached (function-built/exotic\n * configs), with a hint to add the block manually.\n */\nexport function viteProxyEdit(\n devPort: number,\n server: string,\n): (source: string | undefined) => string {\n return (source) => {\n const label = \"the Vite config (vite.config.*)\";\n let workingSource = source;\n if (workingSource !== undefined && isLegacyManagedProxy(workingSource)) {\n // Replace only the generated bearer listener. User changes elsewhere in\n // the proxy entry (target, rewrite, TLS options, comments) remain intact.\n workingSource = workingSource.replace(\n LEGACY_PROXY_REQUEST_LISTENER,\n (_listener, indent: string) => exchangeOnlyProxyRequestListener(indent),\n );\n } else if (workingSource !== undefined) {\n assertNoUnreviewedProjectSecretProxy(workingSource, label);\n }\n\n const mod = parseConfigModule(workingSource, label);\n const config = resolveDefaultExportObject(mod, label);\n let changed = workingSource !== source;\n const serverConfig = ensureEditableObject(config, \"server\");\n if (serverConfig.port === undefined) {\n serverConfig.port = devPort;\n changed = true;\n }\n if (serverConfig.strictPort === undefined) {\n serverConfig.strictPort = true;\n changed = true;\n }\n const proxyConfig = ensureEditableObject(serverConfig, \"proxy\");\n if (proxyConfig[PROXY_PATH] === undefined) {\n proxyConfig[PROXY_PATH] = builders.raw(proxyEntryCode(server));\n changed = true;\n }\n for (const imp of PROXY_IMPORTS) {\n if (!importIsPresent(mod, imp.local, imp.from)) {\n mod.imports.$add({ ...imp });\n changed = true;\n }\n }\n // Nothing was missing — return the source untouched so the file-writer skips\n // it instead of letting magicast reformat an already-patched config.\n if (!changed && source !== undefined) {\n return source;\n }\n const code = generateCode(mod).code;\n return code.endsWith(\"\\n\") ? code : `${code}\\n`;\n };\n}\n\n/**\n * Candidate Vite config filenames, in resolution priority. The patcher hands\n * this list to the generic `edit` file-op, which patches the first one that\n * exists — so any project layout (`vite.config.ts`, `.mts`, `.js`, …) is covered.\n */\nexport const VITE_CONFIG_PATHS = configCandidates(\"vite.config\");\n\n/**\n * Capability shared by every Vite-based patcher (React, Vue, and any future\n * Vite framework): contributes the file-op that non-destructively merges the\n * `/__nextgen` dev proxy into the project's Vite config. A patcher opts in by\n * declaring `implements ViteSupport` and spreading {@link viteProxyOp} into its\n * `routeOps`, so the proxy logic is written once and reused everywhere — no\n * per-framework duplication.\n */\nexport interface ViteSupport {\n /** The `edit` file-op that merges the `/__nextgen` proxy into the Vite config. */\n viteProxyOp(devPort: number, server: string): FileOp;\n}\n\n/** Builds the shared Vite-config proxy {@link FileOp} for a {@link ViteSupport} patcher. */\nexport function buildViteProxyOp(devPort: number, server: string): FileOp {\n return {\n kind: \"edit\",\n path: [...VITE_CONFIG_PATHS],\n edit: viteProxyEdit(devPort, server),\n // The dev proxy is the auth request path — the doctor managed-files\n // check fails when this merge is no longer applied.\n wiring: \"infrastructure\",\n };\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n/**\n * The managed `src/app.tsx`: a minimal path-based router that renders the\n * `@zitadel/sdk-qwik` widgets — login at `/login`, register at `/register`, and\n * the signed-in session card at `/profile`. The root path redirects to `/login`.\n * Exports a named `App` (`component$`) to match the create-vite Qwik entry\n * (`main.tsx` imports `{ App }`). The project id comes from\n * `VITE_ZITADEL_PROJECT_ID`. No secret reaches the browser: the dev proxy in\n * `vite.config.*` attaches the project service-key secret (from\n * `ZITADEL_PROJECT_SECRET`) server-side only to `POST /sessions/exchange`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the login widgets, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. A plain `locales` prop\n * suffices here: the wrapper component assigns it as a DOM property internally.\n */\nexport function appTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, ZitadelSession, businessLocales, configureZitadel\"\n : \"ZitadelLogin, ZitadelSession, configureZitadel\";\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the locales prop to\n// fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? \" locales={businessLocales}\" : \"\";\n return `${MANAGED_MARKER}\nimport { component$, useVisibleTask$ } from \"@builder.io/qwik\";\nimport { ${importNames} } from \"@zitadel/sdk-qwik\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,\n proxyPath: \"${PROXY_PATH}\",\n});\n\nexport const App = component$(() => {\n const path = window.location.pathname;\n\n useVisibleTask$(() => {\n if (path === \"/\") {\n window.location.replace(\"/login\");\n }\n });\n\n if (path === \"/\") {\n return null;\n }\n if (path.startsWith(\"/profile\")) {\n return (\n <div style={{ position: \"fixed\", inset: \"0\", overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelSession project={project} postSignOutUrl=\"/login\" />\n </div>\n );\n }\n if (path.startsWith(\"/register\")) {\n return (\n <div style={{ position: \"fixed\", inset: \"0\", overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelLogin project={project}${localesAttr} purpose=\"register\" postSignInUrl=\"/profile\" />\n </div>\n );\n }\n return (\n <div style={{ position: \"fixed\", inset: \"0\", overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelLogin project={project}${localesAttr} purpose=\"login\" postSignInUrl=\"/profile\" />\n </div>\n );\n});\n`;\n}\n","import { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { type ViteSupport, buildViteProxyOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-qwik\";\n\n/**\n * Rule-based patcher for a Vite + Qwik single-page app. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * managed `src/app.tsx` auth entry, a non-destructive `vite.config.*` merge\n * that adds the `/__nextgen` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`), the `VITE_`-prefixed\n * project id, and the SDK dep.\n *\n * The create-vite Qwik template uses a lowercase `src/app.tsx` exporting a named\n * `App` (mounted by `main.tsx`), so this patcher writes that exact entry. Unlike\n * Next.js — whose middleware runs the proxy server-side — a SPA has no server,\n * so the dev proxy provides the same-origin `/__nextgen` path locally. In\n * production that path comes from a platform rewrite or minimal worker\n * (ADR 036); CLI scaffolding for it is tracked in issue #560.\n */\nexport class QwikPatcher extends AbstractRulePatcher implements ViteSupport {\n canPatch(framework: string): boolean {\n return framework === \"qwik\";\n }\n\n viteProxyOp(devPort: number, server: string): FileOp {\n return buildViteProxyOp(devPort, server);\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: \"src/app.tsx\", contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n { kind: \"merge-env\", path: \".env.example\", entries: { VITE_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/app.tsx\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Qwik (Vite) integration\",\n detail:\n \"Wrote src/app.tsx auth entry and merged the /__nextgen dev proxy into vite.config.*.\",\n };\n }\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n/**\n * The managed `src/App.tsx`: a minimal path-based router that renders the\n * `@zitadel/sdk-react` widgets — login at `/login`, register at `/register`, and\n * the signed-in session card at `/profile`. The root path redirects to `/login`.\n * The project id comes from `VITE_ZITADEL_PROJECT_ID` (Vite only exposes\n * `VITE_`-prefixed env to the client). No secret reaches the browser: the dev\n * proxy in `vite.config.*` attaches the project service-key secret (from\n * `ZITADEL_PROJECT_SECRET`) server-side only to `POST /sessions/exchange`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the login widgets, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. A plain `locales` prop\n * suffices here: the wrapper component assigns it as a DOM property internally,\n * so the React-18 attribute-decay caveat of the raw custom element does not\n * apply.\n */\nexport function appTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, ZitadelSession, businessLocales, configureZitadel\"\n : \"ZitadelLogin, ZitadelSession, configureZitadel\";\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the locales prop to\n// fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? \" locales={businessLocales}\" : \"\";\n return `${MANAGED_MARKER}\nimport { useEffect } from \"react\";\nimport { ${importNames} } from \"@zitadel/sdk-react\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,\n proxyPath: \"${PROXY_PATH}\",\n});\n\nexport default function App() {\n const path = window.location.pathname;\n\n useEffect(() => {\n if (path === \"/\") {\n window.location.replace(\"/login\");\n }\n }, [path]);\n\n if (path === \"/\") {\n return null;\n }\n if (path.startsWith(\"/profile\")) {\n return (\n <div style={{ position: \"fixed\", inset: 0, overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelSession project={project} postSignOutUrl=\"/login\" />\n </div>\n );\n }\n if (path.startsWith(\"/register\")) {\n return (\n <div style={{ position: \"fixed\", inset: 0, overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelLogin project={project}${localesAttr} purpose=\"register\" postSignInUrl=\"/profile\" />\n </div>\n );\n }\n return (\n <div style={{ position: \"fixed\", inset: 0, overflow: \"auto\", background: \"#0f0f11\", colorScheme: \"dark\" }}>\n <ZitadelLogin project={project}${localesAttr} purpose=\"login\" postSignInUrl=\"/profile\" />\n </div>\n );\n}\n`;\n}\n","import { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { type ViteSupport, buildViteProxyOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-react\";\n\n/**\n * Rule-based patcher for a Vite + React single-page app. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * managed `src/App.tsx` auth entry, a non-destructive `vite.config.*` merge\n * that adds the `/__nextgen` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`), the `VITE_`-prefixed\n * project id, and the SDK dep.\n *\n * Unlike Next.js — whose middleware runs the proxy and token exchange\n * server-side — a SPA has no server, so the dev proxy provides the same-origin\n * `/__nextgen` path locally. In production that path comes from a platform\n * rewrite or minimal worker (ADR 036); CLI scaffolding for it is tracked in\n * issue #560.\n */\nexport class ReactPatcher extends AbstractRulePatcher implements ViteSupport {\n canPatch(framework: string): boolean {\n return framework === \"react\";\n }\n\n viteProxyOp(devPort: number, server: string): FileOp {\n return buildViteProxyOp(devPort, server);\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: \"src/App.tsx\", contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n { kind: \"merge-env\", path: \".env.example\", entries: { VITE_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/App.tsx\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"React (Vite) integration\",\n detail:\n \"Wrote src/App.tsx auth entry and merged the /__nextgen dev proxy into vite.config.*.\",\n };\n }\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n/**\n * The managed `src/App.tsx`: a minimal path-based router that renders the\n * `@zitadel/sdk-solid` widgets — login at `/login`, register at `/register`, and\n * the signed-in session card at `/profile`. The root path redirects to `/login`.\n * The project id comes from `VITE_ZITADEL_PROJECT_ID` (Vite only exposes\n * `VITE_`-prefixed env to the client). No secret reaches the browser: the dev\n * proxy in `vite.config.*` attaches the project service-key secret (from\n * `ZITADEL_PROJECT_SECRET`) server-side only to `POST /sessions/exchange`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the login widgets, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. A plain `locales` prop\n * suffices here: the wrapper component assigns it as a DOM property internally.\n */\nexport function appTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, ZitadelSession, businessLocales, configureZitadel\"\n : \"ZitadelLogin, ZitadelSession, configureZitadel\";\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the locales prop to\n// fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? \" locales={businessLocales}\" : \"\";\n return `${MANAGED_MARKER}\nimport { onMount } from \"solid-js\";\nimport { ${importNames} } from \"@zitadel/sdk-solid\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,\n proxyPath: \"${PROXY_PATH}\",\n});\n\nexport default function App() {\n const path = window.location.pathname;\n\n onMount(() => {\n if (path === \"/\") {\n window.location.replace(\"/login\");\n }\n });\n\n if (path === \"/\") {\n return null;\n }\n if (path.startsWith(\"/profile\")) {\n return (\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelSession project={project} postSignOutUrl=\"/login\" />\n </div>\n );\n }\n if (path.startsWith(\"/register\")) {\n return (\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelLogin project={project}${localesAttr} purpose=\"register\" postSignInUrl=\"/profile\" />\n </div>\n );\n }\n return (\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelLogin project={project}${localesAttr} purpose=\"login\" postSignInUrl=\"/profile\" />\n </div>\n );\n}\n`;\n}\n","import { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { type ViteSupport, buildViteProxyOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-solid\";\n\n/**\n * Rule-based patcher for a Vite + Solid single-page app. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * managed `src/App.tsx` auth entry, a non-destructive `vite.config.*` merge\n * that adds the `/__nextgen` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`), the `VITE_`-prefixed\n * project id, and the SDK dep.\n *\n * Unlike Next.js — whose middleware runs the proxy and token exchange\n * server-side — a SPA has no server, so the dev proxy provides the same-origin\n * `/__nextgen` path locally. In production that path comes from a platform\n * rewrite or minimal worker (ADR 036); CLI scaffolding for it is tracked in\n * issue #560.\n */\nexport class SolidPatcher extends AbstractRulePatcher implements ViteSupport {\n canPatch(framework: string): boolean {\n return framework === \"solid\";\n }\n\n viteProxyOp(devPort: number, server: string): FileOp {\n return buildViteProxyOp(devPort, server);\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: \"src/App.tsx\", contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n { kind: \"merge-env\", path: \".env.example\", entries: { VITE_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/App.tsx\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Solid (Vite) integration\",\n detail:\n \"Wrote src/App.tsx auth entry and merged the /__nextgen dev proxy into vite.config.*.\",\n };\n }\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\n\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n/**\n * The managed `src/App.svelte`: a minimal path-based router that renders the\n * `@zitadel/sdk-svelte` widgets — login at `/login`, register at `/register`, and\n * the signed-in session card at `/profile`. The root path redirects to `/login`.\n * The managed marker lives in the `<script lang=\"ts\">` block (a JS comment) so\n * eject/doctor stay marker-aware. The project id comes from\n * `VITE_ZITADEL_PROJECT_ID`. No secret reaches the browser: the dev proxy in\n * `vite.config.*` attaches the project service-key secret (from\n * `ZITADEL_PROJECT_SECRET`) server-side only to `POST /sessions/exchange`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the login widgets, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. A plain `locales` prop\n * suffices here: the wrapper component assigns it as a DOM property internally.\n */\nexport function appTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, ZitadelSession, businessLocales, configureZitadel\"\n : \"ZitadelLogin, ZitadelSession, configureZitadel\";\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the locales prop to\n// fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? \" locales={businessLocales}\" : \"\";\n return `<script lang=\"ts\">\n${MANAGED_MARKER}\nimport { onMount } from \"svelte\";\nimport { ${importNames} } from \"@zitadel/sdk-svelte\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,\n proxyPath: \"${PROXY_PATH}\",\n});\n\nconst path = window.location.pathname;\n\nonMount(() => {\n if (path === \"/\") {\n window.location.replace(\"/login\");\n }\n});\n</script>\n\n{#if path.startsWith(\"/profile\")}\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelSession {project} postSignOutUrl=\"/login\" />\n </div>\n{:else if path.startsWith(\"/register\")}\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelLogin {project}${localesAttr} purpose=\"register\" postSignInUrl=\"/profile\" />\n </div>\n{:else if path !== \"/\"}\n <div style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelLogin {project}${localesAttr} purpose=\"login\" postSignInUrl=\"/profile\" />\n </div>\n{/if}\n`;\n}\n","import { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { type ViteSupport, buildViteProxyOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-svelte\";\n\n/**\n * Rule-based patcher for a Vite + Svelte single-page app. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * managed `src/App.svelte` auth entry, a non-destructive `vite.config.*` merge\n * that adds the `/__nextgen` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`), the `VITE_`-prefixed\n * project id, and the SDK dep.\n *\n * Unlike Next.js — whose middleware runs the proxy and token exchange\n * server-side — a SPA has no server, so the dev proxy provides the same-origin\n * `/__nextgen` path locally. In production that path comes from a platform\n * rewrite or minimal worker (ADR 036); CLI scaffolding for it is tracked in\n * issue #560.\n */\nexport class SveltePatcher extends AbstractRulePatcher implements ViteSupport {\n canPatch(framework: string): boolean {\n return framework === \"svelte\";\n }\n\n viteProxyOp(devPort: number, server: string): FileOp {\n return buildViteProxyOp(devPort, server);\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: \"src/App.svelte\", contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n // Vite only exposes VITE_-prefixed vars to client code (import.meta.env).\n { kind: \"merge-env\", path: \".env.example\", entries: { VITE_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/App.svelte\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Svelte (Vite) integration\",\n detail:\n \"Wrote src/App.svelte auth entry and merged the /__nextgen dev proxy into vite.config.*.\",\n };\n }\n}\n","import { MANAGED_MARKER } from \"../../../../paths\";\nimport type { PatchContext } from \"../../types\";\nimport { PROXY_PATH } from \"../proxy\";\n\n/**\n * The managed `src/App.vue`: a minimal path-based router that renders the\n * `@zitadel/sdk-vue` widgets — login at `/login`, register at `/register`, and\n * the signed-in session card at `/profile`. The root path redirects to `/login`.\n * The managed marker lives in the `<script setup>` block (a JS comment) so\n * eject/doctor stay marker-aware. The project id comes from\n * `VITE_ZITADEL_PROJECT_ID`. No secret reaches the browser: the dev proxy in\n * `vite.config.*` attaches the project service-key secret (from\n * `ZITADEL_PROJECT_SECRET`) server-side only to `POST /sessions/exchange`.\n *\n * Projects set up with the business use case additionally pass the SDK's\n * `businessLocales` overlay to the login widgets, restoring work-email copy on\n * top of the widget's neutral built-in dictionaries. A plain `:locales` prop\n * suffices here: the wrapper component assigns it as a DOM property internally.\n */\nexport function appTemplate(ctx: PatchContext): string {\n const business = ctx.useCase === \"business\";\n const importNames = business\n ? \"ZitadelLogin, ZitadelSession, businessLocales, configureZitadel\"\n : \"ZitadelLogin, ZitadelSession, configureZitadel\";\n // The overlay ships with the SDK, so the generated app only wires it up\n // (and stays plain otherwise).\n const localesComment = business\n ? `\n\n// Set up for a business audience: businessLocales overlays work-email copy on\n// the login widget's neutral built-in dictionaries. Remove the :locales prop\n// to fall back to the neutral wording.`\n : \"\";\n const localesAttr = business ? ' :locales=\"businessLocales\"' : \"\";\n return `<script setup lang=\"ts\">\n${MANAGED_MARKER}\nimport { onMounted } from \"vue\";\nimport { ${importNames} } from \"@zitadel/sdk-vue\";${localesComment}\n\nconst project = configureZitadel({\n projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,\n proxyPath: \"${PROXY_PATH}\",\n});\n\nconst path = window.location.pathname;\n\nonMounted(() => {\n if (path === \"/\") {\n window.location.replace(\"/login\");\n }\n});\n</script>\n\n<template>\n <div\n v-if=\"path.startsWith('/profile')\"\n style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\"\n >\n <ZitadelSession :project=\"project\" postSignOutUrl=\"/login\" />\n </div>\n <div\n v-else-if=\"path.startsWith('/register')\"\n style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\"\n >\n <ZitadelLogin :project=\"project\"${localesAttr} purpose=\"register\" postSignInUrl=\"/profile\" />\n </div>\n <div v-else-if=\"path !== '/'\" style=\"position:fixed;inset:0;overflow:auto;background:#0f0f11;color-scheme:dark\">\n <ZitadelLogin :project=\"project\"${localesAttr} purpose=\"login\" postSignInUrl=\"/profile\" />\n </div>\n</template>\n`;\n}\n","import { npmDistTagForCliVersion } from \"../../../../public-cli\";\nimport type { FileOp } from \"../file-writer/types\";\nimport type { PatchContext, PatchView } from \"../../types\";\nimport { AbstractRulePatcher } from \"../base\";\nimport { type ViteSupport, buildViteProxyOp } from \"../vite-support\";\nimport { appTemplate } from \"./templates\";\n\nconst SDK_DEPENDENCY = \"@zitadel/sdk-vue\";\n\n/**\n * Rule-based patcher for a Vite + Vue single-page app. Inherits the shared\n * `.zitadel/` base files from {@link AbstractRulePatcher} and contributes the\n * managed `src/App.vue` auth entry, a non-destructive `vite.config.*` merge\n * that adds the `/__nextgen` dev proxy (attaching the project secret from\n * `ZITADEL_PROJECT_SECRET` only to `POST /sessions/exchange`), the `VITE_`-prefixed\n * project id, and the SDK dep.\n */\nexport class VuePatcher extends AbstractRulePatcher implements ViteSupport {\n canPatch(framework: string): boolean {\n return framework === \"vue\";\n }\n\n viteProxyOp(devPort: number, server: string): FileOp {\n return buildViteProxyOp(devPort, server);\n }\n\n protected routeOps(ctx: PatchContext): FileOp[] {\n return [\n { kind: \"write\", path: \"src/App.vue\", contents: appTemplate(ctx) },\n this.viteProxyOp(ctx.framework.devPort, ctx.server),\n { kind: \"merge-env\", path: \".env.example\", entries: { VITE_ZITADEL_PROJECT_ID: \"\" } },\n {\n kind: \"merge-env\",\n path: \".env.local\",\n entries: { VITE_ZITADEL_PROJECT_ID: ctx.project.id },\n },\n {\n kind: \"add-dep\",\n name: SDK_DEPENDENCY,\n version: npmDistTagForCliVersion(ctx.cliVersion),\n },\n ];\n }\n\n protected routeFiles(_view: PatchView): ReadonlyArray<string> {\n return [\"src/App.vue\"];\n }\n\n protected routeDeps(_view: PatchView): ReadonlyArray<string> {\n return [SDK_DEPENDENCY];\n }\n\n protected override routeConfigEdits(_view: PatchView): ReadonlyArray<string> {\n return [\"vite.config.*\"];\n }\n\n protected summary(_ctx: PatchContext): { title: string; detail: string } {\n return {\n title: \"Vue (Vite) integration\",\n detail:\n \"Wrote src/App.vue auth entry and merged the /__nextgen dev proxy into vite.config.*.\",\n };\n }\n}\n","import { AngularPatcher } from \"./rule/angular\";\nimport { NextPatcher } from \"./rule/next\";\nimport { NuxtPatcher } from \"./rule/nuxt\";\nimport { QwikPatcher } from \"./rule/qwik\";\nimport { ReactPatcher } from \"./rule/react\";\nimport { SolidPatcher } from \"./rule/solid\";\nimport { SveltePatcher } from \"./rule/svelte\";\nimport { VuePatcher } from \"./rule/vue\";\nimport type { Patcher } from \"./types\";\n\n/**\n * Active patchers, in priority order; the first whose `canPatch` matches wins.\n *\n * Patchers are grouped by family under subdirectories: `rule/` holds the\n * deterministic, template-driven patchers (extending\n * {@link import(\"./rule/base\").AbstractRulePatcher}). A future LLM-driven\n * family lives under `llm/` and registers its concrete patchers here — no\n * orchestrator or command changes needed. Only Next.js is supported today.\n */\nexport const patchers = [\n new NextPatcher(),\n new NuxtPatcher(),\n new ReactPatcher(),\n new VuePatcher(),\n new SolidPatcher(),\n new SveltePatcher(),\n new QwikPatcher(),\n new AngularPatcher(),\n] as const satisfies ReadonlyArray<Patcher>;\n","import { spawnSync } from \"node:child_process\";\n\nimport { ZitadelError } from \"../../errors\";\nimport type { Scaffolder } from \"./types\";\n\n/**\n * Base for scaffolders that delegate to an external CLI (e.g. create-next-app).\n * Subclasses implement {@link scaffold} and call {@link runCommand}.\n */\nexport abstract class AbstractCLIScaffolder implements Scaffolder {\n abstract readonly displayName: string;\n abstract readonly supportedFrameworks: ReadonlyArray<string>;\n\n /** True when the requested framework is in {@link supportedFrameworks}. */\n canScaffold(framework: string): boolean {\n return this.supportedFrameworks.includes(framework);\n }\n\n abstract scaffold(cwd: string, framework: string): Promise<void>;\n\n /**\n * Runs an external command in `cwd`, throwing a typed {@link ZitadelError} on\n * failure so the cause surfaces as a categorized CLI error. Distinguishes\n * \"binary not on PATH\" (`ENOENT` from the spawn itself) from \"binary ran but\n * exited non-zero\" — the former previously got masked as a generic\n * `exited with status 1`, leaving users to guess. Tests stub\n * `node:child_process` to assert the command without spawning.\n */\n protected runCommand(command: string, args: ReadonlyArray<string>, cwd: string): void {\n const result = spawnSync(command, [...args], { cwd, encoding: \"utf8\" });\n if (result.error) {\n const err = result.error as NodeJS.ErrnoException;\n const notFound = err.code === \"ENOENT\";\n throw new ZitadelError(\n \"E_VALIDATION\",\n notFound ? `Command not found: ${command}` : `Failed to spawn \"${command}\": ${err.message}`,\n {\n hint: notFound ? `Ensure '${command}' is installed and on PATH.` : undefined,\n details: { command, args: [...args], code: err.code },\n },\n );\n }\n const status = result.status ?? 1;\n if (status !== 0) {\n const stdout = String(result.stdout ?? \"\");\n const stderr = String(result.stderr ?? \"\");\n const output = truncateCommandOutput([stderr, stdout].filter(Boolean).join(\"\\n\").trim());\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Command \"${command} ${args.join(\" \")}\" exited with status ${String(status)}`,\n {\n hint: output ? `Command output:\\n${output}` : \"Run the command directly for more detail.\",\n details: { command, args: [...args], cwd, stdout, stderr },\n },\n );\n }\n }\n}\n\nfunction truncateCommandOutput(output: string): string {\n const limit = 4000;\n if (output.length <= limit) {\n return output;\n }\n return `${output.slice(0, limit)}\\n... output truncated ...`;\n}\n","import { rm } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Derives a valid Angular project name from the target directory. `ng new`\n * validates the name against `^[a-zA-Z0-9-~][a-zA-Z0-9-._~]*$` and rejects `.`,\n * so we slugify the directory's basename (lowercase, non-alphanumerics → `-`)\n * and guarantee a leading letter by prefixing `app-` when the slug does not\n * start with one (`app-zitadel` when the basename slugifies to nothing).\n */\nfunction angularProjectName(cwd: string): string {\n const slug = basename(cwd)\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return /^[a-z]/.test(slug) ? slug : `app-${slug || \"zitadel\"}`;\n}\n\n/**\n * Scaffolds a new Angular app with the Angular CLI, then removes the starter\n * `app.ts`/`app.html` root component (and its now-unreferenced `app.css`) so the\n * patcher can write the managed ones without colliding with boilerplate. The\n * managed component uses only `templateUrl`, so `app.css` would otherwise be a\n * dangling file eject never cleans up. Unlike `create-vite`/`nuxi`, `ng new`\n * needs a real project name plus `--directory .` to populate the current dir.\n * Requires a Node version Angular supports (^22.22.3 || ^24.15.0 || >=26).\n */\nexport class AngularScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Angular\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"angular\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npx\",\n [\n \"-y\",\n \"@angular/cli@latest\",\n \"new\",\n angularProjectName(cwd),\n \"--directory\",\n \".\",\n \"--defaults\",\n \"--style=css\",\n \"--ssr=false\",\n \"--skip-git\",\n ],\n cwd,\n );\n await rm(join(cwd, \"src/app/app.ts\"), { force: true });\n await rm(join(cwd, \"src/app/app.html\"), { force: true });\n await rm(join(cwd, \"src/app/app.css\"), { force: true });\n }\n}\n","import { AbstractCLIScaffolder } from \"./cli\";\n\nconst CREATE_NEXT_APP_VERSION = \"16.2.4\";\n\n/** Scaffolds a new Next.js App Router project with `create-next-app`. */\nexport class NextScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Next.js\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"next\"];\n\n /**\n * Runs the pinned `create-next-app` version in `cwd`, creating a TypeScript\n * App Router project in place. `--yes` accepts all defaults so the command\n * runs unattended, and `--skip-install` leaves dependency installation to the\n * setup command's explicit next step after Zitadel patches package.json.\n */\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npx\",\n [\n \"--yes\",\n `create-next-app@${CREATE_NEXT_APP_VERSION}`,\n \".\",\n \"--ts\",\n \"--app\",\n \"--use-npm\",\n \"--disable-git\",\n \"--yes\",\n \"--skip-install\",\n ],\n cwd,\n );\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Nuxt app with `nuxi init`, then removes the starter `app.vue`\n * so the patcher can write the managed one without colliding with boilerplate.\n * Nuxt 4 (what `nuxi init` scaffolds today) puts it under `app/`; older Nuxt put\n * it at the root, so both are removed. `nuxt.config.ts` is left in place — the\n * patcher merges into it via an `edit`, which preserves whatever `nuxi` generated.\n */\nexport class NuxtScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Nuxt\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"nuxt\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\n \"npx\",\n [\n \"-y\",\n \"nuxi@latest\",\n \"init\",\n \".\",\n \"--template\",\n \"minimal\",\n \"--packageManager\",\n \"npm\",\n \"--no-gitInit\",\n \"--force\",\n ],\n cwd,\n );\n await rm(join(cwd, \"app/app.vue\"), { force: true });\n await rm(join(cwd, \"app.vue\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Vite + Qwik (TypeScript) single-page app with `create-vite`,\n * then removes the starter `app.tsx`/`app.css` demo so the patcher can write the\n * managed `src/app.tsx` without colliding with boilerplate. The create-vite Qwik\n * template uses a lowercase `app.tsx` (named `App` export, mounted by `main.tsx`)\n * — the patched file keeps that same entry.\n */\nexport class QwikScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Qwik (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"qwik\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"qwik-ts\"], cwd);\n await rm(join(cwd, \"src/app.tsx\"), { force: true });\n await rm(join(cwd, \"src/app.css\"), { force: true });\n // create-vite's Qwik template pairs qwik 1.x with vite 8, but qwik 1.x peers\n // vite \">=5 <8\", so a bare `npm install` fails with ERESOLVE. Pin vite to v7\n // (what @zitadel/sdk-qwik builds against) so the generated app installs.\n this.runCommand(\"npm\", [\"pkg\", \"set\", \"devDependencies.vite=^7.3.5\"], cwd);\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Vite + React (TypeScript) single-page app with `create-vite`,\n * then removes the starter `App.tsx`/`App.css` demo so the patcher can write the\n * managed `src/App.tsx` without colliding with boilerplate. `index.css` and\n * `main.tsx` are left in place — the patched `App.tsx` keeps the same entry.\n */\nexport class ReactScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"React (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"react\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"react-ts\"], cwd);\n await rm(join(cwd, \"src/App.tsx\"), { force: true });\n await rm(join(cwd, \"src/App.css\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Vite + Solid (TypeScript) single-page app with `create-vite`,\n * then removes the starter `App.tsx`/`App.css` demo so the patcher can write the\n * managed `src/App.tsx` without colliding with boilerplate. `index.css` and\n * `index.tsx` are left in place — the patched `App.tsx` keeps the same entry.\n */\nexport class SolidScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Solid (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"solid\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"solid-ts\"], cwd);\n await rm(join(cwd, \"src/App.tsx\"), { force: true });\n await rm(join(cwd, \"src/App.css\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Vite + Svelte (TypeScript) single-page app with `create-vite`,\n * then removes the starter `App.svelte`/`lib/Counter.svelte` demo so the patcher\n * can write the managed `src/App.svelte` without colliding with boilerplate.\n * `app.css` and `main.ts` are left in place — the patched `App.svelte` keeps the\n * same entry.\n */\nexport class SvelteScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Svelte (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"svelte\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"svelte-ts\"], cwd);\n await rm(join(cwd, \"src/App.svelte\"), { force: true });\n await rm(join(cwd, \"src/lib/Counter.svelte\"), { force: true });\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractCLIScaffolder } from \"./cli\";\n\n/**\n * Scaffolds a new Vite + Vue (TypeScript) single-page app with `create-vite`,\n * then removes the starter `App.vue`/`components/HelloWorld.vue` demo so the\n * patcher can write the managed `src/App.vue` without colliding with boilerplate.\n */\nexport class VueScaffolder extends AbstractCLIScaffolder {\n readonly displayName = \"Vue (Vite)\";\n readonly supportedFrameworks: ReadonlyArray<string> = [\"vue\"];\n\n async scaffold(cwd: string, _framework: string): Promise<void> {\n this.runCommand(\"npm\", [\"create\", \"vite@latest\", \".\", \"--\", \"--template\", \"vue-ts\"], cwd);\n await rm(join(cwd, \"src/App.vue\"), { force: true });\n await rm(join(cwd, \"src/components/HelloWorld.vue\"), { force: true });\n }\n}\n","import { AngularScaffolder } from \"./angular\";\nimport { NextScaffolder } from \"./next\";\nimport { NuxtScaffolder } from \"./nuxt\";\nimport { QwikScaffolder } from \"./qwik\";\nimport { ReactScaffolder } from \"./react\";\nimport { SolidScaffolder } from \"./solid\";\nimport { SvelteScaffolder } from \"./svelte\";\nimport { VueScaffolder } from \"./vue\";\nimport type { Scaffolder } from \"./types\";\n\n/**\n * Active scaffolders, in priority order. The framework picker derives its\n * choices from this list. Add a new framework by appending its scaffolder\n * here — no orchestrator changes needed.\n */\nexport const scaffolders = [\n new NextScaffolder(),\n new NuxtScaffolder(),\n new ReactScaffolder(),\n new VueScaffolder(),\n new SolidScaffolder(),\n new SvelteScaffolder(),\n new QwikScaffolder(),\n new AngularScaffolder(),\n] as const satisfies ReadonlyArray<Scaffolder>;\n","import { mkdir, readdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\n\nimport { ZitadelError } from \"../errors\";\nimport { detectors } from \"./detectors\";\nimport type { Detector, FrameworkFacts } from \"./detectors/types\";\nimport { patchers } from \"./patchers\";\nimport type { Patcher } from \"./patchers/types\";\nimport { scaffolders } from \"./scaffolders\";\nimport type { Scaffolder } from \"./scaffolders/types\";\n\nexport type { Detector, FrameworkFacts } from \"./detectors/types\";\nexport { issuerFromPort } from \"./detectors/port\";\n\n/** One framework the CLI can scaffold from scratch, surfaced to the picker. */\nexport type FrameworkChoice = Readonly<{ id: string; displayName: string }>;\n\nexport type ScaffoldTarget = Readonly<{\n scaffoldable: boolean;\n hasGitignore: boolean;\n hasRuntimeOnlyZitadel: boolean;\n reason?: string;\n entries: ReadonlyArray<string>;\n}>;\n\ntype ScaffoldStash = Readonly<{\n gitignore?: string;\n root: string;\n zitadel?: string;\n}>;\n\n/**\n * Orchestrates the three per-framework strategies — detectors (recognise an\n * existing project and extract its facts), scaffolders (create a project), and\n * patchers (integrate Zitadel) — over their respective registries. It resolves\n * the right strategy for a framework and drives the detect/scaffold lifecycle;\n * how a patcher applies its work (file operations vs an LLM agent) stays\n * internal to that patcher. Registries are injected so tests can supply fakes.\n */\nexport class Orca {\n constructor(\n private readonly detectors: ReadonlyArray<Detector>,\n private readonly scaffolders: ReadonlyArray<Scaffolder>,\n private readonly patchers: ReadonlyArray<Patcher>,\n ) {}\n\n /**\n * Detects the framework in `cwd` and extracts its {@link FrameworkFacts},\n * honouring an explicit `requested` framework. Throws\n * `E_FRAMEWORK_NOT_DETECTED` when nothing matches; a detector's\n * `E_UNSUPPORTED_PROJECT_SHAPE` (recognised but unsupported) propagates.\n */\n async detect(cwd: string, requested?: string): Promise<FrameworkFacts> {\n const candidates = requested\n ? this.detectors.filter((detector) => detector.framework === requested)\n : this.detectors;\n if (requested && candidates.length === 0) {\n throw new ZitadelError(\"E_FRAMEWORK_NOT_DETECTED\", `Unsupported framework \"${requested}\"`, {\n hint: `Supported frameworks: ${this.frameworkIds().join(\", \")}.`,\n });\n }\n for (const detector of candidates) {\n const facts = await detector.detect(cwd);\n if (facts) {\n return facts;\n }\n }\n throw new ZitadelError(\n \"E_FRAMEWORK_NOT_DETECTED\",\n \"Could not detect a supported app framework\",\n {\n hint: \"Run setup from your app project directory, pass --cwd <path-to-app>, or run setup from an empty directory to scaffold a new app.\",\n },\n );\n }\n\n /**\n * Non-throwing detection: returns `undefined` instead of raising for a\n * project that is absent, unrecognised, or recognised-but-unsupported, so\n * callers (e.g. `eject`) can probe and degrade gracefully.\n */\n async tryDetect(cwd: string): Promise<FrameworkFacts | undefined> {\n try {\n return await this.detect(cwd);\n } catch (error) {\n if (\n error instanceof ZitadelError &&\n (error.code === \"E_FRAMEWORK_NOT_DETECTED\" || error.code === \"E_UNSUPPORTED_PROJECT_SHAPE\")\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n /** Whether `cwd` is safe for an in-place framework scaffold. */\n async isFreshScaffoldTarget(cwd: string): Promise<boolean> {\n return (await inspectScaffoldTarget(cwd)).scaffoldable;\n }\n\n /**\n * Creates a new `framework` project in `cwd`, then re-detects it to return\n * the resulting {@link FrameworkFacts}. Throws `E_CONFLICT` when the directory\n * already contains a project (\"already scaffolded\") and `E_VALIDATION` when no\n * scaffolder supports the framework.\n */\n async scaffold(cwd: string, framework: string): Promise<FrameworkFacts> {\n const target = await inspectScaffoldTarget(cwd);\n if (!target.scaffoldable) {\n throw new ZitadelError(\"E_CONFLICT\", `Cannot scaffold: ${cwd} is not empty`, {\n hint:\n target.reason ??\n \"Run setup in an empty directory, or run setup from an existing supported app project.\",\n details: { entries: target.entries },\n });\n }\n assertNpmSafeScaffoldDirectoryName(cwd);\n const stash = await stashFreshScaffoldArtifacts(cwd, target);\n try {\n await this.scaffolderFor(framework).scaffold(cwd, framework);\n } finally {\n await restoreFreshScaffoldArtifacts(cwd, stash);\n }\n return this.detect(cwd, framework);\n }\n\n /**\n * Resolves the scaffolder for a framework, throwing `E_VALIDATION` (with the\n * available list) when none matches.\n */\n scaffolderFor(framework: string): Scaffolder {\n const scaffolder = this.scaffolders.find((candidate) => candidate.canScaffold(framework));\n if (!scaffolder) {\n throw new ZitadelError(\"E_VALIDATION\", `No scaffolder supports \"${framework}\"`, {\n hint: `Available frameworks: ${this.availableFrameworks()\n .map((f) => f.id)\n .join(\", \")}.`,\n });\n }\n return scaffolder;\n }\n\n /**\n * Resolves the patcher for a framework, throwing `E_VALIDATION` when none\n * matches (e.g. a framework that can be scaffolded but not yet integrated).\n */\n patcherFor(framework: string): Patcher {\n const patcher = this.patchers.find((candidate) => candidate.canPatch(framework));\n if (!patcher) {\n throw new ZitadelError(\"E_VALIDATION\", `No patcher supports \"${framework}\"`, {\n hint: \"Zitadel integration currently supports Next.js.\",\n });\n }\n return patcher;\n }\n\n /** The frameworks that can be scaffolded, derived from the scaffolder registry. */\n availableFrameworks(): ReadonlyArray<FrameworkChoice> {\n return this.scaffolders.map((scaffolder) => ({\n id: scaffolder.supportedFrameworks[0] ?? scaffolder.displayName,\n displayName: scaffolder.displayName,\n }));\n }\n\n private frameworkIds(): ReadonlyArray<string> {\n return this.detectors.map((detector) => detector.framework);\n }\n}\n\nfunction assertNpmSafeScaffoldDirectoryName(cwd: string): void {\n const name = basename(cwd);\n const errors = npmPackageNameErrors(name);\n if (errors.length === 0) {\n return;\n }\n\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Fresh app directory name \"${name}\" is not npm-package-safe`,\n {\n hint:\n \"Rename the directory to a lowercase npm-package-safe name, for example `my-zitadel-app`, then rerun setup.\",\n details: { cwd, name, validation_errors: errors },\n },\n );\n}\n\nfunction npmPackageNameErrors(name: string): string[] {\n // This local preflight catches common package-name failures before the\n // scaffolder mutates disk; framework generators still own stricter checks.\n const errors: string[] = [];\n if (name.length === 0) {\n errors.push(\"name is empty\");\n }\n if (name.length > 214) {\n errors.push(\"name is longer than 214 characters\");\n }\n if (name !== name.trim()) {\n errors.push(\"name contains leading or trailing whitespace\");\n }\n if (/[A-Z]/.test(name)) {\n errors.push(\"name can no longer contain capital letters\");\n }\n if (name.startsWith(\".\") || name.startsWith(\"_\")) {\n errors.push(\"name cannot start with a period or underscore\");\n }\n if (!/^[a-z0-9][a-z0-9._~-]*$/.test(name)) {\n errors.push(\"name may only contain lowercase letters, numbers, dots, underscores, tildes, and hyphens\");\n }\n if (name === \"node_modules\" || name === \"favicon.ico\") {\n errors.push(`name \"${name}\" is reserved`);\n }\n return [...new Set(errors)];\n}\n\n/** {@link Orca} wired with the default detector, scaffolder, and patcher registries. */\nexport function createOrca(): Orca {\n return new Orca(detectors, scaffolders, patchers);\n}\n\nexport async function inspectScaffoldTarget(cwd: string): Promise<ScaffoldTarget> {\n const entries = await readdir(cwd, { withFileTypes: true });\n const names = entries.map((entry) => entry.name).sort();\n let hasGitignore = false;\n let hasRuntimeOnlyZitadel = false;\n\n for (const entry of entries) {\n if (entry.name === \".gitignore\") {\n if (!entry.isFile()) {\n return {\n scaffoldable: false,\n hasGitignore: false,\n hasRuntimeOnlyZitadel: false,\n reason: \".gitignore exists but is not a file.\",\n entries: names,\n };\n }\n hasGitignore = true;\n continue;\n }\n\n if (entry.name === \".zitadel\") {\n if (!entry.isDirectory() || !(await isRuntimeOnlyZitadelDir(join(cwd, \".zitadel\")))) {\n return {\n scaffoldable: false,\n hasGitignore,\n hasRuntimeOnlyZitadel: false,\n reason:\n \".zitadel contains project state. Move it aside or run setup from an empty app directory.\",\n entries: names,\n };\n }\n hasRuntimeOnlyZitadel = true;\n continue;\n }\n\n return {\n scaffoldable: false,\n hasGitignore,\n hasRuntimeOnlyZitadel: false,\n reason: `Directory contains ${entry.name}. Run setup from an empty directory to scaffold a new app.`,\n entries: names,\n };\n }\n\n return { scaffoldable: true, hasGitignore, hasRuntimeOnlyZitadel, entries: names };\n}\n\nasync function isRuntimeOnlyZitadelDir(path: string): Promise<boolean> {\n const entries = await readdir(path, { withFileTypes: true });\n if (entries.length !== 1 || entries[0]?.name !== \"local\" || !entries[0].isDirectory()) {\n return false;\n }\n return true;\n}\n\nasync function stashFreshScaffoldArtifacts(\n cwd: string,\n target: ScaffoldTarget,\n): Promise<ScaffoldStash | undefined> {\n if (!target.hasGitignore && !target.hasRuntimeOnlyZitadel) {\n return undefined;\n }\n\n const parent = dirname(cwd);\n const root = join(\n parent,\n `.${basename(cwd)}.fresh-scaffold-stash-${String(process.pid)}-${String(Date.now())}`,\n );\n await mkdir(root, { mode: 0o700 });\n\n const stash: { gitignore?: string; root: string; zitadel?: string } = { root };\n if (target.hasRuntimeOnlyZitadel) {\n stash.zitadel = join(root, \".zitadel\");\n await rename(join(cwd, \".zitadel\"), stash.zitadel);\n }\n if (target.hasGitignore) {\n stash.gitignore = join(root, \".gitignore\");\n await rename(join(cwd, \".gitignore\"), stash.gitignore);\n }\n return stash;\n}\n\nasync function restoreFreshScaffoldArtifacts(\n cwd: string,\n stash: ScaffoldStash | undefined,\n): Promise<void> {\n if (!stash) {\n return;\n }\n\n try {\n await restoreRuntimeOnlyZitadel(cwd, stash.zitadel);\n await restoreGitignore(cwd, stash.gitignore);\n } finally {\n await rm(stash.root, { recursive: true, force: true });\n }\n}\n\nasync function restoreRuntimeOnlyZitadel(cwd: string, stash: string | undefined): Promise<void> {\n if (!stash) {\n return;\n }\n\n const target = join(cwd, \".zitadel\");\n try {\n await rename(stash, target);\n await appendGitignoreEntry(cwd, \".zitadel/local/\");\n return;\n } catch (error) {\n if (!isErrno(error, \"EEXIST\")) {\n throw error;\n }\n }\n\n await mkdir(target, { recursive: true, mode: 0o700 });\n await rename(join(stash, \"local\"), join(target, \"local\"));\n await rm(stash, { recursive: true, force: true });\n await appendGitignoreEntry(cwd, \".zitadel/local/\");\n}\n\nasync function restoreGitignore(cwd: string, stash: string | undefined): Promise<void> {\n if (!stash) {\n return;\n }\n\n const path = join(cwd, \".gitignore\");\n const stashed = await readFile(stash, \"utf8\");\n let current = \"\";\n try {\n current = await readFile(path, \"utf8\");\n } catch (error) {\n if (!isErrno(error, \"ENOENT\")) {\n throw error;\n }\n }\n\n const existingLines = new Set(\n current\n .split(/\\r?\\n/g)\n .map((line) => line.trim())\n .filter(Boolean),\n );\n const missingLines = stashed\n .split(/\\r?\\n/g)\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !existingLines.has(line));\n if (missingLines.length === 0) {\n return;\n }\n\n const prefix = current.length === 0 || current.endsWith(\"\\n\") ? \"\" : \"\\n\";\n await writeFile(path, `${current}${prefix}${missingLines.join(\"\\n\")}\\n`);\n}\n\nasync function appendGitignoreEntry(cwd: string, entry: string): Promise<void> {\n const path = join(cwd, \".gitignore\");\n let existing = \"\";\n try {\n existing = await readFile(path, \"utf8\");\n } catch (error) {\n if (!isErrno(error, \"ENOENT\")) {\n throw error;\n }\n }\n\n const lines = existing.split(/\\r?\\n/g).map((line) => line.trim());\n if (lines.includes(entry)) {\n return;\n }\n const prefix = existing.length === 0 || existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n await writeFile(path, `${existing}${prefix}${entry}\\n`);\n}\n\nfunction isErrno(error: unknown, code: string): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === code\n );\n}\n","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 { 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 preview_origins: secret.preview_origins,\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 } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { loadPatchContext } from \"../patch-context\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/**\n * Verifies the project still declares a Zitadel SDK dependency in\n * `package.json`. The patcher adds a scoped package (e.g.\n * `@zitadel/sdk-next`); the check is generic over the `@zitadel*`\n * scope so any framework renderer's dependency satisfies it.\n */\nexport class DependencyCheck extends AbstractSanityCheck {\n readonly name = \"dependency\";\n readonly path = \"package.json\";\n protected readonly summary = \"package.json depends on a Zitadel SDK package\";\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 = [\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ];\n if (!names.some((name) => name.startsWith(\"@zitadel\"))) {\n throw new Error(\"no @zitadel* dependency found in package.json\");\n }\n }\n\n /**\n * Repairs by re-applying the patcher's managed artifacts: rebuilds the\n * `PatchContext` from disk and calls `patcher.repair`, which re-adds the\n * SDK dependency via its `add-dep` op. The exact package name is framework\n * + renderer specific and known only to the patcher (which deliberately\n * hides its file-op plan behind the family-neutral `Patcher` interface),\n * so going through `repair` is the only sanctioned path. Missing-only:\n * the repair restores absent managed files as a side effect but never\n * overwrites an existing one, edited or not.\n */\n override async fix(ctx: CheckContext): Promise<void> {\n const patchCtx = await loadPatchContext(ctx.cwd, ctx.orca, ctx.cliVersion);\n await ctx.orca.patcherFor(patchCtx.framework.id).repair(patchCtx, {\n cwd: ctx.cwd,\n dryRun: ctx.dryRun,\n force: false,\n missingOnly: true,\n });\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@alpha`)\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(\n ([, version]) => !semver.eq(version.trim(), ctx.cliVersion),\n );\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 { 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\n ? await detectBoundaryConflicts(actions, ctx.cwd, manifest)\n : [];\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\n .map((s) => s.path)\n .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(\", \")}`,\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 ? `, ${wiring.length} wiring${wiring.length === 1 ? \"\" : \"s\"} verified` : \"\"\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.\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)) {\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(\n ctx: CheckContext,\n): Promise<ReadonlyArray<ConfigWiringStatus>> {\n try {\n const patchCtx = await loadPatchContext(ctx.cwd, ctx.orca, ctx.cliVersion);\n return await ctx.orca\n .patcherFor(patchCtx.framework.id)\n .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 */\nasync 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 { 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 { assertServerPackageAvailable } from \"../../lib/local-server/binary\";\nimport { dockerAvailable, imageAvailable } from \"../../lib/local-server/docker\";\nimport {\n dockerRuntimeGuidance,\n dockerUnavailableMessage,\n} from \"../../lib/local-server/docker-guidance\";\nimport {\n discoverManagedRuntimeProcesses,\n type ManagedRuntimeProcess,\n} from \"../../lib/local-server/processes\";\nimport {\n DEFAULT_LOCAL_SERVER_PORT,\n assertLocalStateWritable,\n checkLocalServerHealth,\n defaultLocalServerImageForCliVersion,\n localServerUrl,\n readRuntimeMetadata,\n type RuntimeBackend,\n type RuntimeMetadata,\n} from \"../../lib/local-server/runtime\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../../lib/oclif\";\nimport { createOrca } from \"../../lib/orca\";\nimport { hasZitadelConfig } from \"../../lib/project\";\nimport { listenersForPort } from \"../../lib/prober/ports\";\nimport { 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: Flags.string({ description: \"Container image to check.\" }),\n port: Flags.integer({ description: \"Local HTTP port.\", default: DEFAULT_LOCAL_SERVER_PORT }),\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 const port = flags.port ?? DEFAULT_LOCAL_SERVER_PORT;\n await this.toMeta(flags, { resolveServer: false, source: localServerUrl(port) });\n const { cwd, dryRun } = this.meta;\n const existingRuntime = await readRuntimeMetadata(cwd);\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(cwd, runtimeBackend, image, port);\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(failed, image, port, this.meta.cliVersion);\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: data,\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\nfunction failureAdvice(\n failed: CheckOutcome[],\n image: string,\n port: number,\n cliVersion: string,\n): { hint: string; nextCommands: 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 return {\n hint: \"Existing local runtime metadata was found, but the local Zitadel server is not healthy. Start it again or reset stale local data.\",\n nextCommands: [\n publicCliCommand(\"start\", cliVersion),\n publicCliCommand(\"reset --force\", cliVersion),\n ],\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) ? claimWindowClosedAction(cliVersion) : claimAction(cliVersion),\n );\n nextCommands.push(claimCommand(cliVersion));\n }\n\n const managedRuntimeWarning = warnings.find((check) => check.name === \"managed-runtime-processes\");\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\nasync function runLocalRuntimeChecks(\n cwd: string,\n runtimeBackend: RuntimeBackend,\n image: string,\n port: number,\n): Promise<CheckOutcome[]> {\n const runtime = await readRuntimeMetadata(cwd);\n const managedRuntimeCheck = await checkManagedRuntimeProcesses(runtime);\n if (runtimeBackend === \"binary\") {\n return [\n await check(\"server-binary\", \"Server npm package is available\", async () => {\n const version = await assertServerPackageAvailable();\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(cwd);\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(\n \"port\",\n `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 dockerAvailable>>;\n try {\n result = await dockerAvailable();\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 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(cwd);\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(\n \"port\",\n `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 constructor(\n readonly port: number,\n readonly serverUrl: string,\n readonly listeners: Awaited<ReturnType<typeof listenersForPort>>,\n ) {\n super(`Port ${String(port)} is already in use by ${formatListeners(listeners)}`);\n }\n}\n\nasync function checkManagedRuntimeProcesses(\n runtime: RuntimeMetadata | undefined,\n): Promise<CheckOutcome> {\n const discovery = await discoverManagedRuntimeProcesses();\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((processInfo) => processInfo.pid !== runtime.pid && processInfo.ppid !== runtime.pid);\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 { ZitadelError } from \"../lib/errors\";\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, force, nonInteractive, dryRun } = this.meta;\n\n if (!force && nonInteractive) {\n throw new ZitadelError(\"E_VALIDATION\", \"Eject requires --force in non-interactive mode\", {\n hint: \"Re-run with --force to confirm deletion of managed files.\",\n });\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 { binaryLogs, followBinaryLogs } from \"../lib/local-server/binary\";\nimport { containerLogs, followContainerLogs } from \"../lib/local-server/docker\";\nimport { DEFAULT_LOCAL_SERVER_URL, readRuntimeMetadata } from \"../lib/local-server/runtime\";\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 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 if (runtime.backend === \"binary\") {\n await followBinaryLogs(runtime.log_path, tail);\n } else {\n await followContainerLogs(runtime.container_name, tail);\n }\n return this.emit({\n status: \"ok\",\n data: { title: \"Stopped following local Zitadel logs.\" },\n });\n }\n\n const logs =\n runtime.backend === \"binary\"\n ? await binaryLogs(runtime.log_path, tail)\n : await containerLogs(runtime.container_name, 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 { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"../lib/api-client\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport { environmentSchema } from \"../lib/environment\";\nimport {\n buildSyncPlan,\n collectPlanWarnings,\n enumeratePlanResources,\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 static override flags = {\n environment: Flags.string({\n char: \"e\",\n description: \"Target environment (default: development).\",\n options: [...environmentSchema.options],\n }),\n };\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.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}, ` +\n `${plan.length - summary.total} unchanged`,\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\";\nimport { cancel, confirm, isCancel } from \"@clack/prompts\";\n\nimport { ZitadelError } from \"../lib/errors\";\nimport { stopBinaryRuntime } from \"../lib/local-server/binary\";\nimport { stopAndRemoveContainer } from \"../lib/local-server/docker\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n localContainerName,\n readRuntimeMetadata,\n removeLocalData,\n removeRuntimeMetadata,\n} from \"../lib/local-server/runtime\";\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 if (!this.meta.force) {\n if (this.meta.nonInteractive) {\n throw new ZitadelError(\"E_VALIDATION\", \"Reset requires --force in non-interactive mode\", {\n hint: \"Pass --force to delete `.zitadel/local/nextgen-data`.\",\n nextCommands: [publicCliCommand(\"reset --force\", this.meta.cliVersion)],\n });\n }\n const answer = await confirm({\n message: \"Delete the local Zitadel runtime and .zitadel/local/nextgen-data?\",\n initialValue: false,\n });\n if (isCancel(answer)) {\n cancel(\"Reset cancelled.\");\n throw new ZitadelError(\"E_VALIDATION\", \"Reset cancelled by user\");\n }\n if (!answer) {\n return this.emit({ status: \"skipped\", reason: \"reset-cancelled\" });\n }\n }\n\n if (runtime?.backend === \"binary\") {\n const stopResult = await stopBinaryRuntime(runtime.pid);\n if (stopResult.status === \"failed\") {\n throw new ZitadelError(\"E_VALIDATION\", \"Local Zitadel server did not stop\", {\n hint: \"Stop the local runtime manually, then rerun reset.\",\n details: { runtime, stop_result: stopResult },\n });\n }\n } else {\n await stopAndRemoveContainer(containerName);\n }\n await removeLocalData(this.meta.cwd);\n await removeRuntimeMetadata(this.meta.cwd);\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\";\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 * Whether a property name reads as a credential. Splits snake_case,\n * kebab-case and camelCase alike, so `client_secret`, `api-key` and\n * `userToken` all match while `passwordless` — one word that merely starts the\n * same way — does not.\n */\nexport const isSecretKey = (key: string): boolean => {\n const words = 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 return (\n words.some((word) => SECRET_WORDS.has(word)) ||\n SECRET_COMPOUNDS.some((compound) => words.join(\"\").includes(compound))\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/** Refuse a credential that reached the command line, naming a route that does not. */\nexport const refuseSecret = (key: string, source: string): never => {\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 { hint: `Pass the body with ${SECRET_ROUTES}.`, details: { field: key } },\n );\n};\n\n/** The first credential-looking property anywhere in a body, if there is one. */\nexport const findSecretKey = (value: unknown): string | undefined => {\n if (Array.isArray(value)) {\n for (const entry of value) {\n const found = findSecretKey(entry);\n if (found) {\n return found;\n }\n }\n return undefined;\n }\n if (!isObject(value)) {\n return undefined;\n }\n for (const [key, nested] of Object.entries(value)) {\n if (isSecretKey(key)) {\n return key;\n }\n const found = findSecretKey(nested);\n if (found) {\n return found;\n }\n }\n return undefined;\n};\n\n/**\n * A body with every credential-valued property masked. A body may legitimately\n * carry a secret when it arrives by `--file` or stdin, but `--dry-run` prints\n * what would be sent — to a terminal, and to whatever captures CI logs — so the\n * value must not travel with it.\n */\nexport const redactSecrets = (value: unknown): unknown => {\n if (Array.isArray(value)) {\n return value.map((entry) => redactSecrets(entry));\n }\n if (!isObject(value)) {\n return value;\n }\n return Object.fromEntries(\n Object.entries(value).map(([key, nested]) => [\n key,\n isSecretKey(key) ? \"«redacted»\" : redactSecrets(nested),\n ]),\n );\n};\n","import { Args } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../../errors\";\nimport type { CommandResult } from \"../types\";\nimport { redactSecrets } 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]: Args.string({ 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 * 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\". Vowel letter rather than vowel sound, which is right for every\n * resource noun here and wrong only for words like \"hour\".\n */\nexport const article = (phrase: string): string =>\n \"aeiou\".includes(phrase[0]?.toLowerCase() ?? \"\") ? \"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 = (\n schema: Schema,\n value: unknown,\n message: string,\n hint?: string,\n): Json => {\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 as Json;\n};\n\nexport const dryRunResult = (\n verb: string,\n topic: string,\n id?: string,\n body?: Json,\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.\n const shown = body === undefined ? undefined : (redactSecrets(body) 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 { cancel, confirm, isCancel } from \"@clack/prompts\";\nimport { Flags } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../../../errors\";\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 if (!meta.force) {\n if (meta.nonInteractive) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${capitalize(verb)} requires --force in non-interactive mode`,\n {\n hint: `Pass --force to ${verb} ${resource.singular} ${id}.`,\n nextCommands: [publicCliCommand(`${topic} ${verb} ${id} --force`, meta.cliVersion)],\n },\n );\n }\n const answer = await confirm({\n message: `${capitalize(verb)} ${resource.singular} ${id}?`,\n initialValue: false,\n });\n if (isCancel(answer) || !answer) {\n cancel(`${capitalize(verb)} cancelled.`);\n return { status: \"skipped\", reason: `${verb}-cancelled` };\n }\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 { ZitadelError } from \"../../errors\";\nimport { isObject } from \"../../json\";\nimport type { Page } from \"./types\";\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.\n */\nexport const collectPages = async (\n request: (token?: string) => Promise<unknown>,\n {\n items,\n all,\n token,\n nextPageToken,\n }: Readonly<{ items?: string; all: boolean; token?: string; nextPageToken: string }>,\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 --all would never finish\",\n {\n hint: \"Fetch one page at a time with --limit and --page-token, 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","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","/**\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 };\n shape?: Record<string, ZodLike>;\n /** The allowed values of an enum. */\n options?: readonly string[];\n description?: string;\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 = (schema: ZodLike | undefined, depth = MAX_WRAPPER_DEPTH): ZodLike | undefined =>\n schema?.def?.innerType && depth > 0 ? unwrap(schema.def.innerType, depth - 1) : schema;\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 { 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 { spinner } from \"@clack/prompts\";\nimport { Flags } from \"@oclif/core\";\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\": Flags.string({\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: Flags.string({\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: Flags.string({\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: Flags.string({\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\n ? [`<%= config.bin %> ${topic} list --all --json`]\n : []),\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:\n 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 [`${topic} list`, ...repeatedFlags(flags), `--page-token ${shellArg(next)}`, \"--json\"].join(\n \" \",\n ),\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\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 return { ...params, [key]: value };\n }\n return {\n ...params,\n [key]: Array.isArray(existing) ? [...existing, value] : existing === undefined ? [value] : [existing, value],\n };\n }, {});\n","import { Flags } from \"@oclif/core\";\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: Flags.string({\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 = 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 { findSecretKey, refuseSecret } from \"./secrets\";\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. `what` names the command in the stdin hint.\n */\nexport const readRawBody = async (flags: Json, what: string): Promise<Json | undefined> => {\n if (typeof flags.data === \"string\") {\n const body = parseJsonObject(flags.data, \"--data\");\n // `--data` is a flag value like any other, and `--data \"$(cat body.json)\"`\n // is expanded by the shell before the CLI sees it, so a credential here is\n // just as exposed as one in `--attributes`.\n const secret = findSecretKey(body);\n if (secret) {\n refuseSecret(secret, \"--data\");\n }\n return body;\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, type Interfaces } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../../errors\";\nimport { isObject } from \"../../json\";\nimport { isSecretKey, refuseSecret } from \"./secrets\";\nimport type { Json, Schema } from \"./types\";\nimport { unwrap, type ZodLike } 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. Whatever cannot\n * be expressed as a single flag (a nested object, an array) stays reachable\n * through `--data` / `--file`; an open record (a user's `attributes`) gets a\n * repeatable `key=value` flag.\n *\n * Introspection is defensive: an unrecognised schema yields no fields, and\n * the command falls back to the raw-body flags alone.\n */\n\n/** How a field is rendered on the command line. */\nexport type FieldKind = \"string\" | \"number\" | \"boolean\" | \"enum\" | \"record\";\n\nexport type BodyField = Readonly<{\n /** Property name on the wire (`relation`). */\n name: string;\n /** Flag name as typed (`relation`). */\n flag: string;\n kind: FieldKind;\n required: boolean;\n /** Closed value set, for `enum` fields. */\n options?: readonly string[];\n /** One-line summary of the schema's description, used as flag help. */\n summary: string;\n}>;\n\n/** Flags the write commands own; a body field of the same name stays raw-body only. */\nconst RESERVED = new Set([\"data\", \"file\", \"json\", \"cwd\", \"server\", \"force\", \"environment\", \"help\"]);\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\nconst kindOf = (type: ZodLike | undefined): FieldKind | undefined => {\n switch (type?.def?.type) {\n case \"string\":\n return \"string\";\n case \"number\":\n return \"number\";\n case \"boolean\":\n return \"boolean\";\n case \"enum\":\n return \"enum\";\n case \"record\":\n return \"record\";\n // A union of string|null (a clearable field) reads as a plain string flag.\n case \"union\":\n return \"string\";\n default:\n return undefined;\n }\n};\n\n/**\n * Read the body fields of a generated request schema. Returns an empty list\n * for anything that is not a plain object schema, so the caller degrades to\n * `--data` / `--file`.\n */\nexport const describeBody = (schema: Schema): readonly BodyField[] => {\n const shape = (schema as { shape?: Record<string, ZodLike> }).shape;\n if (!isObject(shape)) {\n return [];\n }\n return Object.entries(shape).flatMap(([name, field]): BodyField[] => {\n const flag = kebab(name);\n if (RESERVED.has(flag)) {\n return [];\n }\n const inner = unwrap(field);\n const kind = kindOf(inner);\n if (!kind) {\n return [];\n }\n const options = kind === \"enum\" ? inner?.options : undefined;\n return [\n {\n name,\n flag,\n kind,\n required: !schemaAccepts(schema, name),\n ...(options ? { options } : {}),\n summary: summarize(field.description ?? inner?.description),\n },\n ];\n });\n};\n\n/** Whether the schema accepts a body that omits `name` — i.e. the field is optional. */\nconst schemaAccepts = (schema: Schema, name: string): boolean => {\n const probe = schema.safeParse({});\n if (probe.success) {\n return true;\n }\n const issues = (probe.error?.issues ?? []) as Array<{ path?: unknown[] }>;\n return !issues.some((issue) => issue.path?.length === 1 && issue.path[0] === name);\n};\n\n/** oclif flags for the given fields, grouped so `--help` separates required from optional. */\nexport const bodyFieldFlags = (fields: readonly BodyField[]): Interfaces.FlagInput =>\n Object.fromEntries(\n fields.map((field) => {\n // oclif orders help groups by their first flag alphabetically, so the\n // required marker also rides in the description rather than relying on\n // the group heading coming first.\n const helpGroup = field.required ? \"REQUIRED FIELD\" : \"OPTIONAL FIELD\";\n const description = [\n field.required ? \"(required)\" : \"\",\n field.kind === \"record\"\n ? `Repeatable ${field.name} entry: key=value for a string, key:=value for JSON.`\n : \"\",\n field.summary,\n ]\n .filter(Boolean)\n .join(\" \");\n if (field.kind === \"boolean\") {\n return [field.flag, Flags.boolean({ description, helpGroup })];\n }\n if (field.kind === \"number\") {\n return [field.flag, Flags.integer({ description, helpGroup })];\n }\n if (field.kind === \"record\") {\n return [field.flag, Flags.string({ description, helpGroup, multiple: true })];\n }\n return [\n field.flag,\n Flags.string({\n description,\n helpGroup,\n ...(field.options ? { options: [...field.options] } : {}),\n }),\n ];\n }),\n );\n\n/**\n * Build the body fragment the field flags describe. Returns `undefined` when\n * no field flag was given, so the caller can tell \"no body at all\" from\n * \"a body made of flags\".\n */\nexport const bodyFromFlags = (fields: readonly BodyField[], flags: Json): Json | undefined => {\n const collected = fields.flatMap((field): Array<[string, unknown]> => {\n const value = flags[field.flag];\n if (value === undefined) {\n return [];\n }\n if (field.kind === \"record\") {\n const pairs = (Array.isArray(value) ? value : [value]).map((entry) =>\n parsePair(String(entry), field.flag),\n );\n return [[field.name, Object.fromEntries(pairs)]];\n }\n return [[field.name, value]];\n });\n return collected.length > 0 ? Object.fromEntries(collected) : undefined;\n};\n\n/**\n * One entry of a repeatable record flag.\n *\n * `key=value` is always a string, so an identifier that looks numeric (a postal\n * code, a phone number) survives intact. `key:=value` parses the value as JSON,\n * which is how a field the customer's schema declares as a number, a boolean,\n * null, an array, or an object is set — the same split HTTPie uses. Keeping the\n * two explicit means the CLI never has to guess which one was meant.\n */\nconst parsePair = (raw: string, flag: string): readonly [string, unknown] => {\n const json = raw.indexOf(\":=\");\n const plain = raw.indexOf(\"=\");\n const hint = `Use --${flag} key=value for a string, or key:=value for JSON (e.g. --${flag} age:=30).`;\n if (json > 0 && json === plain - 1) {\n const key = secretChecked(raw.slice(0, json), flag);\n const value = raw.slice(json + 2);\n try {\n return [key, JSON.parse(value) as unknown];\n } catch {\n throw new ZitadelError(\"E_VALIDATION\", `--${flag} ${key}:= expects JSON, got \"${value}\"`, {\n hint: `Quote a JSON value, e.g. --${flag} ${key}:=30, ${key}:=true, or ${key}:='{\"a\":1}'. For a plain string use ${key}=${value}.`,\n });\n }\n }\n if (plain <= 0) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid --${flag} \"${raw}\"`, { hint });\n }\n return [secretChecked(raw.slice(0, plain), flag), raw.slice(plain + 1)];\n};\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) {\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\n\n/** A record key, refused when it names a credential. */\nconst secretChecked = (key: string, flag: string): string =>\n isSecretKey(key) ? refuseSecret(key, `--${flag}`) : key;\n","import { Flags } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../../../errors\";\nimport { isObject } from \"../../../json\";\nimport { publicCliCommand } from \"../../../public-cli\";\nimport type { CommandResult, GlobalOptions } from \"../../types\";\nimport { readRawBody } from \"../body\";\nimport { bodyFieldFlags, bodyFromFlags, describeBody, fieldExample } from \"../fields\";\nimport { article, dryRunResult, idArg, idName, parseOrThrow } from \"../shared\";\nimport type {\n CreateSpec,\n Json,\n ResourceCommandOptions,\n ResourceDescriptor,\n UpdateSpec,\n} from \"../types\";\nimport {\n type OperationDefinition,\n type OperationInput,\n type OperationStatics,\n ResourceCommand,\n} from \"./command\";\n\n/** `--data` / `--file`: the whole body at once, for anything the field flags cannot express. */\nconst rawBodyFlags = {\n data: Flags.string({\n // No `-d`: the CLI conventions reserve that short form for `--debug`.\n description: \"Whole body as a JSON object, instead of the field flags.\",\n exclusive: [\"file\"],\n helpGroup: \"RAW BODY\",\n }),\n file: Flags.string({\n description: \"Read the body from a JSON file; `-` reads stdin.\",\n exclusive: [\"data\"],\n helpGroup: \"RAW BODY\",\n }),\n};\n\n/**\n * `<topic> create` and `<topic> update <id>` share everything but the id\n * argument. The body comes from one flag per schema field, from `--data` /\n * `--file`, or from both — a field flag overrides the same key in the raw\n * body. It is validated against the request schema before the call, and the\n * resource is echoed back with a `next_commands` hint at the matching `get`.\n */\nconst describeWrite = <Ctx, Spec extends { readonly schema: CreateSpec<Ctx>[\"schema\"] }>(\n { topic, resource, spec }: OperationDefinition<Ctx, Spec>,\n options: ResourceCommandOptions<Ctx>,\n verb: \"create\" | \"update\",\n): OperationStatics => {\n const fields = describeBody(spec.schema);\n const example = fieldExample(fields);\n const target = verb === \"create\" ? topic : `${topic} 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\n ? [`<%= config.bin %> ${target.replace(topic, `${topic} ${verb}`)} ${example} --json`]\n : []),\n `<%= config.bin %> ${topic} ${verb}${verb === \"update\" ? \" <id>\" : \"\"} --data '{...}' --json`,\n `<%= config.bin %> ${topic} ${verb}${verb === \"update\" ? \" <id>\" : \"\"} --file ./${resource.singular}.json`,\n ],\n flags: { ...bodyFieldFlags(fields), ...rawBodyFlags, ...options.flags },\n args: verb === \"create\" ? {} : idArg(resource),\n };\n};\n\nabstract class WriteOperation<\n Ctx,\n Spec extends { 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 } = this.definition;\n const idKey = idName(resource);\n const id = typeof args[idKey] === \"string\" ? (args[idKey] as string) : undefined;\n\n const raw = await readRawBody(flags, `${topic} ${this.verb}`);\n // A field flag wins over the same key in --data / --file.\n const fields = describeBody(spec.schema);\n const fromFlags = bodyFromFlags(fields, flags);\n if (!raw && !fromFlags) {\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\\`), or --data '<json>' / --file <path>.`,\n });\n }\n // Required fields are not oclif-required — `--data` / `--file` may carry\n // them — so presence is checked here, once both sources are merged, and\n // reported as the flags the caller is missing rather than as schema issues.\n const merged = { ...raw, ...fromFlags };\n const missing = fields.filter((field) => field.required && merged[field.name] === undefined);\n if (missing.length > 0) {\n const flagNames = missing.map((field) => `--${field.flag}`);\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 body = parseOrThrow(spec.schema, merged, \"Body does not match the API schema\");\n if (meta.dryRun) {\n return dryRunResult(this.verb, topic, id, body);\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 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 } 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\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 // 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.schema) } : {}),\n ...(resource.update ? { update_fields: fieldsOf(resource.update.schema) } : {}),\n };\n });\n\n/** A write's fields as an agent needs them: flag, kind, whether it is required. */\nconst fieldsOf = (schema: Parameters<typeof describeBody>[0]): readonly Json[] =>\n describeBody(schema).map((field) => ({\n name: field.name,\n flag: `--${field.flag}`,\n kind: field.kind,\n required: field.required,\n ...(field.options ? { options: [...field.options] } : {}),\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 { bodyFieldFlags, bodyFromFlags, describeBody, fieldExample } from \"./fields\";\nexport type { BodyField, FieldKind } from \"./fields\";\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 { Flags } from \"@oclif/core\";\nimport {\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 GetEnvironmentByNameResponse,\n GetFlowDefinitionResponse,\n CreateIdpBody,\n GetGrantResponse,\n GetProjectResponse,\n GetSessionResponse,\n GetReleaseByIdResponse,\n GetSchemaByIdResponse,\n GetIdpByIdResponse,\n GetTeamResponse,\n GetUserByIDResponse,\n ListBrandingResponse,\n ListEnvironmentsResponse,\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 type {\n CreateGrantBody as CreateGrantBodyT,\n CreateIdpBody as CreateIdpBodyT,\n CreateTeamBody as CreateTeamBodyT,\n CreateUserBody as CreateUserBodyT,\n ListEnvironmentsParams,\n ListEventsParams,\n ListFlowDefinitionsParams,\n ListReleasesParams,\n ListSchemasParams,\n PatchProjectBody as PatchProjectBodyT,\n PatchUserByIDBody as PatchUserByIDBodyT,\n QueryGrantsBody as QueryGrantsBodyT,\n QueryIdpsBody as QueryIdpsBodyT,\n QueryProjectsBody as QueryProjectsBodyT,\n QuerySessionsBody as QuerySessionsBodyT,\n QueryTeamsBody as QueryTeamsBodyT,\n QueryUsersBody as QueryUsersBodyT,\n UpdateTeamBody as UpdateTeamBodyT,\n} from \"@zitadel/api/generated/model\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient, type ZitadelClient } from \"../lib/api-client\";\nimport { environmentSchema } from \"../lib/environment\";\nimport { CommandGroups } from \"../lib/oclif/groups\";\nimport { ZitadelError } from \"../lib/errors\";\nimport { buildResourceCommands, type ResourceRegistry } 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/** 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: {\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 // The users query binds to the token's project; no project_id param.\n call: ({ client }, body) => client.queryUsers(body as QueryUsersBodyT),\n },\n get: { call: ({ client }, id) => client.getUserByID(id), response: GetUserByIDResponse },\n create: {\n schema: CreateUserBody,\n call: ({ client, projectId }, body) =>\n client.createUser(body as CreateUserBodyT, { project_id: projectId }),\n },\n update: {\n schema: PatchUserByIDBody,\n call: ({ client }, id, body) => client.patchUserByID(id, body as PatchUserByIDBodyT),\n },\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: {\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) =>\n client.queryTeams(body as QueryTeamsBodyT, { project_id: projectId }),\n },\n get: { call: ({ client }, id) => client.getTeam(id), response: GetTeamResponse },\n create: {\n schema: CreateTeamBody,\n call: ({ client, projectId }, body) =>\n client.createTeam(body as CreateTeamBodyT, { project_id: projectId }),\n },\n update: {\n schema: UpdateTeamBody,\n call: ({ client }, id, body) => client.updateTeam(id, body as UpdateTeamBodyT),\n },\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: {\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) =>\n client.querySessions(body as QuerySessionsBodyT, { 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 } as ListEventsParams),\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: [\n \"user.user_id\",\n \"team.team_id\",\n \"relation\",\n \"object_type\",\n \"created_at\",\n \"expires_at\",\n ],\n 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) =>\n client.queryGrants(body as QueryGrantsBodyT, { project_id: projectId }),\n },\n get: {\n call: ({ client, projectId }, id) => client.getGrant(id, { project_id: projectId }),\n response: GetGrantResponse,\n },\n create: {\n schema: CreateGrantBody,\n call: ({ client, projectId }, body) =>\n client.createGrant(body as CreateGrantBodyT, { project_id: projectId }),\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: {\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) =>\n client.queryIdps(body as QueryIdpsBodyT, { project_id: projectId }),\n },\n get: {\n call: ({ client, projectId }, id) => client.getIdpById(id, { project_id: projectId }),\n response: GetIdpByIdResponse,\n },\n create: {\n // The body nests everything under `idp`, so there are no field flags to\n // generate; `--data` and `--file` carry it.\n schema: CreateIdpBody,\n call: ({ client, projectId }, body) =>\n client.createIdp(body as CreateIdpBodyT, { project_id: projectId }),\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\", \"preview_origins\", \"created_at\", \"updated_at\"],\n list: {\n items: \"projects\",\n body: QueryProjectsBody,\n response: QueryProjectsResponse,\n filters: [\n { field: \"created_at\", operations: FILTER_OPERATIONS },\n ],\n sorts: [\"created_at\"],\n call: ({ client }, body) => client.queryProjects(body as QueryProjectsBodyT),\n },\n get: { call: ({ client }, id) => client.getProject(id), response: GetProjectResponse },\n update: {\n schema: PatchProjectBody,\n call: ({ client }, id, body) => client.patchProject(id, body as PatchProjectBodyT),\n },\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 } as ListSchemasParams),\n },\n get: {\n response: GetSchemaByIdResponse,\n // A schema is addressed two ways. `sch_…`, or the customer's own `$id`\n // URI, names one immutable revision and fetches directly. Anything else\n // is an object type, which the endpoint resolves to the current revision\n // in a single call. The API has no fetch-by-object-type route yet; when\n // it does, this collapses to one client call like every other `get`.\n call: async ({ client, projectId }, ref) => {\n if (ref.startsWith(\"sch_\") || ref.includes(\"://\")) {\n return client.getSchemaById(ref);\n }\n const page = await client.listSchemas({\n project_id: projectId,\n object_type: ref,\n revisions: \"latest\",\n limit: 1,\n } as ListSchemasParams);\n const current = page.schemas[0];\n if (!current) {\n throw new ZitadelError(\"E_NOT_FOUND\", `No schema for object type \"${ref}\"`, {\n hint: \"Run `schemas list` to see the object types this project has.\",\n });\n }\n return current;\n },\n },\n },\n\n environments: {\n group: CommandGroups.configuration,\n singular: \"environment\",\n idField: \"id\",\n // Addressed by its public handle: `GET /environments/{name}`, and the name\n // is what a deploy target is called everywhere else in the CLI.\n idArg: \"name\",\n columns: [\"name\", \"id\", \"created_at\"],\n heading: \"name\",\n detail: [\"name\", \"id\", \"project_id\", \"created_at\"],\n list: {\n items: \"environments\",\n response: ListEnvironmentsResponse,\n call: ({ client, projectId }, params) =>\n client.listEnvironments({ ...params, project_id: projectId } as ListEnvironmentsParams),\n },\n get: {\n call: ({ client, projectId }, name) =>\n client.getEnvironmentByName(name, { project_id: projectId }),\n response: GetEnvironmentByNameResponse,\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 } as ListReleasesParams),\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 } as ListFlowDefinitionsParams),\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 } as ListFlowDefinitionsParams);\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 flags: {\n environment: Flags.string({\n char: \"e\",\n description: \"Target environment (default: development).\",\n options: [...environmentSchema.options],\n }),\n },\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, depending on whether setup already ejected\n * a starter design. With a design, revision 1 is already live and the\n * template is repo-owned — point at the files and the plan/apply loop.\n * Without one, point at `branding eject` so the built-in template's\n * customization path stays discoverable after setup.\n */\nexport function brandingGuidanceAction(\n design: string | undefined,\n cliVersion: string,\n): string {\n if (design) {\n return (\n `Make the login yours: the ${design} design is live as branding revision 1. ` +\n \"Edit .zitadel/branding/login.liquid (logo and hero image URLs live in \" +\n `branding.json), then ${publicCliCommand(\"plan\", cliVersion)} and ` +\n `${publicCliCommand(\"apply\", cliVersion)} to publish the next revision.`\n );\n }\n return (\n \"Change how the login looks: \" +\n `${publicCliCommand(\"branding eject\", cliVersion)} scaffolds .zitadel/branding/ ` +\n \"from a starter design (centered, split, split-right, hero, minimal) for you to edit.\"\n );\n}\n","import { createZitadelClient } from \"@zitadel/api/client\";\n\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.\n const cookie = await adminSessionCookie(serverUrl, admin);\n const { team_id, claimed_at } = await createZitadelClient({ baseUrl: serverUrl }).completeClaim(\n projectId,\n { challenge_id },\n localAdminRequest(serverUrl, { cookie }),\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 */\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 { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { consola } from \"consola\";\n\nimport type {\n CreateBranding201,\n CreateBrandingBody,\n CreateFlowDefinition201,\n CreateSchema201,\n CreateSchemaBody,\n GetSchemaById200,\n} from \"@zitadel/api/generated/model\";\nimport type { ZitadelClient } from \"@zitadel/api/client\";\nimport {\n DEFAULT_BRANDING_CONFIG_PATH,\n DEFAULT_BRANDING_TEMPLATE_PATH,\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 brandingReadmeContent,\n flowsReadmeContent,\n getDefaultBrandingConfig,\n getDefaultHumanUserSchema,\n getDefaultLoginFlow,\n schemasReadmeContent,\n type SetupPreset,\n type SetupUseCase,\n} from \"@zitadel/config/defaults\";\nimport { BRANDING_FILE_SCHEMA_REF } from \"@zitadel/config/meta-schemas\";\n\nimport { normalizeFlowBody, normalizeSchemaBody } from \"@zitadel/config/normalize\";\n\nimport { BRANDING_DIR, toBrandingWireBody } from \"./branding\";\nimport { FLOWS_DIR } from \"./flows\";\nimport { stableStringify } from \"./json\";\nimport { normalizePublicCliProse } from \"./public-cli\";\nimport { hashForState, writeBackResource } 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`, and the flow file can only be rendered after that id comes\n * back because `flow_definition.user_schema` must reference it.\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 * Login design to eject into `.zitadel/branding/` and publish as branding\n * revision 1. When absent, no branding files are scaffolded and the login\n * renders the built-in template (the `branding eject` command opts in later).\n */\n design?: string;\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\n const { $id: _templateId, ...schemaBody } = getDefaultHumanUserSchema({ preset, useCase }) as {\n $id?: string;\n } & Record<string, unknown>;\n void _templateId;\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 const schemaId = requiredString(schema.id, \"created schema id\");\n // Reconcile the just-written file with the server's stored body so local\n // config matches live state from the first second; a fetch failure keeps\n // the template body and its hash (parity is best-effort at setup).\n let schemaHash = hashForState({ normalize: normalizeSchemaBody }, schemaBody);\n try {\n // The response is the `{id, schema, metadata}` envelope; the local config\n // file keeps only the customer-authored document.\n const canonical = (\n (await opts.client.getSchemaById(\n encodeURIComponent(schemaId),\n )) as unknown as GetSchemaById200\n ).schema;\n const written = await writeBackResource(\n opts.cwd,\n DEFAULT_SCHEMA_CONFIG_PATH,\n { normalize: normalizeSchemaBody },\n canonical,\n );\n schemaHash = written.hash;\n } catch (err) {\n consola.debug(`fetch created schema ${schemaId} during setup failed:`, err);\n }\n await updateState(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH, {\n id: schemaId,\n hash: schemaHash,\n });\n\n const flowBody = getDefaultLoginFlow({ userSchemaUrl: schemaId, preset, useCase });\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 let flowHash = hashForState({ normalize: normalizeFlowBody }, flowBody);\n if (flow.flow_definition) {\n const written = await writeBackResource(\n opts.cwd,\n DEFAULT_FLOW_CONFIG_PATH,\n { normalize: normalizeFlowBody, normalizeWrite: normalizeFlowBody },\n flow.flow_definition as object,\n );\n flowHash = written.hash;\n }\n await updateState(opts.cwd, DEFAULT_FLOW_CONFIG_PATH, {\n id: requiredString(flow.id, \"created flow definition id\"),\n hash: flowHash,\n name: flowBody.name,\n status: flowBody.status,\n });\n\n if (opts.design) {\n await mkdir(join(opts.cwd, BRANDING_DIR), { recursive: true });\n const { branding, template } = getDefaultBrandingConfig(opts.design);\n const descriptor = { $schema: BRANDING_FILE_SCHEMA_REF, ...branding };\n\n if (await writeResourceFile(opts.cwd, DEFAULT_BRANDING_CONFIG_PATH, descriptor, opts.force)) {\n filesWritten.push(join(opts.cwd, DEFAULT_BRANDING_CONFIG_PATH));\n }\n if (await writeRawFile(opts.cwd, DEFAULT_BRANDING_TEMPLATE_PATH, template, opts.force)) {\n filesWritten.push(join(opts.cwd, DEFAULT_BRANDING_TEMPLATE_PATH));\n }\n\n const brandingNormalize = (data: object): object => toBrandingWireBody(opts.cwd, data);\n const created = (await opts.client.createBranding(\n brandingNormalize(descriptor) as CreateBrandingBody,\n { project_id: opts.projectId },\n )) as CreateBranding201;\n await updateState(opts.cwd, DEFAULT_BRANDING_CONFIG_PATH, {\n id: requiredString(created.id, \"created branding revision id\"),\n hash: hashForState({ normalize: brandingNormalize }, descriptor),\n });\n\n const brandingReadme = join(BRANDING_DIR, \"README.md\");\n if (\n await writeReadmeFile(\n opts.cwd,\n brandingReadme,\n normalizePublicCliProse(brandingReadmeContent(), opts.cliVersion),\n )\n ) {\n filesWritten.push(join(opts.cwd, brandingReadme));\n }\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 * Write a non-JSON scaffold file (the `.liquid` template) with the same\n * conflict semantics as {@link writeResourceFile}: `--force` overwrites,\n * otherwise an existing file is an `E_CONFLICT`.\n */\nasync function writeRawFile(\n cwd: string,\n relPath: string,\n content: string,\n force: boolean,\n): Promise<boolean> {\n const dest = join(cwd, relPath);\n await mkdir(dirname(dest), { recursive: true });\n try {\n await writeFile(dest, content, force ? undefined : { flag: \"wx\" });\n return true;\n } catch (error) {\n if (isErrno(error, \"EEXIST\")) {\n throw new ZitadelError(\"E_CONFLICT\", `${relPath} already exists`, {\n hint: \"Move the file aside or rerun setup with --force if you want setup to replace it.\",\n });\n }\n throw error;\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(\n cwd: string,\n relPath: string,\n content: string,\n): 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\nasync function writeResourceFile(\n cwd: string,\n relPath: string,\n body: object,\n force: boolean,\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 new ZitadelError(\"E_CONFLICT\", `${relPath} already exists`, {\n hint: \"Move the file aside or rerun setup with --force if you want setup to replace it.\",\n });\n }\n throw error;\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 {\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 { cancel, isCancel } from \"@clack/prompts\";\n\nimport { ZitadelError } from \"../../../lib/errors\";\n\n/**\n * Converts a clack cancellation (Ctrl-C) into a thrown `E_VALIDATION` rather\n * than a partial answer. Every prompt funnels its clack return value through\n * this so the wizard never proceeds with a sentinel or missing value.\n */\nexport function bail<T>(value: T | symbol): asserts value is T {\n if (isCancel(value)) {\n cancel(\"Setup cancelled.\");\n throw new ZitadelError(\"E_VALIDATION\", \"Setup cancelled by user\");\n }\n}\n","import { select } from \"@clack/prompts\";\n\nimport { BRANDING_DESIGNS, type BrandingDesign } from \"@zitadel/config/defaults\";\n\nimport { BRANDING_DESIGN_INFO } from \"../../../lib/branding/designs\";\n\nimport { bail } from \"./cancel\";\nimport type { PromptContext, SetupAnswers, SetupPrompt } from \"./types\";\n\n/**\n * Sentinel select value for \"keep the built-in login\" — clack option values\n * must be strings, and `undefined` in {@link SetupAnswers.design} is the\n * real representation of that choice.\n */\nconst BUILT_IN = \"built-in\";\n\n/**\n * \"How should the login look?\" — the last wizard question (#676). Asks after\n * the sign-in preset so the order tells a story: the use case owns what is\n * collected, the preset owns how users authenticate, the design owns how\n * that experience looks.\n *\n * The built-in default is preselected and writes nothing. Picking a starter\n * design forks its Liquid template into `.zitadel/branding/` and publishes\n * it as branding revision 1 — from then on the template is repo-owned and\n * stops tracking built-in improvements, so the option labels make the\n * file-write explicit and keep ownership an opt-in. `--design` is\n * authoritative; non-interactive runs keep the built-in template.\n */\nexport class DesignPrompt implements SetupPrompt {\n async ask(answers: SetupAnswers, ctx: PromptContext): Promise<SetupAnswers> {\n if (ctx.designFromFlag) {\n return answers;\n }\n const value = await select({\n message:\n \"How should the login look? A starter design adds its editable template to .zitadel/branding/.\",\n initialValue: (answers.design as string | undefined) ?? BUILT_IN,\n options: [\n {\n value: BUILT_IN,\n label: \"Built-in\",\n hint: \"no files added; pick a design anytime later with `branding eject`\",\n },\n ...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 bail(value);\n if (value === BUILT_IN) {\n return { ...answers, design: undefined };\n }\n return { ...answers, design: value as BrandingDesign };\n }\n}\n","import { text } from \"@clack/prompts\";\n\nimport { bail } from \"./cancel\";\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 value = await text({\n message: \"Dev server port\",\n placeholder: String(answers.devPort),\n initialValue: String(answers.devPort),\n validate: (input) => {\n const num = Number.parseInt(input ?? \"\", 10);\n return Number.isFinite(num) && num > 0 && num < 65536\n ? undefined\n : \"Must be a port number\";\n },\n });\n bail(value);\n return { ...answers, devPort: Number.parseInt(String(value), 10) };\n }\n}\n","import { confirm } from \"@clack/prompts\";\n\nimport { ZitadelError } from \"../../../lib/errors\";\nimport { bail } from \"./cancel\";\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`).\n */\nexport class FrameworkConfirmPrompt implements SetupPrompt {\n async ask(answers: SetupAnswers, ctx: PromptContext): Promise<SetupAnswers> {\n const ack = await confirm({\n message: `Detected ${ctx.framework.id}. Proceed?`,\n initialValue: true,\n });\n bail(ack);\n if (ack === false) {\n throw new ZitadelError(\n \"E_UNSUPPORTED_PROJECT_SHAPE\",\n \"Setup cancelled — framework declined\",\n { hint: `Re-run with --framework ${ctx.framework.id} when ready.` },\n );\n }\n return answers;\n }\n}\n","import { select, spinner, text } from \"@clack/prompts\";\n\nimport { detectHealthyLocalServer } from \"../../../lib/local-server/runtime\";\nimport { DEFAULT_SERVER } from \"../../../lib/server\";\nimport { bail } from \"./cancel\";\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 (`detectHealthyLocalServer`: 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 select({\n message: \"Which server should zitadel.json point to?\",\n options: [\n {\n value: DEFAULT_SERVER,\n label: \"Zitadel Cloud (api.zitadel.cloud)\",\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 bail(choice);\n if (choice !== CUSTOM) {\n return { ...answers, server: choice as string };\n }\n const custom = await text({\n message: \"Server URL\",\n placeholder: \"https://zitadel.internal\",\n validate: (value) => {\n try {\n new URL(value ?? \"\");\n return;\n } catch {\n return \"Must be a valid URL\";\n }\n },\n });\n bail(custom);\n return { ...answers, server: custom as string };\n }\n}\n\n/**\n * Wraps {@link detectHealthyLocalServer} 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 detectHealthyLocalServer(cwd);\n s.stop(\n detected\n ? `Found local Zitadel server at ${detected}.`\n : \"No local Zitadel server detected.\",\n );\n return detected;\n}\n","import { select } from \"@clack/prompts\";\n\nimport { SETUP_PRESETS, type SetupPreset } from \"@zitadel/config/defaults\";\n\nimport { bail } from \"./cancel\";\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, passkey optional during registration\",\n \"passkey-first\": \"Passkey first — one-tap passkey up front, email + password fallback\",\n };\n const value = await select({\n message: \"How should users sign in?\",\n initialValue: answers.preset,\n options: SETUP_PRESETS.map((preset) => ({ value: preset, label: labels[preset] })),\n });\n bail(value);\n return { ...answers, preset: value as SetupPreset };\n }\n}\n","import { select } from \"@clack/prompts\";\n\nimport { SETUP_USE_CASES, type SetupUseCase } from \"@zitadel/config/defaults\";\n\nimport { bail } from \"./cancel\";\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 value = await select({\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 bail(value);\n return { ...answers, useCase: value as SetupUseCase };\n }\n}\n","import { intro, select } from \"@clack/prompts\";\n\nimport { bail } from \"./cancel\";\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 ): Promise<string> {\n intro(\"Zitadel setup — new project\");\n const picked = await select({\n message: \"Choose a framework to scaffold\",\n options: choices.map((choice) => ({ value: choice.id, label: choice.displayName })),\n });\n bail(picked);\n return picked as string;\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 { DesignPrompt } from \"./design\";\nimport { DevPortPrompt } from \"./dev-port\";\nimport { FrameworkConfirmPrompt } from \"./framework-confirm\";\nimport { ServerPrompt } from \"./server\";\nimport { SignInPresetPrompt } from \"./sign-in-preset\";\nimport type { SetupPrompt } from \"./types\";\nimport { UseCasePrompt } from \"./use-case\";\n\nexport type { PromptContext, SetupAnswers, SetupPrompt } from \"./types\";\nexport { bail } from \"./cancel\";\nexport { DesignPrompt } from \"./design\";\nexport { DevPortPrompt } from \"./dev-port\";\nexport { FrameworkConfirmPrompt } from \"./framework-confirm\";\nexport { ServerPrompt } from \"./server\";\nexport { SignInPresetPrompt } from \"./sign-in-preset\";\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 DesignPrompt(),\n];\n","import { readFile, stat } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport type { BrandingDesign } from \"@zitadel/config/defaults\";\nimport pc from \"picocolors\";\n\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 if (range) {\n facts.frameworkVersion = stripRange(range);\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 depFromFramework(framework: string): string {\n switch (framework) {\n case \"next\":\n return \"next\";\n case \"nuxt\":\n return \"nuxt\";\n default:\n return framework;\n }\n}\n\nfunction prettyFramework(framework: string): string {\n switch (framework) {\n case \"next\":\n return \"Next.js\";\n case \"nuxt\":\n return \"Nuxt\";\n default:\n return framework;\n }\n}\n\n/** Strips `^`/`~`/`>=`/`v` prefixes from an npm range so the version reads cleanly in the summary. */\nfunction stripRange(range: string): string {\n const trimmed = range.replace(/^([\\^~]|>=?|v)/, \"\").trim();\n // Take the first dotted segment so multi-range strings (`^15.0.0 || ^14.0.0`)\n // collapse to a single readable version in the report.\n const first = trimmed.split(/\\s+/)[0];\n return first ?? trimmed;\n}\n\n/** Returns just the file name from a relative path, for the `→ filename` secondary detail in PACKAGE rows. */\nexport function fileNameOf(p: string): string {\n return basename(p);\n}\n\n/**\n * Layout caveats for the chosen login design, shown to humans after the\n * summary box and carried in the JSON envelope's `warnings`.\n *\n * The split family's brand pane is keyed to the **login's own container**\n * width — a `@container (max-width: 48rem)` query on the widget's mount, not\n * a viewport media query. Above that the pane renders; below it the pane is\n * `display: none` and the compact brand mark takes its place — and the split\n * template only emits that mark when `branding.json` names `logo_url` or\n * `hero_url`, so without one the narrow layout loses the branding entirely.\n *\n * Independent of posture, because the container query is: a full-page login\n * hits the same collapse on a phone that an embedded card hits in a sidebar.\n * Gating on `widget` would have been a guess about the container, and a wrong\n * one in both directions — the wrapper setup scaffolds for a widget is\n * full-width (the pane renders there), and a page-posture login on a phone is\n * exactly the narrow case the advice is for. `hero` stays quiet: its compact\n * fallback is editable text, so a narrow container never leaves it blank.\n */\nexport function designWarnings(design?: BrandingDesign): string[] {\n if (design !== \"split\" && design !== \"split-right\") {\n return [];\n }\n return [\n `The ${design} design shows its brand pane only when the login's container is wide; a narrow container — a card-width embed, or any phone-width viewport — collapses it to the compact brand mark. Set logo_url (or hero_url) in .zitadel/branding/branding.json so that mark isn't empty.`,\n ];\n}\n","import { rm } 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 BRANDING_DESIGNS,\n DEFAULT_SETUP_PRESET,\n DEFAULT_SETUP_USE_CASE,\n SETUP_PRESETS,\n SETUP_USE_CASES,\n type BrandingDesign,\n type SetupPreset,\n type SetupUseCase,\n} from \"@zitadel/config/defaults\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"../../lib/api-client\";\nimport { brandingDesignLabel } from \"../../lib/branding/designs\";\nimport { renderBoxActions, wrapForBox } from \"../../lib/box\";\nimport {\n claimAction,\n claimBoxAction,\n claimCommand,\n claimState,\n claimWindowDeadline,\n} from \"../../lib/claim-state\";\nimport { toZitadelError, ZitadelError } from \"../../lib/errors\";\nimport { brandingGuidanceAction } from \"../../lib/journey-guidance\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../../lib/oclif\";\nimport { serverKind } from \"../../lib/oclif/server-kind\";\nimport { readLocalAdmin } from \"../../lib/local-server/admin-credential\";\nimport { claimProjectAsAdmin } from \"../../lib/local-server/claim-as-admin\";\nimport { readPlatformRuntime } from \"../../lib/local-server/runtime\";\nimport { readZitadelSecret, writeZitadelSecret } from \"../../lib/project\";\nimport {\n createOrca,\n inspectScaffoldTarget,\n issuerFromPort,\n type FrameworkFacts,\n type Orca,\n type ScaffoldTarget,\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 { 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 materializeSetupResources,\n type MaterializeSetupResourcesResult,\n} from \"../../lib/setup-resources\";\nimport { installDependenciesForSetup } from \"./install\";\nimport { PickFrameworkPrompt, SETUP_PROMPTS, type SetupAnswers } from \"./prompts\";\nimport {\n designWarnings,\n detectProjectFacts,\n dim as styleDim,\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\";\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(\n (id) => !AVAILABLE_RENDERER_IDS.includes(id),\n);\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 (or, for an empty directory, scaffolds then re-detects) the\n * framework, runs the wizard prompts to fill in any answers not pre-supplied\n * by flags, creates the remote project without server fallback defaults,\n * patches the local files via `Orca`'s framework patcher, then scaffolds and\n * uploads editable schema/flow 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({ char: \"f\", description: \"Overwrite managed files that already exist.\" }),\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.\",\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 design: Flags.string({\n description:\n \"Login design to eject into .zitadel/branding/ and publish as branding revision 1. Skips the wizard's design question. When omitted in non-interactive runs, the login uses the built-in template; run the `branding eject` command later to customize. Split-family designs (split, split-right, hero) collapse their brand pane by container width: narrow containers — including widget-posture embeds at card width — render the compact brand mark instead (logo_url, else hero_url, from .zitadel/branding/branding.json; hero falls back to editable text).\",\n options: [...BRANDING_DESIGNS],\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Setup);\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 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\n const orca = createOrca();\n\n consola.start(`Detecting framework in ${shortPath(cwd)}`);\n let framework: FrameworkFacts;\n let scaffoldedFramework = false;\n try {\n framework = await orca.detect(cwd, flags.framework);\n consola.success(\n `Detected ${framework.id}${framework.devPort ? ` (dev port ${framework.devPort})` : \"\"}`,\n );\n } catch (error) {\n if (\n error instanceof ZitadelError &&\n error.code === \"E_FRAMEWORK_NOT_DETECTED\"\n ) {\n const target = await inspectScaffoldTarget(cwd);\n if (!target.scaffoldable) {\n throw frameworkDetectionWithScaffoldTarget(error, cwd, target);\n }\n consola.info(\"Fresh app directory — scaffolding a fresh project\");\n framework = await orca.scaffold(\n cwd,\n await resolveScaffoldFramework(flags.framework, nonInteractive, orca),\n );\n scaffoldedFramework = true;\n consola.success(`Scaffolded ${framework.id} skeleton`);\n } else {\n throw error;\n }\n }\n\n this.recordTelemetry({\n framework: framework.id,\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 design: flags.design ?? \"built-in\",\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 const devPort = flags[\"dev-port\"];\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 framework = {\n ...framework,\n devPort,\n url: issuerFromPort(devPort),\n };\n }\n\n let answers: SetupAnswers = {\n server: this.meta.source,\n devPort: framework.devPort,\n preset: (flags.preset as SetupPreset | undefined) ?? DEFAULT_SETUP_PRESET,\n useCase: (flags[\"use-case\"] as SetupUseCase | undefined) ?? DEFAULT_SETUP_USE_CASE,\n design: flags.design as BrandingDesign | undefined,\n };\n\n if (!nonInteractive && !dryRun) {\n intro(\"Zitadel setup\");\n const promptCtx = {\n framework,\n cwd,\n serverFlag: this.meta.serverFlag,\n devPortFromFlag: flags[\"dev-port\"] !== undefined,\n presetFromFlag: flags.preset !== undefined,\n useCaseFromFlag: flags[\"use-case\"] !== undefined,\n designFromFlag: flags.design !== undefined,\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, use\n // case, and design 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 design: answers.design ?? \"built-in\",\n });\n\n const issuer = issuerFromPort(answers.devPort);\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 framework = { ...framework, devPort: answers.devPort, url: issuer };\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, framework.id);\n // Register the app's own origin so the backend's origin check allows\n // requests the dev proxy forwards from it.\n const 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, design, 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: framework.id,\n preset: answers.preset,\n useCase: answers.useCase,\n design: answers.design,\n devPort: answers.devPort,\n },\n );\n consola.success(`Created project ${project.id}`);\n this.recordTelemetry({ step: \"project_created\" });\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(framework.id, scaffoldedFramework);\n const ctx: PatchContext = {\n framework,\n rendererId: flags.renderer ?? \"react\",\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 consola.start(`Patching project files${dryRun ? \" (dry run)\" : \"\"}`);\n const result = await orca.patcherFor(framework.id).patch(ctx, { cwd, dryRun, force });\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 let resourceResult: MaterializeSetupResourcesResult;\n try {\n resourceResult = dryRun\n ? { filesWritten: [] }\n : await materializeSetupResources({\n cwd,\n // Verbatim: the canonical bodies are written back to the project.\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 design: answers.design,\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.\n await rm(join(cwd, \"zitadel.json\"), { force: true });\n await rm(join(cwd, \".zitadel/secret\"), { force: true });\n const cause = toZitadelError(error);\n throw new ZitadelError(cause.code, `Default resource setup failed: ${cause.message}`, {\n hint:\n \"The project was created but its default schema/flow upload did not finish. \" +\n \"Re-run `zitadel setup` to start over (add --force to overwrite partially \" +\n \"written .zitadel files).\",\n nextCommands: [\"zitadel setup --force\"],\n details: cause.details,\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 consola.success(\n `Patched ${allFilesWritten.length} file${allFilesWritten.length === 1 ? \"\" : \"s\"}` +\n (result.filesSkipped.length > 0 ? ` (${result.filesSkipped.length} unchanged)` : \"\"),\n );\n this.recordTelemetry({\n step: \"files_patched\",\n files_written_count: allFilesWritten.length,\n });\n\n if (!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({\n framework,\n rendererId: ctx.rendererId,\n }),\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 if (!dryRun && serverKind.value(answers.server) === \"local\") {\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 readLocalAdmin(cwd);\n if (admin && (await localServerHostsPlatform(answers.server))) {\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 consola.warn(\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 (serverKind.value(answers.server) === \"local\" &&\n (dryRun || (await localServerHostsPlatform(answers.server)))));\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 // 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 // The split-family brand pane collapses to the compact brand mark once the\n // login's container is narrow — and the template only emits that mark when\n // branding.json names an asset. Say so at setup time instead of letting the\n // branding's absence read as a rendering bug. Keyed to the design alone:\n // the collapse is a container query, so posture doesn't decide it (see\n // `designWarnings`).\n const warnings = designWarnings(answers.design);\n if (!this.jsonEnabled()) {\n const projectFacts = await detectProjectFacts(cwd, framework.id);\n const sections = buildSummary({\n projectFacts,\n writtenRel,\n depsAdded: result.depsAdded,\n project,\n server: answers.server,\n issuer,\n scaffoldedFramework,\n design: answers.design,\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([...installOutcome.boxActions, ...claimNudge.boxActions]),\n ].join(\"\\n\"),\n ),\n style: { padding: 1, borderStyle: \"rounded\", borderColor: \"green\" },\n });\n // The envelope's `warnings` never render in non-JSON mode (setup\n // passes `pretty: \"\"`), so surface them to humans here.\n for (const warning of warnings) {\n consola.warn(warning);\n }\n }\n\n return this.emit({\n status: \"ok\",\n warnings,\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: framework.id,\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 chosen login design, or null for the built-in template — so\n // agents can verify what setup published without diffing the repo.\n design: answers.design ?? null,\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(answers.design, this.meta.cliVersion),\n ...claimNudge.actions,\n ],\n next_commands: [...installOutcome.nextCommands, ...claimNudge.commands],\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 a fresh scaffold target\",\n {\n hint:\n `${target.reason ?? \"Directory is not empty.\"} ` +\n \"Run setup from an empty directory to scaffold a new app, 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): Promise<string> {\n if (framework) {\n return framework;\n }\n if (nonInteractive) {\n throw new ZitadelError(\"E_FRAMEWORK_NOT_DETECTED\", \"Empty directory — pass --framework\", {\n hint: \"Run without --json/--non-interactive to choose from a prompt, or pass --framework for scripted setup.\",\n });\n }\n return new PickFrameworkPrompt().ask(orca.availableFrameworks());\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(\n server: string,\n timeoutMs = 1500,\n): Promise<boolean> {\n return Boolean(await readPlatformRuntime(server, timeoutMs));\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 preview_origins: [issuer],\n created_at: \"2026-04-21T14:03:11.000Z\",\n };\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 */\ntype SetupRetryOptions = {\n framework?: string;\n preset?: SetupPreset;\n useCase?: SetupUseCase;\n design?: string;\n renderer?: string;\n devPort?: number;\n nonInteractive?: boolean;\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 */\nfunction 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.design) {\n parts.push(`--design ${opts.design}`);\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 if (opts.nonInteractive) {\n parts.push(\"--non-interactive\");\n }\n parts.push(\"--server local\");\n return parts.join(\" \");\n}\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 */\nfunction retryOptionsFromFlags(flags: {\n framework?: string;\n preset?: string;\n \"use-case\"?: string;\n design?: string;\n renderer?: string;\n \"dev-port\"?: number;\n \"non-interactive\"?: boolean;\n}): SetupRetryOptions {\n return {\n framework: flags.framework,\n preset: flags.preset as SetupPreset | undefined,\n useCase: flags[\"use-case\"] as SetupUseCase | undefined,\n design: flags.design,\n renderer: flags.renderer,\n devPort: flags[\"dev-port\"],\n nonInteractive: Boolean(flags[\"non-interactive\"]),\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 // API contract requires a project name; generated TS models may lag\n // briefly until `packages/api` regeneration catches up.\n const payload = { name: projectName, preview_origins: [issuer], seed_defaults: false } as {\n name: string;\n preview_origins: string[];\n seed_defaults: false;\n };\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(payload as Parameters<typeof client.createProject>[0]);\n } catch (error) {\n const normalized = toZitadelError(error);\n const retryFlags = setupRetryFlags(retry);\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}.`,\n nextCommands: [\n publicCliCommand(\"start\", cliVersion),\n publicCliCommand(`setup ${retryFlags}`, cliVersion),\n ],\n details: {\n server,\n original: normalized.details,\n },\n });\n }\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\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\n return new ZitadelError(normalized.code, normalized.message, {\n hint:\n `${normalized.hint ? `${normalized.hint} ` : \"\"}` +\n \"Start local Zitadel first, then rerun setup. \" +\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 ],\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/branding/branding.json\": { subject: \"the branding descriptor (layout + asset URLs)\" },\n \".zitadel/branding/login.liquid\": { subject: \"the editable login template\" },\n \".zitadel/branding/README.md\": { subject: \"the branding folder README\" },\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/** Builds the section list driving {@link renderSummary} for the setup command. */\nfunction 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 design?: BrandingDesign;\n}): Section[] {\n const {\n projectFacts,\n writtenRel,\n depsAdded,\n project,\n server,\n issuer,\n scaffoldedFramework,\n design,\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({ label: \"Scaffold\", value: \"fresh project (no existing files)\" });\n }\n\n const installedRows: Row[] = [];\n if (packageJsonHit && depsAdded.length > 0) {\n installedRows.push({\n label: \"Package\",\n value: depsAdded.join(\", \"),\n secondary: stylePath(fileNameOf(packageJsonHit)),\n });\n }\n // A union over every framework's scaffold artifacts: rows only render when\n // the patcher actually wrote the file, so entries for other frameworks are\n // inert. Suffixes are matched case-sensitively (src/App.tsx is React/Solid,\n // src/app.tsx is Qwik, app.vue is the Nuxt shell, src/App.vue is Vue).\n for (const [label, suffix] of [\n [\"Home redirect\", \"app/page.tsx\"],\n [\"Login page\", \"app/login/page.tsx\"],\n [\"Register page\", \"app/register/page.tsx\"],\n [\"Profile page\", \"app/profile/page.tsx\"],\n [\"Request proxy\", \"proxy.ts\"],\n [\"Middleware\", \"middleware.ts\"],\n [\"App entry\", \"src/App.tsx\"],\n [\"App entry\", \"src/app.tsx\"],\n [\"App entry\", \"src/App.vue\"],\n [\"App entry\", \"src/App.svelte\"],\n [\"App entry\", \"src/app/app.ts\"],\n [\"Routes\", \"src/app/app.routes.ts\"],\n [\"Request proxy\", \"proxy.conf.cjs\"],\n [\"App shell\", \"app.vue\"],\n [\"Home redirect\", \"pages/index.vue\"],\n [\"Login page\", \"pages/login.vue\"],\n [\"Register page\", \"pages/register.vue\"],\n [\"Profile page\", \"pages/profile.vue\"],\n [\"Env vars\", \".env.local\"],\n ] as const) {\n const hit = pickWrittenFile(writtenRel, suffix);\n if (hit) installedRows.push({ label, value: stylePath(hit) });\n }\n // The Vite config merge carries the /__nextgen dev proxy; the file name\n // varies (ts/js/mts/mjs), so it can't ride the suffix table above.\n const viteConfigHit = writtenRel.find((file) => /(^|\\/)vite\\.config\\.[cm]?[jt]s$/.test(file));\n if (viteConfigHit) {\n installedRows.push({ label: \"Dev proxy\", value: stylePath(viteConfigHit) });\n }\n\n // The login-customization entry points. These are what a user edits to\n // change what the login collects, how it authenticates, and how it looks —\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 [\"Login template\", \".zitadel/branding/login.liquid\", \".zitadel/branding/\"],\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\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 design\n ? {\n label: \"Login design\",\n value: brandingDesignLabel(design),\n secondary: `${design} · ${stylePath(\".zitadel/branding/\")}`,\n }\n : { label: \"Login design\", value: styleDim(\"built-in template\") },\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 { setTimeout as sleep } from \"node:timers/promises\";\n\nimport { 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 { consoleSignInUrl } from \"../lib/local-server/sign-in\";\nimport {\n binaryLogs,\n isProcessRunning,\n startBinaryRuntime,\n stopBinaryRuntime,\n type StopBinaryRuntimeResult,\n} from \"../lib/local-server/binary\";\nimport {\n currentUser,\n dockerAvailable,\n ensureImage,\n inspectContainer,\n metadataFromStart,\n startContainer,\n stopAndRemoveContainer,\n} from \"../lib/local-server/docker\";\nimport {\n dockerRuntimeGuidance,\n dockerUnavailableMessage,\n} from \"../lib/local-server/docker-guidance\";\nimport { EMPTY_SUMMARY, loadProjectEnv } from \"../lib/local-server/env-vars\";\nimport {\n DEFAULT_LOCAL_SERVER_PORT,\n PLATFORM_PROJECT_ID,\n checkLocalServerHealth,\n defaultLocalServerImageForCliVersion,\n ensureContainerIdentity,\n ensureLocalState,\n localContainerName,\n localServerUrl,\n readRuntimeMetadata,\n writeRuntimeMetadata,\n type RuntimeBackend,\n type RuntimeMetadata,\n} from \"../lib/local-server/runtime\";\nimport { BaseCommand, CommandGroups, type JsonEnvelope } from \"../lib/oclif\";\nimport { listenersForPort, type TcpListener } from \"../lib/prober/ports\";\nimport { publicCliCommand } from \"../lib/public-cli\";\n\nconst START_TIMEOUT_MS = 90_000;\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: Flags.string({ description: \"Container image to run.\" }),\n port: Flags.integer({ description: \"Local HTTP port.\", default: DEFAULT_LOCAL_SERVER_PORT }),\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 port = flags.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 const paths = await ensureLocalState(this.meta.cwd);\n const existingRuntime = await readRuntimeMetadata(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);\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 if (runtimeBackend === \"binary\") {\n if (\n existingRuntime?.backend === \"binary\" &&\n existingRuntime.port === port &&\n isProcessRunning(existingRuntime.pid) &&\n (await checkLocalServerHealth(serverUrl))\n ) {\n await writeRuntimeMetadata(this.meta.cwd, existingRuntime);\n return this.emit({\n status: \"ok\",\n data: readyData(\n existingRuntime,\n true,\n this.meta.cliVersion,\n await consoleLoginFor(serverUrl, local?.admin),\n ),\n });\n }\n await stopExistingRuntime(existingRuntime);\n await assertPortAvailableForStart(port, serverUrl, this.meta.cliVersion);\n const metadata = await startBinaryRuntime({\n cliVersion: this.meta.cliVersion,\n dataDir: paths.dataDir,\n logPath: paths.logFile,\n port,\n serverUrl,\n env,\n userFile: local?.userFile,\n });\n try {\n await waitForHealth(\n serverUrl,\n this.meta.cliVersion,\n {\n runtime: \"binary\",\n pid: metadata.pid,\n log_path: metadata.log_path,\n },\n {\n pid: metadata.pid,\n logPath: metadata.log_path,\n },\n );\n } catch (error) {\n const stopResult = await stopBinaryRuntime(metadata.pid);\n if (stopResult.status === \"failed\") {\n throw startupCleanupFailedError(error, stopResult, this.meta.cliVersion);\n }\n throw error;\n }\n await writeRuntimeMetadata(this.meta.cwd, metadata);\n return this.emit({\n status: \"ok\",\n data: readyData(metadata, false, this.meta.cliVersion, await consoleLoginFor(serverUrl, local?.admin)),\n });\n }\n\n await assertDockerAvailable(this.meta.cliVersion);\n if (existingRuntime?.backend === \"binary\") {\n await stopBinaryRuntime(existingRuntime.pid);\n }\n const existing = await inspectContainer(containerName);\n if (\n existing.exists &&\n existing.running &&\n existing.image === image &&\n (await checkLocalServerHealth(serverUrl))\n ) {\n const metadata = metadataFromStart({\n cwdDataDir: paths.dataDir,\n cliVersion: this.meta.cliVersion,\n containerName,\n containerId: existing.id ?? containerName,\n image,\n port,\n serverUrl,\n // The container was started with whatever was recorded then.\n env: existingRuntime?.backend === \"docker\" ? existingRuntime.env : undefined,\n });\n await writeRuntimeMetadata(this.meta.cwd, metadata);\n return this.emit({\n status: \"ok\",\n data: readyData(metadata, true, this.meta.cliVersion, await consoleLoginFor(serverUrl, local?.admin)),\n });\n }\n\n if (existing.exists) {\n await stopAndRemoveContainer(containerName);\n }\n\n await assertPortAvailableForStart(port, serverUrl, this.meta.cliVersion);\n await ensureImage(image);\n const { containerId, env: containerEnv } = await startContainer({\n containerName,\n image,\n port,\n dataDir: paths.dataDir,\n identity: await ensureContainerIdentity(this.meta.cwd, currentUser()),\n env,\n userFile: local?.userFile,\n });\n await waitForHealth(serverUrl, this.meta.cliVersion, {\n runtime: \"docker\",\n container_name: containerName,\n });\n\n const metadata = metadataFromStart({\n cwdDataDir: paths.dataDir,\n cliVersion: this.meta.cliVersion,\n containerName,\n containerId,\n image,\n port,\n serverUrl,\n env: containerEnv,\n });\n await writeRuntimeMetadata(this.meta.cwd, metadata);\n return this.emit({\n status: \"ok\",\n data: readyData(metadata, false, this.meta.cliVersion, await consoleLoginFor(serverUrl, local?.admin)),\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 consola.warn(`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 startupCleanupFailedError(\n error: unknown,\n stopResult: StopBinaryRuntimeResult,\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\nasync function assertDockerAvailable(cliVersion: string): Promise<void> {\n let result: Awaited<ReturnType<typeof dockerAvailable>>;\n try {\n result = await dockerAvailable();\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\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\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 \"From your app directory, run setup; 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\nasync function waitForHealth(\n serverUrl: string,\n cliVersion: string,\n details: Record<string, unknown>,\n runtime?: { logPath?: string; pid?: number },\n): Promise<void> {\n const started = Date.now();\n while (Date.now() - started < START_TIMEOUT_MS) {\n if (runtime?.pid && !isProcessRunning(runtime.pid)) {\n throw await serverExitedError(serverUrl, cliVersion, details, runtime.logPath);\n }\n if (await checkLocalServerHealth(serverUrl, 1000)) {\n return;\n }\n await sleep(1000);\n }\n throw 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: { ...details, server_url: serverUrl },\n });\n}\n\nasync function assertPortAvailableForStart(\n port: number,\n serverUrl: string,\n cliVersion: string,\n): Promise<void> {\n const listeners = await listenersForPort(port);\n if (listeners.length === 0) {\n return;\n }\n throw portInUseError(port, serverUrl, listeners, cliVersion);\n}\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\nasync function serverExitedError(\n serverUrl: string,\n cliVersion: string,\n details: Record<string, unknown>,\n logPath: string | undefined,\n): Promise<ZitadelError> {\n const logTail = logPath ? await binaryLogs(logPath, 40) : undefined;\n return new ZitadelError(\"E_NETWORK\", \"Local Zitadel server process exited before becoming healthy\", {\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\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\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n\nasync function stopExistingRuntime(runtime: RuntimeMetadata | undefined): Promise<void> {\n if (!runtime) {\n return;\n }\n if (runtime.backend === \"binary\") {\n const stopResult = await stopBinaryRuntime(runtime.pid);\n if (stopResult.status === \"failed\") {\n throw 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, stop_result: stopResult },\n });\n }\n return;\n }\n await stopAndRemoveContainer(runtime.container_name);\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 { isProcessRunning } from \"../lib/local-server/binary\";\nimport { inspectContainer } from \"../lib/local-server/docker\";\nimport { customizeAndPublishActions, verifyLoginAction } from \"../lib/journey-guidance\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n checkLocalServerHealth,\n readRuntimeMetadata,\n runtimeSummary,\n} from \"../lib/local-server/runtime\";\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 let docker: Awaited<ReturnType<typeof inspectContainer>> | undefined;\n let dockerError: string | undefined;\n if (runtime?.backend === \"docker\") {\n try {\n docker = await inspectContainer(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 processRunning = runtime?.backend === \"binary\" ? isProcessRunning(runtime.pid) : false;\n const serverLifecycle = lifecycleForRuntime({ docker, healthy, processRunning, runtime });\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(runtime),\n docker: {\n available: dockerError === undefined,\n error: dockerError,\n container_exists: docker?.exists ?? false,\n container_running: docker?.running ?? false,\n },\n process:\n runtime?.backend === \"binary\"\n ? {\n pid: runtime.pid,\n running: processRunning,\n }\n : undefined,\n health: {\n healthy,\n url: runtime?.server_url,\n },\n },\n project,\n next_actions: nextActions,\n next_commands: nextCommands,\n },\n });\n }\n}\n\nfunction lifecycleForRuntime(input: {\n docker: Awaited<ReturnType<typeof inspectContainer>> | undefined;\n healthy: boolean;\n processRunning: boolean;\n runtime: Awaited<ReturnType<typeof readRuntimeMetadata>>;\n}): string {\n if (!input.runtime) {\n return \"missing\";\n }\n if (input.runtime.backend === \"binary\") {\n if (input.processRunning && input.healthy) {\n return \"running\";\n }\n return input.processRunning ? \"unhealthy\" : \"stopped\";\n }\n if (input.docker?.running && input.healthy) {\n return \"running\";\n }\n if (input.docker?.exists) {\n return \"unhealthy\";\n }\n return \"stopped\";\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 }, { signal: AbortSignal.timeout(PRESENCE_PROBE_TIMEOUT_MS) })\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 { ZitadelError } from \"../lib/errors\";\nimport { stopBinaryRuntime, type StopBinaryRuntimeResult } from \"../lib/local-server/binary\";\nimport { stopAndRemoveContainer } from \"../lib/local-server/docker\";\nimport {\n discoverManagedRuntimeProcesses,\n type ManagedRuntimeProcess,\n} from \"../lib/local-server/processes\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n localContainerName,\n readRuntimeMetadata,\n} from \"../lib/local-server/runtime\";\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 let stopResult: StopBinaryRuntimeResult | undefined;\n if (runtime?.backend === \"binary\") {\n stopResult = await stopBinaryRuntime(runtime.pid);\n if (stopResult.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 `zitadel stop`.\",\n details: { runtime, stop_result: stopResult },\n });\n }\n } else {\n await stopAndRemoveContainer(containerName);\n }\n\n return this.emit({\n status: \"ok\",\n data: {\n title:\n stopResult?.status === \"stale\"\n ? \"Local Zitadel server was not running.\"\n : \"Local Zitadel server stopped.\",\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: stopResult,\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 discovery = await discoverManagedRuntimeProcesses();\n if (!discovery.supported) {\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Managed local runtime process discovery is unavailable.\",\n sweep: { supported: false, error: discovery.error, stopped: [] },\n },\n warnings: [\"managed-runtime-processes: discovery unavailable\"],\n });\n }\n\n const results: ManagedRuntimeSweepResult[] = [];\n for (const processInfo of discovery.processes) {\n results.push({\n process: processInfo,\n stop_result: await stopBinaryRuntime(processInfo.pid),\n });\n }\n const failed = results.filter((result) => result.stop_result.status === \"failed\");\n if (failed.length > 0) {\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\n return this.emit({\n status: \"ok\",\n data: {\n title:\n 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: results.length,\n results,\n },\n },\n });\n }\n}\n\ntype ManagedRuntimeSweepResult = Readonly<{\n process: ManagedRuntimeProcess;\n stop_result: StopBinaryRuntimeResult;\n}>;\n","import type { GetVariable200, GetVariables200 } from \"@zitadel/api/generated/model\";\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/**\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: GetVariable200): VariableRow {\n return typeof value === \"object\" && value !== null\n ? { name, secret: true }\n : { name, secret: false, value };\n}\n\n/**\n * Project the wire map into rows, sorted by name so output is stable between\n * runs.\n */\nexport function toVariableRows(body: GetVariables200): VariableRow[] {\n return Object.entries(body)\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 * A whole-field reference keeps its value's type, so `\"retry\": \"${{ RETRY }}\"`\n * resolves to `5`, not `\"5\"`, only when the value was stored as a number.\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.\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(raw: string, type: VariableType): string | number | boolean {\n switch (type) {\n case \"string\":\n return raw;\n case \"boolean\":\n if (raw === \"true\" || raw === \"false\") {\n return raw === \"true\";\n }\n throw new ZitadelError(\n \"E_VALIDATION\",\n `Expected true or false, got ${JSON.stringify(raw)}.`,\n {\n hint: \"A boolean variable is exactly `true` or `false`.\",\n },\n );\n case \"number\": {\n const value = Number(raw);\n if (!JSON_NUMBER.test(raw) || !Number.isFinite(value)) {\n throw new ZitadelError(\"E_VALIDATION\", `Expected a number, got ${JSON.stringify(raw)}.`, {\n hint: \"Write it as a JSON number, such as 5, -1.5 or 1e3.\",\n });\n }\n if (Number.isInteger(value) && !Number.isSafeInteger(value)) {\n throw new ZitadelError(\n \"E_VALIDATION\",\n `${raw} is too large to store exactly as a number.`,\n { hint: \"Store it as a string, which keeps every digit.\" },\n );\n }\n return value;\n }\n }\n}\n\n/**\n * Read a value from stdin, for the non-interactive path\n * (`variables set NAME --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 { Args, Flags } from \"@oclif/core\";\nimport { cancel, confirm, isCancel } from \"@clack/prompts\";\n\nimport { ownerLabel } from \"../../lib/environment\";\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { dryRunResult } from \"../../lib/oclif/crud/shared\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport { assertVariableName } from \"../../lib/variables\";\nimport { publicCliCommand } from \"../../lib/public-cli\";\n\n/**\n * The `variables delete` topic command — remove one variable from one owner.\n *\n * A variable is removable only by the owner that entered it: deleting a name\n * another owner of the same project holds answers `var.not_found` and leaves\n * that owner's value standing (ADR 062 §4). Destructive, so it takes the same\n * `--force`-or-confirm gate the resource commands' `delete` uses.\n */\nexport default class VariablesDelete extends EnvironmentCommand {\n static override description = \"Delete one variable from an environment or the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variables delete GOOGLE_CLIENT_ID --environment prod\",\n \"<%= config.bin %> variables delete GOOGLE_CLIENT_ID --project-level --force\",\n ];\n static override args = {\n name: Args.string({ 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 { nonInteractive, dryRun, force, cliVersion } = this.meta;\n const name = args.name;\n\n assertVariableName(name);\n\n const { client, scope, environment } = await this.connect();\n const where = ownerLabel(environment);\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({\n ...preview,\n data: { ...(preview.data as object), environment: environment ?? null },\n pretty: `${preview.pretty} from ${where}`,\n });\n }\n\n if (!force) {\n if (nonInteractive) {\n const retry = publicCliCommand(\n `variables delete ${name} ${environment ? `--environment ${environment}` : \"--project-level\"} --force`,\n cliVersion,\n );\n throw new ZitadelError(\n \"E_VALIDATION\",\n \"Deleting a variable requires --force in non-interactive mode\",\n {\n hint: `Pass --force to delete ${name} from ${where}.`,\n nextCommands: [retry],\n },\n );\n }\n const answer = await confirm({\n message: `Delete ${name} from ${where}?`,\n initialValue: false,\n });\n if (isCancel(answer) || !answer) {\n cancel(\"Delete cancelled.\");\n return this.emit({ status: \"skipped\", reason: \"delete-cancelled\" });\n }\n }\n\n await client.deleteVariable(name, scope);\n this.recordTelemetry({ is_environment_scoped: environment !== undefined });\n\n return this.emit({\n status: \"ok\",\n data: { environment: environment ?? null, name, deleted: true },\n pretty: `Deleted ${name} from ${where}`,\n });\n }\n}\n","import { Args } from \"@oclif/core\";\n\nimport { ownerLabel } from \"../../lib/environment\";\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\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 one owner.\n *\n * A name that owner has not entered answers `var.not_found`, even when another\n * owner of the same project holds it: nothing is inherited (ADR 062 §4). A\n * secret is found but not disclosed, so the answer says it is held and nothing\n * more.\n */\nexport default class VariablesGet extends EnvironmentCommand {\n static override description = \"Get one variable from an environment or the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variables get GOOGLE_CLIENT_ID --environment prod\",\n \"<%= config.bin %> variables get GOOGLE_CLIENT_ID --environment prod --json\",\n ];\n static override args = {\n name: Args.string({ 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, environment } = 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 row = toVariableRow(name, await client.getVariable(name, scope));\n this.recordTelemetry({\n is_secret: row.secret,\n is_environment_scoped: environment !== undefined,\n });\n\n const data = { environment: environment ?? null, ...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, [\"environment\", \"value\"], {\n environment: ownerLabel(environment),\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 { ownerLabel } from \"../../lib/environment\";\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { renderRows, renderTable } from \"../../lib/oclif/crud/table\";\nimport { 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 one owner.\n *\n * Owners are separate, not a ladder: an environment does not see the project\n * level's variables, nor the project level an environment's (ADR 062 §4). A\n * secret is reported as held without its value, because the platform never\n * discloses one.\n */\nexport default class VariablesList extends EnvironmentCommand {\n static override description = \"List the variables entered on an environment or the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variables list --environment prod\",\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, environment } = await this.connect();\n\n const rows = toVariableRows(await client.getVariables(scope));\n this.recordTelemetry({\n variable_count: rows.length,\n is_environment_scoped: environment !== undefined,\n });\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 environment: environment ?? null,\n variables: rows,\n count: rows.length,\n },\n pretty: plain\n ? renderRows(COLUMNS, cells)\n : rows.length === 0\n ? `No variables on ${ownerLabel(environment)}.`\n : [\n renderTable(COLUMNS, cells),\n \"\",\n `${rows.length} ${rows.length === 1 ? \"variable\" : \"variables\"}`,\n ].join(\"\\n\"),\n });\n }\n}\n","import { Args, Flags } from \"@oclif/core\";\nimport { cancel, isCancel, password, text } from \"@clack/prompts\";\n\nimport { ownerLabel } from \"../../lib/environment\";\nimport { CommandGroups, EnvironmentCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { dryRunResult } from \"../../lib/oclif/crud/shared\";\nimport { ZitadelError } from \"../../lib/errors\";\nimport {\n assertVariableName,\n parseVariableValue,\n readStdin,\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 one\n * owner.\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 EnvironmentCommand {\n static override description = \"Set one variable on an environment or the project.\";\n static override group = CommandGroups.configuration;\n static override examples = [\n \"<%= config.bin %> variables set GOOGLE_CLIENT_ID --environment prod\",\n \"<%= config.bin %> variables set GOOGLE_CLIENT_SECRET --environment prod --secret < secret.txt\",\n \"<%= config.bin %> variables set SESSION_TTL --project-level --as number\",\n ];\n static override args = {\n name: Args.string({\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:\n \"Store the value as this JSON type. A reference to the whole field resolves to that type, so a number stays a number.\",\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { args, flags } = await this.parse(VariablesSet);\n await this.toMeta(flags);\n const { nonInteractive, 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 // The owner is resolved before the value is asked for: being refused after\n // typing a secret would mean typing it again.\n const { client, scope, environment } = await this.connect();\n const where = ownerLabel(environment);\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: {\n ...(preview.data as object),\n environment: environment ?? null,\n secret: flags.secret,\n as: type,\n },\n pretty: `${preview.pretty} on ${where}${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. A\n // terminal on stdin means nothing was piped: fail rather than block on a\n // read that would never end.\n if (nonInteractive && process.stdin.isTTY) {\n const retry = pipeHint(name, environment, flags.secret, type, cliVersion);\n throw new ZitadelError(\"E_VALIDATION\", `No value supplied for ${name}.`, {\n hint: `Pipe the value in: ${retry}`,\n nextCommands: [retry],\n });\n }\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.\n const answer = nonInteractive\n ? await readStdin(process.stdin)\n : flags.secret\n ? await password({ message: `Value for ${name}` })\n : await text({ message: `Value for ${name}` });\n if (isCancel(answer)) {\n cancel(\"Set cancelled.\");\n throw new ZitadelError(\"E_VALIDATION\", \"Set cancelled by user\");\n }\n // An empty submission reads as `undefined` from the prompt and has to\n // become `\"\"`, not the string \"undefined\". An empty string is a value the\n // scalar schema accepts; only an absent input is an error, which the stdin\n // guard above and the cancel signal cover.\n const value = parseVariableValue(String(answer ?? \"\"), type);\n\n await client.updateVariables({ [name]: { value, secret: flags.secret } }, scope);\n this.recordTelemetry({\n is_secret: flags.secret,\n is_environment_scoped: environment !== undefined,\n });\n\n return this.emit({\n status: \"ok\",\n data: { environment: environment ?? null, name, secret: flags.secret, type },\n pretty: `Set ${name} on ${where}${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 somewhere else,\n * writes a credential as a readable value, or stores a number as a string.\n */\nfunction pipeHint(\n name: string,\n environment: string | undefined,\n secret: boolean,\n type: VariableType,\n cliVersion: string,\n): string {\n const args = [\n \"variables\",\n \"set\",\n name,\n ...(environment ? [\"--environment\", environment] : [\"--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 Apply from \"./commands/apply\";\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 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 \"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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"}
|