workos 0.15.2 → 0.16.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 (107) hide show
  1. package/README.md +37 -11
  2. package/dist/bin.js +1439 -1257
  3. package/dist/bin.js.map +1 -1
  4. package/dist/cli.config.d.ts +1 -0
  5. package/dist/cli.config.js +1 -0
  6. package/dist/cli.config.js.map +1 -1
  7. package/dist/commands/api/index.js +7 -2
  8. package/dist/commands/api/index.js.map +1 -1
  9. package/dist/commands/api/interactive.js +9 -3
  10. package/dist/commands/api/interactive.js.map +1 -1
  11. package/dist/commands/debug.d.ts +2 -1
  12. package/dist/commands/debug.js +43 -3
  13. package/dist/commands/debug.js.map +1 -1
  14. package/dist/commands/dev.js +5 -4
  15. package/dist/commands/dev.js.map +1 -1
  16. package/dist/commands/doctor.js +13 -4
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/commands/emulate.js +2 -2
  19. package/dist/commands/emulate.js.map +1 -1
  20. package/dist/commands/env.js +5 -4
  21. package/dist/commands/env.js.map +1 -1
  22. package/dist/commands/install-skill.js +4 -3
  23. package/dist/commands/install-skill.js.map +1 -1
  24. package/dist/commands/install.js +2 -2
  25. package/dist/commands/install.js.map +1 -1
  26. package/dist/commands/login.js +3 -3
  27. package/dist/commands/login.js.map +1 -1
  28. package/dist/commands/migrations.d.ts +1 -1
  29. package/dist/commands/migrations.js +4 -1
  30. package/dist/commands/migrations.js.map +1 -1
  31. package/dist/commands/telemetry.d.ts +3 -0
  32. package/dist/commands/telemetry.js +88 -0
  33. package/dist/commands/telemetry.js.map +1 -0
  34. package/dist/commands/uninstall-skill.js +3 -2
  35. package/dist/commands/uninstall-skill.js.map +1 -1
  36. package/dist/commands/vault-run.d.ts +13 -0
  37. package/dist/commands/vault-run.js +194 -0
  38. package/dist/commands/vault-run.js.map +1 -0
  39. package/dist/commands/vault.d.ts +3 -2
  40. package/dist/commands/vault.js +41 -8
  41. package/dist/commands/vault.js.map +1 -1
  42. package/dist/lib/api-error-handler.d.ts +15 -3
  43. package/dist/lib/api-error-handler.js +52 -34
  44. package/dist/lib/api-error-handler.js.map +1 -1
  45. package/dist/lib/command-aliases.d.ts +8 -0
  46. package/dist/lib/command-aliases.js +12 -0
  47. package/dist/lib/command-aliases.js.map +1 -0
  48. package/dist/lib/constants.d.ts +0 -1
  49. package/dist/lib/constants.js +0 -1
  50. package/dist/lib/constants.js.map +1 -1
  51. package/dist/lib/device-id.d.ts +25 -0
  52. package/dist/lib/device-id.js +102 -0
  53. package/dist/lib/device-id.js.map +1 -0
  54. package/dist/lib/preferences.d.ts +101 -0
  55. package/dist/lib/preferences.js +198 -0
  56. package/dist/lib/preferences.js.map +1 -0
  57. package/dist/lib/run-with-core.js +15 -15
  58. package/dist/lib/run-with-core.js.map +1 -1
  59. package/dist/lib/settings.d.ts +6 -0
  60. package/dist/lib/settings.js +7 -0
  61. package/dist/lib/settings.js.map +1 -1
  62. package/dist/lib/telemetry-notice.d.ts +25 -0
  63. package/dist/lib/telemetry-notice.js +56 -0
  64. package/dist/lib/telemetry-notice.js.map +1 -0
  65. package/dist/test/force-insecure-storage.d.ts +1 -0
  66. package/dist/test/force-insecure-storage.js +9 -0
  67. package/dist/test/force-insecure-storage.js.map +1 -0
  68. package/dist/test/setup.d.ts +1 -0
  69. package/dist/test/setup.js +38 -0
  70. package/dist/test/setup.js.map +1 -0
  71. package/dist/utils/analytics.d.ts +41 -0
  72. package/dist/utils/analytics.js +199 -12
  73. package/dist/utils/analytics.js.map +1 -1
  74. package/dist/utils/box.d.ts +29 -1
  75. package/dist/utils/box.js +92 -4
  76. package/dist/utils/box.js.map +1 -1
  77. package/dist/utils/cli-exit.d.ts +15 -0
  78. package/dist/utils/cli-exit.js +11 -0
  79. package/dist/utils/cli-exit.js.map +1 -0
  80. package/dist/utils/cli-symbols.d.ts +1 -1
  81. package/dist/utils/command-telemetry.d.ts +17 -0
  82. package/dist/utils/command-telemetry.js +67 -0
  83. package/dist/utils/command-telemetry.js.map +1 -0
  84. package/dist/utils/crash-reporter.d.ts +13 -0
  85. package/dist/utils/crash-reporter.js +91 -0
  86. package/dist/utils/crash-reporter.js.map +1 -0
  87. package/dist/utils/debug.d.ts +1 -0
  88. package/dist/utils/debug.js +4 -1
  89. package/dist/utils/debug.js.map +1 -1
  90. package/dist/utils/exit-codes.d.ts +5 -0
  91. package/dist/utils/exit-codes.js +30 -1
  92. package/dist/utils/exit-codes.js.map +1 -1
  93. package/dist/utils/help-json.d.ts +6 -0
  94. package/dist/utils/help-json.js +87 -10
  95. package/dist/utils/help-json.js.map +1 -1
  96. package/dist/utils/output.d.ts +7 -2
  97. package/dist/utils/output.js +9 -2
  98. package/dist/utils/output.js.map +1 -1
  99. package/dist/utils/telemetry-client.d.ts +30 -2
  100. package/dist/utils/telemetry-client.js +122 -12
  101. package/dist/utils/telemetry-client.js.map +1 -1
  102. package/dist/utils/telemetry-store-forward.d.ts +11 -0
  103. package/dist/utils/telemetry-store-forward.js +94 -0
  104. package/dist/utils/telemetry-store-forward.js.map +1 -0
  105. package/dist/utils/telemetry-types.d.ts +58 -9
  106. package/dist/utils/telemetry-types.js.map +1 -1
  107. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -21,9 +21,43 @@ if (!satisfies(process.version, NODE_VERSION_RANGE)) {
21
21
  process.exit(1);
22
22
  }
23
23
  import { InvalidInteractionModeError, isPromptAllowed, resolveInteractionMode, setInteractionMode, } from './utils/interaction-mode.js';
24
- import { resolveEffectiveOutputMode, resolveOutputMode, setOutputMode, isJsonMode, outputJson, exitWithError, } from './utils/output.js';
24
+ import { resolveEffectiveOutputMode, resolveOutputMode, setOutputMode, isJsonMode, outputJson, outputError, exitWithError, } from './utils/output.js';
25
25
  import clack from './utils/clack.js';
26
26
  import { registerSubcommand } from './utils/register-subcommand.js';
27
+ import { installCrashReporter, sanitizeMessage } from './utils/crash-reporter.js';
28
+ import { installStoreForward, recoverPendingEvents } from './utils/telemetry-store-forward.js';
29
+ import { loadDeviceId } from './lib/device-id.js';
30
+ import { loadPreferences, isTelemetryEnabled } from './lib/preferences.js';
31
+ import { maybeShowTelemetryNotice } from './lib/telemetry-notice.js';
32
+ import { resolveCanonicalName, resolveCommandNameFromRawArgs, extractUserFlags, SKIP_TELEMETRY_COMMANDS, } from './utils/command-telemetry.js';
33
+ import { CliExit } from './utils/cli-exit.js';
34
+ import { telemetryClient } from './utils/telemetry-client.js';
35
+ import { ExitCode } from './utils/exit-codes.js';
36
+ import { analytics } from './utils/analytics.js';
37
+ // Enable debug logging for all commands via env var.
38
+ // Subsumes the installer's --debug flag for non-installer commands.
39
+ if (process.env.WORKOS_DEBUG === '1') {
40
+ const { enableDebugLogs } = await import('./utils/debug.js');
41
+ enableDebugLogs();
42
+ }
43
+ // Telemetry infrastructure: crash reporter, store-forward, and gateway init.
44
+ // Must be before yargs so crashes during startup are captured.
45
+ installCrashReporter();
46
+ installStoreForward();
47
+ // Prewarm the telemetry opt-out preference before init: initForNonInstaller()
48
+ // checks isEnabled() (which reads the preference), and session/command events
49
+ // may fire shortly after. The sync getPreferences() fallback makes correctness
50
+ // ordering-independent, but prewarming keeps the synchronous event path off
51
+ // blocking fs IO (same rationale as the device-id prewarm).
52
+ await loadPreferences();
53
+ analytics.initForNonInstaller();
54
+ // Prewarm the device id off the blocking-fs path so the synchronous telemetry
55
+ // event path reads it from cache. Cheap (a tiny file read); awaited so it is
56
+ // resolved before any command emits an event.
57
+ await loadDeviceId();
58
+ // Fire-and-forget: recover events from previous crashes/exits.
59
+ // NO await — must not block startup (flush timeout is 3s).
60
+ recoverPendingEvents();
27
61
  // Resolve output mode early from raw argv (before yargs parses)
28
62
  const rawArgs = hideBin(process.argv);
29
63
  const hasJsonFlag = rawArgs.includes('--json');
@@ -36,8 +70,11 @@ try {
36
70
  }
37
71
  catch (error) {
38
72
  if (error instanceof InvalidInteractionModeError) {
39
- exitWithError({ code: 'invalid_mode', message: error.message });
73
+ outputError({ code: 'invalid_mode', message: error.message });
74
+ process.exit(ExitCode.GENERAL_ERROR);
40
75
  }
76
+ if (error instanceof CliExit)
77
+ process.exit(error.exitCode);
41
78
  throw error;
42
79
  }
43
80
  // Intercept --help --json before yargs parses (yargs exits on --help)
