workos 0.18.0 → 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 (333) hide show
  1. package/README.md +8 -145
  2. package/dist/bin.js +129 -50
  3. package/dist/bin.js.map +1 -1
  4. package/dist/commands/api/index.js +18 -10
  5. package/dist/commands/api/index.js.map +1 -1
  6. package/dist/commands/api/interactive.js +11 -11
  7. package/dist/commands/api/interactive.js.map +1 -1
  8. package/dist/commands/claim.js +28 -16
  9. package/dist/commands/claim.js.map +1 -1
  10. package/dist/commands/connection.js +3 -3
  11. package/dist/commands/connection.js.map +1 -1
  12. package/dist/commands/debug.js +6 -6
  13. package/dist/commands/debug.js.map +1 -1
  14. package/dist/commands/dev.d.ts +7 -8
  15. package/dist/commands/dev.js +14 -14
  16. package/dist/commands/dev.js.map +1 -1
  17. package/dist/commands/directory.js +3 -3
  18. package/dist/commands/directory.js.map +1 -1
  19. package/dist/commands/doctor.js +2 -2
  20. package/dist/commands/doctor.js.map +1 -1
  21. package/dist/commands/emulate.d.ts +1 -0
  22. package/dist/commands/emulate.js +3 -2
  23. package/dist/commands/emulate.js.map +1 -1
  24. package/dist/commands/env.d.ts +10 -0
  25. package/dist/commands/env.js +94 -18
  26. package/dist/commands/env.js.map +1 -1
  27. package/dist/commands/install.js +8 -13
  28. package/dist/commands/install.js.map +1 -1
  29. package/dist/commands/login.d.ts +25 -15
  30. package/dist/commands/login.js +126 -71
  31. package/dist/commands/login.js.map +1 -1
  32. package/dist/commands/logout.js +4 -4
  33. package/dist/commands/logout.js.map +1 -1
  34. package/dist/commands/mcp.js +7 -16
  35. package/dist/commands/mcp.js.map +1 -1
  36. package/dist/commands/migrations.js +2 -1
  37. package/dist/commands/migrations.js.map +1 -1
  38. package/dist/commands/seed.js +5 -4
  39. package/dist/commands/seed.js.map +1 -1
  40. package/dist/commands/setup.d.ts +50 -0
  41. package/dist/commands/setup.js +237 -0
  42. package/dist/commands/setup.js.map +1 -0
  43. package/dist/commands/vault-run.js +3 -2
  44. package/dist/commands/vault-run.js.map +1 -1
  45. package/dist/commands/verify-login.d.ts +25 -0
  46. package/dist/commands/verify-login.js +158 -0
  47. package/dist/commands/verify-login.js.map +1 -0
  48. package/dist/doctor/issues.js +3 -2
  49. package/dist/doctor/issues.js.map +1 -1
  50. package/dist/doctor/output.js +2 -1
  51. package/dist/doctor/output.js.map +1 -1
  52. package/dist/integrations/dotnet/index.js +1 -1
  53. package/dist/integrations/dotnet/index.js.map +1 -1
  54. package/dist/integrations/elixir/index.js +1 -1
  55. package/dist/integrations/elixir/index.js.map +1 -1
  56. package/dist/integrations/go/index.js +1 -1
  57. package/dist/integrations/go/index.js.map +1 -1
  58. package/dist/integrations/nextjs/index.js +8 -5
  59. package/dist/integrations/nextjs/index.js.map +1 -1
  60. package/dist/integrations/nextjs/utils.d.ts +1 -1
  61. package/dist/integrations/nextjs/utils.js +21 -6
  62. package/dist/integrations/nextjs/utils.js.map +1 -1
  63. package/dist/integrations/react-router/index.js +5 -5
  64. package/dist/integrations/react-router/index.js.map +1 -1
  65. package/dist/integrations/react-router/utils.js +28 -12
  66. package/dist/integrations/react-router/utils.js.map +1 -1
  67. package/dist/integrations/ruby/index.js +1 -1
  68. package/dist/integrations/ruby/index.js.map +1 -1
  69. package/dist/lib/adapters/cli-adapter.d.ts +33 -4
  70. package/dist/lib/adapters/cli-adapter.js +251 -135
  71. package/dist/lib/adapters/cli-adapter.js.map +1 -1
  72. package/dist/lib/adapters/dashboard-adapter.js +3 -3
  73. package/dist/lib/adapters/dashboard-adapter.js.map +1 -1
  74. package/dist/lib/adapters/headless-adapter.d.ts +7 -0
  75. package/dist/lib/adapters/headless-adapter.js +42 -5
  76. package/dist/lib/adapters/headless-adapter.js.map +1 -1
  77. package/dist/lib/agent-interface.js +15 -1
  78. package/dist/lib/agent-interface.js.map +1 -1
  79. package/dist/lib/agent-runner.js +1 -1
  80. package/dist/lib/agent-runner.js.map +1 -1
  81. package/dist/lib/api-key.js +2 -1
  82. package/dist/lib/api-key.js.map +1 -1
  83. package/dist/lib/completion-data.d.ts +33 -0
  84. package/dist/lib/completion-data.js +33 -0
  85. package/dist/lib/completion-data.js.map +1 -0
  86. package/dist/lib/config-store.d.ts +13 -0
  87. package/dist/lib/config-store.js +24 -0
  88. package/dist/lib/config-store.js.map +1 -1
  89. package/dist/lib/config.d.ts +1 -1
  90. package/dist/lib/config.js +1 -1
  91. package/dist/lib/config.js.map +1 -1
  92. package/dist/lib/constants.d.ts +8 -0
  93. package/dist/lib/constants.js +8 -0
  94. package/dist/lib/constants.js.map +1 -1
  95. package/dist/lib/events.d.ts +34 -1
  96. package/dist/lib/events.js.map +1 -1
  97. package/dist/lib/framework-config.d.ts +6 -0
  98. package/dist/lib/framework-config.js.map +1 -1
  99. package/dist/lib/installer-core.d.ts +14 -1
  100. package/dist/lib/installer-core.js +24 -5
  101. package/dist/lib/installer-core.js.map +1 -1
  102. package/dist/lib/installer-core.types.d.ts +3 -1
  103. package/dist/lib/installer-core.types.js.map +1 -1
  104. package/dist/lib/mcp-clients.d.ts +6 -0
  105. package/dist/lib/mcp-clients.js +13 -0
  106. package/dist/lib/mcp-clients.js.map +1 -1
  107. package/dist/lib/port-detection.js +19 -13
  108. package/dist/lib/port-detection.js.map +1 -1
  109. package/dist/lib/preferences.d.ts +30 -2
  110. package/dist/lib/preferences.js +34 -8
  111. package/dist/lib/preferences.js.map +1 -1
  112. package/dist/lib/run-with-core.js +40 -3
  113. package/dist/lib/run-with-core.js.map +1 -1
  114. package/dist/lib/telemetry-notice.d.ts +5 -5
  115. package/dist/lib/telemetry-notice.js +7 -8
  116. package/dist/lib/telemetry-notice.js.map +1 -1
  117. package/dist/lib/unclaimed-env-provision.js +15 -12
  118. package/dist/lib/unclaimed-env-provision.js.map +1 -1
  119. package/dist/lib/unclaimed-warning.js +4 -3
  120. package/dist/lib/unclaimed-warning.js.map +1 -1
  121. package/dist/lib/validation/security-checks.js +2 -1
  122. package/dist/lib/validation/security-checks.js.map +1 -1
  123. package/dist/lib/validation/validator.js +30 -3
  124. package/dist/lib/validation/validator.js.map +1 -1
  125. package/dist/lib/workos-management.js +26 -19
  126. package/dist/lib/workos-management.js.map +1 -1
  127. package/dist/run.d.ts +1 -0
  128. package/dist/run.js +5 -1
  129. package/dist/run.js.map +1 -1
  130. package/dist/steps/add-or-update-environment-variables.js +10 -10
  131. package/dist/steps/add-or-update-environment-variables.js.map +1 -1
  132. package/dist/steps/run-prettier.js +3 -3
  133. package/dist/steps/run-prettier.js.map +1 -1
  134. package/dist/steps/upload-environment-variables/index.js +15 -3
  135. package/dist/steps/upload-environment-variables/index.js.map +1 -1
  136. package/dist/steps/upload-environment-variables/providers/vercel.js +2 -2
  137. package/dist/steps/upload-environment-variables/providers/vercel.js.map +1 -1
  138. package/dist/utils/box.d.ts +6 -30
  139. package/dist/utils/box.js +8 -95
  140. package/dist/utils/box.js.map +1 -1
  141. package/dist/utils/cli-symbols.d.ts +14 -2
  142. package/dist/utils/cli-symbols.js +12 -0
  143. package/dist/utils/cli-symbols.js.map +1 -1
  144. package/dist/utils/debug.js +3 -3
  145. package/dist/utils/debug.js.map +1 -1
  146. package/dist/utils/environment.js +1 -1
  147. package/dist/utils/environment.js.map +1 -1
  148. package/dist/utils/help-json.js +115 -4
  149. package/dist/utils/help-json.js.map +1 -1
  150. package/dist/utils/package-manager.js +1 -1
  151. package/dist/utils/package-manager.js.map +1 -1
  152. package/dist/utils/recovery-hints.d.ts +5 -0
  153. package/dist/utils/recovery-hints.js +12 -0
  154. package/dist/utils/recovery-hints.js.map +1 -1
  155. package/dist/utils/summary-box.d.ts +8 -1
  156. package/dist/utils/summary-box.js +67 -4
  157. package/dist/utils/summary-box.js.map +1 -1
  158. package/dist/utils/types.d.ts +10 -0
  159. package/dist/utils/types.js.map +1 -1
  160. package/dist/utils/{clack-utils.d.ts → ui-utils.d.ts} +1 -1
  161. package/dist/utils/{clack-utils.js → ui-utils.js} +64 -37
  162. package/dist/utils/ui-utils.js.map +1 -0
  163. package/dist/utils/ui.d.ts +148 -0
  164. package/dist/utils/ui.js +368 -0
  165. package/dist/utils/ui.js.map +1 -0
  166. package/package.json +5 -13
  167. package/dist/check-coverage.ts +0 -237
  168. package/dist/emulate/core/id.d.ts +0 -48
  169. package/dist/emulate/core/id.js +0 -73
  170. package/dist/emulate/core/id.js.map +0 -1
  171. package/dist/emulate/core/index.d.ts +0 -8
  172. package/dist/emulate/core/index.js +0 -8
  173. package/dist/emulate/core/index.js.map +0 -1
  174. package/dist/emulate/core/jwt.d.ts +0 -28
  175. package/dist/emulate/core/jwt.js +0 -78
  176. package/dist/emulate/core/jwt.js.map +0 -1
  177. package/dist/emulate/core/middleware/auth.d.ts +0 -15
  178. package/dist/emulate/core/middleware/auth.js +0 -17
  179. package/dist/emulate/core/middleware/auth.js.map +0 -1
  180. package/dist/emulate/core/middleware/error-handler.d.ts +0 -22
  181. package/dist/emulate/core/middleware/error-handler.js +0 -72
  182. package/dist/emulate/core/middleware/error-handler.js.map +0 -1
  183. package/dist/emulate/core/pagination.d.ts +0 -27
  184. package/dist/emulate/core/pagination.js +0 -43
  185. package/dist/emulate/core/pagination.js.map +0 -1
  186. package/dist/emulate/core/plugin.d.ts +0 -15
  187. package/dist/emulate/core/plugin.js +0 -2
  188. package/dist/emulate/core/plugin.js.map +0 -1
  189. package/dist/emulate/core/server.d.ts +0 -17
  190. package/dist/emulate/core/server.js +0 -90
  191. package/dist/emulate/core/server.js.map +0 -1
  192. package/dist/emulate/core/store.d.ts +0 -44
  193. package/dist/emulate/core/store.js +0 -169
  194. package/dist/emulate/core/store.js.map +0 -1
  195. package/dist/emulate/index.d.ts +0 -25
  196. package/dist/emulate/index.js +0 -47
  197. package/dist/emulate/index.js.map +0 -1
  198. package/dist/emulate/workos/constants.d.ts +0 -56
  199. package/dist/emulate/workos/constants.js +0 -56
  200. package/dist/emulate/workos/constants.js.map +0 -1
  201. package/dist/emulate/workos/entities.d.ts +0 -360
  202. package/dist/emulate/workos/entities.js +0 -2
  203. package/dist/emulate/workos/entities.js.map +0 -1
  204. package/dist/emulate/workos/event-bus.d.ts +0 -17
  205. package/dist/emulate/workos/event-bus.js +0 -70
  206. package/dist/emulate/workos/event-bus.js.map +0 -1
  207. package/dist/emulate/workos/helpers.d.ts +0 -72
  208. package/dist/emulate/workos/helpers.js +0 -211
  209. package/dist/emulate/workos/helpers.js.map +0 -1
  210. package/dist/emulate/workos/index.d.ts +0 -93
  211. package/dist/emulate/workos/index.js +0 -326
  212. package/dist/emulate/workos/index.js.map +0 -1
  213. package/dist/emulate/workos/role-helpers.d.ts +0 -21
  214. package/dist/emulate/workos/role-helpers.js +0 -130
  215. package/dist/emulate/workos/role-helpers.js.map +0 -1
  216. package/dist/emulate/workos/routes/api-keys.d.ts +0 -2
  217. package/dist/emulate/workos/routes/api-keys.js +0 -32
  218. package/dist/emulate/workos/routes/api-keys.js.map +0 -1
  219. package/dist/emulate/workos/routes/audit-logs.d.ts +0 -2
  220. package/dist/emulate/workos/routes/audit-logs.js +0 -104
  221. package/dist/emulate/workos/routes/audit-logs.js.map +0 -1
  222. package/dist/emulate/workos/routes/auth-challenges.d.ts +0 -2
  223. package/dist/emulate/workos/routes/auth-challenges.js +0 -51
  224. package/dist/emulate/workos/routes/auth-challenges.js.map +0 -1
  225. package/dist/emulate/workos/routes/auth-factors.d.ts +0 -2
  226. package/dist/emulate/workos/routes/auth-factors.js +0 -51
  227. package/dist/emulate/workos/routes/auth-factors.js.map +0 -1
  228. package/dist/emulate/workos/routes/auth.d.ts +0 -2
  229. package/dist/emulate/workos/routes/auth.js +0 -350
  230. package/dist/emulate/workos/routes/auth.js.map +0 -1
  231. package/dist/emulate/workos/routes/authorization-checks.d.ts +0 -10
  232. package/dist/emulate/workos/routes/authorization-checks.js +0 -123
  233. package/dist/emulate/workos/routes/authorization-checks.js.map +0 -1
  234. package/dist/emulate/workos/routes/authorization-org-roles.d.ts +0 -2
  235. package/dist/emulate/workos/routes/authorization-org-roles.js +0 -64
  236. package/dist/emulate/workos/routes/authorization-org-roles.js.map +0 -1
  237. package/dist/emulate/workos/routes/authorization-permissions.d.ts +0 -2
  238. package/dist/emulate/workos/routes/authorization-permissions.js +0 -67
  239. package/dist/emulate/workos/routes/authorization-permissions.js.map +0 -1
  240. package/dist/emulate/workos/routes/authorization-resources.d.ts +0 -2
  241. package/dist/emulate/workos/routes/authorization-resources.js +0 -117
  242. package/dist/emulate/workos/routes/authorization-resources.js.map +0 -1
  243. package/dist/emulate/workos/routes/authorization-roles.d.ts +0 -2
  244. package/dist/emulate/workos/routes/authorization-roles.js +0 -13
  245. package/dist/emulate/workos/routes/authorization-roles.js.map +0 -1
  246. package/dist/emulate/workos/routes/config.d.ts +0 -2
  247. package/dist/emulate/workos/routes/config.js +0 -57
  248. package/dist/emulate/workos/routes/config.js.map +0 -1
  249. package/dist/emulate/workos/routes/connect.d.ts +0 -2
  250. package/dist/emulate/workos/routes/connect.js +0 -65
  251. package/dist/emulate/workos/routes/connect.js.map +0 -1
  252. package/dist/emulate/workos/routes/connections.d.ts +0 -2
  253. package/dist/emulate/workos/routes/connections.js +0 -73
  254. package/dist/emulate/workos/routes/connections.js.map +0 -1
  255. package/dist/emulate/workos/routes/data-integrations.d.ts +0 -2
  256. package/dist/emulate/workos/routes/data-integrations.js +0 -55
  257. package/dist/emulate/workos/routes/data-integrations.js.map +0 -1
  258. package/dist/emulate/workos/routes/directories.d.ts +0 -2
  259. package/dist/emulate/workos/routes/directories.js +0 -90
  260. package/dist/emulate/workos/routes/directories.js.map +0 -1
  261. package/dist/emulate/workos/routes/email-verification.d.ts +0 -2
  262. package/dist/emulate/workos/routes/email-verification.js +0 -49
  263. package/dist/emulate/workos/routes/email-verification.js.map +0 -1
  264. package/dist/emulate/workos/routes/events.d.ts +0 -2
  265. package/dist/emulate/workos/routes/events.js +0 -18
  266. package/dist/emulate/workos/routes/events.js.map +0 -1
  267. package/dist/emulate/workos/routes/feature-flags.d.ts +0 -2
  268. package/dist/emulate/workos/routes/feature-flags.js +0 -103
  269. package/dist/emulate/workos/routes/feature-flags.js.map +0 -1
  270. package/dist/emulate/workos/routes/invitations.d.ts +0 -2
  271. package/dist/emulate/workos/routes/invitations.js +0 -122
  272. package/dist/emulate/workos/routes/invitations.js.map +0 -1
  273. package/dist/emulate/workos/routes/legacy-mfa.d.ts +0 -2
  274. package/dist/emulate/workos/routes/legacy-mfa.js +0 -75
  275. package/dist/emulate/workos/routes/legacy-mfa.js.map +0 -1
  276. package/dist/emulate/workos/routes/magic-auth.d.ts +0 -2
  277. package/dist/emulate/workos/routes/magic-auth.js +0 -32
  278. package/dist/emulate/workos/routes/magic-auth.js.map +0 -1
  279. package/dist/emulate/workos/routes/memberships.d.ts +0 -2
  280. package/dist/emulate/workos/routes/memberships.js +0 -114
  281. package/dist/emulate/workos/routes/memberships.js.map +0 -1
  282. package/dist/emulate/workos/routes/organization-domains.d.ts +0 -2
  283. package/dist/emulate/workos/routes/organization-domains.js +0 -58
  284. package/dist/emulate/workos/routes/organization-domains.js.map +0 -1
  285. package/dist/emulate/workos/routes/organizations.d.ts +0 -2
  286. package/dist/emulate/workos/routes/organizations.js +0 -131
  287. package/dist/emulate/workos/routes/organizations.js.map +0 -1
  288. package/dist/emulate/workos/routes/password-reset.d.ts +0 -2
  289. package/dist/emulate/workos/routes/password-reset.js +0 -61
  290. package/dist/emulate/workos/routes/password-reset.js.map +0 -1
  291. package/dist/emulate/workos/routes/pipes.d.ts +0 -2
  292. package/dist/emulate/workos/routes/pipes.js +0 -82
  293. package/dist/emulate/workos/routes/pipes.js.map +0 -1
  294. package/dist/emulate/workos/routes/portal.d.ts +0 -2
  295. package/dist/emulate/workos/routes/portal.js +0 -18
  296. package/dist/emulate/workos/routes/portal.js.map +0 -1
  297. package/dist/emulate/workos/routes/radar.d.ts +0 -2
  298. package/dist/emulate/workos/routes/radar.js +0 -41
  299. package/dist/emulate/workos/routes/radar.js.map +0 -1
  300. package/dist/emulate/workos/routes/sessions.d.ts +0 -2
  301. package/dist/emulate/workos/routes/sessions.js +0 -51
  302. package/dist/emulate/workos/routes/sessions.js.map +0 -1
  303. package/dist/emulate/workos/routes/sso.d.ts +0 -2
  304. package/dist/emulate/workos/routes/sso.js +0 -161
  305. package/dist/emulate/workos/routes/sso.js.map +0 -1
  306. package/dist/emulate/workos/routes/user-features.d.ts +0 -2
  307. package/dist/emulate/workos/routes/user-features.js +0 -50
  308. package/dist/emulate/workos/routes/user-features.js.map +0 -1
  309. package/dist/emulate/workos/routes/users.d.ts +0 -2
  310. package/dist/emulate/workos/routes/users.js +0 -129
  311. package/dist/emulate/workos/routes/users.js.map +0 -1
  312. package/dist/emulate/workos/routes/webhook-endpoints.d.ts +0 -2
  313. package/dist/emulate/workos/routes/webhook-endpoints.js +0 -67
  314. package/dist/emulate/workos/routes/webhook-endpoints.js.map +0 -1
  315. package/dist/emulate/workos/routes/widgets.d.ts +0 -2
  316. package/dist/emulate/workos/routes/widgets.js +0 -27
  317. package/dist/emulate/workos/routes/widgets.js.map +0 -1
  318. package/dist/emulate/workos/store.d.ts +0 -48
  319. package/dist/emulate/workos/store.js +0 -102
  320. package/dist/emulate/workos/store.js.map +0 -1
  321. package/dist/emulate/workos/webhook-signer.d.ts +0 -1
  322. package/dist/emulate/workos/webhook-signer.js +0 -8
  323. package/dist/emulate/workos/webhook-signer.js.map +0 -1
  324. package/dist/gen-routes-lib.spec.ts +0 -659
  325. package/dist/gen-routes-lib.ts +0 -647
  326. package/dist/gen-routes.ts +0 -96
  327. package/dist/lib/mcp-notice.d.ts +0 -72
  328. package/dist/lib/mcp-notice.js +0 -275
  329. package/dist/lib/mcp-notice.js.map +0 -1
  330. package/dist/utils/clack-utils.js.map +0 -1
  331. package/dist/utils/clack.d.ts +0 -5
  332. package/dist/utils/clack.js +0 -34
  333. package/dist/utils/clack.js.map +0 -1
