@zitadel/cli 1.0.0-alpha.21 → 1.0.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2248 -227
- package/SKILLS.md +246 -58
- package/dist/groups-CMB0fMzE.mjs +22 -0
- package/dist/groups-CMB0fMzE.mjs.map +1 -0
- package/dist/index.mjs +16027 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/oclif/help.mjs +67 -0
- package/dist/lib/oclif/help.mjs.map +1 -0
- package/oclif.manifest.json +4577 -185
- package/package.json +42 -8
- package/dist/branding-cygSBPkV.mjs +0 -79
- package/dist/branding-cygSBPkV.mjs.map +0 -1
- package/dist/claim-state-DlfD6Res.mjs +0 -66
- package/dist/claim-state-DlfD6Res.mjs.map +0 -1
- package/dist/commands/apply.mjs +0 -81
- package/dist/commands/apply.mjs.map +0 -1
- package/dist/commands/branding/eject.mjs +0 -104
- package/dist/commands/branding/eject.mjs.map +0 -1
- package/dist/commands/claim.mjs +0 -415
- package/dist/commands/claim.mjs.map +0 -1
- package/dist/commands/doctor.mjs +0 -1122
- package/dist/commands/doctor.mjs.map +0 -1
- package/dist/commands/eject.mjs +0 -157
- package/dist/commands/eject.mjs.map +0 -1
- package/dist/commands/logs.mjs +0 -58
- package/dist/commands/logs.mjs.map +0 -1
- package/dist/commands/plan.mjs +0 -65
- package/dist/commands/plan.mjs.map +0 -1
- package/dist/commands/reset.mjs +0 -79
- package/dist/commands/reset.mjs.map +0 -1
- package/dist/commands/schemas/list.mjs +0 -146
- package/dist/commands/schemas/list.mjs.map +0 -1
- package/dist/commands/setup.mjs +0 -1271
- package/dist/commands/setup.mjs.map +0 -1
- package/dist/commands/start.mjs +0 -288
- package/dist/commands/start.mjs.map +0 -1
- package/dist/commands/status.mjs +0 -151
- package/dist/commands/status.mjs.map +0 -1
- package/dist/commands/stop.mjs +0 -105
- package/dist/commands/stop.mjs.map +0 -1
- package/dist/designs-Ckz18Dpo.mjs +0 -38
- package/dist/designs-Ckz18Dpo.mjs.map +0 -1
- package/dist/docker-Ev1Ggt9l.mjs +0 -436
- package/dist/docker-Ev1Ggt9l.mjs.map +0 -1
- package/dist/environment-rjRVkJjW.mjs +0 -17
- package/dist/environment-rjRVkJjW.mjs.map +0 -1
- package/dist/journey-guidance-BGrOX_gT.mjs +0 -40
- package/dist/journey-guidance-BGrOX_gT.mjs.map +0 -1
- package/dist/oclif-CanO3zdt.mjs +0 -1769
- package/dist/oclif-CanO3zdt.mjs.map +0 -1
- package/dist/orca-66vAxeIe.mjs +0 -3917
- package/dist/orca-66vAxeIe.mjs.map +0 -1
- package/dist/package-manager-DFdLcDx1.mjs +0 -194
- package/dist/package-manager-DFdLcDx1.mjs.map +0 -1
- package/dist/ports-BM20XIZb.mjs +0 -116
- package/dist/ports-BM20XIZb.mjs.map +0 -1
- package/dist/processes-DKHPkU8O.mjs +0 -120
- package/dist/processes-DKHPkU8O.mjs.map +0 -1
- package/dist/project-CHhot85s.mjs +0 -140
- package/dist/project-CHhot85s.mjs.map +0 -1
- package/dist/sync-BBlACKzT.mjs +0 -1633
- package/dist/sync-BBlACKzT.mjs.map +0 -1
- package/dist/user-schema-DTuOsdKE.mjs +0 -91
- package/dist/user-schema-DTuOsdKE.mjs.map +0 -1
package/SKILLS.md
CHANGED
|
@@ -23,7 +23,8 @@ parse the result rather than scraping human output.
|
|
|
23
23
|
- The CLI sends anonymous usage telemetry by default. For automated/agent runs
|
|
24
24
|
that should stay silent, disable it with `--no-telemetry` (per invocation) or
|
|
25
25
|
`ZITADEL_TELEMETRY=0` / `DO_NOT_TRACK=1` (per environment); this also skips the
|
|
26
|
-
small end-of-command network flush
|
|
26
|
+
small end-of-command network flush and drops the `ci/` and `host/` tokens from
|
|
27
|
+
the CLI's HTTP `User-Agent`.
|
|
27
28
|
- See `README.md` (its commands section is generated from the CLI's own
|
|
28
29
|
metadata) or run `zitadel <command> --help` for the full per-command flag list.
|
|
29
30
|
|
|
@@ -71,6 +72,29 @@ Each invocation prints one JSON object:
|
|
|
71
72
|
Stop that process, run `npx @zitadel/cli@alpha stop --all` for host-wide
|
|
72
73
|
CLI-managed local runtimes, or choose another `start --port`.
|
|
73
74
|
|
|
75
|
+
In human mode the output follows the terminal: a TTY gets the project and
|
|
76
|
+
server lines and an aligned table, while a piped or redirected run (or
|
|
77
|
+
`--plain`) gets one tab-separated record per line and nothing else. `--json`
|
|
78
|
+
is unaffected and remains the contract for agents.
|
|
79
|
+
|
|
80
|
+
Text the server returns is escaped before it is printed, in `--json` as in
|
|
81
|
+
human mode, so a value someone stored cannot drive the reader's terminal.
|
|
82
|
+
Control, format and bidi characters in `data` values and keys and in an
|
|
83
|
+
error's `message` appear as visible `\xNN`, `\uNNNN` or `\u{NNNNN}` text;
|
|
84
|
+
newlines and tabs are kept, and a key's backslashes are doubled so two keys
|
|
85
|
+
never merge. A value that contained such a character is therefore not the
|
|
86
|
+
stored value byte for byte: do not send it back in an update as if it were.
|
|
87
|
+
When you need the exact stored value, call the platform API directly with the
|
|
88
|
+
project secret; the CLI only ever shows the escaped form.
|
|
89
|
+
`plan`, `apply` and `setup` are the exception for `.zitadel/` files: they
|
|
90
|
+
write the server's bodies back verbatim and escape only what they print.
|
|
91
|
+
|
|
92
|
+
A property whose name reads as a credential (`password`, `client_secret`,
|
|
93
|
+
`api_key`, …) is refused anywhere on the command line — as an `--attributes`
|
|
94
|
+
entry and inside an inline `--data` body alike, since argv is visible to other
|
|
95
|
+
processes and kept in shell history. Send such bodies with `--file <path>` or
|
|
96
|
+
`--file -` (stdin), which never pass through argv.
|
|
97
|
+
|
|
74
98
|
Capture stdout and stderr separately when scripting. Some terminals and agent
|
|
75
99
|
UIs display both streams together, but the machine contract is one parseable
|
|
76
100
|
JSON object on stdout; installer, audit, and package-manager progress belongs
|
|
@@ -80,8 +104,86 @@ Exit codes mirror the error class (3 = validation, 4 = network or not-found,
|
|
|
80
104
|
5 = conflict, 1 = auth, 2 = not-implemented). An unknown command is handled by
|
|
81
105
|
the CLI's help layer, not the envelope.
|
|
82
106
|
|
|
107
|
+
## Resource commands
|
|
108
|
+
|
|
109
|
+
Runtime resources — users, teams, sessions, events, grants, projects — have a
|
|
110
|
+
uniform `zitadel <resource> <verb>` surface built from one registry
|
|
111
|
+
(`src/commands/resources.ts`); the conventions are documented in
|
|
112
|
+
`docs/design/cli/resource-commands.md`. Config resources (schemas, flows,
|
|
113
|
+
branding) stay on `plan` / `apply`; the resource commands never write them.
|
|
114
|
+
|
|
115
|
+
| Resource | Verbs |
|
|
116
|
+
| ---------- | -------------------------------------- |
|
|
117
|
+
| `users` | list, get, create, update, delete |
|
|
118
|
+
| `teams` | list, get, create, update, deactivate |
|
|
119
|
+
| `sessions` | list, get, revoke |
|
|
120
|
+
| `events` | list, get |
|
|
121
|
+
| `grants` | list, get, create, delete |
|
|
122
|
+
| `projects` | list, get, update |
|
|
123
|
+
|
|
124
|
+
Every verb reads the project credential from `.zitadel/secret` and injects
|
|
125
|
+
`project_id` itself; there is no project flag.
|
|
126
|
+
|
|
127
|
+
`zitadel resources --json` reports the whole surface in one call: every
|
|
128
|
+
resource, its verbs, its `filter_fields` / `sort_fields`, and the fields of its writes,
|
|
129
|
+
reported per verb as `create_fields` and `update_fields` (flag name, kind,
|
|
130
|
+
`required`, and any closed value set), and `delete_outcome`, the property a
|
|
131
|
+
delete's envelope carries beside `id`. Prefer it
|
|
132
|
+
over reading `--help` per command. It contacts no server.
|
|
133
|
+
|
|
134
|
+
- `list` emits `data: { items, count, next_page_token }`, and when a page
|
|
135
|
+
remains, `data.next_commands` carries the exact command for the next page —
|
|
136
|
+
the cursor repeated alongside the same `--limit`, `--sort` and `--filter`,
|
|
137
|
+
since a token is only valid with the query that issued it. Prefer it over
|
|
138
|
+
rebuilding the invocation yourself. One page by default
|
|
139
|
+
(`--limit`, `--page-token`); `--all` drains every page and sets
|
|
140
|
+
`next_page_token` to `null`. Query-backed lists take `--filter
|
|
141
|
+
field=operation:value` (repeatable, AND-combined; the operation defaults to
|
|
142
|
+
`equals`) and `--sort field:asc|desc`; the accepted fields are listed in
|
|
143
|
+
`--help` and an unknown one fails with `E_VALIDATION` before any request.
|
|
144
|
+
`events list` takes its filters as named flags (`--category`, `--actor-id`,
|
|
145
|
+
`--created-after`, …).
|
|
146
|
+
- `--fields id,attributes.email` chooses which columns the human rendering
|
|
147
|
+
shows (dot-paths allowed); an unknown path fails before any request, with the
|
|
148
|
+
available ones in `details.available`; a user's schema-defined `attributes`
|
|
149
|
+
accept any key. `--json` always carries the whole resource regardless.
|
|
150
|
+
- `get <id>` emits the resource as `data`. Its human rendering lays the record
|
|
151
|
+
out field by field on a terminal and prints the whole object when piped;
|
|
152
|
+
`--json` is unchanged either way.
|
|
153
|
+
- `create` / `update <id>` take the body either as one flag per schema field
|
|
154
|
+
(`--name`, `--principal-type`, …; run `<resource> create --help` for the
|
|
155
|
+
list, where required fields are marked `(required)`) or as a whole JSON
|
|
156
|
+
object via `--data '<json>'` / `--file <path>` (`--file -` reads stdin). A
|
|
157
|
+
field flag overrides the same key in `--data`. A user's schema-defined
|
|
158
|
+
`attributes` are set with the repeatable `--attributes`, where `key=value` is
|
|
159
|
+
always a string and `key:=value` parses the value as JSON — use `:=` for a
|
|
160
|
+
field the user schema types as a number, boolean, null, array, or object
|
|
161
|
+
(`--attributes age:=42`), and `=` to keep a numeric-looking identifier a
|
|
162
|
+
string (`--attributes postcode=02139`). A missing
|
|
163
|
+
required field fails with `E_VALIDATION`, naming the flags in `message` and
|
|
164
|
+
listing their wire names in `details.missing`. The body is validated against
|
|
165
|
+
the API schema locally, and the server's resource is emitted as `data`. A create adds
|
|
166
|
+
`data.next_commands` pointing at the matching `get`. `--dry-run` emits
|
|
167
|
+
`{ dry_run: true, verb, topic, body }` without calling the platform.
|
|
168
|
+
- The destructive verb (`delete`, `revoke`, `deactivate`) requires `--force` in non-interactive mode (declared per command, so its help says what it permits)
|
|
169
|
+
(the error's `next_commands` carries the exact retry) and report what the API
|
|
170
|
+
did: `{ id, deleted: true }` for users and grants, `{ id, revoked: true }` for
|
|
171
|
+
sessions, and `{ id, deactivated: true }` for teams, whose DELETE deactivates
|
|
172
|
+
the team and leaves it readable (ADR 024). Read the property that accompanies
|
|
173
|
+
`id` rather than assuming `deleted`.
|
|
174
|
+
|
|
175
|
+
```sh
|
|
176
|
+
npx @zitadel/cli@alpha users list --filter status=active --sort created_at:desc --non-interactive --json
|
|
177
|
+
npx @zitadel/cli@alpha users create --schema sch_… --attributes email=a@b.c --non-interactive --json
|
|
178
|
+
npx @zitadel/cli@alpha sessions revoke sess_… --force --non-interactive --json
|
|
179
|
+
```
|
|
180
|
+
|
|
83
181
|
## Commands
|
|
84
182
|
|
|
183
|
+
The groups below mirror the ones `zitadel --help` prints.
|
|
184
|
+
|
|
185
|
+
### Project commands
|
|
186
|
+
|
|
85
187
|
- `setup` — create a Zitadel project and scaffold local auth (routes,
|
|
86
188
|
middleware, `.zitadel/**`, env templates). Setup writes the versioned local
|
|
87
189
|
default user schema and login flow into
|
|
@@ -144,32 +246,48 @@ the CLI's help layer, not the envelope.
|
|
|
144
246
|
`hero_url`, from `.zitadel/branding/branding.json`; `hero` falls back to
|
|
145
247
|
editable text), and setup warns when a widget-posture app picks `split`
|
|
146
248
|
or `split-right`.
|
|
147
|
-
- `
|
|
148
|
-
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
`
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
249
|
+
- `claim` — claim the project for a team to make it permanent. Mints a
|
|
250
|
+
short-lived link, opens it in a browser, and blocks until the developer
|
|
251
|
+
finishes signing in there, then records `claimed_at` and `team_id` in
|
|
252
|
+
`.zitadel/secret`. Nothing about the project changes: the issuer, users,
|
|
253
|
+
passkeys, and applications keep working, and the project secret is not
|
|
254
|
+
rotated. Re-running once the project belongs to a team is a clean
|
|
255
|
+
`status: "skipped"` with `reason: "already-claimed"`, so agents can retry
|
|
256
|
+
safely. The link is always printed before any browser opens, so a headless
|
|
257
|
+
machine, an SSH session, or `--no-open` needs no special handling — copy it
|
|
258
|
+
and open it anywhere. Links last 10 minutes; once one lapses the command
|
|
259
|
+
exits `E_VALIDATION` and points at a fresh run. Claiming itself is only
|
|
260
|
+
possible within 14 days of project creation: past that the platform answers
|
|
261
|
+
`410 proj.claim_window_expired`, the command exits `E_VALIDATION`, and a
|
|
262
|
+
fresh link does **not** help — only a fresh `setup` yields a claimable
|
|
263
|
+
project (the old one can no longer be claimed; it stays temporary and its
|
|
264
|
+
data may be lost).
|
|
265
|
+
`--dry-run` stops before
|
|
266
|
+
anything is minted and reports `status: "skipped"`, `reason: "dry-run"` —
|
|
267
|
+
there is nothing to preview, because a claim is decided in a browser.
|
|
268
|
+
Flags: `--no-open` (print the link instead of launching a browser),
|
|
269
|
+
`--timeout <seconds>` (stop waiting sooner than the link's own expiry).
|
|
270
|
+
`setup`, `status`, and `doctor` report whether a team is attached, reading
|
|
271
|
+
`claimed_at`/`team_id` from `.zitadel/secret` (no platform call). `status`
|
|
272
|
+
carries `data.project.claim` as
|
|
273
|
+
`{"kind": "detached", "claimable": true, "deadline": "2026-09-18T09:00:00.000Z"}`
|
|
274
|
+
(`claimable` flips to `false` once the locally recorded creation time says
|
|
275
|
+
the 14-day window has passed; the guidance then switches to reconciliation
|
|
276
|
+
wording but the claim command stays in `next_commands`, because the local
|
|
277
|
+
record can be stale and running `claim` answers authoritatively — an
|
|
278
|
+
attached project skips cleanly. `deadline` is omitted when the creation
|
|
279
|
+
time is unknown) or
|
|
280
|
+
`{"kind": "attached", "team_id": "team_01H…", "claimed_at": "2026-08-01T09:00:00.000Z"}`,
|
|
281
|
+
and `doctor` reports a
|
|
282
|
+
`claim` check. A project with no team is only ever a **warning**, never a
|
|
283
|
+
failure — it works exactly like one with a team, so `doctor` still exits 0
|
|
284
|
+
and `--fix` deliberately does nothing (a claim needs a human in a browser).
|
|
285
|
+
`status` and `doctor` stay silent about teams off the cloud: they answer
|
|
286
|
+
offline and cannot know whether a local or self-hosted server hosts a
|
|
287
|
+
platform to claim into. `setup` is online anyway, so against a local server
|
|
288
|
+
it probes the runtime document and nudges only when the server hosts the
|
|
289
|
+
platform plane (`platform.bootstrap_project`), where the claim can actually
|
|
290
|
+
complete.
|
|
173
291
|
- `doctor` — verify generated app files and local state once `zitadel.json`
|
|
174
292
|
exists. The `managed-files` check compares the scaffolded app files against
|
|
175
293
|
the manifest setup recorded in `.zitadel/state.json`: a missing
|
|
@@ -200,34 +318,11 @@ the CLI's help layer, not the envelope.
|
|
|
200
318
|
and are not compared. The repair — an exact-pin install command for the
|
|
201
319
|
project's detected package manager — is emitted in `data.next_commands`
|
|
202
320
|
and quoted in the warning message.
|
|
203
|
-
- `claim` — attach the project to a team so it becomes permanent. Mints a
|
|
204
|
-
short-lived link, opens it in a browser, and blocks until the developer
|
|
205
|
-
finishes signing in there, then records `claimed_at` and `team_id` in
|
|
206
|
-
`.zitadel/secret`. Nothing about the project changes: the issuer, users,
|
|
207
|
-
passkeys, and applications keep working, and the project secret is not
|
|
208
|
-
rotated. Re-running once the project belongs to a team is a clean
|
|
209
|
-
`status: "skipped"` with `reason: "already-claimed"`, so agents can retry
|
|
210
|
-
safely. The link is always printed before any browser opens, so a headless
|
|
211
|
-
machine, an SSH session, or `--no-open` needs no special handling — copy it
|
|
212
|
-
and open it anywhere. Links last 10 minutes; once one lapses the command
|
|
213
|
-
exits `E_VALIDATION` and points at a fresh run. `--dry-run` stops before
|
|
214
|
-
anything is minted and reports `status: "skipped"`, `reason: "dry-run"` —
|
|
215
|
-
there is nothing to preview, because a claim is decided in a browser.
|
|
216
|
-
Flags: `--no-open` (print the link instead of launching a browser),
|
|
217
|
-
`--timeout <seconds>` (stop waiting sooner than the link's own expiry).
|
|
218
|
-
`setup`, `status`, and `doctor` report whether a team is attached, reading
|
|
219
|
-
`claimed_at`/`team_id` from `.zitadel/secret` (no platform call). `status`
|
|
220
|
-
carries `data.project.claim` as `{"kind": "detached"}` or
|
|
221
|
-
`{"kind": "attached", "team_id": "team_01H…", "claimed_at": "2026-08-01T09:00:00.000Z"}`,
|
|
222
|
-
and `doctor` reports a
|
|
223
|
-
`claim` check. A project with no team is only ever a **warning**, never a
|
|
224
|
-
failure — it works exactly like one with a team, so `doctor` still exits 0
|
|
225
|
-
and `--fix` deliberately does nothing (a claim needs a human in a browser).
|
|
226
|
-
All three stay silent about teams when the project's `server` in
|
|
227
|
-
`zitadel.json` is local or self-hosted, where there is nothing to attach.
|
|
228
|
-
- `status` — summarize the local runtime and project state.
|
|
229
321
|
- `eject` (alias `uninstall`) — remove managed files and local Zitadel state;
|
|
230
322
|
requires `--force` when non-interactive.
|
|
323
|
+
|
|
324
|
+
### Local server commands
|
|
325
|
+
|
|
231
326
|
- `start` — start the managed local Zitadel server and persist runtime metadata
|
|
232
327
|
under `.zitadel/local/runtime.json`. The binary runtime defaults to SQLite
|
|
233
328
|
under `.zitadel/local/nextgen-data/`. Runtime metadata reports the published
|
|
@@ -235,11 +330,43 @@ the CLI's help layer, not the envelope.
|
|
|
235
330
|
`dev+<short-commit>` source build it launched. That label names the revision
|
|
236
331
|
the binary was built from, which after a Moon cache hit can be an earlier
|
|
237
332
|
commit whose server sources are byte-identical. Use `--runtime docker` or
|
|
238
|
-
`--image` for the Docker backend.
|
|
333
|
+
`--image` for the Docker backend. The project's env files configure the
|
|
334
|
+
local server: every `NEXTGEN_*` variable in `.env.local` and `.env` (the
|
|
335
|
+
former wins; empty values are skipped) is handed to the runtime through its
|
|
336
|
+
environment only (bare `--env NAME` on Docker), so no value reaches `argv`,
|
|
337
|
+
logs, `runtime.json`, or `--json`. The address, data dir and public base the
|
|
338
|
+
CLI sets itself always win. `data.runtime.env` and `runtime.json` carry
|
|
339
|
+
`injected`, the list of names. A running runtime is not updated in place:
|
|
340
|
+
after changing a value run `stop` then `start`. An unreadable env file fails
|
|
341
|
+
`start` with `E_VALIDATION` before any runtime is stopped. `setup` writes a
|
|
342
|
+
comment saying so at the top of the scaffolded `.env.example` and
|
|
343
|
+
`.env.local`.
|
|
344
|
+
The server boots with the platform project
|
|
345
|
+
and a local admin, so the developer exists on their own server without
|
|
346
|
+
signing up: the admin signs in as `admin@zitadel.localhost`, and a
|
|
347
|
+
generated password is kept in `.zitadel/local/admin.json` (gitignored with
|
|
348
|
+
the rest of `.zitadel/local/`) and never printed. `start` prints a one-time
|
|
349
|
+
console sign-in link and reports it as `data.console.sign_in_url` with
|
|
350
|
+
`data.console.signed_in_as`; if no link can be minted (for example a data
|
|
351
|
+
directory from before the local admin existed), `data.console.error` and
|
|
352
|
+
`data.console.hint` say why, `start` still succeeds, and `zitadel console`
|
|
353
|
+
drops out of `next_commands`. Setting `NEXTGEN_PLATFORM_BOOTSTRAP_PROJECT=false`,
|
|
354
|
+
in the shell or in `.env.local` / `.env`, opts out of both the platform project
|
|
355
|
+
and the local admin, for harnesses that
|
|
356
|
+
want a bare single-project server; `data.console` is then absent.
|
|
357
|
+
- `console` — print (and, interactively, open) a fresh one-time sign-in link
|
|
358
|
+
for the local console as the local admin: `data.sign_in_url`,
|
|
359
|
+
`data.signed_in_as`, `data.browser_opened`. Each link works once; run the
|
|
360
|
+
command again for a new one. The console honours the link only when it is
|
|
361
|
+
served from loopback, since the token signs in whoever opens it. Fails with `E_VALIDATION` when `start` never
|
|
362
|
+
created a local admin in this directory. Flags: `--no-open`.
|
|
239
363
|
- `stop` — stop the managed runtime while preserving
|
|
240
364
|
`.zitadel/local/nextgen-data`. Use `stop --all` to sweep all discovered
|
|
241
365
|
host-wide CLI-managed local runtime processes, including healthy runtimes
|
|
242
366
|
from other local projects; it does not kill arbitrary `/healthz` listeners.
|
|
367
|
+
- `status` — summarize the local runtime and project state.
|
|
368
|
+
`data.server.runtime.env.injected` repeats the variable names recorded at
|
|
369
|
+
the last `start` (empty for a runtime started before this field existed).
|
|
243
370
|
- `logs` — print managed runtime logs; `--follow` streams in human mode.
|
|
244
371
|
- `reset` — stop/remove the managed runtime and delete local runtime data;
|
|
245
372
|
requires `--force` when non-interactive.
|
|
@@ -248,6 +375,63 @@ Alpha releases are fixed product package trains. `npx @zitadel/cli@alpha start`
|
|
|
248
375
|
uses the matching `@zitadel/server` package by default. `zitadel start --runtime
|
|
249
376
|
docker --image <ref>` remains the explicit image override for debugging.
|
|
250
377
|
|
|
378
|
+
### Configuration commands
|
|
379
|
+
|
|
380
|
+
- `plan` — validate config and preview the sync diff without mutating anything.
|
|
381
|
+
- `apply` — validate and upload repo config to the platform.
|
|
382
|
+
- `plan` and `apply --dry-run` also emit `data.warnings`: non-blocking
|
|
383
|
+
findings as `{path, rule, message}`, the same text the human plan prints as
|
|
384
|
+
`# warning:` lines and `apply` prints through stderr. They never fail a run.
|
|
385
|
+
Two families exist today: flow-definition rules (`warn/…`, mirrored from the
|
|
386
|
+
server's validator) and branding asset reachability. `warn/asset-unreachable`
|
|
387
|
+
and `warn/asset-content-type` come from a bounded HEAD probe of
|
|
388
|
+
`logo_url` / `hero_url` — a URL that is well-formed but dead passes every
|
|
389
|
+
gate and then renders as a 0×0 image with nothing in the console, so the
|
|
390
|
+
probe is the only place it can be caught. It is advisory by design: the
|
|
391
|
+
machine planning is not necessarily the machine that renders the login page.
|
|
392
|
+
The probe only contacts public HTTPS destinations and re-checks every
|
|
393
|
+
redirect; loopback/private/internal targets stay inconclusive instead of
|
|
394
|
+
turning repo config into a network request from the planning host.
|
|
395
|
+
Set `ZITADEL_SKIP_ASSET_PROBE` to turn it off (offline, air-gapped CI, or a
|
|
396
|
+
CDN that only resolves from production) and `ZITADEL_ASSET_PROBE_TIMEOUT_MS`
|
|
397
|
+
to retune the per-URL budget (default 2500).
|
|
398
|
+
- In the human-readable plan, a multi-line field (branding's inlined
|
|
399
|
+
`liquid_template`) renders as `(<n> lines, sha256:…)` when it is created or
|
|
400
|
+
unchanged, and as a changed-line diff when it moved — not as one escaped
|
|
401
|
+
line. Read the file itself for full content.
|
|
402
|
+
- `schemas list` — inspect the revision history of a user-schema, filtered by
|
|
403
|
+
`--object-type` (e.g. `human-user`). Non-interactive/`--json` prints one row
|
|
404
|
+
per revision (newest first); interactive adds a picker that fetches and
|
|
405
|
+
pretty-prints the selected revision body.
|
|
406
|
+
- `branding eject` — take ownership of the login template: scaffold
|
|
407
|
+
`.zitadel/branding/` (a `branding.json` descriptor plus the `login.liquid`
|
|
408
|
+
template) from a shipped design, `--design centered|split|split-right|hero|minimal`
|
|
409
|
+
or an interactive picker on a TTY. `plan`/`apply` then publish every edit as
|
|
410
|
+
a new branding revision.
|
|
411
|
+
- `variables list|get|set|delete` — manage the per-environment variables and
|
|
412
|
+
secrets a configuration document references as `${{ NAME }}`. Every command
|
|
413
|
+
addresses one owner: `--environment <name>` (`-e`, alias `--env`) names an
|
|
414
|
+
environment, and `--project-level` names the project level. Owners do not
|
|
415
|
+
inherit from one another — a value set at the project level is **not** seen
|
|
416
|
+
by any environment — so a value a running environment needs must be set on
|
|
417
|
+
that environment, and one needed on several must be set on each. Because of
|
|
418
|
+
that, the owner is never defaulted: with neither flag a person is asked and a
|
|
419
|
+
non-interactive run fails with `E_VALIDATION` naming the project's
|
|
420
|
+
environments, as ADR 035 specifies for `deploy`. `set` takes its value from a
|
|
421
|
+
prompt or from stdin and never from a flag, so a credential never reaches
|
|
422
|
+
`argv`; `--secret` stores it encrypted, after which it can be replaced but
|
|
423
|
+
never read back (`list` reports it as held, and `--json` omits the value key
|
|
424
|
+
entirely). `set --as number|boolean` stores a JSON number or boolean
|
|
425
|
+
instead of a string, so a whole-field `${{ NAME }}` reference resolves to that
|
|
426
|
+
type; it is refused with `--secret`, and an integer too large to store exactly
|
|
427
|
+
is refused rather than rounded. Output follows the resource commands: on a
|
|
428
|
+
pipe, `list` prints tab-separated `name`/`value` rows (a secret's value is
|
|
429
|
+
`(secret)`) and `get` prints the whole record as JSON, which carries no
|
|
430
|
+
`value` key for a secret. There is no `pull` and no bulk import. `set` and
|
|
431
|
+
`delete` honour `--dry-run` and make no change (with no owner flag, a person is still asked,
|
|
432
|
+
which reads the project's environments); `delete` needs `--force` when
|
|
433
|
+
non-interactive.
|
|
434
|
+
|
|
251
435
|
## Golden path
|
|
252
436
|
|
|
253
437
|
```sh
|
|
@@ -316,7 +500,7 @@ then re-run `plan` and `apply`. Schema and flow files are synced from
|
|
|
316
500
|
`.zitadel/schemas/*.json` and `.zitadel/flows/*.json`. Login templates
|
|
317
501
|
(branding) are synced from `.zitadel/branding/`: a single `branding.json`
|
|
318
502
|
descriptor (layout, asset URLs) plus a sibling `login.liquid` LiquidJS
|
|
319
|
-
template referenced
|
|
503
|
+
template referenced as `"liquid_template": { "$file": "./login.liquid" }`. Scaffold them with the
|
|
320
504
|
`branding eject` command (`--design centered|split|split-right|hero|minimal`,
|
|
321
505
|
interactive picker on a TTY) or at project creation with
|
|
322
506
|
`setup --design <name>`, which also publishes revision 1. Branding is
|
|
@@ -329,9 +513,13 @@ validator (`E_VALIDATION` lists rule ids such as `no-script-tag` and
|
|
|
329
513
|
must be absolute `https://`. Keep exactly one descriptor in
|
|
330
514
|
`.zitadel/branding/` — extra `*.json` files there fail the scan.
|
|
331
515
|
Server-provisioned defaults remain a fallback for non-CLI project
|
|
332
|
-
creation, but CLI-created projects are authored from local files first.
|
|
333
|
-
|
|
334
|
-
|
|
516
|
+
creation, but CLI-created projects are authored from local files first. Flows are
|
|
517
|
+
revisioned like branding: an edit plans as a `revise` and `apply` publishes a new
|
|
518
|
+
immutable flow revision; a schema revise re-publishes the flows pinned to it with
|
|
519
|
+
the new `user_schema` in the same run. A login pinned by `flow-name` serves that
|
|
520
|
+
flow's newest revision; an unpinned login serves the newest active unscoped flow
|
|
521
|
+
in the project, whatever its name. Removing a flow file does not retire the
|
|
522
|
+
flow. Managed files carry a marker comment; `eject` removes only
|
|
335
523
|
files that still carry it, preserving anything the user replaced. For app-local
|
|
336
524
|
development, `--server local` resolves through `.zitadel/local/runtime.json` and
|
|
337
525
|
requires a healthy
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/lib/oclif/groups.ts
|
|
2
|
+
/**
|
|
3
|
+
* The groups the root help lists commands under, declared in print order: the
|
|
4
|
+
* journey runs from setting up a project, to running the local server, to
|
|
5
|
+
* managing its configuration, to acting on the resources inside it. Every command declares its own group
|
|
6
|
+
* (`static group` on the class) so nothing has to be registered centrally; a
|
|
7
|
+
* command without one lands in the trailing {@link ADDITIONAL_COMMANDS_GROUP}
|
|
8
|
+
* with oclif's own utilities.
|
|
9
|
+
*/
|
|
10
|
+
const CommandGroups = {
|
|
11
|
+
project: "Project commands",
|
|
12
|
+
localServer: "Local server commands",
|
|
13
|
+
configuration: "Configuration commands",
|
|
14
|
+
resources: "Resource commands"
|
|
15
|
+
};
|
|
16
|
+
const COMMAND_GROUPS = Object.values(CommandGroups);
|
|
17
|
+
/** Where ungrouped commands (oclif's `autocomplete`, `search`, …) are listed. */
|
|
18
|
+
const ADDITIONAL_COMMANDS_GROUP = "Additional commands";
|
|
19
|
+
//#endregion
|
|
20
|
+
export { COMMAND_GROUPS as n, CommandGroups as r, ADDITIONAL_COMMANDS_GROUP as t };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=groups-CMB0fMzE.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"groups-CMB0fMzE.mjs","names":[],"sources":["../src/lib/oclif/groups.ts"],"sourcesContent":["/**\n * The groups the root help lists commands under, declared in print order: the\n * journey runs from setting up a project, to running the local server, to\n * managing its configuration, to acting on the resources inside it. Every command declares its own group\n * (`static group` on the class) so nothing has to be registered centrally; a\n * command without one lands in the trailing {@link ADDITIONAL_COMMANDS_GROUP}\n * with oclif's own utilities.\n */\nexport const CommandGroups = {\n project: \"Project commands\",\n localServer: \"Local server commands\",\n configuration: \"Configuration commands\",\n resources: \"Resource commands\",\n} as const;\n\nexport type CommandGroup = (typeof CommandGroups)[keyof typeof CommandGroups];\n\nexport const COMMAND_GROUPS: readonly CommandGroup[] = Object.values(CommandGroups);\n\n/** Where ungrouped commands (oclif's `autocomplete`, `search`, …) are listed. */\nexport const ADDITIONAL_COMMANDS_GROUP = \"Additional commands\";\n"],"mappings":";;;;;;;;;AAQA,MAAa,gBAAgB;CAC3B,SAAS;CACT,aAAa;CACb,eAAe;CACf,WAAW;CACZ;AAID,MAAa,iBAA0C,OAAO,OAAO,cAAc;;AAGnF,MAAa,4BAA4B"}
|