@zitadel/cli 1.0.0-alpha.22 → 1.0.0-alpha.24
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 +2112 -233
- package/SKILLS.md +263 -84
- package/dist/groups-CMB0fMzE.mjs +22 -0
- package/dist/groups-CMB0fMzE.mjs.map +1 -0
- package/dist/index.mjs +15745 -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 +4063 -227
- package/package.json +44 -9
- package/dist/box-B_mwKole.mjs +0 -35
- package/dist/box-B_mwKole.mjs.map +0 -1
- package/dist/branding-DvoH8e0D.mjs +0 -79
- package/dist/branding-DvoH8e0D.mjs.map +0 -1
- package/dist/claim-state-B6ZSKmhW.mjs +0 -125
- package/dist/claim-state-B6ZSKmhW.mjs.map +0 -1
- package/dist/commands/apply.mjs +0 -81
- package/dist/commands/apply.mjs.map +0 -1
- package/dist/commands/branding/eject.mjs +0 -104
- package/dist/commands/branding/eject.mjs.map +0 -1
- package/dist/commands/claim.mjs +0 -445
- package/dist/commands/claim.mjs.map +0 -1
- package/dist/commands/doctor.mjs +0 -1138
- package/dist/commands/doctor.mjs.map +0 -1
- package/dist/commands/eject.mjs +0 -157
- package/dist/commands/eject.mjs.map +0 -1
- package/dist/commands/logs.mjs +0 -58
- package/dist/commands/logs.mjs.map +0 -1
- package/dist/commands/plan.mjs +0 -65
- package/dist/commands/plan.mjs.map +0 -1
- package/dist/commands/reset.mjs +0 -79
- package/dist/commands/reset.mjs.map +0 -1
- package/dist/commands/schemas/list.mjs +0 -146
- package/dist/commands/schemas/list.mjs.map +0 -1
- package/dist/commands/setup.mjs +0 -1309
- package/dist/commands/setup.mjs.map +0 -1
- package/dist/commands/start.mjs +0 -288
- package/dist/commands/start.mjs.map +0 -1
- package/dist/commands/status.mjs +0 -151
- package/dist/commands/status.mjs.map +0 -1
- package/dist/commands/stop.mjs +0 -105
- package/dist/commands/stop.mjs.map +0 -1
- package/dist/designs-Ckz18Dpo.mjs +0 -38
- package/dist/designs-Ckz18Dpo.mjs.map +0 -1
- package/dist/docker-B1MjOMFo.mjs +0 -436
- package/dist/docker-B1MjOMFo.mjs.map +0 -1
- package/dist/environment-fibXmzM8.mjs +0 -17
- package/dist/environment-fibXmzM8.mjs.map +0 -1
- package/dist/journey-guidance-C9MxJNTg.mjs +0 -40
- package/dist/journey-guidance-C9MxJNTg.mjs.map +0 -1
- package/dist/oclif-JlsN1lfO.mjs +0 -1769
- package/dist/oclif-JlsN1lfO.mjs.map +0 -1
- package/dist/orca-CPMHzmg3.mjs +0 -3917
- package/dist/orca-CPMHzmg3.mjs.map +0 -1
- package/dist/package-manager-CDUsoGBy.mjs +0 -194
- package/dist/package-manager-CDUsoGBy.mjs.map +0 -1
- package/dist/ports-hidBnSW-.mjs +0 -116
- package/dist/ports-hidBnSW-.mjs.map +0 -1
- package/dist/processes-Cv19mJ2I.mjs +0 -120
- package/dist/processes-Cv19mJ2I.mjs.map +0 -1
- package/dist/project-Ba0nriNm.mjs +0 -140
- package/dist/project-Ba0nriNm.mjs.map +0 -1
- package/dist/sync-ChlLQ4vZ.mjs +0 -1633
- package/dist/sync-ChlLQ4vZ.mjs.map +0 -1
- package/dist/user-schema-C2mC-JTN.mjs +0 -91
- package/dist/user-schema-C2mC-JTN.mjs.map +0 -1
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
|
|
|
@@ -56,10 +57,10 @@ Each invocation prints one JSON object:
|
|
|
56
57
|
see what setup created versus merged into (your `package.json` is an
|
|
57
58
|
`update`). `data.files_written` remains the flat list — deduplicated file
|
|
58
59
|
paths only, covering both scaffolded and `.zitadel/` resource files.
|
|
59
|
-
- `setup`
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
- `setup` never writes `.zitadel/branding/` or publishes a branding
|
|
61
|
+
revision: the login renders the maintained `<zitadel-login>` component.
|
|
62
|
+
Taking ownership of the widget template is the separate, opt-in
|
|
63
|
+
`branding eject` command.
|
|
63
64
|
- `E_LOCAL_SERVER_NOT_RUNNING`: start the local runtime with
|
|
64
65
|
`npx @zitadel/cli@alpha start`, then retry with `--server local`.
|
|
65
66
|
- `E_NOT_FOUND`: an HTTP 404 from the target server. With the platform's
|
|
@@ -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,14 +104,103 @@ 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`, `--relation`, …; 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
|
|
88
190
|
`.zitadel/schemas/default-human-user.json` and
|
|
89
191
|
`.zitadel/flows/default-login.json`, uploads them through the schema and flow
|
|
90
|
-
APIs, then seeds `.zitadel/state.json` so `plan` is immediately empty.
|
|
192
|
+
APIs, then seeds `.zitadel/state.json` so `plan` is immediately empty.
|
|
193
|
+
Against a local server that hosts the platform project and has a local admin
|
|
194
|
+
(the default `start` configuration), setup also attaches the project to the
|
|
195
|
+
local admin's team: it writes `team_id` and `claimed_at` into
|
|
196
|
+
`.zitadel/secret` and prints
|
|
197
|
+
`Project owned by admin@zitadel.localhost (team ...)`, so a later `claim`
|
|
198
|
+
returns `status: "skipped"` with `reason: "already-claimed"`. The step is
|
|
199
|
+
best-effort. When the attempt fails on a platform-hosting runtime, setup
|
|
200
|
+
warns and the normal claim nudge applies. When `start` opted out of the
|
|
201
|
+
platform bootstrap there is no local admin and no claim surface, so setup
|
|
202
|
+
skips the step silently, emits no nudge, and the project has no owning
|
|
203
|
+
team. Agents
|
|
91
204
|
must pass `--framework` when scaffolding into a fresh directory; interactive
|
|
92
205
|
humans can omit it and choose from the prompt. Supported floors: Next.js 15+
|
|
93
206
|
and React 18+ — `setup` and `doctor` fail with `E_UNSUPPORTED_PROJECT_SHAPE`
|
|
@@ -115,12 +228,9 @@ the CLI's help layer, not the envelope.
|
|
|
115
228
|
email only; `consumer` adds given and family name; `business` also adds a
|
|
116
229
|
`companyName` attribute and overlays work-email copy on the generated auth
|
|
117
230
|
pages via the SDK's `businessLocales`; asked before `--preset` and recorded
|
|
118
|
-
in `zitadel.json`), `--
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
the interactive wizard asks this as its final question with the built-in
|
|
122
|
-
template preselected — omit the flag in non-interactive runs to keep the
|
|
123
|
-
built-in template and no branding files), `--skip-install`.
|
|
231
|
+
in `zitadel.json`), `--skip-install`. Setup does not ask about or apply a
|
|
232
|
+
login design: it writes no `.zitadel/branding/` files and publishes no
|
|
233
|
+
branding revision (`branding eject` is the opt-in for that).
|
|
124
234
|
On Next and Nuxt, the scaffolded auth/profile pages derive their embedding
|
|
125
235
|
posture from the app: a fresh scaffold (setup created the skeleton) pins
|
|
126
236
|
`variant="page"` full-page chrome, while a pre-existing app embeds
|
|
@@ -139,68 +249,9 @@ the CLI's help layer, not the envelope.
|
|
|
139
249
|
link color `--zl-link`); the `suppress-header` attribute
|
|
140
250
|
(wrapper prop `suppressHeader`) visually hides the widget's own heading
|
|
141
251
|
block when the page already carries one, keeping it in the accessibility
|
|
142
|
-
tree.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
editable text), and setup warns when a widget-posture app picks `split`
|
|
146
|
-
or `split-right`.
|
|
147
|
-
- `plan` — validate config and preview the sync diff without mutating anything.
|
|
148
|
-
- `apply` — validate and upload repo config to the platform.
|
|
149
|
-
- `plan` and `apply --dry-run` also emit `data.warnings`: non-blocking
|
|
150
|
-
findings as `{path, rule, message}`, the same text the human plan prints as
|
|
151
|
-
`# warning:` lines and `apply` prints through stderr. They never fail a run.
|
|
152
|
-
Two families exist today: flow-definition rules (`warn/…`, mirrored from the
|
|
153
|
-
server's validator) and branding asset reachability. `warn/asset-unreachable`
|
|
154
|
-
and `warn/asset-content-type` come from a bounded HEAD probe of
|
|
155
|
-
`logo_url` / `hero_url` — a URL that is well-formed but dead passes every
|
|
156
|
-
gate and then renders as a 0×0 image with nothing in the console, so the
|
|
157
|
-
probe is the only place it can be caught. It is advisory by design: the
|
|
158
|
-
machine planning is not necessarily the machine that renders the login page.
|
|
159
|
-
The probe only contacts public HTTPS destinations and re-checks every
|
|
160
|
-
redirect; loopback/private/internal targets stay inconclusive instead of
|
|
161
|
-
turning repo config into a network request from the planning host.
|
|
162
|
-
Set `ZITADEL_SKIP_ASSET_PROBE` to turn it off (offline, air-gapped CI, or a
|
|
163
|
-
CDN that only resolves from production) and `ZITADEL_ASSET_PROBE_TIMEOUT_MS`
|
|
164
|
-
to retune the per-URL budget (default 2500).
|
|
165
|
-
- In the human-readable plan, a multi-line field (branding's inlined
|
|
166
|
-
`liquid_template`) renders as `(<n> lines, sha256:…)` when it is created or
|
|
167
|
-
unchanged, and as a changed-line diff when it moved — not as one escaped
|
|
168
|
-
line. Read the file itself for full content.
|
|
169
|
-
- `schemas list` — inspect the revision history of a user-schema, filtered by
|
|
170
|
-
`--object-type` (e.g. `human-user`). Non-interactive/`--json` prints one row
|
|
171
|
-
per revision (newest first); interactive adds a picker that fetches and
|
|
172
|
-
pretty-prints the selected revision body.
|
|
173
|
-
- `doctor` — verify generated app files and local state once `zitadel.json`
|
|
174
|
-
exists. The `managed-files` check compares the scaffolded app files against
|
|
175
|
-
the manifest setup recorded in `.zitadel/state.json`: a missing
|
|
176
|
-
infrastructure file (the request boundary, `custom-elements.d.ts`) fails,
|
|
177
|
-
a missing generated page warns, and files you edited (marker kept) or
|
|
178
|
-
replaced (marker removed) pass as `edited`/`adopted`. It also verifies the
|
|
179
|
-
managed config wirings (Vite/Nuxt proxy merges, Angular's `angular.json`
|
|
180
|
-
proxy and auth routes) through the patchers' idempotent transforms — a
|
|
181
|
-
detached or missing wiring config fails, an unverifiable one warns, and
|
|
182
|
-
`--fix` re-applies it. The Next/Nuxt `dev` script is verified the same way,
|
|
183
|
-
against the port recorded as the development issuer rather than the port the
|
|
184
|
-
script names today: a script moved off that port reports as an unapplied
|
|
185
|
-
config edit (a warning — a `dev` script is not the only way to choose a
|
|
186
|
-
port), and `--fix` restores the registered one. Boundary migrations converge: a pristine leftover
|
|
187
|
-
`middleware.ts` from a Next 15→16 upgrade is swapped for `proxy.ts`, while
|
|
188
|
-
an edited one is reported as a conflict instead of creating both (Next
|
|
189
|
-
rejects the pair). The default local
|
|
190
|
-
runtime is the `@zitadel/server` npm binary; Docker checks apply only when
|
|
191
|
-
using `--runtime docker` or `--image`. `--fix` restores missing managed
|
|
192
|
-
files and never replaces an existing scaffolded app file; additive repairs
|
|
193
|
-
(missing `.gitignore` entries, `.env.example` keys) still append to their
|
|
194
|
-
targets, and the SDK dependency is re-added only when absent — an existing
|
|
195
|
-
version pin is never rewritten. The `dependency-version` check warns when
|
|
196
|
-
an exactly-pinned `@zitadel/*` dependency does not match the CLI's own
|
|
197
|
-
version (the packages release as one train, and a floating
|
|
198
|
-
`npx @zitadel/cli@alpha` can run ahead of the app's pins); ranges,
|
|
199
|
-
dist-tags, and `file:`/`workspace:` specifiers express a deliberate choice
|
|
200
|
-
and are not compared. The repair — an exact-pin install command for the
|
|
201
|
-
project's detected package manager — is emitted in `data.next_commands`
|
|
202
|
-
and quoted in the warning message.
|
|
203
|
-
- `claim` — attach the project to a team so it becomes permanent. Mints a
|
|
252
|
+
tree. Page layout around the widget (split screens, hero panes) is the
|
|
253
|
+
app's own code, not a Zitadel template.
|
|
254
|
+
- `claim` — claim the project for a team to make it permanent. Mints a
|
|
204
255
|
short-lived link, opens it in a browser, and blocks until the developer
|
|
205
256
|
finishes signing in there, then records `claimed_at` and `team_id` in
|
|
206
257
|
`.zitadel/secret`. Nothing about the project changes: the issuer, users,
|
|
@@ -214,7 +265,8 @@ the CLI's help layer, not the envelope.
|
|
|
214
265
|
possible within 14 days of project creation: past that the platform answers
|
|
215
266
|
`410 proj.claim_window_expired`, the command exits `E_VALIDATION`, and a
|
|
216
267
|
fresh link does **not** help — only a fresh `setup` yields a claimable
|
|
217
|
-
project (the old one
|
|
268
|
+
project (the old one can no longer be claimed; it stays temporary and its
|
|
269
|
+
data may be lost).
|
|
218
270
|
`--dry-run` stops before
|
|
219
271
|
anything is minted and reports `status: "skipped"`, `reason: "dry-run"` —
|
|
220
272
|
there is nothing to preview, because a claim is decided in a browser.
|
|
@@ -241,9 +293,41 @@ the CLI's help layer, not the envelope.
|
|
|
241
293
|
it probes the runtime document and nudges only when the server hosts the
|
|
242
294
|
platform plane (`platform.bootstrap_project`), where the claim can actually
|
|
243
295
|
complete.
|
|
244
|
-
- `
|
|
296
|
+
- `doctor` — verify generated app files and local state once `zitadel.json`
|
|
297
|
+
exists. The `managed-files` check compares the scaffolded app files against
|
|
298
|
+
the manifest setup recorded in `.zitadel/state.json`: a missing
|
|
299
|
+
infrastructure file (the request boundary, `custom-elements.d.ts`) fails,
|
|
300
|
+
a missing generated page warns, and files you edited (marker kept) or
|
|
301
|
+
replaced (marker removed) pass as `edited`/`adopted`. It also verifies the
|
|
302
|
+
managed config wirings (Vite/Nuxt proxy merges, Angular's `angular.json`
|
|
303
|
+
proxy and auth routes) through the patchers' idempotent transforms — a
|
|
304
|
+
detached or missing wiring config fails, an unverifiable one warns, and
|
|
305
|
+
`--fix` re-applies it. The Next/Nuxt `dev` script is verified the same way,
|
|
306
|
+
against the port recorded as the development issuer rather than the port the
|
|
307
|
+
script names today: a script moved off that port reports as an unapplied
|
|
308
|
+
config edit (a warning — a `dev` script is not the only way to choose a
|
|
309
|
+
port), and `--fix` restores the registered one. Boundary migrations converge: a pristine leftover
|
|
310
|
+
`middleware.ts` from a Next 15→16 upgrade is swapped for `proxy.ts`, while
|
|
311
|
+
an edited one is reported as a conflict instead of creating both (Next
|
|
312
|
+
rejects the pair). The default local
|
|
313
|
+
runtime is the `@zitadel/server` npm binary; Docker checks apply only when
|
|
314
|
+
using `--runtime docker` or `--image`. `--fix` restores missing managed
|
|
315
|
+
files and never replaces an existing scaffolded app file; additive repairs
|
|
316
|
+
(missing `.gitignore` entries, `.env.example` keys) still append to their
|
|
317
|
+
targets, and the SDK dependency is re-added only when absent — an existing
|
|
318
|
+
version pin is never rewritten. The `dependency-version` check warns when
|
|
319
|
+
an exactly-pinned `@zitadel/*` dependency does not match the CLI's own
|
|
320
|
+
version (the packages release as one train, and a floating
|
|
321
|
+
`npx @zitadel/cli@alpha` can run ahead of the app's pins); ranges,
|
|
322
|
+
dist-tags, and `file:`/`workspace:` specifiers express a deliberate choice
|
|
323
|
+
and are not compared. The repair — an exact-pin install command for the
|
|
324
|
+
project's detected package manager — is emitted in `data.next_commands`
|
|
325
|
+
and quoted in the warning message.
|
|
245
326
|
- `eject` (alias `uninstall`) — remove managed files and local Zitadel state;
|
|
246
327
|
requires `--force` when non-interactive.
|
|
328
|
+
|
|
329
|
+
### Local server commands
|
|
330
|
+
|
|
247
331
|
- `start` — start the managed local Zitadel server and persist runtime metadata
|
|
248
332
|
under `.zitadel/local/runtime.json`. The binary runtime defaults to SQLite
|
|
249
333
|
under `.zitadel/local/nextgen-data/`. Runtime metadata reports the published
|
|
@@ -251,11 +335,43 @@ the CLI's help layer, not the envelope.
|
|
|
251
335
|
`dev+<short-commit>` source build it launched. That label names the revision
|
|
252
336
|
the binary was built from, which after a Moon cache hit can be an earlier
|
|
253
337
|
commit whose server sources are byte-identical. Use `--runtime docker` or
|
|
254
|
-
`--image` for the Docker backend.
|
|
338
|
+
`--image` for the Docker backend. The project's env files configure the
|
|
339
|
+
local server: every `NEXTGEN_*` variable in `.env.local` and `.env` (the
|
|
340
|
+
former wins; empty values are skipped) is handed to the runtime through its
|
|
341
|
+
environment only (bare `--env NAME` on Docker), so no value reaches `argv`,
|
|
342
|
+
logs, `runtime.json`, or `--json`. The address, data dir and public base the
|
|
343
|
+
CLI sets itself always win. `data.runtime.env` and `runtime.json` carry
|
|
344
|
+
`injected`, the list of names. A running runtime is not updated in place:
|
|
345
|
+
after changing a value run `stop` then `start`. An unreadable env file fails
|
|
346
|
+
`start` with `E_VALIDATION` before any runtime is stopped. `setup` writes a
|
|
347
|
+
comment saying so at the top of the scaffolded `.env.example` and
|
|
348
|
+
`.env.local`.
|
|
349
|
+
The server boots with the platform project
|
|
350
|
+
and a local admin, so the developer exists on their own server without
|
|
351
|
+
signing up: the admin signs in as `admin@zitadel.localhost`, and a
|
|
352
|
+
generated password is kept in `.zitadel/local/admin.json` (gitignored with
|
|
353
|
+
the rest of `.zitadel/local/`) and never printed. `start` prints a one-time
|
|
354
|
+
console sign-in link and reports it as `data.console.sign_in_url` with
|
|
355
|
+
`data.console.signed_in_as`; if no link can be minted (for example a data
|
|
356
|
+
directory from before the local admin existed), `data.console.error` and
|
|
357
|
+
`data.console.hint` say why, `start` still succeeds, and `zitadel console`
|
|
358
|
+
drops out of `next_commands`. Setting `NEXTGEN_PLATFORM_BOOTSTRAP_PROJECT=false`,
|
|
359
|
+
in the shell or in `.env.local` / `.env`, opts out of both the platform project
|
|
360
|
+
and the local admin, for harnesses that
|
|
361
|
+
want a bare single-project server; `data.console` is then absent.
|
|
362
|
+
- `console` — print (and, interactively, open) a fresh one-time sign-in link
|
|
363
|
+
for the local console as the local admin: `data.sign_in_url`,
|
|
364
|
+
`data.signed_in_as`, `data.browser_opened`. Each link works once; run the
|
|
365
|
+
command again for a new one. The console honours the link only when it is
|
|
366
|
+
served from loopback, since the token signs in whoever opens it. Fails with `E_VALIDATION` when `start` never
|
|
367
|
+
created a local admin in this directory. Flags: `--no-open`.
|
|
255
368
|
- `stop` — stop the managed runtime while preserving
|
|
256
369
|
`.zitadel/local/nextgen-data`. Use `stop --all` to sweep all discovered
|
|
257
370
|
host-wide CLI-managed local runtime processes, including healthy runtimes
|
|
258
371
|
from other local projects; it does not kill arbitrary `/healthz` listeners.
|
|
372
|
+
- `status` — summarize the local runtime and project state.
|
|
373
|
+
`data.server.runtime.env.injected` repeats the variable names recorded at
|
|
374
|
+
the last `start` (empty for a runtime started before this field existed).
|
|
259
375
|
- `logs` — print managed runtime logs; `--follow` streams in human mode.
|
|
260
376
|
- `reset` — stop/remove the managed runtime and delete local runtime data;
|
|
261
377
|
requires `--force` when non-interactive.
|
|
@@ -264,6 +380,66 @@ Alpha releases are fixed product package trains. `npx @zitadel/cli@alpha start`
|
|
|
264
380
|
uses the matching `@zitadel/server` package by default. `zitadel start --runtime
|
|
265
381
|
docker --image <ref>` remains the explicit image override for debugging.
|
|
266
382
|
|
|
383
|
+
### Configuration commands
|
|
384
|
+
|
|
385
|
+
- `plan` — validate config and preview the sync diff without mutating anything.
|
|
386
|
+
- `apply` — validate and upload repo config to the platform.
|
|
387
|
+
- `plan` and `apply --dry-run` also emit `data.warnings`: non-blocking
|
|
388
|
+
findings as `{path, rule, message}`, the same text the human plan prints as
|
|
389
|
+
`# warning:` lines and `apply` prints through stderr. They never fail a run.
|
|
390
|
+
Two families exist today: flow-definition rules (`warn/…`, mirrored from the
|
|
391
|
+
server's validator) and branding asset reachability. `warn/asset-unreachable`
|
|
392
|
+
and `warn/asset-content-type` come from a bounded HEAD probe of
|
|
393
|
+
`logo_url` / `hero_url` — a URL that is well-formed but dead passes every
|
|
394
|
+
gate and then renders as a 0×0 image with nothing in the console, so the
|
|
395
|
+
probe is the only place it can be caught. It is advisory by design: the
|
|
396
|
+
machine planning is not necessarily the machine that renders the login page.
|
|
397
|
+
The probe only contacts public HTTPS destinations and re-checks every
|
|
398
|
+
redirect; loopback/private/internal targets stay inconclusive instead of
|
|
399
|
+
turning repo config into a network request from the planning host.
|
|
400
|
+
Set `ZITADEL_SKIP_ASSET_PROBE` to turn it off (offline, air-gapped CI, or a
|
|
401
|
+
CDN that only resolves from production) and `ZITADEL_ASSET_PROBE_TIMEOUT_MS`
|
|
402
|
+
to retune the per-URL budget (default 2500).
|
|
403
|
+
- In the human-readable plan, a multi-line field (branding's inlined
|
|
404
|
+
`liquid_template`) renders as `(<n> lines, sha256:…)` when it is created or
|
|
405
|
+
unchanged, and as a changed-line diff when it moved — not as one escaped
|
|
406
|
+
line. Read the file itself for full content.
|
|
407
|
+
- No command takes `--environment` (`-e`, `--env`). `plan`, `apply` and the
|
|
408
|
+
resource commands work on the project's resources and never selected an
|
|
409
|
+
environment; `variables` names its owner with `--project-level`. The flag
|
|
410
|
+
returns when the platform's environments settle, and `deploy` (ADR 035) is
|
|
411
|
+
what will put config onto one.
|
|
412
|
+
- `schemas list` — inspect the revision history of a user-schema, filtered by
|
|
413
|
+
`--object-type` (e.g. `human-user`). Non-interactive/`--json` prints one row
|
|
414
|
+
per revision (newest first); interactive adds a picker that fetches and
|
|
415
|
+
pretty-prints the selected revision body.
|
|
416
|
+
- `branding eject` — take ownership of the login template: scaffold
|
|
417
|
+
`.zitadel/branding/` (a `branding.json` descriptor plus the `login.liquid`
|
|
418
|
+
template) from a shipped design, `--design centered|minimal` (the default card, or
|
|
419
|
+
the same form without card chrome) or an interactive picker on a TTY. `plan`/`apply` then publish every edit as
|
|
420
|
+
a new branding revision.
|
|
421
|
+
- `variables list|get|set|delete` — manage the variables and secrets a
|
|
422
|
+
configuration document references as `${{ NAME }}`. Every command addresses
|
|
423
|
+
one owner, and `--project-level` is the only one the CLI can name today, so it
|
|
424
|
+
is **required**: a run without it fails with `E_VALIDATION`, on a terminal as
|
|
425
|
+
in a script. The platform also keeps variables per environment, but the CLI
|
|
426
|
+
cannot address those until the platform's environments settle; `--environment`
|
|
427
|
+
returns then, and every command written today keeps its meaning because the
|
|
428
|
+
owner was named rather than assumed. Owners do not inherit from one another —
|
|
429
|
+
a value entered at the project level is **not** seen by an environment
|
|
430
|
+
(ADR 062 §4). `set` takes its value from a prompt or from stdin and never from
|
|
431
|
+
a flag, so a credential never reaches `argv`; `--secret` stores it encrypted,
|
|
432
|
+
after which it can be replaced but never read back (`list` reports it as held,
|
|
433
|
+
and `--json` omits the value key entirely). `set --as number|boolean` stores a
|
|
434
|
+
JSON number or boolean instead of a string, so a whole-field `${{ NAME }}`
|
|
435
|
+
reference resolves to that type; it is refused with `--secret`, and an integer
|
|
436
|
+
too large to store exactly is refused rather than rounded. Output follows the
|
|
437
|
+
resource commands: on a pipe, `list` prints tab-separated `name`/`value` rows
|
|
438
|
+
(a secret's value is `(secret)`) and `get` prints the whole record as JSON,
|
|
439
|
+
which carries no `value` key for a secret. There is no `pull` and no bulk
|
|
440
|
+
import. `set` and `delete` honour `--dry-run` and make no change; `delete`
|
|
441
|
+
needs `--force` when non-interactive.
|
|
442
|
+
|
|
267
443
|
## Golden path
|
|
268
444
|
|
|
269
445
|
```sh
|
|
@@ -332,10 +508,9 @@ then re-run `plan` and `apply`. Schema and flow files are synced from
|
|
|
332
508
|
`.zitadel/schemas/*.json` and `.zitadel/flows/*.json`. Login templates
|
|
333
509
|
(branding) are synced from `.zitadel/branding/`: a single `branding.json`
|
|
334
510
|
descriptor (layout, asset URLs) plus a sibling `login.liquid` LiquidJS
|
|
335
|
-
template referenced
|
|
336
|
-
`branding eject` command (`--design centered|
|
|
337
|
-
interactive picker on a TTY)
|
|
338
|
-
`setup --design <name>`, which also publishes revision 1. Branding is
|
|
511
|
+
template referenced as `"liquid_template": { "$file": "./login.liquid" }`. Scaffold them with the
|
|
512
|
+
`branding eject` command (`--design centered|minimal`,
|
|
513
|
+
interactive picker on a TTY); setup never scaffolds them. Branding is
|
|
339
514
|
revisioned and immutable: every edit — including a `.liquid`-only edit —
|
|
340
515
|
plans as a `revise` and `apply` publishes a new revision; the login serves
|
|
341
516
|
the newest one. `plan` validates templates with the authoritative LiquidJS
|
|
@@ -345,9 +520,13 @@ validator (`E_VALIDATION` lists rule ids such as `no-script-tag` and
|
|
|
345
520
|
must be absolute `https://`. Keep exactly one descriptor in
|
|
346
521
|
`.zitadel/branding/` — extra `*.json` files there fail the scan.
|
|
347
522
|
Server-provisioned defaults remain a fallback for non-CLI project
|
|
348
|
-
creation, but CLI-created projects are authored from local files first.
|
|
349
|
-
|
|
350
|
-
|
|
523
|
+
creation, but CLI-created projects are authored from local files first. Flows are
|
|
524
|
+
revisioned like branding: an edit plans as a `revise` and `apply` publishes a new
|
|
525
|
+
immutable flow revision; a schema revise re-publishes the flows pinned to it with
|
|
526
|
+
the new `user_schema` in the same run. A login pinned by `flow-name` serves that
|
|
527
|
+
flow's newest revision; an unpinned login serves the newest active unscoped flow
|
|
528
|
+
in the project, whatever its name. Removing a flow file does not retire the
|
|
529
|
+
flow. Managed files carry a marker comment; `eject` removes only
|
|
351
530
|
files that still carry it, preserving anything the user replaced. For app-local
|
|
352
531
|
development, `--server local` resolves through `.zitadel/local/runtime.json` and
|
|
353
532
|
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"}
|