@@ -5,29 +5,29 @@ import { apiRequest } from './request.js';
5
5
  import { resolveApiBaseUrl } from '../../lib/api-key.js';
6
6
  import { exitWithError, isJsonMode, outputJson } from '../../utils/output.js';
7
7
  import { ExitCode, exitWithCode } from '../../utils/exit-codes.js';
8
- import { isCiMode, isPromptAllowed } from '../../utils/interaction-mode.js';
9
- import { confirmationRecovery } from '../../utils/recovery-hints.js';
10
- import { formatWorkOSCommandArgs } from '../../utils/command-invocation.js';
8
+ import { isCiMode, isPromptAllowed, getInteractionMode } from '../../utils/interaction-mode.js';
9
+ import { confirmationRecovery, authLoginRecovery, missingArgsRecovery } from '../../utils/recovery-hints.js';
10
+ import { formatWorkOSCommand, formatWorkOSCommandArgs } from '../../utils/command-invocation.js';
11
11
  import { colorMethod, printResponse } from './format.js';
12
12
  export { colorMethod } from './format.js';
13
13
  const MUTATING_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
14
14
  export async function runApiInteractive(options) {
15
- // Interactive mode is inherently human-oriented (clack prompts, preview text,
15
+ // Interactive mode is inherently human-oriented (interactive prompts, preview text,
16
16
  // etc.). Refuse to enter it whenever JSON output was requested, regardless of
17
17
  // TTY status, so stdout stays machine-readable.
18
18
  if (isJsonMode()) {
19
19
  exitWithError({
20
20
  code: 'tty_required',
21
- message: 'Interactive mode is not available with --json. Provide an endpoint or use `workos api ls`.',
21
+ message: `Interactive mode is not available with --json. Provide an endpoint or use \`${formatWorkOSCommand('api ls')}\`.`,
22
22
  details: {
23
- usage: ['workos api <endpoint>', 'workos api ls [filter]'],
23
+ usage: [formatWorkOSCommand('api <endpoint>'), formatWorkOSCommand('api ls [filter]')],
24
24
  },
25
25
  });
26
26
  }
27
27
  if (!isPromptAllowed()) {
28
28
  exitWithError({
29
29
  code: 'tty_required',
30
- message: 'Interactive API mode requires human mode. Usage: workos api <endpoint> or workos api ls [filter]. Example: workos api /user_management/users',
30
+ message: `Interactive API mode requires human mode. Usage: ${formatWorkOSCommand('api <endpoint>')} or ${formatWorkOSCommand('api ls [filter]')}. Example: ${formatWorkOSCommand('api /user_management/users')}`,
31
31
  });
32
32
  }
33
33
  const { apiInteractive } = await import('./interactive.js');
@@ -116,12 +116,12 @@ export async function runApiRequest(endpoint, options) {
116
116
  recovery: confirmationRecovery(confirmCommand),
117
117
  });
118
118
  }
119
- const clack = (await import('../../utils/clack.js')).default;
119
+ const ui = (await import('../../utils/ui.js')).default;
120
120
  console.log(`\n${chalk.yellow('About to')} ${method} ${endpoint}`);
121
121
  if (hasBody)
122
122
  prettyPrint(body);
123
- const ok = await clack.confirm({ message: 'Proceed?' });
124
- if (!ok || clack.isCancel(ok)) {
123
+ const ok = await ui.confirm({ message: 'Proceed?' });
124
+ if (!ok || ui.isCancel(ok)) {
125
125
  exitWithCode(ExitCode.CANCELLED);
126
126
  }
127
127
  }
@@ -134,10 +134,18 @@ export async function runApiRequest(endpoint, options) {
134
134
  });
135
135
  printResponse(response, { includeStatus: options.include });
136
136
  if (response.status >= 400) {
137
+ // Give the caller a concrete next step keyed off the status: re-auth for
138
+ // 401/403, discover endpoints for 404.
139
+ const recovery = response.status === 401 || response.status === 403
140
+ ? authLoginRecovery({ mode: getInteractionMode().mode })
141
+ : response.status === 404
142
+ ? missingArgsRecovery(formatWorkOSCommand('api ls'), 'List available endpoints, then re-run with a valid path.')
143
+ : undefined;
137
144
  exitWithError({
138
145
  code: `http_${response.status}`,
139
146
  message: `API request failed with status ${response.status}`,
140
147
  apiContext: { status: response.status },
148
+ ...(recovery && { recovery }),
141
149
  });
142
150
  }