@@ -169,1302 +206,1447 @@ const installerOptions = {
169
206
  // Check for updates (blocks up to 500ms, skip in JSON/non-human modes to keep machine streams clean)
170
207
  if (!isJsonMode() && isPromptAllowed())
171
208
  await checkForUpdates();
172
- yargs(rawArgs)
173
- .parserConfiguration({ 'populate--': true })
174
- .env('WORKOS_INSTALLER')
175
- .option('json', {
176
- type: 'boolean',
177
- default: false,
178
- describe: 'Output results as JSON (auto-enabled in non-TTY)',
179
- global: true,
180
- })
181
- .option('mode', {
182
- type: 'string',
183
- choices: ['human', 'agent', 'ci'],
184
- describe: 'Interaction mode: human, coding agent, or CI automation',
185
- global: true,
186
- })
187
- .middleware(async (argv) => {
188
- // Warn about unclaimed environments before management commands.
189
- // Excluded: auth/claim/install/dashboard handle their own credential flows;
190
- // skills/doctor/env/debug are utility commands where the warning is unnecessary.
191
- const command = String(argv._?.[0] ?? '');
192
- if ([
193
- 'auth',
194
- 'skills',
195
- 'doctor',
196
- 'env',
197
- 'claim',
198
- 'install',
199
- 'debug',
200
- 'dashboard',
201
- 'emulate',
202
- 'dev',
203
- 'migrations',
204
- '',
205
- ].includes(command))
206
- return;
207
- await applyInsecureStorage(argv.insecureStorage);
208
- await maybeWarnUnclaimed();
209
- })
210
- .command('auth', 'Manage authentication (login, logout, status)', (yargs) => {
211
- yargs.options(insecureStorageOption);
212
- registerSubcommand(yargs, 'login', 'Authenticate with WorkOS via browser-based OAuth', (y) => y, async (argv) => {
213
- await applyInsecureStorage(argv.insecureStorage);
214
- const { runLogin } = await import('./commands/login.js');
215
- await runLogin();
216
- process.exit(0);
217
- });
218
- registerSubcommand(yargs, 'logout', 'Remove stored WorkOS credentials and tokens', (y) => y, async (argv) => {
219
- await applyInsecureStorage(argv.insecureStorage);
220
- const { runLogout } = await import('./commands/logout.js');
221
- await runLogout();
222
- });
223
- registerSubcommand(yargs, 'status', 'Show current authentication status', (y) => y, async (argv) => {
224
- await applyInsecureStorage(argv.insecureStorage);
225
- const { runAuthStatus } = await import('./commands/auth-status.js');
226
- await runAuthStatus();
227
- });
228
- return yargs.demandCommand(1, 'Please specify an auth subcommand').strict();
229
- })
230
- .command('skills', 'Manage WorkOS skills for coding agents (Claude Code, Codex, Cursor, Goose)', (yargs) => {
231
- registerSubcommand(yargs, 'install', 'Install bundled AuthKit skills to coding agents', (y) => y
232
- .option('skill', {
233
- alias: 's',
234
- type: 'array',
235
- string: true,
236
- description: 'Install specific skill(s) by name',
237
- })
238
- .option('agent', {
239
- alias: 'a',
240
- type: 'array',
241
- string: true,
242
- description: 'Target specific agent(s): claude-code, codex, cursor, goose',
243
- }), async (argv) => {
244
- const { runInstallSkill } = await import('./commands/install-skill.js');
245
- await runInstallSkill({
246
- skill: argv.skill,
247
- agent: argv.agent,
248
- });
249
- });
250
- registerSubcommand(yargs, 'uninstall', 'Remove installed WorkOS skills from coding agents', (y) => y
251
- .option('skill', {
252
- alias: 's',
253
- type: 'array',
254
- string: true,
255
- description: 'Remove specific skill(s) by name',
209
+ async function runCli() {
210
+ const startTime = Date.now();
211
+ let commandName = 'root';
212
+ const flags = extractUserFlags(rawArgs);
213
+ const parser = yargs(rawArgs)
214
+ .parserConfiguration({ 'populate--': true })
215
+ .exitProcess(false)
216
+ .fail((msg, err) => {
217
+ if (err instanceof CliExit)
218
+ throw err;
219
+ // yargs runs its demand/strict validation before dispatching middleware,
220
+ // so the command-name middleware below has not run yet and commandName is
221
+ // still 'root' (which SKIP_TELEMETRY_COMMANDS would drop). Recover the
222
+ // top-level command from the raw args so the validation_error event is
223
+ // attributed to the real command instead of being silently skipped. Only
224
+ // the top-level token is used. Later positionals can be user values
225
+ // (org names, emails, IDs), so recording them would leak data.
226
+ if (commandName === 'root') {
227
+ commandName = resolveCommandNameFromRawArgs(rawArgs);
228
+ }
229
+ if (msg) {
230
+ outputError({ code: 'invalid_usage', message: msg });
231
+ }
232
+ throw new CliExit(ExitCode.GENERAL_ERROR, { reason: 'validation_error' });
256
233
  })
257
- .option('agent', {
258
- alias: 'a',
259
- type: 'array',
260
- string: true,
261
- description: 'Target specific agent(s): claude-code, codex, cursor, goose',
262
- }), async (argv) => {
263
- const { runUninstallSkill } = await import('./commands/uninstall-skill.js');
264
- await runUninstallSkill({
265
- skill: argv.skill,
266
- agent: argv.agent,
267
- });
268
- });
269
- registerSubcommand(yargs, 'list', 'List available and installed skills', (y) => y.option('agent', {
270
- alias: 'a',
271
- type: 'array',
272
- string: true,
273
- description: 'Target specific agent(s): claude-code, codex, cursor, goose',
274
- }), async (argv) => {
275
- const { runListSkills } = await import('./commands/list-skills.js');
276
- await runListSkills({
277
- agent: argv.agent,
278
- });
279
- });
280
- return yargs.demandCommand(1, 'Please specify a skills subcommand').strict();
281
- })
282
- .command('doctor', 'Diagnose WorkOS AuthKit integration issues in the current project', (yargs) => yargs.options({
283
- verbose: {
284
- type: 'boolean',
285
- default: false,
286
- description: 'Include additional diagnostic information',
287
- },
288
- 'skip-api': {
289
- type: 'boolean',
290
- default: false,
291
- description: 'Skip API calls (offline mode)',
292
- },
293
- 'skip-ai': {
234
+ .env('WORKOS_INSTALLER')
235
+ .option('json', {
294
236
  type: 'boolean',
295
237
  default: false,
296
- description: 'Skip AI-powered analysis',
297
- },
298
- 'install-dir': {
238
+ describe: 'Output results as JSON (auto-enabled in non-TTY)',
239
+ global: true,
240
+ })
241
+ .option('mode', {
299
242
  type: 'string',
300
- default: process.cwd(),
301
- description: 'Project directory to analyze',
302
- },
303
- json: {
243
+ choices: ['human', 'agent', 'ci'],
244
+ describe: 'Interaction mode: human, coding agent, or CI automation',
245
+ global: true,
246
+ })
247
+ .middleware((argv) => {
248
+ const commandParts = argv._ || [];
249
+ commandName = resolveCanonicalName(commandParts);
250
+ })
251
+ .middleware((argv) => {
252
+ // First-run, stderr-only notice that telemetry is being collected.
253
+ // Skip while the user is actively managing telemetry, and on the
254
+ // empty/root command (bare `--help` / `--version` / `$0`). The notice
255
+ // is self-guarded — it no-ops in json mode, when already shown, when
256
+ // opted out, and after the first display this session.
257
+ const command = String(argv._?.[0] ?? '');
258
+ if (command === 'telemetry' || command === '')
259
+ return;
260
+ maybeShowTelemetryNotice();
261
+ })
262
+ .middleware(async (argv) => {
263
+ // Warn about unclaimed environments before management commands.
264
+ // Excluded: auth/claim/install/dashboard handle their own credential flows;
265
+ // skills/doctor/env/debug are utility commands where the warning is unnecessary.
266
+ const command = String(argv._?.[0] ?? '');
267
+ if ([
268
+ 'auth',
269
+ 'skills',
270
+ 'doctor',
271
+ 'env',
272
+ 'claim',
273
+ 'install',
274
+ 'debug',
275
+ 'dashboard',
276
+ 'emulate',
277
+ 'dev',
278
+ 'migrations',
279
+ '',
280
+ ].includes(command))
281
+ return;
282
+ await applyInsecureStorage(argv.insecureStorage);
283
+ await maybeWarnUnclaimed();
284
+ })
285
+ .command('auth', 'Manage authentication (login, logout, status)', (yargs) => {
286
+ yargs.options(insecureStorageOption);
287
+ registerSubcommand(yargs, 'login', 'Authenticate with WorkOS via browser-based OAuth', (y) => y, async (argv) => {
288
+ await applyInsecureStorage(argv.insecureStorage);
289
+ const { runLogin } = await import('./commands/login.js');
290
+ await runLogin();
291
+ });
292
+ registerSubcommand(yargs, 'logout', 'Remove stored WorkOS credentials and tokens', (y) => y, async (argv) => {
293
+ await applyInsecureStorage(argv.insecureStorage);
294
+ const { runLogout } = await import('./commands/logout.js');
295
+ await runLogout();
296
+ });
297
+ registerSubcommand(yargs, 'status', 'Show current authentication status', (y) => y, async (argv) => {
298
+ await applyInsecureStorage(argv.insecureStorage);
299
+ const { runAuthStatus } = await import('./commands/auth-status.js');
300
+ await runAuthStatus();
301
+ });
302
+ return yargs.demandCommand(1, 'Please specify an auth subcommand').strict();
303
+ })
304
+ .command('telemetry', 'Manage telemetry collection (opt-out, opt-in, status)', (yargs) => {
305
+ registerSubcommand(yargs, 'opt-out', 'Disable telemetry collection (persists across runs)', (y) => y, async () => {
306
+ const { runTelemetryOptOut } = await import('./commands/telemetry.js');
307
+ await runTelemetryOptOut();
308
+ });
309
+ registerSubcommand(yargs, 'opt-in', 'Re-enable telemetry collection', (y) => y, async () => {
310
+ const { runTelemetryOptIn } = await import('./commands/telemetry.js');
311
+ await runTelemetryOptIn();
312
+ });
313
+ registerSubcommand(yargs, 'status', 'Show whether telemetry is enabled and why', (y) => y, async () => {
314
+ const { runTelemetryStatus } = await import('./commands/telemetry.js');
315
+ await runTelemetryStatus();
316
+ });
317
+ return yargs.demandCommand(1, 'Please specify a telemetry subcommand').strict();
318
+ })
319
+ .command('skills', 'Manage WorkOS skills for coding agents (Claude Code, Codex, Cursor, Goose)', (yargs) => {
320
+ registerSubcommand(yargs, 'install', 'Install bundled AuthKit skills to coding agents', (y) => y
321
+ .option('skill', {
322
+ alias: 's',
323
+ type: 'array',
324
+ string: true,
325
+ description: 'Install specific skill(s) by name',
326
+ })
327
+ .option('agent', {
328
+ alias: 'a',
329
+ type: 'array',
330
+ string: true,
331
+ description: 'Target specific agent(s): claude-code, codex, cursor, goose',
332
+ }), async (argv) => {
333
+ const { runInstallSkill } = await import('./commands/install-skill.js');
334
+ await runInstallSkill({
335
+ skill: argv.skill,
336
+ agent: argv.agent,
337
+ });
338
+ });
339
+ registerSubcommand(yargs, 'uninstall', 'Remove installed WorkOS skills from coding agents', (y) => y
340
+ .option('skill', {
341
+ alias: 's',
342
+ type: 'array',
343
+ string: true,
344
+ description: 'Remove specific skill(s) by name',
345
+ })
346
+ .option('agent', {
347
+ alias: 'a',
348
+ type: 'array',
349
+ string: true,
350
+ description: 'Target specific agent(s): claude-code, codex, cursor, goose',
351
+ }), async (argv) => {
352
+ const { runUninstallSkill } = await import('./commands/uninstall-skill.js');
353
+ await runUninstallSkill({
354
+ skill: argv.skill,
355
+ agent: argv.agent,
356
+ });
357
+ });
358
+ registerSubcommand(yargs, 'list', 'List available and installed skills', (y) => y.option('agent', {
359
+ alias: 'a',
360
+ type: 'array',
361
+ string: true,
362
+ description: 'Target specific agent(s): claude-code, codex, cursor, goose',
363
+ }), async (argv) => {
364
+ const { runListSkills } = await import('./commands/list-skills.js');
365
+ await runListSkills({
366
+ agent: argv.agent,
367
+ });
368
+ });
369
+ return yargs.demandCommand(1, 'Please specify a skills subcommand').strict();
370
+ })
371
+ .command('doctor', 'Diagnose WorkOS AuthKit integration issues in the current project', (yargs) => yargs.options({
372
+ verbose: {
373
+ type: 'boolean',
374
+ default: false,
375
+ description: 'Include additional diagnostic information',
376
+ },
377
+ 'skip-api': {
378
+ type: 'boolean',
379
+ default: false,
380
+ description: 'Skip API calls (offline mode)',
381
+ },
382
+ 'skip-ai': {
383
+ type: 'boolean',
384
+ default: false,
385
+ description: 'Skip AI-powered analysis',
386
+ },
387
+ 'install-dir': {
388
+ type: 'string',
389
+ default: process.cwd(),
390
+ description: 'Project directory to analyze',
391
+ },
392
+ json: {
393
+ type: 'boolean',
394
+ default: false,
395
+ description: 'Output report as JSON',
396
+ },
397
+ copy: {
398
+ type: 'boolean',
399
+ default: false,
400
+ description: 'Copy report to clipboard',
401
+ },
402
+ fix: {
403
+ type: 'boolean',
404
+ default: false,
405
+ description: 'Auto-update stale WorkOS skills (writes to <agent>/skills/workos/ and workos-widgets/ only)',
406
+ },
407
+ }), async (argv) => {
408
+ const { handleDoctor } = await import('./commands/doctor.js');
409
+ await handleDoctor(argv);
410
+ })
411
+ // NOTE: When adding commands here, also update src/utils/help-json.ts
412
+ .command('env', 'Manage environment configurations (API keys, endpoints, active environment)', (yargs) => {
413
+ yargs.options(insecureStorageOption);
414
+ registerSubcommand(yargs, 'add [name] [apiKey]', 'Add an environment configuration', (y) => y
415
+ .positional('name', { type: 'string', describe: 'Environment name' })
416
+ .positional('apiKey', { type: 'string', describe: 'WorkOS API key' })
417
+ .option('client-id', { type: 'string', describe: 'WorkOS client ID' })
418
+ .option('endpoint', { type: 'string', describe: 'Custom API endpoint' }), async (argv) => {
419
+ await applyInsecureStorage(argv.insecureStorage);
420
+ const { runEnvAdd } = await import('./commands/env.js');
421
+ await runEnvAdd({
422
+ name: argv.name,
423
+ apiKey: argv.apiKey,
424
+ clientId: argv.clientId,
425
+ endpoint: argv.endpoint,
426
+ });
427
+ });
428
+ registerSubcommand(yargs, 'remove <name>', 'Remove an environment configuration', (y) => y.positional('name', { type: 'string', demandOption: true, describe: 'Environment name' }), async (argv) => {
429
+ await applyInsecureStorage(argv.insecureStorage);
430
+ const { runEnvRemove } = await import('./commands/env.js');
431
+ await runEnvRemove(argv.name);
432
+ });
433
+ registerSubcommand(yargs, 'switch [name]', 'Switch active environment', (y) => y.positional('name', { type: 'string', describe: 'Environment name' }), async (argv) => {
434
+ if (!argv.name && !isPromptAllowed()) {
435
+ exitWithError({
436
+ code: 'missing_args',
437
+ message: 'Environment name required. Usage: workos env switch <name>',
438
+ });
439
+ }
440
+ await applyInsecureStorage(argv.insecureStorage);
441
+ const { runEnvSwitch } = await import('./commands/env.js');
442
+ await runEnvSwitch(argv.name);
443
+ });
444
+ registerSubcommand(yargs, 'list', 'List configured environments', (y) => y, async (argv) => {
445
+ await applyInsecureStorage(argv.insecureStorage);
446
+ const { runEnvList } = await import('./commands/env.js');
447
+ await runEnvList();
448
+ });
449
+ registerSubcommand(yargs, 'claim', 'Claim an unclaimed environment (link it to your account)', (y) => y, async (argv) => {
450
+ await applyInsecureStorage(argv.insecureStorage);
451
+ const { runClaim } = await import('./commands/claim.js');
452
+ await runClaim();
453
+ });
454
+ return yargs.demandCommand(1, 'Please specify an env subcommand').strict();
455
+ })
456
+ .command('api [endpoint] [filter]', 'Make authenticated requests to the WorkOS API', (yargs) => yargs
457
+ .options(insecureStorageOption)
458
+ .positional('endpoint', {
459
+ type: 'string',
460
+ describe: "API endpoint path (e.g. /users), or 'ls' to list endpoints",
461
+ })
462
+ .positional('filter', {
463
+ type: 'string',
464
+ describe: 'Filter keyword (used with ls)',
465
+ })
466
+ .option('method', {
467
+ alias: 'X',
468
+ type: 'string',
469
+ describe: 'HTTP method (default: GET, or POST if body provided)',
470
+ })
471
+ .option('data', {
472
+ alias: 'd',
473
+ type: 'string',
474
+ describe: 'JSON request body',
475
+ })
476
+ .option('file', {
477
+ type: 'string',
478
+ describe: 'Read request body from a file (or - for stdin)',
479
+ })
480
+ .option('include', {
481
+ alias: 'i',
304
482
  type: 'boolean',
305
483
  default: false,
306
- description: 'Output report as JSON',
307
- },
308
- copy: {
484
+ describe: 'Show response headers',
485
+ })
486
+ .option('api-key', {
487
+ type: 'string',
488
+ describe: 'Override the API key',
489
+ })
490
+ .option('dry-run', {
309
491
  type: 'boolean',
310
492
  default: false,
311
- description: 'Copy report to clipboard',
312
- },
313
- fix: {
493
+ describe: 'Show the request without executing it',
494
+ })
495
+ .option('yes', {
496
+ alias: 'y',
314
497
  type: 'boolean',
315
498
  default: false,
316
- description: 'Auto-update stale WorkOS skills (writes to <agent>/skills/workos/ and workos-widgets/ only)',
317
- },
318
- }), async (argv) => {
319
- const { handleDoctor } = await import('./commands/doctor.js');
320
- await handleDoctor(argv);
321
- })
322
- // NOTE: When adding commands here, also update src/utils/help-json.ts
323
- .command('env', 'Manage environment configurations (API keys, endpoints, active environment)', (yargs) => {
324
- yargs.options(insecureStorageOption);
325
- registerSubcommand(yargs, 'add [name] [apiKey]', 'Add an environment configuration', (y) => y
326
- .positional('name', { type: 'string', describe: 'Environment name' })
327
- .positional('apiKey', { type: 'string', describe: 'WorkOS API key' })
328
- .option('client-id', { type: 'string', describe: 'WorkOS client ID' })
329
- .option('endpoint', { type: 'string', describe: 'Custom API endpoint' }), async (argv) => {
330
- await applyInsecureStorage(argv.insecureStorage);
331
- const { runEnvAdd } = await import('./commands/env.js');
332
- await runEnvAdd({
333
- name: argv.name,
499
+ describe: 'Skip confirmation for mutating requests',
500
+ })
501
+ .example('workos api ls', 'List all available endpoints')
502
+ .example('workos api ls users', 'List endpoints matching "users"')
503
+ .example('workos api /user_management/users', 'GET /user_management/users')
504
+ .example('workos api /organizations -d \'{"name":"Acme"}\'', 'POST with a JSON body')
505
+ .example('workos api /organizations/org_123 -X DELETE', 'DELETE an organization'), async (argv) => {
506
+ await applyInsecureStorage(argv.insecureStorage);
507
+ const endpoint = argv.endpoint;
508
+ const filter = argv.filter;
509
+ const { runApiLs, runApiRequest, runApiInteractive } = await import('./commands/api/index.js');
510
+ if (!endpoint) {
511
+ await runApiInteractive({ apiKey: argv.apiKey });
512
+ return;
513
+ }
514
+ if (endpoint === 'ls') {
515
+ await runApiLs(filter);
516
+ return;
517
+ }
518
+ await runApiRequest(endpoint, {
519
+ method: argv.method,
520
+ data: argv.data,
521
+ file: argv.file,
522
+ include: argv.include,
334
523
  apiKey: argv.apiKey,
335
- clientId: argv.clientId,
336
- endpoint: argv.endpoint,
524
+ dryRun: argv.dryRun,
525
+ yes: argv.yes,
337
526
  });
338
- });
339
- registerSubcommand(yargs, 'remove <name>', 'Remove an environment configuration', (y) => y.positional('name', { type: 'string', demandOption: true, describe: 'Environment name' }), async (argv) => {
340
- await applyInsecureStorage(argv.insecureStorage);
341
- const { runEnvRemove } = await import('./commands/env.js');
342
- await runEnvRemove(argv.name);
343
- });
344
- registerSubcommand(yargs, 'switch [name]', 'Switch active environment', (y) => y.positional('name', { type: 'string', describe: 'Environment name' }), async (argv) => {
345
- if (!argv.name && !isPromptAllowed()) {
346
- exitWithError({
347
- code: 'missing_args',
348
- message: 'Environment name required. Usage: workos env switch <name>',
349
- });
350
- }
351
- await applyInsecureStorage(argv.insecureStorage);
352
- const { runEnvSwitch } = await import('./commands/env.js');
353
- await runEnvSwitch(argv.name);
354
- });
355
- registerSubcommand(yargs, 'list', 'List configured environments', (y) => y, async (argv) => {
356
- await applyInsecureStorage(argv.insecureStorage);
357
- const { runEnvList } = await import('./commands/env.js');
358
- await runEnvList();
359
- });
360
- registerSubcommand(yargs, 'claim', 'Claim an unclaimed environment (link it to your account)', (y) => y, async (argv) => {
361
- await applyInsecureStorage(argv.insecureStorage);
362
- const { runClaim } = await import('./commands/claim.js');
363
- await runClaim();
364
- });
365
- return yargs.demandCommand(1, 'Please specify an env subcommand').strict();
366
- })
367
- .command('api [endpoint] [filter]', 'Make authenticated requests to the WorkOS API', (yargs) => yargs
368
- .options(insecureStorageOption)
369
- .positional('endpoint', {
370
- type: 'string',
371
- describe: "API endpoint path (e.g. /users), or 'ls' to list endpoints",
372
- })
373
- .positional('filter', {
374
- type: 'string',
375
- describe: 'Filter keyword (used with ls)',
376
- })
377
- .option('method', {
378
- alias: 'X',
379
- type: 'string',
380
- describe: 'HTTP method (default: GET, or POST if body provided)',
381
- })
382
- .option('data', {
383
- alias: 'd',
384
- type: 'string',
385
- describe: 'JSON request body',
386
- })
387
- .option('file', {
388
- type: 'string',
389
- describe: 'Read request body from a file (or - for stdin)',
390
- })
391
- .option('include', {
392
- alias: 'i',
393
- type: 'boolean',
394
- default: false,
395
- describe: 'Show response headers',
396
- })
397
- .option('api-key', {
398
- type: 'string',
399
- describe: 'Override the API key',
400
- })
401
- .option('dry-run', {
402
- type: 'boolean',
403
- default: false,
404
- describe: 'Show the request without executing it',
405
- })
406
- .option('yes', {
407
- alias: 'y',
408
- type: 'boolean',
409
- default: false,
410
- describe: 'Skip confirmation for mutating requests',
411
- })
412
- .example('workos api ls', 'List all available endpoints')
413
- .example('workos api ls users', 'List endpoints matching "users"')
414
- .example('workos api /user_management/users', 'GET /user_management/users')
415
- .example('workos api /organizations -d \'{"name":"Acme"}\'', 'POST with a JSON body')
416
- .example('workos api /organizations/org_123 -X DELETE', 'DELETE an organization'), async (argv) => {
417
- await applyInsecureStorage(argv.insecureStorage);
418
- const endpoint = argv.endpoint;
419
- const filter = argv.filter;
420
- const { runApiLs, runApiRequest, runApiInteractive } = await import('./commands/api/index.js');
421
- if (!endpoint) {
422
- await runApiInteractive({ apiKey: argv.apiKey });
423
- return;
424
- }
425
- if (endpoint === 'ls') {
426
- await runApiLs(filter);
427
- return;
428
- }
429
- await runApiRequest(endpoint, {
430
- method: argv.method,
431
- data: argv.data,
432
- file: argv.file,
433
- include: argv.include,
434
- apiKey: argv.apiKey,
435
- dryRun: argv.dryRun,
436
- yes: argv.yes,
437
- });
438
- })
439
- .command(['organization', 'org'], 'Manage WorkOS organizations (create, update, get, list, delete)', (yargs) => {
440
- yargs.options({
441
- ...insecureStorageOption,
442
- 'api-key': {
527
+ })
528
+ .command(['organization', 'org'], 'Manage WorkOS organizations (create, update, get, list, delete)', (yargs) => {
529
+ yargs.options({
530
+ ...insecureStorageOption,
531
+ 'api-key': {
532
+ type: 'string',
533
+ describe: 'WorkOS API key (overrides environment config). Format: sk_live_* or sk_test_*',
534
+ },
535
+ });
536
+ registerSubcommand(yargs, 'create <name> [domains..]', 'Create a new organization with optional verified domains', (y) => y
537
+ .positional('name', { type: 'string', demandOption: true, describe: 'Organization name' })
538
+ .positional('domains', {
443
539
  type: 'string',
444
- describe: 'WorkOS API key (overrides environment config). Format: sk_live_* or sk_test_*',
445
- },
446
- });
447
- registerSubcommand(yargs, 'create <name> [domains..]', 'Create a new organization with optional verified domains', (y) => y
448
- .positional('name', { type: 'string', demandOption: true, describe: 'Organization name' })
449
- .positional('domains', {
450
- type: 'string',
451
- array: true,
452
- describe: 'Domains in format domain:state (state defaults to verified)',
453
- }), async (argv) => {
454
- await applyInsecureStorage(argv.insecureStorage);
455
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
456
- const { runOrgCreate } = await import('./commands/organization.js');
457
- const apiKey = resolveApiKey({ apiKey: argv.apiKey });
458
- await runOrgCreate(argv.name, argv.domains || [], apiKey, resolveApiBaseUrl());
459
- });
460
- registerSubcommand(yargs, 'update <orgId> <name> [domain] [state]', 'Update an organization', (y) => y
461
- .positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' })
462
- .positional('name', { type: 'string', demandOption: true, describe: 'Organization name' })
463
- .positional('domain', { type: 'string', describe: 'Domain' })
464
- .positional('state', { type: 'string', describe: 'Domain state (verified or pending)' }), async (argv) => {
465
- await applyInsecureStorage(argv.insecureStorage);
466
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
467
- const { runOrgUpdate } = await import('./commands/organization.js');
468
- const apiKey = resolveApiKey({ apiKey: argv.apiKey });
469
- await runOrgUpdate(argv.orgId, argv.name, apiKey, argv.domain, argv.state, resolveApiBaseUrl());
470
- });
471
- registerSubcommand(yargs, 'get <orgId>', 'Get an organization by ID', (y) => y.positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' }), async (argv) => {
472
- await applyInsecureStorage(argv.insecureStorage);
473
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
474
- const { runOrgGet } = await import('./commands/organization.js');
475
- const apiKey = resolveApiKey({ apiKey: argv.apiKey });
476
- await runOrgGet(argv.orgId, apiKey, resolveApiBaseUrl());
477
- });
478
- registerSubcommand(yargs, 'list', 'List organizations', (y) => y.options({
479
- domain: { type: 'string', describe: 'Filter by domain' },
480
- limit: { type: 'number', describe: 'Limit number of results' },
481
- before: { type: 'string', describe: 'Cursor for results before a specific item' },
482
- after: { type: 'string', describe: 'Cursor for results after a specific item' },
483
- order: { type: 'string', describe: 'Order of results (asc or desc)' },
484
- }), async (argv) => {
485
- await applyInsecureStorage(argv.insecureStorage);
486
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
487
- const { runOrgList } = await import('./commands/organization.js');
488
- const apiKey = resolveApiKey({ apiKey: argv.apiKey });
489
- await runOrgList({ domain: argv.domain, limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, apiKey, resolveApiBaseUrl());
490
- });
491
- registerSubcommand(yargs, 'delete <orgId>', 'Delete an organization', (y) => y.positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' }), async (argv) => {
492
- await applyInsecureStorage(argv.insecureStorage);
493
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
494
- const { runOrgDelete } = await import('./commands/organization.js');
495
- const apiKey = resolveApiKey({ apiKey: argv.apiKey });
496
- await runOrgDelete(argv.orgId, apiKey, resolveApiBaseUrl());
497
- });
498
- return yargs.demandCommand(1, 'Please specify an organization subcommand').strict();
499
- })
500
- .command('user', 'Manage WorkOS users (get, list, update, delete)', (yargs) => {
501
- yargs.options({
502
- ...insecureStorageOption,
503
- 'api-key': {
504
- type: 'string',
505
- describe: 'WorkOS API key (overrides environment config). Format: sk_live_* or sk_test_*',
506
- },
507
- });
508
- registerSubcommand(yargs, 'get <userId>', 'Get a user by ID', (y) => y.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }), async (argv) => {
509
- await applyInsecureStorage(argv.insecureStorage);
510
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
511
- const { runUserGet } = await import('./commands/user.js');
512
- await runUserGet(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
513
- });
514
- registerSubcommand(yargs, 'list', 'List users', (y) => y.options({
515
- email: { type: 'string', describe: 'Filter by email' },
516
- organization: { type: 'string', describe: 'Filter by organization ID' },
517
- limit: { type: 'number', describe: 'Limit number of results' },
518
- before: { type: 'string', describe: 'Cursor for results before a specific item' },
519
- after: { type: 'string', describe: 'Cursor for results after a specific item' },
520
- order: { type: 'string', describe: 'Order of results (asc or desc)' },
521
- }), async (argv) => {
522
- await applyInsecureStorage(argv.insecureStorage);
523
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
524
- const { runUserList } = await import('./commands/user.js');
525
- await runUserList({
526
- email: argv.email,
527
- organization: argv.organization,
528
- limit: argv.limit,
529
- before: argv.before,
530
- after: argv.after,
531
- order: argv.order,
532
- }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
533
- });
534
- registerSubcommand(yargs, 'update <userId>', 'Update a user', (y) => y.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }).options({
535
- 'first-name': { type: 'string', describe: 'First name' },
536
- 'last-name': { type: 'string', describe: 'Last name' },
537
- 'email-verified': { type: 'boolean', describe: 'Email verification status' },
538
- password: { type: 'string', describe: 'New password' },
539
- 'external-id': { type: 'string', describe: 'External ID' },
540
- }), async (argv) => {
541
- await applyInsecureStorage(argv.insecureStorage);
542
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
543
- const { runUserUpdate } = await import('./commands/user.js');
544
- await runUserUpdate(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), {
545
- firstName: argv.firstName,
546
- lastName: argv.lastName,
547
- emailVerified: argv.emailVerified,
548
- password: argv.password,
549
- externalId: argv.externalId,
550
- }, resolveApiBaseUrl());
551
- });
552
- registerSubcommand(yargs, 'delete <userId>', 'Delete a user', (y) => y.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }), async (argv) => {
553
- await applyInsecureStorage(argv.insecureStorage);
554
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
555
- const { runUserDelete } = await import('./commands/user.js');
556
- await runUserDelete(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
557
- });
558
- return yargs.demandCommand(1, 'Please specify a user subcommand').strict();
559
- })
560
- // --- Resource Management Commands ---
561
- .command('role', 'Manage WorkOS roles (environment and organization-scoped)', (yargs) => {
562
- yargs.options({
563
- ...insecureStorageOption,
564
- 'api-key': { type: 'string', describe: 'WorkOS API key' },
565
- org: { type: 'string', describe: 'Organization ID (for org-scoped roles)' },
566
- });
567
- registerSubcommand(yargs, 'list', 'List roles', (y) => y, async (argv) => {
568
- await applyInsecureStorage(argv.insecureStorage);
569
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
570
- const { runRoleList } = await import('./commands/role.js');
571
- await runRoleList(argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
572
- });
573
- registerSubcommand(yargs, 'get <slug>', 'Get a role by slug', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
574
- await applyInsecureStorage(argv.insecureStorage);
575
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
576
- const { runRoleGet } = await import('./commands/role.js');
577
- await runRoleGet(argv.slug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
578
- });
579
- registerSubcommand(yargs, 'create', 'Create a role', (y) => y.options({
580
- slug: { type: 'string', demandOption: true, describe: 'Role slug' },
581
- name: { type: 'string', demandOption: true, describe: 'Role name' },
582
- description: { type: 'string', describe: 'Role description' },
583
- }), async (argv) => {
584
- await applyInsecureStorage(argv.insecureStorage);
585
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
586
- const { runRoleCreate } = await import('./commands/role.js');
587
- await runRoleCreate({ slug: argv.slug, name: argv.name, description: argv.description }, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
588
- });
589
- registerSubcommand(yargs, 'update <slug>', 'Update a role', (y) => y
590
- .positional('slug', { type: 'string', demandOption: true })
591
- .options({ name: { type: 'string' }, description: { type: 'string' } }), async (argv) => {
592
- await applyInsecureStorage(argv.insecureStorage);
593
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
594
- const { runRoleUpdate } = await import('./commands/role.js');
595
- await runRoleUpdate(argv.slug, { name: argv.name, description: argv.description }, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
596
- });
597
- registerSubcommand(yargs, 'delete <slug>', 'Delete an org-scoped role (requires --org)', (y) => y.positional('slug', { type: 'string', demandOption: true }).demandOption('org'), async (argv) => {
598
- await applyInsecureStorage(argv.insecureStorage);
599
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
600
- const { runRoleDelete } = await import('./commands/role.js');
601
- await runRoleDelete(argv.slug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
602
- });
603
- registerSubcommand(yargs, 'set-permissions <slug>', 'Set all permissions on a role (replaces existing)', (y) => y.positional('slug', { type: 'string', demandOption: true }).option('permissions', {
604
- type: 'string',
605
- demandOption: true,
606
- describe: 'Comma-separated permission slugs',
607
- }), async (argv) => {
608
- await applyInsecureStorage(argv.insecureStorage);
609
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
610
- const { runRoleSetPermissions } = await import('./commands/role.js');
611
- await runRoleSetPermissions(argv.slug, argv.permissions.split(','), argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
612
- });
613
- registerSubcommand(yargs, 'add-permission <slug> <permissionSlug>', 'Add a permission to a role', (y) => y
614
- .positional('slug', { type: 'string', demandOption: true })
615
- .positional('permissionSlug', { type: 'string', demandOption: true }), async (argv) => {
616
- await applyInsecureStorage(argv.insecureStorage);
617
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
618
- const { runRoleAddPermission } = await import('./commands/role.js');
619
- await runRoleAddPermission(argv.slug, argv.permissionSlug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
620
- });
621
- registerSubcommand(yargs, 'remove-permission <slug> <permissionSlug>', 'Remove a permission from an org role (requires --org)', (y) => y
622
- .positional('slug', { type: 'string', demandOption: true })
623
- .positional('permissionSlug', { type: 'string', demandOption: true })
624
- .demandOption('org'), async (argv) => {
625
- await applyInsecureStorage(argv.insecureStorage);
626
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
627
- const { runRoleRemovePermission } = await import('./commands/role.js');
628
- await runRoleRemovePermission(argv.slug, argv.permissionSlug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
629
- });
630
- return yargs.demandCommand(1, 'Please specify a role subcommand').strict();
631
- })
632
- .command('permission', 'Manage WorkOS permissions', (yargs) => {
633
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
634
- registerSubcommand(yargs, 'list', 'List permissions', (y) => y.options({
635
- limit: { type: 'number' },
636
- before: { type: 'string' },
637
- after: { type: 'string' },
638
- order: { type: 'string' },
639
- }), async (argv) => {
640
- await applyInsecureStorage(argv.insecureStorage);
641
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
642
- const { runPermissionList } = await import('./commands/permission.js');
643
- await runPermissionList({ limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
644
- });
645
- registerSubcommand(yargs, 'get <slug>', 'Get a permission', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
646
- await applyInsecureStorage(argv.insecureStorage);
647
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
648
- const { runPermissionGet } = await import('./commands/permission.js');
649
- await runPermissionGet(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
650
- });
651
- registerSubcommand(yargs, 'create', 'Create a permission', (y) => y.options({
652
- slug: { type: 'string', demandOption: true },
653
- name: { type: 'string', demandOption: true },
654
- description: { type: 'string' },
655
- }), async (argv) => {
656
- await applyInsecureStorage(argv.insecureStorage);
657
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
658
- const { runPermissionCreate } = await import('./commands/permission.js');
659
- await runPermissionCreate({ slug: argv.slug, name: argv.name, description: argv.description }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
660
- });
661
- registerSubcommand(yargs, 'update <slug>', 'Update a permission', (y) => y
662
- .positional('slug', { type: 'string', demandOption: true })
663
- .options({ name: { type: 'string' }, description: { type: 'string' } }), async (argv) => {
664
- await applyInsecureStorage(argv.insecureStorage);
665
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
666
- const { runPermissionUpdate } = await import('./commands/permission.js');
667
- await runPermissionUpdate(argv.slug, { name: argv.name, description: argv.description }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
668
- });
669
- registerSubcommand(yargs, 'delete <slug>', 'Delete a permission', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
670
- await applyInsecureStorage(argv.insecureStorage);
671
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
672
- const { runPermissionDelete } = await import('./commands/permission.js');
673
- await runPermissionDelete(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
674
- });
675
- return yargs.demandCommand(1, 'Please specify a permission subcommand').strict();
676
- })
677
- .command('membership', 'Manage organization memberships', (yargs) => {
678
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
679
- registerSubcommand(yargs, 'list', 'List memberships', (y) => y.options({
680
- org: { type: 'string' },
681
- user: { type: 'string' },
682
- limit: { type: 'number' },
683
- before: { type: 'string' },
684
- after: { type: 'string' },
685
- order: { type: 'string' },
686
- }), async (argv) => {
687
- await applyInsecureStorage(argv.insecureStorage);
688
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
689
- const { runMembershipList } = await import('./commands/membership.js');
690
- await runMembershipList({
691
- org: argv.org,
692
- user: argv.user,
693
- limit: argv.limit,
694
- before: argv.before,
695
- after: argv.after,
696
- order: argv.order,
697
- }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
698
- });
699
- registerSubcommand(yargs, 'get <id>', 'Get a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
700
- await applyInsecureStorage(argv.insecureStorage);
701
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
702
- const { runMembershipGet } = await import('./commands/membership.js');
703
- await runMembershipGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
704
- });
705
- registerSubcommand(yargs, 'create', 'Create a membership', (y) => y.options({
706
- org: { type: 'string', demandOption: true },
707
- user: { type: 'string', demandOption: true },
708
- role: { type: 'string' },
709
- }), async (argv) => {
710
- await applyInsecureStorage(argv.insecureStorage);
711
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
712
- const { runMembershipCreate } = await import('./commands/membership.js');
713
- await runMembershipCreate({ org: argv.org, user: argv.user, role: argv.role }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
714
- });
715
- registerSubcommand(yargs, 'update <id>', 'Update a membership', (y) => y.positional('id', { type: 'string', demandOption: true }).option('role', { type: 'string' }), async (argv) => {
716
- await applyInsecureStorage(argv.insecureStorage);
717
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
718
- const { runMembershipUpdate } = await import('./commands/membership.js');
719
- await runMembershipUpdate(argv.id, argv.role, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
720
- });
721
- registerSubcommand(yargs, 'delete <id>', 'Delete a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
722
- await applyInsecureStorage(argv.insecureStorage);
723
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
724
- const { runMembershipDelete } = await import('./commands/membership.js');
725
- await runMembershipDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
726
- });
727
- registerSubcommand(yargs, 'deactivate <id>', 'Deactivate a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
728
- await applyInsecureStorage(argv.insecureStorage);
729
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
730
- const { runMembershipDeactivate } = await import('./commands/membership.js');
731
- await runMembershipDeactivate(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
732
- });
733
- registerSubcommand(yargs, 'reactivate <id>', 'Reactivate a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
734
- await applyInsecureStorage(argv.insecureStorage);
735
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
736
- const { runMembershipReactivate } = await import('./commands/membership.js');
737
- await runMembershipReactivate(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
738
- });
739
- return yargs.demandCommand(1, 'Please specify a membership subcommand').strict();
740
- })
741
- .command('invitation', 'Manage user invitations', (yargs) => {
742
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
743
- registerSubcommand(yargs, 'list', 'List invitations', (y) => y.options({
744
- org: { type: 'string' },
745
- email: { type: 'string' },
746
- limit: { type: 'number' },
747
- before: { type: 'string' },
748
- after: { type: 'string' },
749
- order: { type: 'string' },
750
- }), async (argv) => {
751
- await applyInsecureStorage(argv.insecureStorage);
752
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
753
- const { runInvitationList } = await import('./commands/invitation.js');
754
- await runInvitationList({
755
- org: argv.org,
756
- email: argv.email,
757
- limit: argv.limit,
758
- before: argv.before,
759
- after: argv.after,
760
- order: argv.order,
761
- }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
762
- });
763
- registerSubcommand(yargs, 'get <id>', 'Get an invitation', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
764
- await applyInsecureStorage(argv.insecureStorage);
765
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
766
- const { runInvitationGet } = await import('./commands/invitation.js');
767
- await runInvitationGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
768
- });
769
- registerSubcommand(yargs, 'send', 'Send an invitation', (y) => y.options({
770
- email: { type: 'string', demandOption: true },
771
- org: { type: 'string' },
772
- role: { type: 'string' },
773
- 'expires-in-days': { type: 'number' },
774
- }), async (argv) => {
775
- await applyInsecureStorage(argv.insecureStorage);
776
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
777
- const { runInvitationSend } = await import('./commands/invitation.js');
778
- await runInvitationSend({ email: argv.email, org: argv.org, role: argv.role, expiresInDays: argv.expiresInDays }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
779
- });
780
- registerSubcommand(yargs, 'revoke <id>', 'Revoke an invitation', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
781
- await applyInsecureStorage(argv.insecureStorage);
782
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
783
- const { runInvitationRevoke } = await import('./commands/invitation.js');
784
- await runInvitationRevoke(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
785
- });
786
- registerSubcommand(yargs, 'resend <id>', 'Resend an invitation', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
787
- await applyInsecureStorage(argv.insecureStorage);
788
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
789
- const { runInvitationResend } = await import('./commands/invitation.js');
790
- await runInvitationResend(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
791
- });
792
- return yargs.demandCommand(1, 'Please specify an invitation subcommand').strict();
793
- })
794
- .command('session', 'Manage user sessions', (yargs) => {
795
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
796
- registerSubcommand(yargs, 'list <userId>', 'List sessions for a user', (y) => y.positional('userId', { type: 'string', demandOption: true }).options({
797
- limit: { type: 'number' },
798
- before: { type: 'string' },
799
- after: { type: 'string' },
800
- order: { type: 'string' },
801
- }), async (argv) => {
802
- await applyInsecureStorage(argv.insecureStorage);
803
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
804
- const { runSessionList } = await import('./commands/session.js');
805
- await runSessionList(argv.userId, { limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
806
- });
807
- registerSubcommand(yargs, 'revoke <sessionId>', 'Revoke a session', (y) => y.positional('sessionId', { type: 'string', demandOption: true }), async (argv) => {
808
- await applyInsecureStorage(argv.insecureStorage);
809
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
810
- const { runSessionRevoke } = await import('./commands/session.js');
811
- await runSessionRevoke(argv.sessionId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
812
- });
813
- return yargs.demandCommand(1, 'Please specify a session subcommand').strict();
814
- })
815
- .command('connection', 'Manage SSO connections (read/delete)', (yargs) => {
816
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
817
- registerSubcommand(yargs, 'list', 'List connections', (y) => y.options({
818
- org: { type: 'string', describe: 'Filter by org ID' },
819
- type: { type: 'string', describe: 'Filter by connection type' },
820
- limit: { type: 'number' },
821
- before: { type: 'string' },
822
- after: { type: 'string' },
823
- order: { type: 'string' },
824
- }), async (argv) => {
825
- await applyInsecureStorage(argv.insecureStorage);
826
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
827
- const { runConnectionList } = await import('./commands/connection.js');
828
- await runConnectionList({
829
- organizationId: argv.org,
830
- connectionType: argv.type,
831
- limit: argv.limit,
832
- before: argv.before,
833
- after: argv.after,
834
- order: argv.order,
835
- }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
836
- });
837
- registerSubcommand(yargs, 'get <id>', 'Get a connection', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
838
- await applyInsecureStorage(argv.insecureStorage);
839
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
840
- const { runConnectionGet } = await import('./commands/connection.js');
841
- await runConnectionGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
842
- });
843
- registerSubcommand(yargs, 'delete <id>', 'Delete a connection', (y) => y.positional('id', { type: 'string', demandOption: true }).option('force', { type: 'boolean', default: false }), async (argv) => {
844
- await applyInsecureStorage(argv.insecureStorage);
845
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
846
- const { runConnectionDelete } = await import('./commands/connection.js');
847
- await runConnectionDelete(argv.id, { force: argv.force }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
848
- });
849
- return yargs.demandCommand(1, 'Please specify a connection subcommand').strict();
850
- })
851
- .command('directory', 'Manage directory sync (read/delete, list users/groups)', (yargs) => {
852
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
853
- registerSubcommand(yargs, 'list', 'List directories', (y) => y.options({
854
- org: { type: 'string' },
855
- limit: { type: 'number' },
856
- before: { type: 'string' },
857
- after: { type: 'string' },
858
- order: { type: 'string' },
859
- }), async (argv) => {
860
- await applyInsecureStorage(argv.insecureStorage);
861
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
862
- const { runDirectoryList } = await import('./commands/directory.js');
863
- await runDirectoryList({ organizationId: argv.org, limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
864
- });
865
- registerSubcommand(yargs, 'get <id>', 'Get a directory', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
866
- await applyInsecureStorage(argv.insecureStorage);
867
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
868
- const { runDirectoryGet } = await import('./commands/directory.js');
869
- await runDirectoryGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
870
- });
871
- registerSubcommand(yargs, 'delete <id>', 'Delete a directory', (y) => y.positional('id', { type: 'string', demandOption: true }).option('force', { type: 'boolean', default: false }), async (argv) => {
872
- await applyInsecureStorage(argv.insecureStorage);
873
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
874
- const { runDirectoryDelete } = await import('./commands/directory.js');
875
- await runDirectoryDelete(argv.id, { force: argv.force }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
876
- });
877
- registerSubcommand(yargs, 'list-users', 'List directory users', (y) => y.options({
878
- directory: { type: 'string' },
879
- group: { type: 'string' },
880
- limit: { type: 'number' },
881
- before: { type: 'string' },
882
- after: { type: 'string' },
883
- }), async (argv) => {
884
- await applyInsecureStorage(argv.insecureStorage);
885
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
886
- const { runDirectoryListUsers } = await import('./commands/directory.js');
887
- await runDirectoryListUsers({ directory: argv.directory, group: argv.group, limit: argv.limit, before: argv.before, after: argv.after }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
888
- });
889
- registerSubcommand(yargs, 'list-groups', 'List directory groups', (y) => y.options({
890
- directory: { type: 'string', demandOption: true },
891
- limit: { type: 'number' },
892
- before: { type: 'string' },
893
- after: { type: 'string' },
894
- }), async (argv) => {
895
- await applyInsecureStorage(argv.insecureStorage);
896
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
897
- const { runDirectoryListGroups } = await import('./commands/directory.js');
898
- await runDirectoryListGroups({ directory: argv.directory, limit: argv.limit, before: argv.before, after: argv.after }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
899
- });
900
- return yargs.demandCommand(1, 'Please specify a directory subcommand').strict();
901
- })
902
- .command('event', 'Query WorkOS events', (yargs) => {
903
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
904
- registerSubcommand(yargs, 'list', 'List events', (y) => y.options({
905
- events: { type: 'string', demandOption: true, describe: 'Comma-separated event types' },
906
- after: { type: 'string' },
907
- org: { type: 'string' },
908
- 'range-start': { type: 'string' },
909
- 'range-end': { type: 'string' },
910
- limit: { type: 'number' },
911
- }), async (argv) => {
912
- await applyInsecureStorage(argv.insecureStorage);
913
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
914
- const { runEventList } = await import('./commands/event.js');
915
- await runEventList({
916
- events: argv.events.split(','),
917
- after: argv.after,
918
- organizationId: argv.org,
919
- rangeStart: argv.rangeStart,
920
- rangeEnd: argv.rangeEnd,
921
- limit: argv.limit,
922
- }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
923
- });
924
- return yargs.demandCommand(1, 'Please specify an event subcommand').strict();
925
- })
926
- .command('audit-log', 'Manage audit logs', (yargs) => {
927
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
928
- registerSubcommand(yargs, 'create-event <orgId>', 'Create an audit log event', (y) => y.positional('orgId', { type: 'string', demandOption: true }).options({
929
- action: { type: 'string' },
930
- 'actor-type': { type: 'string' },
931
- 'actor-id': { type: 'string' },
932
- 'actor-name': { type: 'string' },
933
- targets: { type: 'string' },
934
- context: { type: 'string' },
935
- metadata: { type: 'string' },
936
- 'occurred-at': { type: 'string' },
937
- file: { type: 'string' },
938
- }), async (argv) => {
939
- await applyInsecureStorage(argv.insecureStorage);
940
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
941
- const { runAuditLogCreateEvent } = await import('./commands/audit-log.js');
942
- await runAuditLogCreateEvent(argv.orgId, {
943
- action: argv.action,
944
- actorType: argv.actorType,
945
- actorId: argv.actorId,
946
- actorName: argv.actorName,
947
- targets: argv.targets,
948
- context: argv.context,
949
- metadata: argv.metadata,
950
- occurredAt: argv.occurredAt,
951
- file: argv.file,
952
- }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
953
- });
954
- registerSubcommand(yargs, 'export', 'Export audit logs', (y) => y.options({
955
- org: { type: 'string', demandOption: true },
956
- 'range-start': { type: 'string', demandOption: true },
957
- 'range-end': { type: 'string', demandOption: true },
958
- actions: { type: 'string' },
959
- 'actor-names': { type: 'string' },
960
- 'actor-ids': { type: 'string' },
961
- targets: { type: 'string' },
962
- }), async (argv) => {
963
- await applyInsecureStorage(argv.insecureStorage);
964
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
965
- const { runAuditLogExport } = await import('./commands/audit-log.js');
966
- await runAuditLogExport({
967
- organizationId: argv.org,
968
- rangeStart: argv.rangeStart,
969
- rangeEnd: argv.rangeEnd,
970
- actions: argv.actions?.split(','),
971
- actorNames: argv.actorNames?.split(','),
972
- actorIds: argv.actorIds?.split(','),
973
- targets: argv.targets?.split(','),
974
- }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
975
- });
976
- registerSubcommand(yargs, 'list-actions', 'List available audit log actions', (y) => y, async (argv) => {
977
- await applyInsecureStorage(argv.insecureStorage);
978
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
979
- const { runAuditLogListActions } = await import('./commands/audit-log.js');
980
- await runAuditLogListActions(resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
981
- });
982
- registerSubcommand(yargs, 'get-schema <action>', 'Get schema for an audit log action', (y) => y.positional('action', { type: 'string', demandOption: true }), async (argv) => {
983
- await applyInsecureStorage(argv.insecureStorage);
984
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
985
- const { runAuditLogGetSchema } = await import('./commands/audit-log.js');
986
- await runAuditLogGetSchema(argv.action, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
987
- });
988
- registerSubcommand(yargs, 'create-schema <action>', 'Create an audit log schema', (y) => y
989
- .positional('action', { type: 'string', demandOption: true })
990
- .option('file', { type: 'string', demandOption: true }), async (argv) => {
991
- await applyInsecureStorage(argv.insecureStorage);
992
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
993
- const { runAuditLogCreateSchema } = await import('./commands/audit-log.js');
994
- await runAuditLogCreateSchema(argv.action, argv.file, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
995
- });
996
- registerSubcommand(yargs, 'get-retention <orgId>', 'Get audit log retention period', (y) => y.positional('orgId', { type: 'string', demandOption: true }), async (argv) => {
997
- await applyInsecureStorage(argv.insecureStorage);
998
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
999
- const { runAuditLogGetRetention } = await import('./commands/audit-log.js');
1000
- await runAuditLogGetRetention(argv.orgId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1001
- });
1002
- return yargs.demandCommand(1, 'Please specify an audit-log subcommand').strict();
1003
- })
1004
- .command('feature-flag', 'Manage feature flags', (yargs) => {
1005
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1006
- registerSubcommand(yargs, 'list', 'List feature flags', (y) => y.options({
1007
- limit: { type: 'number' },
1008
- before: { type: 'string' },
1009
- after: { type: 'string' },
1010
- order: { type: 'string' },
1011
- }), async (argv) => {
1012
- await applyInsecureStorage(argv.insecureStorage);
1013
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1014
- const { runFeatureFlagList } = await import('./commands/feature-flag.js');
1015
- await runFeatureFlagList({ limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1016
- });
1017
- registerSubcommand(yargs, 'get <slug>', 'Get a feature flag', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
1018
- await applyInsecureStorage(argv.insecureStorage);
1019
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1020
- const { runFeatureFlagGet } = await import('./commands/feature-flag.js');
1021
- await runFeatureFlagGet(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1022
- });
1023
- registerSubcommand(yargs, 'enable <slug>', 'Enable a feature flag', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
1024
- await applyInsecureStorage(argv.insecureStorage);
1025
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1026
- const { runFeatureFlagEnable } = await import('./commands/feature-flag.js');
1027
- await runFeatureFlagEnable(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1028
- });
1029
- registerSubcommand(yargs, 'disable <slug>', 'Disable a feature flag', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
1030
- await applyInsecureStorage(argv.insecureStorage);
1031
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1032
- const { runFeatureFlagDisable } = await import('./commands/feature-flag.js');
1033
- await runFeatureFlagDisable(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1034
- });
1035
- registerSubcommand(yargs, 'add-target <slug> <targetId>', 'Add a target to a feature flag', (y) => y
1036
- .positional('slug', { type: 'string', demandOption: true })
1037
- .positional('targetId', { type: 'string', demandOption: true }), async (argv) => {
1038
- await applyInsecureStorage(argv.insecureStorage);
1039
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1040
- const { runFeatureFlagAddTarget } = await import('./commands/feature-flag.js');
1041
- await runFeatureFlagAddTarget(argv.slug, argv.targetId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1042
- });
1043
- registerSubcommand(yargs, 'remove-target <slug> <targetId>', 'Remove a target from a feature flag', (y) => y
1044
- .positional('slug', { type: 'string', demandOption: true })
1045
- .positional('targetId', { type: 'string', demandOption: true }), async (argv) => {
1046
- await applyInsecureStorage(argv.insecureStorage);
1047
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1048
- const { runFeatureFlagRemoveTarget } = await import('./commands/feature-flag.js');
1049
- await runFeatureFlagRemoveTarget(argv.slug, argv.targetId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1050
- });
1051
- return yargs.demandCommand(1, 'Please specify a feature-flag subcommand').strict();
1052
- })
1053
- .command('webhook', 'Manage webhooks', (yargs) => {
1054
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1055
- registerSubcommand(yargs, 'list', 'List webhooks', (y) => y, async (argv) => {
1056
- await applyInsecureStorage(argv.insecureStorage);
1057
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1058
- const { runWebhookList } = await import('./commands/webhook.js');
1059
- await runWebhookList(resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1060
- });
1061
- registerSubcommand(yargs, 'create', 'Create a webhook', (y) => y.options({
1062
- url: { type: 'string', demandOption: true },
1063
- events: { type: 'string', demandOption: true, describe: 'Comma-separated event types' },
1064
- }), async (argv) => {
1065
- await applyInsecureStorage(argv.insecureStorage);
1066
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1067
- const { runWebhookCreate } = await import('./commands/webhook.js');
1068
- await runWebhookCreate(argv.url, argv.events.split(','), resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1069
- });
1070
- registerSubcommand(yargs, 'delete <id>', 'Delete a webhook', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1071
- await applyInsecureStorage(argv.insecureStorage);
1072
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1073
- const { runWebhookDelete } = await import('./commands/webhook.js');
1074
- await runWebhookDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1075
- });
1076
- return yargs.demandCommand(1, 'Please specify a webhook subcommand').strict();
1077
- })
1078
- .command('config', 'Manage WorkOS configuration (redirect URIs, CORS, homepage)', (yargs) => {
1079
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1080
- yargs.command('redirect', 'Manage redirect URIs', (yargs) => {
1081
- registerSubcommand(yargs, 'add <uri>', 'Add a redirect URI', (y) => y.positional('uri', { type: 'string', demandOption: true }), async (argv) => {
1082
- await applyInsecureStorage(argv.insecureStorage);
1083
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1084
- const { runConfigRedirectAdd } = await import('./commands/config.js');
1085
- await runConfigRedirectAdd(argv.uri, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1086
- });
1087
- return yargs.demandCommand(1).strict();
1088
- });
1089
- yargs.command('cors', 'Manage CORS origins', (yargs) => {
1090
- registerSubcommand(yargs, 'add <origin>', 'Add a CORS origin', (y) => y.positional('origin', { type: 'string', demandOption: true }), async (argv) => {
1091
- await applyInsecureStorage(argv.insecureStorage);
1092
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1093
- const { runConfigCorsAdd } = await import('./commands/config.js');
1094
- await runConfigCorsAdd(argv.origin, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1095
- });
1096
- return yargs.demandCommand(1).strict();
1097
- });
1098
- yargs.command('homepage-url', 'Manage homepage URL', (yargs) => {
1099
- registerSubcommand(yargs, 'set <url>', 'Set the homepage URL', (y) => y.positional('url', { type: 'string', demandOption: true }), async (argv) => {
1100
- await applyInsecureStorage(argv.insecureStorage);
1101
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1102
- const { runConfigHomepageUrlSet } = await import('./commands/config.js');
1103
- await runConfigHomepageUrlSet(argv.url, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1104
- });
1105
- return yargs.demandCommand(1).strict();
1106
- });
1107
- return yargs.demandCommand(1, 'Please specify a config subcommand').strict();
1108
- })
1109
- .command('portal', 'Manage Admin Portal', (yargs) => {
1110
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1111
- registerSubcommand(yargs, 'generate-link', 'Generate an Admin Portal link', (y) => y.options({
1112
- intent: {
540
+ array: true,
541
+ describe: 'Domains in format domain:state (state defaults to verified)',
542
+ }), async (argv) => {
543
+ await applyInsecureStorage(argv.insecureStorage);
544
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
545
+ const { runOrgCreate } = await import('./commands/organization.js');
546
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey });
547
+ await runOrgCreate(argv.name, argv.domains || [], apiKey, resolveApiBaseUrl());
548
+ });
549
+ registerSubcommand(yargs, 'update <orgId> <name> [domain] [state]', 'Update an organization', (y) => y
550
+ .positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' })
551
+ .positional('name', { type: 'string', demandOption: true, describe: 'Organization name' })
552
+ .positional('domain', { type: 'string', describe: 'Domain' })
553
+ .positional('state', { type: 'string', describe: 'Domain state (verified or pending)' }), async (argv) => {
554
+ await applyInsecureStorage(argv.insecureStorage);
555
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
556
+ const { runOrgUpdate } = await import('./commands/organization.js');
557
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey });
558
+ await runOrgUpdate(argv.orgId, argv.name, apiKey, argv.domain, argv.state, resolveApiBaseUrl());
559
+ });
560
+ registerSubcommand(yargs, 'get <orgId>', 'Get an organization by ID', (y) => y.positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' }), async (argv) => {
561
+ await applyInsecureStorage(argv.insecureStorage);
562
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
563
+ const { runOrgGet } = await import('./commands/organization.js');
564
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey });
565
+ await runOrgGet(argv.orgId, apiKey, resolveApiBaseUrl());
566
+ });
567
+ registerSubcommand(yargs, 'list', 'List organizations', (y) => y.options({
568
+ domain: { type: 'string', describe: 'Filter by domain' },
569
+ limit: { type: 'number', describe: 'Limit number of results' },
570
+ before: { type: 'string', describe: 'Cursor for results before a specific item' },
571
+ after: { type: 'string', describe: 'Cursor for results after a specific item' },
572
+ order: { type: 'string', describe: 'Order of results (asc or desc)' },
573
+ }), async (argv) => {
574
+ await applyInsecureStorage(argv.insecureStorage);
575
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
576
+ const { runOrgList } = await import('./commands/organization.js');
577
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey });
578
+ await runOrgList({ domain: argv.domain, limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, apiKey, resolveApiBaseUrl());
579
+ });
580
+ registerSubcommand(yargs, 'delete <orgId>', 'Delete an organization', (y) => y.positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' }), async (argv) => {
581
+ await applyInsecureStorage(argv.insecureStorage);
582
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
583
+ const { runOrgDelete } = await import('./commands/organization.js');
584
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey });
585
+ await runOrgDelete(argv.orgId, apiKey, resolveApiBaseUrl());
586
+ });
587
+ return yargs.demandCommand(1, 'Please specify an organization subcommand').strict();
588
+ })
589
+ .command('user', 'Manage WorkOS users (get, list, update, delete)', (yargs) => {
590
+ yargs.options({
591
+ ...insecureStorageOption,
592
+ 'api-key': {
593
+ type: 'string',
594
+ describe: 'WorkOS API key (overrides environment config). Format: sk_live_* or sk_test_*',
595
+ },
596
+ });
597
+ registerSubcommand(yargs, 'get <userId>', 'Get a user by ID', (y) => y.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }), async (argv) => {
598
+ await applyInsecureStorage(argv.insecureStorage);
599
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
600
+ const { runUserGet } = await import('./commands/user.js');
601
+ await runUserGet(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
602
+ });
603
+ registerSubcommand(yargs, 'list', 'List users', (y) => y.options({
604
+ email: { type: 'string', describe: 'Filter by email' },
605
+ organization: { type: 'string', describe: 'Filter by organization ID' },
606
+ limit: { type: 'number', describe: 'Limit number of results' },
607
+ before: { type: 'string', describe: 'Cursor for results before a specific item' },
608
+ after: { type: 'string', describe: 'Cursor for results after a specific item' },
609
+ order: { type: 'string', describe: 'Order of results (asc or desc)' },
610
+ }), async (argv) => {
611
+ await applyInsecureStorage(argv.insecureStorage);
612
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
613
+ const { runUserList } = await import('./commands/user.js');
614
+ await runUserList({
615
+ email: argv.email,
616
+ organization: argv.organization,
617
+ limit: argv.limit,
618
+ before: argv.before,
619
+ after: argv.after,
620
+ order: argv.order,
621
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
622
+ });
623
+ registerSubcommand(yargs, 'update <userId>', 'Update a user', (y) => y.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }).options({
624
+ 'first-name': { type: 'string', describe: 'First name' },
625
+ 'last-name': { type: 'string', describe: 'Last name' },
626
+ 'email-verified': { type: 'boolean', describe: 'Email verification status' },
627
+ password: { type: 'string', describe: 'New password' },
628
+ 'external-id': { type: 'string', describe: 'External ID' },
629
+ }), async (argv) => {
630
+ await applyInsecureStorage(argv.insecureStorage);
631
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
632
+ const { runUserUpdate } = await import('./commands/user.js');
633
+ await runUserUpdate(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), {
634
+ firstName: argv.firstName,
635
+ lastName: argv.lastName,
636
+ emailVerified: argv.emailVerified,
637
+ password: argv.password,
638
+ externalId: argv.externalId,
639
+ }, resolveApiBaseUrl());
640
+ });
641
+ registerSubcommand(yargs, 'delete <userId>', 'Delete a user', (y) => y.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }), async (argv) => {
642
+ await applyInsecureStorage(argv.insecureStorage);
643
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
644
+ const { runUserDelete } = await import('./commands/user.js');
645
+ await runUserDelete(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
646
+ });
647
+ return yargs.demandCommand(1, 'Please specify a user subcommand').strict();
648
+ })
649
+ // --- Resource Management Commands ---
650
+ .command('role', 'Manage WorkOS roles (environment and organization-scoped)', (yargs) => {
651
+ yargs.options({
652
+ ...insecureStorageOption,
653
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
654
+ org: { type: 'string', describe: 'Organization ID (for org-scoped roles)' },
655
+ });
656
+ registerSubcommand(yargs, 'list', 'List roles', (y) => y, async (argv) => {
657
+ await applyInsecureStorage(argv.insecureStorage);
658
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
659
+ const { runRoleList } = await import('./commands/role.js');
660
+ await runRoleList(argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
661
+ });
662
+ registerSubcommand(yargs, 'get <slug>', 'Get a role by slug', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
663
+ await applyInsecureStorage(argv.insecureStorage);
664
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
665
+ const { runRoleGet } = await import('./commands/role.js');
666
+ await runRoleGet(argv.slug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
667
+ });
668
+ registerSubcommand(yargs, 'create', 'Create a role', (y) => y.options({
669
+ slug: { type: 'string', demandOption: true, describe: 'Role slug' },
670
+ name: { type: 'string', demandOption: true, describe: 'Role name' },
671
+ description: { type: 'string', describe: 'Role description' },
672
+ }), async (argv) => {
673
+ await applyInsecureStorage(argv.insecureStorage);
674
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
675
+ const { runRoleCreate } = await import('./commands/role.js');
676
+ await runRoleCreate({ slug: argv.slug, name: argv.name, description: argv.description }, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
677
+ });
678
+ registerSubcommand(yargs, 'update <slug>', 'Update a role', (y) => y
679
+ .positional('slug', { type: 'string', demandOption: true })
680
+ .options({ name: { type: 'string' }, description: { type: 'string' } }), async (argv) => {
681
+ await applyInsecureStorage(argv.insecureStorage);
682
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
683
+ const { runRoleUpdate } = await import('./commands/role.js');
684
+ await runRoleUpdate(argv.slug, { name: argv.name, description: argv.description }, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
685
+ });
686
+ registerSubcommand(yargs, 'delete <slug>', 'Delete an org-scoped role (requires --org)', (y) => y.positional('slug', { type: 'string', demandOption: true }).demandOption('org'), async (argv) => {
687
+ await applyInsecureStorage(argv.insecureStorage);
688
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
689
+ const { runRoleDelete } = await import('./commands/role.js');
690
+ await runRoleDelete(argv.slug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
691
+ });
692
+ registerSubcommand(yargs, 'set-permissions <slug>', 'Set all permissions on a role (replaces existing)', (y) => y.positional('slug', { type: 'string', demandOption: true }).option('permissions', {
1113
693
  type: 'string',
1114
694
  demandOption: true,
1115
- describe: 'Portal intent (sso, dsync, audit_logs, log_streams)',
1116
- },
1117
- org: { type: 'string', demandOption: true, describe: 'Organization ID' },
1118
- 'return-url': { type: 'string' },
1119
- 'success-url': { type: 'string' },
695
+ describe: 'Comma-separated permission slugs',
696
+ }), async (argv) => {
697
+ await applyInsecureStorage(argv.insecureStorage);
698
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
699
+ const { runRoleSetPermissions } = await import('./commands/role.js');
700
+ await runRoleSetPermissions(argv.slug, argv.permissions.split(','), argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
701
+ });
702
+ registerSubcommand(yargs, 'add-permission <slug> <permissionSlug>', 'Add a permission to a role', (y) => y
703
+ .positional('slug', { type: 'string', demandOption: true })
704
+ .positional('permissionSlug', { type: 'string', demandOption: true }), async (argv) => {
705
+ await applyInsecureStorage(argv.insecureStorage);
706
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
707
+ const { runRoleAddPermission } = await import('./commands/role.js');
708
+ await runRoleAddPermission(argv.slug, argv.permissionSlug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
709
+ });
710
+ registerSubcommand(yargs, 'remove-permission <slug> <permissionSlug>', 'Remove a permission from an org role (requires --org)', (y) => y
711
+ .positional('slug', { type: 'string', demandOption: true })
712
+ .positional('permissionSlug', { type: 'string', demandOption: true })
713
+ .demandOption('org'), async (argv) => {
714
+ await applyInsecureStorage(argv.insecureStorage);
715
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
716
+ const { runRoleRemovePermission } = await import('./commands/role.js');
717
+ await runRoleRemovePermission(argv.slug, argv.permissionSlug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
718
+ });
719
+ return yargs.demandCommand(1, 'Please specify a role subcommand').strict();
720
+ })
721
+ .command('permission', 'Manage WorkOS permissions', (yargs) => {
722
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
723
+ registerSubcommand(yargs, 'list', 'List permissions', (y) => y.options({
724
+ limit: { type: 'number' },
725
+ before: { type: 'string' },
726
+ after: { type: 'string' },
727
+ order: { type: 'string' },
728
+ }), async (argv) => {
729
+ await applyInsecureStorage(argv.insecureStorage);
730
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
731
+ const { runPermissionList } = await import('./commands/permission.js');
732
+ await runPermissionList({ limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
733
+ });
734
+ registerSubcommand(yargs, 'get <slug>', 'Get a permission', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
735
+ await applyInsecureStorage(argv.insecureStorage);
736
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
737
+ const { runPermissionGet } = await import('./commands/permission.js');
738
+ await runPermissionGet(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
739
+ });
740
+ registerSubcommand(yargs, 'create', 'Create a permission', (y) => y.options({
741
+ slug: { type: 'string', demandOption: true },
742
+ name: { type: 'string', demandOption: true },
743
+ description: { type: 'string' },
744
+ }), async (argv) => {
745
+ await applyInsecureStorage(argv.insecureStorage);
746
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
747
+ const { runPermissionCreate } = await import('./commands/permission.js');
748
+ await runPermissionCreate({ slug: argv.slug, name: argv.name, description: argv.description }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
749
+ });
750
+ registerSubcommand(yargs, 'update <slug>', 'Update a permission', (y) => y
751
+ .positional('slug', { type: 'string', demandOption: true })
752
+ .options({ name: { type: 'string' }, description: { type: 'string' } }), async (argv) => {
753
+ await applyInsecureStorage(argv.insecureStorage);
754
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
755
+ const { runPermissionUpdate } = await import('./commands/permission.js');
756
+ await runPermissionUpdate(argv.slug, { name: argv.name, description: argv.description }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
757
+ });
758
+ registerSubcommand(yargs, 'delete <slug>', 'Delete a permission', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
759
+ await applyInsecureStorage(argv.insecureStorage);
760
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
761
+ const { runPermissionDelete } = await import('./commands/permission.js');
762
+ await runPermissionDelete(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
763
+ });
764
+ return yargs.demandCommand(1, 'Please specify a permission subcommand').strict();
765
+ })
766
+ .command('membership', 'Manage organization memberships', (yargs) => {
767
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
768
+ registerSubcommand(yargs, 'list', 'List memberships', (y) => y.options({
769
+ org: { type: 'string' },
770
+ user: { type: 'string' },
771
+ limit: { type: 'number' },
772
+ before: { type: 'string' },
773
+ after: { type: 'string' },
774
+ order: { type: 'string' },
775
+ }), async (argv) => {
776
+ await applyInsecureStorage(argv.insecureStorage);
777
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
778
+ const { runMembershipList } = await import('./commands/membership.js');
779
+ await runMembershipList({
780
+ org: argv.org,
781
+ user: argv.user,
782
+ limit: argv.limit,
783
+ before: argv.before,
784
+ after: argv.after,
785
+ order: argv.order,
786
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
787
+ });
788
+ registerSubcommand(yargs, 'get <id>', 'Get a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
789
+ await applyInsecureStorage(argv.insecureStorage);
790
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
791
+ const { runMembershipGet } = await import('./commands/membership.js');
792
+ await runMembershipGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
793
+ });
794
+ registerSubcommand(yargs, 'create', 'Create a membership', (y) => y.options({
795
+ org: { type: 'string', demandOption: true },
796
+ user: { type: 'string', demandOption: true },
797
+ role: { type: 'string' },
798
+ }), async (argv) => {
799
+ await applyInsecureStorage(argv.insecureStorage);
800
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
801
+ const { runMembershipCreate } = await import('./commands/membership.js');
802
+ await runMembershipCreate({ org: argv.org, user: argv.user, role: argv.role }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
803
+ });
804
+ registerSubcommand(yargs, 'update <id>', 'Update a membership', (y) => y.positional('id', { type: 'string', demandOption: true }).option('role', { type: 'string' }), async (argv) => {
805
+ await applyInsecureStorage(argv.insecureStorage);
806
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
807
+ const { runMembershipUpdate } = await import('./commands/membership.js');
808
+ await runMembershipUpdate(argv.id, argv.role, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
809
+ });
810
+ registerSubcommand(yargs, 'delete <id>', 'Delete a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
811
+ await applyInsecureStorage(argv.insecureStorage);
812
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
813
+ const { runMembershipDelete } = await import('./commands/membership.js');
814
+ await runMembershipDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
815
+ });
816
+ registerSubcommand(yargs, 'deactivate <id>', 'Deactivate a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
817
+ await applyInsecureStorage(argv.insecureStorage);
818
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
819
+ const { runMembershipDeactivate } = await import('./commands/membership.js');
820
+ await runMembershipDeactivate(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
821
+ });
822
+ registerSubcommand(yargs, 'reactivate <id>', 'Reactivate a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
823
+ await applyInsecureStorage(argv.insecureStorage);
824
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
825
+ const { runMembershipReactivate } = await import('./commands/membership.js');
826
+ await runMembershipReactivate(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
827
+ });
828
+ return yargs.demandCommand(1, 'Please specify a membership subcommand').strict();
829
+ })
830
+ .command('invitation', 'Manage user invitations', (yargs) => {
831
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
832
+ registerSubcommand(yargs, 'list', 'List invitations', (y) => y.options({
833
+ org: { type: 'string' },
834
+ email: { type: 'string' },
835
+ limit: { type: 'number' },
836
+ before: { type: 'string' },
837
+ after: { type: 'string' },
838
+ order: { type: 'string' },
839
+ }), async (argv) => {
840
+ await applyInsecureStorage(argv.insecureStorage);
841
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
842
+ const { runInvitationList } = await import('./commands/invitation.js');
843
+ await runInvitationList({
844
+ org: argv.org,
845
+ email: argv.email,
846
+ limit: argv.limit,
847
+ before: argv.before,
848
+ after: argv.after,
849
+ order: argv.order,
850
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
851
+ });
852
+ registerSubcommand(yargs, 'get <id>', 'Get an invitation', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
853
+ await applyInsecureStorage(argv.insecureStorage);
854
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
855
+ const { runInvitationGet } = await import('./commands/invitation.js');
856
+ await runInvitationGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
857
+ });
858
+ registerSubcommand(yargs, 'send', 'Send an invitation', (y) => y.options({
859
+ email: { type: 'string', demandOption: true },
860
+ org: { type: 'string' },
861
+ role: { type: 'string' },
862
+ 'expires-in-days': { type: 'number' },
863
+ }), async (argv) => {
864
+ await applyInsecureStorage(argv.insecureStorage);
865
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
866
+ const { runInvitationSend } = await import('./commands/invitation.js');
867
+ await runInvitationSend({ email: argv.email, org: argv.org, role: argv.role, expiresInDays: argv.expiresInDays }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
868
+ });
869
+ registerSubcommand(yargs, 'revoke <id>', 'Revoke an invitation', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
870
+ await applyInsecureStorage(argv.insecureStorage);
871
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
872
+ const { runInvitationRevoke } = await import('./commands/invitation.js');
873
+ await runInvitationRevoke(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
874
+ });
875
+ registerSubcommand(yargs, 'resend <id>', 'Resend an invitation', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
876
+ await applyInsecureStorage(argv.insecureStorage);
877
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
878
+ const { runInvitationResend } = await import('./commands/invitation.js');
879
+ await runInvitationResend(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
880
+ });
881
+ return yargs.demandCommand(1, 'Please specify an invitation subcommand').strict();
882
+ })
883
+ .command('session', 'Manage user sessions', (yargs) => {
884
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
885
+ registerSubcommand(yargs, 'list <userId>', 'List sessions for a user', (y) => y.positional('userId', { type: 'string', demandOption: true }).options({
886
+ limit: { type: 'number' },
887
+ before: { type: 'string' },
888
+ after: { type: 'string' },
889
+ order: { type: 'string' },
890
+ }), async (argv) => {
891
+ await applyInsecureStorage(argv.insecureStorage);
892
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
893
+ const { runSessionList } = await import('./commands/session.js');
894
+ await runSessionList(argv.userId, { limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
895
+ });
896
+ registerSubcommand(yargs, 'revoke <sessionId>', 'Revoke a session', (y) => y.positional('sessionId', { type: 'string', demandOption: true }), async (argv) => {
897
+ await applyInsecureStorage(argv.insecureStorage);
898
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
899
+ const { runSessionRevoke } = await import('./commands/session.js');
900
+ await runSessionRevoke(argv.sessionId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
901
+ });
902
+ return yargs.demandCommand(1, 'Please specify a session subcommand').strict();
903
+ })
904
+ .command('connection', 'Manage SSO connections (read/delete)', (yargs) => {
905
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
906
+ registerSubcommand(yargs, 'list', 'List connections', (y) => y.options({
907
+ org: { type: 'string', describe: 'Filter by org ID' },
908
+ type: { type: 'string', describe: 'Filter by connection type' },
909
+ limit: { type: 'number' },
910
+ before: { type: 'string' },
911
+ after: { type: 'string' },
912
+ order: { type: 'string' },
913
+ }), async (argv) => {
914
+ await applyInsecureStorage(argv.insecureStorage);
915
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
916
+ const { runConnectionList } = await import('./commands/connection.js');
917
+ await runConnectionList({
918
+ organizationId: argv.org,
919
+ connectionType: argv.type,
920
+ limit: argv.limit,
921
+ before: argv.before,
922
+ after: argv.after,
923
+ order: argv.order,
924
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
925
+ });
926
+ registerSubcommand(yargs, 'get <id>', 'Get a connection', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
927
+ await applyInsecureStorage(argv.insecureStorage);
928
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
929
+ const { runConnectionGet } = await import('./commands/connection.js');
930
+ await runConnectionGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
931
+ });
932
+ registerSubcommand(yargs, 'delete <id>', 'Delete a connection', (y) => y
933
+ .positional('id', { type: 'string', demandOption: true })
934
+ .option('force', { type: 'boolean', default: false }), async (argv) => {
935
+ await applyInsecureStorage(argv.insecureStorage);
936
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
937
+ const { runConnectionDelete } = await import('./commands/connection.js');
938
+ await runConnectionDelete(argv.id, { force: argv.force }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
939
+ });
940
+ return yargs.demandCommand(1, 'Please specify a connection subcommand').strict();
941
+ })
942
+ .command('directory', 'Manage directory sync (read/delete, list users/groups)', (yargs) => {
943
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
944
+ registerSubcommand(yargs, 'list', 'List directories', (y) => y.options({
945
+ org: { type: 'string' },
946
+ limit: { type: 'number' },
947
+ before: { type: 'string' },
948
+ after: { type: 'string' },
949
+ order: { type: 'string' },
950
+ }), async (argv) => {
951
+ await applyInsecureStorage(argv.insecureStorage);
952
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
953
+ const { runDirectoryList } = await import('./commands/directory.js');
954
+ await runDirectoryList({ organizationId: argv.org, limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
955
+ });
956
+ registerSubcommand(yargs, 'get <id>', 'Get a directory', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
957
+ await applyInsecureStorage(argv.insecureStorage);
958
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
959
+ const { runDirectoryGet } = await import('./commands/directory.js');
960
+ await runDirectoryGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
961
+ });
962
+ registerSubcommand(yargs, 'delete <id>', 'Delete a directory', (y) => y
963
+ .positional('id', { type: 'string', demandOption: true })
964
+ .option('force', { type: 'boolean', default: false }), async (argv) => {
965
+ await applyInsecureStorage(argv.insecureStorage);
966
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
967
+ const { runDirectoryDelete } = await import('./commands/directory.js');
968
+ await runDirectoryDelete(argv.id, { force: argv.force }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
969
+ });
970
+ registerSubcommand(yargs, 'list-users', 'List directory users', (y) => y.options({
971
+ directory: { type: 'string' },
972
+ group: { type: 'string' },
973
+ limit: { type: 'number' },
974
+ before: { type: 'string' },
975
+ after: { type: 'string' },
976
+ }), async (argv) => {
977
+ await applyInsecureStorage(argv.insecureStorage);
978
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
979
+ const { runDirectoryListUsers } = await import('./commands/directory.js');
980
+ await runDirectoryListUsers({ directory: argv.directory, group: argv.group, limit: argv.limit, before: argv.before, after: argv.after }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
981
+ });
982
+ registerSubcommand(yargs, 'list-groups', 'List directory groups', (y) => y.options({
983
+ directory: { type: 'string', demandOption: true },
984
+ limit: { type: 'number' },
985
+ before: { type: 'string' },
986
+ after: { type: 'string' },
987
+ }), async (argv) => {
988
+ await applyInsecureStorage(argv.insecureStorage);
989
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
990
+ const { runDirectoryListGroups } = await import('./commands/directory.js');
991
+ await runDirectoryListGroups({ directory: argv.directory, limit: argv.limit, before: argv.before, after: argv.after }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
992
+ });
993
+ return yargs.demandCommand(1, 'Please specify a directory subcommand').strict();
994
+ })
995
+ .command('event', 'Query WorkOS events', (yargs) => {
996
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
997
+ registerSubcommand(yargs, 'list', 'List events', (y) => y.options({
998
+ events: { type: 'string', demandOption: true, describe: 'Comma-separated event types' },
999
+ after: { type: 'string' },
1000
+ org: { type: 'string' },
1001
+ 'range-start': { type: 'string' },
1002
+ 'range-end': { type: 'string' },
1003
+ limit: { type: 'number' },
1004
+ }), async (argv) => {
1005
+ await applyInsecureStorage(argv.insecureStorage);
1006
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1007
+ const { runEventList } = await import('./commands/event.js');
1008
+ await runEventList({
1009
+ events: argv.events.split(','),
1010
+ after: argv.after,
1011
+ organizationId: argv.org,
1012
+ rangeStart: argv.rangeStart,
1013
+ rangeEnd: argv.rangeEnd,
1014
+ limit: argv.limit,
1015
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1016
+ });
1017
+ return yargs.demandCommand(1, 'Please specify an event subcommand').strict();
1018
+ })
1019
+ .command('audit-log', 'Manage audit logs', (yargs) => {
1020
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1021
+ registerSubcommand(yargs, 'create-event <orgId>', 'Create an audit log event', (y) => y.positional('orgId', { type: 'string', demandOption: true }).options({
1022
+ action: { type: 'string' },
1023
+ 'actor-type': { type: 'string' },
1024
+ 'actor-id': { type: 'string' },
1025
+ 'actor-name': { type: 'string' },
1026
+ targets: { type: 'string' },
1027
+ context: { type: 'string' },
1028
+ metadata: { type: 'string' },
1029
+ 'occurred-at': { type: 'string' },
1030
+ file: { type: 'string' },
1031
+ }), async (argv) => {
1032
+ await applyInsecureStorage(argv.insecureStorage);
1033
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1034
+ const { runAuditLogCreateEvent } = await import('./commands/audit-log.js');
1035
+ await runAuditLogCreateEvent(argv.orgId, {
1036
+ action: argv.action,
1037
+ actorType: argv.actorType,
1038
+ actorId: argv.actorId,
1039
+ actorName: argv.actorName,
1040
+ targets: argv.targets,
1041
+ context: argv.context,
1042
+ metadata: argv.metadata,
1043
+ occurredAt: argv.occurredAt,
1044
+ file: argv.file,
1045
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1046
+ });
1047
+ registerSubcommand(yargs, 'export', 'Export audit logs', (y) => y.options({
1048
+ org: { type: 'string', demandOption: true },
1049
+ 'range-start': { type: 'string', demandOption: true },
1050
+ 'range-end': { type: 'string', demandOption: true },
1051
+ actions: { type: 'string' },
1052
+ 'actor-names': { type: 'string' },
1053
+ 'actor-ids': { type: 'string' },
1054
+ targets: { type: 'string' },
1055
+ }), async (argv) => {
1056
+ await applyInsecureStorage(argv.insecureStorage);
1057
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1058
+ const { runAuditLogExport } = await import('./commands/audit-log.js');
1059
+ await runAuditLogExport({
1060
+ organizationId: argv.org,
1061
+ rangeStart: argv.rangeStart,
1062
+ rangeEnd: argv.rangeEnd,
1063
+ actions: argv.actions?.split(','),
1064
+ actorNames: argv.actorNames?.split(','),
1065
+ actorIds: argv.actorIds?.split(','),
1066
+ targets: argv.targets?.split(','),
1067
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1068
+ });
1069
+ registerSubcommand(yargs, 'list-actions', 'List available audit log actions', (y) => y, async (argv) => {
1070
+ await applyInsecureStorage(argv.insecureStorage);
1071
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1072
+ const { runAuditLogListActions } = await import('./commands/audit-log.js');
1073
+ await runAuditLogListActions(resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1074
+ });
1075
+ registerSubcommand(yargs, 'get-schema <action>', 'Get schema for an audit log action', (y) => y.positional('action', { type: 'string', demandOption: true }), async (argv) => {
1076
+ await applyInsecureStorage(argv.insecureStorage);
1077
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1078
+ const { runAuditLogGetSchema } = await import('./commands/audit-log.js');
1079
+ await runAuditLogGetSchema(argv.action, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1080
+ });
1081
+ registerSubcommand(yargs, 'create-schema <action>', 'Create an audit log schema', (y) => y
1082
+ .positional('action', { type: 'string', demandOption: true })
1083
+ .option('file', { type: 'string', demandOption: true }), async (argv) => {
1084
+ await applyInsecureStorage(argv.insecureStorage);
1085
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1086
+ const { runAuditLogCreateSchema } = await import('./commands/audit-log.js');
1087
+ await runAuditLogCreateSchema(argv.action, argv.file, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1088
+ });
1089
+ registerSubcommand(yargs, 'get-retention <orgId>', 'Get audit log retention period', (y) => y.positional('orgId', { type: 'string', demandOption: true }), async (argv) => {
1090
+ await applyInsecureStorage(argv.insecureStorage);
1091
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1092
+ const { runAuditLogGetRetention } = await import('./commands/audit-log.js');
1093
+ await runAuditLogGetRetention(argv.orgId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1094
+ });
1095
+ return yargs.demandCommand(1, 'Please specify an audit-log subcommand').strict();
1096
+ })
1097
+ .command('feature-flag', 'Manage feature flags', (yargs) => {
1098
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1099
+ registerSubcommand(yargs, 'list', 'List feature flags', (y) => y.options({
1100
+ limit: { type: 'number' },
1101
+ before: { type: 'string' },
1102
+ after: { type: 'string' },
1103
+ order: { type: 'string' },
1104
+ }), async (argv) => {
1105
+ await applyInsecureStorage(argv.insecureStorage);
1106
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1107
+ const { runFeatureFlagList } = await import('./commands/feature-flag.js');
1108
+ await runFeatureFlagList({ limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1109
+ });
1110
+ registerSubcommand(yargs, 'get <slug>', 'Get a feature flag', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
1111
+ await applyInsecureStorage(argv.insecureStorage);
1112
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1113
+ const { runFeatureFlagGet } = await import('./commands/feature-flag.js');
1114
+ await runFeatureFlagGet(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1115
+ });
1116
+ registerSubcommand(yargs, 'enable <slug>', 'Enable a feature flag', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
1117
+ await applyInsecureStorage(argv.insecureStorage);
1118
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1119
+ const { runFeatureFlagEnable } = await import('./commands/feature-flag.js');
1120
+ await runFeatureFlagEnable(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1121
+ });
1122
+ registerSubcommand(yargs, 'disable <slug>', 'Disable a feature flag', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
1123
+ await applyInsecureStorage(argv.insecureStorage);
1124
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1125
+ const { runFeatureFlagDisable } = await import('./commands/feature-flag.js');
1126
+ await runFeatureFlagDisable(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1127
+ });
1128
+ registerSubcommand(yargs, 'add-target <slug> <targetId>', 'Add a target to a feature flag', (y) => y
1129
+ .positional('slug', { type: 'string', demandOption: true })
1130
+ .positional('targetId', { type: 'string', demandOption: true }), async (argv) => {
1131
+ await applyInsecureStorage(argv.insecureStorage);
1132
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1133
+ const { runFeatureFlagAddTarget } = await import('./commands/feature-flag.js');
1134
+ await runFeatureFlagAddTarget(argv.slug, argv.targetId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1135
+ });
1136
+ registerSubcommand(yargs, 'remove-target <slug> <targetId>', 'Remove a target from a feature flag', (y) => y
1137
+ .positional('slug', { type: 'string', demandOption: true })
1138
+ .positional('targetId', { type: 'string', demandOption: true }), async (argv) => {
1139
+ await applyInsecureStorage(argv.insecureStorage);
1140
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1141
+ const { runFeatureFlagRemoveTarget } = await import('./commands/feature-flag.js');
1142
+ await runFeatureFlagRemoveTarget(argv.slug, argv.targetId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1143
+ });
1144
+ return yargs.demandCommand(1, 'Please specify a feature-flag subcommand').strict();
1145
+ })
1146
+ .command('webhook', 'Manage webhooks', (yargs) => {
1147
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1148
+ registerSubcommand(yargs, 'list', 'List webhooks', (y) => y, async (argv) => {
1149
+ await applyInsecureStorage(argv.insecureStorage);
1150
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1151
+ const { runWebhookList } = await import('./commands/webhook.js');
1152
+ await runWebhookList(resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1153
+ });
1154
+ registerSubcommand(yargs, 'create', 'Create a webhook', (y) => y.options({
1155
+ url: { type: 'string', demandOption: true },
1156
+ events: { type: 'string', demandOption: true, describe: 'Comma-separated event types' },
1157
+ }), async (argv) => {
1158
+ await applyInsecureStorage(argv.insecureStorage);
1159
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1160
+ const { runWebhookCreate } = await import('./commands/webhook.js');
1161
+ await runWebhookCreate(argv.url, argv.events.split(','), resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1162
+ });
1163
+ registerSubcommand(yargs, 'delete <id>', 'Delete a webhook', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1164
+ await applyInsecureStorage(argv.insecureStorage);
1165
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1166
+ const { runWebhookDelete } = await import('./commands/webhook.js');
1167
+ await runWebhookDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1168
+ });
1169
+ return yargs.demandCommand(1, 'Please specify a webhook subcommand').strict();
1170
+ })
1171
+ .command('config', 'Manage WorkOS configuration (redirect URIs, CORS, homepage)', (yargs) => {
1172
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1173
+ yargs.command('redirect', 'Manage redirect URIs', (yargs) => {
1174
+ registerSubcommand(yargs, 'add <uri>', 'Add a redirect URI', (y) => y.positional('uri', { type: 'string', demandOption: true }), async (argv) => {
1175
+ await applyInsecureStorage(argv.insecureStorage);
1176
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1177
+ const { runConfigRedirectAdd } = await import('./commands/config.js');
1178
+ await runConfigRedirectAdd(argv.uri, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1179
+ });
1180
+ return yargs.demandCommand(1).strict();
1181
+ });
1182
+ yargs.command('cors', 'Manage CORS origins', (yargs) => {
1183
+ registerSubcommand(yargs, 'add <origin>', 'Add a CORS origin', (y) => y.positional('origin', { type: 'string', demandOption: true }), async (argv) => {
1184
+ await applyInsecureStorage(argv.insecureStorage);
1185
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1186
+ const { runConfigCorsAdd } = await import('./commands/config.js');
1187
+ await runConfigCorsAdd(argv.origin, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1188
+ });
1189
+ return yargs.demandCommand(1).strict();
1190
+ });
1191
+ yargs.command('homepage-url', 'Manage homepage URL', (yargs) => {
1192
+ registerSubcommand(yargs, 'set <url>', 'Set the homepage URL', (y) => y.positional('url', { type: 'string', demandOption: true }), async (argv) => {
1193
+ await applyInsecureStorage(argv.insecureStorage);
1194
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1195
+ const { runConfigHomepageUrlSet } = await import('./commands/config.js');
1196
+ await runConfigHomepageUrlSet(argv.url, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1197
+ });
1198
+ return yargs.demandCommand(1).strict();
1199
+ });
1200
+ return yargs.demandCommand(1, 'Please specify a config subcommand').strict();
1201
+ })
1202
+ .command('portal', 'Manage Admin Portal', (yargs) => {
1203
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1204
+ registerSubcommand(yargs, 'generate-link', 'Generate an Admin Portal link', (y) => y.options({
1205
+ intent: {
1206
+ type: 'string',
1207
+ demandOption: true,
1208
+ describe: 'Portal intent (sso, dsync, audit_logs, log_streams)',
1209
+ },
1210
+ org: { type: 'string', demandOption: true, describe: 'Organization ID' },
1211
+ 'return-url': { type: 'string' },
1212
+ 'success-url': { type: 'string' },
1213
+ }), async (argv) => {
1214
+ await applyInsecureStorage(argv.insecureStorage);
1215
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1216
+ const { runPortalGenerateLink } = await import('./commands/portal.js');
1217
+ await runPortalGenerateLink({ intent: argv.intent, organization: argv.org, returnUrl: argv.returnUrl, successUrl: argv.successUrl }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1218
+ });
1219
+ return yargs.demandCommand(1, 'Please specify a portal subcommand').strict();
1220
+ })
1221
+ .command('vault', 'Manage WorkOS Vault secrets', (yargs) => {
1222
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1223
+ registerSubcommand(yargs, 'list', 'List vault objects', (y) => y.options({
1224
+ limit: { type: 'number' },
1225
+ before: { type: 'string' },
1226
+ after: { type: 'string' },
1227
+ order: { type: 'string' },
1228
+ }), async (argv) => {
1229
+ await applyInsecureStorage(argv.insecureStorage);
1230
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1231
+ const { runVaultList } = await import('./commands/vault.js');
1232
+ await runVaultList({ limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1233
+ });
1234
+ registerSubcommand(yargs, 'get <id>', 'Get a vault object (metadata only; use --decrypt to include value)', (y) => y
1235
+ .positional('id', { type: 'string', demandOption: true })
1236
+ .option('decrypt', { type: 'boolean', default: false, describe: 'Include the decrypted secret value' }), async (argv) => {
1237
+ await applyInsecureStorage(argv.insecureStorage);
1238
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1239
+ const { runVaultGet } = await import('./commands/vault.js');
1240
+ await runVaultGet(argv.id, argv.decrypt, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1241
+ });
1242
+ registerSubcommand(yargs, 'get-by-name <name>', 'Get a vault object by name (metadata only; use --decrypt to include value)', (y) => y
1243
+ .positional('name', { type: 'string', demandOption: true })
1244
+ .option('decrypt', { type: 'boolean', default: false, describe: 'Include the decrypted secret value' }), async (argv) => {
1245
+ await applyInsecureStorage(argv.insecureStorage);
1246
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1247
+ const { runVaultGetByName } = await import('./commands/vault.js');
1248
+ await runVaultGetByName(argv.name, argv.decrypt, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1249
+ });
1250
+ registerSubcommand(yargs, 'create', 'Create a vault object (reads value from stdin when --value is omitted or -)', (y) => y.options({
1251
+ name: { type: 'string', demandOption: true },
1252
+ value: { type: 'string', describe: 'Secret value (omit or use - to read from stdin)' },
1253
+ org: { type: 'string', demandOption: true, describe: 'Organization ID (required for key context)' },
1254
+ }), async (argv) => {
1255
+ await applyInsecureStorage(argv.insecureStorage);
1256
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1257
+ const { runVaultCreate, readValueFromStdin } = await import('./commands/vault.js');
1258
+ const value = argv.value === undefined || argv.value === '-' ? await readValueFromStdin() : argv.value;
1259
+ await runVaultCreate({ name: argv.name, value, org: argv.org }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1260
+ });
1261
+ registerSubcommand(yargs, 'update <id>', 'Update a vault object (reads value from stdin when --value is omitted or -)', (y) => y.positional('id', { type: 'string', demandOption: true }).options({
1262
+ value: { type: 'string', describe: 'New value (omit or use - to read from stdin)' },
1263
+ 'version-check': { type: 'string' },
1264
+ }), async (argv) => {
1265
+ await applyInsecureStorage(argv.insecureStorage);
1266
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1267
+ const { runVaultUpdate, readValueFromStdin } = await import('./commands/vault.js');
1268
+ const value = argv.value === undefined || argv.value === '-' ? await readValueFromStdin() : argv.value;
1269
+ await runVaultUpdate({ id: argv.id, value, versionCheck: argv.versionCheck }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1270
+ });
1271
+ registerSubcommand(yargs, 'delete <id>', 'Delete a vault object', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1272
+ await applyInsecureStorage(argv.insecureStorage);
1273
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1274
+ const { runVaultDelete } = await import('./commands/vault.js');
1275
+ await runVaultDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1276
+ });
1277
+ registerSubcommand(yargs, 'describe <id>', 'Describe a vault object', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1278
+ await applyInsecureStorage(argv.insecureStorage);
1279
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1280
+ const { runVaultDescribe } = await import('./commands/vault.js');
1281
+ await runVaultDescribe(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1282
+ });
1283
+ registerSubcommand(yargs, 'list-versions <id>', 'List vault object versions', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1284
+ await applyInsecureStorage(argv.insecureStorage);
1285
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1286
+ const { runVaultListVersions } = await import('./commands/vault.js');
1287
+ await runVaultListVersions(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1288
+ });
1289
+ registerSubcommand(yargs, 'run', 'Run a command with Vault secrets injected as environment variables', (y) => y.options({
1290
+ secret: {
1291
+ type: 'string',
1292
+ array: true,
1293
+ describe: 'Map a vault object to an env var: ENV_VAR=vault-name (repeatable)',
1294
+ demandOption: true,
1295
+ },
1296
+ env: { type: 'string', describe: 'Environment name to read API key from (defaults to active)' },
1297
+ 'dry-run': { type: 'boolean', default: false, describe: 'Print which secrets would be injected, no fetch' },
1298
+ }), async (argv) => {
1299
+ await applyInsecureStorage(argv.insecureStorage);
1300
+ const { runVaultRun } = await import('./commands/vault-run.js');
1301
+ const childCommand = argv['--'] ?? [];
1302
+ const exitCode = await runVaultRun({
1303
+ secrets: argv.secret,
1304
+ command: childCommand,
1305
+ env: argv.env,
1306
+ dryRun: argv.dryRun,
1307
+ }, argv.apiKey);
1308
+ if (typeof exitCode === 'number')
1309
+ process.exit(exitCode);
1310
+ });
1311
+ return yargs.demandCommand(1, 'Please specify a vault subcommand').strict();
1312
+ })
1313
+ .command('api-key', 'Manage API keys', (yargs) => {
1314
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1315
+ registerSubcommand(yargs, 'list', 'List API keys', (y) => y.options({
1316
+ org: { type: 'string', demandOption: true },
1317
+ limit: { type: 'number' },
1318
+ before: { type: 'string' },
1319
+ after: { type: 'string' },
1320
+ order: { type: 'string' },
1321
+ }), async (argv) => {
1322
+ await applyInsecureStorage(argv.insecureStorage);
1323
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1324
+ const { runApiKeyList } = await import('./commands/api-key-mgmt.js');
1325
+ await runApiKeyList({ organizationId: argv.org, limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1326
+ });
1327
+ registerSubcommand(yargs, 'create', 'Create an API key', (y) => y.options({
1328
+ org: { type: 'string', demandOption: true },
1329
+ name: { type: 'string', demandOption: true },
1330
+ permissions: { type: 'string', describe: 'Comma-separated permissions' },
1331
+ }), async (argv) => {
1332
+ await applyInsecureStorage(argv.insecureStorage);
1333
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1334
+ const { runApiKeyCreate } = await import('./commands/api-key-mgmt.js');
1335
+ await runApiKeyCreate({ organizationId: argv.org, name: argv.name, permissions: argv.permissions?.split(',') }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1336
+ });
1337
+ registerSubcommand(yargs, 'validate <value>', 'Validate an API key', (y) => y.positional('value', { type: 'string', demandOption: true }), async (argv) => {
1338
+ await applyInsecureStorage(argv.insecureStorage);
1339
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1340
+ const { runApiKeyValidate } = await import('./commands/api-key-mgmt.js');
1341
+ await runApiKeyValidate(argv.value, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1342
+ });
1343
+ registerSubcommand(yargs, 'delete <id>', 'Delete an API key', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1344
+ await applyInsecureStorage(argv.insecureStorage);
1345
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1346
+ const { runApiKeyDelete } = await import('./commands/api-key-mgmt.js');
1347
+ await runApiKeyDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1348
+ });
1349
+ return yargs.demandCommand(1, 'Please specify an api-key subcommand').strict();
1350
+ })
1351
+ .command('org-domain', 'Manage organization domains', (yargs) => {
1352
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1353
+ registerSubcommand(yargs, 'get <id>', 'Get a domain', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1354
+ await applyInsecureStorage(argv.insecureStorage);
1355
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1356
+ const { runOrgDomainGet } = await import('./commands/org-domain.js');
1357
+ await runOrgDomainGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1358
+ });
1359
+ registerSubcommand(yargs, 'create <domain>', 'Create a domain', (y) => y
1360
+ .positional('domain', { type: 'string', demandOption: true })
1361
+ .option('org', { type: 'string', demandOption: true }), async (argv) => {
1362
+ await applyInsecureStorage(argv.insecureStorage);
1363
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1364
+ const { runOrgDomainCreate } = await import('./commands/org-domain.js');
1365
+ await runOrgDomainCreate(argv.domain, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1366
+ });
1367
+ registerSubcommand(yargs, 'verify <id>', 'Verify a domain', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1368
+ await applyInsecureStorage(argv.insecureStorage);
1369
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1370
+ const { runOrgDomainVerify } = await import('./commands/org-domain.js');
1371
+ await runOrgDomainVerify(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1372
+ });
1373
+ registerSubcommand(yargs, 'delete <id>', 'Delete a domain', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1374
+ await applyInsecureStorage(argv.insecureStorage);
1375
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1376
+ const { runOrgDomainDelete } = await import('./commands/org-domain.js');
1377
+ await runOrgDomainDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1378
+ });
1379
+ return yargs.demandCommand(1, 'Please specify an org-domain subcommand').strict();
1380
+ })
1381
+ // --- Workflow Commands ---
1382
+ .command('seed', 'Seed WorkOS environment from a YAML config file', (yargs) => yargs.options({
1383
+ ...insecureStorageOption,
1384
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
1385
+ file: { type: 'string', describe: 'Path to seed YAML file' },
1386
+ clean: { type: 'boolean', default: false, describe: 'Tear down seeded resources' },
1387
+ init: { type: 'boolean', default: false, describe: 'Create an example workos-seed.yml file' },
1120
1388
  }), async (argv) => {
1121
1389
  await applyInsecureStorage(argv.insecureStorage);
1122
1390
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1123
- const { runPortalGenerateLink } = await import('./commands/portal.js');
1124
- await runPortalGenerateLink({ intent: argv.intent, organization: argv.org, returnUrl: argv.returnUrl, successUrl: argv.successUrl }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1125
- });
1126
- return yargs.demandCommand(1, 'Please specify a portal subcommand').strict();
1127
- })
1128
- .command('vault', 'Manage WorkOS Vault secrets', (yargs) => {
1129
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1130
- registerSubcommand(yargs, 'list', 'List vault objects', (y) => y.options({
1131
- limit: { type: 'number' },
1132
- before: { type: 'string' },
1133
- after: { type: 'string' },
1134
- order: { type: 'string' },
1391
+ const { runSeed } = await import('./commands/seed.js');
1392
+ await runSeed({ file: argv.file, clean: argv.clean, init: argv.init }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1393
+ })
1394
+ .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({
1395
+ ...insecureStorageOption,
1396
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
1397
+ domain: { type: 'string', describe: 'Domain to add and verify' },
1398
+ roles: { type: 'string', describe: 'Comma-separated role slugs to create' },
1135
1399
  }), async (argv) => {
1136
1400
  await applyInsecureStorage(argv.insecureStorage);
1137
1401
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1138
- const { runVaultList } = await import('./commands/vault.js');
1139
- await runVaultList({ limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1140
- });
1141
- registerSubcommand(yargs, 'get <id>', 'Get a vault object', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1142
- await applyInsecureStorage(argv.insecureStorage);
1143
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1144
- const { runVaultGet } = await import('./commands/vault.js');
1145
- await runVaultGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1146
- });
1147
- registerSubcommand(yargs, 'get-by-name <name>', 'Get a vault object by name', (y) => y.positional('name', { type: 'string', demandOption: true }), async (argv) => {
1148
- await applyInsecureStorage(argv.insecureStorage);
1149
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1150
- const { runVaultGetByName } = await import('./commands/vault.js');
1151
- await runVaultGetByName(argv.name, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1152
- });
1153
- registerSubcommand(yargs, 'create', 'Create a vault object', (y) => y.options({
1154
- name: { type: 'string', demandOption: true },
1155
- value: { type: 'string', demandOption: true },
1156
- org: { type: 'string' },
1402
+ const { runSetupOrg } = await import('./commands/setup-org.js');
1403
+ await runSetupOrg({ name: argv.name, domain: argv.domain, roles: argv.roles?.split(',') }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1404
+ })
1405
+ .command('onboard-user <email>', 'Onboard a user (send invitation, assign role)', (yargs) => yargs.positional('email', { type: 'string', demandOption: true }).options({
1406
+ ...insecureStorageOption,
1407
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
1408
+ org: { type: 'string', demandOption: true, describe: 'Organization ID' },
1409
+ role: { type: 'string', describe: 'Role slug to assign' },
1410
+ wait: { type: 'boolean', default: false, describe: 'Wait for invitation acceptance' },
1157
1411
  }), async (argv) => {
1158
1412
  await applyInsecureStorage(argv.insecureStorage);
1159
1413
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1160
- const { runVaultCreate } = await import('./commands/vault.js');
1161
- await runVaultCreate({ name: argv.name, value: argv.value, org: argv.org }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1162
- });
1163
- registerSubcommand(yargs, 'update <id>', 'Update a vault object', (y) => y
1164
- .positional('id', { type: 'string', demandOption: true })
1165
- .options({ value: { type: 'string', demandOption: true }, 'version-check': { type: 'string' } }), async (argv) => {
1166
- await applyInsecureStorage(argv.insecureStorage);
1167
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1168
- const { runVaultUpdate } = await import('./commands/vault.js');
1169
- await runVaultUpdate({ id: argv.id, value: argv.value, versionCheck: argv.versionCheck }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1170
- });
1171
- registerSubcommand(yargs, 'delete <id>', 'Delete a vault object', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1172
- await applyInsecureStorage(argv.insecureStorage);
1173
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1174
- const { runVaultDelete } = await import('./commands/vault.js');
1175
- await runVaultDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1176
- });
1177
- registerSubcommand(yargs, 'describe <id>', 'Describe a vault object', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1178
- await applyInsecureStorage(argv.insecureStorage);
1179
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1180
- const { runVaultDescribe } = await import('./commands/vault.js');
1181
- await runVaultDescribe(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1182
- });
1183
- registerSubcommand(yargs, 'list-versions <id>', 'List vault object versions', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1184
- await applyInsecureStorage(argv.insecureStorage);
1185
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1186
- const { runVaultListVersions } = await import('./commands/vault.js');
1187
- await runVaultListVersions(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1188
- });
1189
- return yargs.demandCommand(1, 'Please specify a vault subcommand').strict();
1190
- })
1191
- .command('api-key', 'Manage API keys', (yargs) => {
1192
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1193
- registerSubcommand(yargs, 'list', 'List API keys', (y) => y.options({
1194
- org: { type: 'string', demandOption: true },
1195
- limit: { type: 'number' },
1196
- before: { type: 'string' },
1197
- after: { type: 'string' },
1198
- order: { type: 'string' },
1414
+ const { runOnboardUser } = await import('./commands/onboard-user.js');
1415
+ await runOnboardUser({ email: argv.email, org: argv.org, role: argv.role, wait: argv.wait }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1416
+ })
1417
+ .command('debug-sso <connectionId>', 'Diagnose SSO connection issues', (yargs) => yargs.positional('connectionId', { type: 'string', demandOption: true }).options({
1418
+ ...insecureStorageOption,
1419
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
1199
1420
  }), async (argv) => {
1200
1421
  await applyInsecureStorage(argv.insecureStorage);
1201
1422
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1202
- const { runApiKeyList } = await import('./commands/api-key-mgmt.js');
1203
- await runApiKeyList({ organizationId: argv.org, limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1204
- });
1205
- registerSubcommand(yargs, 'create', 'Create an API key', (y) => y.options({
1206
- org: { type: 'string', demandOption: true },
1207
- name: { type: 'string', demandOption: true },
1208
- permissions: { type: 'string', describe: 'Comma-separated permissions' },
1423
+ const { runDebugSso } = await import('./commands/debug-sso.js');
1424
+ await runDebugSso(argv.connectionId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1425
+ })
1426
+ .command('debug-sync <directoryId>', 'Diagnose directory sync issues', (yargs) => yargs.positional('directoryId', { type: 'string', demandOption: true }).options({
1427
+ ...insecureStorageOption,
1428
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
1209
1429
  }), async (argv) => {
1210
1430
  await applyInsecureStorage(argv.insecureStorage);
1211
1431
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1212
- const { runApiKeyCreate } = await import('./commands/api-key-mgmt.js');
1213
- await runApiKeyCreate({ organizationId: argv.org, name: argv.name, permissions: argv.permissions?.split(',') }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1214
- });
1215
- registerSubcommand(yargs, 'validate <value>', 'Validate an API key', (y) => y.positional('value', { type: 'string', demandOption: true }), async (argv) => {
1216
- await applyInsecureStorage(argv.insecureStorage);
1217
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1218
- const { runApiKeyValidate } = await import('./commands/api-key-mgmt.js');
1219
- await runApiKeyValidate(argv.value, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1220
- });
1221
- registerSubcommand(yargs, 'delete <id>', 'Delete an API key', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1222
- await applyInsecureStorage(argv.insecureStorage);
1223
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1224
- const { runApiKeyDelete } = await import('./commands/api-key-mgmt.js');
1225
- await runApiKeyDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1226
- });
1227
- return yargs.demandCommand(1, 'Please specify an api-key subcommand').strict();
1228
- })
1229
- .command('org-domain', 'Manage organization domains', (yargs) => {
1230
- yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1231
- registerSubcommand(yargs, 'get <id>', 'Get a domain', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1232
- await applyInsecureStorage(argv.insecureStorage);
1233
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1234
- const { runOrgDomainGet } = await import('./commands/org-domain.js');
1235
- await runOrgDomainGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1236
- });
1237
- registerSubcommand(yargs, 'create <domain>', 'Create a domain', (y) => y
1238
- .positional('domain', { type: 'string', demandOption: true })
1239
- .option('org', { type: 'string', demandOption: true }), async (argv) => {
1240
- await applyInsecureStorage(argv.insecureStorage);
1241
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1242
- const { runOrgDomainCreate } = await import('./commands/org-domain.js');
1243
- await runOrgDomainCreate(argv.domain, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1244
- });
1245
- registerSubcommand(yargs, 'verify <id>', 'Verify a domain', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1246
- await applyInsecureStorage(argv.insecureStorage);
1247
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1248
- const { runOrgDomainVerify } = await import('./commands/org-domain.js');
1249
- await runOrgDomainVerify(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1250
- });
1251
- registerSubcommand(yargs, 'delete <id>', 'Delete a domain', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1252
- await applyInsecureStorage(argv.insecureStorage);
1253
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1254
- const { runOrgDomainDelete } = await import('./commands/org-domain.js');
1255
- await runOrgDomainDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1256
- });
1257
- return yargs.demandCommand(1, 'Please specify an org-domain subcommand').strict();
1258
- })
1259
- // --- Workflow Commands ---
1260
- .command('seed', 'Seed WorkOS environment from a YAML config file', (yargs) => yargs.options({
1261
- ...insecureStorageOption,
1262
- 'api-key': { type: 'string', describe: 'WorkOS API key' },
1263
- file: { type: 'string', describe: 'Path to seed YAML file' },
1264
- clean: { type: 'boolean', default: false, describe: 'Tear down seeded resources' },
1265
- init: { type: 'boolean', default: false, describe: 'Create an example workos-seed.yml file' },
1266
- }), async (argv) => {
1267
- await applyInsecureStorage(argv.insecureStorage);
1268
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1269
- const { runSeed } = await import('./commands/seed.js');
1270
- await runSeed({ file: argv.file, clean: argv.clean, init: argv.init }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1271
- })
1272
- .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({
1273
- ...insecureStorageOption,
1274
- 'api-key': { type: 'string', describe: 'WorkOS API key' },
1275
- domain: { type: 'string', describe: 'Domain to add and verify' },
1276
- roles: { type: 'string', describe: 'Comma-separated role slugs to create' },
1277
- }), async (argv) => {
1278
- await applyInsecureStorage(argv.insecureStorage);
1279
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1280
- const { runSetupOrg } = await import('./commands/setup-org.js');
1281
- await runSetupOrg({ name: argv.name, domain: argv.domain, roles: argv.roles?.split(',') }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1282
- })
1283
- .command('onboard-user <email>', 'Onboard a user (send invitation, assign role)', (yargs) => yargs.positional('email', { type: 'string', demandOption: true }).options({
1284
- ...insecureStorageOption,
1285
- 'api-key': { type: 'string', describe: 'WorkOS API key' },
1286
- org: { type: 'string', demandOption: true, describe: 'Organization ID' },
1287
- role: { type: 'string', describe: 'Role slug to assign' },
1288
- wait: { type: 'boolean', default: false, describe: 'Wait for invitation acceptance' },
1289
- }), async (argv) => {
1290
- await applyInsecureStorage(argv.insecureStorage);
1291
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1292
- const { runOnboardUser } = await import('./commands/onboard-user.js');
1293
- await runOnboardUser({ email: argv.email, org: argv.org, role: argv.role, wait: argv.wait }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1294
- })
1295
- .command('debug-sso <connectionId>', 'Diagnose SSO connection issues', (yargs) => yargs.positional('connectionId', { type: 'string', demandOption: true }).options({
1296
- ...insecureStorageOption,
1297
- 'api-key': { type: 'string', describe: 'WorkOS API key' },
1298
- }), async (argv) => {
1299
- await applyInsecureStorage(argv.insecureStorage);
1300
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1301
- const { runDebugSso } = await import('./commands/debug-sso.js');
1302
- await runDebugSso(argv.connectionId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1303
- })
1304
- .command('debug-sync <directoryId>', 'Diagnose directory sync issues', (yargs) => yargs.positional('directoryId', { type: 'string', demandOption: true }).options({
1305
- ...insecureStorageOption,
1306
- 'api-key': { type: 'string', describe: 'WorkOS API key' },
1307
- }), async (argv) => {
1308
- await applyInsecureStorage(argv.insecureStorage);
1309
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1310
- const { runDebugSync } = await import('./commands/debug-sync.js');
1311
- await runDebugSync(argv.directoryId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1312
- })
1313
- // Alias — canonical command is `workos env claim`
1314
- .command('claim', 'Claim an unclaimed WorkOS environment (link it to your account)', (yargs) => yargs.options({
1315
- ...insecureStorageOption,
1316
- }), async (argv) => {
1317
- await applyInsecureStorage(argv.insecureStorage);
1318
- const { runClaim } = await import('./commands/claim.js');
1319
- await runClaim();
1320
- })
1321
- .command('install', 'Install WorkOS AuthKit into your project (interactive framework detection and setup)', (yargs) => yargs.options(installerOptions), async (argv) => {
1322
- await applyInsecureStorage(argv.insecureStorage);
1323
- await resolveInstallCredentials(argv.apiKey, argv.installDir, argv.skipAuth, ensureAuthenticated);
1324
- const { handleInstall } = await import('./commands/install.js');
1325
- await handleInstall(argv);
1326
- })
1327
- .command('emulate', false, // Hidden: unreleased beta feature
1328
- (yargs) => yargs.options({
1329
- port: { type: 'number', default: 4100, describe: 'Port to listen on' },
1330
- seed: { type: 'string', describe: 'Path to seed config file (YAML or JSON)' },
1331
- }), async (argv) => {
1332
- const { runEmulate } = await import('./commands/emulate.js');
1333
- await runEmulate({ port: argv.port, seed: argv.seed, json: argv.json });
1334
- })
1335
- .command('dev', false, // Hidden: unreleased beta feature
1336
- (yargs) => yargs.options({
1337
- port: { type: 'number', default: 4100, describe: 'Emulator port' },
1338
- seed: { type: 'string', describe: 'Path to seed config file' },
1339
- }), async (argv) => {
1340
- const { runDev } = await import('./commands/dev.js');
1341
- await runDev({
1342
- port: argv.port,
1343
- seed: argv.seed,
1344
- '--': argv['--'],
1345
- });
1346
- })
1347
- .command('debug', false, (yargs) => {
1348
- yargs.options(insecureStorageOption);
1349
- registerSubcommand(yargs, 'state', 'Dump raw CLI state (credentials, config, storage)', (y) => y.option('show-secrets', {
1350
- type: 'boolean',
1351
- default: false,
1352
- describe: 'Show unredacted tokens and API keys',
1432
+ const { runDebugSync } = await import('./commands/debug-sync.js');
1433
+ await runDebugSync(argv.directoryId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1434
+ })
1435
+ // Alias canonical command is `workos env claim`
1436
+ .command('claim', 'Claim an unclaimed WorkOS environment (link it to your account)', (yargs) => yargs.options({
1437
+ ...insecureStorageOption,
1353
1438
  }), async (argv) => {
1354
1439
  await applyInsecureStorage(argv.insecureStorage);
1355
- const { runDebugState } = await import('./commands/debug.js');
1356
- await runDebugState({ showSecrets: argv.showSecrets });
1357
- });
1358
- registerSubcommand(yargs, 'reset', 'Clear auth state (keyring + files)', (y) => y
1359
- .option('force', {
1360
- type: 'boolean',
1361
- default: false,
1362
- describe: 'Skip confirmation prompt',
1440
+ const { runClaim } = await import('./commands/claim.js');
1441
+ await runClaim();
1363
1442
  })
1364
- .option('credentials-only', {
1365
- type: 'boolean',
1366
- default: false,
1367
- describe: 'Only clear credentials',
1443
+ .command('install', 'Install WorkOS AuthKit into your project (interactive framework detection and setup)', (yargs) => yargs.options(installerOptions), async (argv) => {
1444
+ await applyInsecureStorage(argv.insecureStorage);
1445
+ await resolveInstallCredentials(argv.apiKey, argv.installDir, argv.skipAuth, ensureAuthenticated);
1446
+ const { handleInstall } = await import('./commands/install.js');
1447
+ await handleInstall(argv);
1368
1448
  })
1369
- .option('config-only', {
1370
- type: 'boolean',
1371
- default: false,
1372
- describe: 'Only clear config',
1449
+ .command('emulate', false, // Hidden: unreleased beta feature
1450
+ (yargs) => yargs.options({
1451
+ port: { type: 'number', default: 4100, describe: 'Port to listen on' },
1452
+ seed: { type: 'string', describe: 'Path to seed config file (YAML or JSON)' },
1373
1453
  }), async (argv) => {
1374
- await applyInsecureStorage(argv.insecureStorage);
1375
- const { runDebugReset } = await import('./commands/debug.js');
1376
- await runDebugReset({
1377
- force: argv.force,
1378
- credentialsOnly: argv.credentialsOnly,
1379
- configOnly: argv.configOnly,
1380
- });
1381
- });
1382
- registerSubcommand(yargs, 'simulate', 'Simulate CLI states for testing', (y) => y
1383
- .option('expired-token', {
1384
- type: 'boolean',
1385
- default: false,
1386
- describe: 'Set token expiresAt to the past',
1454
+ const { runEmulate } = await import('./commands/emulate.js');
1455
+ await runEmulate({ port: argv.port, seed: argv.seed, json: argv.json });
1387
1456
  })
1388
- .option('no-keyring', {
1389
- type: 'boolean',
1390
- default: false,
1391
- describe: 'Force file-only storage mode',
1457
+ .command('dev', false, // Hidden: unreleased beta feature
1458
+ (yargs) => yargs.options({
1459
+ port: { type: 'number', default: 4100, describe: 'Emulator port' },
1460
+ seed: { type: 'string', describe: 'Path to seed config file' },
1461
+ }), async (argv) => {
1462
+ const { runDev } = await import('./commands/dev.js');
1463
+ await runDev({
1464
+ port: argv.port,
1465
+ seed: argv.seed,
1466
+ '--': argv['--'],
1467
+ });
1392
1468
  })
1393
- .option('unclaimed', {
1394
- type: 'boolean',
1395
- default: false,
1396
- describe: 'Write synthetic unclaimed environment',
1469
+ .command('debug', false, (yargs) => {
1470
+ yargs.options(insecureStorageOption);
1471
+ registerSubcommand(yargs, 'state', 'Dump raw CLI state (credentials, config, storage)', (y) => y.option('show-secrets', {
1472
+ type: 'boolean',
1473
+ default: false,
1474
+ describe: 'Show unredacted tokens and API keys',
1475
+ }), async (argv) => {
1476
+ await applyInsecureStorage(argv.insecureStorage);
1477
+ const { runDebugState } = await import('./commands/debug.js');
1478
+ await runDebugState({ showSecrets: argv.showSecrets });
1479
+ });
1480
+ registerSubcommand(yargs, 'reset', 'Clear auth state (keyring + files)', (y) => y
1481
+ .option('force', {
1482
+ type: 'boolean',
1483
+ default: false,
1484
+ describe: 'Skip confirmation prompt',
1485
+ })
1486
+ .option('credentials-only', {
1487
+ type: 'boolean',
1488
+ default: false,
1489
+ describe: 'Only clear credentials',
1490
+ })
1491
+ .option('config-only', {
1492
+ type: 'boolean',
1493
+ default: false,
1494
+ describe: 'Only clear config',
1495
+ }), async (argv) => {
1496
+ await applyInsecureStorage(argv.insecureStorage);
1497
+ const { runDebugReset } = await import('./commands/debug.js');
1498
+ await runDebugReset({
1499
+ force: argv.force,
1500
+ credentialsOnly: argv.credentialsOnly,
1501
+ configOnly: argv.configOnly,
1502
+ });
1503
+ });
1504
+ registerSubcommand(yargs, 'simulate', 'Simulate CLI states for testing', (y) => y
1505
+ .option('expired-token', {
1506
+ type: 'boolean',
1507
+ default: false,
1508
+ describe: 'Set token expiresAt to the past',
1509
+ })
1510
+ .option('no-keyring', {
1511
+ type: 'boolean',
1512
+ default: false,
1513
+ describe: 'Force file-only storage mode',
1514
+ })
1515
+ .option('unclaimed', {
1516
+ type: 'boolean',
1517
+ default: false,
1518
+ describe: 'Write synthetic unclaimed environment',
1519
+ })
1520
+ .option('no-auth', {
1521
+ type: 'boolean',
1522
+ default: false,
1523
+ describe: 'Clear credentials, keep config',
1524
+ })
1525
+ .option('crash', {
1526
+ type: 'boolean',
1527
+ default: false,
1528
+ describe: 'Throw an unexpected error to exercise the crash-telemetry path',
1529
+ }), async (argv) => {
1530
+ await applyInsecureStorage(argv.insecureStorage);
1531
+ const { runDebugSimulate } = await import('./commands/debug.js');
1532
+ await runDebugSimulate({
1533
+ expiredToken: argv.expiredToken,
1534
+ noKeyring: argv.noKeyring,
1535
+ unclaimed: argv.unclaimed,
1536
+ noAuth: argv.noAuth,
1537
+ crash: argv.crash,
1538
+ });
1539
+ });
1540
+ registerSubcommand(yargs, 'env', 'Show WORKOS_* environment variables and their effects', (y) => y, async () => {
1541
+ const { runDebugEnv } = await import('./commands/debug.js');
1542
+ await runDebugEnv();
1543
+ });
1544
+ registerSubcommand(yargs, 'token', 'Decode and inspect the current access token', (y) => y, async (argv) => {
1545
+ await applyInsecureStorage(argv.insecureStorage);
1546
+ const { runDebugToken } = await import('./commands/debug.js');
1547
+ await runDebugToken();
1548
+ });
1549
+ return yargs.demandCommand(1, 'Run "workos debug <command>" for debug tools.').strict();
1397
1550
  })
1398
- .option('no-auth', {
1399
- type: 'boolean',
1400
- default: false,
1401
- describe: 'Clear credentials, keep config',
1551
+ .command('migrations', 'Migrate users from identity providers (Auth0, Cognito, Clerk, Firebase) to WorkOS', (yargs) => yargs
1552
+ .strictCommands(false)
1553
+ .strict(false)
1554
+ .help(false)
1555
+ .version(false)
1556
+ .options({
1557
+ ...insecureStorageOption,
1558
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
1402
1559
  }), async (argv) => {
1403
1560
  await applyInsecureStorage(argv.insecureStorage);
1404
- const { runDebugSimulate } = await import('./commands/debug.js');
1405
- await runDebugSimulate({
1406
- expiredToken: argv.expiredToken,
1407
- noKeyring: argv.noKeyring,
1408
- unclaimed: argv.unclaimed,
1409
- noAuth: argv.noAuth,
1410
- });
1411
- });
1412
- registerSubcommand(yargs, 'env', 'Show WORKOS_* environment variables and their effects', (y) => y, async () => {
1413
- const { runDebugEnv } = await import('./commands/debug.js');
1414
- await runDebugEnv();
1415
- });
1416
- registerSubcommand(yargs, 'token', 'Decode and inspect the current access token', (y) => y, async (argv) => {
1561
+ const { resolveOptionalApiKey } = await import('./lib/api-key.js');
1562
+ const { getActiveEnvironment } = await import('./lib/config-store.js');
1563
+ const { getMigrationsPassthroughArgs, runMigrations } = await import('./commands/migrations.js');
1564
+ const passthrough = getMigrationsPassthroughArgs(rawArgs);
1565
+ const endpoint = getActiveEnvironment()?.endpoint;
1566
+ await runMigrations(passthrough, resolveOptionalApiKey({ apiKey: argv.apiKey }), endpoint);
1567
+ })
1568
+ .command('dashboard', false, // hidden from help
1569
+ (yargs) => yargs.options(installerOptions), async (argv) => {
1417
1570
  await applyInsecureStorage(argv.insecureStorage);
1418
- const { runDebugToken } = await import('./commands/debug.js');
1419
- await runDebugToken();
1420
- });
1421
- return yargs.demandCommand(1, 'Run "workos debug <command>" for debug tools.').strict();
1422
- })
1423
- .command('migrations', 'Migrate users from identity providers (Auth0, Cognito, Clerk, Firebase) to WorkOS', (yargs) => yargs
1424
- .strictCommands(false)
1425
- .strict(false)
1426
- .help(false)
1427
- .version(false)
1428
- .options({
1429
- ...insecureStorageOption,
1430
- 'api-key': { type: 'string', describe: 'WorkOS API key' },
1431
- }), async (argv) => {
1432
- await applyInsecureStorage(argv.insecureStorage);
1433
- const { resolveOptionalApiKey } = await import('./lib/api-key.js');
1434
- const { getMigrationsPassthroughArgs, runMigrations } = await import('./commands/migrations.js');
1435
- const passthrough = getMigrationsPassthroughArgs(rawArgs);
1436
- await runMigrations(passthrough, resolveOptionalApiKey({ apiKey: argv.apiKey }));
1437
- })
1438
- .command('dashboard', false, // hidden from help
1439
- (yargs) => yargs.options(installerOptions), async (argv) => {
1440
- await applyInsecureStorage(argv.insecureStorage);
1441
- await resolveInstallCredentials(argv.apiKey, argv.installDir, argv.skipAuth, ensureAuthenticated);
1442
- const { handleInstall } = await import('./commands/install.js');
1443
- await handleInstall({ ...argv, dashboard: true });
1444
- })
1445
- .command(['$0'], 'WorkOS AuthKit CLI', (yargs) => yargs.options(insecureStorageOption), async (argv) => {
1446
- // Non-human modes: show help instead of prompting
1447
- if (!isPromptAllowed()) {
1448
- yargs(rawArgs).showHelp();
1449
- return;
1571
+ await resolveInstallCredentials(argv.apiKey, argv.installDir, argv.skipAuth, ensureAuthenticated);
1572
+ const { handleInstall } = await import('./commands/install.js');
1573
+ await handleInstall({ ...argv, dashboard: true });
1574
+ })
1575
+ .command(['$0'], 'WorkOS AuthKit CLI', (yargs) => yargs.options(insecureStorageOption), async (argv) => {
1576
+ // Non-human modes: show help instead of prompting
1577
+ if (!isPromptAllowed()) {
1578
+ yargs(rawArgs).showHelp();
1579
+ return;
1580
+ }
1581
+ // TTY: ask if user wants to run installer
1582
+ const shouldInstall = await clack.confirm({
1583
+ message: 'Run the AuthKit installer?',
1584
+ });
1585
+ if (clack.isCancel(shouldInstall) || !shouldInstall) {
1586
+ return;
1587
+ }
1588
+ await applyInsecureStorage(argv.insecureStorage);
1589
+ await resolveInstallCredentials(undefined, undefined, false, ensureAuthenticated);
1590
+ const { handleInstall } = await import('./commands/install.js');
1591
+ await handleInstall({ ...argv, dashboard: false });
1592
+ })
1593
+ .strict()
1594
+ .help()
1595
+ .alias('help', 'h')
1596
+ .version(getVersion())
1597
+ .alias('version', 'v')
1598
+ .wrap(process.stdout.isTTY && process.stdout.columns ? process.stdout.columns : 80);
1599
+ const shouldSkipTelemetry = () => !isTelemetryEnabled() || SKIP_TELEMETRY_COMMANDS.has(commandName.split('.')[0]);
1600
+ let commandOutcome;
1601
+ try {
1602
+ await parser.parseAsync(rawArgs);
1603
+ process.exitCode = 0;
1604
+ commandOutcome = {
1605
+ success: true,
1606
+ options: {
1607
+ flags,
1608
+ reason: 'success',
1609
+ },
1610
+ };
1450
1611
  }
1451
- // TTY: ask if user wants to run installer
1452
- const shouldInstall = await clack.confirm({
1453
- message: 'Run the AuthKit installer?',
1454
- });
1455
- if (clack.isCancel(shouldInstall) || !shouldInstall) {
1456
- process.exit(0);
1612
+ catch (error) {
1613
+ if (error instanceof CliExit) {
1614
+ process.exitCode = error.exitCode;
1615
+ commandOutcome = {
1616
+ success: error.exitCode === 0,
1617
+ options: {
1618
+ flags,
1619
+ reason: error.context?.reason,
1620
+ errorCode: error.context?.errorCode,
1621
+ apiContext: error.context?.apiContext,
1622
+ },
1623
+ };
1624
+ }
1625
+ else {
1626
+ // Unexpected error (crash)
1627
+ process.exitCode = 1;
1628
+ const err = error instanceof Error ? error : new Error(String(error));
1629
+ commandOutcome = {
1630
+ success: false,
1631
+ options: {
1632
+ flags,
1633
+ reason: 'crash',
1634
+ error: err,
1635
+ },
1636
+ };
1637
+ analytics.captureUnhandledCrash(err, { command: commandName });
1638
+ // Don't exit silently on an unexpected error. Surface a sanitized
1639
+ // message (secrets/paths stripped) so the user gets a diagnostic instead
1640
+ // of a bare exit code 1. Full details are in the crash log / telemetry.
1641
+ outputError({ code: 'internal_error', message: sanitizeMessage(err.message) });
1642
+ }
1457
1643
  }
1458
- await applyInsecureStorage(argv.insecureStorage);
1459
- await resolveInstallCredentials(undefined, undefined, false, ensureAuthenticated);
1460
- const { handleInstall } = await import('./commands/install.js');
1461
- await handleInstall({ ...argv, dashboard: false });
1462
- process.exit(0);
1463
- })
1464
- .strict()
1465
- .help()
1466
- .alias('help', 'h')
1467
- .version(getVersion())
1468
- .alias('version', 'v')
1469
- .wrap(process.stdout.isTTY && process.stdout.columns ? process.stdout.columns : 80).argv;
1644
+ finally {
1645
+ if (commandOutcome && !shouldSkipTelemetry()) {
1646
+ analytics.emitCommandEvent(commandName, Date.now() - startTime, commandOutcome.success, commandOutcome.options);
1647
+ }
1648
+ await telemetryClient.flush().catch(() => { });
1649
+ }
1650
+ }
1651
+ runCli();
1470
1652
  //# sourceMappingURL=bin.js.map