All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Fixed provider reload after authentication - Complete fix for provider disappearing after
/connect- Root cause: OpenCode filters providers based on its own auth system (
Auth.get()), not plugin's tokenManager - Solution: Call
client.auth.set()in OAuth callback to save credentials to OpenCode auth system - Provider models now appear immediately after
/connectwithout requiring restart - Added 3-second polling in loader to wait for OAuth callback completion (fixes race condition)
- First request may trigger 401, but automatic recovery fetches fresh credentials transparently
- Works for both first-time authentication and re-authentication scenarios
- Leverages existing 401 recovery mechanism in fetch() for seamless auth on-demand
- Root cause: OpenCode filters providers based on its own auth system (
- Dynamic User-Agent detection - User-Agent header now dynamically detects platform and architecture instead of hardcoded Linux/x64
- Supports Linux, macOS, Windows, FreeBSD, OpenBSD, Solaris, AIX
- Supports x64, arm64, ia32, ppc64, arm, mips architectures
- Maintains qwen-code v0.12.0 client version for compatibility
- Fixes authentication on non-Linux systems and ARM devices (M1/M2/M3 Macs, Raspberry Pi, etc.)
- Fixed credentials loading on new sessions - Added explicit snake_case to camelCase conversion in
loadCredentials()to correctly parse~/.qwen/oauth_creds.json - Fixed rate limiting issue (#4) - Added official Qwen Code headers to prevent aggressive rate limiting
- Headers include
X-DashScope-CacheControl,X-DashScope-AuthType,X-DashScope-UserAgent - Requests now recognized as legitimate Qwen Code client
- Full 1,000 requests/day quota now available (OAuth free tier)
- Headers include
- HTTP 401 handling in device polling - Added explicit error handling for HTTP 401 during device authorization polling
- Attaches HTTP status code to errors for proper classification
- User-friendly error message: "Device code expired or invalid. Please restart authentication."
- Token refresh response validation - Validates access_token presence in refresh response before accepting
- Refresh token security - Removed refresh token from console logs to prevent credential leakage
- Multi-process safety
- Implemented file locking with atomic
fs.openSync('wx') - Added stale lock detection (10s threshold) matching official client
- Registered 5 process exit handlers (exit, SIGINT, SIGTERM, uncaughtException, unhandledRejection)
- Implemented atomic file writes using temp file + rename pattern
- Implemented file locking with atomic
- Token Management
- Added
TokenManagerwith in-memory caching and promise tracking - Implemented file check throttling (5s interval) to reduce I/O overhead
- Added file watcher for real-time cache invalidation when credentials change externally
- Implemented atomic cache state updates to prevent inconsistent states
- Added
- Error Recovery
- Added reactive 401 recovery: automatically forces token refresh and retries request
- Implemented comprehensive credentials validation matching official client
- Added timeout wrappers (3s) for file operations to prevent indefinite hangs
- Performance & Reliability
- Added request throttling (1s min interval + random jitter) to prevent hitting 60 req/min limits
- Implemented
retryWithBackoffwith exponential backoff and jitter (up to 7 attempts) - Added support for
Retry-Afterheader from server - OAuth requests now use 30s timeout to prevent indefinite hangs
- Dynamic API endpoint resolution - Automatic region detection based on
resource_urlin OAuth token - Aligned with qwen-code-0.12.1 - Achieved 98% feature parity with official client
- Enhanced Debug Logging - Detailed context, timing, and state information (enabled via
OPENCODE_QWEN_DEBUG=1) - Custom error hierarchy -
QwenAuthError,CredentialsClearRequiredError,TokenManagerErrorwith error classification - Error classification system -
classifyError()helper for programmatic error handling with retry hints
- Comprehensive test suite - 104 unit tests across 6 test files with 197 assertions
errors.test.ts- Error handling and classification tests (30+ tests)oauth.test.ts- OAuth device flow and PKCE tests (20+ tests)file-lock.test.ts- File locking and concurrency tests (20 tests)token-manager.test.ts- Token caching and refresh tests (10 tests)request-queue.test.ts- Request throttling tests (15+ tests)auth-integration.test.ts- End-to-end integration tests (15 tests)
- Integration tests - Manual test scripts for race conditions and end-to-end debugging
- Robust stress tests - Multi-process concurrency tests with 10 parallel workers
- Test isolation -
QWEN_TEST_CREDS_PATHenvironment variable prevents tests from modifying user credentials - Test configuration -
bunfig.tomlfor test runner configuration - Test documentation -
tests/README.mdwith complete testing guide
- User-focused README cleanup (English and Portuguese)
- Updated troubleshooting section with practical recovery steps
- Detailed CHANGELOG for technical history
- Test suite documentation with commands and examples
- Architecture documentation in code comments
- Dynamic API endpoint resolution
- DashScope headers support
loadCredentials()andresolveBaseUrl()functions
ERR_INVALID_URLerror - loader now returnsbaseURLcorrectly- "Incorrect API key provided" error for portal.qwen.ai tokens
- OAuth Device Flow authentication
- Support for qwen3-coder-plus, qwen3-coder-flash models
- Automatic token refresh
- Compatibility with qwen-code credentials
- Initial release
- Basic OAuth authentication
- Model configuration for Qwen providers