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

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 (34) hide show
  1. package/README.md +75 -11
  2. package/SKILLS.md +11 -4
  3. package/dist/commands/apply.mjs +3 -4
  4. package/dist/commands/apply.mjs.map +1 -1
  5. package/dist/commands/doctor.mjs +6 -7
  6. package/dist/commands/doctor.mjs.map +1 -1
  7. package/dist/commands/eject.mjs +3 -3
  8. package/dist/commands/logs.mjs +3 -3
  9. package/dist/commands/logs.mjs.map +1 -1
  10. package/dist/commands/plan.mjs +3 -4
  11. package/dist/commands/plan.mjs.map +1 -1
  12. package/dist/commands/reset.mjs +3 -3
  13. package/dist/commands/reset.mjs.map +1 -1
  14. package/dist/commands/setup.mjs +23 -6
  15. package/dist/commands/setup.mjs.map +1 -1
  16. package/dist/commands/start.mjs +2 -2
  17. package/dist/commands/status.mjs +6 -7
  18. package/dist/commands/status.mjs.map +1 -1
  19. package/dist/commands/stop.mjs +3 -3
  20. package/dist/commands/stop.mjs.map +1 -1
  21. package/dist/{docker-DrOBycgG.mjs → docker-B4zvLujy.mjs} +2 -2
  22. package/dist/{docker-DrOBycgG.mjs.map → docker-B4zvLujy.mjs.map} +1 -1
  23. package/dist/{oclif-CqkWBQ7i.mjs → oclif-B3Qhw0cj.mjs} +24 -10
  24. package/dist/oclif-B3Qhw0cj.mjs.map +1 -0
  25. package/dist/{orca-S1tVnngd.mjs → orca-BGM8VCgQ.mjs} +139 -33
  26. package/dist/orca-BGM8VCgQ.mjs.map +1 -0
  27. package/dist/{project-B6YfSaZw.mjs → project-kWWyS7fS.mjs} +2 -2
  28. package/dist/{project-B6YfSaZw.mjs.map → project-kWWyS7fS.mjs.map} +1 -1
  29. package/dist/{sync-DN4oNLVH.mjs → sync-CHXZqYR7.mjs} +2 -2
  30. package/dist/{sync-DN4oNLVH.mjs.map → sync-CHXZqYR7.mjs.map} +1 -1
  31. package/oclif.manifest.json +1 -3
  32. package/package.json +4 -4
  33. package/dist/oclif-CqkWBQ7i.mjs.map +0 -1
  34. package/dist/orca-S1tVnngd.mjs.map +0 -1
package/README.md CHANGED
@@ -4,25 +4,29 @@ Scaffolds Zitadel auth (login, register, profile, middleware) into a Next.js app
4
4
 
5
5
  ```sh
6
6
  npx @zitadel/cli@alpha start
7
- npx @zitadel/cli@alpha setup --framework next --server local
7
+ npx @zitadel/cli@alpha setup --server local
8
8
  ```
9
9
 
