@zitadel/cli 0.1.0-alpha.15 → 0.1.0-alpha.17

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 (43) hide show
  1. package/README.md +2 -2
  2. package/SKILLS.md +25 -7
  3. package/dist/commands/apply.mjs +13 -6
  4. package/dist/commands/apply.mjs.map +1 -1
  5. package/dist/commands/doctor.mjs +5 -6
  6. package/dist/commands/doctor.mjs.map +1 -1
  7. package/dist/commands/eject.mjs +17 -5
  8. package/dist/commands/eject.mjs.map +1 -1
  9. package/dist/commands/logs.mjs +2 -2
  10. package/dist/commands/plan.mjs +8 -4
  11. package/dist/commands/plan.mjs.map +1 -1
  12. package/dist/commands/reset.mjs +2 -2
  13. package/dist/commands/schemas/list.mjs +9 -5
  14. package/dist/commands/schemas/list.mjs.map +1 -1
  15. package/dist/commands/setup.mjs +153 -117
  16. package/dist/commands/setup.mjs.map +1 -1
  17. package/dist/commands/start.mjs +3 -4
  18. package/dist/commands/start.mjs.map +1 -1
  19. package/dist/commands/status.mjs +40 -9
  20. package/dist/commands/status.mjs.map +1 -1
  21. package/dist/commands/stop.mjs +2 -2
  22. package/dist/{docker-D7BSD5C9.mjs → docker-pGcTrDIY.mjs} +2 -2
  23. package/dist/{docker-D7BSD5C9.mjs.map → docker-pGcTrDIY.mjs.map} +1 -1
  24. package/dist/journey-guidance-CYVpQszz.mjs +29 -0
  25. package/dist/journey-guidance-CYVpQszz.mjs.map +1 -0
  26. package/dist/{oclif-Bm-FkF6z.mjs → oclif-BRdjVNne.mjs} +37 -36
  27. package/dist/oclif-BRdjVNne.mjs.map +1 -0
  28. package/dist/{orca-CpXj_XsA.mjs → orca-Dip6DPJ2.mjs} +209 -163
  29. package/dist/orca-Dip6DPJ2.mjs.map +1 -0
  30. package/dist/{ports-CxBKS1ga.mjs → ports-V8JfiNgT.mjs} +25 -20
  31. package/dist/ports-V8JfiNgT.mjs.map +1 -0
  32. package/dist/{project-Dk7V0xka.mjs → project-BGgv7Bba.mjs} +2 -2
  33. package/dist/{project-Dk7V0xka.mjs.map → project-BGgv7Bba.mjs.map} +1 -1
  34. package/dist/{sync-CYuHVQT5.mjs → sync-Cd3z7Q1R.mjs} +226 -31
  35. package/dist/sync-Cd3z7Q1R.mjs.map +1 -0
  36. package/oclif.manifest.json +12 -1
  37. package/package.json +6 -6
  38. package/dist/docker-guidance-mcTT3_0E.mjs +0 -21
  39. package/dist/docker-guidance-mcTT3_0E.mjs.map +0 -1
  40. package/dist/oclif-Bm-FkF6z.mjs.map +0 -1
  41. package/dist/orca-CpXj_XsA.mjs.map +0 -1
  42. package/dist/ports-CxBKS1ga.mjs.map +0 -1
  43. package/dist/sync-CYuHVQT5.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
- import { t as BaseCommand } from "../../oclif-Bm-FkF6z.mjs";
2
- import { o as readZitadelSecret } from "../../project-Dk7V0xka.mjs";
1
+ import { t as BaseCommand } from "../../oclif-BRdjVNne.mjs";
2
+ import { o as readZitadelSecret } from "../../project-BGgv7Bba.mjs";
3
3
  import { t as environmentSchema } from "../../environment-BQF7LeCz.mjs";
4
4
  import { cancel, isCancel, select, spinner } from "@clack/prompts";
5
5
  import { Flags } from "@oclif/core";
@@ -45,6 +45,10 @@ var SchemasList = class SchemasList extends BaseCommand {
45
45
  project_id: secret.project_id,
46
46
  object_type: objectType
47
47
  });
