Skip to content

Conversation

@mguttmann
Copy link

Summary

Automatically refresh expired Anthropic OAuth tokens using persistent browser sessions with Puppeteer + Stealth plugin. This eliminates the need for manual re-authentication when tokens expire overnight.

Closes #9360

Problem

When using Anthropic OAuth (Claude Max subscription), tokens expire after a few hours. The refresh token also expires, causing "Token refresh failed: 400" errors. Users had to manually run opencode auth again each morning.

Solution

This PR adds automatic re-login via headless browser sessions:

  1. One-time setup: User runs opencode auth browser setup which opens a browser window
  2. User logs in: Authenticates with claude.ai (the cookies are saved)
  3. Auto-refresh: When tokens expire, a headless browser automatically:
    • Navigates to the OAuth authorize URL
    • Uses saved cookies to auto-authenticate
    • Clicks "Authorize" button automatically
    • Extracts new tokens and updates the auth store
    • Retries the failed request seamlessly

Features

CLI Commands

  • opencode auth browser setup - Configure browser session for an account
  • opencode auth browser status - Show status of all browser sessions
  • opencode auth browser remove - Remove a browser session

Technical Implementation

  • Puppeteer + Stealth: Uses puppeteer-extra-plugin-stealth to bypass Cloudflare bot detection
  • Auto-install: Puppeteer is automatically installed on first use
  • Isolated profiles: Each OAuth account has its own browser profile (cookies isolated)
  • Profile locking: Prevents concurrent browser operations on same profile
  • Dual callback support: Handles both console.anthropic.com and platform.claude.com OAuth callbacks

Error Handling

  • Detects "Token refresh failed: 400" errors in rotating-fetch.ts
  • Attempts auto-relogin before failing over to next account
  • Shows toast notifications for refresh status
  • Falls back gracefully if browser session is not configured

Files Changed

File Description
auth/browser.ts New - Puppeteer browser session management
auth/rotating-fetch.ts Token refresh error detection + auto-relogin trigger
auth/index.ts Added updateRecord() for token updates
cli/cmd/auth.ts CLI commands for browser session management
server/routes/provider.ts API endpoints for browser sessions
dialog-settings.tsx Desktop UI showing browser session status
package.json Puppeteer as optional dependency

Dependencies

Added as optional dependencies (only installed when needed):

  • puppeteer: ^24.9.0
  • puppeteer-extra: ^3.3.6
  • puppeteer-extra-plugin-stealth: ^2.11.2

Testing

  1. Run opencode auth browser setup and log in
  2. Invalidate token manually or wait for expiration
  3. Send a message - auto-relogin should trigger automatically
  4. Token refreshes seamlessly without user interaction

Screenshots

(Screenshots to be added by @mguttmann)

@github-actions
Copy link
Contributor

The following comment was made by an LLM, it may be inaccurate:

No duplicate PRs found

gwizz and others added 15 commits January 21, 2026 22:36
Non-network errors seen in logs:

- AI_APICallError (402 deactivated_workspace)

- AI_APICallError (500 server_error)

- AI_LoadAPIKeyError / OpenAI API key is missing

- ProviderInitError

- ConfigInvalidError

- ProviderAuthOauthCallbackFailed

- NotFoundError

- EditBuffer is destroyed
- Add getUsage() to fetch OAuth account status and health
- Add fetchAnthropicUsage() to fetch Claude Max rate limits from Anthropic API
- Add GET /auth/usage endpoint to expose usage data
- Add DialogAuthUsage component with rate limit visualization
- Display Anthropic 5-hour and 7-day limits with progress bars
- Show OAuth account status, cooldown state, and request counts
- Add button in sidebar to open the dialog
- Add AuthUsageCommand to display rate limit info in terminal
- Show account status, cooldown state, and request counts
- Display Anthropic rate limits when available
The AI SDK's convertToModelMessages() does not accept 'step-start' as a valid
UIMessagePart type. This caused AI_InvalidPromptError during session compaction.

- Remove step-start from being added to UIMessage parts
- Simplify the filter since step-start is no longer included
- Fixes compaction breaking sessions with context overflow
Implements comprehensive multi-account OAuth support with automatic rate limit
rotation, manual account switching, and a new Settings menu for the desktop app.

- Add `Auth.OAuthPool.setActive()` to manually switch active OAuth account
- Add `Auth.OAuthPool.snapshot()` returns `activeID` for credential selection
- Update `rotating-fetch.ts` to prefer `activeID` while keeping auto-rotation
- Update `fetchAnthropicUsage()` to respect `provider.active[namespace]`
- Update `getAccounts()` to correctly identify active account

- Add `POST /auth/active` endpoint to switch active OAuth account
- Returns updated `anthropicUsage` for immediate UI updates

- New `DialogSettings` component with tabbed interface
- **Providers Tab**: View connected providers, add new providers with search
- **Provider Detail View**: Account list, usage stats, switch functionality
- **About Tab**: GitHub, docs, Discord links, keyboard shortcuts
- Inline provider search without leaving settings context

- Add Anthropic Rate Limits section in session context panel
- Shows 5-hour, weekly (all models), weekly (sonnet) usage bars
- Account switch buttons when multiple accounts configured
- Only visible when current session uses Anthropic provider

