Commit d1b0039
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: formatting1 parent 833422c commit d1b0039
25 files changed
Lines changed: 3517 additions & 77 deletions
File tree
- src
- commands
- lib
- __test-helpers__
- utils
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| 53 | + | |
53 | 54 | | |
54 | 55 | | |
55 | 56 | | |
| |||
85 | 86 | | |
86 | 87 | | |
87 | 88 | | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
88 | 107 | | |
89 | 108 | | |
90 | 109 | | |
| |||
483 | 502 | | |
484 | 503 | | |
485 | 504 | | |
486 | | - | |
| 505 | + | |
487 | 506 | | |
488 | 507 | | |
489 | 508 | | |
| |||
Large diffs are not rendered by default.
0 commit comments