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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +250 -62
  2. package/SKILLS.md +227 -38
  3. package/dist/branding-cygSBPkV.mjs +79 -0
  4. package/dist/branding-cygSBPkV.mjs.map +1 -0
  5. package/dist/claim-state-DlfD6Res.mjs +66 -0
  6. package/dist/claim-state-DlfD6Res.mjs.map +1 -0
  7. package/dist/commands/apply.mjs +27 -8
  8. package/dist/commands/apply.mjs.map +1 -1
  9. package/dist/commands/branding/eject.mjs +104 -0
  10. package/dist/commands/branding/eject.mjs.map +1 -0
  11. package/dist/commands/claim.mjs +402 -0
  12. package/dist/commands/claim.mjs.map +1 -0
  13. package/dist/commands/doctor.mjs +687 -55
  14. package/dist/commands/doctor.mjs.map +1 -1
  15. package/dist/commands/eject.mjs +18 -6
  16. package/dist/commands/eject.mjs.map +1 -1
  17. package/dist/commands/logs.mjs +2 -2
  18. package/dist/commands/plan.mjs +19 -6
  19. package/dist/commands/plan.mjs.map +1 -1
  20. package/dist/commands/reset.mjs +12 -4
  21. package/dist/commands/reset.mjs.map +1 -1
  22. package/dist/commands/schemas/list.mjs +146 -0
  23. package/dist/commands/schemas/list.mjs.map +1 -0
  24. package/dist/commands/setup.mjs +642 -287
  25. package/dist/commands/setup.mjs.map +1 -1
  26. package/dist/commands/start.mjs +73 -6
  27. package/dist/commands/start.mjs.map +1 -1
  28. package/dist/commands/status.mjs +52 -13
  29. package/dist/commands/status.mjs.map +1 -1
  30. package/dist/commands/stop.mjs +59 -6
  31. package/dist/commands/stop.mjs.map +1 -1
  32. package/dist/designs-Ckz18Dpo.mjs +38 -0
  33. package/dist/designs-Ckz18Dpo.mjs.map +1 -0
  34. package/dist/{docker-BA78SdC2.mjs → docker-DcRGTOJa.mjs} +61 -11
  35. package/dist/docker-DcRGTOJa.mjs.map +1 -0
  36. package/dist/environment-rjRVkJjW.mjs +17 -0
  37. package/dist/environment-rjRVkJjW.mjs.map +1 -0
  38. package/dist/journey-guidance-BGrOX_gT.mjs +40 -0
  39. package/dist/journey-guidance-BGrOX_gT.mjs.map +1 -0
  40. package/dist/oclif-CanO3zdt.mjs +1769 -0
  41. package/dist/oclif-CanO3zdt.mjs.map +1 -0
  42. package/dist/{orca-CfKDQRop.mjs → orca-BzQIQqzt.mjs} +1663 -303
  43. package/dist/orca-BzQIQqzt.mjs.map +1 -0
  44. package/dist/package-manager-DFdLcDx1.mjs +194 -0
  45. package/dist/package-manager-DFdLcDx1.mjs.map +1 -0
  46. package/dist/ports-BM20XIZb.mjs +116 -0
  47. package/dist/ports-BM20XIZb.mjs.map +1 -0
  48. package/dist/processes-DKHPkU8O.mjs +120 -0
  49. package/dist/processes-DKHPkU8O.mjs.map +1 -0
  50. package/dist/{project-CKAHtHML.mjs → project-CHhot85s.mjs} +57 -4
  51. package/dist/project-CHhot85s.mjs.map +1 -0
  52. package/dist/sync-BBlACKzT.mjs +1633 -0
  53. package/dist/sync-BBlACKzT.mjs.map +1 -0
  54. package/dist/user-schema-DTuOsdKE.mjs +91 -0
  55. package/dist/user-schema-DTuOsdKE.mjs.map +1 -0
  56. package/oclif.manifest.json +412 -5
  57. package/package.json +10 -5
  58. package/dist/docker-BA78SdC2.mjs.map +0 -1
  59. package/dist/docker-guidance-BvfpmsDj.mjs +0 -21
  60. package/dist/docker-guidance-BvfpmsDj.mjs.map +0 -1
  61. package/dist/oclif-VkCTGIEk.mjs +0 -818
  62. package/dist/oclif-VkCTGIEk.mjs.map +0 -1
  63. package/dist/orca-CfKDQRop.mjs.map +0 -1
  64. package/dist/project-CKAHtHML.mjs.map +0 -1
  65. package/dist/sync-B5lqgQO3.mjs +0 -733
  66. package/dist/sync-B5lqgQO3.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"start.mjs","names":["sleep"],"sources":["../../src/commands/start.ts"],"sourcesContent":["import { setTimeout as sleep } from \"node:timers/promises\";\n\nimport { Flags } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../lib/errors\";\nimport { isProcessRunning, startBinaryRuntime, stopBinaryRuntime } 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 {\n DEFAULT_LOCAL_SERVER_PORT,\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, type JsonEnvelope } from \"../lib/oclif\";\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 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 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\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(existingRuntime, true, this.meta.cliVersion),\n });\n }\n await stopExistingRuntime(existingRuntime);\n const metadata = await startBinaryRuntime({\n cliVersion: this.meta.cliVersion,\n dataDir: paths.dataDir,\n logPath: paths.logFile,\n port,\n serverUrl,\n });\n try {\n await waitForHealth(serverUrl, this.meta.cliVersion, {\n runtime: \"binary\",\n pid: metadata.pid,\n log_path: metadata.log_path,\n });\n } catch (error) {\n await stopBinaryRuntime(metadata.pid);\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),\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 });\n await writeRuntimeMetadata(this.meta.cwd, metadata);\n return this.emit({\n status: \"ok\",\n data: readyData(metadata, true, this.meta.cliVersion),\n });\n }\n\n if (existing.exists) {\n await stopAndRemoveContainer(containerName);\n }\n\n await ensureImage(image);\n const containerId = await startContainer({\n containerName,\n image,\n port,\n dataDir: paths.dataDir,\n identity: await ensureContainerIdentity(this.meta.cwd, currentUser()),\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 });\n await writeRuntimeMetadata(this.meta.cwd, metadata);\n return this.emit({\n status: \"ok\",\n data: readyData(metadata, false, this.meta.cliVersion),\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) {\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 },\n urls: {\n api: metadata.server_url,\n console: `${metadata.server_url}/ui/console/`,\n login: `${metadata.server_url}/ui/login/`,\n },\n next_actions: [\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: [publicCliCommand(\"setup --server local\", cliVersion)],\n };\n}\n\nasync function waitForHealth(\n serverUrl: string,\n cliVersion: string,\n details: Record<string, unknown>,\n): Promise<void> {\n const started = Date.now();\n while (Date.now() - started < START_TIMEOUT_MS) {\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\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\nasync function stopExistingRuntime(runtime: RuntimeMetadata | undefined): Promise<void> {\n if (!runtime) {\n return;\n }\n if (runtime.backend === \"binary\") {\n await stopBinaryRuntime(runtime.pid);\n return;\n }\n await stopAndRemoveContainer(runtime.container_name);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"start.mjs","names":["sleep"],"sources":["../../src/commands/start.ts"],"sourcesContent":["import { setTimeout as sleep } from \"node:timers/promises\";\n\nimport { Flags } from \"@oclif/core\";\n\nimport { ZitadelError, toZitadelError } from \"../lib/errors\";\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 {\n DEFAULT_LOCAL_SERVER_PORT,\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, 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 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\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(existingRuntime, true, this.meta.cliVersion),\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 });\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),\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 });\n await writeRuntimeMetadata(this.meta.cwd, metadata);\n return this.emit({\n status: \"ok\",\n data: readyData(metadata, true, this.meta.cliVersion),\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 = await startContainer({\n containerName,\n image,\n port,\n dataDir: paths.dataDir,\n identity: await ensureContainerIdentity(this.meta.cwd, currentUser()),\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 });\n await writeRuntimeMetadata(this.meta.cwd, metadata);\n return this.emit({\n status: \"ok\",\n data: readyData(metadata, false, this.meta.cliVersion),\n });\n }\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) {\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 },\n urls: {\n api: metadata.server_url,\n console: `${metadata.server_url}/ui/console/`,\n login: `${metadata.server_url}/ui/login/`,\n },\n next_actions: [\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: [publicCliCommand(\"setup --server local\", cliVersion)],\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"],"mappings":";;;;;;AA0CA,MAAM,mBAAmB;AAEzB,IAAqB,QAArB,MAAqB,cAAc,YAAY;CAC7C,OAAgB,cAAc;CAC9B,OAAgB,QAAQ;EACtB,OAAO,MAAM,OAAO,EAAE,aAAa,2BAA2B,CAAC;EAC/D,MAAM,MAAM,QAAQ;GAAE,aAAa;GAAoB,SAAS;GAA2B,CAAC;EAC5F,SAAS,MAAM,OAAO;GACpB,aAAa;GACb,SAAS,CAAC,UAAU,SAAS;GAC9B,CAAC;EACH;CAED,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,MAAM;EACzC,MAAM,OAAO,MAAM,QAAA;EACnB,MAAM,YAAY,eAAe,KAAK;AACtC,QAAM,KAAK,OAAO,OAAO;GAAE,eAAe;GAAO,QAAQ;GAAW,CAAC;AAErE,eAAa,KAAK;EAClB,MAAM,iBAAiB,sBAAsB;GAC3C,OAAO,MAAM;GACb,SAAS,MAAM;GACf,UAAU,KAAK,KAAK,IAAI;GACzB,CAAC;AACF,qBAAmB,gBAAgB,MAAM,MAAM;AAC/C,OAAK,gBAAgB,EAAE,SAAS,gBAAgB,CAAC;EACjD,MAAM,QACJ,MAAM,SACN,KAAK,KAAK,IAAI,uBACd,qCAAqC,KAAK,KAAK,WAAW;EAC5D,MAAM,gBAAgB,mBAAmB,KAAK,KAAK,IAAI;AACvD,MAAI,KAAK,KAAK,OACZ,QAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,SAAS;KACP,SAAS;KACT,GAAI,mBAAmB,WACnB;MACE,gBAAgB;MAChB;MACD,GACD,EAAE;KACN;KACD;IACD,MAAM;KACJ,KAAK;KACL,SAAS,GAAG,UAAU;KACtB,OAAO,GAAG,UAAU;KACrB;IACD,eAAe,CAAC,iBAAiB,SAAS,KAAK,KAAK,WAAW,CAAC;IACjE;GACF,CAAC;EAGJ,MAAM,QAAQ,MAAM,iBAAiB,KAAK,KAAK,IAAI;EACnD,MAAM,kBAAkB,MAAM,oBAAoB,KAAK,KAAK,IAAI;AAEhE,MAAI,mBAAmB,UAAU;AAC/B,OACE,iBAAiB,YAAY,YAC7B,gBAAgB,SAAS,QACzB,iBAAiB,gBAAgB,IAAI,IACpC,MAAM,uBAAuB,UAAU,EACxC;AACA,UAAM,qBAAqB,KAAK,KAAK,KAAK,gBAAgB;AAC1D,WAAO,KAAK,KAAK;KACf,QAAQ;KACR,MAAM,UAAU,iBAAiB,MAAM,KAAK,KAAK,WAAW;KAC7D,CAAC;;AAEJ,SAAM,oBAAoB,gBAAgB;AAC1C,SAAM,4BAA4B,MAAM,WAAW,KAAK,KAAK,WAAW;GACxE,MAAM,WAAW,MAAM,mBAAmB;IACxC,YAAY,KAAK,KAAK;IACtB,SAAS,MAAM;IACf,SAAS,MAAM;IACf;IACA;IACD,CAAC;AACF,OAAI;AACF,UAAM,cACJ,WACA,KAAK,KAAK,YACV;KACE,SAAS;KACT,KAAK,SAAS;KACd,UAAU,SAAS;KACpB,EACD;KACE,KAAK,SAAS;KACd,SAAS,SAAS;KACnB,CACF;YACM,OAAO;IACd,MAAM,aAAa,MAAM,kBAAkB,SAAS,IAAI;AACxD,QAAI,WAAW,WAAW,SACxB,OAAM,0BAA0B,OAAO,YAAY,KAAK,KAAK,WAAW;AAE1E,UAAM;;AAER,SAAM,qBAAqB,KAAK,KAAK,KAAK,SAAS;AACnD,UAAO,KAAK,KAAK;IACf,QAAQ;IACR,MAAM,UAAU,UAAU,OAAO,KAAK,KAAK,WAAW;IACvD,CAAC;;AAGJ,QAAM,sBAAsB,KAAK,KAAK,WAAW;AACjD,MAAI,iBAAiB,YAAY,SAC/B,OAAM,kBAAkB,gBAAgB,IAAI;EAE9C,MAAM,WAAW,MAAM,iBAAiB,cAAc;AACtD,MACE,SAAS,UACT,SAAS,WACT,SAAS,UAAU,SAClB,MAAM,uBAAuB,UAAU,EACxC;GACA,MAAM,WAAW,kBAAkB;IACjC,YAAY,MAAM;IAClB,YAAY,KAAK,KAAK;IACtB;IACA,aAAa,SAAS,MAAM;IAC5B;IACA;IACA;IACD,CAAC;AACF,SAAM,qBAAqB,KAAK,KAAK,KAAK,SAAS;AACnD,UAAO,KAAK,KAAK;IACf,QAAQ;IACR,MAAM,UAAU,UAAU,MAAM,KAAK,KAAK,WAAW;IACtD,CAAC;;AAGJ,MAAI,SAAS,OACX,OAAM,uBAAuB,cAAc;AAG7C,QAAM,4BAA4B,MAAM,WAAW,KAAK,KAAK,WAAW;AACxE,QAAM,YAAY,MAAM;EACxB,MAAM,cAAc,MAAM,eAAe;GACvC;GACA;GACA;GACA,SAAS,MAAM;GACf,UAAU,MAAM,wBAAwB,KAAK,KAAK,KAAK,aAAa,CAAC;GACtE,CAAC;AACF,QAAM,cAAc,WAAW,KAAK,KAAK,YAAY;GACnD,SAAS;GACT,gBAAgB;GACjB,CAAC;EAEF,MAAM,WAAW,kBAAkB;GACjC,YAAY,MAAM;GAClB,YAAY,KAAK,KAAK;GACtB;GACA;GACA;GACA;GACA;GACD,CAAC;AACF,QAAM,qBAAqB,KAAK,KAAK,KAAK,SAAS;AACnD,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM,UAAU,UAAU,OAAO,KAAK,KAAK,WAAW;GACvD,CAAC;;;AAIN,SAAS,0BACP,OACA,YACA,YACc;CACd,MAAM,eAAe,eAAe,MAAM;AAC1C,QAAO,IAAI,aACT,aAAa,MACb,GAAG,aAAa,QAAQ,mDACxB;EACE,MAAM;EACN,cAAc,OAAO;GACnB,GAAI,aAAa,gBAAgB,EAAE;GACnC,iBAAiB,cAAc,WAAW;GAC1C,iBAAiB,QAAQ,WAAW;GACpC,iBAAiB,iBAAiB,WAAW;GAC9C,CAAC;EACF,SAAS;GACP,eAAe;IACb,MAAM,aAAa;IACnB,SAAS,aAAa;IACtB,SAAS,aAAa;IACvB;GACD,aAAa;GACd;EACF,CACF;;AAGH,eAAe,sBAAsB,YAAmC;CACtE,IAAI;AACJ,KAAI;AACF,WAAS,MAAM,iBAAiB;UACzB,OAAO;AACd,QAAM,uBAAuB,OAAO,WAAW;;AAEjD,KAAI,OAAO,WAAW,EACpB,OAAM,uBAAuB,OAAO,UAAU,yBAAyB,WAAW;;AAItF,SAAS,uBAAuB,OAAgB,YAAkC;CAChF,MAAM,SAAS,sBAAsB,SAAS,WAAW;AACzD,QAAO,IAAI,aAAa,gBAAgB,2BAA2B;EACjE,MAAM,OAAO;EACb,cAAc,OAAO;EACrB,SAAS,EAAE,SAAS,yBAAyB,MAAM,EAAE;EACtD,CAAC;;AAGJ,SAAS,UACP,UACA,gBACA,YACA;AACA,QAAO;EACL,OAAO,iBACH,6CACA;EACJ,SAAS;GACP,SAAS,SAAS;GAClB,GAAI,SAAS,YAAY,WACrB;IACE,gBAAgB,SAAS;IACzB,cAAc,SAAS;IACvB,OAAO,SAAS;IACjB,GACD;IACE,KAAK,SAAS;IACd,UAAU,SAAS;IACnB,gBAAgB,SAAS;IACzB,gBAAgB,SAAS;IAC1B;GACL,MAAM,SAAS;GACf,UAAU,SAAS;GACpB;EACD,MAAM;GACJ,KAAK,SAAS;GACd,SAAS,GAAG,SAAS,WAAW;GAChC,OAAO,GAAG,SAAS,WAAW;GAC/B;EACD,cAAc,CACZ,6FACA,2EACD;EACD,eAAe,CAAC,iBAAiB,wBAAwB,WAAW,CAAC;EACtE;;AAGH,eAAe,cACb,WACA,YACA,SACA,SACe;CACf,MAAM,UAAU,KAAK,KAAK;AAC1B,QAAO,KAAK,KAAK,GAAG,UAAU,kBAAkB;AAC9C,MAAI,SAAS,OAAO,CAAC,iBAAiB,QAAQ,IAAI,CAChD,OAAM,MAAM,kBAAkB,WAAW,YAAY,SAAS,QAAQ,QAAQ;AAEhF,MAAI,MAAM,uBAAuB,WAAW,IAAK,CAC/C;AAEF,QAAMA,WAAM,IAAK;;AAEnB,OAAM,IAAI,aAAa,aAAa,+CAA+C;EACjF,MAAM;EACN,cAAc,CACZ,iBAAiB,QAAQ,WAAW,EACpC,iBAAiB,iBAAiB,WAAW,CAC9C;EACD,SAAS;GAAE,GAAG;GAAS,YAAY;GAAW;EAC/C,CAAC;;AAGJ,eAAe,4BACb,MACA,WACA,YACe;CACf,MAAM,YAAY,MAAM,iBAAiB,KAAK;AAC9C,KAAI,UAAU,WAAW,EACvB;AAEF,OAAM,eAAe,MAAM,WAAW,WAAW,WAAW;;AAG9D,SAAS,eACP,MACA,WACA,WACA,YACc;CACd,MAAM,eAAe,SAAA,OAAqC,OAAO,IAAI;AACrE,QAAO,IAAI,aAAa,iBAAiB,QAAQ,OAAO,KAAK,CAAC,qBAAqB;EACjF,MAAM,0BAA0B,UAAU;EAC1C,cAAc,CACZ,iBAAiB,cAAc,WAAW,EAC1C,iBAAiB,gBAAgB,OAAO,aAAa,IAAI,WAAW,CACrE;EACD,SAAS;GAAE;GAAM,YAAY;GAAW;GAAW;EACpD,CAAC;;AAGJ,eAAe,kBACb,WACA,YACA,SACA,SACuB;CACvB,MAAM,UAAU,UAAU,MAAM,WAAW,SAAS,GAAG,GAAG,KAAA;AAC1D,QAAO,IAAI,aAAa,aAAa,+DAA+D;EAClG,MAAM;EACN,cAAc,CACZ,iBAAiB,QAAQ,WAAW,EACpC,iBAAiB,iBAAiB,WAAW,CAC9C;EACD,SAAS;GAAE,GAAG;GAAS,YAAY;GAAW,GAAI,UAAU,EAAE,UAAU,SAAS,GAAG,EAAE;GAAG;EAC1F,CAAC;;AAGJ,SAAS,aAAa,MAAoB;AACxC,KAAI,CAAC,OAAO,UAAU,KAAK,IAAI,OAAO,KAAK,OAAO,MAChD,OAAM,IAAI,aAAa,gBAAgB,gBAAgB,OAAO,KAAK,IAAI,EACrE,MAAM,uCACP,CAAC;;AAIN,SAAS,sBAAsB,OAIZ;AACjB,KAAI,MAAM,YAAY,YAAY,MAAM,YAAY,SAClD,QAAO,MAAM;AAEf,KAAI,MAAM,SAAS,MAAM,SACvB,QAAO;AAET,QAAO;;AAGT,SAAS,mBAAmB,SAAyB,OAAiC;AACpF,KAAI,YAAY,YAAY,MAC1B,OAAM,IAAI,aAAa,gBAAgB,qCAAqC,EAC1E,MAAM,mGACP,CAAC;;AAIN,SAAS,OAAO,QAA4B;AAC1C,QAAO,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC;;AAG7B,eAAe,oBAAoB,SAAqD;AACtF,KAAI,CAAC,QACH;AAEF,KAAI,QAAQ,YAAY,UAAU;EAChC,MAAM,aAAa,MAAM,kBAAkB,QAAQ,IAAI;AACvD,MAAI,WAAW,WAAW,SACxB,OAAM,IAAI,aAAa,gBAAgB,8CAA8C;GACnF,MAAM;GACN,SAAS;IAAE;IAAS,aAAa;IAAY;GAC9C,CAAC;AAEJ;;AAEF,OAAM,uBAAuB,QAAQ,eAAe"}
