@zitadel/cli 0.1.0-alpha.4 → 0.1.0-alpha.8

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 (39) hide show
  1. package/README.md +70 -63
  2. package/SKILLS.md +60 -18
  3. package/dist/commands/apply.mjs +3 -3
  4. package/dist/commands/doctor.mjs +75 -20
  5. package/dist/commands/doctor.mjs.map +1 -1
  6. package/dist/commands/eject.mjs +13 -6
  7. package/dist/commands/eject.mjs.map +1 -1
  8. package/dist/commands/logs.mjs +13 -5
  9. package/dist/commands/logs.mjs.map +1 -1
  10. package/dist/commands/plan.mjs +3 -3
  11. package/dist/commands/reset.mjs +16 -7
  12. package/dist/commands/reset.mjs.map +1 -1
  13. package/dist/commands/setup.mjs +56 -17
  14. package/dist/commands/setup.mjs.map +1 -1
  15. package/dist/commands/start.mjs +104 -11
  16. package/dist/commands/start.mjs.map +1 -1
  17. package/dist/commands/status.mjs +26 -7
  18. package/dist/commands/status.mjs.map +1 -1
  19. package/dist/commands/stop.mjs +15 -6
  20. package/dist/commands/stop.mjs.map +1 -1
  21. package/dist/docker-BA78SdC2.mjs +383 -0
  22. package/dist/docker-BA78SdC2.mjs.map +1 -0
  23. package/dist/docker-guidance-BvfpmsDj.mjs +21 -0
  24. package/dist/docker-guidance-BvfpmsDj.mjs.map +1 -0
  25. package/dist/{oclif-B3Qhw0cj.mjs → oclif-VkCTGIEk.mjs} +50 -15
  26. package/dist/oclif-VkCTGIEk.mjs.map +1 -0
  27. package/dist/orca-CfKDQRop.mjs +2556 -0
  28. package/dist/orca-CfKDQRop.mjs.map +1 -0
  29. package/dist/{project-kWWyS7fS.mjs → project-CKAHtHML.mjs} +2 -2
  30. package/dist/{project-kWWyS7fS.mjs.map → project-CKAHtHML.mjs.map} +1 -1
  31. package/dist/{sync-CHXZqYR7.mjs → sync-B5lqgQO3.mjs} +2 -2
  32. package/dist/{sync-CHXZqYR7.mjs.map → sync-B5lqgQO3.mjs.map} +1 -1
  33. package/oclif.manifest.json +37 -3
  34. package/package.json +8 -41
  35. package/dist/docker-B4zvLujy.mjs +0 -210
  36. package/dist/docker-B4zvLujy.mjs.map +0 -1
  37. package/dist/oclif-B3Qhw0cj.mjs.map +0 -1
  38. package/dist/orca-BGM8VCgQ.mjs +0 -1141
  39. package/dist/orca-BGM8VCgQ.mjs.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @zitadel/cli
2
2
 
3
- Scaffolds Zitadel auth (login, register, profile, middleware) into a Next.js app.
3
+ Scaffolds Zitadel auth (login, register, profile, middleware) into a Next.js, React, Vue, Angular, or Nuxt app.
4
4
 
5
5
  ```sh
6
6
  npx @zitadel/cli@alpha start
@@ -15,8 +15,8 @@ automation when reproducibility matters.
15
15
 
16
16
  ## Requirements
17
17
 
18
- - Node 20+
19
- - Docker for the managed local Zitadel runtime
18
+ - Node 24+
19
+ - Docker only when using the optional Docker runtime backend
20
20
  - A Next.js project, or an empty directory where setup can scaffold one
21
21
 
22
22
  ## Quickstart
@@ -30,20 +30,21 @@ npx @zitadel/cli@alpha setup --server local
30
30
  npm run dev
31
31
  ```
32
32
 
33
- `start` runs a Docker-backed local Zitadel server and stores runtime data
34
- under `.zitadel/local/`. Alpha CLI versions use the matching
35
- `ghcr.io/zitadel/nextgen:<cli-version>` image by default; local/dev builds fall
36
- back to `ghcr.io/zitadel/nextgen:latest`. Override with `--image` or
37
- `ZITADEL_LOCAL_IMAGE` for advanced debugging.
33
+ `start` runs the `@zitadel/server` npm binary by default and stores runtime data
34
+ under `.zitadel/local/`. Remote-server setup can use `--server <url>` without
35
+ starting a local runtime. Use `--runtime docker`, `--image`, or
36
+ `ZITADEL_LOCAL_IMAGE` for advanced Docker backend debugging.
38
37
  `setup --server local` creates a project on that local server, asks which
