workos 0.17.1 → 0.19.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.
Files changed (366) hide show
  1. package/README.md +11 -149
  2. package/dist/bin.js +155 -23
  3. package/dist/bin.js.map +1 -1
  4. package/dist/cli.config.d.ts +0 -2
  5. package/dist/cli.config.js +3 -3
  6. package/dist/cli.config.js.map +1 -1
  7. package/dist/commands/api/index.js +18 -10
  8. package/dist/commands/api/index.js.map +1 -1
  9. package/dist/commands/api/interactive.js +11 -11
  10. package/dist/commands/api/interactive.js.map +1 -1
  11. package/dist/commands/claim.js +28 -16
  12. package/dist/commands/claim.js.map +1 -1
  13. package/dist/commands/connection.js +3 -3
  14. package/dist/commands/connection.js.map +1 -1
  15. package/dist/commands/debug.d.ts +11 -0
  16. package/dist/commands/debug.js +30 -14
  17. package/dist/commands/debug.js.map +1 -1
  18. package/dist/commands/dev.d.ts +7 -8
  19. package/dist/commands/dev.js +14 -14
  20. package/dist/commands/dev.js.map +1 -1
  21. package/dist/commands/directory.js +3 -3
  22. package/dist/commands/directory.js.map +1 -1
  23. package/dist/commands/doctor.js +2 -2
  24. package/dist/commands/doctor.js.map +1 -1
  25. package/dist/commands/emulate.d.ts +1 -0
  26. package/dist/commands/emulate.js +3 -2
  27. package/dist/commands/emulate.js.map +1 -1
  28. package/dist/commands/env.d.ts +10 -0
  29. package/dist/commands/env.js +94 -18
  30. package/dist/commands/env.js.map +1 -1
  31. package/dist/commands/install.js +9 -10
  32. package/dist/commands/install.js.map +1 -1
  33. package/dist/commands/login.d.ts +25 -15
  34. package/dist/commands/login.js +126 -71
  35. package/dist/commands/login.js.map +1 -1
  36. package/dist/commands/logout.js +4 -4
  37. package/dist/commands/logout.js.map +1 -1
  38. package/dist/commands/mcp.d.ts +14 -0
  39. package/dist/commands/mcp.js +99 -0
  40. package/dist/commands/mcp.js.map +1 -0
  41. package/dist/commands/migrations.js +2 -1
  42. package/dist/commands/migrations.js.map +1 -1
  43. package/dist/commands/seed.js +5 -4
  44. package/dist/commands/seed.js.map +1 -1
  45. package/dist/commands/setup.d.ts +50 -0
  46. package/dist/commands/setup.js +237 -0
  47. package/dist/commands/setup.js.map +1 -0
  48. package/dist/commands/vault-run.js +3 -2
  49. package/dist/commands/vault-run.js.map +1 -1
  50. package/dist/commands/verify-login.d.ts +25 -0
  51. package/dist/commands/verify-login.js +158 -0
  52. package/dist/commands/verify-login.js.map +1 -0
  53. package/dist/doctor/checks/ai-analysis.js +2 -1
  54. package/dist/doctor/checks/ai-analysis.js.map +1 -1
  55. package/dist/doctor/checks/mcp.d.ts +15 -0
  56. package/dist/doctor/checks/mcp.js +34 -0
  57. package/dist/doctor/checks/mcp.js.map +1 -0
  58. package/dist/doctor/index.js +7 -1
  59. package/dist/doctor/index.js.map +1 -1
  60. package/dist/doctor/issues.js +18 -1
  61. package/dist/doctor/issues.js.map +1 -1
  62. package/dist/doctor/output.js +18 -3
  63. package/dist/doctor/output.js.map +1 -1
  64. package/dist/doctor/types.d.ts +17 -0
  65. package/dist/doctor/types.js.map +1 -1
  66. package/dist/integrations/dotnet/index.js +1 -1
  67. package/dist/integrations/dotnet/index.js.map +1 -1
  68. package/dist/integrations/elixir/index.js +1 -1
  69. package/dist/integrations/elixir/index.js.map +1 -1
  70. package/dist/integrations/go/index.js +1 -1
  71. package/dist/integrations/go/index.js.map +1 -1
  72. package/dist/integrations/nextjs/index.js +8 -5
  73. package/dist/integrations/nextjs/index.js.map +1 -1
  74. package/dist/integrations/nextjs/utils.d.ts +1 -1
  75. package/dist/integrations/nextjs/utils.js +21 -6
  76. package/dist/integrations/nextjs/utils.js.map +1 -1
  77. package/dist/integrations/react-router/index.js +5 -5
  78. package/dist/integrations/react-router/index.js.map +1 -1
  79. package/dist/integrations/react-router/utils.js +28 -12
  80. package/dist/integrations/react-router/utils.js.map +1 -1
  81. package/dist/integrations/ruby/index.js +1 -1
  82. package/dist/integrations/ruby/index.js.map +1 -1
  83. package/dist/lib/adapters/cli-adapter.d.ts +33 -4
  84. package/dist/lib/adapters/cli-adapter.js +251 -135
  85. package/dist/lib/adapters/cli-adapter.js.map +1 -1
  86. package/dist/lib/adapters/dashboard-adapter.js +3 -3
  87. package/dist/lib/adapters/dashboard-adapter.js.map +1 -1
  88. package/dist/lib/adapters/headless-adapter.d.ts +7 -0
  89. package/dist/lib/adapters/headless-adapter.js +42 -5
  90. package/dist/lib/adapters/headless-adapter.js.map +1 -1
  91. package/dist/lib/agent-interface.js +19 -5
  92. package/dist/lib/agent-interface.js.map +1 -1
  93. package/dist/lib/agent-runner.js +1 -1
  94. package/dist/lib/agent-runner.js.map +1 -1
  95. package/dist/lib/ai-content.js +2 -1
  96. package/dist/lib/ai-content.js.map +1 -1
  97. package/dist/lib/api-key.js +2 -1
  98. package/dist/lib/api-key.js.map +1 -1
  99. package/dist/lib/completion-data.d.ts +33 -0
  100. package/dist/lib/completion-data.js +33 -0
  101. package/dist/lib/completion-data.js.map +1 -0
  102. package/dist/lib/config-store.d.ts +13 -0
  103. package/dist/lib/config-store.js +24 -0
  104. package/dist/lib/config-store.js.map +1 -1
  105. package/dist/lib/config.d.ts +1 -1
  106. package/dist/lib/config.js +1 -1
  107. package/dist/lib/config.js.map +1 -1
  108. package/dist/lib/constants.d.ts +17 -0
  109. package/dist/lib/constants.js +17 -0
  110. package/dist/lib/constants.js.map +1 -1
  111. package/dist/lib/events.d.ts +34 -1
  112. package/dist/lib/events.js.map +1 -1
  113. package/dist/lib/framework-config.d.ts +6 -0
  114. package/dist/lib/framework-config.js.map +1 -1
  115. package/dist/lib/installer-core.d.ts +34 -21
  116. package/dist/lib/installer-core.js +24 -5
  117. package/dist/lib/installer-core.js.map +1 -1
  118. package/dist/lib/installer-core.types.d.ts +3 -1
  119. package/dist/lib/installer-core.types.js.map +1 -1
  120. package/dist/lib/mcp-clients.d.ts +45 -0
  121. package/dist/lib/mcp-clients.js +297 -0
  122. package/dist/lib/mcp-clients.js.map +1 -0
  123. package/dist/lib/port-detection.js +19 -13
  124. package/dist/lib/port-detection.js.map +1 -1
  125. package/dist/lib/preferences.d.ts +42 -0
  126. package/dist/lib/preferences.js +34 -5
  127. package/dist/lib/preferences.js.map +1 -1
  128. package/dist/lib/run-with-core.js +42 -4
  129. package/dist/lib/run-with-core.js.map +1 -1
  130. package/dist/lib/settings.d.ts +5 -14
  131. package/dist/lib/settings.js +5 -16
  132. package/dist/lib/settings.js.map +1 -1
  133. package/dist/lib/startup-notice-gate.d.ts +21 -0
  134. package/dist/lib/startup-notice-gate.js +29 -0
  135. package/dist/lib/startup-notice-gate.js.map +1 -0
  136. package/dist/lib/telemetry-notice.d.ts +5 -5
  137. package/dist/lib/telemetry-notice.js +10 -8
  138. package/dist/lib/telemetry-notice.js.map +1 -1
  139. package/dist/lib/unclaimed-env-provision.js +15 -12
  140. package/dist/lib/unclaimed-env-provision.js.map +1 -1
  141. package/dist/lib/unclaimed-warning.js +7 -3
  142. package/dist/lib/unclaimed-warning.js.map +1 -1
  143. package/dist/lib/validation/security-checks.js +2 -1
  144. package/dist/lib/validation/security-checks.js.map +1 -1
  145. package/dist/lib/validation/validator.js +30 -3
  146. package/dist/lib/validation/validator.js.map +1 -1
  147. package/dist/lib/workos-management.js +26 -19
  148. package/dist/lib/workos-management.js.map +1 -1
  149. package/dist/run.d.ts +1 -0
  150. package/dist/run.js +5 -1
  151. package/dist/run.js.map +1 -1
  152. package/dist/steps/add-or-update-environment-variables.js +10 -10
  153. package/dist/steps/add-or-update-environment-variables.js.map +1 -1
  154. package/dist/steps/run-prettier.js +3 -3
  155. package/dist/steps/run-prettier.js.map +1 -1
  156. package/dist/steps/upload-environment-variables/index.js +15 -3
  157. package/dist/steps/upload-environment-variables/index.js.map +1 -1
  158. package/dist/steps/upload-environment-variables/providers/vercel.js +2 -2
  159. package/dist/steps/upload-environment-variables/providers/vercel.js.map +1 -1
  160. package/dist/utils/analytics.d.ts +1 -0
  161. package/dist/utils/analytics.js +5 -1
  162. package/dist/utils/analytics.js.map +1 -1
  163. package/dist/utils/box.d.ts +6 -30
  164. package/dist/utils/box.js +8 -95
  165. package/dist/utils/box.js.map +1 -1
  166. package/dist/utils/cli-symbols.d.ts +14 -2
  167. package/dist/utils/cli-symbols.js +12 -0
  168. package/dist/utils/cli-symbols.js.map +1 -1
  169. package/dist/utils/debug.js +3 -3
  170. package/dist/utils/debug.js.map +1 -1
  171. package/dist/utils/environment.js +1 -1
  172. package/dist/utils/environment.js.map +1 -1
  173. package/dist/utils/help-json.js +153 -4
  174. package/dist/utils/help-json.js.map +1 -1
  175. package/dist/utils/interaction-mode.d.ts +1 -1
  176. package/dist/utils/interaction-mode.js +0 -3
  177. package/dist/utils/interaction-mode.js.map +1 -1
  178. package/dist/utils/output.d.ts +5 -3
  179. package/dist/utils/output.js +5 -5
  180. package/dist/utils/output.js.map +1 -1
  181. package/dist/utils/package-manager.js +1 -1
  182. package/dist/utils/package-manager.js.map +1 -1
  183. package/dist/utils/recovery-hints.d.ts +5 -0
  184. package/dist/utils/recovery-hints.js +12 -0
  185. package/dist/utils/recovery-hints.js.map +1 -1
  186. package/dist/utils/summary-box.d.ts +8 -1
  187. package/dist/utils/summary-box.js +67 -4
  188. package/dist/utils/summary-box.js.map +1 -1
  189. package/dist/utils/telemetry-types.d.ts +1 -1
  190. package/dist/utils/telemetry-types.js.map +1 -1
  191. package/dist/utils/types.d.ts +10 -0
  192. package/dist/utils/types.js.map +1 -1
  193. package/dist/utils/{clack-utils.d.ts → ui-utils.d.ts} +1 -1
  194. package/dist/utils/{clack-utils.js → ui-utils.js} +64 -37
  195. package/dist/utils/ui-utils.js.map +1 -0
  196. package/dist/utils/ui.d.ts +148 -0
  197. package/dist/utils/ui.js +368 -0
  198. package/dist/utils/ui.js.map +1 -0
  199. package/dist/utils/urls.d.ts +9 -3
  200. package/dist/utils/urls.js +10 -4
  201. package/dist/utils/urls.js.map +1 -1
  202. package/package.json +13 -20
  203. package/dist/check-coverage.ts +0 -237
  204. package/dist/emulate/core/id.d.ts +0 -48
  205. package/dist/emulate/core/id.js +0 -73
  206. package/dist/emulate/core/id.js.map +0 -1
  207. package/dist/emulate/core/index.d.ts +0 -8
  208. package/dist/emulate/core/index.js +0 -8
  209. package/dist/emulate/core/index.js.map +0 -1
  210. package/dist/emulate/core/jwt.d.ts +0 -28
  211. package/dist/emulate/core/jwt.js +0 -78
  212. package/dist/emulate/core/jwt.js.map +0 -1
  213. package/dist/emulate/core/middleware/auth.d.ts +0 -15
  214. package/dist/emulate/core/middleware/auth.js +0 -17
  215. package/dist/emulate/core/middleware/auth.js.map +0 -1
  216. package/dist/emulate/core/middleware/error-handler.d.ts +0 -22
  217. package/dist/emulate/core/middleware/error-handler.js +0 -72
  218. package/dist/emulate/core/middleware/error-handler.js.map +0 -1
  219. package/dist/emulate/core/pagination.d.ts +0 -27
  220. package/dist/emulate/core/pagination.js +0 -43
  221. package/dist/emulate/core/pagination.js.map +0 -1
  222. package/dist/emulate/core/plugin.d.ts +0 -15
  223. package/dist/emulate/core/plugin.js +0 -2
  224. package/dist/emulate/core/plugin.js.map +0 -1
  225. package/dist/emulate/core/server.d.ts +0 -17
  226. package/dist/emulate/core/server.js +0 -90
  227. package/dist/emulate/core/server.js.map +0 -1
  228. package/dist/emulate/core/store.d.ts +0 -44
  229. package/dist/emulate/core/store.js +0 -169
  230. package/dist/emulate/core/store.js.map +0 -1
  231. package/dist/emulate/index.d.ts +0 -25
  232. package/dist/emulate/index.js +0 -47
  233. package/dist/emulate/index.js.map +0 -1
  234. package/dist/emulate/workos/constants.d.ts +0 -56
  235. package/dist/emulate/workos/constants.js +0 -56
  236. package/dist/emulate/workos/constants.js.map +0 -1
  237. package/dist/emulate/workos/entities.d.ts +0 -360
  238. package/dist/emulate/workos/entities.js +0 -2
  239. package/dist/emulate/workos/entities.js.map +0 -1
  240. package/dist/emulate/workos/event-bus.d.ts +0 -17
  241. package/dist/emulate/workos/event-bus.js +0 -70
  242. package/dist/emulate/workos/event-bus.js.map +0 -1
  243. package/dist/emulate/workos/helpers.d.ts +0 -72
  244. package/dist/emulate/workos/helpers.js +0 -211
  245. package/dist/emulate/workos/helpers.js.map +0 -1
  246. package/dist/emulate/workos/index.d.ts +0 -93
  247. package/dist/emulate/workos/index.js +0 -326
  248. package/dist/emulate/workos/index.js.map +0 -1
  249. package/dist/emulate/workos/role-helpers.d.ts +0 -21
  250. package/dist/emulate/workos/role-helpers.js +0 -130
  251. package/dist/emulate/workos/role-helpers.js.map +0 -1
  252. package/dist/emulate/workos/routes/api-keys.d.ts +0 -2
  253. package/dist/emulate/workos/routes/api-keys.js +0 -32
  254. package/dist/emulate/workos/routes/api-keys.js.map +0 -1
  255. package/dist/emulate/workos/routes/audit-logs.d.ts +0 -2
  256. package/dist/emulate/workos/routes/audit-logs.js +0 -104
  257. package/dist/emulate/workos/routes/audit-logs.js.map +0 -1
  258. package/dist/emulate/workos/routes/auth-challenges.d.ts +0 -2
  259. package/dist/emulate/workos/routes/auth-challenges.js +0 -51
  260. package/dist/emulate/workos/routes/auth-challenges.js.map +0 -1
  261. package/dist/emulate/workos/routes/auth-factors.d.ts +0 -2
  262. package/dist/emulate/workos/routes/auth-factors.js +0 -51
  263. package/dist/emulate/workos/routes/auth-factors.js.map +0 -1
  264. package/dist/emulate/workos/routes/auth.d.ts +0 -2
  265. package/dist/emulate/workos/routes/auth.js +0 -350
  266. package/dist/emulate/workos/routes/auth.js.map +0 -1
  267. package/dist/emulate/workos/routes/authorization-checks.d.ts +0 -10
  268. package/dist/emulate/workos/routes/authorization-checks.js +0 -123
  269. package/dist/emulate/workos/routes/authorization-checks.js.map +0 -1
  270. package/dist/emulate/workos/routes/authorization-org-roles.d.ts +0 -2
  271. package/dist/emulate/workos/routes/authorization-org-roles.js +0 -64
  272. package/dist/emulate/workos/routes/authorization-org-roles.js.map +0 -1
  273. package/dist/emulate/workos/routes/authorization-permissions.d.ts +0 -2
  274. package/dist/emulate/workos/routes/authorization-permissions.js +0 -67
  275. package/dist/emulate/workos/routes/authorization-permissions.js.map +0 -1
  276. package/dist/emulate/workos/routes/authorization-resources.d.ts +0 -2
  277. package/dist/emulate/workos/routes/authorization-resources.js +0 -117
  278. package/dist/emulate/workos/routes/authorization-resources.js.map +0 -1
  279. package/dist/emulate/workos/routes/authorization-roles.d.ts +0 -2
  280. package/dist/emulate/workos/routes/authorization-roles.js +0 -13
  281. package/dist/emulate/workos/routes/authorization-roles.js.map +0 -1
  282. package/dist/emulate/workos/routes/config.d.ts +0 -2
  283. package/dist/emulate/workos/routes/config.js +0 -57
  284. package/dist/emulate/workos/routes/config.js.map +0 -1
  285. package/dist/emulate/workos/routes/connect.d.ts +0 -2
  286. package/dist/emulate/workos/routes/connect.js +0 -65
  287. package/dist/emulate/workos/routes/connect.js.map +0 -1
  288. package/dist/emulate/workos/routes/connections.d.ts +0 -2
  289. package/dist/emulate/workos/routes/connections.js +0 -73
  290. package/dist/emulate/workos/routes/connections.js.map +0 -1
  291. package/dist/emulate/workos/routes/data-integrations.d.ts +0 -2
  292. package/dist/emulate/workos/routes/data-integrations.js +0 -55
  293. package/dist/emulate/workos/routes/data-integrations.js.map +0 -1
  294. package/dist/emulate/workos/routes/directories.d.ts +0 -2
  295. package/dist/emulate/workos/routes/directories.js +0 -90
  296. package/dist/emulate/workos/routes/directories.js.map +0 -1
  297. package/dist/emulate/workos/routes/email-verification.d.ts +0 -2
  298. package/dist/emulate/workos/routes/email-verification.js +0 -49
  299. package/dist/emulate/workos/routes/email-verification.js.map +0 -1
  300. package/dist/emulate/workos/routes/events.d.ts +0 -2
  301. package/dist/emulate/workos/routes/events.js +0 -18
  302. package/dist/emulate/workos/routes/events.js.map +0 -1
  303. package/dist/emulate/workos/routes/feature-flags.d.ts +0 -2
  304. package/dist/emulate/workos/routes/feature-flags.js +0 -103
  305. package/dist/emulate/workos/routes/feature-flags.js.map +0 -1
  306. package/dist/emulate/workos/routes/invitations.d.ts +0 -2
  307. package/dist/emulate/workos/routes/invitations.js +0 -122
  308. package/dist/emulate/workos/routes/invitations.js.map +0 -1
  309. package/dist/emulate/workos/routes/legacy-mfa.d.ts +0 -2
  310. package/dist/emulate/workos/routes/legacy-mfa.js +0 -75
  311. package/dist/emulate/workos/routes/legacy-mfa.js.map +0 -1
  312. package/dist/emulate/workos/routes/magic-auth.d.ts +0 -2
  313. package/dist/emulate/workos/routes/magic-auth.js +0 -32
  314. package/dist/emulate/workos/routes/magic-auth.js.map +0 -1
  315. package/dist/emulate/workos/routes/memberships.d.ts +0 -2
  316. package/dist/emulate/workos/routes/memberships.js +0 -114
  317. package/dist/emulate/workos/routes/memberships.js.map +0 -1
  318. package/dist/emulate/workos/routes/organization-domains.d.ts +0 -2
  319. package/dist/emulate/workos/routes/organization-domains.js +0 -58
  320. package/dist/emulate/workos/routes/organization-domains.js.map +0 -1
  321. package/dist/emulate/workos/routes/organizations.d.ts +0 -2
  322. package/dist/emulate/workos/routes/organizations.js +0 -131
  323. package/dist/emulate/workos/routes/organizations.js.map +0 -1
  324. package/dist/emulate/workos/routes/password-reset.d.ts +0 -2
  325. package/dist/emulate/workos/routes/password-reset.js +0 -61
  326. package/dist/emulate/workos/routes/password-reset.js.map +0 -1
  327. package/dist/emulate/workos/routes/pipes.d.ts +0 -2
  328. package/dist/emulate/workos/routes/pipes.js +0 -82
  329. package/dist/emulate/workos/routes/pipes.js.map +0 -1
  330. package/dist/emulate/workos/routes/portal.d.ts +0 -2
  331. package/dist/emulate/workos/routes/portal.js +0 -18
  332. package/dist/emulate/workos/routes/portal.js.map +0 -1
  333. package/dist/emulate/workos/routes/radar.d.ts +0 -2
  334. package/dist/emulate/workos/routes/radar.js +0 -41
  335. package/dist/emulate/workos/routes/radar.js.map +0 -1
  336. package/dist/emulate/workos/routes/sessions.d.ts +0 -2
  337. package/dist/emulate/workos/routes/sessions.js +0 -51
  338. package/dist/emulate/workos/routes/sessions.js.map +0 -1
  339. package/dist/emulate/workos/routes/sso.d.ts +0 -2
  340. package/dist/emulate/workos/routes/sso.js +0 -161
  341. package/dist/emulate/workos/routes/sso.js.map +0 -1
  342. package/dist/emulate/workos/routes/user-features.d.ts +0 -2
  343. package/dist/emulate/workos/routes/user-features.js +0 -50
  344. package/dist/emulate/workos/routes/user-features.js.map +0 -1
  345. package/dist/emulate/workos/routes/users.d.ts +0 -2
  346. package/dist/emulate/workos/routes/users.js +0 -129
  347. package/dist/emulate/workos/routes/users.js.map +0 -1
  348. package/dist/emulate/workos/routes/webhook-endpoints.d.ts +0 -2
  349. package/dist/emulate/workos/routes/webhook-endpoints.js +0 -67
  350. package/dist/emulate/workos/routes/webhook-endpoints.js.map +0 -1
  351. package/dist/emulate/workos/routes/widgets.d.ts +0 -2
  352. package/dist/emulate/workos/routes/widgets.js +0 -27
  353. package/dist/emulate/workos/routes/widgets.js.map +0 -1
  354. package/dist/emulate/workos/store.d.ts +0 -48
  355. package/dist/emulate/workos/store.js +0 -102
  356. package/dist/emulate/workos/store.js.map +0 -1
  357. package/dist/emulate/workos/webhook-signer.d.ts +0 -1
  358. package/dist/emulate/workos/webhook-signer.js +0 -8
  359. package/dist/emulate/workos/webhook-signer.js.map +0 -1
  360. package/dist/gen-routes-lib.spec.ts +0 -659
  361. package/dist/gen-routes-lib.ts +0 -647
  362. package/dist/gen-routes.ts +0 -96
  363. package/dist/utils/clack-utils.js.map +0 -1
  364. package/dist/utils/clack.d.ts +0 -5
  365. package/dist/utils/clack.js +0 -34
  366. package/dist/utils/clack.js.map +0 -1
