fix: correct state destructuring and document headless mode

- Fix extractCodeFromInput destructuring: returns { code, state } not
  { code, extractedState }, so state validation was being bypassed
- Add --no-browser hint to CLI banner for discoverability
- Document --no-browser mode in README.md and CLAUDE.md
- Add test:oauth script to package.json
- Add OAuth test to run-all.cjs test suite

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Badri Narayanan S
2026-01-04 14:51:05 +05:30
parent 573ba57db6
commit 1628696ca1
5 changed files with 23 additions and 3 deletions

View File

@@ -29,6 +29,7 @@ npm run dev
# Account management # Account management
npm run accounts # Interactive account management npm run accounts # Interactive account management
npm run accounts:add # Add a new Google account via OAuth npm run accounts:add # Add a new Google account via OAuth
npm run accounts:add -- --no-browser # Add account on headless server (manual code input)
npm run accounts:list # List configured accounts npm run accounts:list # List configured accounts
npm run accounts:verify # Verify account tokens are valid npm run accounts:verify # Verify account tokens are valid
@@ -43,6 +44,7 @@ npm run test:interleaved # Interleaved thinking
npm run test:images # Image processing npm run test:images # Image processing
npm run test:caching # Prompt caching npm run test:caching # Prompt caching
npm run test:crossmodel # Cross-model thinking signatures npm run test:crossmodel # Cross-model thinking signatures
npm run test:oauth # OAuth no-browser mode
``` ```
## Architecture ## Architecture

View File

@@ -84,6 +84,21 @@ npm run accounts:add
This opens your browser for Google OAuth. Sign in and authorize access. Repeat for multiple accounts. This opens your browser for Google OAuth. Sign in and authorize access. Repeat for multiple accounts.
**Headless Servers (Docker, SSH, no desktop):**
```bash
# Use --no-browser mode for servers without a browser
antigravity-claude-proxy accounts add --no-browser
# Or with npx
npx antigravity-claude-proxy accounts add -- --no-browser
# Or if cloned locally
npm run accounts:add -- --no-browser
```
This displays an OAuth URL you can open on another device (phone/laptop). After signing in, copy the redirect URL or authorization code and paste it back into the terminal.
Manage accounts: Manage accounts:
```bash ```bash

View File

@@ -26,7 +26,8 @@
"test:interleaved": "node tests/test-interleaved-thinking.cjs", "test:interleaved": "node tests/test-interleaved-thinking.cjs",
"test:images": "node tests/test-images.cjs", "test:images": "node tests/test-images.cjs",
"test:caching": "node tests/test-caching-streaming.cjs", "test:caching": "node tests/test-caching-streaming.cjs",
"test:crossmodel": "node tests/test-cross-model-thinking.cjs" "test:crossmodel": "node tests/test-cross-model-thinking.cjs",
"test:oauth": "node tests/test-oauth-no-browser.cjs"
}, },
"keywords": [ "keywords": [
"claude", "claude",

View File

@@ -248,7 +248,7 @@ async function addAccountNoBrowser(existingAccounts, rl) {
const input = await rl.question('Paste the callback URL or authorization code: '); const input = await rl.question('Paste the callback URL or authorization code: ');
try { try {
const { code, extractedState } = extractCodeFromInput(input); const { code, state: extractedState } = extractCodeFromInput(input);
// Validate state if present // Validate state if present
if (extractedState && extractedState !== state) { if (extractedState && extractedState !== state) {
@@ -460,6 +460,7 @@ async function main() {
console.log('╔════════════════════════════════════════╗'); console.log('╔════════════════════════════════════════╗');
console.log('║ Antigravity Proxy Account Manager ║'); console.log('║ Antigravity Proxy Account Manager ║');
console.log('║ Use --no-browser for headless mode ║');
console.log('╚════════════════════════════════════════╝'); console.log('╚════════════════════════════════════════╝');
const rl = createRL(); const rl = createRL();

View File

@@ -14,7 +14,8 @@ const tests = [
{ name: 'Multi-turn Tools (Streaming)', file: 'test-multiturn-thinking-tools-streaming.cjs' }, { name: 'Multi-turn Tools (Streaming)', file: 'test-multiturn-thinking-tools-streaming.cjs' },
{ name: 'Interleaved Thinking', file: 'test-interleaved-thinking.cjs' }, { name: 'Interleaved Thinking', file: 'test-interleaved-thinking.cjs' },
{ name: 'Image Support', file: 'test-images.cjs' }, { name: 'Image Support', file: 'test-images.cjs' },
{ name: 'Prompt Caching', file: 'test-caching-streaming.cjs' } { name: 'Prompt Caching', file: 'test-caching-streaming.cjs' },
{ name: 'OAuth No-Browser Mode', file: 'test-oauth-no-browser.cjs' }
]; ];
async function runTest(test) { async function runTest(test) {