opencode-qwen-cli-auth 2.2.9 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,62 +1,273 @@
1
- # opencode-qwen-cli-auth (local fork)
2
-
3
- Plugin OAuth cho **OpenCode** để dùng Qwen theo cơ chế giống **qwen-code CLI** (free tier bằng Qwen account), không cần DashScope API key.
4
-
5
- ## Cấu hình nhanh
6
-
7
- `opencode.json`:
8
-
9
- ```json
10
- {
11
- "$schema": "https://opencode.ai/config.json",
12
- "plugin": ["opencode-qwen-cli-auth"],
13
- "model": "qwen-code/coder-model"
14
- }
15
- ```
16
-
17
- Đăng nhập:
18
-
19
- ```bash
20
- opencode auth login
21
- ```
22
-
23
- Chọn provider **Qwen Code (qwen.ai OAuth)**.
24
-
25
- ## Vì sao plugin trước bị `insufficient_quota`?
26
-
27
- Từ việc đối chiếu với **qwen-code** (gốc), request free-tier cần:
28
-
29
- - Base URL đúng (DashScope OpenAI-compatible):
30
- - mặc định: `https://dashscope.aliyuncs.com/compatible-mode/v1`
31
- - có thể thay đổi theo `resource_url` trong `~/.qwen/oauth_creds.json`
32
- - Headers DashScope đặc thù:
33
- - `X-DashScope-AuthType: qwen-oauth`
34
- - `X-DashScope-CacheControl: enable`
35
- - `User-Agent` + `X-DashScope-UserAgent`
36
- - Giới hạn output token theo model (qwen-code):
37
- - `coder-model`: 65536
38
- - `vision-model`: 8192
39
-
40
- Fork này đã **inject headers ở tầng fetch** để vẫn hoạt động ngay cả khi OpenCode không gọi hook `chat.headers`.
41
-
42
- ## Debug / logging
43
-
44
- ```bash
45
- DEBUG_QWEN_PLUGIN=1 opencode run "hello" --model=qwen-code/coder-model
46
- ENABLE_PLUGIN_REQUEST_LOGGING=1 opencode run "hello" --model=qwen-code/coder-model
47
- ```
48
-
49
- Log path: `~/.opencode/logs/qwen-plugin/`
50
-
51
- ## Clear auth
52
-
53
- PowerShell:
54
-
55
- ```powershell
56
- Remove-Item -Recurse -Force "$HOME/.opencode/qwen"
57
- Remove-Item -Recurse -Force "$HOME/.qwen" # nếu muốn xoá token qwen-code luôn
58
- ```
59
-
60
- ## Ghi chú build
61
-
62
- Repo này chỉ chứa output `dist/` (không có `src/`/`tsconfig.json`), nên `npm run build/typecheck` sẽ không compile lại TS.
1
+ # opencode-qwen-cli-auth
2
+
3
+ OAuth plugin for [OpenCode](https://opencode.ai) to use Qwen for free via Qwen Account, compatible with the [qwen-code CLI](https://github.com/QwenLM/qwen-code) mechanism.
4
+
5
+ ## Features
6
+
7
+ - **OAuth 2.0 Device Authorization Grant** (RFC 8628) - login with your Qwen Account
8
+ - **No API key required** - utilize Qwen's free tier
9
+ - **Automatic token refresh** when expired
10
+ - **Multi-account support** - add multiple Qwen accounts and keep one active account
11
+ - **DashScope compatibility** - automatically injects required headers for the OAuth flow
12
+ - **Smart output token limit** - auto-caps tokens based on model (65K for coder-model, 8K for vision-model)
13
+ - **Retry & Fallback** - handles quota/rate limit errors with payload degradation mechanism
14
+ - **Logging & Debugging** - detailed debugging support via environment variables
15
+
16
+ ## Installation
17
+
18
+ ### Requirements
19
+
20
+ - Node.js >= 20.0.0
21
+ - OpenCode with plugin support
22
+ - Qwen Account (free)
23
+
24
+ ### Add to OpenCode
25
+
26
+ Configure in `opencode.json`:
27
+
28
+ ```json
29
+ {
30
+ "$schema": "https://opencode.ai/config.json",
31
+ "plugin": ["opencode-qwen-cli-auth"],
32
+ "model": "qwen-code/coder-model"
33
+ }
34
+ ```
35
+
36
+ ### Login
37
+
38
+ ```bash
39
+ opencode auth login
40
+ ```
41
+
42
+ Select provider **Qwen Code (qwen.ai OAuth)** and follow the instructions:
43
+
44
+ 1. Open the URL displayed in the terminal
45
+ 2. Enter the provided code
46
+ 3. The plugin will automatically poll and save the token
47
+
48
+ To add more accounts, run `opencode auth login` again.
49
+ The plugin stores each successful login in the multi-account store and can auto-switch on quota exhaustion.
50
+
51
+ ## Supported Models
52
+
53
+ | Model | ID | Context | Max Output | Cost |
54
+ |-------|-----|---------|------------|---------|
55
+ | Qwen Coder (Qwen 3.5 Plus) | `coder-model` | 1M tokens | 65,536 tokens | Free |
56
+ | Qwen VL Plus (Vision) | `vision-model` | 128K tokens | 8,192 tokens | Free |
57
+
58
+ ## Configuration
59
+
60
+ ### Environment Variables
61
+
62
+ | Variable | Description | Value |
63
+ |------|-------|---------|
64
+ | `QWEN_CLI_PATH` | Path to qwen CLI (for fallback) | Default: auto-detect |
65
+ | `QWEN_MODE` | Qwen mode toggle | `1`/`true` (default) |
66
+ | `DEBUG_QWEN_PLUGIN=1` | Enable debug logging | Optional |
67
+ | `ENABLE_PLUGIN_REQUEST_LOGGING=1` | Enable request logging to file | Optional |
68
+ | `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1` | Enable CLI fallback on quota error | Optional |
69
+ | `OPENCODE_QWEN_ACCOUNTS_PATH` | Override multi-account store path (must be inside `~/.qwen`) | Optional |
70
+ | `OPENCODE_QWEN_QUOTA_COOLDOWN_MS` | Cooldown for exhausted accounts | Default: `1800000` (30 min) |
71
+
72
+ ### Debug & Logging
73
+
74
+ ```bash
75
+ # Debug mode - logs to console
76
+ DEBUG_QWEN_PLUGIN=1 opencode run "hello" --model=qwen-code/coder-model
77
+
78
+ # Request logging - saves detailed JSON files
79
+ ENABLE_PLUGIN_REQUEST_LOGGING=1 opencode run "hello" --model=qwen-code/coder-model
80
+ ```
81
+
82
+ Log files are stored at: `~/.opencode/logs/qwen-plugin/`
83
+
84
+ ## How It Works
85
+
86
+ ### OAuth Flow
87
+
88
+ ```
89
+ 1. OpenCode requests auth -> Plugin
90
+ 2. Plugin requests device code from Qwen OAuth Server
91
+ 3. Displays URL + code to user
92
+ 4. User opens URL and enters code to authorize
93
+ 5. Plugin polls token from Qwen OAuth Server
94
+ 6. Saves token and returns to OpenCode
95
+ 7. All API requests are injected with headers and sent to DashScope
96
+ ```
97
+
98
+ ### Token Storage
99
+
100
+ - **Location**: `~/.qwen/oauth_creds.json`
101
+ - **Format**: JSON with access_token, refresh_token, expiry_date, resource_url
102
+ - **Auto-refresh**: Triggered when less than 30 seconds to expiration
103
+ - **Lock mechanism**: Safe multi-process token refresh
104
+ - **Multi-account store**: `~/.qwen/oauth_accounts.json`
105
+ - **Multi-account lock**: `~/.qwen/oauth_accounts.lock`
106
+
107
+ ### Required Headers
108
+
109
+ The plugin automatically injects required headers for DashScope OAuth:
110
+
111
+ ```
112
+ X-DashScope-AuthType: qwen-oauth
113
+ X-DashScope-CacheControl: enable
114
+ User-Agent: opencode-qwen-cli-auth/{version}
115
+ X-DashScope-UserAgent: opencode-qwen-cli-auth/{version}
116
+ ```
117
+
118
+ ## Error Handling
119
+
120
+ ### Insufficient Quota
121
+
122
+ When hitting a `429 insufficient_quota` error, the plugin automatically:
123
+
124
+ 1. **Marks current account exhausted** for cooldown window
125
+ 2. **Switches to next healthy account** and retries with same payload
126
+ 3. **Degrades payload** if no healthy account can be switched
127
+ 4. **CLI fallback** (optional) - invokes `qwen` CLI if `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1` is set
128
+
129
+ ### Token Expiration
130
+
131
+ - Automatically uses refresh token
132
+ - Retries up to 2 times for transient errors (timeout, network)
133
+ - Clears token and requests re-auth on 401/403
134
+
135
+ ## Authentication Management
136
+
137
+ ### Check Status
138
+
139
+ ```bash
140
+ # View saved token
141
+ cat ~/.qwen/oauth_creds.json
142
+
143
+ # View multi-account store
144
+ cat ~/.qwen/oauth_accounts.json
145
+ ```
146
+
147
+ ### Remove Authentication
148
+
149
+ **PowerShell:**
150
+ ```powershell
151
+ Remove-Item -Recurse -Force "$HOME/.opencode/qwen"
152
+ Remove-Item -Force "$HOME/.qwen/oauth_creds.json"
153
+ ```
154
+
155
+ **Bash (Linux/macOS):**
156
+ ```bash
157
+ rm -rf ~/.opencode/qwen
158
+ rm ~/.qwen/oauth_creds.json
159
+ ```
160
+
161
+ ### Manual Refresh
162
+
163
+ ```bash
164
+ # Clear old token and login again
165
+ opencode auth logout
166
+ opencode auth login
167
+ ```
168
+
169
+ ## Plugin Architecture
170
+
171
+ ```
172
+ dist/
173
+ ├── index.js # Entry point, exports QwenAuthPlugin
174
+ ├── lib/
175
+ │ ├── auth/
176
+ │ │ ├── auth.js # OAuth flow: device code, poll token, refresh
177
+ │ │ └── browser.js # Browser opener utility
178
+ │ ├── config.js # Config paths, QWEN_MODE
179
+ │ ├── constants.js # Constants: OAuth endpoints, headers, errors
180
+ │ ├── logger.js # Logging utilities
181
+ │ └── types.js # TypeScript types
182
+ ```
183
+
184
+ ### Internal Hooks Used
185
+
186
+ | Hook | Purpose |
187
+ |------|----------|
188
+ | `auth.loader` | Provides apiKey, baseURL, custom fetch |
189
+ | `auth.methods.authorize` | Device Authorization OAuth flow |
190
+ | `config` | Registers provider and models |
191
+ | `chat.params` | Sets timeout, maxRetries, max_tokens limits |
192
+ | `chat.headers` | Injects DashScope headers |
193
+
194
+ ## Comparison with Previous Plugin
195
+
196
+ | Feature | Old Plugin | This Plugin |
197
+ |-----------|-----------|------------|
198
+ | OAuth Device Flow | ✓ | ✓ |
199
+ | Custom fetch layer | ✗ | ✓ |
200
+ | DashScope headers | ✗ | ✓ (auto-inject) |
201
+ | Output token capping | ✗ | ✓ |
202
+ | Quota degradation | ✗ | ✓ |
203
+ | CLI fallback | ✗ | ✓ (optional) |
204
+ | Multi-process lock | ✗ | ✓ |
205
+ | Legacy token migration | ✗ | ✓ |
206
+
207
+ ## Troubleshooting
208
+
209
+ ### Common Issues
210
+
211
+ **1. Persistent `insufficient_quota` errors**
212
+ - Your account may have exhausted the free tier quota
213
+ - Try deleting the token and logging in again
214
+ - Enable CLI fallback: `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1`
215
+
216
+ **2. OAuth timeout**
217
+ - Check network connection
218
+ - Increase timeout in config if needed
219
+ - View detailed logs with `DEBUG_QWEN_PLUGIN=1`
220
+
221
+ **3. Cannot find qwen CLI**
222
+ - Install qwen-code: `npm install -g @qwen-code/qwen-code`
223
+ - Or set env var: `QWEN_CLI_PATH=/path/to/qwen`
224
+
225
+ **4. Token not saving**
226
+ - Check write permissions for `~/.qwen/` directory
227
+ - View logs with `ENABLE_PLUGIN_REQUEST_LOGGING=1`
228
+
229
+ ## Development
230
+
231
+ ### Build
232
+
233
+ ```bash
234
+ npm install
235
+ npm run build
236
+ ```
237
+
238
+ ### Test
239
+
240
+ ```bash
241
+ npm test
242
+ ```
243
+
244
+ ### Type Check
245
+
246
+ ```bash
247
+ npm run typecheck
248
+ ```
249
+
250
+ ### Lint & Format
251
+
252
+ ```bash
253
+ npm run lint
254
+ npm run format
255
+ ```
256
+
257
+ ## License
258
+
259
+ MIT
260
+
261
+ ## Repository
262
+
263
+ - **Source**: https://github.com/TVD-00/opencode-qwen-cli-auth
264
+ - **Issues**: https://github.com/TVD-00/opencode-qwen-cli-auth/issues
265
+ - **NPM**: https://www.npmjs.com/package/opencode-qwen-cli-auth
266
+
267
+ ## Author
268
+
269
+ Geoff Hammond
270
+
271
+ ## Contributing
272
+
273
+ All contributions (PRs, issues, feedback) are welcome at the GitHub repository.
package/README.vi.md ADDED
@@ -0,0 +1,273 @@
1
+ # opencode-qwen-cli-auth
2
+
3
+ Plugin OAuth cho [OpenCode](https://opencode.ai) để sử dụng Qwen miễn phí thông qua Qwen Account, tương thích với cơ chế của [qwen-code CLI](https://github.com/QwenLM/qwen-code).
4
+
5
+ ## Tính năng
6
+
7
+ - **OAuth 2.0 Device Authorization Grant** (RFC 8628) - đăng nhập bằng Qwen Account
8
+ - **Không cần API key** - sử dụng free tier của Qwen
9
+ - **Tự động refresh token** khi hết hạn
10
+ - **Hỗ trợ đa tài khoản** - thêm nhiều Qwen account và duy trì một tài khoản active
11
+ - **Tương thích DashScope** - tự động inject headers cần thiết cho OAuth flow
12
+ - **Giới hạn output token thông minh** - tự động cap theo model (65K cho coder-model, 8K cho vision-model)
13
+ - **Retry & Fallback** - xử lý lỗi quota/rate limit với cơ chế degrade (giảm tải payload)
14
+ - **Logging & Debugging** - hỗ trợ debug chi tiết qua biến môi trường
15
+
16
+ ## Cài đặt
17
+
18
+ ### Yêu cầu
19
+
20
+ - Node.js >= 20.0.0
21
+ - OpenCode có hỗ trợ plugin
22
+ - Qwen Account (miễn phí)
23
+
24
+ ### Thêm vào OpenCode
25
+
26
+ Cấu hình trong file `opencode.json`:
27
+
28
+ ```json
29
+ {
30
+ "$schema": "https://opencode.ai/config.json",
31
+ "plugin": ["opencode-qwen-cli-auth"],
32
+ "model": "qwen-code/coder-model"
33
+ }
34
+ ```
35
+
36
+ ### Đăng nhập
37
+
38
+ ```bash
39
+ opencode auth login
40
+ ```
41
+
42
+ Chọn provider **Qwen Code (qwen.ai OAuth)** và làm theo hướng dẫn:
43
+
44
+ 1. Mở URL hiển thị trong terminal
45
+ 2. Nhập mã code được cung cấp
46
+ 3. Plugin sẽ tự động poll và lưu token
47
+
48
+ Để thêm tài khoản mới, chạy lại `opencode auth login`.
49
+ Plugin sẽ lưu từng lần đăng nhập thành công vào kho đa tài khoản và có thể tự động đổi tài khoản khi hết quota.
50
+
51
+ ## Models hỗ trợ
52
+
53
+ | Model | ID | Context | Max Output | Chi phí |
54
+ |-------|-----|---------|------------|---------|
55
+ | Qwen Coder (Qwen 3.5 Plus) | `coder-model` | 1M tokens | 65,536 tokens | Miễn phí |
56
+ | Qwen VL Plus (Vision) | `vision-model` | 128K tokens | 8,192 tokens | Miễn phí |
57
+
58
+ ## Cấu hình
59
+
60
+ ### Biến môi trường
61
+
62
+ | Biến | Mô tả | Giá trị |
63
+ |------|-------|---------|
64
+ | `QWEN_CLI_PATH` | Đường dẫn đến qwen CLI (cho fallback) | Mặc định: tự động tìm |
65
+ | `QWEN_MODE` | Bật/tắt Qwen mode | `1`/`true` (mặc định) |
66
+ | `DEBUG_QWEN_PLUGIN=1` | Bật debug logging | Tùy chọn |
67
+ | `ENABLE_PLUGIN_REQUEST_LOGGING=1` | Bật ghi log request ra file | Tùy chọn |
68
+ | `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1` | Bật tính năng gọi CLI khi hết quota | Tùy chọn |
69
+ | `OPENCODE_QWEN_ACCOUNTS_PATH` | Ghi đè đường dẫn kho đa tài khoản (phải nằm trong `~/.qwen`) | Tùy chọn |
70
+ | `OPENCODE_QWEN_QUOTA_COOLDOWN_MS` | Thời gian cooldown cho tài khoản đã hết quota | Mặc định: `1800000` (30 phút) |
71
+
72
+ ### Debug & Logging
73
+
74
+ ```bash
75
+ # Debug mode - in log ra console
76
+ DEBUG_QWEN_PLUGIN=1 opencode run "hello" --model=qwen-code/coder-model
77
+
78
+ # Request logging - lưu chi tiết vào file JSON
79
+ ENABLE_PLUGIN_REQUEST_LOGGING=1 opencode run "hello" --model=qwen-code/coder-model
80
+ ```
81
+
82
+ File log được lưu tại: `~/.opencode/logs/qwen-plugin/`
83
+
84
+ ## Cơ chế hoạt động
85
+
86
+ ### Luồng OAuth (OAuth Flow)
87
+
88
+ ```
89
+ 1. OpenCode yêu cầu xác thực -> Plugin
90
+ 2. Plugin xin cấp device code từ Qwen OAuth Server
91
+ 3. Hiển thị URL + code cho người dùng
92
+ 4. Người dùng mở URL và nhập code để ủy quyền
93
+ 5. Plugin liên tục gọi (poll) Qwen OAuth Server để lấy token
94
+ 6. Lưu token và trả về cho OpenCode
95
+ 7. Tất cả request API sẽ được đính kèm headers và gửi đến DashScope
96
+ ```
97
+
98
+ ### Lưu trữ Token
99
+
100
+ - **Vị trí**: `~/.qwen/oauth_creds.json`
101
+ - **Định dạng**: JSON chứa access_token, refresh_token, expiry_date, resource_url
102
+ - **Tự động refresh**: Kích hoạt khi token còn dưới 30 giây là hết hạn
103
+ - **Cơ chế khóa (Lock)**: Đảm bảo an toàn khi refresh token trong môi trường đa tiến trình (multi-process)
104
+ - **Kho đa tài khoản**: `~/.qwen/oauth_accounts.json`
105
+ - **Lock đa tài khoản**: `~/.qwen/oauth_accounts.lock`
106
+
107
+ ### Headers Bắt buộc
108
+
109
+ Plugin tự động đính kèm các headers cần thiết cho DashScope OAuth:
110
+
111
+ ```
112
+ X-DashScope-AuthType: qwen-oauth
113
+ X-DashScope-CacheControl: enable
114
+ User-Agent: opencode-qwen-cli-auth/{version}
115
+ X-DashScope-UserAgent: opencode-qwen-cli-auth/{version}
116
+ ```
117
+
118
+ ## Xử lý lỗi
119
+
120
+ ### Hết Quota (Insufficient Quota)
121
+
122
+ Khi gặp lỗi `429 insufficient_quota`, plugin sẽ tự động:
123
+
124
+ 1. **Đánh dấu tài khoản hiện tại đã hết quota** trong cửa sổ cooldown
125
+ 2. **Đổi sang tài khoản khỏe tiếp theo** và retry với payload ban đầu
126
+ 3. **Degrade payload** nếu không còn tài khoản khỏe để đổi
127
+ 4. **CLI fallback** (tùy chọn) - gọi `qwen` CLI nếu biến `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1` được bật
128
+
129
+ ### Token Hết Hạn
130
+
131
+ - Tự động sử dụng refresh token để lấy token mới
132
+ - Thử lại tối đa 2 lần đối với các lỗi tạm thời (timeout, lỗi mạng)
133
+ - Xóa token cũ và yêu cầu đăng nhập lại nếu nhận lỗi 401/403
134
+
135
+ ## Quản lý xác thực
136
+
137
+ ### Kiểm tra trạng thái
138
+
139
+ ```bash
140
+ # Xem token đang được lưu
141
+ cat ~/.qwen/oauth_creds.json
142
+
143
+ # Xem kho đa tài khoản
144
+ cat ~/.qwen/oauth_accounts.json
145
+ ```
146
+
147
+ ### Xóa xác thực
148
+
149
+ **PowerShell:**
150
+ ```powershell
151
+ Remove-Item -Recurse -Force "$HOME/.opencode/qwen"
152
+ Remove-Item -Force "$HOME/.qwen/oauth_creds.json"
153
+ ```
154
+
155
+ **Bash (Linux/macOS):**
156
+ ```bash
157
+ rm -rf ~/.opencode/qwen
158
+ rm ~/.qwen/oauth_creds.json
159
+ ```
160
+
161
+ ### Refresh thủ công
162
+
163
+ ```bash
164
+ # Xóa token cũ và đăng nhập lại
165
+ opencode auth logout
166
+ opencode auth login
167
+ ```
168
+
169
+ ## Kiến trúc Plugin
170
+
171
+ ```
172
+ dist/
173
+ ├── index.js # Entry point, exports QwenAuthPlugin
174
+ ├── lib/
175
+ │ ├── auth/
176
+ │ │ ├── auth.js # Luồng OAuth: device code, poll token, refresh
177
+ │ │ └── browser.js # Tiện ích mở trình duyệt
178
+ │ ├── config.js # Đường dẫn cấu hình, QWEN_MODE
179
+ │ ├── constants.js # Hằng số: OAuth endpoints, headers, mã lỗi
180
+ │ ├── logger.js # Tiện ích logging
181
+ │ └── types.js # Định nghĩa kiểu (TypeScript)
182
+ ```
183
+
184
+ ### Các Hook Sử Dụng
185
+
186
+ | Hook | Mục đích |
187
+ |------|----------|
188
+ | `auth.loader` | Cung cấp apiKey, baseURL, custom fetch |
189
+ | `auth.methods.authorize` | Thực hiện luồng Device Authorization OAuth |
190
+ | `config` | Đăng ký provider và models |
191
+ | `chat.params` | Thiết lập timeout, maxRetries, giới hạn max_tokens |
192
+ | `chat.headers` | Đính kèm các headers của DashScope |
193
+
194
+ ## So sánh với Plugin Cũ
195
+
196
+ | Tính năng | Plugin cũ | Plugin này |
197
+ |-----------|-----------|------------|
198
+ | OAuth Device Flow | ✓ | ✓ |
199
+ | Custom fetch layer | ✗ | ✓ |
200
+ | Headers của DashScope | ✗ | ✓ (tự động đính kèm) |
201
+ | Giới hạn Output token | ✗ | ✓ |
202
+ | Degradation khi hết quota| ✗ | ✓ |
203
+ | Fallback dùng CLI | ✗ | ✓ (tùy chọn) |
204
+ | Khóa đa tiến trình | ✗ | ✓ |
205
+ | Migrate token cũ | ✗ | ✓ |
206
+
207
+ ## Khắc phục sự cố (Troubleshooting)
208
+
209
+ ### Các lỗi thường gặp
210
+
211
+ **1. Bị lỗi `insufficient_quota` liên tục**
212
+ - Tài khoản của bạn có thể đã hết hạn mức miễn phí
213
+ - Hãy thử xóa token và đăng nhập lại
214
+ - Bật tính năng CLI fallback: `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1`
215
+
216
+ **2. OAuth timeout**
217
+ - Kiểm tra lại kết nối mạng
218
+ - Tăng timeout trong cấu hình nếu cần
219
+ - Xem log chi tiết bằng cách bật `DEBUG_QWEN_PLUGIN=1`
220
+
221
+ **3. Không tìm thấy qwen CLI**
222
+ - Cài đặt qwen-code: `npm install -g @qwen-code/qwen-code`
223
+ - Hoặc cấu hình biến: `QWEN_CLI_PATH=/path/to/qwen`
224
+
225
+ **4. Không lưu được token**
226
+ - Kiểm tra quyền ghi (write permissions) cho thư mục `~/.qwen/`
227
+ - Xem log bằng cách bật `ENABLE_PLUGIN_REQUEST_LOGGING=1`
228
+
229
+ ## Phát triển
230
+
231
+ ### Build
232
+
233
+ ```bash
234
+ npm install
235
+ npm run build
236
+ ```
237
+
238
+ ### Test
239
+
240
+ ```bash
241
+ npm test
242
+ ```
243
+
244
+ ### Type Check
245
+
246
+ ```bash
247
+ npm run typecheck
248
+ ```
249
+
250
+ ### Lint & Format
251
+
252
+ ```bash
253
+ npm run lint
254
+ npm run format
255
+ ```
256
+
257
+ ## Giấy phép (License)
258
+
259
+ MIT
260
+
261
+ ## Repository
262
+
263
+ - **Mã nguồn**: https://github.com/TVD-00/opencode-qwen-cli-auth
264
+ - **Báo lỗi (Issues)**: https://github.com/TVD-00/opencode-qwen-cli-auth/issues
265
+ - **NPM**: https://www.npmjs.com/package/opencode-qwen-cli-auth
266
+
267
+ ## Tác giả
268
+
269
+ Geoff Hammond
270
+
271
+ ## Đóng góp
272
+
273
+ Mọi sự đóng góp (PR, issue, feedback) đều được hoan nghênh tại GitHub repository.