143
151
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/api/index.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { readFile } from 'node:fs/promises';\nimport { loadCatalog, endpointsByTag } from './catalog.js';\nimport { apiRequest } from './request.js';\nimport { resolveApiBaseUrl } from '../../lib/api-key.js';\nimport { exitWithError, isJsonMode, outputJson } from '../../utils/output.js';\nimport { ExitCode, exitWithCode } from '../../utils/exit-codes.js';\nimport { isCiMode, isPromptAllowed } from '../../utils/interaction-mode.js';\nimport { confirmationRecovery } from '../../utils/recovery-hints.js';\nimport { formatWorkOSCommandArgs } from '../../utils/command-invocation.js';\nimport { colorMethod, printResponse } from './format.js';\n\nexport { colorMethod } from './format.js';\n\nexport interface ApiCommandOptions {\n method?: string;\n data?: string;\n file?: string;\n include?: boolean;\n apiKey?: string;\n dryRun?: boolean;\n yes?: boolean;\n}\n\nconst MUTATING_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);\n\nexport async function runApiInteractive(options?: { apiKey?: string }): Promise<void> {\n // Interactive mode is inherently human-oriented (clack prompts, preview text,\n // etc.). Refuse to enter it whenever JSON output was requested, regardless of\n // TTY status, so stdout stays machine-readable.\n if (isJsonMode()) {\n exitWithError({\n code: 'tty_required',\n message: 'Interactive mode is not available with --json. Provide an endpoint or use `workos api ls`.',\n details: {\n usage: ['workos api <endpoint>', 'workos api ls [filter]'],\n },\n });\n }\n\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'tty_required',\n message:\n 'Interactive API mode requires human mode. Usage: workos api <endpoint> or workos api ls [filter]. Example: workos api /user_management/users',\n });\n }\n\n const { apiInteractive } = await import('./interactive.js');\n await apiInteractive({ apiKey: options?.apiKey });\n}\n\nexport async function runApiLs(filter?: string): Promise<void> {\n const catalog = await loadCatalog();\n let endpoints = catalog.endpoints;\n\n if (filter) {\n const lower = filter.toLowerCase();\n endpoints = endpoints.filter(\n (e) =>\n e.path.toLowerCase().includes(lower) ||\n e.tag.toLowerCase().includes(lower) ||\n e.summary.toLowerCase().includes(lower) ||\n e.operationId.toLowerCase().includes(lower),\n );\n }\n\n if (isJsonMode()) {\n outputJson({\n data: endpoints.map((e) => ({\n method: e.method,\n path: e.path,\n summary: e.summary,\n tag: e.tag,\n })),\n });\n return;\n }\n\n if (endpoints.length === 0) {\n console.log(filter ? `No endpoints matching \"${filter}\".` : 'No endpoints found.');\n return;\n }\n\n const grouped = endpointsByTag(endpoints);\n\n for (const [tag, eps] of grouped) {\n console.log(`\\n${chalk.bold(tag)}`);\n for (const ep of eps) {\n const method = colorMethod(ep.method).padEnd(18);\n console.log(` ${method} ${ep.path} ${chalk.dim(ep.summary)}`);\n }\n }\n console.log();\n}\n\nexport async function runApiRequest(endpoint: string, options: ApiCommandOptions): Promise<void> {\n const body = await resolveBody(options);\n const hasBody = body !== undefined;\n const method = (options.method ?? (hasBody ? 'POST' : 'GET')).toUpperCase();\n const baseUrl = resolveApiBaseUrl();\n\n if (options.dryRun) {\n if (isJsonMode()) {\n let parsedBody: unknown;\n if (hasBody) {\n try {\n parsedBody = JSON.parse(body);\n } catch {\n exitWithError({ code: 'invalid_json_body', message: 'Request body is not valid JSON.' });\n }\n }\n outputJson({\n dryRun: true,\n method,\n url: `${baseUrl}${normalizePath(endpoint)}`,\n body: parsedBody,\n });\n } else {\n console.log(`${chalk.dim('[dry-run]')} ${method} ${baseUrl}${normalizePath(endpoint)}`);\n if (hasBody) prettyPrint(body);\n }\n return;\n }\n\n if (MUTATING_METHODS.has(method) && !options.yes) {\n const confirmCommand = buildConfirmationCommand(endpoint, method, options);\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'confirmation_required',\n message: isCiMode()\n ? `Mutating requests in CI mode require --yes. Refusing to ${method} ${endpoint}.`\n : `Mutating requests in agent mode require --yes. Refusing to ${method} ${endpoint}.`,\n recovery: confirmationRecovery(confirmCommand),\n });\n }\n if (isJsonMode()) {\n exitWithError({\n code: 'confirmation_required',\n message: 'Mutating requests in JSON mode require --yes to keep stdout machine-readable.',\n recovery: confirmationRecovery(confirmCommand),\n });\n }\n const clack = (await import('../../utils/clack.js')).default;\n console.log(`\\n${chalk.yellow('About to')} ${method} ${endpoint}`);\n if (hasBody) prettyPrint(body);\n const ok = await clack.confirm({ message: 'Proceed?' });\n if (!ok || clack.isCancel(ok)) {\n exitWithCode(ExitCode.CANCELLED);\n }\n }\n\n const response = await apiRequest({\n method,\n path: normalizePath(endpoint),\n apiKey: options.apiKey,\n body,\n baseUrl,\n });\n\n printResponse(response, { includeStatus: options.include });\n\n if (response.status >= 400) {\n exitWithError({\n code: `http_${response.status}`,\n message: `API request failed with status ${response.status}`,\n apiContext: { status: response.status },\n });\n }\n}\n\nfunction normalizePath(path: string): string {\n if (!path.startsWith('/')) return `/${path}`;\n return path;\n}\n\nfunction buildConfirmationCommand(endpoint: string, method: string, options: ApiCommandOptions): string | undefined {\n if (options.apiKey || options.file === '-') {\n return undefined;\n }\n\n const args = ['api', endpoint, '--method', method];\n if (options.data !== undefined) {\n args.push(`--data=${options.data}`);\n }\n if (options.file) {\n args.push(`--file=${options.file}`);\n }\n if (options.include) {\n args.push('--include');\n }\n args.push('--yes');\n return formatWorkOSCommandArgs(args);\n}\n\nasync function resolveBody(options: ApiCommandOptions): Promise<string | undefined> {\n if (options.data !== undefined) return options.data;\n if (options.file) {\n if (options.file === '-') {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n const stdinBody = Buffer.concat(chunks).toString('utf-8');\n if (stdinBody.length === 0) {\n exitWithError({\n code: 'empty_stdin_body',\n message:\n 'Reading request body from stdin (--file -) yielded no data. Pipe data into the command or pass --data instead.',\n });\n }\n return stdinBody;\n }\n try {\n return await readFile(options.file, 'utf-8');\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n exitWithError({\n code: 'file_read_error',\n message: `Could not read request body file \"${options.file}\": ${message}`,\n });\n }\n }\n return undefined;\n}\n\nfunction prettyPrint(jsonString: string): void {\n try {\n console.log(JSON.stringify(JSON.parse(jsonString), null, 2));\n } catch {\n console.log(jsonString);\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/api/index.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { readFile } from 'node:fs/promises';\nimport { loadCatalog, endpointsByTag } from './catalog.js';\nimport { apiRequest } from './request.js';\nimport { resolveApiBaseUrl } from '../../lib/api-key.js';\nimport { exitWithError, isJsonMode, outputJson } from '../../utils/output.js';\nimport { ExitCode, exitWithCode } from '../../utils/exit-codes.js';\nimport { isCiMode, isPromptAllowed, getInteractionMode } from '../../utils/interaction-mode.js';\nimport { confirmationRecovery, authLoginRecovery, missingArgsRecovery } from '../../utils/recovery-hints.js';\nimport { formatWorkOSCommand, formatWorkOSCommandArgs } from '../../utils/command-invocation.js';\nimport { colorMethod, printResponse } from './format.js';\n\nexport { colorMethod } from './format.js';\n\nexport interface ApiCommandOptions {\n method?: string;\n data?: string;\n file?: string;\n include?: boolean;\n apiKey?: string;\n dryRun?: boolean;\n yes?: boolean;\n}\n\nconst MUTATING_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);\n\nexport async function runApiInteractive(options?: { apiKey?: string }): Promise<void> {\n // Interactive mode is inherently human-oriented (interactive prompts, preview text,\n // etc.). Refuse to enter it whenever JSON output was requested, regardless of\n // TTY status, so stdout stays machine-readable.\n if (isJsonMode()) {\n exitWithError({\n code: 'tty_required',\n message: `Interactive mode is not available with --json. Provide an endpoint or use \\`${formatWorkOSCommand('api ls')}\\`.`,\n details: {\n usage: [formatWorkOSCommand('api <endpoint>'), formatWorkOSCommand('api ls [filter]')],\n },\n });\n }\n\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'tty_required',\n message: `Interactive API mode requires human mode. Usage: ${formatWorkOSCommand('api <endpoint>')} or ${formatWorkOSCommand('api ls [filter]')}. Example: ${formatWorkOSCommand('api /user_management/users')}`,\n });\n }\n\n const { apiInteractive } = await import('./interactive.js');\n await apiInteractive({ apiKey: options?.apiKey });\n}\n\nexport async function runApiLs(filter?: string): Promise<void> {\n const catalog = await loadCatalog();\n let endpoints = catalog.endpoints;\n\n if (filter) {\n const lower = filter.toLowerCase();\n endpoints = endpoints.filter(\n (e) =>\n e.path.toLowerCase().includes(lower) ||\n e.tag.toLowerCase().includes(lower) ||\n e.summary.toLowerCase().includes(lower) ||\n e.operationId.toLowerCase().includes(lower),\n );\n }\n\n if (isJsonMode()) {\n outputJson({\n data: endpoints.map((e) => ({\n method: e.method,\n path: e.path,\n summary: e.summary,\n tag: e.tag,\n })),\n });\n return;\n }\n\n if (endpoints.length === 0) {\n console.log(filter ? `No endpoints matching \"${filter}\".` : 'No endpoints found.');\n return;\n }\n\n const grouped = endpointsByTag(endpoints);\n\n for (const [tag, eps] of grouped) {\n console.log(`\\n${chalk.bold(tag)}`);\n for (const ep of eps) {\n const method = colorMethod(ep.method).padEnd(18);\n console.log(` ${method} ${ep.path} ${chalk.dim(ep.summary)}`);\n }\n }\n console.log();\n}\n\nexport async function runApiRequest(endpoint: string, options: ApiCommandOptions): Promise<void> {\n const body = await resolveBody(options);\n const hasBody = body !== undefined;\n const method = (options.method ?? (hasBody ? 'POST' : 'GET')).toUpperCase();\n const baseUrl = resolveApiBaseUrl();\n\n if (options.dryRun) {\n if (isJsonMode()) {\n let parsedBody: unknown;\n if (hasBody) {\n try {\n parsedBody = JSON.parse(body);\n } catch {\n exitWithError({ code: 'invalid_json_body', message: 'Request body is not valid JSON.' });\n }\n }\n outputJson({\n dryRun: true,\n method,\n url: `${baseUrl}${normalizePath(endpoint)}`,\n body: parsedBody,\n });\n } else {\n console.log(`${chalk.dim('[dry-run]')} ${method} ${baseUrl}${normalizePath(endpoint)}`);\n if (hasBody) prettyPrint(body);\n }\n return;\n }\n\n if (MUTATING_METHODS.has(method) && !options.yes) {\n const confirmCommand = buildConfirmationCommand(endpoint, method, options);\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'confirmation_required',\n message: isCiMode()\n ? `Mutating requests in CI mode require --yes. Refusing to ${method} ${endpoint}.`\n : `Mutating requests in agent mode require --yes. Refusing to ${method} ${endpoint}.`,\n recovery: confirmationRecovery(confirmCommand),\n });\n }\n if (isJsonMode()) {\n exitWithError({\n code: 'confirmation_required',\n message: 'Mutating requests in JSON mode require --yes to keep stdout machine-readable.',\n recovery: confirmationRecovery(confirmCommand),\n });\n }\n const ui = (await import('../../utils/ui.js')).default;\n console.log(`\\n${chalk.yellow('About to')} ${method} ${endpoint}`);\n if (hasBody) prettyPrint(body);\n const ok = await ui.confirm({ message: 'Proceed?' });\n if (!ok || ui.isCancel(ok)) {\n exitWithCode(ExitCode.CANCELLED);\n }\n }\n\n const response = await apiRequest({\n method,\n path: normalizePath(endpoint),\n apiKey: options.apiKey,\n body,\n baseUrl,\n });\n\n printResponse(response, { includeStatus: options.include });\n\n if (response.status >= 400) {\n // Give the caller a concrete next step keyed off the status: re-auth for\n // 401/403, discover endpoints for 404.\n const recovery =\n response.status === 401 || response.status === 403\n ? authLoginRecovery({ mode: getInteractionMode().mode })\n : response.status === 404\n ? missingArgsRecovery(\n formatWorkOSCommand('api ls'),\n 'List available endpoints, then re-run with a valid path.',\n )\n : undefined;\n exitWithError({\n code: `http_${response.status}`,\n message: `API request failed with status ${response.status}`,\n apiContext: { status: response.status },\n ...(recovery && { recovery }),\n });\n }\n}\n\nfunction normalizePath(path: string): string {\n if (!path.startsWith('/')) return `/${path}`;\n return path;\n}\n\nfunction buildConfirmationCommand(endpoint: string, method: string, options: ApiCommandOptions): string | undefined {\n if (options.apiKey || options.file === '-') {\n return undefined;\n }\n\n const args = ['api', endpoint, '--method', method];\n if (options.data !== undefined) {\n args.push(`--data=${options.data}`);\n }\n if (options.file) {\n args.push(`--file=${options.file}`);\n }\n if (options.include) {\n args.push('--include');\n }\n args.push('--yes');\n return formatWorkOSCommandArgs(args);\n}\n\nasync function resolveBody(options: ApiCommandOptions): Promise<string | undefined> {\n if (options.data !== undefined) return options.data;\n if (options.file) {\n if (options.file === '-') {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n const stdinBody = Buffer.concat(chunks).toString('utf-8');\n if (stdinBody.length === 0) {\n exitWithError({\n code: 'empty_stdin_body',\n message:\n 'Reading request body from stdin (--file -) yielded no data. Pipe data into the command or pass --data instead.',\n });\n }\n return stdinBody;\n }\n try {\n return await readFile(options.file, 'utf-8');\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n exitWithError({\n code: 'file_read_error',\n message: `Could not read request body file \"${options.file}\": ${message}`,\n });\n }\n }\n return undefined;\n}\n\nfunction prettyPrint(jsonString: string): void {\n try {\n console.log(JSON.stringify(JSON.parse(jsonString), null, 2));\n } catch {\n console.log(jsonString);\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import clack from '../../utils/clack.js';
1
+ import ui from '../../utils/ui.js';
2
2
  import { loadCatalog, endpointsByTag } from './catalog.js';
3
3
  import { apiRequest } from './request.js';
4
4
  import { colorMethod, printResponse } from './format.js';
@@ -6,14 +6,14 @@ import { resolveApiKey, resolveApiBaseUrl } from '../../lib/api-key.js';
6
6
  import { ExitCode, exitWithCode } from '../../utils/exit-codes.js';
7
7
  import { exitWithError } from '../../utils/output.js';
8
8
  function assertNotCancelled(value) {
9
- if (clack.isCancel(value))
9
+ if (ui.isCancel(value))
10
10
  exitWithCode(ExitCode.CANCELLED);
11
11
  return value;
12
12
  }
13
13
  export async function apiInteractive(options) {
14
14
  const catalog = await loadCatalog();
15
15
  const grouped = endpointsByTag(catalog.endpoints);
16
- const tag = assertNotCancelled(await clack.select({
16
+ const tag = assertNotCancelled(await ui.select({
17
17
  message: 'Select a category:',
18
18
  options: catalog.tags.map((t) => {
19
19
  const count = grouped.get(t)?.length ?? 0;
@@ -21,7 +21,7 @@ export async function apiInteractive(options) {
21
21
  }),
22
22
  }));
23
23
  const endpoints = grouped.get(tag);
24
- const ep = assertNotCancelled(await clack.select({
24
+ const ep = assertNotCancelled(await ui.select({
25
25
  message: 'Select an endpoint:',
26
26
  options: endpoints.map((e) => ({
27
27
  value: e,
@@ -31,7 +31,7 @@ export async function apiInteractive(options) {
31
31
  }));
32
32
  let resolvedPath = ep.path;
33
33
  for (const param of ep.pathParams) {
34
- const value = assertNotCancelled(await clack.text({
34
+ const value = assertNotCancelled(await ui.text({
35
35
  message: `${param.name}:`,
36
36
  placeholder: param.description || undefined,
37
37
  validate: (v) => {
@@ -47,7 +47,7 @@ export async function apiInteractive(options) {
47
47
  const optionalParams = ep.queryParams.filter((qp) => !qp.required);
48
48
  const params = [];
49
49
  for (const qp of requiredParams) {
50
- const value = assertNotCancelled(await clack.text({
50
+ const value = assertNotCancelled(await ui.text({
51
51
  message: `${qp.name} (required):`,
52
52
  placeholder: qp.description || undefined,
53
53
  validate: (v) => {
@@ -58,13 +58,13 @@ export async function apiInteractive(options) {
58
58
  params.push(`${encodeURIComponent(qp.name)}=${encodeURIComponent(value.trim())}`);
59
59
  }
60
60
  if (optionalParams.length > 0) {
61
- const wantsOptional = assertNotCancelled(await clack.confirm({
61
+ const wantsOptional = assertNotCancelled(await ui.confirm({
62
62
  message: `Add optional query parameters? (${optionalParams.length} available)`,
63
63
  initialValue: false,
64
64
  }));
65
65
  if (wantsOptional) {
66
66
  for (const qp of optionalParams) {
67
- const value = assertNotCancelled(await clack.text({
67
+ const value = assertNotCancelled(await ui.text({
68
68
  message: `${qp.name}:`,
69
69
  placeholder: qp.description || undefined,
70
70
  }));
@@ -83,13 +83,13 @@ export async function apiInteractive(options) {
83
83
  if (ep.hasRequestBody) {
84
84
  let collectBody = ep.requestBodyRequired;
85
85
  if (!collectBody) {
86
- collectBody = assertNotCancelled(await clack.confirm({
86
+ collectBody = assertNotCancelled(await ui.confirm({
87
87
  message: 'Provide a request body?',
88
88
  initialValue: ep.method === 'POST' || ep.method === 'PUT',
89
89
  }));
90
90
  }
91
91
  if (collectBody) {
92
- body = assertNotCancelled(await clack.text({
92
+ body = assertNotCancelled(await ui.text({
93
93
  message: 'Request body (JSON):',
94
94
  placeholder: '{"key": "value"}',
95
95
  validate: (v) => {
@@ -111,7 +111,7 @@ export async function apiInteractive(options) {
111
111
  console.log(JSON.stringify(JSON.parse(body), null, 2));
112
112
  }
113
113
  console.log();
114
- const ok = assertNotCancelled(await clack.confirm({ message: 'Execute this request?' }));
114
+ const ok = assertNotCancelled(await ui.confirm({ message: 'Execute this request?' }));
115
115
  if (!ok)
116
116
  exitWithCode(ExitCode.CANCELLED);
117
117
  const response = await apiRequest({
@@ -1 +1 @@
1
- {"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../../src/commands/api/interactive.ts"],"names":[],"mappings":"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","sourcesContent":["import clack from '../../utils/clack.js';\nimport { loadCatalog, endpointsByTag, type EndpointInfo } from './catalog.js';\nimport { apiRequest } from './request.js';\nimport { colorMethod, printResponse } from './format.js';\nimport { resolveApiKey, resolveApiBaseUrl } from '../../lib/api-key.js';\nimport { ExitCode, exitWithCode } from '../../utils/exit-codes.js';\nimport { exitWithError } from '../../utils/output.js';\n\nfunction assertNotCancelled<T>(value: T | symbol): T {\n if (clack.isCancel(value)) exitWithCode(ExitCode.CANCELLED);\n return value as T;\n}\n\nexport async function apiInteractive(options?: { apiKey?: string }): Promise<void> {\n const catalog = await loadCatalog();\n const grouped = endpointsByTag(catalog.endpoints);\n\n const tag = assertNotCancelled(\n await clack.select({\n message: 'Select a category:',\n options: catalog.tags.map((t) => {\n const count = grouped.get(t)?.length ?? 0;\n return { value: t, label: `${t} (${count})` };\n }),\n }),\n );\n\n const endpoints = grouped.get(tag)!;\n const ep = assertNotCancelled(\n await clack.select<EndpointInfo>({\n message: 'Select an endpoint:',\n options: endpoints.map((e) => ({\n value: e,\n label: `${colorMethod(e.method).padEnd(18)} ${e.path}`,\n hint: e.summary,\n })),\n }),\n );\n\n let resolvedPath = ep.path;\n for (const param of ep.pathParams) {\n const value = assertNotCancelled(\n await clack.text({\n message: `${param.name}:`,\n placeholder: param.description || undefined,\n validate: (v) => {\n if (!v?.trim()) return `${param.name} is required`;\n },\n }),\n );\n resolvedPath = resolvedPath.replaceAll(`{${param.name}}`, encodeURIComponent(value.trim()));\n }\n\n let queryString = '';\n if (ep.queryParams.length > 0) {\n const requiredParams = ep.queryParams.filter((qp) => qp.required);\n const optionalParams = ep.queryParams.filter((qp) => !qp.required);\n const params: string[] = [];\n\n for (const qp of requiredParams) {\n const value = assertNotCancelled(\n await clack.text({\n message: `${qp.name} (required):`,\n placeholder: qp.description || undefined,\n validate: (v) => {\n if (!v?.trim()) return `${qp.name} is required`;\n },\n }),\n );\n params.push(`${encodeURIComponent(qp.name)}=${encodeURIComponent(value.trim())}`);\n }\n\n if (optionalParams.length > 0) {\n const wantsOptional = assertNotCancelled(\n await clack.confirm({\n message: `Add optional query parameters? (${optionalParams.length} available)`,\n initialValue: false,\n }),\n );\n\n if (wantsOptional) {\n for (const qp of optionalParams) {\n const value = assertNotCancelled(\n await clack.text({\n message: `${qp.name}:`,\n placeholder: qp.description || undefined,\n }),\n );\n const trimmed = value.trim();\n if (trimmed) {\n params.push(`${encodeURIComponent(qp.name)}=${encodeURIComponent(trimmed)}`);\n }\n }\n }\n }\n\n if (params.length > 0) {\n queryString = `?${params.join('&')}`;\n }\n }\n\n let body: string | undefined;\n if (ep.hasRequestBody) {\n let collectBody = ep.requestBodyRequired;\n if (!collectBody) {\n collectBody = assertNotCancelled(\n await clack.confirm({\n message: 'Provide a request body?',\n initialValue: ep.method === 'POST' || ep.method === 'PUT',\n }),\n );\n }\n\n if (collectBody) {\n body = assertNotCancelled(\n await clack.text({\n message: 'Request body (JSON):',\n placeholder: '{\"key\": \"value\"}',\n validate: (v) => {\n if (!v?.trim()) return 'Body cannot be empty';\n try {\n JSON.parse(v);\n } catch {\n return 'Invalid JSON';\n }\n },\n }),\n ).trim();\n }\n }\n\n const fullPath = `${resolvedPath}${queryString}`;\n\n console.log(`\\n ${colorMethod(ep.method)} ${fullPath}`);\n if (body) {\n console.log(JSON.stringify(JSON.parse(body), null, 2));\n }\n console.log();\n\n const ok = assertNotCancelled(await clack.confirm({ message: 'Execute this request?' }));\n if (!ok) exitWithCode(ExitCode.CANCELLED);\n\n const response = await apiRequest({\n method: ep.method,\n path: fullPath,\n apiKey: options?.apiKey ?? resolveApiKey(),\n baseUrl: resolveApiBaseUrl(),\n body,\n });\n\n printResponse(response, { includeStatus: true });\n\n if (response.status >= 400) {\n exitWithError({\n code: `http_${response.status}`,\n message: `API request failed with status ${response.status}`,\n apiContext: { status: response.status },\n });\n }\n}\n"]}
1
+ {"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../../src/commands/api/interactive.ts"],"names":[],"mappings":"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","sourcesContent":["import ui from '../../utils/ui.js';\nimport { loadCatalog, endpointsByTag, type EndpointInfo } from './catalog.js';\nimport { apiRequest } from './request.js';\nimport { colorMethod, printResponse } from './format.js';\nimport { resolveApiKey, resolveApiBaseUrl } from '../../lib/api-key.js';\nimport { ExitCode, exitWithCode } from '../../utils/exit-codes.js';\nimport { exitWithError } from '../../utils/output.js';\n\nfunction assertNotCancelled<T>(value: T | symbol): T {\n if (ui.isCancel(value)) exitWithCode(ExitCode.CANCELLED);\n return value as T;\n}\n\nexport async function apiInteractive(options?: { apiKey?: string }): Promise<void> {\n const catalog = await loadCatalog();\n const grouped = endpointsByTag(catalog.endpoints);\n\n const tag = assertNotCancelled(\n await ui.select({\n message: 'Select a category:',\n options: catalog.tags.map((t) => {\n const count = grouped.get(t)?.length ?? 0;\n return { value: t, label: `${t} (${count})` };\n }),\n }),\n );\n\n const endpoints = grouped.get(tag)!;\n const ep = assertNotCancelled(\n await ui.select<EndpointInfo>({\n message: 'Select an endpoint:',\n options: endpoints.map((e) => ({\n value: e,\n label: `${colorMethod(e.method).padEnd(18)} ${e.path}`,\n hint: e.summary,\n })),\n }),\n );\n\n let resolvedPath = ep.path;\n for (const param of ep.pathParams) {\n const value = assertNotCancelled(\n await ui.text({\n message: `${param.name}:`,\n placeholder: param.description || undefined,\n validate: (v) => {\n if (!v?.trim()) return `${param.name} is required`;\n },\n }),\n );\n resolvedPath = resolvedPath.replaceAll(`{${param.name}}`, encodeURIComponent(value.trim()));\n }\n\n let queryString = '';\n if (ep.queryParams.length > 0) {\n const requiredParams = ep.queryParams.filter((qp) => qp.required);\n const optionalParams = ep.queryParams.filter((qp) => !qp.required);\n const params: string[] = [];\n\n for (const qp of requiredParams) {\n const value = assertNotCancelled(\n await ui.text({\n message: `${qp.name} (required):`,\n placeholder: qp.description || undefined,\n validate: (v) => {\n if (!v?.trim()) return `${qp.name} is required`;\n },\n }),\n );\n params.push(`${encodeURIComponent(qp.name)}=${encodeURIComponent(value.trim())}`);\n }\n\n if (optionalParams.length > 0) {\n const wantsOptional = assertNotCancelled(\n await ui.confirm({\n message: `Add optional query parameters? (${optionalParams.length} available)`,\n initialValue: false,\n }),\n );\n\n if (wantsOptional) {\n for (const qp of optionalParams) {\n const value = assertNotCancelled(\n await ui.text({\n message: `${qp.name}:`,\n placeholder: qp.description || undefined,\n }),\n );\n const trimmed = value.trim();\n if (trimmed) {\n params.push(`${encodeURIComponent(qp.name)}=${encodeURIComponent(trimmed)}`);\n }\n }\n }\n }\n\n if (params.length > 0) {\n queryString = `?${params.join('&')}`;\n }\n }\n\n let body: string | undefined;\n if (ep.hasRequestBody) {\n let collectBody = ep.requestBodyRequired;\n if (!collectBody) {\n collectBody = assertNotCancelled(\n await ui.confirm({\n message: 'Provide a request body?',\n initialValue: ep.method === 'POST' || ep.method === 'PUT',\n }),\n );\n }\n\n if (collectBody) {\n body = assertNotCancelled(\n await ui.text({\n message: 'Request body (JSON):',\n placeholder: '{\"key\": \"value\"}',\n validate: (v) => {\n if (!v?.trim()) return 'Body cannot be empty';\n try {\n JSON.parse(v);\n } catch {\n return 'Invalid JSON';\n }\n },\n }),\n ).trim();\n }\n }\n\n const fullPath = `${resolvedPath}${queryString}`;\n\n console.log(`\\n ${colorMethod(ep.method)} ${fullPath}`);\n if (body) {\n console.log(JSON.stringify(JSON.parse(body), null, 2));\n }\n console.log();\n\n const ok = assertNotCancelled(await ui.confirm({ message: 'Execute this request?' }));\n if (!ok) exitWithCode(ExitCode.CANCELLED);\n\n const response = await apiRequest({\n method: ep.method,\n path: fullPath,\n apiKey: options?.apiKey ?? resolveApiKey(),\n baseUrl: resolveApiBaseUrl(),\n body,\n });\n\n printResponse(response, { includeStatus: true });\n\n if (response.status >= 400) {\n exitWithError({\n code: `http_${response.status}`,\n message: `API request failed with status ${response.status}`,\n apiContext: { status: response.status },\n });\n }\n}\n"]}
@@ -6,7 +6,7 @@
6
6
  * until the environment is claimed.
7
7
  */
8
8
  import open from 'open';
9
- import clack from '../utils/clack.js';
9
+ import ui from '../utils/ui.js';
10
10
  import { getActiveEnvironment, isUnclaimedEnvironment, markEnvironmentClaimed } from '../lib/config-store.js';
11
11
  import { createClaimNonce, UnclaimedEnvApiError } from '../lib/unclaimed-env-api.js';
12
12
  import { observeHostFailure } from '../lib/host-probe.js';
@@ -15,6 +15,7 @@ import { isJsonMode, outputJson, exitWithError } from '../utils/output.js';
15
15
  import { isAgentMode, isCiMode } from '../utils/interaction-mode.js';
16
16
  import { sleep } from '../lib/helper-functions.js';
17
17
  import { formatWorkOSCommand } from '../utils/command-invocation.js';
18
+ import { networkRetryRecovery } from '../utils/recovery-hints.js';
18
19
  const POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
19
20
  const POLL_INTERVAL_MS = 5_000; // 5 seconds
20
21
  const MAX_CONSECUTIVE_FAILURES = 10;
@@ -28,14 +29,14 @@ export async function runClaim() {
28
29
  outputJson({ status: 'no_unclaimed_environment', message: 'No unclaimed environment found. Nothing to claim.' });
29
30
  }
30
31
  else {
31
- clack.log.info('No unclaimed environment found. Nothing to claim.');
32
+ ui.log.info('No unclaimed environment found. Nothing to claim.');
32
33
  }
33
34
  return;
34
35
  }
35
36
  // claimToken and clientId guaranteed present by UnclaimedEnvironmentConfig
36
37
  logInfo('[claim] Starting claim flow for environment:', activeEnv.name);
37
38
  try {
38
- clack.log.step('Generating claim link...');
39
+ ui.log.step('Generating claim link...');
39
40
  const result = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);
40
41
  if (result.alreadyClaimed) {
41
42
  markEnvironmentClaimed();
@@ -43,14 +44,20 @@ export async function runClaim() {
43
44
  outputJson({ status: 'already_claimed', message: 'Environment already claimed!' });
44
45
  }
45
46
  else {
46
- clack.log.success('Environment already claimed!');
47
- clack.log.info(`Run \`${formatWorkOSCommand('auth login')}\` to connect your account.`);
47
+ ui.log.success('Environment already claimed!');
48
+ ui.log.info(`Run \`${formatWorkOSCommand('auth login')}\` to connect your account.`);
48
49
  }
49
50
  return;
50
51
  }
51
52
  const claimUrl = `https://dashboard.workos.com/claim?nonce=${result.nonce}`;
52
53
  if (isJsonMode()) {
53
- outputJson({ status: 'claim_url', claimUrl, nonce: result.nonce });
54
+ outputJson({
55
+ status: 'claim_url',
56
+ claimUrl,
57
+ nonce: result.nonce,
58
+ permanent: true,
59
+ note: 'Claiming permanently links this environment to your account and cannot be undone.',
60
+ });
54
61
  return;
55
62
  }
56
63
  if (isCiMode()) {
@@ -60,14 +67,15 @@ export async function runClaim() {
60
67
  details: { claimUrl, nonce: result.nonce },
61
68
  });
62
69
  }
63
- clack.log.info(`Open this URL to claim your environment:\n\n ${claimUrl}`);
70
+ ui.log.warn('Claiming permanently links this environment to your account and cannot be undone.');
71
+ ui.log.info(`Open this URL to claim your environment:\n\n ${claimUrl}`);
64
72
  try {
65
73
  await open(claimUrl, { wait: false });
66
74
  if (isAgentMode()) {
67
- clack.log.info('Browser launch attempted. If it did not open on the host, use the URL above.');
75
+ ui.log.info('Browser launch attempted. If it did not open on the host, use the URL above.');
68
76
  }
69
77
  else {
70
- clack.log.info('Browser opened automatically');
78
+ ui.log.info('Browser opened automatically');
71
79
  }
72
80
  }
73
81
  catch (openError) {
@@ -77,10 +85,10 @@ export async function runClaim() {
77
85
  label: 'environment claim browser',
78
86
  });
79
87
  logError('[claim] Failed to open browser:', openError instanceof Error ? openError.message : String(openError));
80
- clack.log.info('Could not open browser — open the URL above manually.');
88
+ ui.log.info('Could not open browser — open the URL above manually.');
81
89
  }
82
90
  // Poll for claim completion
83
- const spinner = clack.spinner();
91
+ const spinner = ui.spinner();
84
92
  spinner.start('Waiting for claim...');
85
93
  const startTime = Date.now();
86
94
  let consecutiveFailures = 0;
@@ -91,7 +99,7 @@ export async function runClaim() {
91
99
  if (check.alreadyClaimed) {
92
100
  spinner.stop('Environment claimed!');
93
101
  markEnvironmentClaimed();
94
- clack.log.info(`Run \`${formatWorkOSCommand('auth login')}\` to connect your account.`);
102
+ ui.log.info(`Run \`${formatWorkOSCommand('auth login')}\` to connect your account.`);
95
103
  return;
96
104
  }
97
105
  consecutiveFailures = 0;
@@ -103,14 +111,14 @@ export async function runClaim() {
103
111
  // when the environment is claimed. Safe to promote to sandbox.
104
112
  spinner.stop('Claim token is invalid or expired.');
105
113
  markEnvironmentClaimed();
106
- clack.log.warn(`Run \`${formatWorkOSCommand('auth login')}\` to set up your environment.`);
114
+ ui.log.warn(`Run \`${formatWorkOSCommand('auth login')}\` to set up your environment.`);
107
115
  return;
108
116
  }
109
117
  consecutiveFailures++;
110
118
  logError('[claim] Poll error:', pollError instanceof Error ? pollError.message : 'Unknown');
111
119
  if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
112
120
  spinner.stop('Too many connection failures');
113
- clack.log.error(`Polling failed ${consecutiveFailures} times in a row. Check your network and try again.\n` +
121
+ ui.log.error(`Polling failed ${consecutiveFailures} times in a row. Check your network and try again.\n` +
114
122
  `You can also complete the claim at: ${claimUrl}`);
115
123
  return;
116
124
  }
@@ -120,12 +128,16 @@ export async function runClaim() {
120
128
  }
121
129
  }
122
130
  spinner.stop('Claim timed out');
123
- clack.log.info('Complete the claim in your browser, then run `workos env list` to verify.');
131
+ ui.log.info(`Complete the claim in your browser, then run \`${formatWorkOSCommand('env list')}\` to verify.`);
124
132
  }
125
133
  catch (error) {
126
134
  const message = error instanceof Error ? error.message : 'Unknown error';
127
135
  logError('[claim] Error:', message);
128
- exitWithError({ code: 'claim_failed', message: `Claim failed: ${message}` });
136
+ exitWithError({
137
+ code: 'claim_failed',
138
+ message: `Could not claim this environment: ${message}`,
139
+ recovery: networkRetryRecovery({ command: formatWorkOSCommand('env claim') }),
140
+ });
129
141
  }
130
142
  }
131
143
  //# sourceMappingURL=claim.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claim.js","sourceRoot":"","sources":["../../src/commands/claim.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `workos env claim` — claim an unclaimed environment.\n *\n * Reads claim token from active environment, generates a nonce via\n * createClaimNonce(), opens browser to dashboard claim URL, and polls\n * until the environment is claimed.\n */\n\nimport open from 'open';\nimport clack from '../utils/clack.js';\nimport { getActiveEnvironment, isUnclaimedEnvironment, markEnvironmentClaimed } from '../lib/config-store.js';\nimport { createClaimNonce, UnclaimedEnvApiError } from '../lib/unclaimed-env-api.js';\nimport { observeHostFailure } from '../lib/host-probe.js';\nimport { logInfo, logError } from '../utils/debug.js';\nimport { isJsonMode, outputJson, exitWithError } from '../utils/output.js';\nimport { isAgentMode, isCiMode } from '../utils/interaction-mode.js';\nimport { sleep } from '../lib/helper-functions.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\n\nconst POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\nconst POLL_INTERVAL_MS = 5_000; // 5 seconds\nconst MAX_CONSECUTIVE_FAILURES = 10;\n\n/**\n * Run the claim flow.\n */\nexport async function runClaim(): Promise<void> {\n const activeEnv = getActiveEnvironment();\n\n if (!activeEnv || !isUnclaimedEnvironment(activeEnv)) {\n if (isJsonMode()) {\n outputJson({ status: 'no_unclaimed_environment', message: 'No unclaimed environment found. Nothing to claim.' });\n } else {\n clack.log.info('No unclaimed environment found. Nothing to claim.');\n }\n return;\n }\n\n // claimToken and clientId guaranteed present by UnclaimedEnvironmentConfig\n\n logInfo('[claim] Starting claim flow for environment:', activeEnv.name);\n\n try {\n clack.log.step('Generating claim link...');\n\n const result = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);\n\n if (result.alreadyClaimed) {\n markEnvironmentClaimed();\n if (isJsonMode()) {\n outputJson({ status: 'already_claimed', message: 'Environment already claimed!' });\n } else {\n clack.log.success('Environment already claimed!');\n clack.log.info(`Run \\`${formatWorkOSCommand('auth login')}\\` to connect your account.`);\n }\n return;\n }\n\n const claimUrl = `https://dashboard.workos.com/claim?nonce=${result.nonce}`;\n\n if (isJsonMode()) {\n outputJson({ status: 'claim_url', claimUrl, nonce: result.nonce });\n return;\n }\n\n if (isCiMode()) {\n exitWithError({\n code: 'unsupported_in_ci',\n message: 'Environment claim requires opening the claim URL outside CI.',\n details: { claimUrl, nonce: result.nonce },\n });\n }\n\n clack.log.info(`Open this URL to claim your environment:\\n\\n ${claimUrl}`);\n\n try {\n await open(claimUrl, { wait: false });\n if (isAgentMode()) {\n clack.log.info('Browser launch attempted. If it did not open on the host, use the URL above.');\n } else {\n clack.log.info('Browser opened automatically');\n }\n } catch (openError) {\n observeHostFailure('browser-launch', openError, {\n operation: 'open',\n target: claimUrl,\n label: 'environment claim browser',\n });\n logError('[claim] Failed to open browser:', openError instanceof Error ? openError.message : String(openError));\n clack.log.info('Could not open browser — open the URL above manually.');\n }\n\n // Poll for claim completion\n const spinner = clack.spinner();\n spinner.start('Waiting for claim...');\n\n const startTime = Date.now();\n let consecutiveFailures = 0;\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n await sleep(POLL_INTERVAL_MS);\n try {\n const check = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);\n if (check.alreadyClaimed) {\n spinner.stop('Environment claimed!');\n markEnvironmentClaimed();\n clack.log.info(`Run \\`${formatWorkOSCommand('auth login')}\\` to connect your account.`);\n return;\n }\n consecutiveFailures = 0;\n } catch (pollError) {\n const statusCode = pollError instanceof UnclaimedEnvApiError ? pollError.statusCode : undefined;\n if (statusCode === 401) {\n // 401 means the server invalidated the claim token — this happens\n // when the environment is claimed. Safe to promote to sandbox.\n spinner.stop('Claim token is invalid or expired.');\n markEnvironmentClaimed();\n clack.log.warn(`Run \\`${formatWorkOSCommand('auth login')}\\` to set up your environment.`);\n return;\n }\n consecutiveFailures++;\n logError('[claim] Poll error:', pollError instanceof Error ? pollError.message : 'Unknown');\n if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {\n spinner.stop('Too many connection failures');\n clack.log.error(\n `Polling failed ${consecutiveFailures} times in a row. Check your network and try again.\\n` +\n `You can also complete the claim at: ${claimUrl}`,\n );\n return;\n }\n if (consecutiveFailures >= 3) {\n spinner.message('Still waiting... (connection issues detected)');\n }\n }\n }\n\n spinner.stop('Claim timed out');\n clack.log.info('Complete the claim in your browser, then run `workos env list` to verify.');\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n logError('[claim] Error:', message);\n exitWithError({ code: 'claim_failed', message: `Claim failed: ${message}` });\n }\n}\n"]}
1
+ {"version":3,"file":"claim.js","sourceRoot":"","sources":["../../src/commands/claim.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `workos env claim` — claim an unclaimed environment.\n *\n * Reads claim token from active environment, generates a nonce via\n * createClaimNonce(), opens browser to dashboard claim URL, and polls\n * until the environment is claimed.\n */\n\nimport open from 'open';\nimport ui from '../utils/ui.js';\nimport { getActiveEnvironment, isUnclaimedEnvironment, markEnvironmentClaimed } from '../lib/config-store.js';\nimport { createClaimNonce, UnclaimedEnvApiError } from '../lib/unclaimed-env-api.js';\nimport { observeHostFailure } from '../lib/host-probe.js';\nimport { logInfo, logError } from '../utils/debug.js';\nimport { isJsonMode, outputJson, exitWithError } from '../utils/output.js';\nimport { isAgentMode, isCiMode } from '../utils/interaction-mode.js';\nimport { sleep } from '../lib/helper-functions.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\nimport { networkRetryRecovery } from '../utils/recovery-hints.js';\n\nconst POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\nconst POLL_INTERVAL_MS = 5_000; // 5 seconds\nconst MAX_CONSECUTIVE_FAILURES = 10;\n\n/**\n * Run the claim flow.\n */\nexport async function runClaim(): Promise<void> {\n const activeEnv = getActiveEnvironment();\n\n if (!activeEnv || !isUnclaimedEnvironment(activeEnv)) {\n if (isJsonMode()) {\n outputJson({ status: 'no_unclaimed_environment', message: 'No unclaimed environment found. Nothing to claim.' });\n } else {\n ui.log.info('No unclaimed environment found. Nothing to claim.');\n }\n return;\n }\n\n // claimToken and clientId guaranteed present by UnclaimedEnvironmentConfig\n\n logInfo('[claim] Starting claim flow for environment:', activeEnv.name);\n\n try {\n ui.log.step('Generating claim link...');\n\n const result = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);\n\n if (result.alreadyClaimed) {\n markEnvironmentClaimed();\n if (isJsonMode()) {\n outputJson({ status: 'already_claimed', message: 'Environment already claimed!' });\n } else {\n ui.log.success('Environment already claimed!');\n ui.log.info(`Run \\`${formatWorkOSCommand('auth login')}\\` to connect your account.`);\n }\n return;\n }\n\n const claimUrl = `https://dashboard.workos.com/claim?nonce=${result.nonce}`;\n\n if (isJsonMode()) {\n outputJson({\n status: 'claim_url',\n claimUrl,\n nonce: result.nonce,\n permanent: true,\n note: 'Claiming permanently links this environment to your account and cannot be undone.',\n });\n return;\n }\n\n if (isCiMode()) {\n exitWithError({\n code: 'unsupported_in_ci',\n message: 'Environment claim requires opening the claim URL outside CI.',\n details: { claimUrl, nonce: result.nonce },\n });\n }\n\n ui.log.warn('Claiming permanently links this environment to your account and cannot be undone.');\n ui.log.info(`Open this URL to claim your environment:\\n\\n ${claimUrl}`);\n\n try {\n await open(claimUrl, { wait: false });\n if (isAgentMode()) {\n ui.log.info('Browser launch attempted. If it did not open on the host, use the URL above.');\n } else {\n ui.log.info('Browser opened automatically');\n }\n } catch (openError) {\n observeHostFailure('browser-launch', openError, {\n operation: 'open',\n target: claimUrl,\n label: 'environment claim browser',\n });\n logError('[claim] Failed to open browser:', openError instanceof Error ? openError.message : String(openError));\n ui.log.info('Could not open browser — open the URL above manually.');\n }\n\n // Poll for claim completion\n const spinner = ui.spinner();\n spinner.start('Waiting for claim...');\n\n const startTime = Date.now();\n let consecutiveFailures = 0;\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n await sleep(POLL_INTERVAL_MS);\n try {\n const check = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);\n if (check.alreadyClaimed) {\n spinner.stop('Environment claimed!');\n markEnvironmentClaimed();\n ui.log.info(`Run \\`${formatWorkOSCommand('auth login')}\\` to connect your account.`);\n return;\n }\n consecutiveFailures = 0;\n } catch (pollError) {\n const statusCode = pollError instanceof UnclaimedEnvApiError ? pollError.statusCode : undefined;\n if (statusCode === 401) {\n // 401 means the server invalidated the claim token — this happens\n // when the environment is claimed. Safe to promote to sandbox.\n spinner.stop('Claim token is invalid or expired.');\n markEnvironmentClaimed();\n ui.log.warn(`Run \\`${formatWorkOSCommand('auth login')}\\` to set up your environment.`);\n return;\n }\n consecutiveFailures++;\n logError('[claim] Poll error:', pollError instanceof Error ? pollError.message : 'Unknown');\n if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {\n spinner.stop('Too many connection failures');\n ui.log.error(\n `Polling failed ${consecutiveFailures} times in a row. Check your network and try again.\\n` +\n `You can also complete the claim at: ${claimUrl}`,\n );\n return;\n }\n if (consecutiveFailures >= 3) {\n spinner.message('Still waiting... (connection issues detected)');\n }\n }\n }\n\n spinner.stop('Claim timed out');\n ui.log.info(`Complete the claim in your browser, then run \\`${formatWorkOSCommand('env list')}\\` to verify.`);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n logError('[claim] Error:', message);\n exitWithError({\n code: 'claim_failed',\n message: `Could not claim this environment: ${message}`,\n recovery: networkRetryRecovery({ command: formatWorkOSCommand('env claim') }),\n });\n }\n}\n"]}
@@ -4,7 +4,7 @@ import { formatTable } from '../utils/table.js';
4
4
  import { outputSuccess, outputJson, isJsonMode, exitWithError } from '../utils/output.js';
5
5
  import { createApiErrorHandler } from '../lib/api-error-handler.js';
6
6
  import { isCiMode, isPromptAllowed } from '../utils/interaction-mode.js';
7
- import clack from '../utils/clack.js';
7
+ import ui from '../utils/ui.js';
8
8
  const handleApiError = createApiErrorHandler('Connection');
9
9
  export async function runConnectionList(options, apiKey, baseUrl) {
10
10
  const client = createWorkOSClient(apiKey, baseUrl);
@@ -76,10 +76,10 @@ export async function runConnectionDelete(id, options, apiKey, baseUrl) {
76
76
  : 'Destructive operation requires --force flag in agent mode.',
77
77
  });
78
78
  }
79
- const confirmed = await clack.confirm({
79
+ const confirmed = await ui.confirm({
80
80
  message: `Delete connection ${id}? This cannot be undone.`,
81
81
  });
82
- if (clack.isCancel(confirmed) || !confirmed) {
82
+ if (ui.isCancel(confirmed) || !confirmed) {
83
83
  console.log('Delete cancelled.');
84
84
  return;
85
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/commands/connection.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport type { ConnectionType } from '@workos-inc/node';\nimport { createWorkOSClient } from '../lib/workos-client.js';\nimport { formatTable } from '../utils/table.js';\nimport { outputSuccess, outputJson, isJsonMode, exitWithError } from '../utils/output.js';\nimport { createApiErrorHandler } from '../lib/api-error-handler.js';\nimport { isCiMode, isPromptAllowed } from '../utils/interaction-mode.js';\nimport clack from '../utils/clack.js';\n\nconst handleApiError = createApiErrorHandler('Connection');\n\nexport interface ConnectionListOptions {\n organizationId?: string;\n connectionType?: string;\n limit?: number;\n before?: string;\n after?: string;\n order?: string;\n}\n\nexport async function runConnectionList(\n options: ConnectionListOptions,\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n const result = await client.sdk.sso.listConnections({\n ...(options.organizationId && { organizationId: options.organizationId }),\n ...(options.connectionType && { connectionType: options.connectionType as ConnectionType }),\n limit: options.limit,\n before: options.before,\n after: options.after,\n order: options.order as 'asc' | 'desc' | undefined,\n });\n\n if (isJsonMode()) {\n outputJson({ data: result.data, listMetadata: result.listMetadata });\n return;\n }\n\n if (result.data.length === 0) {\n console.log('No connections found.');\n return;\n }\n\n const rows = result.data.map((conn) => [\n conn.id,\n conn.name,\n conn.type,\n conn.organizationId || chalk.dim('-'),\n conn.state,\n conn.createdAt,\n ]);\n\n console.log(\n formatTable(\n [\n { header: 'ID' },\n { header: 'Name' },\n { header: 'Type' },\n { header: 'Org ID' },\n { header: 'State' },\n { header: 'Created' },\n ],\n rows,\n ),\n );\n\n const { before, after } = result.listMetadata;\n if (before && after) {\n console.log(chalk.dim(`Before: ${before} After: ${after}`));\n } else if (before) {\n console.log(chalk.dim(`Before: ${before}`));\n } else if (after) {\n console.log(chalk.dim(`After: ${after}`));\n }\n } catch (error) {\n handleApiError(error);\n }\n}\n\nexport async function runConnectionGet(id: string, apiKey: string, baseUrl?: string): Promise<void> {\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n const connection = await client.sdk.sso.getConnection(id);\n outputJson(connection);\n } catch (error) {\n handleApiError(error);\n }\n}\n\nexport async function runConnectionDelete(\n id: string,\n options: { force?: boolean },\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n if (!options.force) {\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'confirmation_required',\n message: isCiMode()\n ? 'Destructive operation requires --force flag in CI mode.'\n : 'Destructive operation requires --force flag in agent mode.',\n });\n }\n\n const confirmed = await clack.confirm({\n message: `Delete connection ${id}? This cannot be undone.`,\n });\n\n if (clack.isCancel(confirmed) || !confirmed) {\n console.log('Delete cancelled.');\n return;\n }\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n await client.sdk.sso.deleteConnection(id);\n outputSuccess('Deleted connection', { id });\n } catch (error) {\n handleApiError(error);\n }\n}\n"]}
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/commands/connection.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport type { ConnectionType } from '@workos-inc/node';\nimport { createWorkOSClient } from '../lib/workos-client.js';\nimport { formatTable } from '../utils/table.js';\nimport { outputSuccess, outputJson, isJsonMode, exitWithError } from '../utils/output.js';\nimport { createApiErrorHandler } from '../lib/api-error-handler.js';\nimport { isCiMode, isPromptAllowed } from '../utils/interaction-mode.js';\nimport ui from '../utils/ui.js';\n\nconst handleApiError = createApiErrorHandler('Connection');\n\nexport interface ConnectionListOptions {\n organizationId?: string;\n connectionType?: string;\n limit?: number;\n before?: string;\n after?: string;\n order?: string;\n}\n\nexport async function runConnectionList(\n options: ConnectionListOptions,\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n const result = await client.sdk.sso.listConnections({\n ...(options.organizationId && { organizationId: options.organizationId }),\n ...(options.connectionType && { connectionType: options.connectionType as ConnectionType }),\n limit: options.limit,\n before: options.before,\n after: options.after,\n order: options.order as 'asc' | 'desc' | undefined,\n });\n\n if (isJsonMode()) {\n outputJson({ data: result.data, listMetadata: result.listMetadata });\n return;\n }\n\n if (result.data.length === 0) {\n console.log('No connections found.');\n return;\n }\n\n const rows = result.data.map((conn) => [\n conn.id,\n conn.name,\n conn.type,\n conn.organizationId || chalk.dim('-'),\n conn.state,\n conn.createdAt,\n ]);\n\n console.log(\n formatTable(\n [\n { header: 'ID' },\n { header: 'Name' },\n { header: 'Type' },\n { header: 'Org ID' },\n { header: 'State' },\n { header: 'Created' },\n ],\n rows,\n ),\n );\n\n const { before, after } = result.listMetadata;\n if (before && after) {\n console.log(chalk.dim(`Before: ${before} After: ${after}`));\n } else if (before) {\n console.log(chalk.dim(`Before: ${before}`));\n } else if (after) {\n console.log(chalk.dim(`After: ${after}`));\n }\n } catch (error) {\n handleApiError(error);\n }\n}\n\nexport async function runConnectionGet(id: string, apiKey: string, baseUrl?: string): Promise<void> {\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n const connection = await client.sdk.sso.getConnection(id);\n outputJson(connection);\n } catch (error) {\n handleApiError(error);\n }\n}\n\nexport async function runConnectionDelete(\n id: string,\n options: { force?: boolean },\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n if (!options.force) {\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'confirmation_required',\n message: isCiMode()\n ? 'Destructive operation requires --force flag in CI mode.'\n : 'Destructive operation requires --force flag in agent mode.',\n });\n }\n\n const confirmed = await ui.confirm({\n message: `Delete connection ${id}? This cannot be undone.`,\n });\n\n if (ui.isCancel(confirmed) || !confirmed) {\n console.log('Delete cancelled.');\n return;\n }\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n await client.sdk.sso.deleteConnection(id);\n outputSuccess('Deleted connection', { id });\n } catch (error) {\n handleApiError(error);\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import chalk from 'chalk';
2
- import clack from '../utils/clack.js';
2
+ import ui from '../utils/ui.js';
3
3
  import { getCredentials, saveCredentials, clearCredentials, isTokenExpired, diagnoseCredentials, getCredentialsPath, setInsecureStorage, } from '../lib/credentials.js';
4
4
  import { getConfig, saveConfig, clearConfig, getConfigPath, setInsecureConfigStorage, diagnoseConfig, } from '../lib/config-store.js';
5
5
  import { clearPreferences, getPreferencesPath, getTelemetrySource, isNoticeShown, isTelemetryEnabled, isTelemetryOptedOut, } from '../lib/preferences.js';
@@ -191,15 +191,15 @@ export async function runDebugReset({ force, credentialsOnly, configOnly, }) {
191
191
  message: 'Use --force to reset in agent or CI mode',
192
192
  });
193
193
  }
194
- const confirmed = await clack.confirm({
194
+ const confirmed = await ui.confirm({
195
195
  message: `Clear all ${targets}? This cannot be undone.`,
196
196
  });
197
- if (clack.isCancel(confirmed) || !confirmed) {
197
+ if (ui.isCancel(confirmed) || !confirmed) {
198
198
  if (isJsonMode()) {
199
199
  outputJson({ cleared: false, cancelled: true });
200
200
  }
201
201
  else {
202
- clack.log.info('Reset cancelled');
202
+ ui.log.info('Reset cancelled');
203
203
  }
204
204
  return;
205
205
  }
@@ -214,7 +214,7 @@ export async function runDebugReset({ force, credentialsOnly, configOnly, }) {
214
214
  outputJson({ cleared: true, credentials: clearCreds, config: clearConf, preferences: clearPrefs });
215
215
  }
216
216
  else {
217
- clack.log.success(`Cleared ${targets}`);
217
+ ui.log.success(`Cleared ${targets}`);
218
218
  }
219
219
  }
220
220
  // --- debug simulate ---
@@ -287,7 +287,7 @@ export async function runDebugSimulate({ expiredToken, noKeyring, unclaimed, noA
287
287
  }
288
288
  else {
289
289
  for (const action of actions) {
290
- clack.log.success(action);
290
+ ui.log.success(action);
291
291
  }
292
292
  }
293
293
  }