@@ -1,6 +1,9 @@
1
- import { C as resolveCwd, c as checkLocalServerHealth, h as readRuntimeMetadata, t as BaseCommand, v as runtimeSummary, x as publicCliCommand } from "../oclif-VkCTGIEk.mjs";
2
- import { a as readZitadelConfig, n as hasZitadelSecret, o as readZitadelSecret, r as readDevelopmentIssuer, t as hasZitadelConfig } from "../project-CKAHtHML.mjs";
3
- import { m as isProcessRunning, s as inspectContainer } from "../docker-BA78SdC2.mjs";
1
+ import { c as checkLocalServerHealth, h as readRuntimeMetadata, j as publicCliCommand, t as BaseCommand, v as runtimeSummary, x as resolveCwd } from "../oclif-CanO3zdt.mjs";
2
+ import { n as claimCommand, r as claimState, t as claimAction } from "../claim-state-DlfD6Res.mjs";
3
+ import { n as customizeAndPublishActions, r as verifyLoginAction } from "../journey-guidance-BGrOX_gT.mjs";
4
+ import { a as readProjectServer, c as readZitadelConfig, l as readZitadelSecret, n as hasZitadelSecret, r as readDevelopmentIssuer, t as hasZitadelConfig } from "../project-CHhot85s.mjs";
5
+ import { m as isProcessRunning, s as inspectContainer } from "../docker-DcRGTOJa.mjs";
6
+ import { createZitadelClient } from "@zitadel/api/client";
4
7
  //#region src/commands/status.ts
