workos 0.10.0 → 0.11.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 (48) hide show
  1. package/README.md +20 -1
  2. package/dist/bin.js +108 -20
  3. package/dist/bin.js.map +1 -1
  4. package/dist/commands/claim.d.ts +11 -0
  5. package/dist/commands/claim.js +111 -0
  6. package/dist/commands/claim.js.map +1 -0
  7. package/dist/commands/debug.d.ts +16 -0
  8. package/dist/commands/debug.js +350 -0
  9. package/dist/commands/debug.js.map +1 -0
  10. package/dist/commands/env.js +11 -4
  11. package/dist/commands/env.js.map +1 -1
  12. package/dist/commands/login.d.ts +8 -0
  13. package/dist/commands/login.js +41 -1
  14. package/dist/commands/login.js.map +1 -1
  15. package/dist/lib/__test-helpers__/mock-unclaimed-env-api-error.d.ts +7 -0
  16. package/dist/lib/__test-helpers__/mock-unclaimed-env-api-error.js +12 -0
  17. package/dist/lib/__test-helpers__/mock-unclaimed-env-api-error.js.map +1 -0
  18. package/dist/lib/agent-interface.js +17 -3
  19. package/dist/lib/agent-interface.js.map +1 -1
  20. package/dist/lib/config-store.d.ts +26 -3
  21. package/dist/lib/config-store.js +82 -0
  22. package/dist/lib/config-store.js.map +1 -1
  23. package/dist/lib/credential-proxy.d.ts +10 -1
  24. package/dist/lib/credential-proxy.js +96 -38
  25. package/dist/lib/credential-proxy.js.map +1 -1
  26. package/dist/lib/env-writer.d.ts +1 -0
  27. package/dist/lib/env-writer.js.map +1 -1
  28. package/dist/lib/installer-core.d.ts +3 -3
  29. package/dist/lib/resolve-install-credentials.d.ts +11 -0
  30. package/dist/lib/resolve-install-credentials.js +53 -0
  31. package/dist/lib/resolve-install-credentials.js.map +1 -0
  32. package/dist/lib/run-with-core.js +5 -0
  33. package/dist/lib/run-with-core.js.map +1 -1
  34. package/dist/lib/unclaimed-env-api.d.ts +42 -0
  35. package/dist/lib/unclaimed-env-api.js +139 -0
  36. package/dist/lib/unclaimed-env-api.js.map +1 -0
  37. package/dist/lib/unclaimed-env-provision.d.ts +24 -0
  38. package/dist/lib/unclaimed-env-provision.js +77 -0
  39. package/dist/lib/unclaimed-env-provision.js.map +1 -0
  40. package/dist/lib/unclaimed-warning.d.ts +15 -0
  41. package/dist/lib/unclaimed-warning.js +74 -0
  42. package/dist/lib/unclaimed-warning.js.map +1 -0
  43. package/dist/utils/box.d.ts +5 -0
  44. package/dist/utils/box.js +14 -0
  45. package/dist/utils/box.js.map +1 -0
  46. package/dist/utils/help-json.js +15 -0
  47. package/dist/utils/help-json.js.map +1 -1
  48. package/package.json +1 -1
package/README.md CHANGED
@@ -50,6 +50,7 @@ workos [command]
50
50
 
51
51
  Commands:
52
52
  install Install WorkOS AuthKit into your project
53
+ claim Claim an unclaimed environment (link to your account)
53
54
  auth Manage authentication (login, logout, status)
54
55
  env Manage environment configurations
55
56
  doctor Diagnose WorkOS integration issues
@@ -85,6 +86,24 @@ Workflows:
85
86
 
86
87
  All management commands support `--json` for structured output (auto-enabled in non-TTY) and `--api-key` to override the active environment's key.
87
88
 
89
+ ### Unclaimed Environments
90
+
91
+ When you run `workos install` without credentials, the CLI automatically provisions a temporary WorkOS environment — no account needed. This lets you try AuthKit immediately.
92
+
93
+ ```bash
94
+ # Install with zero setup — environment provisioned automatically
95
+ workos install
96
+
97
+ # Check your environment
98
+ workos env list
99
+ # Shows: unclaimed (unclaimed) ← active
100
+
101
+ # Claim the environment to link it to your WorkOS account
102
+ workos claim
103
+ ```
104
+
105
+ Management commands work on unclaimed environments with a warning reminding you to claim.
106
+
88
107
  ### Workflows
89
108
 
90
109
  The compound workflow commands compose multiple API calls into common operations. These are the highest-value commands for both developers and AI agents.
