@zitadel/cli 0.3.0 → 0.4.0

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.
@@ -425,7 +425,7 @@
425
425
  },
426
426
  "message": {
427
427
  "char": "m",
428
- "description": "A short summary of what this release changes.",
428
+ "description": "A short summary of what this release changes. Defaults to the pull request's title or the current commit's subject.",
429
429
  "name": "message",
430
430
  "hasDynamicHelp": false,
431
431
  "multiple": false,
@@ -868,7 +868,8 @@
868
868
  "examples": [
869
869
  "<%= config.bin %> preview",
870
870
  "<%= config.bin %> preview --origin https://acme-git-sso-acmeinc.vercel.app",
871
- "<%= config.bin %> preview --ttl 24h"
871
+ "<%= config.bin %> preview --ttl 24h",
872
+ "<%= config.bin %> preview -m 'add phone_number to human-user'"
872
873
  ],
873
874
  "flags": {
874
875
  "json": {
@@ -961,6 +962,14 @@
961
962
  "multiple": false,
962
963
  "type": "option"
963
964
  },
965
+ "message": {
966
+ "char": "m",
967
+ "description": "A short summary of what this release changes. Defaults to the pull request's title or the current commit's subject.",
968
+ "name": "message",
969
+ "hasDynamicHelp": false,
970
+ "multiple": false,
971
+ "type": "option"
972
+ },
964
973
  "strict": {
965
974
  "description": "Fail instead of warning when no preview credential (ZITADEL_PROJECT_SECRET) is set.",
966
975
  "name": "strict",
@@ -3050,6 +3059,14 @@
3050
3059
  "name": "force",
3051
3060
  "allowNo": false,
3052
3061
  "type": "boolean"
3062
+ },
3063
+ "message": {
3064
+ "char": "m",
3065
+ "description": "A short summary of why this rolls back.",
3066
+ "name": "message",
3067
+ "hasDynamicHelp": false,
3068
+ "multiple": false,
3069
+ "type": "option"
3053
3070
  }
3054
3071
  },
3055
3072
  "hasDynamicHelp": false,
@@ -4157,6 +4174,88 @@
4157
4174
  "strict": true,
4158
4175
  "group": "Configuration and releases"
4159
4176
  },
4177
+ "skills:add": {
4178
+ "aliases": [],
4179
+ "args": {},
4180
+ "description": "Add the Zitadel agent skills to this project.\n\nAdds the skills of this CLI's version to .agents/skills, which most coding agents read, and to .claude/skills for Claude Code. Run it again after updating the CLI to replace them with the new version's.",
4181
+ "examples": [
4182
+ "<%= config.bin %> <%= command.id %>",
4183
+ "<%= config.bin %> <%= command.id %> --cwd my-app"
4184
+ ],
4185
+ "flags": {
4186
+ "json": {
4187
+ "description": "Format output as json.",
4188
+ "helpGroup": "GLOBAL",
4189
+ "name": "json",
4190
+ "allowNo": false,
4191
+ "type": "boolean"
4192
+ },
4193
+ "cwd": {
4194
+ "char": "c",
4195
+ "description": "Project directory to operate on.",
4196
+ "name": "cwd",
4197
+ "hasDynamicHelp": false,
4198
+ "multiple": false,
4199
+ "type": "option"
4200
+ },
4201
+ "server": {
4202
+ "char": "s",
4203
+ "description": "Override the resolved server URL.",
4204
+ "name": "server",
4205
+ "hasDynamicHelp": false,
4206
+ "multiple": false,
4207
+ "type": "option"
4208
+ },
4209
+ "non-interactive": {
4210
+ "char": "n",
4211
+ "description": "Disable prompts. Required when scripting or running as an agent.",
4212
+ "name": "non-interactive",
4213
+ "allowNo": false,
4214
+ "type": "boolean"
4215
+ },
4216
+ "dry-run": {
4217
+ "description": "Preview without mutating files or the platform.",
4218
+ "name": "dry-run",
4219
+ "allowNo": false,
4220
+ "type": "boolean"
4221
+ },
4222
+ "verbose": {
4223
+ "char": "v",
4224
+ "description": "Verbose logging.",
4225
+ "name": "verbose",
4226
+ "allowNo": false,
4227
+ "type": "boolean"
4228
+ },
4229
+ "debug": {
4230
+ "description": "Debug logging.",
4231
+ "name": "debug",
4232
+ "allowNo": false,
4233
+ "type": "boolean"
4234
+ },
4235
+ "color": {
4236
+ "description": "Colorize human output. Disable with --no-color; NO_COLOR and FORCE_COLOR are honored too.",
4237
+ "name": "color",
4238
+ "allowNo": true,
4239
+ "type": "boolean"
4240
+ },
4241
+ "telemetry": {
4242
+ "description": "Send anonymous usage analytics. Disable with --no-telemetry.",
4243
+ "name": "telemetry",
4244
+ "allowNo": true,
4245
+ "type": "boolean"
4246
+ }
4247
+ },
4248
+ "hasDynamicHelp": false,
4249
+ "hiddenAliases": [],
4250
+ "id": "skills:add",
4251
+ "pluginAlias": "@zitadel/cli",
4252
+ "pluginName": "@zitadel/cli",
4253
+ "pluginType": "core",
4254
+ "strict": true,
4255
+ "enableJsonFlag": true,
4256
+ "group": "Getting started",
4257
+ "groupOrder": 5
4258
+ },
4160
4259
  "variable:set": {
4161
4260
  "aliases": [],
4162
4261
  "args": {
@@ -9409,5 +9508,5 @@
9409
9508
  "group": "Configuration and releases"
9410
9509
  }
9411
9510
  },
9412
- "version": "0.3.0"
9511
+ "version": "0.4.0"
9413
9512
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zitadel/cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Agent-friendly Zitadel CLI",
5
5
  "homepage": "https://github.com/zitadel/nextgen/tree/main/apps/cli#readme",
6
6
  "bugs": {
@@ -113,6 +113,9 @@
113
113
  },
114
114
  "api": {
115
115
  "description": "Call any operation of the Zitadel API."
116
+ },
117
+ "skills": {
118
+ "description": "Give coding agents the Zitadel skills."
116
119
  }
117
120
  }
118
121
  },
@@ -127,9 +130,9 @@
127
130
  "@oclif/plugin-search": "^1.2.50",
128
131
  "@oclif/plugin-version": "^2.2.46",
129
132
  "@oclif/plugin-which": "^3.2.55",
130
- "@zitadel/api": "0.3.0",
131
- "@zitadel/config": "0.3.0",
132
- "@zitadel/server": "0.3.0",
133
+ "@zitadel/api": "0.4.0",
134
+ "@zitadel/config": "0.4.0",
135
+ "@zitadel/server": "0.4.0",
133
136
  "ajv": "^8.20.0",
134
137
  "consola": "^3.4.2",
135
138
  "magicast": "^0.5.3",
@@ -148,7 +151,7 @@
148
151
  "@types/wrap-ansi": "^3.0.0",
149
152
  "@vitest/coverage-v8": "^4.1.11",
150
153
  "@zitadel/api-mock": "0.0.0",
151
- "@zitadel/sdk-next": "0.3.0",
154
+ "@zitadel/sdk-next": "0.4.0",
152
155
  "@zitadel/vitest-config": "0.0.0",
153
156
  "msw": "^2.14.6",
154
157
  "oclif": "^4.17.46",
@@ -47,6 +47,13 @@ by declared range or installed release, with `E_UNSUPPORTED_PROJECT_SHAPE`
47
47
  left the project untouched. The message names the minimum and the hint says to
48
48
  upgrade, so upgrade the app and rerun rather than retrying.
49
49
 
50
+ The CLI ships this skill and the other Zitadel skills. `skills add` puts the
51
+ ones of the version that runs it into the project's `.agents/skills/`, and into
52
+ `.claude/skills/` when Claude Code is installed or the project has a `.claude/`
53
+ folder, replacing older copies. After moving the app to a newer CLI, run it
54
+ with that version so the skills describe it. It talks to no server and asks
55
+ nothing; `data.skills` and `data.directories` say what it added where.
56
+
50
57
  ## Using the CLI
51
58
 
52
59
  - **Drive it non-interactively.** Always pass `--non-interactive --json` (short:
@@ -96,6 +103,9 @@ upgrade, so upgrade the app and rerun rather than retrying.
96
103
  `deploy` yourself. `data.deployment` carries the `release_id`,
97
104
  `content_hash`, `deployment_id` and `origins` when a person accepted, and is
98
105
  null otherwise — a failed deploy is a warning, never a failed `env add`.
106
+ `ZITADEL_URL` and `--server` are the server's origin: the API lives under
107
+ `/api/v1` there, which the CLI adds (and drops from a URL that already ends
108
+ in it).
99
109
  - **Origins.** `zitadel origin add <url> --kind primary|preview`, `origin list`
100
110
  and `origin rm <url>` manage the URLs a project serves: a `primary` origin is
101
111
  where the app is served, a `preview` pattern (it may hold a `*`) is where
@@ -137,8 +147,9 @@ upgrade, so upgrade the app and rerun rather than retrying.
137
147
  - **Calling an operation no command covers.** `zitadel api <operation>` calls
138
148
  any operation of the API with the resolved server and `.zitadel/secret`.
139
149
  Name it by its `operationId` (`queryUsers`, as the API reference and
140
- `@zitadel/api` spell it) or by its path (`/users/query`; `-X` picks the
141
- method where a path has several). Path parameters follow as arguments, in
150
+ `@zitadel/api` spell it) or by its path as the spec has it (`/users/query`,
151
+ which the server serves at `/api/v1/users/query`; a path copied with the
152
+ prefix works too, and `-X` picks the method where a path has several). Path parameters follow as arguments, in
142
153
  path order; a `project_id` left out is the project's own. `-F name=value`
143
154
  (or `name:=json`) sets a query parameter when the operation declares one by
144
155
  that name, else a dot path into the body, typed by the operation's schema;
@@ -238,6 +249,15 @@ Each invocation prints one JSON object:
238
249
  `--origin`, which selects targets but never authorizes a preview deploy. A CI
239
250
  build other than Vercel or Netlify must set `ZITADEL_ENV=preview`, or it is
240
251
  skipped too. `preview list` and `preview rm <url>` read and end live previews.
252
+ - `deploy` and `preview` record `-m` on the release and the deployment. Omitted,
253
+ they use a GitHub pull request's title, Vercel's commit message, or a clean
254
+ worktree's commit subject; with none, a non-interactive `deploy` fails. A
255
+ blank `-m` is refused. A release keeps the message of
256
+ the run that first built its content, usually the pull request's `preview`.
257
+ `deployment rollback -m` records why on the rollback.
258
+ - `deployment get <id>` emits the deployment as the API serves it; on a
259
+ terminal it also shows the variables the deployment froze, secrets masked.
260
+ Read them as JSON with `variable resolve`.
241
261
  - `deployment rollback` emits `data.release_id` (the release live again),
242
262
  `data.origins` and `data.pointers`, the `{kind, handle, revision_id}`
243
263
  revisions that release pins; the `schema` one is what new registrations use.
@@ -248,7 +268,8 @@ Each invocation prints one JSON object:
248
268
  shows, against the live release's commit (`diff.against`): `diff.files` holds
249
269
  one `{path, status, previous_path?, patch}` per changed file (`status` is
250
270
  `added`, `modified`, `deleted`, `renamed` or `copied`; `patch` is its unified
251
- diff). Review it before you deploy. `files` is `[]` when nothing changed and
271
+ diff), including rapid same-size edits and untracked configuration files.
272
+ Review it before you deploy. `files` is `[]` when nothing changed and
252
273
  `null` when there is nothing to diff against, with `diff.note` saying why.
253
274
  - A write verb's `--dry-run` reports what it would send without calling the
254
275
  platform, so you can preview a mutation before making it.
@@ -268,13 +289,18 @@ Common error codes point at their own fix in `next_commands`:
268
289
  - `E_LOCAL_SERVER_NOT_RUNNING`: start the local runtime, then retry with
269
290
  `--server local`.
270
291
  - `E_NOT_FOUND`: an HTTP 404 — a missing resource, an operation the server's
271
- version does not have (`details.body.code` is `req.not_found`), or a
292
+ version does not have (`details.body.code` is `req.not_found`; a server
293
+ from before the API moved under `/api/v1` answers every call so), or a
272
294
  `--server` that is not a Zitadel platform API. Follow `next_commands`.
273
295
  - `E_PORT_IN_USE`: the requested local runtime port already has a listener; stop
274
296
  that process or choose another port.
275
297
 
276
298
  In human mode the output follows the terminal (TTY table, or tab-separated lines
277
- when piped or `--plain`); `--json` is unaffected and remains the contract.
299
+ when piped or `--plain`); `--json` is unaffected and remains the contract. A
300
+ human run lists its next steps under `Next:` after its result (`setup` shows
301
+ them in its summary box instead); where stdout is data a script reads (a piped
302
+ or `--plain` list, a resource's created or updated JSON) they go to stderr, so
303
+ stdout holds only that data.
278
304
 
279
305
  Text the server returns is escaped before it is printed, in `--json` as in human
280
306
  mode, so a stored value cannot drive the reader's terminal. Control, format and
@@ -380,20 +406,32 @@ zitadel setup`. A release records the commit it was built from and `deploy`
380
406
  diffs `.zitadel/` against it, so without this the first release carries no
381
407
  commit and the next deploy reports no diff.
382
408
 
409
+ Then setup deploys `.zitadel/` to the app's origin, so the sign-in it asks you
410
+ to verify is served the release it built. `data.deployment` carries the
411
+ `release_id`, `content_hash`, `deployment_id` and `origins`, and is null on
412
+ `--dry-run` or when the deploy failed. A failed deploy is a warning, never a
413
+ failed setup, and `data.next_commands` then leads with the `deploy` that fixes
414
+ it.
415
+
383
416
  Setup refuses with `E_CONFLICT` when the repository already has uncommitted
384
417
  work, untracked files included, which `details.untracked` lists separately
385
418
  from `details.modified`. The commit covers the project directory, so it can
386
- only tell its own files from yours when the tree starts clean. Commit or stash
419
+ only tell its own files from yours when the tree starts clean. It never
420
+ commits `.env*` files (other than `.env.example`), `.zitadel/secret` or
421
+ `.zitadel/local/`, whatever their case. Commit or stash
387
422
  first, then rerun. Only what `start` leaves is exempt: `.zitadel/local/` and
388
423
  the `.gitignore` line that ignores it. A connection under `.zitadel/idps/` is
389
- yours and is not exempt.
424
+ yours and is not exempt. During a merge, rebase, cherry-pick, revert or bisect,
425
+ or on a detached HEAD, setup refuses with `E_CONFLICT` before it writes
426
+ anything, naming what stops the commit.
390
427
 
391
428
  Setup deploys nothing, and it does not need to: a project with no release
392
429
  resolves the newest revisions, which are the ones setup just uploaded, so
393
430
  sign-in already runs on `.zitadel/`. Deploying pins them into a release, which
394
431
  is what the server will require once that fallback goes (#1616). The publish
395
- step says so and names the command. `data.git` reports what setup did
396
- (`initialized`, and the `commit`, or null). `--no-git` skips both the refusal
432
+ step says so and names the command. `data.git` reports what setup did:
433
+ `initialized` when it ran `git init`, even if the commit then failed, and the
434
+ `commit`, or null. `--no-git` skips both the refusal
397
435
  and the commit, and nothing prompts, so this is the same interactively and in
398
436
  CI.
399
437
 
@@ -555,6 +593,21 @@ missing or outdated (after an upgrade that changed a dialect), and
555
593
  `doctor --fix` writes the current ones, unless the project pins a newer
556
594
  `@zitadel/*` version (run that version's `doctor --fix`) or a symlink is on
557
595
  the path; `deploy --dry-run` validates without them either way.
596
+ `deploy`, `preview` and `release create`, `--dry-run` included, check the
597
+ shape of `.zitadel/` locally before anything is written, and fail with
598
+ `E_VALIDATION` listing each problem by field and by the schema's or flow's
599
+ handle (a policy by its file). The server still applies its own release rules
600
+ when the build is submitted, such as handles being unique, so a passing dry run
601
+ does not promise the release is accepted.
602
+
603
+ An SPA's dev proxy (`vite.config.*`, Angular's `proxy.conf.cjs`) keeps the
604
+ app's session in a cookie of its own project, `zitadel_session_<project id>`
605
+ on `http://localhost` and `__Host-zitadel_session_<project id>` over https.
606
+ `doctor` fails (`managed-files`, `outdated managed config wiring`) on the
607
+ session-cookie hooks a CLI wrote before these names: the server no longer
608
+ reads the cookies they keep. `doctor --fix` replaces hooks that are as the CLI
609
+ wrote them; ones changed by hand must be updated by hand, which the failure
610
+ says. Browsers signed in before the change sign in again.
558
611
 
559
612
  ## Claiming a project
560
613