5
8
  /**
6
9
  * `zitadel status` — summarize the local server and project state.
@@ -35,8 +38,9 @@ var Status = class Status extends BaseCommand {
35
38
  runtime
36
39
  });
37
40
  const project = await projectStatus(this.meta.cwd);
38
- const nextCommands = nextCommandsFor(serverLifecycle, project.lifecycle, this.meta.cliVersion);
39
- const nextActions = nextActionsFor(project.lifecycle);
41
+ const users = project.lifecycle === "configured" ? await detectUserPresence(this.meta.cwd, this.meta.source) : "unknown";
42
+ const nextCommands = nextCommandsFor(serverLifecycle, project, users, this.meta.cliVersion);
43
+ const nextActions = nextActionsFor(project, users, this.meta.cliVersion);
40
44
  return this.emit({
41
45
  status: "ok",
42
46
  data: {
@@ -88,22 +92,57 @@ async function projectStatus(cwd) {
88
92
  message: "zitadel.json exists but .zitadel/secret is missing."
89
93
  };
90
94
  const secret = await readZitadelSecret(cwd);
95
+ const claim = claimState({
96
+ secret,
97
+ server: readProjectServer(config)
98
+ });
91
99
  return {
92
100
  lifecycle: "configured",
93
101
  project_id: String(config.project ?? secret.project_id ?? ""),
94
- issuer: readDevelopmentIssuer(config)
102
+ issuer: readDevelopmentIssuer(config),
103
+ ...claim.kind === "not-applicable" ? {} : { claim }
95
104
  };
96
105
  }
97
- function nextActionsFor(projectLifecycle) {
98
- if (projectLifecycle === "not-configured") return ["From your app directory, run setup; the CLI will detect the framework or ask in an empty directory."];
99
- return [];
106
+ const PRESENCE_PROBE_TIMEOUT_MS = 1500;
107
+ /**
108
+ * Whether the project has any users yet — the journey signal that stages the
109
+ * guidance: before the first successful registration the next step is
110
+ * verifying login, afterwards it is customizing and publishing config. Best
111
+ * effort by design: any failure (server unreachable, stale secret, timeout)
112
+ * reads as `unknown` and the caller keeps the lifecycle-only output.
113
+ */
114
+ async function detectUserPresence(cwd, source) {
115
+ try {
116
+ const probe = createZitadelClient({
117
+ baseUrl: source,
118
+ token: (await readZitadelSecret(cwd)).project_secret
119
+ }).queryUsers({ limit: 1 }, { signal: AbortSignal.timeout(PRESENCE_PROBE_TIMEOUT_MS) }).then(({ users }) => users.length > 0 ? "some" : "none").catch(() => "unknown");
120
+ return await Promise.race([probe, new Promise((resolve) => {
121
+ setTimeout(() => resolve("unknown"), PRESENCE_PROBE_TIMEOUT_MS + 250).unref();
122
+ })]);
123
+ } catch {
124
+ return "unknown";
125
+ }
100
126
  }