@@ -483,7 +502,7 @@ OAuth credentials are stored in the system keychain (with `~/.workos/credentials
483
502
  ## How It Works
484
503
 
485
504
  1. **Detects** your framework and project structure
486
- 2. **Prompts** for WorkOS credentials (API key masked)
505
+ 2. **Resolves credentials** uses existing config, or auto-provisions an unclaimed environment if none found
487
506
  3. **Auto-configures** WorkOS dashboard (redirect URI, CORS, homepage URL)
488
507
  4. **Fetches** latest SDK documentation from workos.com
489
508
  5. **Uses AI** (Claude) to generate integration code
package/dist/bin.js CHANGED
@@ -45,6 +45,12 @@ async function applyInsecureStorage(insecureStorage) {
45
45
  setInsecureConfigStorage(true);
46
46
  }
47
47
  }
48
+ /** Show non-blocking warning if active env is unclaimed (once per session). */
49
+ async function maybeWarnUnclaimed() {
50
+ const { warnIfUnclaimed } = await import('./lib/unclaimed-warning.js');
51
+ await warnIfUnclaimed();
52
+ }
53
+ import { resolveInstallCredentials } from './lib/resolve-install-credentials.js';
48
54
  /** Shared insecure-storage option for commands that access credentials */
49
55
  const insecureStorageOption = {
50
56
  'insecure-storage': {
@@ -53,20 +59,6 @@ const insecureStorageOption = {
53
59
  type: 'boolean',
54
60
  },
55
61
  };
56
- /**
57
- * Wrap a command handler with authentication check.
58
- * Ensures valid auth before executing the handler.
59
- * Respects --skip-auth flag for CI/testing.
60
- */
61
- function withAuth(handler) {
62
- return async (argv) => {
63
- const typedArgv = argv;
64
- await applyInsecureStorage(typedArgv.insecureStorage);
65
- if (!typedArgv.skipAuth)
66
- await ensureAuthenticated();
67
- await handler(argv);
68
- };
69
- }
70
62
  const installerOptions = {
71
63
  direct: {
72
64
  alias: 'D',
@@ -173,6 +165,16 @@ yargs(rawArgs)
173
165
  default: false,
174
166
  describe: 'Output results as JSON (auto-enabled in non-TTY)',
175
167
  global: true,
168
+ })
169
+ .middleware(async (argv) => {
170
+ // Warn about unclaimed environments before management commands.
171
+ // Excluded: auth/claim/install/dashboard handle their own credential flows;
172
+ // skills/doctor/env/debug are utility commands where the warning is unnecessary.
173
+ const command = String(argv._?.[0] ?? '');
174
+ if (['auth', 'skills', 'doctor', 'env', 'claim', 'install', 'debug', 'dashboard', ''].includes(command))
175
+ return;
176
+ await applyInsecureStorage(argv.insecureStorage);
177
+ await maybeWarnUnclaimed();
176
178
  })
177
179
  .command('auth', 'Manage authentication (login, logout, status)', (yargs) => {
178
180
  yargs.options(insecureStorageOption);
@@ -1194,15 +1196,102 @@ yargs(rawArgs)
1194
1196
  const { runDebugSync } = await import('./commands/debug-sync.js');
1195
1197
  await runDebugSync(argv.directoryId, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1196
1198
  })
1197
- .command('install', 'Install WorkOS AuthKit into your project (interactive framework detection and setup)', (yargs) => yargs.options(installerOptions), withAuth(async (argv) => {
1199
+ .command('claim', 'Claim an unclaimed WorkOS environment (link it to your account)', (yargs) => yargs.options({
1200
+ ...insecureStorageOption,
1201
+ }), async (argv) => {
1202
+ await applyInsecureStorage(argv.insecureStorage);
1203
+ const { runClaim } = await import('./commands/claim.js');
1204
+ await runClaim();
1205
+ })
1206
+ .command('install', 'Install WorkOS AuthKit into your project (interactive framework detection and setup)', (yargs) => yargs.options(installerOptions), async (argv) => {
1207
+ await applyInsecureStorage(argv.insecureStorage);
1208
+ await resolveInstallCredentials(argv.apiKey, argv.installDir, argv.skipAuth, ensureAuthenticated);
1198
1209
  const { handleInstall } = await import('./commands/install.js');
1199
1210
  await handleInstall(argv);
1200
- }))
1211
+ })
1212
+ .command('debug', false, (yargs) => {
1213
+ yargs.options(insecureStorageOption);
1214
+ registerSubcommand(yargs, 'state', 'Dump raw CLI state (credentials, config, storage)', (y) => y.option('show-secrets', {
1215
+ type: 'boolean',
1216
+ default: false,
1217
+ describe: 'Show unredacted tokens and API keys',
1218
+ }), async (argv) => {
1219
+ await applyInsecureStorage(argv.insecureStorage);
1220
+ const { runDebugState } = await import('./commands/debug.js');
1221
+ await runDebugState({ showSecrets: argv.showSecrets });
1222
+ });
1223
+ registerSubcommand(yargs, 'reset', 'Clear auth state (keyring + files)', (y) => y
1224
+ .option('force', {
1225
+ type: 'boolean',
1226
+ default: false,
1227
+ describe: 'Skip confirmation prompt',
1228
+ })
1229
+ .option('credentials-only', {
1230
+ type: 'boolean',
1231
+ default: false,
1232
+ describe: 'Only clear credentials',
1233
+ })
1234
+ .option('config-only', {
1235
+ type: 'boolean',
1236
+ default: false,
1237
+ describe: 'Only clear config',
1238
+ }), async (argv) => {
1239
+ await applyInsecureStorage(argv.insecureStorage);
1240
+ const { runDebugReset } = await import('./commands/debug.js');
1241
+ await runDebugReset({
1242
+ force: argv.force,
1243
+ credentialsOnly: argv.credentialsOnly,
1244
+ configOnly: argv.configOnly,
1245
+ });
1246
+ });
1247
+ registerSubcommand(yargs, 'simulate', 'Simulate CLI states for testing', (y) => y
1248
+ .option('expired-token', {
1249
+ type: 'boolean',
1250
+ default: false,
1251
+ describe: 'Set token expiresAt to the past',
1252
+ })
1253
+ .option('no-keyring', {
1254
+ type: 'boolean',
1255
+ default: false,
1256
+ describe: 'Force file-only storage mode',
1257
+ })
1258
+ .option('unclaimed', {
1259
+ type: 'boolean',
1260
+ default: false,
1261
+ describe: 'Write synthetic unclaimed environment',
1262
+ })
1263
+ .option('no-auth', {
1264
+ type: 'boolean',
1265
+ default: false,
1266
+ describe: 'Clear credentials, keep config',
1267
+ }), async (argv) => {
1268
+ await applyInsecureStorage(argv.insecureStorage);
1269
+ const { runDebugSimulate } = await import('./commands/debug.js');
1270
+ await runDebugSimulate({
1271
+ expiredToken: argv.expiredToken,
1272
+ noKeyring: argv.noKeyring,
1273
+ unclaimed: argv.unclaimed,
1274
+ noAuth: argv.noAuth,
1275
+ });
1276
+ });
1277
+ registerSubcommand(yargs, 'env', 'Show WORKOS_* environment variables and their effects', (y) => y, async () => {
1278
+ const { runDebugEnv } = await import('./commands/debug.js');
1279
+ await runDebugEnv();
1280
+ });
1281
+ registerSubcommand(yargs, 'token', 'Decode and inspect the current access token', (y) => y, async (argv) => {
1282
+ await applyInsecureStorage(argv.insecureStorage);
1283
+ const { runDebugToken } = await import('./commands/debug.js');
1284
+ await runDebugToken();
1285
+ });
1286
+ return yargs.demandCommand(1, 'Run "workos debug <command>" for debug tools.').strict();
1287
+ })
1201
1288
  .command('dashboard', false, // hidden from help
1202
- (yargs) => yargs.options(installerOptions), withAuth(async (argv) => {
1289
+ (yargs) => yargs.options(installerOptions), async (argv) => {
1290
+ await applyInsecureStorage(argv.insecureStorage);
1291
+ await resolveInstallCredentials(argv.apiKey, argv.installDir, argv.skipAuth, ensureAuthenticated);
1203
1292
  const { handleInstall } = await import('./commands/install.js');
1204
1293
  await handleInstall({ ...argv, dashboard: true });
1205
- }))
1294
+ })
1206
1295
  .command(['$0'], 'WorkOS AuthKit CLI', (yargs) => yargs.options(insecureStorageOption), async (argv) => {
1207
1296
  // Non-TTY: show help
1208
1297
  if (isNonInteractiveEnvironment()) {
@@ -1216,9 +1305,8 @@ yargs(rawArgs)
1216
1305
  if (clack.isCancel(shouldInstall) || !shouldInstall) {
1217
1306
  process.exit(0);
1218
1307
  }
1219
- // Auth check happens HERE, after user confirms
1220
1308
  await applyInsecureStorage(argv.insecureStorage);
1221
- await ensureAuthenticated();
1309
+ await resolveInstallCredentials(undefined, undefined, false, ensureAuthenticated);
1222
1310
  const { handleInstall } = await import('./commands/install.js');
1223
1311
  await handleInstall({ ...argv, dashboard: false });
1224
1312
  process.exit(0);