package/README.md CHANGED
@@ -85,6 +85,9 @@ Resource Management:
85
85
  Migrations:
86
86
  migrations Migrate users and SSO connections into WorkOS
87
87
 
88
+ Local Development:
89
+ emulate Start a local WorkOS API emulator
90
+
88
91
  Workflows:
89
92
  seed Declarative resource provisioning from YAML
90
93
  setup-org One-shot organization onboarding
@@ -221,38 +224,9 @@ workos migrations import --csv users.csv
221
224
 
222
225
  Run `workos migrations --help` for all available subcommands.
223
226
 
224
- <!-- UNRELEASED: Local Development (emulator) — hidden until beta testing is complete.
225
- To restore, uncomment this section and re-enable the `emulate` and `dev` commands
226
- in src/bin.ts and src/utils/help-json.ts.
227
-
228
- ### Local Development
229
-
230
- Test your WorkOS integration locally without hitting the live API. The emulator provides a full in-memory WorkOS API replacement with all major endpoints.
231
-
232
- #### `workos dev` — One command to start everything
233
-
234
- The fastest way to develop locally. Starts the emulator and your app together, auto-detecting your framework and injecting the right environment variables.
235
-
236
- ```bash
237
- # Auto-detects framework (Next.js, Vite, Remix, SvelteKit, etc.) and dev command
238
- workos dev
239
-
240
- # Override the dev command
241
- workos dev -- npx vite --port 5173
242
-
243
- # Custom emulator port and seed data
244
- workos dev --port 8080 --seed workos-emulate.config.yaml
245
- ```
246
-
247
- Your app receives these environment variables automatically:
227
+ ### Local Emulation
248
228
 