101
- function nextCommandsFor(serverLifecycle, projectLifecycle, cliVersion) {
127
+ function nextActionsFor(project, users, cliVersion) {
128
+ if (project.lifecycle === "not-configured") return ["From your app directory, run setup; the CLI will detect the framework or ask in an empty directory."];
129
+ if (project.lifecycle !== "configured") return [];
130
+ const claim = project.claim?.kind === "detached" ? [claimAction(cliVersion)] : [];
131
+ if (users === "none") return [verifyLoginAction(project.issuer), ...claim];
132
+ if (users === "some") return [...customizeAndPublishActions(cliVersion), ...claim];
133
+ return claim;
134
+ }
135
+ function nextCommandsFor(serverLifecycle, project, users, cliVersion) {
102
136
  const commands = [];
103
137
  if (serverLifecycle !== "running") commands.push(publicCliCommand("start", cliVersion));
104
- if (projectLifecycle === "not-configured") commands.push(publicCliCommand("setup --server local", cliVersion));
105
- else if (projectLifecycle === "orphaned-config") commands.push(publicCliCommand("setup --force", cliVersion), publicCliCommand("doctor --fix", cliVersion));
106
- else commands.push(publicCliCommand("doctor", cliVersion), publicCliCommand("apply", cliVersion));
138
+ if (project.lifecycle === "not-configured") commands.push(publicCliCommand("setup --server local", cliVersion));
139
+ else if (project.lifecycle === "orphaned-config") commands.push(publicCliCommand("setup --force", cliVersion), publicCliCommand("doctor --fix", cliVersion));
140
+ else {
141
+ commands.push(publicCliCommand("doctor", cliVersion));
142
+ if (project.claim?.kind === "detached") commands.push(claimCommand(cliVersion));
143
+ if (users === "none") commands.push(publicCliCommand("plan", cliVersion));
144
+ else commands.push(publicCliCommand("apply", cliVersion));
145
+ }
107
146
  return commands;
108
147
  }
109
148
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"status.mjs","names":[],"sources":["../../src/commands/status.ts"],"sourcesContent":["import { isProcessRunning } from \"../lib/local-server/binary\";\nimport { inspectContainer } from \"../lib/local-server/docker\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n checkLocalServerHealth,\n readRuntimeMetadata,\n runtimeSummary,\n} from \"../lib/local-server/runtime\";\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\nimport {\n hasZitadelConfig,\n hasZitadelSecret,\n readDevelopmentIssuer,\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\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 nextCommands = nextCommandsFor(serverLifecycle, project.lifecycle, this.meta.cliVersion);\n const nextActions = nextActionsFor(project.lifecycle);\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\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 return {\n lifecycle: \"configured\",\n project_id: String(config.project ?? secret.project_id ?? \"\"),\n issuer: readDevelopmentIssuer(config),\n };\n}\n\nfunction nextActionsFor(projectLifecycle: ProjectStatus[\"lifecycle\"]): string[] {\n if (projectLifecycle === \"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 return [];\n}\n\nfunction nextCommandsFor(\n serverLifecycle: string,\n projectLifecycle: ProjectStatus[\"lifecycle\"],\n cliVersion: string,\n): string[] {\n const commands: string[] = [];\n if (serverLifecycle !== \"running\") {\n commands.push(publicCliCommand(\"start\", cliVersion));\n }\n if (projectLifecycle === \"not-configured\") {\n commands.push(publicCliCommand(\"setup --server local\", cliVersion));\n } else if (projectLifecycle === \"orphaned-config\") {\n commands.push(\n publicCliCommand(\"setup --force\", cliVersion),\n publicCliCommand(\"doctor --fix\", cliVersion),\n );\n } else {\n commands.push(publicCliCommand(\"doctor\", cliVersion), publicCliCommand(\"apply\", cliVersion));\n }\n return commands;\n}\n"],"mappings":";;;;;;;;;;;AA0BA,IAAqB,SAArB,MAAqB,eAAe,YAAY;CAC9C,OAAgB,cAAc;CAE9B,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,OAAO;EAE1C,MAAM,UAAU,MAAM,oBADV,WAAW,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM,KAAA,EACtB,CAAC;AAC9C,MAAI,MAAM,WAAW,QACnB,OAAM,KAAK,OAAO,OAAO;GACvB,eAAe;GACf,QAAQ,SAAS,cAAA;GAClB,CAAC;MAEF,OAAM,KAAK,OAAO,MAAM;EAE1B,IAAI;EACJ,IAAI;AACJ,MAAI,SAAS,YAAY,SACvB,KAAI;AACF,YAAS,MAAM,iBAAiB,QAAQ,eAAe;WAChD,OAAO;AACd,iBAAc,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;EAGxE,MAAM,UAAU,UAAU,MAAM,uBAAuB,QAAQ,WAAW,GAAG;EAC7E,MAAM,iBAAiB,SAAS,YAAY,WAAW,iBAAiB,QAAQ,IAAI,GAAG;EACvF,MAAM,kBAAkB,oBAAoB;GAAE;GAAQ;GAAS;GAAgB;GAAS,CAAC;EAEzF,MAAM,UAAU,MAAM,cAAc,KAAK,KAAK,IAAI;EAClD,MAAM,eAAe,gBAAgB,iBAAiB,QAAQ,WAAW,KAAK,KAAK,WAAW;EAC9F,MAAM,cAAc,eAAe,QAAQ,UAAU;AAErD,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,QAAQ;KACN,WAAW;KACX,SAAS,eAAe,QAAQ;KAChC,QAAQ;MACN,WAAW,gBAAgB,KAAA;MAC3B,OAAO;MACP,kBAAkB,QAAQ,UAAU;MACpC,mBAAmB,QAAQ,WAAW;MACvC;KACD,SACE,SAAS,YAAY,WACjB;MACE,KAAK,QAAQ;MACb,SAAS;MACV,GACD,KAAA;KACN,QAAQ;MACN;MACA,KAAK,SAAS;MACf;KACF;IACD;IACA,cAAc;IACd,eAAe;IAChB;GACF,CAAC;;;AAIN,SAAS,oBAAoB,OAKlB;AACT,KAAI,CAAC,MAAM,QACT,QAAO;AAET,KAAI,MAAM,QAAQ,YAAY,UAAU;AACtC,MAAI,MAAM,kBAAkB,MAAM,QAChC,QAAO;AAET,SAAO,MAAM,iBAAiB,cAAc;;AAE9C,KAAI,MAAM,QAAQ,WAAW,MAAM,QACjC,QAAO;AAET,KAAI,MAAM,QAAQ,OAChB,QAAO;AAET,QAAO;;AAmBT,eAAe,cAAc,KAAqC;AAChE,KAAI,CAAE,MAAM,iBAAiB,IAAI,CAC/B,QAAO;EACL,WAAW;EACX,SAAS;EACV;CAGH,MAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,KAAI,CAAE,MAAM,iBAAiB,IAAI,CAC/B,QAAO;EACL,WAAW;EACX,YAAY,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU,KAAA;EAClE,SAAS;EACV;CAGH,MAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,QAAO;EACL,WAAW;EACX,YAAY,OAAO,OAAO,WAAW,OAAO,cAAc,GAAG;EAC7D,QAAQ,sBAAsB,OAAO;EACtC;;AAGH,SAAS,eAAe,kBAAwD;AAC9E,KAAI,qBAAqB,iBACvB,QAAO,CACL,sGACD;AAEH,QAAO,EAAE;;AAGX,SAAS,gBACP,iBACA,kBACA,YACU;CACV,MAAM,WAAqB,EAAE;AAC7B,KAAI,oBAAoB,UACtB,UAAS,KAAK,iBAAiB,SAAS,WAAW,CAAC;AAEtD,KAAI,qBAAqB,iBACvB,UAAS,KAAK,iBAAiB,wBAAwB,WAAW,CAAC;UAC1D,qBAAqB,kBAC9B,UAAS,KACP,iBAAiB,iBAAiB,WAAW,EAC7C,iBAAiB,gBAAgB,WAAW,CAC7C;KAED,UAAS,KAAK,iBAAiB,UAAU,WAAW,EAAE,iBAAiB,SAAS,WAAW,CAAC;AAE9F,QAAO"}
1
+ {"version":3,"file":"status.mjs","names":[],"sources":["../../src/commands/status.ts"],"sourcesContent":["import { createZitadelClient } from \"@zitadel/api/client\";\n\nimport { claimAction, claimCommand, claimState, type ClaimState } 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, 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\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.\n const claim = project.claim?.kind === \"detached\" ? [claimAction(cliVersion)] : [];\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 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"],"mappings":"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"}
@@ -1,8 +1,11 @@
1
- import { C as resolveCwd, h as readRuntimeMetadata, p as localContainerName, t as BaseCommand, x as publicCliCommand } from "../oclif-VkCTGIEk.mjs";
2
- import { g as stopBinaryRuntime, u as stopAndRemoveContainer } from "../docker-BA78SdC2.mjs";
1
+ import { E as ZitadelError, h as readRuntimeMetadata, j as publicCliCommand, p as localContainerName, t as BaseCommand, x as resolveCwd } from "../oclif-CanO3zdt.mjs";
2
+ import { g as stopBinaryRuntime, u as stopAndRemoveContainer } from "../docker-DcRGTOJa.mjs";
3
+ import { t as discoverManagedRuntimeProcesses } from "../processes-DKHPkU8O.mjs";
4
+ import { Flags } from "@oclif/core";
3
5
  //#region src/commands/stop.ts
