workos 0.7.3 → 0.8.1

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 (151) hide show
  1. package/README.md +353 -8
  2. package/dist/bin.js +938 -128
  3. package/dist/bin.js.map +1 -1
  4. package/dist/commands/api-key-mgmt.d.ts +16 -0
  5. package/dist/commands/api-key-mgmt.js +96 -0
  6. package/dist/commands/api-key-mgmt.js.map +1 -0
  7. package/dist/commands/audit-log.d.ts +26 -0
  8. package/dist/commands/audit-log.js +155 -0
  9. package/dist/commands/audit-log.js.map +1 -0
  10. package/dist/commands/config.d.ts +3 -0
  11. package/dist/commands/config.js +54 -0
  12. package/dist/commands/config.js.map +1 -0
  13. package/dist/commands/connection.d.ts +13 -0
  14. package/dist/commands/connection.js +94 -0
  15. package/dist/commands/connection.js.map +1 -0
  16. package/dist/commands/debug-sso.d.ts +1 -0
  17. package/dist/commands/debug-sso.js +78 -0
  18. package/dist/commands/debug-sso.js.map +1 -0
  19. package/dist/commands/debug-sync.d.ts +1 -0
  20. package/dist/commands/debug-sync.js +102 -0
  21. package/dist/commands/debug-sync.js.map +1 -0
  22. package/dist/commands/directory.d.ts +27 -0
  23. package/dist/commands/directory.js +174 -0
  24. package/dist/commands/directory.js.map +1 -0
  25. package/dist/commands/env.js +41 -28
  26. package/dist/commands/env.js.map +1 -1
  27. package/dist/commands/event.d.ts +9 -0
  28. package/dist/commands/event.js +43 -0
  29. package/dist/commands/event.js.map +1 -0
  30. package/dist/commands/feature-flag.d.ts +12 -0
  31. package/dist/commands/feature-flag.js +96 -0
  32. package/dist/commands/feature-flag.js.map +1 -0
  33. package/dist/commands/install-skill.js +3 -5
  34. package/dist/commands/install-skill.js.map +1 -1
  35. package/dist/commands/install.js +13 -20
  36. package/dist/commands/install.js.map +1 -1
  37. package/dist/commands/invitation.d.ts +19 -0
  38. package/dist/commands/invitation.js +94 -0
  39. package/dist/commands/invitation.js.map +1 -0
  40. package/dist/commands/membership.d.ts +20 -0
  41. package/dist/commands/membership.js +129 -0
  42. package/dist/commands/membership.js.map +1 -0
  43. package/dist/commands/onboard-user.d.ts +7 -0
  44. package/dist/commands/onboard-user.js +61 -0
  45. package/dist/commands/onboard-user.js.map +1 -0
  46. package/dist/commands/org-domain.d.ts +4 -0
  47. package/dist/commands/org-domain.js +45 -0
  48. package/dist/commands/org-domain.js.map +1 -0
  49. package/dist/commands/organization.d.ts +1 -5
  50. package/dist/commands/organization.js +34 -73
  51. package/dist/commands/organization.js.map +1 -1
  52. package/dist/commands/permission.d.ts +20 -0
  53. package/dist/commands/permission.js +93 -0
  54. package/dist/commands/permission.js.map +1 -0
  55. package/dist/commands/portal.d.ts +7 -0
  56. package/dist/commands/portal.js +26 -0
  57. package/dist/commands/portal.js.map +1 -0
  58. package/dist/commands/role.d.ts +17 -0
  59. package/dist/commands/role.js +122 -0
  60. package/dist/commands/role.js.map +1 -0
  61. package/dist/commands/seed.d.ts +4 -0
  62. package/dist/commands/seed.js +238 -0
  63. package/dist/commands/seed.js.map +1 -0
  64. package/dist/commands/session.d.ts +8 -0
  65. package/dist/commands/session.js +63 -0
  66. package/dist/commands/session.js.map +1 -0
  67. package/dist/commands/setup-org.d.ts +6 -0
  68. package/dist/commands/setup-org.js +99 -0
  69. package/dist/commands/setup-org.js.map +1 -0
  70. package/dist/commands/user.js +35 -71
  71. package/dist/commands/user.js.map +1 -1
  72. package/dist/commands/vault.d.ts +24 -0
  73. package/dist/commands/vault.js +120 -0
  74. package/dist/commands/vault.js.map +1 -0
  75. package/dist/commands/webhook.d.ts +3 -0
  76. package/dist/commands/webhook.js +73 -0
  77. package/dist/commands/webhook.js.map +1 -0
  78. package/dist/dashboard/components/DiffPanel.js.map +1 -1
  79. package/dist/dashboard/lib/logo-frames.js +1 -1
  80. package/dist/dashboard/lib/logo-frames.js.map +1 -1
  81. package/dist/doctor/checks/dashboard.js.map +1 -1
  82. package/dist/doctor/checks/environment.js.map +1 -1
  83. package/dist/integrations/go/index.js +1 -3
  84. package/dist/integrations/go/index.js.map +1 -1
  85. package/dist/lib/adapters/headless-adapter.d.ts +67 -0
  86. package/dist/lib/adapters/headless-adapter.js +263 -0
  87. package/dist/lib/adapters/headless-adapter.js.map +1 -0
  88. package/dist/lib/adapters/index.d.ts +1 -0
  89. package/dist/lib/adapters/index.js +1 -0
  90. package/dist/lib/adapters/index.js.map +1 -1
  91. package/dist/lib/agent-interface.d.ts +3 -11
  92. package/dist/lib/agent-interface.js +3 -19
  93. package/dist/lib/agent-interface.js.map +1 -1
  94. package/dist/lib/api-error-handler.d.ts +6 -0
  95. package/dist/lib/api-error-handler.js +58 -0
  96. package/dist/lib/api-error-handler.js.map +1 -0
  97. package/dist/lib/api-key.js +5 -1
  98. package/dist/lib/api-key.js.map +1 -1
  99. package/dist/lib/config.js.map +1 -1
  100. package/dist/lib/credential-proxy.js +0 -6
  101. package/dist/lib/credential-proxy.js.map +1 -1
  102. package/dist/lib/device-auth.js +1 -1
  103. package/dist/lib/device-auth.js.map +1 -1
  104. package/dist/lib/ensure-auth.js +25 -4
  105. package/dist/lib/ensure-auth.js.map +1 -1
  106. package/dist/lib/installer-core.d.ts +12 -12
  107. package/dist/lib/run-with-core.js +25 -4
  108. package/dist/lib/run-with-core.js.map +1 -1
  109. package/dist/lib/validation/validator.js +0 -1
  110. package/dist/lib/validation/validator.js.map +1 -1
  111. package/dist/lib/workos-client.d.ts +58 -0
  112. package/dist/lib/workos-client.js +137 -0
  113. package/dist/lib/workos-client.js.map +1 -0
  114. package/dist/run.d.ts +7 -0
  115. package/dist/run.js +5 -2
  116. package/dist/run.js.map +1 -1
  117. package/dist/smoke-test.ts +881 -0
  118. package/dist/steps/run-prettier.js +1 -1
  119. package/dist/steps/run-prettier.js.map +1 -1
  120. package/dist/utils/analytics.d.ts +1 -1
  121. package/dist/utils/analytics.js.map +1 -1
  122. package/dist/utils/clack-utils.js +1 -1
  123. package/dist/utils/clack-utils.js.map +1 -1
  124. package/dist/utils/environment.js +8 -0
  125. package/dist/utils/environment.js.map +1 -1
  126. package/dist/utils/exit-codes.d.ts +22 -0
  127. package/dist/utils/exit-codes.js +30 -0
  128. package/dist/utils/exit-codes.js.map +1 -0
  129. package/dist/utils/help-json.d.ts +45 -0
  130. package/dist/utils/help-json.js +1161 -0
  131. package/dist/utils/help-json.js.map +1 -0
  132. package/dist/utils/ndjson.d.ts +16 -0
  133. package/dist/utils/ndjson.js +18 -0
  134. package/dist/utils/ndjson.js.map +1 -0
  135. package/dist/utils/output.d.ts +40 -0
  136. package/dist/utils/output.js +95 -0
  137. package/dist/utils/output.js.map +1 -0
  138. package/dist/utils/package-manager.js +2 -3
  139. package/dist/utils/package-manager.js.map +1 -1
  140. package/dist/utils/paths.d.ts +5 -0
  141. package/dist/utils/paths.js +18 -0
  142. package/dist/utils/paths.js.map +1 -0
  143. package/dist/utils/register-subcommand.d.ts +7 -0
  144. package/dist/utils/register-subcommand.js +36 -0
  145. package/dist/utils/register-subcommand.js.map +1 -0
  146. package/dist/utils/telemetry-types.d.ts +1 -1
  147. package/dist/utils/telemetry-types.js.map +1 -1
  148. package/dist/utils/types.d.ts +12 -0
  149. package/dist/utils/types.js.map +1 -1
  150. package/package.json +20 -16
  151. package/skills/workos-management/SKILL.md +250 -0