- `opencode auth usage`: Shows individual usage per OAuth account
- `opencode auth switch`: Interactive command to switch active account
- `opencode auth list`: Shows account count per provider
- All provider lists now sorted alphabetically

- `packages/opencode/src/auth/index.ts`: Core OAuth pool functions
- `packages/opencode/src/auth/rotating-fetch.ts`: Credential selection
- `packages/opencode/src/server/server.ts`: API endpoint
- `packages/opencode/src/cli/cmd/auth.ts`: CLI commands
- `packages/app/src/components/dialog-settings.tsx`: New settings UI
- `packages/app/src/components/session/session-context-tab.tsx`: Context panel
- `packages/app/src/pages/layout.tsx`: Settings button integration

1. Request uses `activeID` (manually selected or first available)
2. On 429 rate limit → account gets cooldown, moved to back
3. Next request automatically uses next available account
4. Manual switch via UI/CLI updates `provider.active[namespace]`

Currently only Anthropic provides OAuth usage statistics.
Other providers show multi-account switching but no usage bars.
Contributions welcome for additional provider support.
- Add Auth.OAuthPool.removeRecord() to remove individual OAuth accounts
- Add DELETE /auth/account API endpoint for Desktop app
- Update CLI 'opencode auth logout' to select specific accounts
- Add delete button with confirmation in Desktop Provider settings
- Move auth endpoints to provider routes
- Add delete account functionality to dialog-auth-usage
- Fix duplicate imports in layout.tsx
- Fix message-v2.ts convertToModelMessages call
- Regenerate SDK types
@mguttmann mguttmann force-pushed the feat/auto-relogin-browser-sessions-clean branch from a88f9a5 to 9f73bcd Compare January 21, 2026 21:51
@mguttmann
Copy link
Author

Rebased onto latest dev (v1.1.30+) and restructured to build on top of my other PRs:

Branch chain: dev <- feat/multi-account-oauth-rotation-and-settings (#9069) <- feat/yolo-mode (#9073) <- feat/auto-relogin-browser-sessions-clean (this PR)

Changes in this update:

  • Added OAuthPool.updateRecord() to packages/opencode/src/auth/index.ts for persisting refreshed tokens
  • Browser session endpoints now at /provider/auth/browser/* to match the new modular provider routes
  • Integrated with rotating-fetch to trigger auto-relogin on 401 responses
  • Added CLI commands: opencode auth browser setup, status, refresh

Files added/modified:

  • packages/opencode/src/auth/browser.ts - Puppeteer browser session management
  • packages/opencode/src/auth/rotating-fetch.ts - Auto-relogin integration
  • packages/opencode/src/cli/cmd/auth.ts - AuthBrowserCommand
  • packages/opencode/src/server/routes/provider.ts - Browser session API endpoints
  • packages/opencode/src/auth/index.ts - Added updateRecord() function

Build and typecheck pass. Ready for review!

Claude Agent added 4 commits January 21, 2026 22:57
- Add browser.ts for Puppeteer-based browser session management
- Add rotating-fetch.ts integration with auto-relogin trigger on 401s
- Add AuthBrowserCommand CLI for setup/status/refresh operations
- Add /provider/auth/browser/* API endpoints for browser session control
- Add OAuthPool.updateRecord() to persist refreshed tokens
@mguttmann
Copy link
Author

Update: Rebased onto latest dev (v1.1.30+)

Branch has been rebased onto the updated #9069 (Multi-Account OAuth).

Structure:

origin/dev
    └── #9069 Multi-Account OAuth
            └── #9455 Auto-Relogin (this PR)

Note: This PR is independent of #9073 (YOLO Mode) - they are sibling branches that can be merged separately.

Features:

  • Persistent browser sessions for automatic token refresh
  • One-time setup: opencode auth browser setup
  • Automatic re-authentication on 401 errors (headless)
  • CLI commands: opencode auth browser [setup|status|refresh|remove]
  • API endpoints: /provider/auth/browser/*

How it works:

  1. User runs opencode auth browser setup → browser opens → login to claude.ai
  2. Browser profile saved to ~/.opencode/browsers/anthropic/<account-id>/
  3. On 401 error: headless browser launches with saved profile → auto-redirects through OAuth → new tokens saved

Files:

  • packages/opencode/src/auth/browser.ts - Puppeteer browser session management
  • packages/opencode/src/auth/rotating-fetch.ts - Auto-relogin integration
  • packages/opencode/src/cli/cmd/auth.ts - Browser CLI commands
  • packages/opencode/src/server/routes/provider.ts - Browser API endpoints

Typecheck passes ✅ | Build passes ✅

Depends on #9069 being merged first.

- Add browser session management UI
- Setup/Test/Remove buttons per account
- Show last refresh time
- Automatic token refresh via headless browser
- Integration with auth.usage command
@mguttmann
Copy link
Author

Closing in favor of combined PR with all features (Multi-Account, YOLO Mode, Auto-Relogin)

@mguttmann mguttmann closed this Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Auto-Relogin for Anthropic OAuth via Persistent Browser Sessions

1 participant