249
- - `WORKOS_API_BASE_URL` points to the local emulator (e.g. `http://localhost:4100`)
250
- - `WORKOS_API_KEY` — `sk_test_default`
251
- - `WORKOS_CLIENT_ID` — `client_emulate`
252
-
253
- #### `workos emulate` — Standalone emulator
254
-
255
- Run the emulator on its own for CI, test suites, or when you want manual control.
229
+ Start a local WorkOS API emulator. The command is backed by [`@workos/emulate`](https://github.com/workos/emulate); the standalone package binary is `workos-emulate`.
256
230
 
257
231
  ```bash
258
232
  # Start with defaults (port 4100)
@@ -260,124 +234,13 @@ workos emulate
260
234
 
261
235
  # CI-friendly: JSON output, custom port
262
236
  workos emulate --port 9100 --json
263
- # → {"url":"http://localhost:9100","port":9100,"apiKey":"sk_test_default","health":"http://localhost:9100/health"}
264
237
 
265
238
  # Pre-load seed data
266
239
  workos emulate --seed workos-emulate.config.yaml
267
- ```
268
240
 
269
- The emulator supports `GET /health` for readiness polling and shuts down cleanly on Ctrl+C.
270
-
271
- #### Seed configuration
272
-
273
- Create a `workos-emulate.config.yaml` (auto-detected) or pass `--seed <path>`:
274
-
275
- ```yaml
276
- users:
277
- - email: alice@acme.com
278
- first_name: Alice
279
- password: test123
280
- email_verified: true
281
-
282
- organizations:
283
- - name: Acme Corp
284
- domains:
285
- - domain: acme.com
286
- state: verified
287
- memberships:
288
- - user_id: <user_id>
289
- role: admin
290
-
291
- connections:
292
- - name: Acme SSO
293
- organization: Acme Corp
294
- connection_type: GenericSAML
295
- domains: [acme.com]
296
-
297
- roles:
298
- - slug: admin
299
- name: Admin
300
- permissions: [posts:read, posts:write]
301
-
302
- permissions:
303
- - slug: posts:read
304
- name: Read Posts
305
- - slug: posts:write
306
- name: Write Posts
307
-
308
- webhookEndpoints:
309
- - url: http://localhost:3000/webhooks
310
- events: [user.created, organization.updated]
311
- ```
312
-
313
- #### Programmatic API
314
-
315
- Use the emulator directly in test suites without the CLI:
316
-
317
- ```typescript
318
- import { createEmulator } from 'workos/emulate';
319
-
320
- const emulator = await createEmulator({
321
- port: 0, // random available port
322
- seed: {
323
- users: [{ email: 'test@example.com', password: 'secret' }],
324
- },
325
- });
326
-
327
- // Use emulator.url as your WORKOS_API_BASE_URL
328
- const res = await fetch(`${emulator.url}/user_management/users`, {
329
- headers: { Authorization: 'Bearer sk_test_default' },
330
- });
331
-
332
- // Reset between tests (clears data, re-applies seed)
333
- emulator.reset();
334
-
335
- // Clean up
336
- await emulator.close();
337
- ```
338
-
339
- #### Emulated endpoints
340
-
341
- The emulator covers the full WorkOS API surface (~84% of OpenAPI spec endpoints). Run `pnpm check:coverage <openapi-spec>` to see exact coverage.
342
-
343
- | Endpoint Group | Routes |
344
- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
345
- | Organizations | CRUD, external_id lookup, domain management |
346
- | Users | CRUD, email uniqueness, password management |
347
- | Organization memberships | CRUD, role assignment, deactivate/reactivate |
348
- | Organization domains | CRUD, verification |
349
- | SSO connections | CRUD, domain-based lookup |
350
- | SSO flow | Authorize, token exchange, profile, JWKS, SSO logout |
351
- | AuthKit | OAuth authorize (login_hint, multi-user), authenticate (7 grant types incl. refresh_token, MFA TOTP, org selection, device code), PKCE, sealed sessions, impersonation |
352
- | Sessions | List, revoke, logout redirect, JWKS per client |
353
- | Email verification | Send code, confirm |
354
- | Password reset | Create token, confirm |
355
- | Magic auth | Create code |
356
- | Auth factors | TOTP enrollment, delete |
357
- | MFA challenges | Create challenge, verify code |
358
- | Invitations | CRUD, accept, revoke, resend, get by token |
359
- | Config | Redirect URIs, CORS origins, JWT template |
360
- | User features | Authorized apps, connected accounts, data providers |
361
- | Widgets | Token generation |
362
- | Authorization (RBAC) | Environment roles, org roles (priority ordering), permissions, role-permission management |
363
- | Authorization (FGA) | Resources CRUD, permission checks, role assignments |
364
- | Directory Sync | List/get/delete directories, users, groups |
365
- | Audit Logs | Actions, schemas, events, exports, org config/retention |
366
- | Feature Flags | List/get, enable/disable, targets, org/user evaluations |
367
- | Connect | Applications CRUD, client secrets |
368
- | Data Integrations | OAuth authorize + token exchange |
369
- | Radar | Attempts list/get, allow/deny lists |
370
- | API Keys | Validate, delete, list by org |
371
- | Portal | Generate admin portal links |
372
- | Legacy MFA | Enroll/get/delete factors, challenge/verify |
373
- | Webhook Endpoints | CRUD with auto-generated secrets, secret masking |
374
- | Events | Paginated event stream with type filtering |
375
- | Event Bus | Auto-emits events on entity CRUD via collection hooks, fire-and-forget webhook delivery with HMAC signatures |
376
- | Pipes | Connection CRUD, mock `getAccessToken()` |
377
-
378
- JWT tokens include `role` and `permissions` claims for org-scoped sessions. All list endpoints support cursor pagination (`before`, `after`, `limit`, `order`). Error responses match the WorkOS format (`{ message, code, errors }`).
379
-
380
- END UNRELEASED -->
241
+ # Show login pages for SSO/AuthKit browser testing
242
+ workos emulate --interactive
243
+ ```
381
244
 
382
245
  ### Environment Management
383
246
 
@@ -663,10 +526,10 @@ In agent mode the CLI:
663
526
 
664
527
  In `ci` mode the CLI additionally refuses browser-based auth flows and prefers terse failures over recovery handoff text.
665
528
 
666
- Legacy compatibility:
529
+ Mode resolution notes:
667
530
 
668
- - `WORKOS_NO_PROMPT=1` continues to work and is treated as agent interaction behavior plus JSON output.
669
- - `WORKOS_FORCE_TTY=1` continues to force human **output** mode but does not change interaction mode.
531
+ - `WORKOS_MODE=agent` sets agent interaction behavior and forces JSON output. (This replaces the removed `WORKOS_NO_PROMPT` alias.)
532
+ - `WORKOS_FORCE_TTY=1` forces human **output** mode but does not change interaction mode.
670
533
  - Non-TTY without an explicit mode still defaults output to JSON and interaction to agent.
671
534
 
672
535
  ### Headless Installer
@@ -697,7 +560,6 @@ workos install --api-key sk_test_xxx --client-id client_xxx --no-commit 2>/dev/n
697
560
  | `WORKOS_API_KEY` | API key for management commands (bypasses stored config) |
698
561
  | `WORKOS_API_BASE_URL` | Override API base URL (set automatically by `workos dev`) |
699
562
  | `WORKOS_MODE` | Interaction mode: `human`, `agent`, or `ci` |
700
- | `WORKOS_NO_PROMPT=1` | Legacy alias: agent interaction behavior + JSON output |
701
563
  | `WORKOS_FORCE_TTY=1` | Force human (non-JSON) **output** mode even when piped |
702
564
  | `WORKOS_TELEMETRY=false` | Disable telemetry |
703
565
 
package/dist/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  // Load .env.local for local development when --local flag is used
3
- if (process.argv.includes('--local') || process.env.INSTALLER_DEV) {
3
+ if (process.argv.includes('--local') || process.env.WORKOS_DEV) {
4
4
  const { config } = await import('dotenv');
5
5
  // bin.ts compiles to dist/bin.js, so go up one level to find .env.local
6
6
  const { fileURLToPath } = await import('node:url');
@@ -14,7 +14,7 @@ import { hideBin } from 'yargs/helpers';
14
14
  import { ensureAuthenticated } from './lib/ensure-auth.js';
15
15
  import { checkForUpdates } from './lib/version-check.js';
16
16
  const NODE_VERSION_RANGE = getConfig().nodeVersion;
17
- // Have to run this above the other imports because they are importing clack that
17
+ // Have to run this above the other imports because they are importing the UI facade that
18
18
  // has the problematic imports.
19
19
  if (!satisfies(process.version, NODE_VERSION_RANGE)) {
20
20
  red(`WorkOS AuthKit installer requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`);
@@ -22,7 +22,7 @@ if (!satisfies(process.version, NODE_VERSION_RANGE)) {
22
22
  }
23
23
  import { InvalidInteractionModeError, isPromptAllowed, resolveInteractionMode, setInteractionMode, } from './utils/interaction-mode.js';
24
24
  import { resolveEffectiveOutputMode, resolveOutputMode, setOutputMode, isJsonMode, outputJson, outputError, exitWithError, } from './utils/output.js';
25
- import clack from './utils/clack.js';
25
+ import ui, { PromptUnavailableError } from './utils/ui.js';
26
26
  import { registerSubcommand } from './utils/register-subcommand.js';
27
27
  import { installCrashReporter, sanitizeMessage } from './utils/crash-reporter.js';
28
28
  import { installStoreForward, recoverPendingEvents } from './utils/telemetry-store-forward.js';
@@ -34,6 +34,8 @@ import { CliExit } from './utils/cli-exit.js';
34
34
  import { telemetryClient } from './utils/telemetry-client.js';
35
35
  import { ExitCode } from './utils/exit-codes.js';
36
36
  import { analytics } from './utils/analytics.js';
37
+ import { formatWorkOSCommand, getWorkOSCommand } from './utils/command-invocation.js';
38
+ import { MIGRATIONS_DESCRIPTION } from './lib/constants.js';
37
39
  // Enable debug logging for all commands via env var.
38
40
  // Subsumes the installer's --debug flag for non-installer commands.
39
41
  if (process.env.WORKOS_DEBUG === '1') {
@@ -208,6 +210,11 @@ const installerOptions = {
208
210
  choices: ['npm', 'pnpm', 'yarn', 'bun'],
209
211
  type: 'string',
210
212
  },
213
+ router: {
214
+ choices: ['app', 'pages'],
215
+ describe: 'Next.js router to target when detection is ambiguous (app or pages)',
216
+ type: 'string',
217
+ },
211
218
  };
212
219
  // Check for updates (blocks up to 500ms, skip in JSON/non-human modes to keep machine streams clean)
213
220
  if (!isJsonMode() && isPromptAllowed())
@@ -267,8 +274,9 @@ async function runCli() {
267
274
  })
268
275
  .middleware(async (argv) => {
269
276
  // Warn about unclaimed environments before management commands.
270
- // Excluded: auth/claim/install/dashboard handle their own credential flows;
271
- // skills/doctor/env/debug are utility commands where the warning is unnecessary.
277
+ // Excluded: auth/claim/install/setup/dashboard handle their own credential
278
+ // or onboarding flows; skills/doctor/env/debug are utility commands where
279
+ // the warning is unnecessary.
272
280
  const command = String(argv._?.[0] ?? '');
273
281
  if ([
274
282
  'auth',
@@ -277,6 +285,7 @@ async function runCli() {
277
285
  'env',
278
286
  'claim',
279
287
  'install',
288
+ 'setup',
280
289
  'debug',
281
290
  'dashboard',
282
291
  'emulate',
@@ -373,6 +382,31 @@ async function runCli() {
373
382
  });
374
383
  });
375
384
  return yargs.demandCommand(1, 'Please specify a skills subcommand').strict();
385
+ })
386
+ .command('mcp', 'Manage the WorkOS MCP server in coding agents (Claude Code, Codex, Cursor)', (yargs) => {
387
+ registerSubcommand(yargs, 'install', 'Add the WorkOS MCP server to detected coding agents', (y) => y.option('agent', {
388
+ alias: 'a',
389
+ type: 'array',
390
+ string: true,
391
+ description: 'Target specific agent(s): claude-code, codex, cursor',
392
+ }), async (argv) => {
393
+ const { runMcpInstall } = await import('./commands/mcp.js');
394
+ await runMcpInstall({ agent: argv.agent });
395
+ });
396
+ registerSubcommand(yargs, 'remove', 'Remove the WorkOS MCP server from coding agents', (y) => y.option('agent', {
397
+ alias: 'a',
398
+ type: 'array',
399
+ string: true,
400
+ description: 'Target specific agent(s): claude-code, codex, cursor',
401
+ }), async (argv) => {
402
+ const { runMcpRemove } = await import('./commands/mcp.js');
403
+ await runMcpRemove({ agent: argv.agent });
404
+ });
405
+ registerSubcommand(yargs, 'status', 'Show which coding agents have the WorkOS MCP server configured', (y) => y, async () => {
406
+ const { runMcpStatus } = await import('./commands/mcp.js');
407
+ await runMcpStatus();
408
+ });
409
+ return yargs.demandCommand(1, 'Please specify an mcp subcommand').strict();
376
410
  })
377
411
  .command('doctor', 'Diagnose WorkOS AuthKit integration issues in the current project', (yargs) => yargs.options({
378
412
  verbose: {
@@ -413,6 +447,38 @@ async function runCli() {
413
447
  }), async (argv) => {
414
448
  const { handleDoctor } = await import('./commands/doctor.js');
415
449
  await handleDoctor(argv);
450
+ })
451
+ .command('verify-login', 'Verify the AuthKit login loop end-to-end against the active environment (creates and deletes a throwaway user)', (yargs) => yargs.options({
452
+ ...insecureStorageOption,
453
+ 'api-key': {
454
+ type: 'string',
455
+ describe: 'WorkOS API key (overrides environment config). Format: sk_test_* (production keys are refused)',
456
+ },
457
+ 'client-id': {
458
+ type: 'string',
459
+ describe: 'WorkOS client ID (overrides the active environment)',
460
+ },
461
+ method: {
462
+ type: 'string',
463
+ choices: ['password'],
464
+ default: 'password',
465
+ describe: 'Authentication method to verify',
466
+ },
467
+ }), async (argv) => {
468
+ await applyInsecureStorage(argv.insecureStorage);
469
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
470
+ const { getActiveEnvironment } = await import('./lib/config-store.js');
471
+ const { runVerifyLogin } = await import('./commands/verify-login.js');
472
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey }); // exits 4 if none
473
+ const activeEnv = getActiveEnvironment();
474
+ await runVerifyLogin({
475
+ apiKey,
476
+ clientId: argv.clientId ?? activeEnv?.clientId,
477
+ baseUrl: resolveApiBaseUrl(),
478
+ envType: activeEnv?.type ?? null,
479
+ envName: activeEnv?.name,
480
+ method: argv.method,
481
+ });
416
482
  })
417
483
  // NOTE: When adding commands here, also update src/utils/help-json.ts
418
484
  .command('env', 'Manage environment configurations (API keys, endpoints, active environment)', (yargs) => {
@@ -431,7 +497,7 @@ async function runCli() {
431
497
  endpoint: argv.endpoint,
432
498
  });
433
499
  });
434
- registerSubcommand(yargs, 'remove <name>', 'Remove an environment configuration', (y) => y.positional('name', { type: 'string', demandOption: true, describe: 'Environment name' }), async (argv) => {
500
+ registerSubcommand(yargs, 'remove <name>', 'Remove an environment from local CLI config (does not delete or unclaim the environment in WorkOS)', (y) => y.positional('name', { type: 'string', demandOption: true, describe: 'Environment name' }), async (argv) => {
435
501
  await applyInsecureStorage(argv.insecureStorage);
436
502
  const { runEnvRemove } = await import('./commands/env.js');
437
503
  await runEnvRemove(argv.name);
@@ -440,7 +506,7 @@ async function runCli() {
440
506
  if (!argv.name && !isPromptAllowed()) {
441
507
  exitWithError({
442
508
  code: 'missing_args',
443
- message: 'Environment name required. Usage: workos env switch <name>',
509
+ message: `Environment name required. Usage: ${formatWorkOSCommand('env switch <name>')}`,
444
510
  });
445
511
  }
446
512
  await applyInsecureStorage(argv.insecureStorage);
@@ -452,11 +518,16 @@ async function runCli() {
452
518
  const { runEnvList } = await import('./commands/env.js');
453
519
  await runEnvList();
454
520
  });
455
- registerSubcommand(yargs, 'claim', 'Claim an unclaimed environment (link it to your account)', (y) => y, async (argv) => {
521
+ registerSubcommand(yargs, 'claim', 'Claim an unclaimed environment link it to your account (permanent — cannot be undone)', (y) => y, async (argv) => {
456
522
  await applyInsecureStorage(argv.insecureStorage);
457
523
  const { runClaim } = await import('./commands/claim.js');
458
524
  await runClaim();
459
525
  });
526
+ registerSubcommand(yargs, 'provision', 'Provision a new unclaimed WorkOS environment (credentials only, no code changes)', (y) => y, async (argv) => {
527
+ await applyInsecureStorage(argv.insecureStorage);
528
+ const { runEnvProvision } = await import('./commands/env.js');
529
+ await runEnvProvision();
530
+ });
460
531
  return yargs.demandCommand(1, 'Please specify an env subcommand').strict();
461
532
  })
462
533
  .command('api [endpoint] [filter]', 'Make authenticated requests to the WorkOS API', (yargs) => yargs
@@ -1396,6 +1467,30 @@ async function runCli() {
1396
1467
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1397
1468
  const { runSeed } = await import('./commands/seed.js');
1398
1469
  await runSeed({ file: argv.file, clean: argv.clean, init: argv.init }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1470
+ })
1471
+ .command('setup', 'Set up your coding agent (install WorkOS skills + MCP server)', (yargs) => yargs.options({
1472
+ ...insecureStorageOption,
1473
+ agents: { type: 'string', describe: 'Comma-separated agent keys (claude-code, codex, cursor, goose)' },
1474
+ 'skills-only': { type: 'boolean', describe: 'Install skills only (skip the MCP server)' },
1475
+ 'mcp-only': { type: 'boolean', describe: 'Install the MCP server only (skip skills)' },
1476
+ yes: { type: 'boolean', alias: 'y', describe: 'Install without prompting' },
1477
+ reset: { type: 'boolean', describe: 'Re-enable automatic setup offers after a decline' },
1478
+ }), async (argv) => {
1479
+ await applyInsecureStorage(argv.insecureStorage);
1480
+ const { runSetup } = await import('./commands/setup.js');
1481
+ await runSetup({
1482
+ trigger: 'command',
1483
+ agents: argv.agents
1484
+ ? String(argv.agents)
1485
+ .split(',')
1486
+ .map((a) => a.trim())
1487
+ .filter(Boolean)
1488
+ : undefined,
1489
+ skillsOnly: argv.skillsOnly,
1490
+ mcpOnly: argv.mcpOnly,
1491
+ assumeYes: argv.yes,
1492
+ reset: argv.reset,
1493
+ });
1399
1494
  })
1400
1495
  .command('setup-org <name>', 'One-shot organization onboarding (create org, domain, roles, portal link)', (yargs) => yargs.positional('name', { type: 'string', demandOption: true, describe: 'Organization name' }).options({
1401
1496
  ...insecureStorageOption,
@@ -1439,7 +1534,7 @@ async function runCli() {
1439
1534
  await runDebugSync(argv.directoryId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1440
1535
  })
1441
1536
  // Alias — canonical command is `workos env claim`
1442
- .command('claim', 'Claim an unclaimed WorkOS environment (link it to your account)', (yargs) => yargs.options({
1537
+ .command('claim', 'Claim an unclaimed WorkOS environment link it to your account (permanent — cannot be undone)', (yargs) => yargs.options({
1443
1538
  ...insecureStorageOption,
1444
1539
  }), async (argv) => {
1445
1540
  await applyInsecureStorage(argv.insecureStorage);
@@ -1451,14 +1546,6 @@ async function runCli() {
1451
1546
  await resolveInstallCredentials(argv.apiKey, argv.installDir, argv.skipAuth, ensureAuthenticated);
1452
1547
  const { handleInstall } = await import('./commands/install.js');
1453
1548
  await handleInstall(argv);
1454
- })
1455
- .command('emulate', false, // Hidden: unreleased beta feature
1456
- (yargs) => yargs.options({
1457
- port: { type: 'number', default: 4100, describe: 'Port to listen on' },
1458
- seed: { type: 'string', describe: 'Path to seed config file (YAML or JSON)' },
1459
- }), async (argv) => {
1460
- const { runEmulate } = await import('./commands/emulate.js');
1461
- await runEmulate({ port: argv.port, seed: argv.seed, json: argv.json });
1462
1549
  })
1463
1550
  .command('dev', false, // Hidden: unreleased beta feature
1464
1551
  (yargs) => yargs.options({
@@ -1471,6 +1558,33 @@ async function runCli() {
1471
1558
  seed: argv.seed,
1472
1559
  '--': argv['--'],
1473
1560
  });
1561
+ })
1562
+ .command('emulate', 'Start a local WorkOS API emulator', (yargs) => yargs.options({
1563
+ port: {
1564
+ alias: 'p',
1565
+ type: 'number',
1566
+ default: 4100,
1567
+ describe: 'Port to listen on',
1568
+ },
1569
+ seed: {
1570
+ alias: 's',
1571
+ type: 'string',
1572
+ describe: 'Path to seed config file (YAML or JSON)',
1573
+ },
1574
+ interactive: {
1575
+ alias: 'i',
1576
+ type: 'boolean',
1577
+ default: false,
1578
+ describe: 'Show login pages for SSO/AuthKit',
1579
+ },
1580
+ }), async (argv) => {
1581
+ const { runEmulate } = await import('./commands/emulate.js');
1582
+ await runEmulate({
1583
+ port: argv.port,
1584
+ seed: argv.seed,
1585
+ json: argv.json,
1586
+ interactive: argv.interactive,
1587
+ });
1474
1588
  })
1475
1589
  .command('debug', false, (yargs) => {
1476
1590
  yargs.options(insecureStorageOption);
@@ -1552,9 +1666,9 @@ async function runCli() {
1552
1666
  const { runDebugToken } = await import('./commands/debug.js');
1553
1667
  await runDebugToken();
1554
1668
  });
1555
- return yargs.demandCommand(1, 'Run "workos debug <command>" for debug tools.').strict();
1669
+ return yargs.demandCommand(1, `Run "${getWorkOSCommand()} debug <command>" for debug tools.`).strict();
1556
1670
  })
1557
- .command('migrations', 'Migrate users from identity providers (Auth0, Cognito, Clerk, Firebase) to WorkOS', (yargs) => yargs
1671
+ .command('migrations', MIGRATIONS_DESCRIPTION, (yargs) => yargs
1558
1672
  .strictCommands(false)
1559
1673
  .strict(false)
1560
1674
  .help(false)
@@ -1579,16 +1693,23 @@ async function runCli() {
1579
1693
  await handleInstall({ ...argv, dashboard: true });
1580
1694
  })
1581
1695
  .command(['$0'], 'WorkOS AuthKit CLI', (yargs) => yargs.options(insecureStorageOption), async (argv) => {
1582
- // Non-human modes: show help instead of prompting
1696
+ // Non-human modes: emit machine-readable command tree (JSON) or the
1697
+ // fully-configured parser help (human non-TTY edge) instead of prompting.
1583
1698
  if (!isPromptAllowed()) {
1584
- yargs(rawArgs).showHelp();
1699
+ if (isJsonMode()) {
1700
+ const { buildCommandTree } = await import('./utils/help-json.js');
1701
+ outputJson(buildCommandTree());
1702
+ }
1703
+ else {
1704
+ parser.showHelp();
1705
+ }
1585
1706
  return;
1586
1707
  }
1587
1708
  // TTY: ask if user wants to run installer
1588
- const shouldInstall = await clack.confirm({
1709
+ const shouldInstall = await ui.confirm({
1589
1710
  message: 'Run the AuthKit installer?',
1590
1711
  });
1591
- if (clack.isCancel(shouldInstall) || !shouldInstall) {
1712
+ if (ui.isCancel(shouldInstall) || !shouldInstall) {
1592
1713
  return;
1593
1714
  }
1594
1715
  await applyInsecureStorage(argv.insecureStorage);
@@ -1628,6 +1749,17 @@ async function runCli() {
1628
1749
  },
1629
1750
  };
1630
1751
  }
1752
+ else if (error instanceof PromptUnavailableError) {
1753
+ // A prompt was attempted where the user can't answer (--json, or non-TTY
1754
+ // stdin) on a direct command. Not a crash — surface a clear, structured
1755
+ // error with its own code so scripts and telemetry can distinguish it.
1756
+ process.exitCode = 1;
1757
+ commandOutcome = {
1758
+ success: false,
1759
+ options: { flags, reason: 'validation_error', errorCode: 'prompt_unavailable' },
1760
+ };
1761
+ outputError({ code: 'prompt_unavailable', message: error.message });
1762
+ }
1631
1763
  else {
1632
1764
  // Unexpected error (crash)
1633
1765
  process.exitCode = 1;