10
+ During the public alpha, bare `npx @zitadel/cli` resolves to the same tested
11
+ alpha CLI. Use `@alpha` or an exact `0.1.0-alpha.N` selector in bug reports and
12
+ automation when reproducibility matters.
13
+
10
14
  > **Beta.** This is the **next-generation Zitadel**, a ground-up rewrite of the platform. It is distinct from the established Zitadel at [github.com/zitadel/zitadel](https://github.com/zitadel/zitadel). APIs and CLI flags will change.
11
15
 
12
16
  ## Requirements
13
17
 
14
18
  - Node 20+
15
19
  - Docker for the managed local Zitadel runtime
16
- - A Next.js project created with `create-next-app`
20
+ - A Next.js project, or an empty directory where setup can scaffold one
17
21
 
18
22
  ## Quickstart
19
23
 
20
24
  ```sh
21
- npx create-next-app@latest my-app
25
+ mkdir my-app
22
26
  cd my-app
23
27
  npx @zitadel/cli@alpha doctor
24
28
  npx @zitadel/cli@alpha start
25
- npx @zitadel/cli@alpha setup --framework next --server local
29
+ npx @zitadel/cli@alpha setup --server local
26
30
  npm run dev
27
31
  ```
28
32
 
@@ -31,12 +35,14 @@ under `.zitadel/local/`. Alpha CLI versions use the matching
31
35
  `ghcr.io/zitadel/nextgen:<cli-version>` image by default; local/dev builds fall
32
36
  back to `ghcr.io/zitadel/nextgen:latest`. Override with `--image` or
33
37
  `ZITADEL_LOCAL_IMAGE` for advanced debugging.
34
- `setup --server local` creates a project on that local server, scaffolds
35
- `app/login`, `app/register`, and `middleware.ts`, writes `.env.local` and
36
- `.zitadel/`, and installs dependencies with the detected package manager. Pass
37
- `--skip-install` to install them yourself. The project's default user schema
38
- and login flow are provisioned server-side at creation time, so the CLI does
39
- not scaffold or upload them. Open `http://localhost:3000/login` to see the
38
+ `setup --server local` creates a project on that local server, asks which
39
+ 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
40
46
  login page.
41
47
 
42
48
  For a reproducible tester report, use the exact alpha train from the GitHub
@@ -45,7 +51,7 @@ Release:
45
51
  ```sh
46
52
  npx @zitadel/cli@0.1.0-alpha.N doctor
47
53
  npx @zitadel/cli@0.1.0-alpha.N start
48
- npx @zitadel/cli@0.1.0-alpha.N setup --framework next --server local
54
+ npx @zitadel/cli@0.1.0-alpha.N setup --server local
49
55
  ```
50
56
 
51
57
  The default project flow supports password registration/login, passkey
@@ -57,6 +63,8 @@ passkey can sign in with either credential.
57
63
 
58
64
  - `zitadel doctor` — verify the local Docker runtime and generated project files
59
65
  - `zitadel status` — summarise the local Docker runtime and project
66
+ - `zitadel plan` — validate config and preview sync changes without mutation
67
+ - `zitadel apply` — validate and upload repo config to Zitadel
60
68
  - `zitadel eject` — remove what setup wrote (alias: `zitadel uninstall`)
61
69
  - `zitadel start|stop|logs|reset` — manage the local Docker runtime
62
70
 
@@ -67,12 +75,14 @@ passkey can sign in with either credential.
67
75
 
68
76
  <!-- commands -->
69
77
 
78
+ - [`zitadel apply`](#zitadel-apply)
70
79
  - [`zitadel autocomplete [SHELL]`](#zitadel-autocomplete-shell)
71
80
  - [`zitadel commands`](#zitadel-commands)
72
81
  - [`zitadel doctor`](#zitadel-doctor)
73
82
  - [`zitadel eject`](#zitadel-eject)
74
83
  - [`zitadel help [COMMAND]`](#zitadel-help-command)
75
84
  - [`zitadel logs`](#zitadel-logs)
85
+ - [`zitadel plan`](#zitadel-plan)
76
86
  - [`zitadel reset`](#zitadel-reset)
77
87
  - [`zitadel search`](#zitadel-search)
78
88
  - [`zitadel setup`](#zitadel-setup)
@@ -83,6 +93,33 @@ passkey can sign in with either credential.
83
93
  - [`zitadel version`](#zitadel-version)
84
94
  - [`zitadel which`](#zitadel-which)
85
95
 
96
+ ## `zitadel apply`
97
+
98
+ Validate and upload repo config to the platform.
99
+
100
+ ```
101
+ USAGE
102
+ $ zitadel apply [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
103
+ [-e development|preview|production]
104
+
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.
115
+
116
+ GLOBAL FLAGS
117
+ --json Format output as json.
118
+
119
+ DESCRIPTION
120
+ Validate and upload repo config to the platform.
121
+ ```
122
+
86
123
  ## `zitadel autocomplete [SHELL]`
87
124
 
88
125
  Display autocomplete installation instructions.
@@ -245,6 +282,33 @@ DESCRIPTION
245
282
  Show local Zitadel server logs.
246
283
  ```
247
284
 
285
+ ## `zitadel plan`
286
+
287
+ Validate config without mutation and preview the sync diff.
288
+
289
+ ```
290
+ USAGE
291
+ $ zitadel plan [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
292
+ [-e development|preview|production]
293
+
294
+ 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.
304
+
305
+ GLOBAL FLAGS
306
+ --json Format output as json.
307
+
308
+ DESCRIPTION
309
+ Validate config without mutation and preview the sync diff.
310
+ ```
311
+
248
312
  ## `zitadel reset`
249
313
 
250
314
  Delete the local Zitadel server runtime and data.
package/SKILLS.md CHANGED
@@ -27,6 +27,10 @@ parse the result rather than scraping human output.
27
27
  npx @zitadel/cli@alpha <command> --non-interactive --json
28
28
  ```
29
29
 
30
+ During the public alpha, bare `npx @zitadel/cli` is promoted to the same tested
31
+ alpha CLI so discovery works for first-time users. Prefer `@alpha` or an exact
32
+ `0.1.0-alpha.N` selector in agent scripts and bug reports for reproducibility.
33
+
30
34
  ## Reading the envelope
31
35
 
32
36
  Each invocation prints one JSON object:
@@ -50,7 +54,9 @@ layer, not the envelope.
50
54
  - `setup` — create a Zitadel project and scaffold local auth (routes,
51
55
  middleware, `.zitadel/**`, env templates). The project's default user schema
52
56
  and login flow are provisioned server-side at creation, so setup neither
53
- scaffolds nor uploads them. Flags: `--framework`, `--renderer`.
57
+ scaffolds nor uploads them. Agents must pass `--framework` when scaffolding
58
+ into a fresh directory; interactive humans can omit it and choose from the
59
+ prompt. Flags: `--framework`, `--renderer`.
54
60
  - `plan` — validate config and preview the sync diff without mutating anything.
55
61
  - `apply` — validate and upload repo config to the platform.
56
62
  - `doctor` — verify generated app files and local state once `zitadel.json`
@@ -98,6 +104,7 @@ then re-run `plan` and `apply`. Managed files carry a marker comment; `eject`
98
104
  removes only files that still carry it, preserving anything the user replaced.
99
105
  For app-local development, `--server local` resolves through
100
106
  `.zitadel/local/runtime.json` and requires a healthy `npx @zitadel/cli@alpha start`
101
- runtime. `setup` installs dependencies with the detected package manager by
102
- default; pass `--skip-install` when the agent or host workflow will install
103
- dependencies separately.
107
+ runtime. Runtime-only `.zitadel/local/**` state does not block fresh
108
+ same-directory scaffolding. `setup` installs dependencies with the detected
109
+ package manager by default; pass `--skip-install` when the agent or host
110
+ workflow will install dependencies separately.
@@ -1,6 +1,6 @@
1
- import { t as BaseCommand } from "../oclif-CqkWBQ7i.mjs";
2
- import { o as readZitadelSecret } from "../project-B6YfSaZw.mjs";
3
- import { a as makeSyncers, i as runSyncLoop, n as summarizePlan, o as environmentSchema, r as buildSyncPlan, t as renderPlan } from "../sync-DN4oNLVH.mjs";
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";
4
4
  import { Flags } from "@oclif/core";
5
5
  import { createZitadelClient } from "@zitadel/api/client";
6
6
  import { consola as consola$1 } from "consola";
@@ -16,7 +16,6 @@ import { consola as consola$1 } from "consola";
16
16
  */
17
17
  var Apply = class Apply extends BaseCommand {
18
18
  static description = "Validate and upload repo config to the platform.";
19
- static hidden = true;
20
19
  static flags = { environment: Flags.string({
21
20
  char: "e",
22
21
  description: "Target environment (default: development).",
@@ -1 +1 @@
1
- {"version":3,"file":"apply.mjs","names":[],"sources":["../../src/commands/apply.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"@zitadel/api/client\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { environmentSchema } from \"../lib/environment\";\nimport { buildSyncPlan, makeSyncers, renderPlan, runSyncLoop, summarizePlan } from \"../lib/sync\";\nimport { readZitadelSecret } from \"../lib/project\";\n\n/**\n * `zitadel apply` — validate and upload repo config to the platform.\n *\n * Runs the sync loop to convergence, or (with `--dry-run`) previews the diff\n * without mutating. All validation — structural shape and `${VAR}` / `*_env`\n * reference presence — happens inside the sync engine ({@link buildSyncPlan}),\n * so an invalid or under-configured file fails with `E_VALIDATION` before any\n * platform call.\n */\nexport default class Apply extends BaseCommand {\n static override description = \"Validate and upload repo config to the platform.\";\n // Temporarily hidden while we collapse the dev workflow around `setup`'s\n // auto-apply. The logic stays wired up so re-exposing this command is a\n // one-line flip when we settle on the surface area.\n static override hidden = true;\n static override flags = {\n environment: Flags.string({\n char: \"e\",\n description: \"Target environment (default: development).\",\n options: [...environmentSchema.options],\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Apply);\n await this.toMeta(flags);\n const { cwd, source, env, dryRun, isTTY } = this.meta;\n\n const secret = await readZitadelSecret(cwd);\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n const client = createZitadelClient({\n baseUrl: source,\n token: secret.project_secret,\n });\n const syncers = makeSyncers({ client, projectId: secret.project_id, env });\n\n if (!dryRun) {\n consola.start(\"Syncing schemas and flows to Zitadel\");\n await runSyncLoop(cwd, syncers);\n consola.success(\"Sync complete\");\n return this.emit({ status: \"ok\", data: { synced: true } });\n }\n\n consola.start(\"Building plan (dry run)\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}`,\n );\n return this.emit({\n status: \"ok\",\n data: summary,\n pretty: renderPlan(plan, isTTY),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,IAAqB,QAArB,MAAqB,cAAc,YAAY;CAC7C,OAAgB,cAAc;CAI9B,OAAgB,SAAS;CACzB,OAAgB,QAAQ,EACtB,aAAa,MAAM,OAAO;EACxB,MAAM;EACN,aAAa;EACb,SAAS,CAAC,GAAG,kBAAkB,QAAQ;EACxC,CAAC,EACH;CAED,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,MAAM;AACzC,QAAM,KAAK,OAAO,MAAM;EACxB,MAAM,EAAE,KAAK,QAAQ,KAAK,QAAQ,UAAU,KAAK;EAEjD,MAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,YAAQ,KAAK,aAAa,OAAO,aAAa;AAC9C,YAAQ,KAAK,aAAa,SAAS;EAKnC,MAAM,UAAU,YAAY;GAAE,QAJf,oBAAoB;IACjC,SAAS;IACT,OAAO,OAAO;IACf,CACmC;GAAE,WAAW,OAAO;GAAY;GAAK,CAAC;AAE1E,MAAI,CAAC,QAAQ;AACX,aAAQ,MAAM,uCAAuC;AACrD,SAAM,YAAY,KAAK,QAAQ;AAC/B,aAAQ,QAAQ,gBAAgB;AAChC,UAAO,KAAK,KAAK;IAAE,QAAQ;IAAM,MAAM,EAAE,QAAQ,MAAM;IAAE,CAAC;;AAG5D,YAAQ,MAAM,0BAA0B;EACxC,MAAM,OAAO,MAAM,cAAc,KAAK,SAAS,KAAK;EACpD,MAAM,UAAU,cAAc,KAAK;AACnC,YAAQ,QACN,SAAS,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC9D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,MAC5D;AACD,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;GACN,QAAQ,WAAW,MAAM,MAAM;GAChC,CAAC"}
1
+ {"version":3,"file":"apply.mjs","names":[],"sources":["../../src/commands/apply.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"@zitadel/api/client\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { environmentSchema } from \"../lib/environment\";\nimport { buildSyncPlan, makeSyncers, renderPlan, runSyncLoop, summarizePlan } from \"../lib/sync\";\nimport { readZitadelSecret } from \"../lib/project\";\n\n/**\n * `zitadel apply` — validate and upload repo config to the platform.\n *\n * Runs the sync loop to convergence, or (with `--dry-run`) previews the diff\n * without mutating. All validation — structural shape and `${VAR}` / `*_env`\n * reference presence — happens inside the sync engine ({@link buildSyncPlan}),\n * so an invalid or under-configured file fails with `E_VALIDATION` before any\n * platform call.\n */\nexport default class Apply extends BaseCommand {\n static override description = \"Validate and upload repo config to the platform.\";\n static override flags = {\n environment: Flags.string({\n char: \"e\",\n description: \"Target environment (default: development).\",\n options: [...environmentSchema.options],\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Apply);\n await this.toMeta(flags);\n const { cwd, source, env, dryRun, isTTY } = this.meta;\n\n const secret = await readZitadelSecret(cwd);\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n const client = createZitadelClient({\n baseUrl: source,\n token: secret.project_secret,\n });\n const syncers = makeSyncers({ client, projectId: secret.project_id, env });\n\n if (!dryRun) {\n consola.start(\"Syncing schemas and flows to Zitadel\");\n await runSyncLoop(cwd, syncers);\n consola.success(\"Sync complete\");\n return this.emit({ status: \"ok\", data: { synced: true } });\n }\n\n consola.start(\"Building plan (dry run)\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}`,\n );\n return this.emit({\n status: \"ok\",\n data: summary,\n pretty: renderPlan(plan, isTTY),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,IAAqB,QAArB,MAAqB,cAAc,YAAY;CAC7C,OAAgB,cAAc;CAC9B,OAAgB,QAAQ,EACtB,aAAa,MAAM,OAAO;EACxB,MAAM;EACN,aAAa;EACb,SAAS,CAAC,GAAG,kBAAkB,QAAQ;EACxC,CAAC,EACH;CAED,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,MAAM;AACzC,QAAM,KAAK,OAAO,MAAM;EACxB,MAAM,EAAE,KAAK,QAAQ,KAAK,QAAQ,UAAU,KAAK;EAEjD,MAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,YAAQ,KAAK,aAAa,OAAO,aAAa;AAC9C,YAAQ,KAAK,aAAa,SAAS;EAKnC,MAAM,UAAU,YAAY;GAAE,QAJf,oBAAoB;IACjC,SAAS;IACT,OAAO,OAAO;IACf,CACmC;GAAE,WAAW,OAAO;GAAY;GAAK,CAAC;AAE1E,MAAI,CAAC,QAAQ;AACX,aAAQ,MAAM,uCAAuC;AACrD,SAAM,YAAY,KAAK,QAAQ;AAC/B,aAAQ,QAAQ,gBAAgB;AAChC,UAAO,KAAK,KAAK;IAAE,QAAQ;IAAM,MAAM,EAAE,QAAQ,MAAM;IAAE,CAAC;;AAG5D,YAAQ,MAAM,0BAA0B;EACxC,MAAM,OAAO,MAAM,cAAc,KAAK,SAAS,KAAK;EACpD,MAAM,UAAU,cAAc,KAAK;AACnC,YAAQ,QACN,SAAS,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC9D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,MAC5D;AACD,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;GACN,QAAQ,WAAW,MAAM,MAAM;GAChC,CAAC"}
@@ -1,7 +1,7 @@
1
- import { C as isObject, E as ZitadelError, a as DEFAULT_LOCAL_SERVER_PORT, c as checkLocalServerHealth, f as isPortAvailable, g as readRuntimeMetadata, h as localServerUrl, l as defaultLocalServerImageForCliVersion, m as localRuntimePaths, s as assertWritableDirectory, t as BaseCommand, x as publicCliCommand } from "../oclif-CqkWBQ7i.mjs";
2
- import { r as issuerFromPort, t as createOrca } from "../orca-S1tVnngd.mjs";
3
- import { a as readZitadelConfig, i as readRendererId, o as readZitadelSecret, r as readDevelopmentIssuer, t as hasZitadelConfig } from "../project-B6YfSaZw.mjs";
4
- import { o as imageAvailable, r as dockerAvailable } from "../docker-DrOBycgG.mjs";
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";
5
5
  import { Flags } from "@oclif/core";
6
6
  import consola from "consola";
7
7
  import { join } from "node:path";
@@ -391,9 +391,8 @@ async function runLocalRuntimeChecks(cwd, image, port) {
391
391
  message: "Skipped image check because Docker is not reachable."
392
392
  },
393
393
  await check("state-dir", "Local state directory is writable", async () => {
394
- const paths = localRuntimePaths(cwd);
395
- await assertWritableDirectory(paths.dataDir);
396
- return `${paths.dataDir} is writable`;
394
+ const probe = await assertLocalStateWritable(cwd);
395
+ return probe.checkedPath === probe.targetPath ? `${probe.targetPath} is writable` : `${probe.targetPath} can be created (${probe.checkedPath} is writable)`;
397
396
  }, "warn"),
398
397
  await check("port", `Port ${String(port)} is available`, async () => {
399
398
  if (runtime && await checkLocalServerHealth(runtime.server_url)) return `${runtime.server_url} is already healthy`;
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.mjs","names":[],"sources":["../../src/commands/doctor/checks/types.ts","../../src/commands/doctor/checks/config.ts","../../src/commands/doctor/checks/secret.ts","../../src/commands/doctor/checks/secret-permissions.ts","../../src/commands/doctor/checks/gitignore.ts","../../src/commands/doctor/checks/env-example.ts","../../src/commands/doctor/checks/framework.ts","../../src/commands/doctor/patch-context.ts","../../src/commands/doctor/checks/dependency.ts","../../src/commands/doctor/checks/project-match.ts","../../src/commands/doctor/checks/index.ts","../../src/commands/doctor/index.ts"],"sourcesContent":["import type { Orca } from \"../../../lib/orca\";\n\n/** Pass/fail/advisory outcome of a single {@link SanityCheck}. */\nexport type CheckOutcome = {\n name: string;\n status: \"pass\" | \"warn\" | \"fail\";\n message: string;\n path?: string;\n};\n\n/** Everything a check needs to inspect or repair a project. */\nexport type CheckContext = {\n readonly cwd: string;\n readonly orca: Orca;\n readonly cliVersion: string;\n /** When true, {@link SanityCheck.fix} must preview without writing. */\n readonly dryRun: boolean;\n};\n\n/**\n * One diagnostic the `doctor` command runs. Each concrete check is a small\n * standalone class that both verifies its concern ({@link run}) and knows how\n * to repair it ({@link fix}); the command executes every registered check,\n * aggregates the {@link CheckOutcome}s, and (under `--fix`) repairs the ones\n * that failed.\n */\nexport interface SanityCheck {\n /** Stable identifier surfaced in logs and the JSON envelope. */\n readonly name: string;\n run(ctx: CheckContext): Promise<CheckOutcome>;\n /** Repair what this check verifies. A no-op when there is no safe auto-fix. */\n fix(ctx: CheckContext): Promise<void>;\n}\n\n/**\n * Base class for checks: subclasses declare `name`, `path`, and a success\n * `summary`, and implement the single {@link verify} method that throws on\n * failure. {@link run} wraps it so a thrown error becomes a `fail` outcome\n * carrying the error message, and success becomes a `pass` with `summary`.\n *\n * {@link fix} defaults to a no-op: checks whose failure has no safe automatic\n * remedy (a missing secret, an invalid user schema) simply do not override it.\n */\nexport abstract class AbstractSanityCheck implements SanityCheck {\n abstract readonly name: string;\n abstract readonly path: string;\n protected abstract readonly summary: string;\n\n /** Throw to signal failure; the thrown message is surfaced to the user. */\n protected abstract verify(ctx: CheckContext): Promise<void>;\n\n async run(ctx: CheckContext): Promise<CheckOutcome> {\n try {\n await this.verify(ctx);\n return { name: this.name, status: \"pass\", message: this.summary, path: this.path };\n } catch (error) {\n return {\n name: this.name,\n status: \"fail\",\n message: error instanceof Error ? error.message : String(error),\n path: this.path,\n };\n }\n }\n\n async fix(_ctx: CheckContext): Promise<void> {\n return;\n }\n}\n","import { readZitadelConfig } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `zitadel.json` exists and parses. */\nexport class ConfigCheck extends AbstractSanityCheck {\n readonly name = \"config\";\n readonly path = \"zitadel.json\";\n protected readonly summary = \"zitadel.json parses\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n await readZitadelConfig(ctx.cwd);\n }\n}\n","import { readZitadelSecret } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `.zitadel/secret` exists and parses. */\nexport class SecretCheck extends AbstractSanityCheck {\n readonly name = \"secret\";\n readonly path = \".zitadel/secret\";\n protected readonly summary = \".zitadel/secret parses\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n await readZitadelSecret(ctx.cwd);\n }\n}\n","import { chmod, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `.zitadel/secret` is locked down to `0600`, and re-locks it on fix. */\nexport class SecretPermissionsCheck extends AbstractSanityCheck {\n readonly name = \"secret-permissions\";\n readonly path = \".zitadel/secret\";\n protected readonly summary = \".zitadel/secret has 0600 permissions\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const mode = (await stat(join(ctx.cwd, \".zitadel/secret\"))).mode & 0o777;\n if (mode !== 0o600) {\n throw new Error(`expected 0600, got ${mode.toString(8)}`);\n }\n }\n\n override async fix(ctx: CheckContext): Promise<void> {\n if (ctx.dryRun) {\n return;\n }\n await chmod(join(ctx.cwd, \".zitadel/secret\"), 0o600);\n }\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** The entries `.gitignore` must carry to keep secrets and env files untracked. */\nconst REQUIRED_ENTRIES = [\".zitadel/secret\", \".env*\", \"!.env.example\"];\n\n/** Verifies `.gitignore` excludes the local secret and env files; appends any missing. */\nexport class GitignoreCheck extends AbstractSanityCheck {\n readonly name = \"gitignore\";\n readonly path = \".gitignore\";\n protected readonly summary = \".gitignore protects local secret/env files\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const lines = (await readFile(join(ctx.cwd, \".gitignore\"), \"utf8\")).split(/\\r?\\n/g);\n for (const entry of REQUIRED_ENTRIES) {\n if (!lines.includes(entry)) {\n throw new Error(`missing ${entry}`);\n }\n }\n }\n\n override async fix(ctx: CheckContext): Promise<void> {\n const path = join(ctx.cwd, \".gitignore\");\n const existing = await readFile(path, \"utf8\").catch(() => \"\");\n const lines = existing.split(/\\r?\\n/g);\n const missing = REQUIRED_ENTRIES.filter((entry) => !lines.includes(entry));\n if (missing.length === 0 || ctx.dryRun) {\n return;\n }\n const prefix = existing.length > 0 && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\";\n await writeFile(path, `${existing}${prefix}${missing.join(\"\\n\")}\\n`);\n }\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** The keys `.env.example` must document for a Zitadel-managed project. */\nconst REQUIRED_KEYS = [\"ZITADEL_PROJECT_ID\", \"ZITADEL_ENVIRONMENT\", \"ZITADEL_ISSUER\"];\n\n/** Verifies `.env.example` documents the required Zitadel keys; appends any missing. */\nexport class EnvExampleCheck extends AbstractSanityCheck {\n readonly name = \"env-example\";\n readonly path = \".env.example\";\n protected readonly summary = \".env.example references required keys\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const contents = await readFile(join(ctx.cwd, \".env.example\"), \"utf8\");\n for (const key of REQUIRED_KEYS) {\n if (!contents.includes(`${key}=`)) {\n throw new Error(`missing ${key}`);\n }\n }\n }\n\n override async fix(ctx: CheckContext): Promise<void> {\n const path = join(ctx.cwd, \".env.example\");\n const existing = await readFile(path, \"utf8\").catch(() => \"\");\n const missing = REQUIRED_KEYS.filter((key) => !existing.includes(`${key}=`));\n if (missing.length === 0 || ctx.dryRun) {\n return;\n }\n const prefix = existing.length > 0 && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\";\n await writeFile(path, `${existing}${prefix}${missing.map((key) => `${key}=`).join(\"\\n\")}\\n`);\n }\n}\n","import { isObject } from \"../../../lib/json\";\nimport { readZitadelConfig } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies the framework detected on disk matches the one recorded in config. */\nexport class FrameworkCheck extends AbstractSanityCheck {\n readonly name = \"framework\";\n readonly path = \"zitadel.json\";\n protected readonly summary = \"Detected framework matches recorded framework\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const config = await readZitadelConfig(ctx.cwd);\n const detected = await ctx.orca.detect(ctx.cwd);\n const recorded = isObject(config.framework) ? config.framework.id : undefined;\n if (recorded !== detected.id) {\n throw new Error(`expected ${String(recorded)}, detected ${detected.id}`);\n }\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { issuerFromPort, type FrameworkFacts, type Orca } from \"../../lib/orca\";\nimport type { PatchContext } from \"../../lib/orca/patchers/types\";\nimport { readDevelopmentIssuer, readRendererId, readZitadelConfig, readZitadelSecret } from \"../../lib/project\";\n\n/**\n * Reconstructs a {@link PatchContext} from the on-disk project (config, secret)\n * plus fresh framework detection, so a patcher repair can rebuild its plan.\n * Used by the dependency check's `fix`, which reclaims the framework-specific\n * SDK package via `patcher.repair`. The user schema and flow definition are\n * server-owned and no longer scaffolded locally, so nothing here reads them.\n */\nexport async function loadPatchContext(\n cwd: string,\n orca: Orca,\n cliVersion: string,\n): Promise<PatchContext> {\n const config = await readZitadelConfig(cwd);\n const secret = await readZitadelSecret(cwd);\n const framework = await orca.detect(cwd);\n return {\n framework,\n rendererId: readRendererId(config),\n issuer: await resolveIssuer(cwd, config, framework),\n server: typeof config.server === \"string\" ? config.server : \"\",\n cliVersion,\n project: {\n id: secret.project_id,\n projectSecret: secret.project_secret,\n previewSecret: secret.preview_secret,\n previewOrigins: secret.preview_origins,\n createdAt: secret.created_at,\n },\n };\n}\n\nasync function resolveIssuer(\n cwd: string,\n config: Record<string, unknown>,\n facts: FrameworkFacts,\n): Promise<string> {\n const fromConfig = readDevelopmentIssuer(config);\n if (fromConfig && fromConfig.length > 0) {\n return fromConfig;\n }\n const state = await readState(cwd);\n if (typeof state?.dev_port === \"number\") {\n return issuerFromPort(state.dev_port);\n }\n return facts.url;\n}\n\nasync function readState(cwd: string): Promise<{ dev_port?: number } | undefined> {\n try {\n const contents = await readFile(join(cwd, \".zitadel/state.json\"), \"utf8\");\n return JSON.parse(contents) as { dev_port?: number };\n } catch {\n return undefined;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { loadPatchContext } from \"../patch-context\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/**\n * Verifies the project still declares a Zitadel SDK dependency in\n * `package.json`. The patcher adds a scoped package (e.g.\n * `@zitadel/sdk-next`); the check is generic over the `@zitadel*`\n * scope so any framework renderer's dependency satisfies it.\n */\nexport class DependencyCheck extends AbstractSanityCheck {\n readonly name = \"dependency\";\n readonly path = \"package.json\";\n protected readonly summary = \"package.json depends on a Zitadel SDK package\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const pkg = JSON.parse(await readFile(join(ctx.cwd, \"package.json\"), \"utf8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const names = [\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ];\n if (!names.some((name) => name.startsWith(\"@zitadel\"))) {\n throw new Error(\"no @zitadel* dependency found in package.json\");\n }\n }\n\n /**\n * Repairs by reclaiming the patcher's managed artifacts: rebuilds the\n * `PatchContext` from disk and calls `patcher.repair`, which re-adds the\n * SDK dependency via its `add-dep` op. The exact package name is framework\n * + renderer specific and known only to the patcher (which deliberately\n * hides its file-op plan behind the family-neutral `Patcher` interface),\n * so going through `repair` is the only sanctioned path.\n */\n override async fix(ctx: CheckContext): Promise<void> {\n const patchCtx = await loadPatchContext(ctx.cwd, ctx.orca, ctx.cliVersion);\n await ctx.orca.patcherFor(patchCtx.framework.id).repair(patchCtx, {\n cwd: ctx.cwd,\n dryRun: ctx.dryRun,\n force: true,\n });\n }\n}\n","import { readZitadelConfig, readZitadelSecret } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `.zitadel/secret`'s project_id matches `zitadel.json`'s project. */\nexport class ProjectMatchCheck extends AbstractSanityCheck {\n readonly name = \"project-match\";\n readonly path = \".zitadel/secret\";\n protected readonly summary = \".zitadel/secret project_id matches zitadel.json project\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const config = await readZitadelConfig(ctx.cwd);\n const secret = await readZitadelSecret(ctx.cwd);\n const configProject = typeof config.project === \"string\" ? config.project : undefined;\n if (secret.project_id !== configProject) {\n throw new Error(\".zitadel/secret project_id does not match zitadel.json project\");\n }\n }\n}\n","/**\n * Public surface for the doctor sanity checks. The `doctor` command imports\n * {@link SANITY_CHECKS} and runs every entry, aggregating the outcomes. Each\n * check is a small standalone class (see its own file); add a new diagnostic\n * by writing a class and appending an instance to the registry below.\n */\nimport type { SanityCheck } from \"./types\";\nimport { ConfigCheck } from \"./config\";\nimport { SecretCheck } from \"./secret\";\nimport { SecretPermissionsCheck } from \"./secret-permissions\";\nimport { GitignoreCheck } from \"./gitignore\";\nimport { EnvExampleCheck } from \"./env-example\";\nimport { FrameworkCheck } from \"./framework\";\nimport { DependencyCheck } from \"./dependency\";\nimport { ProjectMatchCheck } from \"./project-match\";\n\nexport type { SanityCheck, CheckContext, CheckOutcome } from \"./types\";\nexport { AbstractSanityCheck } from \"./types\";\nexport { ConfigCheck } from \"./config\";\nexport { SecretCheck } from \"./secret\";\nexport { SecretPermissionsCheck } from \"./secret-permissions\";\nexport { GitignoreCheck } from \"./gitignore\";\nexport { EnvExampleCheck } from \"./env-example\";\nexport { FrameworkCheck } from \"./framework\";\nexport { SchemaCheck } from \"./schema\";\nexport { DependencyCheck } from \"./dependency\";\nexport { ProjectMatchCheck } from \"./project-match\";\n\n/** Every diagnostic the `doctor` command runs, in display order. */\nexport const SANITY_CHECKS: ReadonlyArray<SanityCheck> = [\n new ConfigCheck(),\n new SecretCheck(),\n new SecretPermissionsCheck(),\n new GitignoreCheck(),\n new EnvExampleCheck(),\n new FrameworkCheck(),\n // SchemaCheck is disabled: the user schema is now provisioned server-side\n // and no longer scaffolded into `.zitadel/schemas/user.json`, so there is\n // no local file to verify. The check is kept (imported/exported below) for\n // the future pull-based workflow that will re-introduce local resources.\n // new SchemaCheck(),\n new DependencyCheck(),\n new ProjectMatchCheck(),\n];\n","import { Flags } from \"@oclif/core\";\nimport consola from \"consola\";\n\nimport { ZitadelError } from \"../../lib/errors\";\nimport { dockerAvailable, imageAvailable } from \"../../lib/local-server/docker\";\nimport {\n DEFAULT_LOCAL_SERVER_PORT,\n assertWritableDirectory,\n checkLocalServerHealth,\n defaultLocalServerImageForCliVersion,\n isPortAvailable,\n localRuntimePaths,\n localServerUrl,\n readRuntimeMetadata,\n} from \"../../lib/local-server/runtime\";\nimport { BaseCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { createOrca } from \"../../lib/orca\";\nimport { hasZitadelConfig } from \"../../lib/project\";\nimport { publicCliCommand } from \"../../lib/public-cli\";\nimport { SANITY_CHECKS, type CheckContext, type CheckOutcome } from \"./checks\";\n\nconst LOCAL_RUNTIME_CHECK_NAMES = new Set([\"docker-cli\", \"image\", \"state-dir\", \"port\", \"runtime\"]);\n\n/**\n * `zitadel doctor` — verify generated files and local state.\n *\n * Runs every registered {@link SANITY_CHECKS} entry and emits the aggregate\n * result; if any check fails it throws `E_VALIDATION` carrying the full check\n * details. With `--fix`, each failing check first attempts its own repair (a\n * no-op for checks with no safe automatic remedy), then the battery re-runs.\n *\n * The `--fix` loop is best-effort: a repair that throws (e.g. a missing\n * prerequisite file the check itself would also flag) is logged at debug\n * level and skipped, not propagated — the post-fix re-verify still reports\n * whatever remains broken.\n */\nexport default class Doctor extends BaseCommand {\n static override description = \"Verify local runtime and project state.\";\n static override flags = {\n fix: Flags.boolean({ description: \"Re-apply missing managed files.\" }),\n image: Flags.string({ description: \"Container image to check.\" }),\n port: Flags.integer({ description: \"Local HTTP port.\", default: DEFAULT_LOCAL_SERVER_PORT }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Doctor);\n const port = flags.port ?? DEFAULT_LOCAL_SERVER_PORT;\n await this.toMeta(flags, { resolveServer: false, source: localServerUrl(port) });\n const { cwd, dryRun } = this.meta;\n const image =\n flags.image ??\n this.meta.env.ZITADEL_LOCAL_IMAGE ??\n defaultLocalServerImageForCliVersion(this.meta.cliVersion);\n const runtimeChecks = await runLocalRuntimeChecks(cwd, image, port);\n const hasConfig = await hasZitadelConfig(cwd);\n const ctx: CheckContext = { cwd, orca: createOrca(), cliVersion: this.meta.cliVersion, dryRun };\n\n if (hasConfig && flags.fix) {\n const before = await Promise.all(SANITY_CHECKS.map((check) => check.run(ctx)));\n for (const [index, check] of SANITY_CHECKS.entries()) {\n if (before[index]?.status !== \"fail\") {\n continue;\n }\n try {\n await check.fix(ctx);\n } catch (error) {\n consola.debug(`doctor --fix: ${check.name} repair failed`, error);\n }\n }\n }\n\n const projectChecks = hasConfig\n ? await Promise.all(SANITY_CHECKS.map((check) => check.run(ctx)))\n : [];\n const checks = [...runtimeChecks, ...projectChecks];\n const failed = checks.filter((check) => check.status === \"fail\");\n const warnings = checks.filter((check) => check.status === \"warn\");\n const data = {\n title:\n failed.length > 0\n ? \"Zitadel doctor found issues.\"\n : warnings.length > 0\n ? \"Zitadel doctor passed with warnings.\"\n : \"Zitadel doctor passed.\",\n ok: failed.length === 0,\n image,\n port,\n project: {\n lifecycle: hasConfig ? \"configured\" : \"not-configured\",\n },\n checks,\n };\n\n if (failed.length > 0) {\n const advice = failureAdvice(failed, image, port, this.meta.cliVersion);\n throw new ZitadelError(\"E_VALIDATION\", \"Zitadel doctor found issues\", {\n hint: advice.hint,\n nextCommands: advice.nextCommands,\n details: data,\n });\n }\n\n return this.emit({\n status: \"ok\",\n data,\n warnings: warnings.map((warning) => `${warning.name}: ${warning.message}`),\n });\n }\n}\n\nfunction failureAdvice(\n failed: CheckOutcome[],\n image: string,\n port: number,\n cliVersion: string,\n): { hint: string; nextCommands: string[] } {\n const failedNames = new Set(failed.map((check) => check.name));\n\n if (failedNames.has(\"docker-cli\")) {\n return {\n hint: \"Docker is required for `zitadel start`, but the Docker daemon is not reachable. Install or start Docker, then rerun `zitadel doctor`.\",\n nextCommands: [\"docker version\", publicCliCommand(\"doctor\", cliVersion)],\n };\n }\n\n if (failedNames.has(\"image\")) {\n return {\n hint: \"The local Zitadel image is not available. Check Docker registry access, build it locally, or pass --image / ZITADEL_LOCAL_IMAGE.\",\n nextCommands: [`docker pull ${image}`, publicCliCommand(\"doctor\", cliVersion)],\n };\n }\n\n if (failedNames.has(\"state-dir\")) {\n return {\n hint: \"The local Zitadel state directory is not writable. Fix directory permissions, then rerun `zitadel doctor`.\",\n nextCommands: [publicCliCommand(\"doctor\", cliVersion)],\n };\n }\n\n if (failedNames.has(\"port\")) {\n const fallbackPort = port === DEFAULT_LOCAL_SERVER_PORT ? port + 1 : DEFAULT_LOCAL_SERVER_PORT;\n return {\n hint: `Port ${String(port)} is already in use. Stop the process using it, or choose another port for local Zitadel.`,\n nextCommands: [publicCliCommand(`doctor --port ${String(fallbackPort)}`, cliVersion)],\n };\n }\n\n if (failedNames.has(\"runtime\")) {\n return {\n hint: \"Existing local runtime metadata was found, but the local Zitadel server is not healthy. Start it again or reset stale local data.\",\n nextCommands: [\n publicCliCommand(\"start\", cliVersion),\n publicCliCommand(\"reset --force\", cliVersion),\n ],\n };\n }\n\n const hasProjectFailure = failed.some((check) => !LOCAL_RUNTIME_CHECK_NAMES.has(check.name));\n if (hasProjectFailure) {\n return {\n hint: `Run \\`${publicCliCommand(\"doctor --fix\", cliVersion)}\\` to re-apply missing managed files.`,\n nextCommands: [publicCliCommand(\"doctor --fix\", cliVersion)],\n };\n }\n\n return {\n hint: \"Fix the reported checks, then rerun `zitadel doctor`.\",\n nextCommands: [publicCliCommand(\"doctor\", cliVersion)],\n };\n}\n\nasync function runLocalRuntimeChecks(\n cwd: string,\n image: string,\n port: number,\n): Promise<CheckOutcome[]> {\n const runtime = await readRuntimeMetadata(cwd);\n const docker = await check(\n \"docker-cli\",\n \"Docker is reachable\",\n async () => {\n let result: Awaited<ReturnType<typeof dockerAvailable>>;\n try {\n result = await dockerAvailable();\n } catch (error) {\n throw new Error(dockerUnavailableMessage(error), { cause: error });\n }\n if (result.status !== 0) {\n throw new Error(dockerUnavailableMessage(result.stderr || \"docker version failed\"));\n }\n return `Docker engine ${result.stdout.trim() || \"available\"}`;\n },\n \"warn\",\n );\n\n const imageCheck =\n docker.status === \"pass\"\n ? await check(\n \"image\",\n `Image ${image} is available`,\n async () => {\n try {\n const source = await imageAvailable(image);\n return source === \"local\"\n ? `Image ${image} is available locally`\n : `Image ${image} is available from the registry`;\n } catch (error) {\n throw new Error(imageUnavailableMessage(image, error), { cause: error });\n }\n },\n \"warn\",\n )\n : ({\n name: \"image\",\n status: \"warn\",\n message: \"Skipped image check because Docker is not reachable.\",\n } satisfies CheckOutcome);\n\n return [\n docker,\n imageCheck,\n await check(\n \"state-dir\",\n \"Local state directory is writable\",\n async () => {\n const paths = localRuntimePaths(cwd);\n await assertWritableDirectory(paths.dataDir);\n return `${paths.dataDir} is writable`;\n },\n \"warn\",\n ),\n await check(\n \"port\",\n `Port ${String(port)} is available`,\n async () => {\n if (runtime && (await checkLocalServerHealth(runtime.server_url))) {\n return `${runtime.server_url} is already healthy`;\n }\n if (!(await isPortAvailable(port))) {\n throw new Error(`Port ${String(port)} is already in use`);\n }\n return `Port ${String(port)} is available`;\n },\n \"warn\",\n ),\n await check(\"runtime\", \"Existing local runtime is healthy\", async () => {\n if (!runtime) {\n return \"No existing runtime metadata\";\n }\n if (!(await checkLocalServerHealth(runtime.server_url))) {\n throw new Error(`${runtime.server_url} did not respond to /healthz`);\n }\n return `${runtime.server_url} is healthy`;\n }),\n ];\n}\n\nasync function check(\n name: string,\n fallback: string,\n run: () => Promise<string>,\n failureStatus: \"warn\" | \"fail\" = \"fail\",\n): Promise<CheckOutcome> {\n try {\n return { name, status: \"pass\", message: await run() };\n } catch (error) {\n return {\n name,\n status: failureStatus,\n message: error instanceof Error ? error.message : fallback,\n };\n }\n}\n\nfunction dockerUnavailableMessage(error: unknown): string {\n const detail = error instanceof Error ? error.message : String(error);\n const suffix = detail.trim() ? ` (${detail.trim()})` : \"\";\n return `Docker is not reachable${suffix}; \\`zitadel start\\` needs Docker, but cloud setup can continue.`;\n}\n\nfunction imageUnavailableMessage(image: string, error: unknown): string {\n const detail = error instanceof Error ? error.message : String(error);\n const suffix = detail.trim() ? ` (${detail.trim()})` : \"\";\n return `Image ${image} is not available to Docker${suffix}; \\`zitadel start\\` may need a pull or a different image.`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"doctor.mjs","names":[],"sources":["../../src/commands/doctor/checks/types.ts","../../src/commands/doctor/checks/config.ts","../../src/commands/doctor/checks/secret.ts","../../src/commands/doctor/checks/secret-permissions.ts","../../src/commands/doctor/checks/gitignore.ts","../../src/commands/doctor/checks/env-example.ts","../../src/commands/doctor/checks/framework.ts","../../src/commands/doctor/patch-context.ts","../../src/commands/doctor/checks/dependency.ts","../../src/commands/doctor/checks/project-match.ts","../../src/commands/doctor/checks/index.ts","../../src/commands/doctor/index.ts"],"sourcesContent":["import type { Orca } from \"../../../lib/orca\";\n\n/** Pass/fail/advisory outcome of a single {@link SanityCheck}. */\nexport type CheckOutcome = {\n name: string;\n status: \"pass\" | \"warn\" | \"fail\";\n message: string;\n path?: string;\n};\n\n/** Everything a check needs to inspect or repair a project. */\nexport type CheckContext = {\n readonly cwd: string;\n readonly orca: Orca;\n readonly cliVersion: string;\n /** When true, {@link SanityCheck.fix} must preview without writing. */\n readonly dryRun: boolean;\n};\n\n/**\n * One diagnostic the `doctor` command runs. Each concrete check is a small\n * standalone class that both verifies its concern ({@link run}) and knows how\n * to repair it ({@link fix}); the command executes every registered check,\n * aggregates the {@link CheckOutcome}s, and (under `--fix`) repairs the ones\n * that failed.\n */\nexport interface SanityCheck {\n /** Stable identifier surfaced in logs and the JSON envelope. */\n readonly name: string;\n run(ctx: CheckContext): Promise<CheckOutcome>;\n /** Repair what this check verifies. A no-op when there is no safe auto-fix. */\n fix(ctx: CheckContext): Promise<void>;\n}\n\n/**\n * Base class for checks: subclasses declare `name`, `path`, and a success\n * `summary`, and implement the single {@link verify} method that throws on\n * failure. {@link run} wraps it so a thrown error becomes a `fail` outcome\n * carrying the error message, and success becomes a `pass` with `summary`.\n *\n * {@link fix} defaults to a no-op: checks whose failure has no safe automatic\n * remedy (a missing secret, an invalid user schema) simply do not override it.\n */\nexport abstract class AbstractSanityCheck implements SanityCheck {\n abstract readonly name: string;\n abstract readonly path: string;\n protected abstract readonly summary: string;\n\n /** Throw to signal failure; the thrown message is surfaced to the user. */\n protected abstract verify(ctx: CheckContext): Promise<void>;\n\n async run(ctx: CheckContext): Promise<CheckOutcome> {\n try {\n await this.verify(ctx);\n return { name: this.name, status: \"pass\", message: this.summary, path: this.path };\n } catch (error) {\n return {\n name: this.name,\n status: \"fail\",\n message: error instanceof Error ? error.message : String(error),\n path: this.path,\n };\n }\n }\n\n async fix(_ctx: CheckContext): Promise<void> {\n return;\n }\n}\n","import { readZitadelConfig } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `zitadel.json` exists and parses. */\nexport class ConfigCheck extends AbstractSanityCheck {\n readonly name = \"config\";\n readonly path = \"zitadel.json\";\n protected readonly summary = \"zitadel.json parses\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n await readZitadelConfig(ctx.cwd);\n }\n}\n","import { readZitadelSecret } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `.zitadel/secret` exists and parses. */\nexport class SecretCheck extends AbstractSanityCheck {\n readonly name = \"secret\";\n readonly path = \".zitadel/secret\";\n protected readonly summary = \".zitadel/secret parses\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n await readZitadelSecret(ctx.cwd);\n }\n}\n","import { chmod, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `.zitadel/secret` is locked down to `0600`, and re-locks it on fix. */\nexport class SecretPermissionsCheck extends AbstractSanityCheck {\n readonly name = \"secret-permissions\";\n readonly path = \".zitadel/secret\";\n protected readonly summary = \".zitadel/secret has 0600 permissions\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const mode = (await stat(join(ctx.cwd, \".zitadel/secret\"))).mode & 0o777;\n if (mode !== 0o600) {\n throw new Error(`expected 0600, got ${mode.toString(8)}`);\n }\n }\n\n override async fix(ctx: CheckContext): Promise<void> {\n if (ctx.dryRun) {\n return;\n }\n await chmod(join(ctx.cwd, \".zitadel/secret\"), 0o600);\n }\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** The entries `.gitignore` must carry to keep secrets and env files untracked. */\nconst REQUIRED_ENTRIES = [\".zitadel/secret\", \".env*\", \"!.env.example\"];\n\n/** Verifies `.gitignore` excludes the local secret and env files; appends any missing. */\nexport class GitignoreCheck extends AbstractSanityCheck {\n readonly name = \"gitignore\";\n readonly path = \".gitignore\";\n protected readonly summary = \".gitignore protects local secret/env files\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const lines = (await readFile(join(ctx.cwd, \".gitignore\"), \"utf8\")).split(/\\r?\\n/g);\n for (const entry of REQUIRED_ENTRIES) {\n if (!lines.includes(entry)) {\n throw new Error(`missing ${entry}`);\n }\n }\n }\n\n override async fix(ctx: CheckContext): Promise<void> {\n const path = join(ctx.cwd, \".gitignore\");\n const existing = await readFile(path, \"utf8\").catch(() => \"\");\n const lines = existing.split(/\\r?\\n/g);\n const missing = REQUIRED_ENTRIES.filter((entry) => !lines.includes(entry));\n if (missing.length === 0 || ctx.dryRun) {\n return;\n }\n const prefix = existing.length > 0 && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\";\n await writeFile(path, `${existing}${prefix}${missing.join(\"\\n\")}\\n`);\n }\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** The keys `.env.example` must document for a Zitadel-managed project. */\nconst REQUIRED_KEYS = [\"ZITADEL_PROJECT_ID\", \"ZITADEL_ENVIRONMENT\", \"ZITADEL_ISSUER\"];\n\n/** Verifies `.env.example` documents the required Zitadel keys; appends any missing. */\nexport class EnvExampleCheck extends AbstractSanityCheck {\n readonly name = \"env-example\";\n readonly path = \".env.example\";\n protected readonly summary = \".env.example references required keys\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const contents = await readFile(join(ctx.cwd, \".env.example\"), \"utf8\");\n for (const key of REQUIRED_KEYS) {\n if (!contents.includes(`${key}=`)) {\n throw new Error(`missing ${key}`);\n }\n }\n }\n\n override async fix(ctx: CheckContext): Promise<void> {\n const path = join(ctx.cwd, \".env.example\");\n const existing = await readFile(path, \"utf8\").catch(() => \"\");\n const missing = REQUIRED_KEYS.filter((key) => !existing.includes(`${key}=`));\n if (missing.length === 0 || ctx.dryRun) {\n return;\n }\n const prefix = existing.length > 0 && !existing.endsWith(\"\\n\") ? \"\\n\" : \"\";\n await writeFile(path, `${existing}${prefix}${missing.map((key) => `${key}=`).join(\"\\n\")}\\n`);\n }\n}\n","import { isObject } from \"../../../lib/json\";\nimport { readZitadelConfig } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies the framework detected on disk matches the one recorded in config. */\nexport class FrameworkCheck extends AbstractSanityCheck {\n readonly name = \"framework\";\n readonly path = \"zitadel.json\";\n protected readonly summary = \"Detected framework matches recorded framework\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const config = await readZitadelConfig(ctx.cwd);\n const detected = await ctx.orca.detect(ctx.cwd);\n const recorded = isObject(config.framework) ? config.framework.id : undefined;\n if (recorded !== detected.id) {\n throw new Error(`expected ${String(recorded)}, detected ${detected.id}`);\n }\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { issuerFromPort, type FrameworkFacts, type Orca } from \"../../lib/orca\";\nimport type { PatchContext } from \"../../lib/orca/patchers/types\";\nimport { readDevelopmentIssuer, readRendererId, readZitadelConfig, readZitadelSecret } from \"../../lib/project\";\n\n/**\n * Reconstructs a {@link PatchContext} from the on-disk project (config, secret)\n * plus fresh framework detection, so a patcher repair can rebuild its plan.\n * Used by the dependency check's `fix`, which reclaims the framework-specific\n * SDK package via `patcher.repair`. The user schema and flow definition are\n * server-owned and no longer scaffolded locally, so nothing here reads them.\n */\nexport async function loadPatchContext(\n cwd: string,\n orca: Orca,\n cliVersion: string,\n): Promise<PatchContext> {\n const config = await readZitadelConfig(cwd);\n const secret = await readZitadelSecret(cwd);\n const framework = await orca.detect(cwd);\n return {\n framework,\n rendererId: readRendererId(config),\n issuer: await resolveIssuer(cwd, config, framework),\n server: typeof config.server === \"string\" ? config.server : \"\",\n cliVersion,\n project: {\n id: secret.project_id,\n projectSecret: secret.project_secret,\n previewSecret: secret.preview_secret,\n previewOrigins: secret.preview_origins,\n createdAt: secret.created_at,\n },\n };\n}\n\nasync function resolveIssuer(\n cwd: string,\n config: Record<string, unknown>,\n facts: FrameworkFacts,\n): Promise<string> {\n const fromConfig = readDevelopmentIssuer(config);\n if (fromConfig && fromConfig.length > 0) {\n return fromConfig;\n }\n const state = await readState(cwd);\n if (typeof state?.dev_port === \"number\") {\n return issuerFromPort(state.dev_port);\n }\n return facts.url;\n}\n\nasync function readState(cwd: string): Promise<{ dev_port?: number } | undefined> {\n try {\n const contents = await readFile(join(cwd, \".zitadel/state.json\"), \"utf8\");\n return JSON.parse(contents) as { dev_port?: number };\n } catch {\n return undefined;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { loadPatchContext } from \"../patch-context\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/**\n * Verifies the project still declares a Zitadel SDK dependency in\n * `package.json`. The patcher adds a scoped package (e.g.\n * `@zitadel/sdk-next`); the check is generic over the `@zitadel*`\n * scope so any framework renderer's dependency satisfies it.\n */\nexport class DependencyCheck extends AbstractSanityCheck {\n readonly name = \"dependency\";\n readonly path = \"package.json\";\n protected readonly summary = \"package.json depends on a Zitadel SDK package\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const pkg = JSON.parse(await readFile(join(ctx.cwd, \"package.json\"), \"utf8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const names = [\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ];\n if (!names.some((name) => name.startsWith(\"@zitadel\"))) {\n throw new Error(\"no @zitadel* dependency found in package.json\");\n }\n }\n\n /**\n * Repairs by reclaiming the patcher's managed artifacts: rebuilds the\n * `PatchContext` from disk and calls `patcher.repair`, which re-adds the\n * SDK dependency via its `add-dep` op. The exact package name is framework\n * + renderer specific and known only to the patcher (which deliberately\n * hides its file-op plan behind the family-neutral `Patcher` interface),\n * so going through `repair` is the only sanctioned path.\n */\n override async fix(ctx: CheckContext): Promise<void> {\n const patchCtx = await loadPatchContext(ctx.cwd, ctx.orca, ctx.cliVersion);\n await ctx.orca.patcherFor(patchCtx.framework.id).repair(patchCtx, {\n cwd: ctx.cwd,\n dryRun: ctx.dryRun,\n force: true,\n });\n }\n}\n","import { readZitadelConfig, readZitadelSecret } from \"../../../lib/project\";\nimport { AbstractSanityCheck, type CheckContext } from \"./types\";\n\n/** Verifies `.zitadel/secret`'s project_id matches `zitadel.json`'s project. */\nexport class ProjectMatchCheck extends AbstractSanityCheck {\n readonly name = \"project-match\";\n readonly path = \".zitadel/secret\";\n protected readonly summary = \".zitadel/secret project_id matches zitadel.json project\";\n\n protected async verify(ctx: CheckContext): Promise<void> {\n const config = await readZitadelConfig(ctx.cwd);\n const secret = await readZitadelSecret(ctx.cwd);\n const configProject = typeof config.project === \"string\" ? config.project : undefined;\n if (secret.project_id !== configProject) {\n throw new Error(\".zitadel/secret project_id does not match zitadel.json project\");\n }\n }\n}\n","/**\n * Public surface for the doctor sanity checks. The `doctor` command imports\n * {@link SANITY_CHECKS} and runs every entry, aggregating the outcomes. Each\n * check is a small standalone class (see its own file); add a new diagnostic\n * by writing a class and appending an instance to the registry below.\n */\nimport type { SanityCheck } from \"./types\";\nimport { ConfigCheck } from \"./config\";\nimport { SecretCheck } from \"./secret\";\nimport { SecretPermissionsCheck } from \"./secret-permissions\";\nimport { GitignoreCheck } from \"./gitignore\";\nimport { EnvExampleCheck } from \"./env-example\";\nimport { FrameworkCheck } from \"./framework\";\nimport { DependencyCheck } from \"./dependency\";\nimport { ProjectMatchCheck } from \"./project-match\";\n\nexport type { SanityCheck, CheckContext, CheckOutcome } from \"./types\";\nexport { AbstractSanityCheck } from \"./types\";\nexport { ConfigCheck } from \"./config\";\nexport { SecretCheck } from \"./secret\";\nexport { SecretPermissionsCheck } from \"./secret-permissions\";\nexport { GitignoreCheck } from \"./gitignore\";\nexport { EnvExampleCheck } from \"./env-example\";\nexport { FrameworkCheck } from \"./framework\";\nexport { SchemaCheck } from \"./schema\";\nexport { DependencyCheck } from \"./dependency\";\nexport { ProjectMatchCheck } from \"./project-match\";\n\n/** Every diagnostic the `doctor` command runs, in display order. */\nexport const SANITY_CHECKS: ReadonlyArray<SanityCheck> = [\n new ConfigCheck(),\n new SecretCheck(),\n new SecretPermissionsCheck(),\n new GitignoreCheck(),\n new EnvExampleCheck(),\n new FrameworkCheck(),\n // SchemaCheck is disabled: the user schema is now provisioned server-side\n // and no longer scaffolded into `.zitadel/schemas/user.json`, so there is\n // no local file to verify. The check is kept (imported/exported below) for\n // the future pull-based workflow that will re-introduce local resources.\n // new SchemaCheck(),\n new DependencyCheck(),\n new ProjectMatchCheck(),\n];\n","import { Flags } from \"@oclif/core\";\nimport consola from \"consola\";\n\nimport { ZitadelError } from \"../../lib/errors\";\nimport { dockerAvailable, imageAvailable } from \"../../lib/local-server/docker\";\nimport {\n DEFAULT_LOCAL_SERVER_PORT,\n assertLocalStateWritable,\n checkLocalServerHealth,\n defaultLocalServerImageForCliVersion,\n isPortAvailable,\n localServerUrl,\n readRuntimeMetadata,\n} from \"../../lib/local-server/runtime\";\nimport { BaseCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { createOrca } from \"../../lib/orca\";\nimport { hasZitadelConfig } from \"../../lib/project\";\nimport { publicCliCommand } from \"../../lib/public-cli\";\nimport { SANITY_CHECKS, type CheckContext, type CheckOutcome } from \"./checks\";\n\nconst LOCAL_RUNTIME_CHECK_NAMES = new Set([\"docker-cli\", \"image\", \"state-dir\", \"port\", \"runtime\"]);\n\n/**\n * `zitadel doctor` — verify generated files and local state.\n *\n * Runs every registered {@link SANITY_CHECKS} entry and emits the aggregate\n * result; if any check fails it throws `E_VALIDATION` carrying the full check\n * details. With `--fix`, each failing check first attempts its own repair (a\n * no-op for checks with no safe automatic remedy), then the battery re-runs.\n *\n * The `--fix` loop is best-effort: a repair that throws (e.g. a missing\n * prerequisite file the check itself would also flag) is logged at debug\n * level and skipped, not propagated — the post-fix re-verify still reports\n * whatever remains broken.\n */\nexport default class Doctor extends BaseCommand {\n static override description = \"Verify local runtime and project state.\";\n static override flags = {\n fix: Flags.boolean({ description: \"Re-apply missing managed files.\" }),\n image: Flags.string({ description: \"Container image to check.\" }),\n port: Flags.integer({ description: \"Local HTTP port.\", default: DEFAULT_LOCAL_SERVER_PORT }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Doctor);\n const port = flags.port ?? DEFAULT_LOCAL_SERVER_PORT;\n await this.toMeta(flags, { resolveServer: false, source: localServerUrl(port) });\n const { cwd, dryRun } = this.meta;\n const image =\n flags.image ??\n this.meta.env.ZITADEL_LOCAL_IMAGE ??\n defaultLocalServerImageForCliVersion(this.meta.cliVersion);\n const runtimeChecks = await runLocalRuntimeChecks(cwd, image, port);\n const hasConfig = await hasZitadelConfig(cwd);\n const ctx: CheckContext = { cwd, orca: createOrca(), cliVersion: this.meta.cliVersion, dryRun };\n\n if (hasConfig && flags.fix) {\n const before = await Promise.all(SANITY_CHECKS.map((check) => check.run(ctx)));\n for (const [index, check] of SANITY_CHECKS.entries()) {\n if (before[index]?.status !== \"fail\") {\n continue;\n }\n try {\n await check.fix(ctx);\n } catch (error) {\n consola.debug(`doctor --fix: ${check.name} repair failed`, error);\n }\n }\n }\n\n const projectChecks = hasConfig\n ? await Promise.all(SANITY_CHECKS.map((check) => check.run(ctx)))\n : [];\n const checks = [...runtimeChecks, ...projectChecks];\n const failed = checks.filter((check) => check.status === \"fail\");\n const warnings = checks.filter((check) => check.status === \"warn\");\n const data = {\n title:\n failed.length > 0\n ? \"Zitadel doctor found issues.\"\n : warnings.length > 0\n ? \"Zitadel doctor passed with warnings.\"\n : \"Zitadel doctor passed.\",\n ok: failed.length === 0,\n image,\n port,\n project: {\n lifecycle: hasConfig ? \"configured\" : \"not-configured\",\n },\n checks,\n };\n\n if (failed.length > 0) {\n const advice = failureAdvice(failed, image, port, this.meta.cliVersion);\n throw new ZitadelError(\"E_VALIDATION\", \"Zitadel doctor found issues\", {\n hint: advice.hint,\n nextCommands: advice.nextCommands,\n details: data,\n });\n }\n\n return this.emit({\n status: \"ok\",\n data,\n warnings: warnings.map((warning) => `${warning.name}: ${warning.message}`),\n });\n }\n}\n\nfunction failureAdvice(\n failed: CheckOutcome[],\n image: string,\n port: number,\n cliVersion: string,\n): { hint: string; nextCommands: string[] } {\n const failedNames = new Set(failed.map((check) => check.name));\n\n if (failedNames.has(\"docker-cli\")) {\n return {\n hint: \"Docker is required for `zitadel start`, but the Docker daemon is not reachable. Install or start Docker, then rerun `zitadel doctor`.\",\n nextCommands: [\"docker version\", publicCliCommand(\"doctor\", cliVersion)],\n };\n }\n\n if (failedNames.has(\"image\")) {\n return {\n hint: \"The local Zitadel image is not available. Check Docker registry access, build it locally, or pass --image / ZITADEL_LOCAL_IMAGE.\",\n nextCommands: [`docker pull ${image}`, publicCliCommand(\"doctor\", cliVersion)],\n };\n }\n\n if (failedNames.has(\"state-dir\")) {\n return {\n hint: \"The local Zitadel state directory is not writable. Fix directory permissions, then rerun `zitadel doctor`.\",\n nextCommands: [publicCliCommand(\"doctor\", cliVersion)],\n };\n }\n\n if (failedNames.has(\"port\")) {\n const fallbackPort = port === DEFAULT_LOCAL_SERVER_PORT ? port + 1 : DEFAULT_LOCAL_SERVER_PORT;\n return {\n hint: `Port ${String(port)} is already in use. Stop the process using it, or choose another port for local Zitadel.`,\n nextCommands: [publicCliCommand(`doctor --port ${String(fallbackPort)}`, cliVersion)],\n };\n }\n\n if (failedNames.has(\"runtime\")) {\n return {\n hint: \"Existing local runtime metadata was found, but the local Zitadel server is not healthy. Start it again or reset stale local data.\",\n nextCommands: [\n publicCliCommand(\"start\", cliVersion),\n publicCliCommand(\"reset --force\", cliVersion),\n ],\n };\n }\n\n const hasProjectFailure = failed.some((check) => !LOCAL_RUNTIME_CHECK_NAMES.has(check.name));\n if (hasProjectFailure) {\n return {\n hint: `Run \\`${publicCliCommand(\"doctor --fix\", cliVersion)}\\` to re-apply missing managed files.`,\n nextCommands: [publicCliCommand(\"doctor --fix\", cliVersion)],\n };\n }\n\n return {\n hint: \"Fix the reported checks, then rerun `zitadel doctor`.\",\n nextCommands: [publicCliCommand(\"doctor\", cliVersion)],\n };\n}\n\nasync function runLocalRuntimeChecks(\n cwd: string,\n image: string,\n port: number,\n): Promise<CheckOutcome[]> {\n const runtime = await readRuntimeMetadata(cwd);\n const docker = await check(\n \"docker-cli\",\n \"Docker is reachable\",\n async () => {\n let result: Awaited<ReturnType<typeof dockerAvailable>>;\n try {\n result = await dockerAvailable();\n } catch (error) {\n throw new Error(dockerUnavailableMessage(error), { cause: error });\n }\n if (result.status !== 0) {\n throw new Error(dockerUnavailableMessage(result.stderr || \"docker version failed\"));\n }\n return `Docker engine ${result.stdout.trim() || \"available\"}`;\n },\n \"warn\",\n );\n\n const imageCheck =\n docker.status === \"pass\"\n ? await check(\n \"image\",\n `Image ${image} is available`,\n async () => {\n try {\n const source = await imageAvailable(image);\n return source === \"local\"\n ? `Image ${image} is available locally`\n : `Image ${image} is available from the registry`;\n } catch (error) {\n throw new Error(imageUnavailableMessage(image, error), { cause: error });\n }\n },\n \"warn\",\n )\n : ({\n name: \"image\",\n status: \"warn\",\n message: \"Skipped image check because Docker is not reachable.\",\n } satisfies CheckOutcome);\n\n return [\n docker,\n imageCheck,\n await check(\n \"state-dir\",\n \"Local state directory is writable\",\n async () => {\n const probe = await assertLocalStateWritable(cwd);\n return probe.checkedPath === probe.targetPath\n ? `${probe.targetPath} is writable`\n : `${probe.targetPath} can be created (${probe.checkedPath} is writable)`;\n },\n \"warn\",\n ),\n await check(\n \"port\",\n `Port ${String(port)} is available`,\n async () => {\n if (runtime && (await checkLocalServerHealth(runtime.server_url))) {\n return `${runtime.server_url} is already healthy`;\n }\n if (!(await isPortAvailable(port))) {\n throw new Error(`Port ${String(port)} is already in use`);\n }\n return `Port ${String(port)} is available`;\n },\n \"warn\",\n ),\n await check(\"runtime\", \"Existing local runtime is healthy\", async () => {\n if (!runtime) {\n return \"No existing runtime metadata\";\n }\n if (!(await checkLocalServerHealth(runtime.server_url))) {\n throw new Error(`${runtime.server_url} did not respond to /healthz`);\n }\n return `${runtime.server_url} is healthy`;\n }),\n ];\n}\n\nasync function check(\n name: string,\n fallback: string,\n run: () => Promise<string>,\n failureStatus: \"warn\" | \"fail\" = \"fail\",\n): Promise<CheckOutcome> {\n try {\n return { name, status: \"pass\", message: await run() };\n } catch (error) {\n return {\n name,\n status: failureStatus,\n message: error instanceof Error ? error.message : fallback,\n };\n }\n}\n\nfunction dockerUnavailableMessage(error: unknown): string {\n const detail = error instanceof Error ? error.message : String(error);\n const suffix = detail.trim() ? ` (${detail.trim()})` : \"\";\n return `Docker is not reachable${suffix}; \\`zitadel start\\` needs Docker, but cloud setup can continue.`;\n}\n\nfunction imageUnavailableMessage(image: string, error: unknown): string {\n const detail = error instanceof Error ? error.message : String(error);\n const suffix = detail.trim() ? ` (${detail.trim()})` : \"\";\n return `Image ${image} is not available to Docker${suffix}; \\`zitadel start\\` may need a pull or a different image.`;\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { E as ZitadelError, t as BaseCommand } from "../oclif-CqkWBQ7i.mjs";
2
- import { t as createOrca } from "../orca-S1tVnngd.mjs";
3
- import { a as readZitadelConfig, i as readRendererId } from "../project-B6YfSaZw.mjs";
1
+ import { E as ZitadelError, t as BaseCommand } from "../oclif-B3Qhw0cj.mjs";
2
+ import { t as createOrca } from "../orca-BGM8VCgQ.mjs";
3
+ import { a as readZitadelConfig, i as readRendererId } from "../project-kWWyS7fS.mjs";
4
4
  import { join } from "node:path";
5
5
  import { readFile, rename, rm, stat } from "node:fs/promises";
6
6
  //#region src/commands/eject.ts
@@ -1,5 +1,5 @@
1
- import { E as ZitadelError, g as readRuntimeMetadata, t as BaseCommand, x as publicCliCommand } from "../oclif-CqkWBQ7i.mjs";
2
- import { a as followContainerLogs, t as containerLogs } from "../docker-DrOBycgG.mjs";
1
+ import { E as ZitadelError, S as resolveCwd, b as publicCliCommand, h as readRuntimeMetadata, t as BaseCommand } from "../oclif-B3Qhw0cj.mjs";
2
+ import { a as followContainerLogs, t as containerLogs } from "../docker-B4zvLujy.mjs";
3
3
  import { Flags } from "@oclif/core";
4
4
  //#region src/commands/logs.ts
5
5
  var Logs = class Logs extends BaseCommand {
@@ -13,7 +13,7 @@ var Logs = class Logs extends BaseCommand {
13
13
  };
14
14
  async run() {
15
15
  const { flags } = await this.parse(Logs);
16
- const runtime = await readRuntimeMetadata(flags.cwd ? String(flags.cwd) : process.cwd());
16
+ const runtime = await readRuntimeMetadata(resolveCwd(typeof flags.cwd === "string" ? flags.cwd : void 0));
17
17
  await this.toMeta(flags, {
18
18
  resolveServer: false,
19
19
  source: runtime?.server_url ?? "http://localhost:8080"
@@ -1 +1 @@
1
- {"version":3,"file":"logs.mjs","names":[],"sources":["../../src/commands/logs.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../lib/errors\";\nimport { containerLogs, followContainerLogs } from \"../lib/local-server/docker\";\nimport { DEFAULT_LOCAL_SERVER_URL, readRuntimeMetadata } from \"../lib/local-server/runtime\";\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { publicCliCommand } from \"../lib/public-cli\";\n\nexport default class Logs extends BaseCommand {\n static override description = \"Show local Zitadel server logs.\";\n static override flags = {\n follow: Flags.boolean({ description: \"Follow logs.\" }),\n tail: Flags.integer({ description: \"Number of lines to show.\", default: 200 }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Logs);\n const runtime = await readRuntimeMetadata(flags.cwd ? String(flags.cwd) : process.cwd());\n await this.toMeta(flags, {\n resolveServer: false,\n source: runtime?.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n\n if (!runtime) {\n throw new ZitadelError(\"E_VALIDATION\", \"Local Zitadel runtime has not been started\", {\n hint: \"Run `zitadel start` first.\",\n nextCommands: [publicCliCommand(\"start\", this.meta.cliVersion)],\n });\n }\n\n const tail = flags.tail ?? 200;\n if (!Number.isInteger(tail) || tail < 1) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid tail value ${String(tail)}`, {\n hint: \"Use a positive integer.\",\n });\n }\n\n if (flags.follow) {\n if (this.jsonEnabled()) {\n throw new ZitadelError(\"E_VALIDATION\", \"Cannot stream logs with --json\", {\n hint: \"Run without --json, or omit --follow.\",\n });\n }\n await followContainerLogs(runtime.container_name, tail);\n return this.emit({\n status: \"ok\",\n data: { title: \"Stopped following local Zitadel logs.\" },\n });\n }\n\n const logs = await containerLogs(runtime.container_name, tail);\n return this.emit({\n status: \"ok\",\n pretty: logs.trimEnd(),\n data: {\n title: \"Local Zitadel server logs.\",\n container_name: runtime.container_name,\n logs,\n },\n });\n }\n}\n"],"mappings":";;;;AAQA,IAAqB,OAArB,MAAqB,aAAa,YAAY;CAC5C,OAAgB,cAAc;CAC9B,OAAgB,QAAQ;EACtB,QAAQ,MAAM,QAAQ,EAAE,aAAa,gBAAgB,CAAC;EACtD,MAAM,MAAM,QAAQ;GAAE,aAAa;GAA4B,SAAS;GAAK,CAAC;EAC/E;CAED,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,KAAK;EACxC,MAAM,UAAU,MAAM,oBAAoB,MAAM,MAAM,OAAO,MAAM,IAAI,GAAG,QAAQ,KAAK,CAAC;AACxF,QAAM,KAAK,OAAO,OAAO;GACvB,eAAe;GACf,QAAQ,SAAS,cAAA;GAClB,CAAC;AAEF,MAAI,CAAC,QACH,OAAM,IAAI,aAAa,gBAAgB,8CAA8C;GACnF,MAAM;GACN,cAAc,CAAC,iBAAiB,SAAS,KAAK,KAAK,WAAW,CAAC;GAChE,CAAC;EAGJ,MAAM,OAAO,MAAM,QAAQ;AAC3B,MAAI,CAAC,OAAO,UAAU,KAAK,IAAI,OAAO,EACpC,OAAM,IAAI,aAAa,gBAAgB,sBAAsB,OAAO,KAAK,IAAI,EAC3E,MAAM,2BACP,CAAC;AAGJ,MAAI,MAAM,QAAQ;AAChB,OAAI,KAAK,aAAa,CACpB,OAAM,IAAI,aAAa,gBAAgB,kCAAkC,EACvE,MAAM,yCACP,CAAC;AAEJ,SAAM,oBAAoB,QAAQ,gBAAgB,KAAK;AACvD,UAAO,KAAK,KAAK;IACf,QAAQ;IACR,MAAM,EAAE,OAAO,yCAAyC;IACzD,CAAC;;EAGJ,MAAM,OAAO,MAAM,cAAc,QAAQ,gBAAgB,KAAK;AAC9D,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,QAAQ,KAAK,SAAS;GACtB,MAAM;IACJ,OAAO;IACP,gBAAgB,QAAQ;IACxB;IACD;GACF,CAAC"}
1
+ {"version":3,"file":"logs.mjs","names":[],"sources":["../../src/commands/logs.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\n\nimport { ZitadelError } from \"../lib/errors\";\nimport { containerLogs, followContainerLogs } from \"../lib/local-server/docker\";\nimport { DEFAULT_LOCAL_SERVER_URL, readRuntimeMetadata } 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 Logs extends BaseCommand {\n static override description = \"Show local Zitadel server logs.\";\n static override flags = {\n follow: Flags.boolean({ description: \"Follow logs.\" }),\n tail: Flags.integer({ description: \"Number of lines to show.\", default: 200 }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Logs);\n const cwd = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n const runtime = await readRuntimeMetadata(cwd);\n await this.toMeta(flags, {\n resolveServer: false,\n source: runtime?.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n\n if (!runtime) {\n throw new ZitadelError(\"E_VALIDATION\", \"Local Zitadel runtime has not been started\", {\n hint: \"Run `zitadel start` first.\",\n nextCommands: [publicCliCommand(\"start\", this.meta.cliVersion)],\n });\n }\n\n const tail = flags.tail ?? 200;\n if (!Number.isInteger(tail) || tail < 1) {\n throw new ZitadelError(\"E_VALIDATION\", `Invalid tail value ${String(tail)}`, {\n hint: \"Use a positive integer.\",\n });\n }\n\n if (flags.follow) {\n if (this.jsonEnabled()) {\n throw new ZitadelError(\"E_VALIDATION\", \"Cannot stream logs with --json\", {\n hint: \"Run without --json, or omit --follow.\",\n });\n }\n await followContainerLogs(runtime.container_name, tail);\n return this.emit({\n status: \"ok\",\n data: { title: \"Stopped following local Zitadel logs.\" },\n });\n }\n\n const logs = await containerLogs(runtime.container_name, tail);\n return this.emit({\n status: \"ok\",\n pretty: logs.trimEnd(),\n data: {\n title: \"Local Zitadel server logs.\",\n container_name: runtime.container_name,\n logs,\n },\n });\n }\n}\n"],"mappings":";;;;AASA,IAAqB,OAArB,MAAqB,aAAa,YAAY;CAC5C,OAAgB,cAAc;CAC9B,OAAgB,QAAQ;EACtB,QAAQ,MAAM,QAAQ,EAAE,aAAa,gBAAgB,CAAC;EACtD,MAAM,MAAM,QAAQ;GAAE,aAAa;GAA4B,SAAS;GAAK,CAAC;EAC/E;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,CAAC,QACH,OAAM,IAAI,aAAa,gBAAgB,8CAA8C;GACnF,MAAM;GACN,cAAc,CAAC,iBAAiB,SAAS,KAAK,KAAK,WAAW,CAAC;GAChE,CAAC;EAGJ,MAAM,OAAO,MAAM,QAAQ;AAC3B,MAAI,CAAC,OAAO,UAAU,KAAK,IAAI,OAAO,EACpC,OAAM,IAAI,aAAa,gBAAgB,sBAAsB,OAAO,KAAK,IAAI,EAC3E,MAAM,2BACP,CAAC;AAGJ,MAAI,MAAM,QAAQ;AAChB,OAAI,KAAK,aAAa,CACpB,OAAM,IAAI,aAAa,gBAAgB,kCAAkC,EACvE,MAAM,yCACP,CAAC;AAEJ,SAAM,oBAAoB,QAAQ,gBAAgB,KAAK;AACvD,UAAO,KAAK,KAAK;IACf,QAAQ;IACR,MAAM,EAAE,OAAO,yCAAyC;IACzD,CAAC;;EAGJ,MAAM,OAAO,MAAM,cAAc,QAAQ,gBAAgB,KAAK;AAC9D,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,QAAQ,KAAK,SAAS;GACtB,MAAM;IACJ,OAAO;IACP,gBAAgB,QAAQ;IACxB;IACD;GACF,CAAC"}
@@ -1,6 +1,6 @@
1
- import { t as BaseCommand } from "../oclif-CqkWBQ7i.mjs";
2
- import { o as readZitadelSecret } from "../project-B6YfSaZw.mjs";
3
- import { a as makeSyncers, n as summarizePlan, o as environmentSchema, r as buildSyncPlan, t as renderPlan } from "../sync-DN4oNLVH.mjs";
1
+ import { t as BaseCommand } from "../oclif-B3Qhw0cj.mjs";
2
+ import { o as readZitadelSecret } from "../project-kWWyS7fS.mjs";
3
+ import { a as makeSyncers, n as summarizePlan, o as environmentSchema, r as buildSyncPlan, t as renderPlan } from "../sync-CHXZqYR7.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";
@@ -15,7 +15,6 @@ import { consola as consola$1 } from "consola";
15
15
  */
16
16
  var Plan = class Plan extends BaseCommand {
17
17
  static description = "Validate config without mutation and preview the sync diff.";
18
- static hidden = true;
19
18
  static flags = { environment: Flags.string({
20
19
  char: "e",
21
20
  description: "Target environment (default: development).",
@@ -1 +1 @@
1
- {"version":3,"file":"plan.mjs","names":[],"sources":["../../src/commands/plan.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"@zitadel/api/client\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { environmentSchema } from \"../lib/environment\";\nimport { buildSyncPlan, makeSyncers, renderPlan, summarizePlan } from \"../lib/sync\";\nimport { readZitadelSecret } from \"../lib/project\";\n\n/**\n * `zitadel plan` — validate config and preview the sync diff without mutating.\n *\n * The read-only counterpart of `apply`: it builds and renders the diff instead\n * of running the sync loop. All validation (structural shape and env-ref\n * presence) happens in the sync engine, so an invalid file fails the same way\n * `apply` would.\n */\nexport default class Plan extends BaseCommand {\n static override description = \"Validate config without mutation and preview the sync diff.\";\n // Temporarily hidden while we collapse the dev workflow around `setup`'s\n // auto-apply. The logic stays wired up so re-exposing this command is a\n // one-line flip when we settle on the surface area.\n static override hidden = true;\n static override flags = {\n environment: Flags.string({\n char: \"e\",\n description: \"Target environment (default: development).\",\n options: [...environmentSchema.options],\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Plan);\n await this.toMeta(flags);\n const { cwd, source, env, isTTY } = this.meta;\n\n const secret = await readZitadelSecret(cwd);\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n const client = createZitadelClient({\n baseUrl: source,\n token: secret.project_secret,\n });\n const syncers = makeSyncers({ client, projectId: secret.project_id, env });\n\n consola.start(\"Building plan\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}, ` +\n `${summary.total - summary.creates - summary.updates - summary.deletes} unchanged`,\n );\n return this.emit({\n status: \"ok\",\n data: summary,\n pretty: renderPlan(plan, isTTY),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,IAAqB,OAArB,MAAqB,aAAa,YAAY;CAC5C,OAAgB,cAAc;CAI9B,OAAgB,SAAS;CACzB,OAAgB,QAAQ,EACtB,aAAa,MAAM,OAAO;EACxB,MAAM;EACN,aAAa;EACb,SAAS,CAAC,GAAG,kBAAkB,QAAQ;EACxC,CAAC,EACH;CAED,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,KAAK;AACxC,QAAM,KAAK,OAAO,MAAM;EACxB,MAAM,EAAE,KAAK,QAAQ,KAAK,UAAU,KAAK;EAEzC,MAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,YAAQ,KAAK,aAAa,OAAO,aAAa;AAC9C,YAAQ,KAAK,aAAa,SAAS;EAKnC,MAAM,UAAU,YAAY;GAAE,QAJf,oBAAoB;IACjC,SAAS;IACT,OAAO,OAAO;IACf,CACmC;GAAE,WAAW,OAAO;GAAY;GAAK,CAAC;AAE1E,YAAQ,MAAM,gBAAgB;EAC9B,MAAM,OAAO,MAAM,cAAc,KAAK,SAAS,KAAK;EACpD,MAAM,UAAU,cAAc,KAAK;AACnC,YAAQ,QACN,SAAS,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC9D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,UAAU,QAAQ,QAAQ,YAC1E;AACD,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;GACN,QAAQ,WAAW,MAAM,MAAM;GAChC,CAAC"}
1
+ {"version":3,"file":"plan.mjs","names":[],"sources":["../../src/commands/plan.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"@zitadel/api/client\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { environmentSchema } from \"../lib/environment\";\nimport { buildSyncPlan, makeSyncers, renderPlan, summarizePlan } from \"../lib/sync\";\nimport { readZitadelSecret } from \"../lib/project\";\n\n/**\n * `zitadel plan` — validate config and preview the sync diff without mutating.\n *\n * The read-only counterpart of `apply`: it builds and renders the diff instead\n * of running the sync loop. All validation (structural shape and env-ref\n * presence) happens in the sync engine, so an invalid file fails the same way\n * `apply` would.\n */\nexport default class Plan extends BaseCommand {\n static override description = \"Validate config without mutation and preview the sync diff.\";\n static override flags = {\n environment: Flags.string({\n char: \"e\",\n description: \"Target environment (default: development).\",\n options: [...environmentSchema.options],\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Plan);\n await this.toMeta(flags);\n const { cwd, source, env, isTTY } = this.meta;\n\n const secret = await readZitadelSecret(cwd);\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n const client = createZitadelClient({\n baseUrl: source,\n token: secret.project_secret,\n });\n const syncers = makeSyncers({ client, projectId: secret.project_id, env });\n\n consola.start(\"Building plan\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}, ` +\n `${summary.total - summary.creates - summary.updates - summary.deletes} unchanged`,\n );\n return this.emit({\n status: \"ok\",\n data: summary,\n pretty: renderPlan(plan, isTTY),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,IAAqB,OAArB,MAAqB,aAAa,YAAY;CAC5C,OAAgB,cAAc;CAC9B,OAAgB,QAAQ,EACtB,aAAa,MAAM,OAAO;EACxB,MAAM;EACN,aAAa;EACb,SAAS,CAAC,GAAG,kBAAkB,QAAQ;EACxC,CAAC,EACH;CAED,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,KAAK;AACxC,QAAM,KAAK,OAAO,MAAM;EACxB,MAAM,EAAE,KAAK,QAAQ,KAAK,UAAU,KAAK;EAEzC,MAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,YAAQ,KAAK,aAAa,OAAO,aAAa;AAC9C,YAAQ,KAAK,aAAa,SAAS;EAKnC,MAAM,UAAU,YAAY;GAAE,QAJf,oBAAoB;IACjC,SAAS;IACT,OAAO,OAAO;IACf,CACmC;GAAE,WAAW,OAAO;GAAY;GAAK,CAAC;AAE1E,YAAQ,MAAM,gBAAgB;EAC9B,MAAM,OAAO,MAAM,cAAc,KAAK,SAAS,KAAK;EACpD,MAAM,UAAU,cAAc,KAAK;AACnC,YAAQ,QACN,SAAS,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC9D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,UAAU,QAAQ,QAAQ,YAC1E;AACD,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;GACN,QAAQ,WAAW,MAAM,MAAM;GAChC,CAAC"}
@@ -1,12 +1,12 @@
1
- import { E as ZitadelError, _ as removeLocalData, g as readRuntimeMetadata, p as localContainerName, t as BaseCommand, v as removeRuntimeMetadata, x as publicCliCommand } from "../oclif-CqkWBQ7i.mjs";
2
- import { u as stopAndRemoveContainer } from "../docker-DrOBycgG.mjs";
1
+ import { E as ZitadelError, S as resolveCwd, _ as removeRuntimeMetadata, b as publicCliCommand, g as removeLocalData, h as readRuntimeMetadata, p as localContainerName, t as BaseCommand } from "../oclif-B3Qhw0cj.mjs";
2
+ import { u as stopAndRemoveContainer } from "../docker-B4zvLujy.mjs";
3
3
  import { cancel, confirm, isCancel } from "@clack/prompts";
4
4
  //#region src/commands/reset.ts
5
5
  var Reset = class Reset extends BaseCommand {
6
6
  static description = "Delete the local Zitadel server runtime and data.";
7
7
  async run() {
8
8
  const { flags } = await this.parse(Reset);
9
- const runtime = await readRuntimeMetadata(flags.cwd ? String(flags.cwd) : process.cwd());
9
+ const runtime = await readRuntimeMetadata(resolveCwd(typeof flags.cwd === "string" ? flags.cwd : void 0));
10
10
  await this.toMeta(flags, {
11
11
  resolveServer: false,
12
12
  source: runtime?.server_url ?? "http://localhost:8080"
@@ -1 +1 @@
1
- {"version":3,"file":"reset.mjs","names":[],"sources":["../../src/commands/reset.ts"],"sourcesContent":["import { cancel, confirm, isCancel } from \"@clack/prompts\";\n\nimport { ZitadelError } from \"../lib/errors\";\nimport { stopAndRemoveContainer } from \"../lib/local-server/docker\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n localContainerName,\n readRuntimeMetadata,\n removeLocalData,\n removeRuntimeMetadata,\n} from \"../lib/local-server/runtime\";\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { publicCliCommand } from \"../lib/public-cli\";\n\nexport default class Reset extends BaseCommand {\n static override description = \"Delete the local Zitadel server runtime and data.\";\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Reset);\n const runtime = await readRuntimeMetadata(flags.cwd ? String(flags.cwd) : process.cwd());\n await this.toMeta(flags, {\n resolveServer: false,\n source: runtime?.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n\n const containerName = runtime?.container_name ?? localContainerName(this.meta.cwd);\n if (this.meta.dryRun) {\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local Zitadel server runtime reset plan.\",\n runtime: {\n container_name: containerName,\n data_deleted: true,\n },\n next_commands: [publicCliCommand(\"reset --force\", this.meta.cliVersion)],\n },\n });\n }\n\n if (!this.meta.force) {\n if (this.meta.nonInteractive) {\n throw new ZitadelError(\"E_VALIDATION\", \"Reset requires --force in non-interactive mode\", {\n hint: \"Pass --force to delete `.zitadel/local/nextgen-data`.\",\n nextCommands: [publicCliCommand(\"reset --force\", this.meta.cliVersion)],\n });\n }\n const answer = await confirm({\n message: \"Delete the local Zitadel container and .zitadel/local/nextgen-data?\",\n initialValue: false,\n });\n if (isCancel(answer)) {\n cancel(\"Reset cancelled.\");\n throw new ZitadelError(\"E_VALIDATION\", \"Reset cancelled by user\");\n }\n if (!answer) {\n return this.emit({ status: \"skipped\", reason: \"reset-cancelled\" });\n }\n }\n\n await stopAndRemoveContainer(containerName);\n await removeLocalData(this.meta.cwd);\n await removeRuntimeMetadata(this.meta.cwd);\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local Zitadel server runtime reset.\",\n runtime: {\n container_name: containerName,\n data_deleted: true,\n },\n },\n });\n }\n}\n"],"mappings":";;;;AAcA,IAAqB,QAArB,MAAqB,cAAc,YAAY;CAC7C,OAAgB,cAAc;CAE9B,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,MAAM;EACzC,MAAM,UAAU,MAAM,oBAAoB,MAAM,MAAM,OAAO,MAAM,IAAI,GAAG,QAAQ,KAAK,CAAC;AACxF,QAAM,KAAK,OAAO,OAAO;GACvB,eAAe;GACf,QAAQ,SAAS,cAAA;GAClB,CAAC;EAEF,MAAM,gBAAgB,SAAS,kBAAkB,mBAAmB,KAAK,KAAK,IAAI;AAClF,MAAI,KAAK,KAAK,OACZ,QAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,SAAS;KACP,gBAAgB;KAChB,cAAc;KACf;IACD,eAAe,CAAC,iBAAiB,iBAAiB,KAAK,KAAK,WAAW,CAAC;IACzE;GACF,CAAC;AAGJ,MAAI,CAAC,KAAK,KAAK,OAAO;AACpB,OAAI,KAAK,KAAK,eACZ,OAAM,IAAI,aAAa,gBAAgB,kDAAkD;IACvF,MAAM;IACN,cAAc,CAAC,iBAAiB,iBAAiB,KAAK,KAAK,WAAW,CAAC;IACxE,CAAC;GAEJ,MAAM,SAAS,MAAM,QAAQ;IAC3B,SAAS;IACT,cAAc;IACf,CAAC;AACF,OAAI,SAAS,OAAO,EAAE;AACpB,WAAO,mBAAmB;AAC1B,UAAM,IAAI,aAAa,gBAAgB,0BAA0B;;AAEnE,OAAI,CAAC,OACH,QAAO,KAAK,KAAK;IAAE,QAAQ;IAAW,QAAQ;IAAmB,CAAC;;AAItE,QAAM,uBAAuB,cAAc;AAC3C,QAAM,gBAAgB,KAAK,KAAK,IAAI;AACpC,QAAM,sBAAsB,KAAK,KAAK,IAAI;AAE1C,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,SAAS;KACP,gBAAgB;KAChB,cAAc;KACf;IACF;GACF,CAAC"}
1
+ {"version":3,"file":"reset.mjs","names":[],"sources":["../../src/commands/reset.ts"],"sourcesContent":["import { cancel, confirm, isCancel } from \"@clack/prompts\";\n\nimport { ZitadelError } from \"../lib/errors\";\nimport { stopAndRemoveContainer } from \"../lib/local-server/docker\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n localContainerName,\n readRuntimeMetadata,\n removeLocalData,\n removeRuntimeMetadata,\n} from \"../lib/local-server/runtime\";\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\nimport { publicCliCommand } from \"../lib/public-cli\";\n\nexport default class Reset extends BaseCommand {\n static override description = \"Delete the local Zitadel server runtime and data.\";\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Reset);\n const cwd = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n const runtime = await readRuntimeMetadata(cwd);\n await this.toMeta(flags, {\n resolveServer: false,\n source: runtime?.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n\n const containerName = runtime?.container_name ?? localContainerName(this.meta.cwd);\n if (this.meta.dryRun) {\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local Zitadel server runtime reset plan.\",\n runtime: {\n container_name: containerName,\n data_deleted: true,\n },\n next_commands: [publicCliCommand(\"reset --force\", this.meta.cliVersion)],\n },\n });\n }\n\n if (!this.meta.force) {\n if (this.meta.nonInteractive) {\n throw new ZitadelError(\"E_VALIDATION\", \"Reset requires --force in non-interactive mode\", {\n hint: \"Pass --force to delete `.zitadel/local/nextgen-data`.\",\n nextCommands: [publicCliCommand(\"reset --force\", this.meta.cliVersion)],\n });\n }\n const answer = await confirm({\n message: \"Delete the local Zitadel container and .zitadel/local/nextgen-data?\",\n initialValue: false,\n });\n if (isCancel(answer)) {\n cancel(\"Reset cancelled.\");\n throw new ZitadelError(\"E_VALIDATION\", \"Reset cancelled by user\");\n }\n if (!answer) {\n return this.emit({ status: \"skipped\", reason: \"reset-cancelled\" });\n }\n }\n\n await stopAndRemoveContainer(containerName);\n await removeLocalData(this.meta.cwd);\n await removeRuntimeMetadata(this.meta.cwd);\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Local Zitadel server runtime reset.\",\n runtime: {\n container_name: containerName,\n data_deleted: true,\n },\n },\n });\n }\n}\n"],"mappings":";;;;AAeA,IAAqB,QAArB,MAAqB,cAAc,YAAY;CAC7C,OAAgB,cAAc;CAE9B,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,MAAM;EAEzC,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,gBAAgB,SAAS,kBAAkB,mBAAmB,KAAK,KAAK,IAAI;AAClF,MAAI,KAAK,KAAK,OACZ,QAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,SAAS;KACP,gBAAgB;KAChB,cAAc;KACf;IACD,eAAe,CAAC,iBAAiB,iBAAiB,KAAK,KAAK,WAAW,CAAC;IACzE;GACF,CAAC;AAGJ,MAAI,CAAC,KAAK,KAAK,OAAO;AACpB,OAAI,KAAK,KAAK,eACZ,OAAM,IAAI,aAAa,gBAAgB,kDAAkD;IACvF,MAAM;IACN,cAAc,CAAC,iBAAiB,iBAAiB,KAAK,KAAK,WAAW,CAAC;IACxE,CAAC;GAEJ,MAAM,SAAS,MAAM,QAAQ;IAC3B,SAAS;IACT,cAAc;IACf,CAAC;AACF,OAAI,SAAS,OAAO,EAAE;AACpB,WAAO,mBAAmB;AAC1B,UAAM,IAAI,aAAa,gBAAgB,0BAA0B;;AAEnE,OAAI,CAAC,OACH,QAAO,KAAK,KAAK;IAAE,QAAQ;IAAW,QAAQ;IAAmB,CAAC;;AAItE,QAAM,uBAAuB,cAAc;AAC3C,QAAM,gBAAgB,KAAK,KAAK,IAAI;AACpC,QAAM,sBAAsB,KAAK,KAAK,IAAI;AAE1C,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,SAAS;KACP,gBAAgB;KAChB,cAAc;KACf;IACF;GACF,CAAC"}