package/dist/bin.js CHANGED
@@ -20,7 +20,22 @@ if (!satisfies(process.version, NODE_VERSION_RANGE)) {
20
20
  process.exit(1);
21
21
  }
22
22
  import { isNonInteractiveEnvironment } from './utils/environment.js';
23
+ import { resolveOutputMode, setOutputMode, outputJson, exitWithError } from './utils/output.js';
23
24
  import clack from './utils/clack.js';
25
+ import { registerSubcommand } from './utils/register-subcommand.js';
26
+ // Resolve output mode early from raw argv (before yargs parses)
27
+ const rawArgs = hideBin(process.argv);
28
+ const hasJsonFlag = rawArgs.includes('--json');
29
+ setOutputMode(resolveOutputMode(hasJsonFlag));
30
+ // Intercept --help --json before yargs parses (yargs exits on --help)
31
+ if (hasJsonFlag && (rawArgs.includes('--help') || rawArgs.includes('-h'))) {
32
+ const { buildCommandTree } = await import('./utils/help-json.js');
33
+ const commandAliases = { org: 'organization' };
34
+ const rawCommand = rawArgs.find((a) => !a.startsWith('-'));
35
+ const command = rawCommand ? (commandAliases[rawCommand] ?? rawCommand) : undefined;
36
+ outputJson(buildCommandTree(command));
37
+ process.exit(0);
38
+ }
24
39
  /** Apply insecure storage flag if set */
