Skip to content

Commit d1b0039

Browse files
authored
feat: add zero-auth install flow with claim command (#91)
* feat(one-shot): add one-shot API client and config store type extension Phase 1 core infrastructure for one-shot mode: - One-shot provisioning API client (provisionOneShotEnvironment) - Claim nonce API client (createClaimNonce) - Cookie password generator (generateCookiePassword) - OneShotApiError with status code, timeout, rate limit handling - Config store: add unclaimed environment type and claimToken field - isUnclaimedEnvironment() helper - 30 new tests covering all API scenarios and config round-trips * feat(one-shot): add install flow credential resolution and claim command * feat(one-shot): add unclaimed environment warning and env list label Add warnIfUnclaimed() module that shows a non-blocking stderr warning when management commands run against an unclaimed environment. Lazily checks claimed status via createClaimNonce() once per session and auto-upgrades config when claimed. Wired into all management command handlers in bin.ts. Updated env list to show (unclaimed) label. * chore: remove case files * chore: run formatter on one-shot mode files * fix(one-shot): send snake_case fields to claim-nonces endpoint * fix(one-shot): make unclaimed environment warning more visible * refactor: rename one-shot to unclaimed-env throughout codebase * chore: remove unused withAuth function * docs: add unclaimed environments and claim command to README * fix: use green box for provisioning success message * refactor: simplify unclaimed env code — dedupe utilities, remove network call from warning * fix: handle 409 as claimed status, handle 401 as invalid/expired token - unclaimed-env-api: treat HTTP 409 as alreadyClaimed (not generic error) - claim command: detect 401 in polling loop, clean up and exit - unclaimed-warning: re-add lazy claim check to detect external claims, handle 401 by removing stale claim token * feat(auth): add claim token proxy for unclaimed environment gateway auth Start a lightweight proxy that injects x-workos-claim-token and x-workos-client-id headers when the active environment is unclaimed. This allows the installer's AI agent to authenticate with the LLM gateway without OAuth tokens. * fix(claim): don't block on browser open — use wait: false for opn * fix(install): detect missing gateway auth after claiming — prompt login instead of re-provisioning * feat: add hidden `debug` command for developer-facing CLI introspection Subcommands: state (dump raw credentials/config/storage), reset (clear auth state), simulate (write real state for edge-case testing), token (decode JWT claims). Hidden from --help, supports --json output mode. * chore: formatting: * feat(debug): add `env` subcommand — show WORKOS_* env vars and their effects * chore: formatting: * refactor: dedupe proxy helpers and move unclaimed warning to yargs middleware - Extract HOP_BY_HOP_HEADERS, filterHeaders(), buildUpstreamPath() in credential-proxy.ts — eliminates duplicate header/URL logic between startCredentialProxy and startClaimTokenProxy - Replace 82 individual maybeWarnUnclaimed() calls in bin.ts with a single yargs middleware (excludes auth/claim/install/debug/env/skills/doctor) - Add change-detection guard in markEnvironmentClaimed() to skip redundant filesystem writes on already-claimed environments * fix: config persistence across processes and improve debug diagnostics - saveConfig() now verifies keyring writes with immediate read-back, falling back to file if the keyring entry isn't readable - Provisioning verifies config persisted after save - debug state shows separate Storage sections for credentials and config, each with their own keyring/file diagnostics - markEnvironmentClaimed() renames env key from 'unclaimed' to 'sandbox' - Claim success now prompts user to run `workos auth login` * docs: update README to reflect zero-auth credential resolution * fix: improve type safety, error handling, and exit codes across unclaimed flow - Split EnvironmentConfig into discriminated union (ClaimedEnvironmentConfig | UnclaimedEnvironmentConfig) with required clientId/claimToken on unclaimed variant, eliminating 4 redundant null checks across the codebase - Make isUnclaimedEnvironment a proper type predicate (env is UnclaimedEnvironmentConfig) - Refactor markEnvironmentClaimed to construct new object instead of mutating + deleting fields - Add logError to outer catch in unclaimed-warning (never-throw preserved) - Surface user-facing message when browser open fails in claim command - Differentiate API vs filesystem errors in tryProvisionUnclaimedEnv - Return false on config read-back failure instead of continuing as success - Add configSource to debug state JSON output for parity with human mode - Use exitWithError in claim command for proper exit code 1 on failures - Remove redundant --json option on claim command (inherited from global) * fix: address PR review suggestions for unclaimed flow - Track consecutive poll failures in claim command and update spinner message after 3+ failures to surface connection issues to user - Fix credential-proxy module comment ("from file" -> "into upstream requests") and soften claim token expiry assumption - Remove vestigial comment in debug.ts that described old approach - Extract MockUnclaimedEnvApiError to shared test helper to deduplicate identical classes in claim.spec.ts and unclaimed-warning.spec.ts - Extract resolveInstallCredentials from bin.ts to standalone module with 10 unit tests covering the full credential resolution priority chain (env var > flag > unclaimed > OAuth > provision > login) * fix: address PR review — error handling, type safety, and test coverage - Reorder .env.local write before config save to prevent orphaned config entries on filesystem failure - Add MAX_CONSECUTIVE_FAILURES (10) cap to claim polling loop for early exit instead of burning full 5-minute timeout - Prevent markEnvironmentClaimed from overwriting existing sandbox env - Add logging for non-401 errors in warnIfUnclaimed claim check - Log browser open errors in claim command for diagnostics - Wrap resolveInstallCredentials in try-catch with contextual logging - Replace || with ?? for camelCase/snake_case API field resolution - Add dashboard and default command to middleware exclusion list - Correct RFC citation (2616 → 7230 §6.1) for hop-by-hop headers - Add 9 tests: 401 poll auto-claim, 401 warning promotion, 409 conflict, consecutive failure cap, spinner message, browser open failure, config read-back failure, non-unclaimed no-op, sandbox key collision - Fix exitWithError mock to throw (matches debug.spec.ts pattern) - Add message method to spinner mock * chore: formatting
1 parent 833422c commit d1b0039

25 files changed

Lines changed: 3517 additions & 77 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,6 @@ tests/eval-results/
3636

3737
# Local ideation artifacts
3838
docs/
39+
40+
# Case harness markers
41+
.case-*

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ workos [command]
5050

5151
Commands:
5252
install Install WorkOS AuthKit into your project
53+
claim Claim an unclaimed environment (link to your account)
5354
auth Manage authentication (login, logout, status)
5455
env Manage environment configurations
5556
doctor Diagnose WorkOS integration issues
@@ -85,6 +86,24 @@ Workflows:
8586

8687
All management commands support `--json` for structured output (auto-enabled in non-TTY) and `--api-key` to override the active environment's key.
8788

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+
88107
### Workflows
89108

90109
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
483502
## How It Works
484503

485504
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
487506
3. **Auto-configures** WorkOS dashboard (redirect URI, CORS, homepage URL)
488507
4. **Fetches** latest SDK documentation from workos.com
489508
5. **Uses AI** (Claude) to generate integration code

src/bin.ts

Lines changed: 228 additions & 20 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)