4
6
  var Stop = class Stop extends BaseCommand {
5
7
  static description = "Stop the local Zitadel server.";
8
+ static flags = { all: Flags.boolean({ description: "Stop all discovered CLI-managed local Zitadel runtime processes." }) };
6
9
  async run() {
7
10
  const { flags } = await this.parse(Stop);
8
11
  const runtime = await readRuntimeMetadata(resolveCwd(typeof flags.cwd === "string" ? flags.cwd : void 0));
@@ -10,6 +13,7 @@ var Stop = class Stop extends BaseCommand {
10
13
  resolveServer: false,
11
14
  source: runtime?.server_url ?? "http://localhost:8080"
12
15
  });
16
+ if (flags.all) return this.stopAllManagedRuntimes();
13
17
  const containerName = runtime?.backend === "docker" ? runtime.container_name : localContainerName(this.meta.cwd);
14
18
  if (this.meta.dryRun) return this.emit({
15
19
  status: "ok",
@@ -27,17 +31,27 @@ var Stop = class Stop extends BaseCommand {
27
31
  next_commands: [publicCliCommand("stop", this.meta.cliVersion)]
28
32
  }
29
33
  });
30
- if (runtime?.backend === "binary") await stopBinaryRuntime(runtime.pid);
31
- else await stopAndRemoveContainer(containerName);
34
+ let stopResult;
35
+ if (runtime?.backend === "binary") {
36
+ stopResult = await stopBinaryRuntime(runtime.pid);
37
+ if (stopResult.status === "failed") throw new ZitadelError("E_VALIDATION", "Local Zitadel server did not stop", {
38
+ hint: "Inspect the local runtime process and stop it manually, then rerun `zitadel stop`.",
39
+ details: {
40
+ runtime,
41
+ stop_result: stopResult
42
+ }
43
+ });
44
+ } else await stopAndRemoveContainer(containerName);
32
45
  return this.emit({
33
46
  status: "ok",
34
47
  data: {
35
- title: "Local Zitadel server stopped.",
48
+ title: stopResult?.status === "stale" ? "Local Zitadel server was not running." : "Local Zitadel server stopped.",
36
49
  runtime: {
37
50
  backend: runtime?.backend ?? "missing",
38
51
  ...runtime?.backend === "binary" ? {
39
52
  pid: runtime.pid,
40
- log_path: runtime.log_path
53
+ log_path: runtime.log_path,
54
+ stop_result: stopResult
41
55
  } : { container_name: containerName },
42
56
  data_preserved: true,
43
57
  data_dir: runtime?.data_dir
@@ -45,6 +59,45 @@ var Stop = class Stop extends BaseCommand {
45
59
  }
46
60
  });
47
61
  }
62
+ async stopAllManagedRuntimes() {
63
+ const discovery = await discoverManagedRuntimeProcesses();
64
+ if (!discovery.supported) return this.emit({
65
+ status: "ok",
66
+ data: {
67
+ title: "Managed local runtime process discovery is unavailable.",
68
+ sweep: {
69
+ supported: false,
70
+ error: discovery.error,
71
+ stopped: []
72
+ }
73
+ },
74
+ warnings: ["managed-runtime-processes: discovery unavailable"]
75
+ });
76
+ const results = [];
77
+ for (const processInfo of discovery.processes) results.push({
78
+ process: processInfo,
79
+ stop_result: await stopBinaryRuntime(processInfo.pid)
80
+ });
81
+ if (results.filter((result) => result.stop_result.status === "failed").length > 0) throw new ZitadelError("E_VALIDATION", "Some managed local runtime processes did not stop", {
82
+ hint: "Inspect the failed process IDs and stop them manually, then rerun `zitadel stop --all`.",
83
+ details: {
84
+ supported: true,
85
+ results
86
+ }
87
+ });
88
+ return this.emit({
89
+ status: "ok",
90
+ data: {
91
+ title: results.length === 0 ? "No host-wide managed local runtime processes found." : "Host-wide managed local runtime processes stopped.",
92
+ sweep: {
93
+ supported: true,
94
+ scope: "host",
95
+ count: results.length,
96
+ results
97
+ }
98
+ }
99
+ });
100
+ }
48
101
  };
49
102
  //#endregion
50
103
  export { Stop as default };
@@ -1 +1 @@
1
- {"version":3,"file":"stop.mjs","names":[],"sources":["../../src/commands/stop.ts"],"sourcesContent":["import { stopBinaryRuntime } from \"../lib/local-server/binary\";\nimport { stopAndRemoveContainer } from \"../lib/local-server/docker\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n localContainerName,\n readRuntimeMetadata,\n} from \"../lib/local-server/runtime\";\nimport { BaseCommand, 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\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 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 if (runtime?.backend === \"binary\") {\n await stopBinaryRuntime(runtime.pid);\n } else {\n await stopAndRemoveContainer(containerName);\n }\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local Zitadel server stopped.\",\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 },\n });\n }\n}\n"],"mappings":";;;AAWA,IAAqB,OAArB,MAAqB,aAAa,YAAY;CAC5C,OAAgB,cAAc;CAE9B,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,KAAK;EAExC,MAAM,UAAU,MAAM,oBADV,WAAW,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM,KAAA,EACtB,CAAC;AAC9C,QAAM,KAAK,OAAO,OAAO;GACvB,eAAe;GACf,QAAQ,SAAS,cAAA;GAClB,CAAC;EAEF,MAAM,gBACJ,SAAS,YAAY,WAAW,QAAQ,iBAAiB,mBAAmB,KAAK,KAAK,IAAI;AAC5F,MAAI,KAAK,KAAK,OACZ,QAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,SAAS;KACP,SAAS,SAAS,WAAW;KAC7B,GAAI,SAAS,YAAY,WACrB;MAAE,KAAK,QAAQ;MAAK,UAAU,QAAQ;MAAU,GAChD,EAAE,gBAAgB,eAAe;KACrC,gBAAgB;KAChB,UAAU,SAAS;KACpB;IACD,eAAe,CAAC,iBAAiB,QAAQ,KAAK,KAAK,WAAW,CAAC;IAChE;GACF,CAAC;AAGJ,MAAI,SAAS,YAAY,SACvB,OAAM,kBAAkB,QAAQ,IAAI;MAEpC,OAAM,uBAAuB,cAAc;AAG7C,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,SAAS;KACP,SAAS,SAAS,WAAW;KAC7B,GAAI,SAAS,YAAY,WACrB;MAAE,KAAK,QAAQ;MAAK,UAAU,QAAQ;MAAU,GAChD,EAAE,gBAAgB,eAAe;KACrC,gBAAgB;KAChB,UAAU,SAAS;KACpB;IACF;GACF,CAAC"}
1
+ {"version":3,"file":"stop.mjs","names":[],"sources":["../../src/commands/stop.ts"],"sourcesContent":["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, 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 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"],"mappings":";;;;;AAkBA,IAAqB,OAArB,MAAqB,aAAa,YAAY;CAC5C,OAAgB,cAAc;CAC9B,OAAgB,QAAQ,EACtB,KAAK,MAAM,QAAQ,EACjB,aAAa,oEACd,CAAC,EACH;CAED,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,KAAK;EAExC,MAAM,UAAU,MAAM,oBADV,WAAW,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM,KAAA,EACtB,CAAC;AAC9C,QAAM,KAAK,OAAO,OAAO;GACvB,eAAe;GACf,QAAQ,SAAS,cAAA;GAClB,CAAC;AAEF,MAAI,MAAM,IACR,QAAO,KAAK,wBAAwB;EAGtC,MAAM,gBACJ,SAAS,YAAY,WAAW,QAAQ,iBAAiB,mBAAmB,KAAK,KAAK,IAAI;AAC5F,MAAI,KAAK,KAAK,OACZ,QAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,SAAS;KACP,SAAS,SAAS,WAAW;KAC7B,GAAI,SAAS,YAAY,WACrB;MAAE,KAAK,QAAQ;MAAK,UAAU,QAAQ;MAAU,GAChD,EAAE,gBAAgB,eAAe;KACrC,gBAAgB;KAChB,UAAU,SAAS;KACpB;IACD,eAAe,CAAC,iBAAiB,QAAQ,KAAK,KAAK,WAAW,CAAC;IAChE;GACF,CAAC;EAGJ,IAAI;AACJ,MAAI,SAAS,YAAY,UAAU;AACjC,gBAAa,MAAM,kBAAkB,QAAQ,IAAI;AACjD,OAAI,WAAW,WAAW,SACxB,OAAM,IAAI,aAAa,gBAAgB,qCAAqC;IAC1E,MAAM;IACN,SAAS;KAAE;KAAS,aAAa;KAAY;IAC9C,CAAC;QAGJ,OAAM,uBAAuB,cAAc;AAG7C,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OACE,YAAY,WAAW,UACnB,0CACA;IACN,SAAS;KACP,SAAS,SAAS,WAAW;KAC7B,GAAI,SAAS,YAAY,WACrB;MACE,KAAK,QAAQ;MACb,UAAU,QAAQ;MAClB,aAAa;MACd,GACD,EAAE,gBAAgB,eAAe;KACrC,gBAAgB;KAChB,UAAU,SAAS;KACpB;IACF;GACF,CAAC;;CAGJ,MAAc,yBAAgD;EAC5D,MAAM,YAAY,MAAM,iCAAiC;AACzD,MAAI,CAAC,UAAU,UACb,QAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,OAAO;KAAE,WAAW;KAAO,OAAO,UAAU;KAAO,SAAS,EAAE;KAAE;IACjE;GACD,UAAU,CAAC,mDAAmD;GAC/D,CAAC;EAGJ,MAAM,UAAuC,EAAE;AAC/C,OAAK,MAAM,eAAe,UAAU,UAClC,SAAQ,KAAK;GACX,SAAS;GACT,aAAa,MAAM,kBAAkB,YAAY,IAAI;GACtD,CAAC;AAGJ,MADe,QAAQ,QAAQ,WAAW,OAAO,YAAY,WAAW,SAC9D,CAAC,SAAS,EAClB,OAAM,IAAI,aAAa,gBAAgB,qDAAqD;GAC1F,MAAM;GACN,SAAS;IAAE,WAAW;IAAM;IAAS;GACtC,CAAC;AAGJ,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OACE,QAAQ,WAAW,IACf,wDACA;IACN,OAAO;KACL,WAAW;KACX,OAAO;KACP,OAAO,QAAQ;KACf;KACD;IACF;GACF,CAAC"}
@@ -0,0 +1,38 @@
1
+ //#region src/lib/branding/designs.ts
2
+ /**
3
+ * Human-facing name and one-line hint for each shipped login design. Shared
4
+ * by the setup wizard, `branding eject`, and the setup summary so the label a
5
+ * user picks ("Split (reversed)") and the slug the machine records
6
+ * (`split-right`) stay visibly paired everywhere — the summary echoing a slug
7
+ * the prompt never showed reads as "did my selection apply?".
8
+ */
9
+ const BRANDING_DESIGN_INFO = {
10
+ centered: {
11
+ label: "Centered",
12
+ hint: "the built-in look, forked as an editable template"
13
+ },
14
+ split: {
15
+ label: "Split",
16
+ hint: "brand panel left, form right; narrow containers show a compact brand mark"
17
+ },
18
+ "split-right": {
19
+ label: "Split (reversed)",
20
+ hint: "form left, brand panel right; narrow containers show a compact brand mark"
21
+ },
22
+ hero: {
23
+ label: "Hero",
24
+ hint: "landing-style brand pane left, form right; editable text fallback when narrow"
25
+ },
26
+ minimal: {
27
+ label: "Minimal",
28
+ hint: "no card chrome, fields straight on the page"
29
+ }
30
+ };
31
+ /** The prompt label for a design slug, falling back to the slug itself. */
32
+ function brandingDesignLabel(design) {
33
+ return BRANDING_DESIGN_INFO[design]?.label ?? design;
34
+ }
35
+ //#endregion
36
+ export { brandingDesignLabel as n, BRANDING_DESIGN_INFO as t };
37
+
38
+ //# sourceMappingURL=designs-Ckz18Dpo.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"designs-Ckz18Dpo.mjs","names":[],"sources":["../src/lib/branding/designs.ts"],"sourcesContent":["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"],"mappings":";;;;;;;;AASA,MAAa,uBAAgF;CAC3F,UAAU;EACR,OAAO;EACP,MAAM;EACP;CACD,OAAO;EACL,OAAO;EACP,MAAM;EACP;CACD,eAAe;EACb,OAAO;EACP,MAAM;EACP;CACD,MAAM;EACJ,OAAO;EACP,MAAM;EACP;CACD,SAAS;EACP,OAAO;EACP,MAAM;EACP;CACF;;AAGD,SAAgB,oBAAoB,QAAwB;AAC1D,QAAQ,qBAA2D,SAAS,SAAS"}
@@ -1,19 +1,22 @@
1
- import { D as ZitadelError, i as CONTAINER_HTTP_PORT, r as CONTAINER_DATA_DIR } from "./oclif-VkCTGIEk.mjs";
1
+ import { E as ZitadelError, i as CONTAINER_HTTP_PORT, r as CONTAINER_DATA_DIR } from "./oclif-CanO3zdt.mjs";
2
2
  import { createRequire } from "node:module";
3
- import { dirname, join } from "node:path";
4
3
  import { mkdir, open, readFile, stat } from "node:fs/promises";
4
+ import { dirname, join } from "node:path";
5
5
  import { createReadStream } from "node:fs";
6
6
  import { spawn } from "node:child_process";
7
7
  //#region src/lib/local-server/binary.ts
8
8
  const SERVER_NPM_PACKAGE = "@zitadel/server";
9
9
  const START_COMMAND_ENV = "ZITADEL_SERVER_BINARY";
10
+ const START_COMMAND_VERSION_ENV = "ZITADEL_SERVER_BINARY_VERSION";
11
+ const STOP_TIMEOUT_MS = 1e4;
12
+ const STOP_KILL_TIMEOUT_MS = 2e3;
10
13
  const require = createRequire(import.meta.url);
11
14
  function resolveServerCommand(env = process.env) {
12
15
  if (env[START_COMMAND_ENV]) return {
13
16
  command: env[START_COMMAND_ENV],
14
17
  args: [],
15
18
  serverPackage: SERVER_NPM_PACKAGE,
16
- serverVersion: "override"
19
+ serverVersion: env[START_COMMAND_VERSION_ENV]?.trim() || "override"
17
20
  };
18
21
  const manifestPath = resolveServerPackageManifest();
19
22
  const manifest = require(manifestPath);
@@ -66,14 +69,38 @@ async function startBinaryRuntime(spec) {
66
69
  }
67
70
  }
68
71
  async function stopBinaryRuntime(pid) {
69
- if (!isProcessRunning(pid)) return;
70
- if (!signalProcess(pid, "SIGTERM")) return;
71
- const deadline = Date.now() + 1e4;
72
- while (Date.now() < deadline) {
73
- if (!isProcessRunning(pid)) return;
74
- await delay(200);
72
+ if (!isProcessRunning(pid)) return {
73
+ pid,
74
+ status: "stale",
75
+ target: "process"
76
+ };
77
+ const term = signalRuntime(pid, "SIGTERM");
78
+ if (!term.sent) return {
79
+ pid,
80
+ status: "stale",
81
+ target: term.target
82
+ };
83
+ if (await waitForExit(pid, STOP_TIMEOUT_MS)) return {
84
+ pid,
85
+ status: "stopped",
86
+ target: term.target,
87
+ signal: "SIGTERM"
88
+ };
89
+ if (isProcessRunning(pid)) {
90
+ const kill = signalRuntime(pid, "SIGKILL");
91
+ if (kill.sent && await waitForExit(pid, STOP_KILL_TIMEOUT_MS)) return {
92
+ pid,
93
+ status: "stopped",
94
+ target: kill.target,
95
+ signal: "SIGKILL"
96
+ };
75
97
  }
76
- if (isProcessRunning(pid)) signalProcess(pid, "SIGKILL");
98
+ return {
99
+ pid,
100
+ status: "failed",
101
+ target: term.target,
102
+ signal: "SIGKILL"
103
+ };
77
104
  }
78
105
  function isProcessRunning(pid) {
79
106
  try {
@@ -165,6 +192,29 @@ function signalProcess(pid, signal) {
165
192
  throw error;
166
193
  }
167
194
  }
195
+ function signalRuntime(pid, signal) {
196
+ if (process.platform !== "win32") try {
197
+ process.kill(-pid, signal);
198
+ return {
199
+ sent: true,
200
+ target: "process-group"
201
+ };
202
+ } catch (error) {
203
+ if (!isErrno(error, "ESRCH")) throw error;
204
+ }
205
+ return {
206
+ sent: signalProcess(pid, signal),
207
+ target: "process"
208
+ };
209
+ }
210
+ async function waitForExit(pid, timeoutMs) {
211
+ const deadline = Date.now() + timeoutMs;
212
+ while (Date.now() < deadline) {
213
+ if (!isProcessRunning(pid)) return true;
214
+ await delay(200);
215
+ }
216
+ return !isProcessRunning(pid);
217
+ }
168
218
  function errorMessage(error) {
169
219
  return error instanceof Error ? error.message : String(error);
170
220
  }
@@ -380,4 +430,4 @@ function dockerError(action, args, cause) {
380
430
  //#endregion
381
431
  export { followContainerLogs as a, metadataFromStart as c, assertServerPackageAvailable as d, binaryLogs as f, stopBinaryRuntime as g, startBinaryRuntime as h, ensureImage as i, startContainer as l, isProcessRunning as m, currentUser as n, imageAvailable as o, followBinaryLogs as p, dockerAvailable as r, inspectContainer as s, containerLogs as t, stopAndRemoveContainer as u };
382
432
 
383
- //# sourceMappingURL=docker-BA78SdC2.mjs.map
433
+ //# sourceMappingURL=docker-DcRGTOJa.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-DcRGTOJa.mjs","names":[],"sources":["../src/lib/local-server/binary.ts","../src/lib/local-server/docker.ts"],"sourcesContent":["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 {\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};\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 await mkdir(dirname(spec.logPath), { recursive: true, mode: 0o700 });\n const log = await open(spec.logPath, \"a\", 0o600);\n try {\n const child = spawn(command.command, command.args, {\n detached: true,\n env: {\n ...process.env,\n NEXTGEN_SERVER_ADDRESS: `:${String(spec.port)}`,\n NEXTGEN_SERVER_DATA_DIR: spec.dataDir,\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, ...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 };\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","import { spawn } from \"node:child_process\";\n\nimport { ZitadelError } from \"../errors\";\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\nexport type DockerRunSpec = {\n containerName: string;\n image: string;\n port: number;\n dataDir: string;\n identity?: ContainerIdentity;\n};\n\nexport function dockerRunArgs(spec: DockerRunSpec): 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 \"--env\",\n `NEXTGEN_SERVER_ADDRESS=:${CONTAINER_HTTP_PORT}`,\n \"--env\",\n `NEXTGEN_SERVER_DATA_DIR=${CONTAINER_DATA_DIR}`,\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 return args;\n}\n\nexport async function runDocker(args: string[]): Promise<DockerResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"docker\", args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: process.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(spec: DockerRunSpec): Promise<string> {\n const args = dockerRunArgs(spec);\n const result = await requireDocker(args, \"Start local Zitadel container\");\n return result.stdout.trim();\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}): 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 };\n}\n\nexport async function requireDocker(args: string[], action: string): Promise<DockerResult> {\n let result: DockerResult;\n try {\n result = await runDocker(args);\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"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ //#region src/lib/environment.ts
3
+ /**
4
+ * CLI-side deployment environment. Not an API model — it gates which
5
+ * `zitadel.json` environment block and server the commands target.
6
+ * Project request/response shapes live in `@zitadel/api`
7
+ * (generated from the OpenAPI spec).
8
+ */
9
+ const environmentSchema = z.enum([
10
+ "development",
11
+ "preview",
12
+ "production"
13
+ ]);
14
+ //#endregion
15
+ export { environmentSchema as t };
16
+
17
+ //# sourceMappingURL=environment-rjRVkJjW.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-rjRVkJjW.mjs","names":[],"sources":["../src/lib/environment.ts"],"sourcesContent":["import { z } from \"zod\";\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 */\nexport const environmentSchema = z.enum([\"development\", \"preview\", \"production\"]);\n"],"mappings":";;;;;;;;AAQA,MAAa,oBAAoB,EAAE,KAAK;CAAC;CAAe;CAAW;CAAa,CAAC"}