Skip to content

feat: auth error classification, streaming buffer inspection, and macOS credential sync#3

Merged
0xPuncker merged 7 commits into
mainfrom
feat/macos-rate-limit-validation
May 22, 2026
Merged

feat: auth error classification, streaming buffer inspection, and macOS credential sync#3
0xPuncker merged 7 commits into
mainfrom
feat/macos-rate-limit-validation

Conversation

@0xPuncker
Copy link
Copy Markdown
Owner

Summary

  • Auth error circuit breakerclassifyProviderError now returns auth_error for 401 and bare 403 responses (body-based checks run first, so a 403 with quota/billing content still maps to rate_limit). The circuit breaker enters immediate cooldown on auth errors instead of burning retry budget on a credential that won't work until fixed.

  • Streaming error buffer inspectioninspectInitialStreamingBuffer parses SSE events in the first chunk before flushing to the client. When a streaming provider returns an event: error or a JSON error payload at stream start, the proxy intercepts it cleanly and fails over rather than sending a partial error stream to the CLI.

  • Container names hardcodeddocker-compose.yml container names changed from ${VAR:-default} to static strings (cc-proxy, cc-db, cc-adminer) to prevent Compose from generating auto-suffixed names. The now-redundant env vars removed from .env.docker.example.

  • Credentials mount fixed — Volume mount corrected from ~/.claude/.credentials.json (which was a directory, silently breaking OAuth reads) to ~/.claude/claude-credentials.json, mounted read-write.

  • macOS Keychain credential syncscripts/sync-credentials.sh reads the Claude OAuth token from the macOS Keychain (Claude Code-credentials service) and writes it to ~/.claude/claude-credentials.json. scripts/setup-credential-sync.sh installs a LaunchAgent that runs this sync every 5 minutes so the proxy always has a fresh token without manual intervention.

Test plan

  • npx tsc --noEmit — passes clean
  • npm run lint — no warnings
  • npm test — 71/71 pass, including the quota-style 403 regression test (classifies quota-style provider responses as rate limits)
  • Proxy verified routing through Claude subscription after re-login and credential sync
  • LaunchAgent installed and running (launchctl list | grep com.claude)

0xPuncker added 7 commits May 17, 2026 19:08
- Add subscriptionCooldownUntil timestamp tracking
- Implement canTryClaudeSubscription() to check cooldown state
- Add resetClaudeSubscriptionCircuit() to reset on success
- Add enterClaudeSubscriptionCooldown() with configurable cooldown period
- Add recordClaudeSubscriptionFailure() to classify and handle errors
- Add getClaudeSubscriptionState() to expose current state
- Classify provider errors as rate_limit, context_window, or other
- Prevents repeated subscription attempts during rate-limit/cooldown
- Tests: quota failure handling, cooldown circuit, state transitions
Adds auth_error classification (401/403 without quota body) to
classifyProviderError so the circuit breaker enters immediate cooldown
on bad/expired credentials instead of burning retry budget.

Adds inspectInitialStreamingBuffer to detect error events in the first
SSE chunk before flushing to the client, enabling clean failover when
a streaming provider returns an error mid-connection.
Container names are now static (cc-proxy, cc-db, cc-adminer) rather
than env-var-interpolated to avoid auto-generated names from Compose.
Credentials mount corrected from .credentials.json (a directory) to
claude-credentials.json and changed to read-write so the sync sidecar
can update it in place.
sync-credentials.sh reads the Claude OAuth token from Keychain and
writes it to ~/.claude/claude-credentials.json for the Docker mount.
setup-credential-sync.sh installs a LaunchAgent that runs the sync
every 5 minutes so the proxy always has a fresh token without manual
intervention.
Container names are now hardcoded in docker-compose.yml so the env
vars PROXY_CONTAINER_NAME, DB_CONTAINER_NAME, ADMINER_CONTAINER_NAME
are removed from the example file. Setup scripts and docs updated to
reflect ANTHROPIC_API_URL routing and the new settings:update commands.
@0xPuncker 0xPuncker merged commit 65e907b into main May 22, 2026
2 checks passed
@0xPuncker 0xPuncker deleted the feat/macos-rate-limit-validation branch May 22, 2026 22:15
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.

1 participant