48
+ const revisionRows = revisions.map((r) => ({
49
+ id: r.id,
50
+ created_at: r.createdAt
51
+ }));
48
52
  if (revisions.length === 0) {
49
53
  const message = `No revisions found for objectType "${objectType}".`;
50
54
  consola$1.warn(message);
@@ -62,7 +66,7 @@ var SchemasList = class SchemasList extends BaseCommand {
62
66
  status: "ok",
63
67
  data: {
64
68
  object_type: objectType,
65
- revisions,
69
+ revisions: revisionRows,
66
70
  count: revisions.length
67
71
  },
68
72
  pretty: renderTable(objectType, revisions)
@@ -80,7 +84,7 @@ var SchemasList = class SchemasList extends BaseCommand {
80
84
  status: "ok",
81
85
  data: {
82
86
  object_type: objectType,
83
- revisions,
87
+ revisions: revisionRows,
84
88
  count: revisions.length
85
89
  },
86
90
  pretty: ""
@@ -95,7 +99,7 @@ var SchemasList = class SchemasList extends BaseCommand {
95
99
  status: "ok",
96
100
  data: {
97
101
  object_type: objectType,
98
- revisions,
102
+ revisions: revisionRows,
99
103
  selected: {
100
104
  id: picked,
101
105
  body
@@ -1 +1 @@
1
- {"version":3,"file":"list.mjs","names":[],"sources":["../../../src/commands/schemas/list.ts"],"sourcesContent":["import { cancel, isCancel, select, spinner } from \"@clack/prompts\";\nimport { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient, type ZitadelClient } from \"@zitadel/api/client\";\nimport type { ListSchemas200Item } from \"@zitadel/api/generated/model\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { environmentSchema } from \"../../lib/environment\";\nimport { readZitadelSecret } from \"../../lib/project\";\n\n/**\n * The `schemas list` topic command — inspect the revision history of a\n * user-schema, filtered by `objectType`.\n *\n * Non-interactive: prints one row per revision (newest first) as a JSON payload\n * or a plain-text table. Interactive: renders a `@clack/prompts` `select` menu\n * of the same rows; on selection, fetches the full schema body via\n * `getSchemaById` and pretty-prints it to stdout.\n */\nexport default class SchemasList extends BaseCommand {\n static override description = \"List revisions of a user-schema by objectType.\";\n static override flags = {\n \"object-type\": Flags.string({\n char: \"t\",\n required: true,\n description: \"Filter revisions by objectType (e.g. human-user).\",\n }),\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(SchemasList);\n await this.toMeta(flags);\n const { cwd, source, nonInteractive } = 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\n const objectType = flags[\"object-type\"];\n const revisions = await client.listSchemas({\n project_id: secret.project_id,\n object_type: objectType,\n });\n\n if (revisions.length === 0) {\n const message = `No revisions found for objectType \"${objectType}\".`;\n consola.warn(message);\n return this.emit({\n status: \"ok\",\n data: { object_type: objectType, revisions: [], count: 0 },\n pretty: message,\n });\n }\n\n // Server orders newest-first; the interactive picker inherits that order.\n if (nonInteractive) {\n return this.emit({\n status: \"ok\",\n data: {\n object_type: objectType,\n revisions,\n count: revisions.length,\n },\n pretty: renderTable(objectType, revisions),\n });\n }\n\n const picked = await select({\n message: `Revisions of objectType \"${objectType}\" (newest first)`,\n options: revisions.map((r, idx) => ({\n value: r.id,\n label: `${r.createdAt} ${r.id}${idx === 0 ? \" (latest)\" : \"\"}`,\n })),\n });\n if (isCancel(picked)) {\n cancel(\"No revision selected.\");\n return this.emit({\n status: \"ok\",\n data: { object_type: objectType, revisions, count: revisions.length },\n pretty: \"\",\n });\n }\n\n const s = spinner();\n s.start(`Loading ${String(picked)}…`);\n const body = await fetchSchemaRevision(client, String(picked), secret.project_id);\n s.stop(`Loaded ${String(picked)}`);\n\n const pretty = JSON.stringify(body, null, 2);\n\n return this.emit({\n status: \"ok\",\n data: {\n object_type: objectType,\n revisions,\n selected: { id: picked, body },\n count: revisions.length,\n },\n pretty,\n });\n }\n}\n\n/**\n * Fetch one schema revision body. The id is URL-encoded before it lands in\n * the path: server-allocated ids are opaque today (`sch_…`), but ids can be\n * full URLs when a schema carried an `$id` (the server-seeded defaults do),\n * and an unencoded URL would break the `/schemas/:id` path. Mirrors the\n * encoding the sync engine's schema syncer applies.\n */\nexport async function fetchSchemaRevision(\n client: ZitadelClient,\n id: string,\n projectId: string,\n): Promise<unknown> {\n return client.getSchemaById(encodeURIComponent(id), { project_id: projectId });\n}\n\nfunction renderTable(objectType: string, revisions: ReadonlyArray<ListSchemas200Item>): string {\n const header = `Revisions of objectType \"${objectType}\" (${revisions.length}, newest first)`;\n const idCol = Math.max(\"id\".length, ...revisions.map((r) => r.id.length));\n const createdCol = Math.max(\"createdAt\".length, ...revisions.map((r) => r.createdAt.length));\n const rows = revisions.map(\n (r) => `${r.createdAt.padEnd(createdCol)} ${r.id.padEnd(idCol)}`,\n );\n return [\n header,\n `${\"createdAt\".padEnd(createdCol)} ${\"id\".padEnd(idCol)}`,\n `${\"-\".repeat(createdCol)} ${\"-\".repeat(idCol)}`,\n ...rows,\n ].join(\"\\n\");\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"list.mjs","names":[],"sources":["../../../src/commands/schemas/list.ts"],"sourcesContent":["import { cancel, isCancel, select, spinner } from \"@clack/prompts\";\nimport { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient, type ZitadelClient } from \"@zitadel/api/client\";\nimport type { ListSchemas200Item } from \"@zitadel/api/generated/model\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../../lib/oclif\";\nimport { environmentSchema } from \"../../lib/environment\";\nimport { readZitadelSecret } from \"../../lib/project\";\n\n/**\n * The `schemas list` topic command — inspect the revision history of a\n * user-schema, filtered by `objectType`.\n *\n * Non-interactive: prints one row per revision (newest first) as a JSON payload\n * or a plain-text table. Interactive: renders a `@clack/prompts` `select` menu\n * of the same rows; on selection, fetches the full schema body via\n * `getSchemaById` and pretty-prints it to stdout.\n */\nexport default class SchemasList extends BaseCommand {\n static override description = \"List revisions of a user-schema by objectType.\";\n static override flags = {\n \"object-type\": Flags.string({\n char: \"t\",\n required: true,\n description: \"Filter revisions by objectType (e.g. human-user).\",\n }),\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(SchemasList);\n await this.toMeta(flags);\n const { cwd, source, nonInteractive } = 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\n const objectType = flags[\"object-type\"];\n const revisions = await client.listSchemas({\n project_id: secret.project_id,\n object_type: objectType,\n });\n\n // Envelope rows are snake_case like every other command's data; the\n // orval model's `createdAt` is not spread verbatim.\n const revisionRows = revisions.map((r) => ({ id: r.id, created_at: r.createdAt }));\n\n if (revisions.length === 0) {\n const message = `No revisions found for objectType \"${objectType}\".`;\n consola.warn(message);\n return this.emit({\n status: \"ok\",\n data: { object_type: objectType, revisions: [], count: 0 },\n pretty: message,\n });\n }\n\n // Server orders newest-first; the interactive picker inherits that order.\n if (nonInteractive) {\n return this.emit({\n status: \"ok\",\n data: {\n object_type: objectType,\n revisions: revisionRows,\n count: revisions.length,\n },\n pretty: renderTable(objectType, revisions),\n });\n }\n\n const picked = await select({\n message: `Revisions of objectType \"${objectType}\" (newest first)`,\n options: revisions.map((r, idx) => ({\n value: r.id,\n label: `${r.createdAt} ${r.id}${idx === 0 ? \" (latest)\" : \"\"}`,\n })),\n });\n if (isCancel(picked)) {\n cancel(\"No revision selected.\");\n return this.emit({\n status: \"ok\",\n data: { object_type: objectType, revisions: revisionRows, count: revisions.length },\n pretty: \"\",\n });\n }\n\n const s = spinner();\n s.start(`Loading ${String(picked)}…`);\n const body = await fetchSchemaRevision(client, String(picked), secret.project_id);\n s.stop(`Loaded ${String(picked)}`);\n\n const pretty = JSON.stringify(body, null, 2);\n\n return this.emit({\n status: \"ok\",\n data: {\n object_type: objectType,\n revisions: revisionRows,\n selected: { id: picked, body },\n count: revisions.length,\n },\n pretty,\n });\n }\n}\n\n/**\n * Fetch one schema revision body. The id is URL-encoded before it lands in\n * the path: server-allocated ids are opaque today (`sch_…`), but ids can be\n * full URLs when a schema carried an `$id` (the server-seeded defaults do),\n * and an unencoded URL would break the `/schemas/:id` path. Mirrors the\n * encoding the sync engine's schema syncer applies.\n */\nexport async function fetchSchemaRevision(\n client: ZitadelClient,\n id: string,\n projectId: string,\n): Promise<unknown> {\n return client.getSchemaById(encodeURIComponent(id), { project_id: projectId });\n}\n\nfunction renderTable(objectType: string, revisions: ReadonlyArray<ListSchemas200Item>): string {\n const header = `Revisions of objectType \"${objectType}\" (${revisions.length}, newest first)`;\n const idCol = Math.max(\"id\".length, ...revisions.map((r) => r.id.length));\n const createdCol = Math.max(\"createdAt\".length, ...revisions.map((r) => r.createdAt.length));\n const rows = revisions.map(\n (r) => `${r.createdAt.padEnd(createdCol)} ${r.id.padEnd(idCol)}`,\n );\n return [\n header,\n `${\"createdAt\".padEnd(createdCol)} ${\"id\".padEnd(idCol)}`,\n `${\"-\".repeat(createdCol)} ${\"-\".repeat(idCol)}`,\n ...rows,\n ].join(\"\\n\");\n}\n"],"mappings":"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"}
@@ -1,17 +1,17 @@
1
- import { D as toZitadelError, E as ZitadelError, T as stableStringify, b as publicCliCommand, n as DEFAULT_SERVER, t as BaseCommand } from "../oclif-Bm-FkF6z.mjs";
2
- import { i as issuerFromPort, n as inspectScaffoldTarget, r as RENDERER_IDS, t as createOrca } from "../orca-CpXj_XsA.mjs";
3
- import { n as hasZitadelSecret, t as hasZitadelConfig } from "../project-Dk7V0xka.mjs";
4
- import { i as hashForState, l as FLOWS_DIR, o as writeBackResource, s as updateState } from "../sync-CYuHVQT5.mjs";
1
+ import { D as ZitadelError, E as stableStringify, O as toZitadelError, n as DEFAULT_SERVER, t as BaseCommand, u as detectHealthyLocalServer, x as publicCliCommand } from "../oclif-BRdjVNne.mjs";
2
+ import { n as inspectScaffoldTarget, o as issuerFromPort, r as RENDERER_IDS, t as createOrca } from "../orca-Dip6DPJ2.mjs";
3
+ import { n as hasZitadelSecret, t as hasZitadelConfig } from "../project-BGgv7Bba.mjs";
4
+ import { c as writeBackResource, d as FLOWS_DIR, l as updateState, o as hashForState } from "../sync-Cd3z7Q1R.mjs";
5
5
  import { t as SCHEMAS_DIR } from "../user-schema-DDz5-lX5.mjs";
6
- import { t as listListeningPorts } from "../ports-CxBKS1ga.mjs";
6
+ import { n as verifyLoginAction, t as customizeAndPublishActions } from "../journey-guidance-CYVpQszz.mjs";
7
7
  import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
8
8
  import { basename, dirname, join } from "node:path";
9
9
  import { cancel, confirm, intro, isCancel, outro, select, spinner, text } from "@clack/prompts";
10
10
  import { Flags } from "@oclif/core";
11
11
  import { createZitadelClient } from "@zitadel/api/client";
12
+ import { DEFAULT_FLOW_CONFIG_PATH, DEFAULT_FLOW_SCHEMA_URI, DEFAULT_SCHEMA_CONFIG_PATH, DEFAULT_SETUP_PRESET, SETUP_PRESETS, flowsReadmeContent, getDefaultHumanUserSchema, getDefaultLoginFlow, schemasReadmeContent } from "@zitadel/config/defaults";
12
13
  import { consola as consola$1 } from "consola";
13
14
  import { spawn } from "node:child_process";
14
- import { DEFAULT_FLOW_CONFIG_PATH, DEFAULT_FLOW_SCHEMA_URI, DEFAULT_SCHEMA_CONFIG_PATH, flowsReadmeContent, getDefaultHumanUserSchema, getDefaultLoginFlow, schemasReadmeContent } from "@zitadel/config/defaults";
15
15
  import { normalizeFlowBody, normalizeSchemaBody } from "@zitadel/config/normalize";
16
16
  import pc from "picocolors";
17
17
  //#region src/lib/setup-resources.ts
@@ -30,7 +30,8 @@ async function materializeSetupResources(opts) {
30
30
  await mkdir(join(opts.cwd, FLOWS_DIR), { recursive: true });
31
31
  await mkdir(join(opts.cwd, SCHEMAS_DIR), { recursive: true });
32
32
  const filesWritten = [];
33
- const { $id: _templateId, ...schemaBody } = getDefaultHumanUserSchema();
33
+ const preset = opts.preset ?? DEFAULT_SETUP_PRESET;
34
+ const { $id: _templateId, ...schemaBody } = getDefaultHumanUserSchema({ preset });
34
35
  if (await writeResourceFile(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH, schemaBody, opts.force)) filesWritten.push(join(opts.cwd, DEFAULT_SCHEMA_CONFIG_PATH));
35
36
  const schemaId = requiredString((await opts.client.createSchema(schemaBody, { project_id: opts.projectId })).id, "created schema id");
36
37
  let schemaHash = hashForState({ normalize: normalizeSchemaBody }, schemaBody);
@@ -44,7 +45,10 @@ async function materializeSetupResources(opts) {
44
45
  id: schemaId,
45
46
  hash: schemaHash
46
47
  });
47
- const flowBody = getDefaultLoginFlow({ userSchemaUrl: schemaId });
48
+ const flowBody = getDefaultLoginFlow({
49
+ userSchemaUrl: schemaId,
50
+ preset
51
+ });
48
52
  if (await writeResourceFile(opts.cwd, DEFAULT_FLOW_CONFIG_PATH, flowBody, opts.force)) filesWritten.push(join(opts.cwd, DEFAULT_FLOW_CONFIG_PATH));
49
53
  const flow = await opts.client.createFlowDefinition({
50
54
  project_id: opts.projectId,
@@ -238,17 +242,18 @@ async function installDependenciesForSetup(input) {
238
242
  }
239
243
  function outcome(input) {
240
244
  const planCommand = publicCliCommand("plan", input.cliVersion);
241
- const applyCommand = publicCliCommand("apply", input.cliVersion);
242
- const afterInstall = [
243
- `Start your project: ${input.devCommand} (then open ${input.issuer})`,
244
- "Verify auth in the browser: register a user, log out, log in again with the same user, and confirm /profile shows Signed in.",
245
- "Customize auth: edit the user schema (.zitadel/schemas/) and login flow (.zitadel/flows/) — each folder has a README explaining what you can change.",
246
- `Preview and publish config changes: ${planCommand} then ${applyCommand}`
245
+ const statusCommand = publicCliCommand("status", input.cliVersion);
246
+ const verifyActions = [
247
+ ...input.includeInstallCommand ? [`Install dependencies: ${input.install.command}`] : [],
248
+ `Start your project: ${input.devCommand} (then open ${input.issuer}/login)`,
249
+ verifyLoginAction()
247
250
  ];
251
+ const breadcrumb = `Once login works: ${statusCommand} shows your next steps; customizing is covered in your README's Zitadel section.`;
248
252
  return {
249
253
  install: input.install,
250
254
  devCommand: input.devCommand,
251
- nextActions: input.includeInstallCommand ? [`Install dependencies: ${input.install.command}`, ...afterInstall] : afterInstall,
255
+ boxActions: [...verifyActions, breadcrumb],
256
+ nextActions: [...verifyActions, ...customizeAndPublishActions(input.cliVersion)],
252
257
  nextCommands: input.includeInstallCommand ? [
253
258
  input.install.command,
254
259
  input.devCommand,
@@ -332,64 +337,27 @@ var FrameworkConfirmPrompt = class {
332
337
  }
333
338
  };
334
339
  //#endregion
335
- //#region src/lib/prober/http.ts
336
- /**
337
- * Fetch `url` with a per-call timeout and pass the resulting `Response` to
338
- * `predicate`. Returns the predicate's value, or `null` on any failure: a
339
- * network error, an `AbortError` from the timeout, a thrown predicate, or the
340
- * predicate returning `null`.
341
- *
342
- * Never throws. The predicate decides what counts as a match — it gets the
343
- * raw `Response` and may read `.json()` / `.headers` / `.status` as needed.
344
- *
345
- * `timeoutMs` defaults to 500ms. The implementation uses
346
- * `AbortSignal.timeout`, so the underlying fetch is cancelled when the
347
- * timeout fires (no orphaned sockets).
348
- */
349
- async function probeUrl(url, predicate, opts) {
350
- const timeoutMs = opts?.timeoutMs ?? 500;
351
- try {
352
- return await predicate(await fetch(url, { signal: AbortSignal.timeout(timeoutMs) }));
353
- } catch {
354
- return null;
355
- }
356
- }
357
- /**
358
- * Probe many URLs in parallel and return the non-null matches, preserving
359
- * the input order. Each URL is bounded by `timeoutMs` independently — one
360
- * slow target can't hold up the others.
361
- */
362
- async function probeUrls(urls, predicate, opts) {
363
- const list = [...urls];
364
- return (await Promise.all(list.map(async (url) => {
365
- const value = await probeUrl(url, predicate, opts);
366
- return value === null ? null : {
367
- url,
368
- value
369
- };
370
- }))).filter((match) => match !== null);
371
- }
372
- //#endregion
373
340
  //#region src/commands/setup/prompts/server.ts
374
341
  /** Sentinel returned by the choice select when the user picks "Custom URL". */
375
342
  const CUSTOM = "__custom__";
376
- /** Per-probe timeout for the localhost OIDC scan — generous enough for a TLS handshake on a busy laptop. */
377
- const OIDC_PROBE_TIMEOUT_MS = 300;
378
343
  /**
379
- * "Which server should `zitadel.json` point to?" — Zitadel Cloud, a localhost
380
- * OIDC server we discovered, or a custom URL.
344
+ * "Which server should `zitadel.json` point to?" — Zitadel Cloud, the managed
345
+ * local server we detected, or a custom URL.
381
346
  *
382
- * Before asking, it scans the loopback for listening ports (via the generic
383
- * `lib/prober`) and `GET`s `/.well-known/openid-configuration` on each. Every
384
- * 2xx response with a string `issuer` becomes an extra option in the choice
385
- * list. Picking a discovered URL writes it directly to `answers.server` and
386
- * skips the follow-up text prompt. Picking "Custom URL" still asks for a
347
+ * Before asking, it looks for a healthy local Zitadel server the same way the
348
+ * rest of the CLI does (`detectHealthyLocalServer`: the runtime metadata that
349
+ * `zitadel start` wrote to `.zitadel/local/runtime.json`, falling back to a
350
+ * `/healthz` probe on the default localhost port). A detected server becomes
351
+ * an extra option in the choice list *and* the preselected answer a user
352
+ * who just ran `zitadel start` almost certainly wants it, and `start`'s own
353
+ * next-step hint says `setup --server local`. Picking it writes the URL
354
+ * directly to `answers.server`; picking "Custom URL" still asks for a
387
355
  * validated URL exactly as before.
388
356
  */
389
357
  var ServerPrompt = class {
390
358
  async ask(answers, ctx) {
391
359
  if (ctx.serverFlag) return answers;
392
- const discovered = await discoverLocalOidc();
360
+ const detected = await detectLocalServer(ctx.cwd);
393
361
  const choice = await select({
394
362
  message: "Which server should zitadel.json point to?",
395
363
  options: [
@@ -398,17 +366,17 @@ var ServerPrompt = class {
398
366
  label: "Zitadel Cloud (api.zitadel.cloud)",
399
367
  hint: "recommended for real projects"
400
368
  },
401
- ...discovered.map((server) => ({
402
- value: server,
403
- label: server,
404
- hint: "detected — OIDC"
405
- })),
369
+ ...detected ? [{
370
+ value: detected,
371
+ label: `Local Zitadel server (${detected})`,
372
+ hint: "detected — started with zitadel start"
373
+ }] : [],
406
374
  {
407
375
  value: CUSTOM,
408
376
  label: "Custom URL (self-hosted)"
409
377
  }
410
378
  ],
411
- initialValue: answers.server ?? "https://api.zitadel.cloud"
379
+ initialValue: detected ?? answers.server ?? "https://api.zitadel.cloud"
412
380
  });
413
381
  bail(choice);
414
382
  if (choice !== CUSTOM) return {
@@ -435,39 +403,48 @@ var ServerPrompt = class {
435
403
  }
436
404
  };
437
405
  /**
438
- * Returns the loopback origins (`http://localhost:<port>`) whose
439
- * `/.well-known/openid-configuration` endpoint responds with a valid OIDC
440
- * discovery document. Sniffs purely via the generic prober — the only
441
- * Zitadel-shaped detail here is the OIDC predicate, which is the standard
442
- * "any OIDC server" contract (no `zitadel`-keyword check), so Keycloak/dex/
443
- * etc. also surface and the user picks the right one.
406
+ * Wraps {@link detectHealthyLocalServer} in a spinner: the unhealthy paths
407
+ * block on up to two 1.5s `/healthz` probes, long enough that the wizard
408
+ * should say what it is doing.
444
409
  */
445
- async function discoverLocalOidc() {
410
+ async function detectLocalServer(cwd) {
446
411
  const s = spinner();
447
- s.start("Scanning localhost for OIDC servers");
448
- try {
449
- const ports = await listListeningPorts();
450
- if (ports.length === 0) {
451
- s.stop("No local servers detected.");
452
- return [];
453
- }
454
- const origins = (await probeUrls(ports.map((port) => `http://localhost:${port}/.well-known/openid-configuration`), async (response) => {
455
- if (!response.ok) return null;
456
- try {
457
- const body = await response.json();
458
- return typeof body.issuer === "string" ? body.issuer : null;
459
- } catch {
460
- return null;
461
- }
462
- }, { timeoutMs: OIDC_PROBE_TIMEOUT_MS })).map((match) => new URL(match.url).origin);
463
- s.stop(origins.length === 0 ? "No local OIDC servers found." : `Found ${origins.length} local OIDC server${origins.length === 1 ? "" : "s"}.`);
464
- return origins;
465
- } catch (error) {
466
- s.stop("Discovery skipped.");
467
- throw error;
468
- }
412
+ s.start("Checking for a local Zitadel server");
413
+ const detected = await detectHealthyLocalServer(cwd);
414
+ s.stop(detected ? `Found local Zitadel server at ${detected}.` : "No local Zitadel server detected.");
415
+ return detected;
469
416
  }
470
417
  //#endregion
418
+ //#region src/commands/setup/prompts/sign-in-preset.ts
419
+ /**
420
+ * "How should users sign in?" — picks the schema+flow preset the scaffold
421
+ * starts from (#448: app-type/preset selection before any `.zitadel/` file
422
+ * is written). `--preset` is authoritative; non-interactive runs keep the
423
+ * password-first default seeded by the command.
424
+ */
425
+ var SignInPresetPrompt = class {
426
+ async ask(answers, ctx) {
427
+ if (ctx.presetFromFlag) return answers;
428
+ const labels = {
429
+ "password-first": "Password first — email + password, passkey optional during registration",
430
+ "passkey-first": "Passkey first — one-tap passkey up front, email + password fallback"
431
+ };
432
+ const value = await select({
433
+ message: "How should users sign in?",
434
+ initialValue: answers.preset,
435
+ options: SETUP_PRESETS.map((preset) => ({
436
+ value: preset,
437
+ label: labels[preset]
438
+ }))
439
+ });
440
+ bail(value);
441
+ return {
442
+ ...answers,
443
+ preset: value
444
+ };
445
+ }
446
+ };
447
+ //#endregion
471
448
  //#region src/commands/setup/prompts/pick-framework.ts
472
449
  /**
473
450
  * "Choose a framework to scaffold" — the only prompt outside the main wizard.
@@ -506,7 +483,8 @@ var PickFrameworkPrompt = class {
506
483
  const SETUP_PROMPTS = [
507
484
  new FrameworkConfirmPrompt(),
508
485
  new ServerPrompt(),
509
- new DevPortPrompt()
486
+ new DevPortPrompt(),
487
+ new SignInPresetPrompt()
510
488
  ];
511
489
  //#endregion
512
490
  //#region src/commands/setup/summary.ts
@@ -633,14 +611,18 @@ var Setup = class Setup extends BaseCommand {
633
611
  options: [...RENDERER_IDS]
634
612
  }),
635
613
  "dev-port": Flags.integer({ description: "Dev-server port; also the issuer origin registered with Zitadel. Defaults to the detected port. Use distinct ports to run several scaffolded apps side by side." }),
636
- "skip-install": Flags.boolean({ description: "Do not install dependencies after setup updates package.json." })
614
+ "skip-install": Flags.boolean({ description: "Do not install dependencies after setup updates package.json." }),
615
+ preset: Flags.string({
616
+ description: "Sign-in preset for the scaffolded schema and login flow (default: password-first).",
617
+ options: [...SETUP_PRESETS]
618
+ })
637
619
  };
638
620
  async run() {
639
621
  const { flags } = await this.parse(Setup);
640
622
  try {
641
623
  await this.toMeta(flags);
642
624
  } catch (error) {
643
- throw localSetupHint(error, flags.framework, this.config.version);
625
+ throw localSetupHint(error, retryOptionsFromFlags(flags), this.config.version);
644
626
  }
645
627
  const { cwd, nonInteractive, dryRun, force } = this.meta;
646
628
  if (await hasZitadelConfig(cwd)) return this.emit({
@@ -671,6 +653,7 @@ var Setup = class Setup extends BaseCommand {
671
653
  scaffolded_skeleton: scaffoldedFramework,
672
654
  skip_install: Boolean(flags["skip-install"]),
673
655
  dev_port_explicit: flags["dev-port"] !== void 0,
656
+ preset: flags.preset ?? DEFAULT_SETUP_PRESET,
674
657
  step: "framework_resolved"
675
658
  });
676
659
  if (flags["dev-port"] !== void 0) {
@@ -684,18 +667,22 @@ var Setup = class Setup extends BaseCommand {
684
667
  }
685
668
  let answers = {
686
669
  server: this.meta.source,
687
- devPort: framework.devPort
670
+ devPort: framework.devPort,
671
+ preset: flags.preset ?? DEFAULT_SETUP_PRESET
688
672
  };
689
673
  if (!nonInteractive && !dryRun) {
690
674
  intro("Zitadel setup");
691
675
  const promptCtx = {
692
676
  framework,
677
+ cwd,
693
678
  serverFlag: this.meta.serverFlag,
694
- devPortFromFlag: flags["dev-port"] !== void 0
679
+ devPortFromFlag: flags["dev-port"] !== void 0,
680
+ presetFromFlag: flags.preset !== void 0
695
681
  };
696
682
  for (const prompt of SETUP_PROMPTS) answers = await prompt.ask(answers, promptCtx);
697
683
  outro("Configuration captured");
698
684
  }
685
+ this.recordTelemetry({ preset: answers.preset });
699
686
  const issuer = issuerFromPort(answers.devPort);
700
687
  framework = {
701
688
  ...framework,
@@ -704,7 +691,13 @@ var Setup = class Setup extends BaseCommand {
704
691
  };
705
692
  consola$1.start(`Creating project on ${answers.server}${dryRun ? " (dry run)" : ""}`);
706
693
  const unauthClient = createZitadelClient({ baseUrl: answers.server });
707
- const project = dryRun ? dryRunProject(issuer) : await createProjectWithLocalHint(unauthClient, answers.server, this.meta.cliVersion, issuer, framework.id);
694
+ const projectName = defaultProjectName(cwd, framework.id);
695
+ const project = dryRun ? dryRunProject(issuer) : await createProjectWithLocalHint(unauthClient, answers.server, this.meta.cliVersion, projectName, issuer, {
696
+ ...retryOptionsFromFlags(flags),
697
+ framework: framework.id,
698
+ preset: answers.preset,
699
+ devPort: answers.devPort
700
+ });
708
701
  consola$1.success(`Created project ${project.id}`);
709
702
  this.recordTelemetry({ step: "project_created" });
710
703
  const ctx = {
@@ -714,7 +707,8 @@ var Setup = class Setup extends BaseCommand {
714
707
  issuer,
715
708
  server: answers.server,
716
709
  cliVersion: this.meta.cliVersion,
717
- scaffoldedFramework
710
+ scaffoldedFramework,
711
+ preset: answers.preset
718
712
  };
719
713
  consola$1.start(`Patching project files${dryRun ? " (dry run)" : ""}`);
720
714
  const result = await orca.patcherFor(framework.id).patch(ctx, {
@@ -736,7 +730,8 @@ var Setup = class Setup extends BaseCommand {
736
730
  token: project.projectSecret
737
731
  }),
738
732
  projectId: project.id,
739
- force
733
+ force,
734
+ preset: answers.preset
740
735
  });
741
736
  } catch (error) {
742
737
  await rm(join(cwd, "zitadel.json"), { force: true });
@@ -788,7 +783,7 @@ var Setup = class Setup extends BaseCommand {
788
783
  message: [
789
784
  renderSummary(sections),
790
785
  "",
791
- installOutcome.nextActions.join("\n")
786
+ installOutcome.boxActions.join("\n")
792
787
  ].join("\n"),
793
788
  style: {
794
789
  padding: 1,
@@ -847,17 +842,49 @@ function dryRunProject(issuer) {
847
842
  createdAt: "2026-04-21T14:03:11.000Z"
848
843
  };
849
844
  }
850
- async function createProjectWithLocalHint(client, server, cliVersion, issuer, framework) {
845
+ /**
846
+ * Reconstructs the flag list of the current invocation for retry guidance,
847
+ * ending in `--server local`. Flags whose resolved value equals the default
848
+ * are omitted — the retry reproduces the same outcome without them.
849
+ */
850
+ function setupRetryFlags(opts) {
851
+ const parts = [];
852
+ if (opts.framework) parts.push(`--framework ${opts.framework}`);
853
+ if (opts.preset && opts.preset !== DEFAULT_SETUP_PRESET) parts.push(`--preset ${opts.preset}`);
854
+ if (opts.renderer && opts.renderer !== "react") parts.push(`--renderer ${opts.renderer}`);
855
+ if (opts.devPort !== void 0) parts.push(`--dev-port ${opts.devPort}`);
856
+ if (opts.nonInteractive) parts.push("--non-interactive");
857
+ parts.push("--server local");
858
+ return parts.join(" ");
859
+ }
860
+ /**
861
+ * Retry options straight from parsed flags, for failures before the wizard
862
+ * resolves answers. `--non-interactive` is echoed only when explicitly passed
863
+ * — TTY/JSON-inferred non-interactivity re-infers itself on the retry.
864
+ */
865
+ function retryOptionsFromFlags(flags) {
866
+ return {
867
+ framework: flags.framework,
868
+ preset: flags.preset,
869
+ renderer: flags.renderer,
870
+ devPort: flags["dev-port"],
871
+ nonInteractive: Boolean(flags["non-interactive"])
872
+ };
873
+ }
874
+ async function createProjectWithLocalHint(client, server, cliVersion, projectName, issuer, retry) {
851
875
  try {
852
- return await client.createProject({
876
+ const payload = {
877
+ name: projectName,
853
878
  previewOrigins: [issuer],
854
879
  seedDefaults: false
855
- });
880
+ };
881
+ return await client.createProject(payload);
856
882
  } catch (error) {
857
883
  const normalized = toZitadelError(error);
884
+ const retryFlags = setupRetryFlags(retry);
858
885
  throw new ZitadelError(normalized.code, normalized.message, {
859
- hint: `${normalized.hint ? `${normalized.hint} ` : ""}If you meant to use a local Zitadel server, start it first and retry setup with --framework ${framework} --server local.`,
860
- nextCommands: [publicCliCommand("start", cliVersion), publicCliCommand(`setup --framework ${framework} --server local`, cliVersion)],
886
+ hint: `${normalized.hint ? `${normalized.hint} ` : ""}If you meant to use a local Zitadel server, start it first and retry setup with ${retryFlags}.`,
887
+ nextCommands: [publicCliCommand("start", cliVersion), publicCliCommand(`setup ${retryFlags}`, cliVersion)],
861
888
  details: {
862
889
  server,
863
890
  original: normalized.details
@@ -865,10 +892,14 @@ async function createProjectWithLocalHint(client, server, cliVersion, issuer, fr
865
892
  });
866
893
  }
867
894
  }
868
- function localSetupHint(error, framework, cliVersion) {
895
+ function defaultProjectName(cwd, framework) {
896
+ const fromDirectory = basename(cwd).trim();
897
+ return fromDirectory.length > 0 ? fromDirectory : `zitadel-${framework}-app`;
898
+ }
899
+ function localSetupHint(error, retry, cliVersion) {
869
900
  const normalized = toZitadelError(error);
870
901
  if (normalized.code !== "E_LOCAL_SERVER_NOT_RUNNING") return error;
871
- const setupCommand = framework ? `setup --framework ${framework} --server local` : "setup --server local";
902
+ const setupCommand = `setup ${setupRetryFlags(retry)}`;
872
903
  return new ZitadelError(normalized.code, normalized.message, {
873
904
  hint: `${normalized.hint ? `${normalized.hint} ` : ""}Start local Zitadel first, then rerun setup. After setup succeeds, follow its next_commands to start the app and verify registration, logout, and login in the browser.`,
874
905
  nextCommands: [publicCliCommand("start", cliVersion), publicCliCommand(setupCommand, cliVersion)],
@@ -907,7 +938,7 @@ function pickWrittenFile(written, suffix) {
907
938
  * something happened.
908
939
  */
909
940
  function describeWrittenFile(relPath, dryRun) {
910
- if (relPath === ".zitadel" || relPath === ".zitadel/flows" || relPath === ".zitadel/schemas") return null;
941
+ if (relPath === ".zitadel" || relPath === ".zitadel/flows" || relPath === ".zitadel/schemas" || relPath === ".zitadel/meta") return null;
911
942
  const verb = dryRun ? "Would write" : "Wrote";
912
943
  const sentence = SENTENCE_BY_PATH[relPath];
913
944
  if (sentence) return `${verb} ${sentence.subject} (${path(relPath)})`;
@@ -930,7 +961,12 @@ const SENTENCE_BY_PATH = {
930
961
  ".zitadel/flows/README.md": { subject: "the flows folder README" },
931
962
  ".zitadel/schemas/default-human-user.json": { subject: "the editable default human user schema" },
932
963
  ".zitadel/schemas/README.md": { subject: "the schemas folder README" },
933
- "app/page.tsx": { subject: "the auth home page" },
964
+ ".zitadel/meta/flow-definition.json": { subject: "the flow dialect spec (editor $schema)" },
965
+ ".zitadel/meta/user-schema.json": { subject: "the user-schema dialect spec" },
966
+ ".zitadel/meta/user-property.json": { subject: "the user-property dialect spec" },
967
+ "AGENTS.md": { subject: "the agent guidance (golden journey + config dialect)" },
968
+ "README.md": { subject: "the README's Zitadel section" },
969
+ "app/page.tsx": { subject: "the home page redirect" },
934
970
  "app/login/page.tsx": { subject: "the login page" },
935
971
  "app/register/page.tsx": { subject: "the registration page" },
936
972
  "app/profile/page.tsx": { subject: "the profile page" },
@@ -959,7 +995,7 @@ function buildSummary(opts) {
959
995
  secondary: path(fileNameOf(packageJsonHit))
960
996
  });
961
997
  for (const [label, suffix] of [
962
- ["Home page", "app/page.tsx"],
998
+ ["Home redirect", "app/page.tsx"],
963
999
  ["Login page", "app/login/page.tsx"],
964
1000
  ["Register page", "app/register/page.tsx"],
965
1001
  ["Profile page", "app/profile/page.tsx"],