25
40
  async function applyInsecureStorage(insecureStorage) {
26
41
  if (insecureStorage) {
@@ -83,11 +98,11 @@ const installerOptions = {
83
98
  },
84
99
  'api-key': {
85
100
  type: 'string',
86
- hidden: true,
101
+ describe: 'WorkOS API key (required in non-interactive mode)',
87
102
  },
88
103
  'client-id': {
89
104
  type: 'string',
90
- hidden: true,
105
+ describe: 'WorkOS client ID (required in non-interactive mode)',
91
106
  },
92
107
  inspect: {
93
108
  default: false,
@@ -103,9 +118,9 @@ const installerOptions = {
103
118
  describe: 'Redirect URI for WorkOS callback (defaults to framework convention)',
104
119
  type: 'string',
105
120
  },
106
- 'no-validate': {
107
- default: false,
108
- describe: 'Skip post-installation validation (includes build check)',
121
+ validate: {
122
+ default: true,
123
+ describe: 'Run post-installation validation (use --no-validate to skip)',
109
124
  type: 'boolean',
110
125
  },
111
126
  'install-dir': {
@@ -127,23 +142,49 @@ const installerOptions = {
127
142
  describe: 'Run with visual dashboard mode',
128
143
  type: 'boolean',
129
144
  },
145
+ branch: {
146
+ default: true,
147
+ describe: 'Create a new branch for changes (use --no-branch to skip)',
148
+ type: 'boolean',
149
+ },
150
+ commit: {
151
+ default: true,
152
+ describe: 'Auto-commit after installation (use --no-commit to skip)',
153
+ type: 'boolean',
154
+ },
155
+ 'create-pr': {
156
+ default: false,
157
+ describe: 'Auto-create pull request after installation',
158
+ type: 'boolean',
159
+ },
160
+ 'git-check': {
161
+ default: true,
162
+ describe: 'Check for dirty working tree (use --no-git-check to skip)',
163
+ type: 'boolean',
164
+ },
130
165
  };
131
166
  // Check for updates (blocks up to 500ms)
132
167
  await checkForUpdates();
133
- yargs(hideBin(process.argv))
168
+ yargs(rawArgs)
134
169
  .env('WORKOS_INSTALLER')
135
- .command('login', 'Authenticate with WorkOS', insecureStorageOption, async (argv) => {
170
+ .option('json', {
171
+ type: 'boolean',
172
+ default: false,
173
+ describe: 'Output results as JSON (auto-enabled in non-TTY)',
174
+ global: true,
175
+ })
176
+ .command('login', 'Authenticate with WorkOS via browser-based OAuth', insecureStorageOption, async (argv) => {
136
177
  await applyInsecureStorage(argv.insecureStorage);
137
178
  const { runLogin } = await import('./commands/login.js');
138
179
  await runLogin();
139
180
  process.exit(0);
140
181
  })
141
- .command('logout', 'Remove stored credentials', insecureStorageOption, async (argv) => {
182
+ .command('logout', 'Remove stored WorkOS credentials and tokens', insecureStorageOption, async (argv) => {
142
183
  await applyInsecureStorage(argv.insecureStorage);
143
184
  const { runLogout } = await import('./commands/logout.js');
144
185
  await runLogout();
145
186
  })
146
- .command('install-skill', 'Install bundled AuthKit skills to coding agents', (yargs) => {
187
+ .command('install-skill', 'Install bundled AuthKit skills to coding agents (Claude Code, Codex, Cursor, Goose)', (yargs) => {
147
188
  return yargs
148
189
  .option('list', {
149
190
  alias: 'l',
@@ -170,7 +211,7 @@ yargs(hideBin(process.argv))
170
211
  agent: argv.agent,
171
212
  });
172
213
  }))
173
- .command('doctor', 'Diagnose WorkOS integration issues', (yargs) => yargs.options({
214
+ .command('doctor', 'Diagnose WorkOS AuthKit integration issues in the current project', (yargs) => yargs.options({
174
215
  verbose: {
175
216
  type: 'boolean',
176
217
  default: false,
@@ -205,151 +246,920 @@ yargs(hideBin(process.argv))
205
246
  const { handleDoctor } = await import('./commands/doctor.js');
206
247
  await handleDoctor(argv);
207
248
  })
208
- .command('env', 'Manage environment configurations', (yargs) => yargs
209
- .options(insecureStorageOption)
210
- .command('add [name] [apiKey]', 'Add an environment configuration', (yargs) => yargs
211
- .positional('name', { type: 'string', describe: 'Environment name' })
212
- .positional('apiKey', { type: 'string', describe: 'WorkOS API key' })
213
- .option('client-id', { type: 'string', describe: 'WorkOS client ID' })
214
- .option('endpoint', { type: 'string', describe: 'Custom API endpoint' }), async (argv) => {
215
- await applyInsecureStorage(argv.insecureStorage);
216
- const { runEnvAdd } = await import('./commands/env.js');
217
- await runEnvAdd({
218
- name: argv.name,
219
- apiKey: argv.apiKey,
220
- clientId: argv.clientId,
221
- endpoint: argv.endpoint,
249
+ // NOTE: When adding commands here, also update src/utils/help-json.ts
250
+ .command('env', 'Manage environment configurations (API keys, endpoints, active environment)', (yargs) => {
251
+ yargs.options(insecureStorageOption);
252
+ registerSubcommand(yargs, 'add [name] [apiKey]', 'Add an environment configuration', (y) => y
253
+ .positional('name', { type: 'string', describe: 'Environment name' })
254
+ .positional('apiKey', { type: 'string', describe: 'WorkOS API key' })
255
+ .option('client-id', { type: 'string', describe: 'WorkOS client ID' })
256
+ .option('endpoint', { type: 'string', describe: 'Custom API endpoint' }), async (argv) => {
257
+ await applyInsecureStorage(argv.insecureStorage);
258
+ const { runEnvAdd } = await import('./commands/env.js');
259
+ await runEnvAdd({
260
+ name: argv.name,
261
+ apiKey: argv.apiKey,
262
+ clientId: argv.clientId,
263
+ endpoint: argv.endpoint,
264
+ });
265
+ });
266
+ registerSubcommand(yargs, 'remove <name>', 'Remove an environment configuration', (y) => y.positional('name', { type: 'string', demandOption: true, describe: 'Environment name' }), async (argv) => {
267
+ await applyInsecureStorage(argv.insecureStorage);
268
+ const { runEnvRemove } = await import('./commands/env.js');
269
+ await runEnvRemove(argv.name);
222
270
  });
271
+ registerSubcommand(yargs, 'switch [name]', 'Switch active environment', (y) => y.positional('name', { type: 'string', describe: 'Environment name' }), async (argv) => {
272
+ if (!argv.name && isNonInteractiveEnvironment()) {
273
+ exitWithError({
274
+ code: 'missing_args',
275
+ message: 'Environment name required. Usage: workos env switch <name>',
276
+ });
277
+ }
278
+ await applyInsecureStorage(argv.insecureStorage);
279
+ const { runEnvSwitch } = await import('./commands/env.js');
280
+ await runEnvSwitch(argv.name);
281
+ });
282
+ registerSubcommand(yargs, 'list', 'List configured environments', (y) => y, async (argv) => {
283
+ await applyInsecureStorage(argv.insecureStorage);
284
+ const { runEnvList } = await import('./commands/env.js');
285
+ await runEnvList();
286
+ });
287
+ return yargs.demandCommand(1, 'Please specify an env subcommand').strict();
223
288
  })
224
- .command('remove <name>', 'Remove an environment configuration', (yargs) => yargs.positional('name', { type: 'string', demandOption: true, describe: 'Environment name' }), async (argv) => {
225
- await applyInsecureStorage(argv.insecureStorage);
226
- const { runEnvRemove } = await import('./commands/env.js');
227
- await runEnvRemove(argv.name);
289
+ .command(['organization', 'org'], 'Manage WorkOS organizations (create, update, get, list, delete)', (yargs) => {
290
+ yargs.options({
291
+ ...insecureStorageOption,
292
+ 'api-key': {
293
+ type: 'string',
294
+ describe: 'WorkOS API key (overrides environment config). Format: sk_live_* or sk_test_*',
295
+ },
296
+ });
297
+ registerSubcommand(yargs, 'create <name> [domains..]', 'Create a new organization with optional verified domains', (y) => y
298
+ .positional('name', { type: 'string', demandOption: true, describe: 'Organization name' })
299
+ .positional('domains', {
300
+ type: 'string',
301
+ array: true,
302
+ describe: 'Domains in format domain:state (state defaults to verified)',
303
+ }), async (argv) => {
304
+ await applyInsecureStorage(argv.insecureStorage);
305
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
306
+ const { runOrgCreate } = await import('./commands/organization.js');
307
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey });
308
+ await runOrgCreate(argv.name, argv.domains || [], apiKey, resolveApiBaseUrl());
309
+ });
310
+ registerSubcommand(yargs, 'update <orgId> <name> [domain] [state]', 'Update an organization', (y) => y
311
+ .positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' })
312
+ .positional('name', { type: 'string', demandOption: true, describe: 'Organization name' })
313
+ .positional('domain', { type: 'string', describe: 'Domain' })
314
+ .positional('state', { type: 'string', describe: 'Domain state (verified or pending)' }), async (argv) => {
315
+ await applyInsecureStorage(argv.insecureStorage);
316
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
317
+ const { runOrgUpdate } = await import('./commands/organization.js');
318
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey });
319
+ await runOrgUpdate(argv.orgId, argv.name, apiKey, argv.domain, argv.state, resolveApiBaseUrl());
320
+ });
321
+ registerSubcommand(yargs, 'get <orgId>', 'Get an organization by ID', (y) => y.positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' }), async (argv) => {
322
+ await applyInsecureStorage(argv.insecureStorage);
323
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
324
+ const { runOrgGet } = await import('./commands/organization.js');
325
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey });
326
+ await runOrgGet(argv.orgId, apiKey, resolveApiBaseUrl());
327
+ });
328
+ registerSubcommand(yargs, 'list', 'List organizations', (y) => y.options({
329
+ domain: { type: 'string', describe: 'Filter by domain' },
330
+ limit: { type: 'number', describe: 'Limit number of results' },
331
+ before: { type: 'string', describe: 'Cursor for results before a specific item' },
332
+ after: { type: 'string', describe: 'Cursor for results after a specific item' },
333
+ order: { type: 'string', describe: 'Order of results (asc or desc)' },
334
+ }), async (argv) => {
335
+ await applyInsecureStorage(argv.insecureStorage);
336
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
337
+ const { runOrgList } = await import('./commands/organization.js');
338
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey });
339
+ await runOrgList({ domain: argv.domain, limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, apiKey, resolveApiBaseUrl());
340
+ });
341
+ registerSubcommand(yargs, 'delete <orgId>', 'Delete an organization', (y) => y.positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' }), async (argv) => {
342
+ await applyInsecureStorage(argv.insecureStorage);
343
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
344
+ const { runOrgDelete } = await import('./commands/organization.js');
345
+ const apiKey = resolveApiKey({ apiKey: argv.apiKey });
346
+ await runOrgDelete(argv.orgId, apiKey, resolveApiBaseUrl());
347
+ });
348
+ return yargs.demandCommand(1, 'Please specify an organization subcommand').strict();
228
349
  })
229
- .command('switch [name]', 'Switch active environment', (yargs) => yargs.positional('name', { type: 'string', describe: 'Environment name' }), async (argv) => {
230
- await applyInsecureStorage(argv.insecureStorage);
231
- const { runEnvSwitch } = await import('./commands/env.js');
232
- await runEnvSwitch(argv.name);
350
+ .command('user', 'Manage WorkOS users (get, list, update, delete)', (yargs) => {
351
+ yargs.options({
352
+ ...insecureStorageOption,
353
+ 'api-key': {
354
+ type: 'string',
355
+ describe: 'WorkOS API key (overrides environment config). Format: sk_live_* or sk_test_*',
356
+ },
357
+ });
358
+ registerSubcommand(yargs, 'get <userId>', 'Get a user by ID', (y) => y.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }), async (argv) => {
359
+ await applyInsecureStorage(argv.insecureStorage);
360
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
361
+ const { runUserGet } = await import('./commands/user.js');
362
+ await runUserGet(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
363
+ });
364
+ registerSubcommand(yargs, 'list', 'List users', (y) => y.options({
365
+ email: { type: 'string', describe: 'Filter by email' },
366
+ organization: { type: 'string', describe: 'Filter by organization ID' },
367
+ limit: { type: 'number', describe: 'Limit number of results' },
368
+ before: { type: 'string', describe: 'Cursor for results before a specific item' },
369
+ after: { type: 'string', describe: 'Cursor for results after a specific item' },
370
+ order: { type: 'string', describe: 'Order of results (asc or desc)' },
371
+ }), async (argv) => {
372
+ await applyInsecureStorage(argv.insecureStorage);
373
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
374
+ const { runUserList } = await import('./commands/user.js');
375
+ await runUserList({
376
+ email: argv.email,
377
+ organization: argv.organization,
378
+ limit: argv.limit,
379
+ before: argv.before,
380
+ after: argv.after,
381
+ order: argv.order,
382
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
383
+ });
384
+ registerSubcommand(yargs, 'update <userId>', 'Update a user', (y) => y.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }).options({
385
+ 'first-name': { type: 'string', describe: 'First name' },
386
+ 'last-name': { type: 'string', describe: 'Last name' },
387
+ 'email-verified': { type: 'boolean', describe: 'Email verification status' },
388
+ password: { type: 'string', describe: 'New password' },
389
+ 'external-id': { type: 'string', describe: 'External ID' },
390
+ }), async (argv) => {
391
+ await applyInsecureStorage(argv.insecureStorage);
392
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
393
+ const { runUserUpdate } = await import('./commands/user.js');
394
+ await runUserUpdate(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), {
395
+ firstName: argv.firstName,
396
+ lastName: argv.lastName,
397
+ emailVerified: argv.emailVerified,
398
+ password: argv.password,
399
+ externalId: argv.externalId,
400
+ }, resolveApiBaseUrl());
401
+ });
402
+ registerSubcommand(yargs, 'delete <userId>', 'Delete a user', (y) => y.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }), async (argv) => {
403
+ await applyInsecureStorage(argv.insecureStorage);
404
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
405
+ const { runUserDelete } = await import('./commands/user.js');
406
+ await runUserDelete(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
407
+ });
408
+ return yargs.demandCommand(1, 'Please specify a user subcommand').strict();
233
409
  })
234
- .command('list', 'List configured environments', (yargs) => yargs, async (argv) => {
235
- await applyInsecureStorage(argv.insecureStorage);
236
- const { runEnvList } = await import('./commands/env.js');
237
- await runEnvList();
410
+ // --- Resource Management Commands ---
411
+ .command('role', 'Manage WorkOS roles (environment and organization-scoped)', (yargs) => {
412
+ yargs.options({
413
+ ...insecureStorageOption,
414
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
415
+ org: { type: 'string', describe: 'Organization ID (for org-scoped roles)' },
416
+ });
417
+ registerSubcommand(yargs, 'list', 'List roles', (y) => y, async (argv) => {
418
+ await applyInsecureStorage(argv.insecureStorage);
419
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
420
+ const { runRoleList } = await import('./commands/role.js');
421
+ await runRoleList(argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
422
+ });
423
+ registerSubcommand(yargs, 'get <slug>', 'Get a role by slug', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
424
+ await applyInsecureStorage(argv.insecureStorage);
425
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
426
+ const { runRoleGet } = await import('./commands/role.js');
427
+ await runRoleGet(argv.slug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
428
+ });
429
+ registerSubcommand(yargs, 'create', 'Create a role', (y) => y.options({
430
+ slug: { type: 'string', demandOption: true, describe: 'Role slug' },
431
+ name: { type: 'string', demandOption: true, describe: 'Role name' },
432
+ description: { type: 'string', describe: 'Role description' },
433
+ }), async (argv) => {
434
+ await applyInsecureStorage(argv.insecureStorage);
435
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
436
+ const { runRoleCreate } = await import('./commands/role.js');
437
+ await runRoleCreate({ slug: argv.slug, name: argv.name, description: argv.description }, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
438
+ });
439
+ registerSubcommand(yargs, 'update <slug>', 'Update a role', (y) => y
440
+ .positional('slug', { type: 'string', demandOption: true })
441
+ .options({ name: { type: 'string' }, description: { type: 'string' } }), async (argv) => {
442
+ await applyInsecureStorage(argv.insecureStorage);
443
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
444
+ const { runRoleUpdate } = await import('./commands/role.js');
445
+ await runRoleUpdate(argv.slug, { name: argv.name, description: argv.description }, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
446
+ });
447
+ registerSubcommand(yargs, 'delete <slug>', 'Delete an org-scoped role (requires --org)', (y) => y.positional('slug', { type: 'string', demandOption: true }).demandOption('org'), async (argv) => {
448
+ await applyInsecureStorage(argv.insecureStorage);
449
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
450
+ const { runRoleDelete } = await import('./commands/role.js');
451
+ await runRoleDelete(argv.slug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
452
+ });
453
+ registerSubcommand(yargs, 'set-permissions <slug>', 'Set all permissions on a role (replaces existing)', (y) => y.positional('slug', { type: 'string', demandOption: true }).option('permissions', {
454
+ type: 'string',
455
+ demandOption: true,
456
+ describe: 'Comma-separated permission slugs',
457
+ }), async (argv) => {
458
+ await applyInsecureStorage(argv.insecureStorage);
459
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
460
+ const { runRoleSetPermissions } = await import('./commands/role.js');
461
+ await runRoleSetPermissions(argv.slug, argv.permissions.split(','), argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
462
+ });
463
+ registerSubcommand(yargs, 'add-permission <slug> <permissionSlug>', 'Add a permission to a role', (y) => y
464
+ .positional('slug', { type: 'string', demandOption: true })
465
+ .positional('permissionSlug', { type: 'string', demandOption: true }), async (argv) => {
466
+ await applyInsecureStorage(argv.insecureStorage);
467
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
468
+ const { runRoleAddPermission } = await import('./commands/role.js');
469
+ await runRoleAddPermission(argv.slug, argv.permissionSlug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
470
+ });
471
+ registerSubcommand(yargs, 'remove-permission <slug> <permissionSlug>', 'Remove a permission from an org role (requires --org)', (y) => y
472
+ .positional('slug', { type: 'string', demandOption: true })
473
+ .positional('permissionSlug', { type: 'string', demandOption: true })
474
+ .demandOption('org'), async (argv) => {
475
+ await applyInsecureStorage(argv.insecureStorage);
476
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
477
+ const { runRoleRemovePermission } = await import('./commands/role.js');
478
+ await runRoleRemovePermission(argv.slug, argv.permissionSlug, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
479
+ });
480
+ return yargs.demandCommand(1, 'Please specify a role subcommand').strict();
238
481
  })
239
- .demandCommand(1, 'Please specify an env subcommand')
240
- .strict())
241
- .command('organization', 'Manage organizations', (yargs) => yargs
242
- .options({
243
- ...insecureStorageOption,
244
- 'api-key': { type: 'string', describe: 'WorkOS API key (overrides environment config)' },
482
+ .command('permission', 'Manage WorkOS permissions', (yargs) => {
483
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
484
+ registerSubcommand(yargs, 'list', 'List permissions', (y) => y.options({
485
+ limit: { type: 'number' },
486
+ before: { type: 'string' },
487
+ after: { type: 'string' },
488
+ order: { type: 'string' },
489
+ }), async (argv) => {
490
+ await applyInsecureStorage(argv.insecureStorage);
491
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
492
+ const { runPermissionList } = await import('./commands/permission.js');
493
+ await runPermissionList({ limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
494
+ });
495
+ registerSubcommand(yargs, 'get <slug>', 'Get a permission', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
496
+ await applyInsecureStorage(argv.insecureStorage);
497
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
498
+ const { runPermissionGet } = await import('./commands/permission.js');
499
+ await runPermissionGet(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
500
+ });
501
+ registerSubcommand(yargs, 'create', 'Create a permission', (y) => y.options({
502
+ slug: { type: 'string', demandOption: true },
503
+ name: { type: 'string', demandOption: true },
504
+ description: { type: 'string' },
505
+ }), async (argv) => {
506
+ await applyInsecureStorage(argv.insecureStorage);
507
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
508
+ const { runPermissionCreate } = await import('./commands/permission.js');
509
+ await runPermissionCreate({ slug: argv.slug, name: argv.name, description: argv.description }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
510
+ });
511
+ registerSubcommand(yargs, 'update <slug>', 'Update a permission', (y) => y
512
+ .positional('slug', { type: 'string', demandOption: true })
513
+ .options({ name: { type: 'string' }, description: { type: 'string' } }), async (argv) => {
514
+ await applyInsecureStorage(argv.insecureStorage);
515
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
516
+ const { runPermissionUpdate } = await import('./commands/permission.js');
517
+ await runPermissionUpdate(argv.slug, { name: argv.name, description: argv.description }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
518
+ });
519
+ registerSubcommand(yargs, 'delete <slug>', 'Delete a permission', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
520
+ await applyInsecureStorage(argv.insecureStorage);
521
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
522
+ const { runPermissionDelete } = await import('./commands/permission.js');
523
+ await runPermissionDelete(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
524
+ });
525
+ return yargs.demandCommand(1, 'Please specify a permission subcommand').strict();
245
526
  })
246
- .command('create <name> [domains..]', 'Create a new organization', (yargs) => yargs
247
- .positional('name', { type: 'string', demandOption: true, describe: 'Organization name' })
248
- .positional('domains', { type: 'string', array: true, describe: 'Domains as domain:state' }), async (argv) => {
249
- await applyInsecureStorage(argv.insecureStorage);
250
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
251
- const { runOrgCreate } = await import('./commands/organization.js');
252
- const apiKey = resolveApiKey({ apiKey: argv.apiKey });
253
- await runOrgCreate(argv.name, argv.domains || [], apiKey, resolveApiBaseUrl());
527
+ .command('membership', 'Manage organization memberships', (yargs) => {
528
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
529
+ registerSubcommand(yargs, 'list', 'List memberships', (y) => y.options({
530
+ org: { type: 'string' },
531
+ user: { type: 'string' },
532
+ limit: { type: 'number' },
533
+ before: { type: 'string' },
534
+ after: { type: 'string' },
535
+ order: { type: 'string' },
536
+ }), async (argv) => {
537
+ await applyInsecureStorage(argv.insecureStorage);
538
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
539
+ const { runMembershipList } = await import('./commands/membership.js');
540
+ await runMembershipList({
541
+ org: argv.org,
542
+ user: argv.user,
543
+ limit: argv.limit,
544
+ before: argv.before,
545
+ after: argv.after,
546
+ order: argv.order,
547
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
548
+ });
549
+ registerSubcommand(yargs, 'get <id>', 'Get a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
550
+ await applyInsecureStorage(argv.insecureStorage);
551
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
552
+ const { runMembershipGet } = await import('./commands/membership.js');
553
+ await runMembershipGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
554
+ });
555
+ registerSubcommand(yargs, 'create', 'Create a membership', (y) => y.options({
556
+ org: { type: 'string', demandOption: true },
557
+ user: { type: 'string', demandOption: true },
558
+ role: { type: 'string' },
559
+ }), async (argv) => {
560
+ await applyInsecureStorage(argv.insecureStorage);
561
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
562
+ const { runMembershipCreate } = await import('./commands/membership.js');
563
+ await runMembershipCreate({ org: argv.org, user: argv.user, role: argv.role }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
564
+ });
565
+ registerSubcommand(yargs, 'update <id>', 'Update a membership', (y) => y.positional('id', { type: 'string', demandOption: true }).option('role', { type: 'string' }), async (argv) => {
566
+ await applyInsecureStorage(argv.insecureStorage);
567
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
568
+ const { runMembershipUpdate } = await import('./commands/membership.js');
569
+ await runMembershipUpdate(argv.id, argv.role, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
570
+ });
571
+ registerSubcommand(yargs, 'delete <id>', 'Delete a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
572
+ await applyInsecureStorage(argv.insecureStorage);
573
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
574
+ const { runMembershipDelete } = await import('./commands/membership.js');
575
+ await runMembershipDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
576
+ });
577
+ registerSubcommand(yargs, 'deactivate <id>', 'Deactivate a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
578
+ await applyInsecureStorage(argv.insecureStorage);
579
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
580
+ const { runMembershipDeactivate } = await import('./commands/membership.js');
581
+ await runMembershipDeactivate(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
582
+ });
583
+ registerSubcommand(yargs, 'reactivate <id>', 'Reactivate a membership', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
584
+ await applyInsecureStorage(argv.insecureStorage);
585
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
586
+ const { runMembershipReactivate } = await import('./commands/membership.js');
587
+ await runMembershipReactivate(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
588
+ });
589
+ return yargs.demandCommand(1, 'Please specify a membership subcommand').strict();
254
590
  })
255
- .command('update <orgId> <name> [domain] [state]', 'Update an organization', (yargs) => yargs
256
- .positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' })
257
- .positional('name', { type: 'string', demandOption: true, describe: 'Organization name' })
258
- .positional('domain', { type: 'string', describe: 'Domain' })
259
- .positional('state', { type: 'string', describe: 'Domain state (verified or pending)' }), async (argv) => {
260
- await applyInsecureStorage(argv.insecureStorage);
261
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
262
- const { runOrgUpdate } = await import('./commands/organization.js');
263
- const apiKey = resolveApiKey({ apiKey: argv.apiKey });
264
- await runOrgUpdate(argv.orgId, argv.name, apiKey, argv.domain, argv.state, resolveApiBaseUrl());
591
+ .command('invitation', 'Manage user invitations', (yargs) => {
592
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
593
+ registerSubcommand(yargs, 'list', 'List invitations', (y) => y.options({
594
+ org: { type: 'string' },
595
+ email: { type: 'string' },
596
+ limit: { type: 'number' },
597
+ before: { type: 'string' },
598
+ after: { type: 'string' },
599
+ order: { type: 'string' },
600
+ }), async (argv) => {
601
+ await applyInsecureStorage(argv.insecureStorage);
602
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
603
+ const { runInvitationList } = await import('./commands/invitation.js');
604
+ await runInvitationList({
605
+ org: argv.org,
606
+ email: argv.email,
607
+ limit: argv.limit,
608
+ before: argv.before,
609
+ after: argv.after,
610
+ order: argv.order,
611
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
612
+ });
613
+ registerSubcommand(yargs, 'get <id>', 'Get an invitation', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
614
+ await applyInsecureStorage(argv.insecureStorage);
615
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
616
+ const { runInvitationGet } = await import('./commands/invitation.js');
617
+ await runInvitationGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
618
+ });
619
+ registerSubcommand(yargs, 'send', 'Send an invitation', (y) => y.options({
620
+ email: { type: 'string', demandOption: true },
621
+ org: { type: 'string' },
622
+ role: { type: 'string' },
623
+ 'expires-in-days': { type: 'number' },
624
+ }), async (argv) => {
625
+ await applyInsecureStorage(argv.insecureStorage);
626
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
627
+ const { runInvitationSend } = await import('./commands/invitation.js');
628
+ await runInvitationSend({ email: argv.email, org: argv.org, role: argv.role, expiresInDays: argv.expiresInDays }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
629
+ });
630
+ registerSubcommand(yargs, 'revoke <id>', 'Revoke an invitation', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
631
+ await applyInsecureStorage(argv.insecureStorage);
632
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
633
+ const { runInvitationRevoke } = await import('./commands/invitation.js');
634
+ await runInvitationRevoke(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
635
+ });
636
+ registerSubcommand(yargs, 'resend <id>', 'Resend an invitation', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
637
+ await applyInsecureStorage(argv.insecureStorage);
638
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
639
+ const { runInvitationResend } = await import('./commands/invitation.js');
640
+ await runInvitationResend(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
641
+ });
642
+ return yargs.demandCommand(1, 'Please specify an invitation subcommand').strict();
265
643
  })
266
- .command('get <orgId>', 'Get an organization by ID', (yargs) => yargs.positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' }), async (argv) => {
267
- await applyInsecureStorage(argv.insecureStorage);
268
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
269
- const { runOrgGet } = await import('./commands/organization.js');
270
- const apiKey = resolveApiKey({ apiKey: argv.apiKey });
271
- await runOrgGet(argv.orgId, apiKey, resolveApiBaseUrl());
644
+ .command('session', 'Manage user sessions', (yargs) => {
645
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
646
+ registerSubcommand(yargs, 'list <userId>', 'List sessions for a user', (y) => y.positional('userId', { type: 'string', demandOption: true }).options({
647
+ limit: { type: 'number' },
648
+ before: { type: 'string' },
649
+ after: { type: 'string' },
650
+ order: { type: 'string' },
651
+ }), async (argv) => {
652
+ await applyInsecureStorage(argv.insecureStorage);
653
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
654
+ const { runSessionList } = await import('./commands/session.js');
655
+ await runSessionList(argv.userId, { limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
656
+ });
657
+ registerSubcommand(yargs, 'revoke <sessionId>', 'Revoke a session', (y) => y.positional('sessionId', { type: 'string', demandOption: true }), async (argv) => {
658
+ await applyInsecureStorage(argv.insecureStorage);
659
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
660
+ const { runSessionRevoke } = await import('./commands/session.js');
661
+ await runSessionRevoke(argv.sessionId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
662
+ });
663
+ return yargs.demandCommand(1, 'Please specify a session subcommand').strict();
272
664
  })
273
- .command('list', 'List organizations', (yargs) => yargs.options({
274
- domain: { type: 'string', describe: 'Filter by domain' },
275
- limit: { type: 'number', describe: 'Limit number of results' },
276
- before: { type: 'string', describe: 'Cursor for results before a specific item' },
277
- after: { type: 'string', describe: 'Cursor for results after a specific item' },
278
- order: { type: 'string', describe: 'Order of results (asc or desc)' },
279
- }), async (argv) => {
280
- await applyInsecureStorage(argv.insecureStorage);
281
- const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
282
- const { runOrgList } = await import('./commands/organization.js');
283
- const apiKey = resolveApiKey({ apiKey: argv.apiKey });
284
- await runOrgList({ domain: argv.domain, limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, apiKey, resolveApiBaseUrl());
665
+ .command('connection', 'Manage SSO connections (read/delete)', (yargs) => {
666
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
667
+ registerSubcommand(yargs, 'list', 'List connections', (y) => y.options({
668
+ org: { type: 'string', describe: 'Filter by org ID' },
669
+ type: { type: 'string', describe: 'Filter by connection type' },
670
+ limit: { type: 'number' },
671
+ before: { type: 'string' },
672
+ after: { type: 'string' },
673
+ order: { type: 'string' },
674
+ }), async (argv) => {
675
+ await applyInsecureStorage(argv.insecureStorage);
676
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
677
+ const { runConnectionList } = await import('./commands/connection.js');
678
+ await runConnectionList({
679
+ organizationId: argv.org,
680
+ connectionType: argv.type,
681
+ limit: argv.limit,
682
+ before: argv.before,
683
+ after: argv.after,
684
+ order: argv.order,
685
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
686
+ });
687
+ registerSubcommand(yargs, 'get <id>', 'Get a connection', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
688
+ await applyInsecureStorage(argv.insecureStorage);
689
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
690
+ const { runConnectionGet } = await import('./commands/connection.js');
691
+ await runConnectionGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
692
+ });
693
+ registerSubcommand(yargs, 'delete <id>', 'Delete a connection', (y) => y.positional('id', { type: 'string', demandOption: true }).option('force', { type: 'boolean', default: false }), async (argv) => {
694
+ await applyInsecureStorage(argv.insecureStorage);
695
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
696
+ const { runConnectionDelete } = await import('./commands/connection.js');
697
+ await runConnectionDelete(argv.id, { force: argv.force }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
698
+ });
699
+ return yargs.demandCommand(1, 'Please specify a connection subcommand').strict();
700
+ })
701
+ .command('directory', 'Manage directory sync (read/delete, list users/groups)', (yargs) => {
702
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
703
+ registerSubcommand(yargs, 'list', 'List directories', (y) => y.options({
704
+ org: { type: 'string' },
705
+ limit: { type: 'number' },
706
+ before: { type: 'string' },
707
+ after: { type: 'string' },
708
+ order: { type: 'string' },
709
+ }), async (argv) => {
710
+ await applyInsecureStorage(argv.insecureStorage);
711
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
712
+ const { runDirectoryList } = await import('./commands/directory.js');
713
+ await runDirectoryList({ organizationId: argv.org, limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
714
+ });
715
+ registerSubcommand(yargs, 'get <id>', 'Get a directory', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
716
+ await applyInsecureStorage(argv.insecureStorage);
717
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
718
+ const { runDirectoryGet } = await import('./commands/directory.js');
719
+ await runDirectoryGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
720
+ });
721
+ registerSubcommand(yargs, 'delete <id>', 'Delete a directory', (y) => y.positional('id', { type: 'string', demandOption: true }).option('force', { type: 'boolean', default: false }), async (argv) => {
722
+ await applyInsecureStorage(argv.insecureStorage);
723
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
724
+ const { runDirectoryDelete } = await import('./commands/directory.js');
725
+ await runDirectoryDelete(argv.id, { force: argv.force }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
726
+ });
727
+ registerSubcommand(yargs, 'list-users', 'List directory users', (y) => y.options({
728
+ directory: { type: 'string' },
729
+ group: { type: 'string' },
730
+ limit: { type: 'number' },
731
+ before: { type: 'string' },
732
+ after: { type: 'string' },
733
+ }), async (argv) => {
734
+ await applyInsecureStorage(argv.insecureStorage);
735
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
736
+ const { runDirectoryListUsers } = await import('./commands/directory.js');
737
+ await runDirectoryListUsers({ directory: argv.directory, group: argv.group, limit: argv.limit, before: argv.before, after: argv.after }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
738
+ });
739
+ registerSubcommand(yargs, 'list-groups', 'List directory groups', (y) => y.options({
740
+ directory: { type: 'string', demandOption: true },
741
+ limit: { type: 'number' },
742
+ before: { type: 'string' },
743
+ after: { type: 'string' },
744
+ }), async (argv) => {
745
+ await applyInsecureStorage(argv.insecureStorage);
746
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
747
+ const { runDirectoryListGroups } = await import('./commands/directory.js');
748
+ await runDirectoryListGroups({ directory: argv.directory, limit: argv.limit, before: argv.before, after: argv.after }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
749
+ });
750
+ return yargs.demandCommand(1, 'Please specify a directory subcommand').strict();
751
+ })
752
+ .command('event', 'Query WorkOS events', (yargs) => {
753
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
754
+ registerSubcommand(yargs, 'list', 'List events', (y) => y.options({
755
+ events: { type: 'string', demandOption: true, describe: 'Comma-separated event types' },
756
+ after: { type: 'string' },
757
+ org: { type: 'string' },
758
+ 'range-start': { type: 'string' },
759
+ 'range-end': { type: 'string' },
760
+ limit: { type: 'number' },
761
+ }), async (argv) => {
762
+ await applyInsecureStorage(argv.insecureStorage);
763
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
764
+ const { runEventList } = await import('./commands/event.js');
765
+ await runEventList({
766
+ events: argv.events.split(','),
767
+ after: argv.after,
768
+ organizationId: argv.org,
769
+ rangeStart: argv.rangeStart,
770
+ rangeEnd: argv.rangeEnd,
771
+ limit: argv.limit,
772
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
773
+ });
774
+ return yargs.demandCommand(1, 'Please specify an event subcommand').strict();
775
+ })
776
+ .command('audit-log', 'Manage audit logs', (yargs) => {
777
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
778
+ registerSubcommand(yargs, 'create-event <orgId>', 'Create an audit log event', (y) => y.positional('orgId', { type: 'string', demandOption: true }).options({
779
+ action: { type: 'string' },
780
+ 'actor-type': { type: 'string' },
781
+ 'actor-id': { type: 'string' },
782
+ 'actor-name': { type: 'string' },
783
+ targets: { type: 'string' },
784
+ context: { type: 'string' },
785
+ metadata: { type: 'string' },
786
+ 'occurred-at': { type: 'string' },
787
+ file: { type: 'string' },
788
+ }), async (argv) => {
789
+ await applyInsecureStorage(argv.insecureStorage);
790
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
791
+ const { runAuditLogCreateEvent } = await import('./commands/audit-log.js');
792
+ await runAuditLogCreateEvent(argv.orgId, {
793
+ action: argv.action,
794
+ actorType: argv.actorType,
795
+ actorId: argv.actorId,
796
+ actorName: argv.actorName,
797
+ targets: argv.targets,
798
+ context: argv.context,
799
+ metadata: argv.metadata,
800
+ occurredAt: argv.occurredAt,
801
+ file: argv.file,
802
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
803
+ });
804
+ registerSubcommand(yargs, 'export', 'Export audit logs', (y) => y.options({
805
+ org: { type: 'string', demandOption: true },
806
+ 'range-start': { type: 'string', demandOption: true },
807
+ 'range-end': { type: 'string', demandOption: true },
808
+ actions: { type: 'string' },
809
+ 'actor-names': { type: 'string' },
810
+ 'actor-ids': { type: 'string' },
811
+ targets: { type: 'string' },
812
+ }), async (argv) => {
813
+ await applyInsecureStorage(argv.insecureStorage);
814
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
815
+ const { runAuditLogExport } = await import('./commands/audit-log.js');
816
+ await runAuditLogExport({
817
+ organizationId: argv.org,
818
+ rangeStart: argv.rangeStart,
819
+ rangeEnd: argv.rangeEnd,
820
+ actions: argv.actions?.split(','),
821
+ actorNames: argv.actorNames?.split(','),
822
+ actorIds: argv.actorIds?.split(','),
823
+ targets: argv.targets?.split(','),
824
+ }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
825
+ });
826
+ registerSubcommand(yargs, 'list-actions', 'List available audit log actions', (y) => y, async (argv) => {
827
+ await applyInsecureStorage(argv.insecureStorage);
828
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
829
+ const { runAuditLogListActions } = await import('./commands/audit-log.js');
830
+ await runAuditLogListActions(resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
831
+ });
832
+ registerSubcommand(yargs, 'get-schema <action>', 'Get schema for an audit log action', (y) => y.positional('action', { type: 'string', demandOption: true }), async (argv) => {
833
+ await applyInsecureStorage(argv.insecureStorage);
834
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
835
+ const { runAuditLogGetSchema } = await import('./commands/audit-log.js');
836
+ await runAuditLogGetSchema(argv.action, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
837
+ });
838
+ registerSubcommand(yargs, 'create-schema <action>', 'Create an audit log schema', (y) => y
839
+ .positional('action', { type: 'string', demandOption: true })
840
+ .option('file', { type: 'string', demandOption: true }), async (argv) => {
841
+ await applyInsecureStorage(argv.insecureStorage);
842
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
843
+ const { runAuditLogCreateSchema } = await import('./commands/audit-log.js');
844
+ await runAuditLogCreateSchema(argv.action, argv.file, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
845
+ });
846
+ registerSubcommand(yargs, 'get-retention <orgId>', 'Get audit log retention period', (y) => y.positional('orgId', { type: 'string', demandOption: true }), async (argv) => {
847
+ await applyInsecureStorage(argv.insecureStorage);
848
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
849
+ const { runAuditLogGetRetention } = await import('./commands/audit-log.js');
850
+ await runAuditLogGetRetention(argv.orgId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
851
+ });
852
+ return yargs.demandCommand(1, 'Please specify an audit-log subcommand').strict();
853
+ })
854
+ .command('feature-flag', 'Manage feature flags', (yargs) => {
855
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
856
+ registerSubcommand(yargs, 'list', 'List feature flags', (y) => y.options({
857
+ limit: { type: 'number' },
858
+ before: { type: 'string' },
859
+ after: { type: 'string' },
860
+ order: { type: 'string' },
861
+ }), async (argv) => {
862
+ await applyInsecureStorage(argv.insecureStorage);
863
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
864
+ const { runFeatureFlagList } = await import('./commands/feature-flag.js');
865
+ await runFeatureFlagList({ limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
866
+ });
867
+ registerSubcommand(yargs, 'get <slug>', 'Get a feature flag', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
868
+ await applyInsecureStorage(argv.insecureStorage);
869
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
870
+ const { runFeatureFlagGet } = await import('./commands/feature-flag.js');
871
+ await runFeatureFlagGet(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
872
+ });
873
+ registerSubcommand(yargs, 'enable <slug>', 'Enable a feature flag', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
874
+ await applyInsecureStorage(argv.insecureStorage);
875
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
876
+ const { runFeatureFlagEnable } = await import('./commands/feature-flag.js');
877
+ await runFeatureFlagEnable(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
878
+ });
879
+ registerSubcommand(yargs, 'disable <slug>', 'Disable a feature flag', (y) => y.positional('slug', { type: 'string', demandOption: true }), async (argv) => {
880
+ await applyInsecureStorage(argv.insecureStorage);
881
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
882
+ const { runFeatureFlagDisable } = await import('./commands/feature-flag.js');
883
+ await runFeatureFlagDisable(argv.slug, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
884
+ });
885
+ registerSubcommand(yargs, 'add-target <slug> <targetId>', 'Add a target to a feature flag', (y) => y
886
+ .positional('slug', { type: 'string', demandOption: true })
887
+ .positional('targetId', { type: 'string', demandOption: true }), async (argv) => {
888
+ await applyInsecureStorage(argv.insecureStorage);
889
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
890
+ const { runFeatureFlagAddTarget } = await import('./commands/feature-flag.js');
891
+ await runFeatureFlagAddTarget(argv.slug, argv.targetId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
892
+ });
893
+ registerSubcommand(yargs, 'remove-target <slug> <targetId>', 'Remove a target from a feature flag', (y) => y
894
+ .positional('slug', { type: 'string', demandOption: true })
895
+ .positional('targetId', { type: 'string', demandOption: true }), async (argv) => {
896
+ await applyInsecureStorage(argv.insecureStorage);
897
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
898
+ const { runFeatureFlagRemoveTarget } = await import('./commands/feature-flag.js');
899
+ await runFeatureFlagRemoveTarget(argv.slug, argv.targetId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
900
+ });
901
+ return yargs.demandCommand(1, 'Please specify a feature-flag subcommand').strict();
902
+ })
903
+ .command('webhook', 'Manage webhooks', (yargs) => {
904
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
905
+ registerSubcommand(yargs, 'list', 'List webhooks', (y) => y, async (argv) => {
906
+ await applyInsecureStorage(argv.insecureStorage);
907
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
908
+ const { runWebhookList } = await import('./commands/webhook.js');
909
+ await runWebhookList(resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
910
+ });
911
+ registerSubcommand(yargs, 'create', 'Create a webhook', (y) => y.options({
912
+ url: { type: 'string', demandOption: true },
913
+ events: { type: 'string', demandOption: true, describe: 'Comma-separated event types' },
914
+ }), async (argv) => {
915
+ await applyInsecureStorage(argv.insecureStorage);
916
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
917
+ const { runWebhookCreate } = await import('./commands/webhook.js');
918
+ await runWebhookCreate(argv.url, argv.events.split(','), resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
919
+ });
920
+ registerSubcommand(yargs, 'delete <id>', 'Delete a webhook', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
921
+ await applyInsecureStorage(argv.insecureStorage);
922
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
923
+ const { runWebhookDelete } = await import('./commands/webhook.js');
924
+ await runWebhookDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
925
+ });
926
+ return yargs.demandCommand(1, 'Please specify a webhook subcommand').strict();
285
927
  })
286
- .command('delete <orgId>', 'Delete an organization', (yargs) => yargs.positional('orgId', { type: 'string', demandOption: true, describe: 'Organization ID' }), async (argv) => {
928
+ .command('config', 'Manage WorkOS configuration (redirect URIs, CORS, homepage)', (yargs) => {
929
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
930
+ yargs.command('redirect', 'Manage redirect URIs', (yargs) => {
931
+ registerSubcommand(yargs, 'add <uri>', 'Add a redirect URI', (y) => y.positional('uri', { type: 'string', demandOption: true }), async (argv) => {
932
+ await applyInsecureStorage(argv.insecureStorage);
933
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
934
+ const { runConfigRedirectAdd } = await import('./commands/config.js');
935
+ await runConfigRedirectAdd(argv.uri, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
936
+ });
937
+ return yargs.demandCommand(1).strict();
938
+ });
939
+ yargs.command('cors', 'Manage CORS origins', (yargs) => {
940
+ registerSubcommand(yargs, 'add <origin>', 'Add a CORS origin', (y) => y.positional('origin', { type: 'string', demandOption: true }), async (argv) => {
941
+ await applyInsecureStorage(argv.insecureStorage);
942
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
943
+ const { runConfigCorsAdd } = await import('./commands/config.js');
944
+ await runConfigCorsAdd(argv.origin, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
945
+ });
946
+ return yargs.demandCommand(1).strict();
947
+ });
948
+ yargs.command('homepage-url', 'Manage homepage URL', (yargs) => {
949
+ registerSubcommand(yargs, 'set <url>', 'Set the homepage URL', (y) => y.positional('url', { type: 'string', demandOption: true }), async (argv) => {
950
+ await applyInsecureStorage(argv.insecureStorage);
951
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
952
+ const { runConfigHomepageUrlSet } = await import('./commands/config.js');
953
+ await runConfigHomepageUrlSet(argv.url, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
954
+ });
955
+ return yargs.demandCommand(1).strict();
956
+ });
957
+ return yargs.demandCommand(1, 'Please specify a config subcommand').strict();
958
+ })
959
+ .command('portal', 'Manage Admin Portal', (yargs) => {
960
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
961
+ registerSubcommand(yargs, 'generate-link', 'Generate an Admin Portal link', (y) => y.options({
962
+ intent: {
963
+ type: 'string',
964
+ demandOption: true,
965
+ describe: 'Portal intent (sso, dsync, audit_logs, log_streams)',
966
+ },
967
+ org: { type: 'string', demandOption: true, describe: 'Organization ID' },
968
+ 'return-url': { type: 'string' },
969
+ 'success-url': { type: 'string' },
970
+ }), async (argv) => {
971
+ await applyInsecureStorage(argv.insecureStorage);
972
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
973
+ const { runPortalGenerateLink } = await import('./commands/portal.js');
974
+ await runPortalGenerateLink({ intent: argv.intent, organization: argv.org, returnUrl: argv.returnUrl, successUrl: argv.successUrl }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
975
+ });
976
+ return yargs.demandCommand(1, 'Please specify a portal subcommand').strict();
977
+ })
978
+ .command('vault', 'Manage WorkOS Vault secrets', (yargs) => {
979
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
980
+ registerSubcommand(yargs, 'list', 'List vault objects', (y) => y.options({
981
+ limit: { type: 'number' },
982
+ before: { type: 'string' },
983
+ after: { type: 'string' },
984
+ order: { type: 'string' },
985
+ }), async (argv) => {
986
+ await applyInsecureStorage(argv.insecureStorage);
987
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
988
+ const { runVaultList } = await import('./commands/vault.js');
989
+ await runVaultList({ limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
990
+ });
991
+ registerSubcommand(yargs, 'get <id>', 'Get a vault object', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
992
+ await applyInsecureStorage(argv.insecureStorage);
993
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
994
+ const { runVaultGet } = await import('./commands/vault.js');
995
+ await runVaultGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
996
+ });
997
+ registerSubcommand(yargs, 'get-by-name <name>', 'Get a vault object by name', (y) => y.positional('name', { type: 'string', demandOption: true }), async (argv) => {
998
+ await applyInsecureStorage(argv.insecureStorage);
999
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1000
+ const { runVaultGetByName } = await import('./commands/vault.js');
1001
+ await runVaultGetByName(argv.name, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1002
+ });
1003
+ registerSubcommand(yargs, 'create', 'Create a vault object', (y) => y.options({
1004
+ name: { type: 'string', demandOption: true },
1005
+ value: { type: 'string', demandOption: true },
1006
+ org: { type: 'string' },
1007
+ }), async (argv) => {
1008
+ await applyInsecureStorage(argv.insecureStorage);
1009
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1010
+ const { runVaultCreate } = await import('./commands/vault.js');
1011
+ await runVaultCreate({ name: argv.name, value: argv.value, org: argv.org }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1012
+ });
1013
+ registerSubcommand(yargs, 'update <id>', 'Update a vault object', (y) => y
1014
+ .positional('id', { type: 'string', demandOption: true })
1015
+ .options({ value: { type: 'string', demandOption: true }, 'version-check': { type: 'string' } }), async (argv) => {
1016
+ await applyInsecureStorage(argv.insecureStorage);
1017
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1018
+ const { runVaultUpdate } = await import('./commands/vault.js');
1019
+ await runVaultUpdate({ id: argv.id, value: argv.value, versionCheck: argv.versionCheck }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1020
+ });
1021
+ registerSubcommand(yargs, 'delete <id>', 'Delete a vault object', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1022
+ await applyInsecureStorage(argv.insecureStorage);
1023
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1024
+ const { runVaultDelete } = await import('./commands/vault.js');
1025
+ await runVaultDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1026
+ });
1027
+ registerSubcommand(yargs, 'describe <id>', 'Describe a vault object', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1028
+ await applyInsecureStorage(argv.insecureStorage);
1029
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1030
+ const { runVaultDescribe } = await import('./commands/vault.js');
1031
+ await runVaultDescribe(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1032
+ });
1033
+ registerSubcommand(yargs, 'list-versions <id>', 'List vault object versions', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1034
+ await applyInsecureStorage(argv.insecureStorage);
1035
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1036
+ const { runVaultListVersions } = await import('./commands/vault.js');
1037
+ await runVaultListVersions(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1038
+ });
1039
+ return yargs.demandCommand(1, 'Please specify a vault subcommand').strict();
1040
+ })
1041
+ .command('api-key', 'Manage API keys', (yargs) => {
1042
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1043
+ registerSubcommand(yargs, 'list', 'List API keys', (y) => y.options({
1044
+ org: { type: 'string', demandOption: true },
1045
+ limit: { type: 'number' },
1046
+ before: { type: 'string' },
1047
+ after: { type: 'string' },
1048
+ order: { type: 'string' },
1049
+ }), async (argv) => {
1050
+ await applyInsecureStorage(argv.insecureStorage);
1051
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1052
+ const { runApiKeyList } = await import('./commands/api-key-mgmt.js');
1053
+ await runApiKeyList({ organizationId: argv.org, limit: argv.limit, before: argv.before, after: argv.after, order: argv.order }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1054
+ });
1055
+ registerSubcommand(yargs, 'create', 'Create an API key', (y) => y.options({
1056
+ org: { type: 'string', demandOption: true },
1057
+ name: { type: 'string', demandOption: true },
1058
+ permissions: { type: 'string', describe: 'Comma-separated permissions' },
1059
+ }), async (argv) => {
1060
+ await applyInsecureStorage(argv.insecureStorage);
1061
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1062
+ const { runApiKeyCreate } = await import('./commands/api-key-mgmt.js');
1063
+ await runApiKeyCreate({ organizationId: argv.org, name: argv.name, permissions: argv.permissions?.split(',') }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1064
+ });
1065
+ registerSubcommand(yargs, 'validate <value>', 'Validate an API key', (y) => y.positional('value', { type: 'string', demandOption: true }), async (argv) => {
1066
+ await applyInsecureStorage(argv.insecureStorage);
1067
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1068
+ const { runApiKeyValidate } = await import('./commands/api-key-mgmt.js');
1069
+ await runApiKeyValidate(argv.value, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1070
+ });
1071
+ registerSubcommand(yargs, 'delete <id>', 'Delete an API key', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1072
+ await applyInsecureStorage(argv.insecureStorage);
1073
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1074
+ const { runApiKeyDelete } = await import('./commands/api-key-mgmt.js');
1075
+ await runApiKeyDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1076
+ });
1077
+ return yargs.demandCommand(1, 'Please specify an api-key subcommand').strict();
1078
+ })
1079
+ .command('org-domain', 'Manage organization domains', (yargs) => {
1080
+ yargs.options({ ...insecureStorageOption, 'api-key': { type: 'string', describe: 'WorkOS API key' } });
1081
+ registerSubcommand(yargs, 'get <id>', 'Get a domain', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1082
+ await applyInsecureStorage(argv.insecureStorage);
1083
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1084
+ const { runOrgDomainGet } = await import('./commands/org-domain.js');
1085
+ await runOrgDomainGet(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1086
+ });
1087
+ registerSubcommand(yargs, 'create <domain>', 'Create a domain', (y) => y
1088
+ .positional('domain', { type: 'string', demandOption: true })
1089
+ .option('org', { type: 'string', demandOption: true }), async (argv) => {
1090
+ await applyInsecureStorage(argv.insecureStorage);
1091
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1092
+ const { runOrgDomainCreate } = await import('./commands/org-domain.js');
1093
+ await runOrgDomainCreate(argv.domain, argv.org, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1094
+ });
1095
+ registerSubcommand(yargs, 'verify <id>', 'Verify a domain', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1096
+ await applyInsecureStorage(argv.insecureStorage);
1097
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1098
+ const { runOrgDomainVerify } = await import('./commands/org-domain.js');
1099
+ await runOrgDomainVerify(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1100
+ });
1101
+ registerSubcommand(yargs, 'delete <id>', 'Delete a domain', (y) => y.positional('id', { type: 'string', demandOption: true }), async (argv) => {
1102
+ await applyInsecureStorage(argv.insecureStorage);
1103
+ const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1104
+ const { runOrgDomainDelete } = await import('./commands/org-domain.js');
1105
+ await runOrgDomainDelete(argv.id, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1106
+ });
1107
+ return yargs.demandCommand(1, 'Please specify an org-domain subcommand').strict();
1108
+ })
1109
+ // --- Workflow Commands ---
1110
+ .command('seed', 'Seed WorkOS environment from a YAML config file', (yargs) => yargs.options({
1111
+ ...insecureStorageOption,
1112
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
1113
+ file: { type: 'string', describe: 'Path to seed YAML file' },
1114
+ clean: { type: 'boolean', default: false, describe: 'Tear down seeded resources' },
1115
+ }), async (argv) => {
287
1116
  await applyInsecureStorage(argv.insecureStorage);
288
1117
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
289
- const { runOrgDelete } = await import('./commands/organization.js');
290
- const apiKey = resolveApiKey({ apiKey: argv.apiKey });
291
- await runOrgDelete(argv.orgId, apiKey, resolveApiBaseUrl());
1118
+ const { runSeed } = await import('./commands/seed.js');
1119
+ await runSeed({ file: argv.file, clean: argv.clean }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
292
1120
  })
293
- .demandCommand(1, 'Please specify an organization subcommand')
294
- .strict())
295
- .command('user', 'Manage users', (yargs) => yargs
296
- .options({
1121
+ .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({
297
1122
  ...insecureStorageOption,
298
- 'api-key': { type: 'string', describe: 'WorkOS API key (overrides environment config)' },
299
- })
300
- .command('get <userId>', 'Get a user by ID', (yargs) => yargs.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }), async (argv) => {
1123
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
1124
+ domain: { type: 'string', describe: 'Domain to add and verify' },
1125
+ roles: { type: 'string', describe: 'Comma-separated role slugs to create' },
1126
+ }), async (argv) => {
301
1127
  await applyInsecureStorage(argv.insecureStorage);
302
1128
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
303
- const { runUserGet } = await import('./commands/user.js');
304
- await runUserGet(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1129
+ const { runSetupOrg } = await import('./commands/setup-org.js');
1130
+ await runSetupOrg({ name: argv.name, domain: argv.domain, roles: argv.roles?.split(',') }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
305
1131
  })
306
- .command('list', 'List users', (yargs) => yargs.options({
307
- email: { type: 'string', describe: 'Filter by email' },
308
- organization: { type: 'string', describe: 'Filter by organization ID' },
309
- limit: { type: 'number', describe: 'Limit number of results' },
310
- before: { type: 'string', describe: 'Cursor for results before a specific item' },
311
- after: { type: 'string', describe: 'Cursor for results after a specific item' },
312
- order: { type: 'string', describe: 'Order of results (asc or desc)' },
1132
+ .command('onboard-user <email>', 'Onboard a user (send invitation, assign role)', (yargs) => yargs.positional('email', { type: 'string', demandOption: true }).options({
1133
+ ...insecureStorageOption,
1134
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
1135
+ org: { type: 'string', demandOption: true, describe: 'Organization ID' },
1136
+ role: { type: 'string', describe: 'Role slug to assign' },
1137
+ wait: { type: 'boolean', default: false, describe: 'Wait for invitation acceptance' },
313
1138
  }), async (argv) => {
314
1139
  await applyInsecureStorage(argv.insecureStorage);
315
1140
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
316
- const { runUserList } = await import('./commands/user.js');
317
- await runUserList({
318
- email: argv.email,
319
- organization: argv.organization,
320
- limit: argv.limit,
321
- before: argv.before,
322
- after: argv.after,
323
- order: argv.order,
324
- }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1141
+ const { runOnboardUser } = await import('./commands/onboard-user.js');
1142
+ await runOnboardUser({ email: argv.email, org: argv.org, role: argv.role, wait: argv.wait }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
325
1143
  })
326
- .command('update <userId>', 'Update a user', (yargs) => yargs.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }).options({
327
- 'first-name': { type: 'string', describe: 'First name' },
328
- 'last-name': { type: 'string', describe: 'Last name' },
329
- 'email-verified': { type: 'boolean', describe: 'Email verification status' },
330
- password: { type: 'string', describe: 'New password' },
331
- 'external-id': { type: 'string', describe: 'External ID' },
1144
+ .command('debug-sso <connectionId>', 'Diagnose SSO connection issues', (yargs) => yargs.positional('connectionId', { type: 'string', demandOption: true }).options({
1145
+ ...insecureStorageOption,
1146
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
332
1147
  }), async (argv) => {
333
1148
  await applyInsecureStorage(argv.insecureStorage);
334
1149
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
335
- const { runUserUpdate } = await import('./commands/user.js');
336
- await runUserUpdate(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), {
337
- firstName: argv.firstName,
338
- lastName: argv.lastName,
339
- emailVerified: argv.emailVerified,
340
- password: argv.password,
341
- externalId: argv.externalId,
342
- }, resolveApiBaseUrl());
1150
+ const { runDebugSso } = await import('./commands/debug-sso.js');
1151
+ await runDebugSso(argv.connectionId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
343
1152
  })
344
- .command('delete <userId>', 'Delete a user', (yargs) => yargs.positional('userId', { type: 'string', demandOption: true, describe: 'User ID' }), async (argv) => {
1153
+ .command('debug-sync <directoryId>', 'Diagnose directory sync issues', (yargs) => yargs.positional('directoryId', { type: 'string', demandOption: true }).options({
1154
+ ...insecureStorageOption,
1155
+ 'api-key': { type: 'string', describe: 'WorkOS API key' },
1156
+ }), async (argv) => {
345
1157
  await applyInsecureStorage(argv.insecureStorage);
346
1158
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
347
- const { runUserDelete } = await import('./commands/user.js');
348
- await runUserDelete(argv.userId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1159
+ const { runDebugSync } = await import('./commands/debug-sync.js');
1160
+ await runDebugSync(argv.directoryId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
349
1161
  })
350
- .demandCommand(1, 'Please specify a user subcommand')
351
- .strict())
352
- .command('install', 'Install WorkOS AuthKit into your project', (yargs) => yargs.options(installerOptions), withAuth(async (argv) => {
1162
+ .command('install', 'Install WorkOS AuthKit into your project (interactive framework detection and setup)', (yargs) => yargs.options(installerOptions), withAuth(async (argv) => {
353
1163
  const { handleInstall } = await import('./commands/install.js');
354
1164
  await handleInstall(argv);
355
1165
  }))
@@ -361,7 +1171,7 @@ yargs(hideBin(process.argv))
361
1171
  .command(['$0'], 'WorkOS AuthKit CLI', (yargs) => yargs.options(insecureStorageOption), async (argv) => {
362
1172
  // Non-TTY: show help
363
1173
  if (isNonInteractiveEnvironment()) {
364
- yargs(hideBin(process.argv)).showHelp();
1174
+ yargs(rawArgs).showHelp();
365
1175
  return;
366
1176
  }
367
1177
  // TTY: ask if user wants to run installer