- Add /login and /logout commands for OAuth flow - OAuth tokens stored in ~/.pi/agent/oauth.json with 0600 permissions - Auto-refresh tokens when expired (5min buffer) - Priority: OAuth > ANTHROPIC_OAUTH_TOKEN env > ANTHROPIC_API_KEY env - Fix model selector async loading and re-render - Add bracketed paste support to Input component for long codes - Update README.md with OAuth documentation - Add implementation docs and testing checklist
5.8 KiB
OAuth Testing Checklist
Manual Testing Guide
Prerequisites
- You need a Claude Pro or Claude Max subscription
- A web browser for OAuth authorization
Test 1: Basic Login Flow
-
Start pi in interactive mode:
pi -
Type
/loginand press Enter -
Expected: OAuth provider selector appears showing "Anthropic (Claude Pro/Max)"
-
Press Enter to select Anthropic
-
Expected:
- Browser opens to https://claude.ai/oauth/authorize?...
- Terminal shows "Paste the authorization code below:"
-
Authorize the app in the browser
-
Copy the authorization code from the browser
-
Paste the code in the terminal and press Enter
-
Expected:
- Success message: "✓ Successfully logged in to Anthropic"
- Message: "Tokens saved to ~/.pi/agent/oauth.json"
-
Verify file created:
ls -la ~/.pi/agent/oauth.jsonExpected: File exists with permissions
-rw-------(0600) -
Verify file contents:
cat ~/.pi/agent/oauth.jsonExpected: JSON with structure:
{ "anthropic": { "type": "oauth", "refresh": "ory_rt_...", "access": "sk-ant-oat-...", "expires": 1234567890000 } }
Test 2: Using OAuth Token
-
With OAuth credentials saved (from Test 1), start a new pi session:
pi -
Type
/modeland press Enter -
Expected: Claude models (e.g., claude-sonnet-4-5) appear in the list
-
Select a Claude model
-
Send a simple message:
You: Hello, tell me what 2+2 is -
Expected:
- Model responds successfully
- No "API key not found" errors
- OAuth token is used automatically (check that it works without ANTHROPIC_API_KEY set)
Test 3: Logout
-
In an interactive pi session, type
/logout -
Expected: OAuth provider selector shows "Anthropic (Claude Pro/Max)"
-
Press Enter to select Anthropic
-
Expected:
- Success message: "✓ Successfully logged out of Anthropic"
- Message: "Credentials removed from ~/.pi/agent/oauth.json"
-
Verify file is empty or doesn't contain anthropic:
cat ~/.pi/agent/oauth.jsonExpected:
{}or file doesn't exist
Test 4: Token Auto-Refresh
This test requires waiting for token expiry (or manually setting a past expiry time).
-
Modify
~/.pi/agent/oauth.jsonto set an expired time:{ "anthropic": { "type": "oauth", "refresh": "ory_rt_...", "access": "sk-ant-oat-...", "expires": 1000000000000 } } -
Start pi and send a message to a Claude model
-
Expected:
- Token is automatically refreshed
- New access token and expiry time saved to oauth.json
- Request succeeds without user intervention
Test 5: Fallback to API Key
-
Remove OAuth credentials:
rm ~/.pi/agent/oauth.json -
Set ANTHROPIC_API_KEY:
export ANTHROPIC_API_KEY=sk-ant-... -
Start pi and send a message to a Claude model
-
Expected:
- Model uses API key successfully
- No errors about missing OAuth credentials
Test 6: OAuth Takes Priority
-
Set both OAuth and API key:
- Login with
/login(saves OAuth credentials) - Also set:
export ANTHROPIC_API_KEY=sk-ant-...
- Login with
-
Start pi and check which is used
-
Expected: OAuth token is used (verify in logs or by checking if API key would fail)
Test 7: Error Handling - Invalid Code
-
Start pi and type
/login -
Select Anthropic
-
Enter an invalid authorization code (e.g., "invalid123")
-
Expected:
- Error message shown
- No credentials saved
- Can try again
Test 8: Error Handling - No Browser
-
Start pi in a headless environment or where browser can't open
-
Type
/loginand select Anthropic -
Expected:
- URL is shown in terminal
- User can manually copy URL to browser
- Auth flow continues normally
Test 9: Slash Command Autocomplete
-
Start pi
-
Type
/and press Tab -
Expected: Autocomplete shows
/loginand/logoutamong other commands -
Type
/logand press Tab -
Expected: Autocomplete completes to
/loginor/logout
Test 10: No OAuth Available (Logout)
-
Ensure no OAuth credentials are saved:
rm ~/.pi/agent/oauth.json -
Start pi and type
/logout -
Expected:
- Message: "No OAuth providers logged in. Use /login first."
- Selector doesn't appear
Automated Testing Ideas
The following tests should be added to the test suite:
-
Unit Tests for
oauth/storage.tssaveOAuthCredentials()creates file with correct permissionsloadOAuthCredentials()returns saved credentialsremoveOAuthCredentials()removes credentialslistOAuthProviders()returns correct list
-
Unit Tests for
oauth/anthropic.ts- PKCE generation creates valid verifier/challenge
- Token refresh makes correct API call
- Error handling for failed requests
-
Integration Tests for
model-config.tsgetApiKeyForModel()checks OAuth before API key- Async behavior works correctly
- Proper fallback to API keys
-
Mock Tests for OAuth Flow
- Mock fetch to test token exchange
- Test auto-refresh logic
- Test expiry checking
Known Limitations
- Manual Testing Required: The OAuth flow involves browser interaction, so it's difficult to fully automate
- Requires Real Credentials: Testing with a real Claude Pro/Max account is needed
- Token Expiry: Default tokens last a long time, so auto-refresh is hard to test naturally
Success Criteria
- All manual tests pass
- OAuth login works end-to-end
- Tokens are saved securely (0600 permissions)
- Token auto-refresh works
- Logout removes credentials
- Fallback to API keys works
- No breaking changes for existing API key users
- Error handling is user-friendly
- Documentation is clear and accurate