39
38
  framework to scaffold when the directory is fresh, writes the Next.js app into
40
- the current directory, scaffolds `app/login`, `app/register`, and `proxy.ts`
41
- for Next 16+ or `middleware.ts` for older Next versions, writes `.env.local`
42
- and `.zitadel/`, and installs dependencies with the detected package manager.
43
- Pass `--skip-install` to install them yourself. The project's default user
44
- schema and login flow are provisioned server-side at creation time, so the CLI
45
- does not scaffold or upload them. Open `http://localhost:3000/login` to see the
46
- login page.
39
+ the current directory, scaffolds `app/login`, `app/register`, `app/profile`, and
40
+ `proxy.ts` for Next 16+ or `middleware.ts` for older Next versions. Fresh
41
+ scaffolds also replace the starter `app/page.tsx` with links to sign in, create
42
+ an account, and profile. Setup writes `.env.local` and `.zitadel/`, and installs
43
+ dependencies with the detected package manager. Pass `--skip-install` to install
44
+ them yourself. The project's default user schema and login flow are provisioned
45
+ server-side at creation time, so the CLI does not scaffold or upload them. Open
46
+ the dev server URL printed by your framework, register a user, log out, log back
47
+ in, and end on the signed-in profile page.
47
48
 
48
49
  For a reproducible tester report, use the exact alpha train from the GitHub
49
50
  Release:
@@ -61,12 +62,12 @@ passkey can sign in with either credential.
61
62
 
62
63
  ## Other commands
63
64
 
64
- - `zitadel doctor` — verify the local Docker runtime and generated project files
65
- - `zitadel status` — summarise the local Docker runtime and project
65
+ - `zitadel doctor` — verify the local runtime and generated project files
66
+ - `zitadel status` — summarise the local runtime and project
66
67
  - `zitadel plan` — validate config and preview sync changes without mutation
67
68
  - `zitadel apply` — validate and upload repo config to Zitadel
68
69
  - `zitadel eject` — remove what setup wrote (alias: `zitadel uninstall`)
69
- - `zitadel start|stop|logs|reset` — manage the local Docker runtime
70
+ - `zitadel start|stop|logs|reset` — manage the local runtime
70
71
 
71
72
  ## Reference
72
73
 
@@ -74,24 +75,23 @@ passkey can sign in with either credential.
74
75
  <summary>Full command reference</summary>
75
76
 
76
77
  <!-- commands -->
77
-
78
- - [`zitadel apply`](#zitadel-apply)
79
- - [`zitadel autocomplete [SHELL]`](#zitadel-autocomplete-shell)
80
- - [`zitadel commands`](#zitadel-commands)
81
- - [`zitadel doctor`](#zitadel-doctor)
82
- - [`zitadel eject`](#zitadel-eject)
83
- - [`zitadel help [COMMAND]`](#zitadel-help-command)
84
- - [`zitadel logs`](#zitadel-logs)
85
- - [`zitadel plan`](#zitadel-plan)
86
- - [`zitadel reset`](#zitadel-reset)
87
- - [`zitadel search`](#zitadel-search)
88
- - [`zitadel setup`](#zitadel-setup)
89
- - [`zitadel start`](#zitadel-start)
90
- - [`zitadel status`](#zitadel-status)
91
- - [`zitadel stop`](#zitadel-stop)
92
- - [`zitadel uninstall`](#zitadel-uninstall)
93
- - [`zitadel version`](#zitadel-version)
94
- - [`zitadel which`](#zitadel-which)
78
+ * [`zitadel apply`](#zitadel-apply)
79
+ * [`zitadel autocomplete [SHELL]`](#zitadel-autocomplete-shell)
80
+ * [`zitadel commands`](#zitadel-commands)
81
+ * [`zitadel doctor`](#zitadel-doctor)
82
+ * [`zitadel eject`](#zitadel-eject)
83
+ * [`zitadel help [COMMAND]`](#zitadel-help-command)
84
+ * [`zitadel logs`](#zitadel-logs)
85
+ * [`zitadel plan`](#zitadel-plan)
86
+ * [`zitadel reset`](#zitadel-reset)
87
+ * [`zitadel search`](#zitadel-search)
88
+ * [`zitadel setup`](#zitadel-setup)
89
+ * [`zitadel start`](#zitadel-start)
90
+ * [`zitadel status`](#zitadel-status)
91
+ * [`zitadel stop`](#zitadel-stop)
92
+ * [`zitadel uninstall`](#zitadel-uninstall)
93
+ * [`zitadel version`](#zitadel-version)
94
+ * [`zitadel which`](#zitadel-which)
95
95
 
96
96
  ## `zitadel apply`
97
97
 
@@ -99,19 +99,19 @@ Validate and upload repo config to the platform.
99
99
 
100
100
  ```
101
101
  USAGE
102
- $ zitadel apply [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
103
- [-e development|preview|production]
102
+ $ zitadel apply [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug] [-e
103
+ development|preview|production]
104
104
 
105
105
  FLAGS
106
- -c, --cwd=<value> Project directory to operate on.
107
- -e, --environment=<option> Target environment (default: development).
108
- <options: development|preview|production>
109
- -f, --force Overwrite protected files on conflict.
110
- -n, --non-interactive Disable prompts. Required when scripting or running as an agent.
111
- -s, --server=<value> Override the resolved server URL.
112
- --debug Debug logging.
113
- --dry-run Preview without mutating files or the platform.
114
- --verbose Verbose logging.
106
+ -c, --cwd=<value> Project directory to operate on.
107
+ -e, --environment=<option> Target environment (default: development).
108
+ <options: development|preview|production>
109
+ -f, --force Overwrite protected files on conflict.
110
+ -n, --non-interactive Disable prompts. Required when scripting or running as an agent.
111
+ -s, --server=<value> Override the resolved server URL.
112
+ --debug Debug logging.
113
+ --dry-run Preview without mutating files or the platform.
114
+ --verbose Verbose logging.
115
115
 
116
116
  GLOBAL FLAGS
117
117
  --json Format output as json.
@@ -187,7 +187,7 @@ Verify local runtime and project state.
187
187
  ```
188
188
  USAGE
189
189
  $ zitadel doctor [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug] [--fix]
190
- [--image <value>] [--port <value>]
190
+ [--image <value>] [--port <value>] [--runtime binary|docker]
191
191
 
192
192
  FLAGS
193
193
  -c, --cwd=<value> Project directory to operate on.
@@ -199,6 +199,8 @@ FLAGS
199
199
  --fix Re-apply missing managed files.
200
200
  --image=<value> Container image to check.
201
201
  --port=<value> [default: 8080] Local HTTP port.
202
+ --runtime=<option> Local runtime backend.
203
+ <options: binary|docker>
202
204
  --verbose Verbose logging.
203
205
 
204
206
  GLOBAL FLAGS
@@ -288,19 +290,19 @@ Validate config without mutation and preview the sync diff.
288
290
 
289
291
  ```
290
292
  USAGE
291
- $ zitadel plan [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
292
- [-e development|preview|production]
293
+ $ zitadel plan [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug] [-e
294
+ development|preview|production]
293
295
 
294
296
  FLAGS
295
- -c, --cwd=<value> Project directory to operate on.
296
- -e, --environment=<option> Target environment (default: development).
297
- <options: development|preview|production>
298
- -f, --force Overwrite protected files on conflict.
299
- -n, --non-interactive Disable prompts. Required when scripting or running as an agent.
300
- -s, --server=<value> Override the resolved server URL.
301
- --debug Debug logging.
302
- --dry-run Preview without mutating files or the platform.
303
- --verbose Verbose logging.
297
+ -c, --cwd=<value> Project directory to operate on.
298
+ -e, --environment=<option> Target environment (default: development).
299
+ <options: development|preview|production>
300
+ -f, --force Overwrite protected files on conflict.
301
+ -n, --non-interactive Disable prompts. Required when scripting or running as an agent.
302
+ -s, --server=<value> Override the resolved server URL.
303
+ --debug Debug logging.
304
+ --dry-run Preview without mutating files or the platform.
305
+ --verbose Verbose logging.
304
306
 
305
307
  GLOBAL FLAGS
306
308
  --json Format output as json.
@@ -356,7 +358,7 @@ Create a Zitadel project and scaffold local auth.
356
358
  ```
357
359
  USAGE
358
360
  $ zitadel setup [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
359
- [--framework next] [--renderer react|web-component] [--skip-install]
361
+ [--framework next|nuxt|react|vue|angular] [--renderer react|web-component] [--dev-port <value>] [--skip-install]
360
362
 
361
363
  FLAGS
362
364
  -c, --cwd=<value> Project directory to operate on.
@@ -364,9 +366,11 @@ FLAGS
364
366
  -n, --non-interactive Disable prompts. Required when scripting or running as an agent.
365
367
  -s, --server=<value> Override the resolved server URL.
366
368
  --debug Debug logging.
369
+ --dev-port=<value> Dev-server port; also the issuer origin registered with Zitadel. Defaults to the detected
370
+ port. Use distinct ports to run several scaffolded apps side by side.
367
371
  --dry-run Preview without mutating files or the platform.
368
372
  --framework=<option> Framework to target.
369
- <options: next>
373
+ <options: next|nuxt|react|vue|angular>
370
374
  --renderer=<option> Renderer (default: react).
371
375
  <options: react|web-component>
372
376
  --skip-install Do not install dependencies after setup updates package.json.
@@ -380,6 +384,8 @@ DESCRIPTION
380
384
 
381
385
  EXAMPLES
382
386
  $ zitadel setup --framework next
387
+
388
+ $ zitadel setup --framework react --dev-port 3000
383
389
  ```
384
390
 
385
391
  ## `zitadel start`
@@ -389,7 +395,7 @@ Start a local Zitadel server.
389
395
  ```
390
396
  USAGE
391
397
  $ zitadel start [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug] [--image
392
- <value>] [--port <value>]
398
+ <value>] [--port <value>] [--runtime binary|docker]
393
399
 
394
400
  FLAGS
395
401
  -c, --cwd=<value> Project directory to operate on.
@@ -400,6 +406,8 @@ FLAGS
400
406
  --dry-run Preview without mutating files or the platform.
401
407
  --image=<value> Container image to run.
402
408
  --port=<value> [default: 8080] Local HTTP port.
409
+ --runtime=<option> Local runtime backend.
410
+ <options: binary|docker>
403
411
  --verbose Verbose logging.
404
412
 
405
413
  GLOBAL FLAGS
@@ -537,7 +545,6 @@ EXAMPLES
537
545
  ```
538
546
 
539
547
  _See code: [@oclif/plugin-which](https://github.com/oclif/plugin-which/blob/3.2.55/src/commands/which.ts)_
540
-
541
548
  <!-- commandsstop -->
542
549
 
543
550
  </details>
package/SKILLS.md CHANGED
@@ -4,8 +4,8 @@ description: >-
4
4
  Set up and manage Zitadel authentication in a local project with the
5
5
  agent-friendly `zitadel` CLI. Use when the user wants to add login,
6
6
  registration, or session handling, create a Zitadel project, scaffold auth
7
- routes for a Next.js App Router app, or plan and apply Zitadel config changes
8
- from repo state.
7
+ for a Next.js, React, Vue, Angular, or Nuxt app, or plan and apply Zitadel
8
+ config changes from repo state.
9
9
  ---
10
10
 
11
11
  # Zitadel CLI
@@ -42,7 +42,7 @@ Each invocation prints one JSON object:
42
42
  - On failure: `code` (e.g. `E_VALIDATION`, `E_NETWORK`, `E_CONFLICT`) and
43
43
  `message`.
44
44
  - `next_commands`: the suggested follow-ups. Prefer these over free-text hints.
45
- - `E_LOCAL_SERVER_NOT_RUNNING`: start the local Docker runtime with
45
+ - `E_LOCAL_SERVER_NOT_RUNNING`: start the local runtime with
46
46
  `npx @zitadel/cli@alpha start`, then retry with `--server local`.
47
47
 
48
48
  Exit codes mirror the error class (3 = validation, 4 = network, 5 = conflict,
@@ -56,29 +56,33 @@ layer, not the envelope.
56
56
  and login flow are provisioned server-side at creation, so setup neither
57
57
  scaffolds nor uploads them. Agents must pass `--framework` when scaffolding
58
58
  into a fresh directory; interactive humans can omit it and choose from the
59
- prompt. Flags: `--framework`, `--renderer`.
59
+ prompt. Flags: `--framework next|react|vue|angular|nuxt`, `--renderer
60
+ react|web-component` (selects the Next.js auth-page renderer; accepted for any
61
+ framework and recorded in `zitadel.json` branding, but only Next varies its
62
+ generated templates by it), `--dev-port` (dev-server port, also the issuer
63
+ origin registered with Zitadel — use distinct ports to run several scaffolded
64
+ apps side by side), `--skip-install`.
60
65
  - `plan` — validate config and preview the sync diff without mutating anything.
61
66
  - `apply` — validate and upload repo config to the platform.
62
67
  - `doctor` — verify generated app files and local state once `zitadel.json`
63
- exists. Local Docker runtime prerequisites are advisory warnings unless an
64
- existing managed runtime is unhealthy; `--fix` re-applies missing managed
65
- files.
66
- - `status` — summarize the local Docker runtime and project state.
68
+ exists. The default local runtime is the `@zitadel/server` npm binary;
69
+ Docker checks apply only when using `--runtime docker` or `--image`.
70
+ `--fix` re-applies missing managed files.
71
+ - `status` — summarize the local runtime and project state.
67
72
  - `eject` (alias `uninstall`) — remove managed files and local Zitadel state;
68
73
  requires `--force` when non-interactive.
69
- - `start` — start the managed local Zitadel container and persist runtime
70
- metadata under `.zitadel/local/runtime.json`.
71
- - `stop` — stop/remove the managed container while preserving
74
+ - `start` — start the managed local Zitadel server and persist runtime metadata
75
+ under `.zitadel/local/runtime.json`. Use `--runtime docker` or `--image` for
76
+ the Docker backend.
77
+ - `stop` — stop the managed runtime while preserving
72
78
  `.zitadel/local/nextgen-data`.
73
- - `logs` — print managed container logs; `--follow` streams in human mode.
74
- - `reset` — stop/remove the managed container and delete local runtime data;
79
+ - `logs` — print managed runtime logs; `--follow` streams in human mode.
80
+ - `reset` — stop/remove the managed runtime and delete local runtime data;
75
81
  requires `--force` when non-interactive.
76
82
 
77
- Alpha releases are lockstep trains. `npx @zitadel/cli@alpha start` runs the
78
- latest tested alpha server image, and
79
- `npx @zitadel/cli@0.1.0-alpha.N start` runs
80
- `ghcr.io/zitadel/nextgen:0.1.0-alpha.N`. `zitadel start --image <ref>` remains
81
- the explicit image override for debugging.
83
+ Alpha releases are fixed product package trains. `npx @zitadel/cli@alpha start`
84
+ uses the matching `@zitadel/server` package by default. `zitadel start --runtime
85
+ docker --image <ref>` remains the explicit image override for debugging.
82
86
 
83
87
  ## Golden path
84
88
 
@@ -99,6 +103,44 @@ npx @zitadel/cli@0.1.0-alpha.N start --non-interactive --json
99
103
  npx @zitadel/cli@0.1.0-alpha.N setup --framework next --server local --non-interactive --json
100
104
  ```
101
105
 
106
+ After `setup`, follow `data.next_commands` to start the app. Prove the generated
107
+ auth flow in a visible browser by registering a unique user, logging out, logging
108
+ back in with the same email/password, and ending on the signed-in profile page.
109
+ Do not treat a rendered login or registration form as completion.
110
+
111
+ ### Driving the login UI
112
+
113
+ `<zitadel-login>` and `<zitadel-logout>` are Lit elements with open shadow
114
+ roots. The stable automation hooks live inside nested shadow roots, so a flat
115
+ `document.querySelector('[data-testid="zitadel-field-email-input"]')` will not
116
+ find them. Browser drivers with shadow-DOM-aware locators, such as Playwright,
117
+ can target the hooks directly. Generic DOM-eval drivers should pierce shadow
118
+ roots recursively:
119
+
120
+ ```js
121
+ function deepQuery(sel, root = document) {
122
+ const hit = root.querySelector(sel);
123
+ if (hit) return hit;
124
+ for (const el of root.querySelectorAll("*")) {
125
+ if (el.shadowRoot) {
126
+ const result = deepQuery(sel, el.shadowRoot);
127
+ if (result) return result;
128
+ }
129
+ }
130
+ return null;
131
+ }
132
+ ```
133
+
134
+ Use `zitadel-field-email-input`, `zitadel-field-password-input`, and
135
+ `zitadel-action-submit-button` for sign-in and registration. For sign-out, open
136
+ the user menu button if needed, then pierce to `.signout-btn`; Playwright-style
137
+ locators may use `zitadel-logout .signout-btn`. The canonical component hook
138
+ list lives in `packages/components/README.md`.
139
+
140
+ The checked-in automated regression path is `moon run workspace:journey`, which
141
+ exercises fresh-app setup plus registration, logout, and login across the
142
+ supported frameworks.
143
+
102
144
  Repo config is authoritative: edit `zitadel.json` or files under `.zitadel/`,
103
145
  then re-run `plan` and `apply`. Managed files carry a marker comment; `eject`
104
146
  removes only files that still carry it, preserving anything the user replaced.
@@ -1,6 +1,6 @@
1
- import { t as BaseCommand } from "../oclif-B3Qhw0cj.mjs";
2
- import { o as readZitadelSecret } from "../project-kWWyS7fS.mjs";
3
- import { a as makeSyncers, i as runSyncLoop, n as summarizePlan, o as environmentSchema, r as buildSyncPlan, t as renderPlan } from "../sync-CHXZqYR7.mjs";
1
+ import { t as BaseCommand } from "../oclif-VkCTGIEk.mjs";
2
+ import { o as readZitadelSecret } from "../project-CKAHtHML.mjs";
3
+ import { a as makeSyncers, i as runSyncLoop, n as summarizePlan, o as environmentSchema, r as buildSyncPlan, t as renderPlan } from "../sync-B5lqgQO3.mjs";
4
4
  import { Flags } from "@oclif/core";
5
5
  import { createZitadelClient } from "@zitadel/api/client";
6
6
  import { consola as consola$1 } from "consola";
@@ -1,7 +1,8 @@
1
- import { C as isObject, E as ZitadelError, a as DEFAULT_LOCAL_SERVER_PORT, b as publicCliCommand, c as checkLocalServerHealth, f as isPortAvailable, h as readRuntimeMetadata, l as defaultLocalServerImageForCliVersion, m as localServerUrl, s as assertLocalStateWritable, t as BaseCommand } from "../oclif-B3Qhw0cj.mjs";
2
- import { r as issuerFromPort, t as createOrca } from "../orca-BGM8VCgQ.mjs";
3
- import { a as readZitadelConfig, i as readRendererId, o as readZitadelSecret, r as readDevelopmentIssuer, t as hasZitadelConfig } from "../project-kWWyS7fS.mjs";
4
- import { o as imageAvailable, r as dockerAvailable } from "../docker-B4zvLujy.mjs";
1
+ import { D as ZitadelError, a as DEFAULT_LOCAL_SERVER_PORT, c as checkLocalServerHealth, f as isPortAvailable, h as readRuntimeMetadata, l as defaultLocalServerImageForCliVersion, m as localServerUrl, s as assertLocalStateWritable, t as BaseCommand, w as isObject, x as publicCliCommand } from "../oclif-VkCTGIEk.mjs";
2
+ import { r as issuerFromPort, t as createOrca } from "../orca-CfKDQRop.mjs";
3
+ import { a as readZitadelConfig, i as readRendererId, o as readZitadelSecret, r as readDevelopmentIssuer, t as hasZitadelConfig } from "../project-CKAHtHML.mjs";
4
+ import { d as assertServerPackageAvailable, o as imageAvailable, r as dockerAvailable } from "../docker-BA78SdC2.mjs";
5
+ import { n as dockerUnavailableMessage, t as dockerRuntimeGuidance } from "../docker-guidance-BvfpmsDj.mjs";
5
6
  import { Flags } from "@oclif/core";
6
7
  import consola from "consola";
7
8
  import { join } from "node:path";
@@ -247,6 +248,7 @@ const SANITY_CHECKS = [
247
248
  //#endregion
248
249
  //#region src/commands/doctor/index.ts
249
250
  const LOCAL_RUNTIME_CHECK_NAMES = new Set([
251
+ "server-binary",
250
252
  "docker-cli",
251
253
  "image",
252
254
  "state-dir",
@@ -274,6 +276,10 @@ var Doctor = class Doctor extends BaseCommand {
274
276
  port: Flags.integer({
275
277
  description: "Local HTTP port.",
276
278
  default: DEFAULT_LOCAL_SERVER_PORT
279
+ }),
280
+ runtime: Flags.string({
281
+ description: "Local runtime backend.",
282
+ options: ["binary", "docker"]
277
283
  })
278
284
  };
279
285
  async run() {
@@ -284,8 +290,15 @@ var Doctor = class Doctor extends BaseCommand {
284
290
  source: localServerUrl(port)
285
291
  });
286
292
  const { cwd, dryRun } = this.meta;
293
+ const existingRuntime = await readRuntimeMetadata(cwd);
294
+ const runtimeBackend = resolveRuntimeBackend({
295
+ runtime: flags.runtime,
296
+ image: flags.image,
297
+ envImage: this.meta.env.ZITADEL_LOCAL_IMAGE,
298
+ existingRuntime
299
+ });
287
300
  const image = flags.image ?? this.meta.env.ZITADEL_LOCAL_IMAGE ?? defaultLocalServerImageForCliVersion(this.meta.cliVersion);
288
- const runtimeChecks = await runLocalRuntimeChecks(cwd, image, port);
301
+ const runtimeChecks = await runLocalRuntimeChecks(cwd, runtimeBackend, image, port);
289
302
  const hasConfig = await hasZitadelConfig(cwd);
290
303
  const ctx = {
291
304
  cwd,
@@ -308,13 +321,19 @@ var Doctor = class Doctor extends BaseCommand {
308
321
  const checks = [...runtimeChecks, ...projectChecks];
309
322
  const failed = checks.filter((check) => check.status === "fail");
310
323
  const warnings = checks.filter((check) => check.status === "warn");
324
+ const warningAdvice = advisoryForWarnings(warnings, this.meta.cliVersion);
311
325
  const data = {
312
326
  title: failed.length > 0 ? "Zitadel doctor found issues." : warnings.length > 0 ? "Zitadel doctor passed with warnings." : "Zitadel doctor passed.",
313
327
  ok: failed.length === 0,
314
- image,
328
+ runtime: runtimeBackend,
329
+ ...runtimeBackend === "docker" ? { image } : {},
315
330
  port,
316
331
  project: { lifecycle: hasConfig ? "configured" : "not-configured" },
317
- checks
332
+ checks,
333
+ ...warningAdvice ? {
334
+ next_actions: warningAdvice.nextActions,
335
+ next_commands: warningAdvice.nextCommands
336
+ } : {}
318
337
  };
319
338
  if (failed.length > 0) {
320
339
  const advice = failureAdvice(failed, image, port, this.meta.cliVersion);
@@ -333,10 +352,17 @@ var Doctor = class Doctor extends BaseCommand {
333
352
  };
334
353
  function failureAdvice(failed, image, port, cliVersion) {
335
354
  const failedNames = new Set(failed.map((check) => check.name));
336
- if (failedNames.has("docker-cli")) return {
337
- hint: "Docker is required for `zitadel start`, but the Docker daemon is not reachable. Install or start Docker, then rerun `zitadel doctor`.",
338
- nextCommands: ["docker version", publicCliCommand("doctor", cliVersion)]
355
+ if (failedNames.has("server-binary")) return {
356
+ hint: "The Zitadel server npm package is not available. Reinstall the CLI package, then retry.",
357
+ nextCommands: [publicCliCommand("doctor", cliVersion)]
339
358
  };
359
+ if (failedNames.has("docker-cli")) {
360
+ const advice = dockerRuntimeGuidance("doctor", cliVersion);
361
+ return {
362
+ hint: advice.hint,
363
+ nextCommands: advice.nextCommands
364
+ };
365
+ }
340
366
  if (failedNames.has("image")) return {
341
367
  hint: "The local Zitadel image is not available. Check Docker registry access, build it locally, or pass --image / ZITADEL_LOCAL_IMAGE.",
342
368
  nextCommands: [`docker pull ${image}`, publicCliCommand("doctor", cliVersion)]
@@ -365,8 +391,31 @@ function failureAdvice(failed, image, port, cliVersion) {
365
391
  nextCommands: [publicCliCommand("doctor", cliVersion)]
366
392
  };
367
393
  }
368
- async function runLocalRuntimeChecks(cwd, image, port) {
394
+ function advisoryForWarnings(warnings, cliVersion) {
395
+ if (!warnings.some((check) => check.name === "docker-cli")) return;
396
+ const advice = dockerRuntimeGuidance("doctor", cliVersion);
397
+ return {
398
+ nextActions: advice.nextActions,
399
+ nextCommands: advice.nextCommands
400
+ };
401
+ }
402
+ async function runLocalRuntimeChecks(cwd, runtimeBackend, image, port) {
369
403
  const runtime = await readRuntimeMetadata(cwd);
404
+ if (runtimeBackend === "binary") return [
405
+ await check("server-binary", "Server npm package is available", async () => {
406
+ return `@zitadel/server ${await assertServerPackageAvailable()} is available`;
407
+ }),
408
+ await check("state-dir", "Local state directory is writable", async () => {
409
+ const probe = await assertLocalStateWritable(cwd);
410
+ return probe.checkedPath === probe.targetPath ? `${probe.targetPath} is writable` : `${probe.targetPath} can be created (${probe.checkedPath} is writable)`;
411
+ }, "warn"),
412
+ await check("port", `Port ${String(port)} is available`, async () => {
413
+ if (runtime && await checkLocalServerHealth(runtime.server_url)) return `${runtime.server_url} is already healthy`;
414
+ if (!await isPortAvailable(port)) throw new Error(`Port ${String(port)} is already in use`);
415
+ return `Port ${String(port)} is available`;
416
+ }, "warn"),
417
+ await checkRuntime(runtime, runtimeBackend)
418
+ ];
370
419
  const docker = await check("docker-cli", "Docker is reachable", async () => {
371
420
  let result;
372
421
  try {
@@ -399,13 +448,23 @@ async function runLocalRuntimeChecks(cwd, image, port) {
399
448
  if (!await isPortAvailable(port)) throw new Error(`Port ${String(port)} is already in use`);
400
449
  return `Port ${String(port)} is available`;
401
450
  }, "warn"),
402
- await check("runtime", "Existing local runtime is healthy", async () => {
403
- if (!runtime) return "No existing runtime metadata";
404
- if (!await checkLocalServerHealth(runtime.server_url)) throw new Error(`${runtime.server_url} did not respond to /healthz`);
405
- return `${runtime.server_url} is healthy`;
406
- })
451
+ await checkRuntime(runtime, runtimeBackend)
407
452
  ];
408
453
  }
454
+ async function checkRuntime(runtime, runtimeBackend) {
455
+ return check("runtime", "Existing local runtime is healthy", async () => {
456
+ if (!runtime) return "No existing runtime metadata";
457
+ if (runtime.backend !== runtimeBackend) throw new Error(`Existing local runtime uses ${runtime.backend}; run start --runtime ${runtimeBackend} to switch backends.`);
458
+ if (!await checkLocalServerHealth(runtime.server_url)) throw new Error(`${runtime.server_url} did not respond to /healthz`);
459
+ return `${runtime.server_url} is healthy`;
460
+ });
461
+ }
462
+ function resolveRuntimeBackend(input) {
463
+ if (input.runtime === "binary" || input.runtime === "docker") return input.runtime;
464
+ if (input.existingRuntime) return input.existingRuntime.backend;
465
+ if (input.image || input.envImage) return "docker";
466
+ return "binary";
467
+ }
409
468
  async function check(name, fallback, run, failureStatus = "fail") {
410
469
  try {
411
470
  return {
@@ -421,10 +480,6 @@ async function check(name, fallback, run, failureStatus = "fail") {
421
480
  };
422
481
  }
423
482
  }
424
- function dockerUnavailableMessage(error) {
425
- const detail = error instanceof Error ? error.message : String(error);
426
- return `Docker is not reachable${detail.trim() ? ` (${detail.trim()})` : ""}; \`zitadel start\` needs Docker, but cloud setup can continue.`;
427
- }
428
483
  function imageUnavailableMessage(image, error) {
429
484
  const detail = error instanceof Error ? error.message : String(error);
430
485
  return `Image ${image} is not available to Docker${detail.trim() ? ` (${detail.trim()})` : ""}; \`zitadel start\` may need a pull or a different image.`;