Skip to content

feat: add zero-auth install flow with claim command#91

Draft
nicknisi wants to merge 12 commits intomainfrom
feat/one-shot-mode
Draft

feat: add zero-auth install flow with claim command#91
nicknisi wants to merge 12 commits intomainfrom
feat/one-shot-mode

Conversation

@nicknisi
Copy link
Member

@nicknisi nicknisi commented Mar 10, 2026

Summary

Implements one-shot mode — zero-friction workos install that works without prior authentication. When no credentials are found, the CLI silently provisions an "unclaimed" environment via the one-shot API, writes all credentials to .env.local, and proceeds with the install. Users can later link the environment to their WorkOS account via workos claim. Management commands on unclaimed environments show a non-blocking warning.

This is a 3-phase implementation from the one-shot-mode ideation contract:

  • Phase 1: One-shot API client (one-shot-api.ts) and config store type extension (unclaimed env type + claimToken)
  • Phase 2: Install flow credential resolution (resolveInstallCredentials), workos claim command with nonce-based browser auth + polling, env-writer CLAIM_TOKEN support, help-json registration
  • Phase 3: Unclaimed environment warning module (stderr-only, once-per-session dedup, JSON-mode suppression), env list (unclaimed) label, and claimed detection

What was tested

Automated

  • 1098 tests passing (68 new across 6 spec files)
  • pnpm typecheck — PASS
  • pnpm build — PASS
  • New test coverage:
    • one-shot-api.spec.ts — 22 tests (provisioning, claim initiation, claim polling, error handling)
    • one-shot-provision.spec.ts — 11 tests (happy path, API failure fallback, config store writes)
    • claim.spec.ts — 15 tests (nonce generation, browser open, polling, timeout, JSON mode)
    • unclaimed-warning.spec.ts — 12 tests (warning display, dedup, JSON suppression, claimed detection)
    • config-store.spec.ts — +13 tests (unclaimed type, claimToken field, type guard)
    • login.spec.ts — +8 tests (one-shot passthrough)

Manual

Full code review of all 17 changed files across 3 implementation commits. Each acceptance criterion verified against source code and tests:

  • One-shot provisioning is non-fatal (try/catch fallback to login flow)
  • Claim flow: nonce generation, browser open, 5-min polling with transient error resilience
  • Unclaimed warning: stderr-only, once-per-session dedup, JSON suppression, lazy claim detection, never-throw guarantee
  • Env list shows (unclaimed) label with hint to run workos claim
  • Management commands wired with maybeWarnUnclaimed() across 80+ command handlers

Key design decisions

  • Non-fatal provisioning: tryOneShotProvision() catches all errors and returns false, allowing seamless fallback to the existing ensureAuthenticated() login flow
  • Once-per-session warning: maybeWarnUnclaimed() uses a module-level flag to prevent repeated warnings across multiple commands in a session
  • JSON mode awareness: Warnings go to stderr only in human output mode; JSON output stays clean
  • Claim polling: 5-minute timeout with 2-second intervals, resilient to transient network errors during polling

Files changed (17)

File Change
src/lib/one-shot-api.ts New — API client for one-shot provisioning and claim
src/lib/one-shot-api.spec.ts New — 22 tests
src/lib/one-shot-provision.ts New — tryOneShotProvision() helper
src/lib/one-shot-provision.spec.ts New — 11 tests
src/lib/unclaimed-warning.ts New — warning module with claim detection
src/lib/unclaimed-warning.spec.ts New — 12 tests
src/commands/claim.ts New — workos claim command
src/commands/claim.spec.ts New — 15 tests
src/lib/config-store.ts Extended — unclaimed type, claimToken field
src/lib/config-store.spec.ts Extended — +13 tests
src/commands/login.ts Extended — one-shot passthrough
src/commands/login.spec.ts Extended — +8 tests
src/commands/env.ts Extended — unclaimed label in env list
src/lib/env-writer.ts Extended — CLAIM_TOKEN env var support
src/lib/run-with-core.ts Extended — maybeWarnUnclaimed() wiring
src/bin.ts Extended — resolveInstallCredentials(), claim command registration
src/utils/help-json.ts Extended — claim command in help registry

Follow-ups

  • env.spec.ts lacks tests for unclaimed label display in runEnvList — should be added
  • help-json.spec.ts does not explicitly verify claim command registration — should be added
  • Duplicate generateCookiePassword exists in one-shot-api.ts and env-writer.ts — consider extracting to a shared utility

Screenshots

Unclaimed environment created
capture_20260310_221758

Warning about taking actions on an unclaimed environment
capture_20260310_215811

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
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.
Copy link
Member Author

@nicknisi nicknisi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Findings

Warnings

  1. Missing test coverage for unclaimed label displayenv.spec.ts lacks tests for the (unclaimed) label in runEnvList (src/commands/env.ts:221-237). Consider adding tests that verify the label renders correctly for unclaimed environments.

  2. Missing test for claim command registrationhelp-json.spec.ts does not explicitly verify the claim command appears in the help registry (src/utils/help-json.ts:1037-1051). A targeted assertion would prevent silent regressions.

  3. Duplicate generateCookiePassword — The same function exists in both src/lib/one-shot-api.ts:196 and src/lib/env-writer.ts:45. Consider extracting to a shared utility module to reduce duplication.

Info

  1. False positive in .case-testedfail_indicators: 1 is a grep heuristic false positive; confirmed 1098/1098 tests passing.

  2. Pre-existing large filesrun-with-core.ts (541 lines) and help-json.ts (1259 lines) were already above the 300-line threshold; changes in this PR are minimal additions.

Automated review by case/reviewer agent

@nicknisi nicknisi changed the title feat(one-shot): add zero-auth install flow with claim command feat: add zero-auth install flow with claim command Mar 11, 2026
@nicknisi nicknisi marked this pull request as draft March 11, 2026 03:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant