opencode-qwencode-auth 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Gustavo Dias
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ # πŸ€– Qwen Code OAuth Plugin for OpenCode
2
+
3
+ ![License](https://img.shields.io/github/license/gustavodiasdev/opencode-qwencode-auth)
4
+ ![GitHub stars](https://img.shields.io/github/stars/gustavodiasdev/opencode-qwencode-auth)
5
+
6
+ **Authenticate OpenCode CLI with your qwen.ai account.** This plugin enables you to use Qwen3-Coder models with **2,000 free requests per day** - no API key or credit card required!
7
+
8
+ [πŸ‡§πŸ‡· Leia em PortuguΓͺs](./README.pt-BR.md)
9
+
10
+ ## ✨ Features
11
+
12
+ - πŸ” **OAuth Device Flow** - Secure browser-based authentication (RFC 8628)
13
+ - ⚑ **Automatic Polling** - No need to press Enter after authorizing
14
+ - πŸ†“ **2,000 req/day free** - Generous free tier with no credit card
15
+ - 🧠 **1M context window** - Models with 1 million token context
16
+ - πŸ”„ **Auto-refresh** - Tokens renewed automatically before expiration
17
+ - πŸ”— **qwen-code compatible** - Reuses credentials from `~/.qwen/oauth_creds.json`
18
+
19
+ ## πŸ“‹ Prerequisites
20
+
21
+ - [OpenCode CLI](https://opencode.ai) installed
22
+ - A [qwen.ai](https://chat.qwen.ai) account (free to create)
23
+
24
+ ## πŸš€ Installation
25
+
26
+ ### 1. Add the plugin to OpenCode
27
+
28
+ Edit `~/.opencode/package.json`:
29
+
30
+ ```json
31
+ {
32
+ "dependencies": {
33
+ "opencode-qwencode-auth": "github:gustavodiasdev/opencode-qwencode-auth"
34
+ }
35
+ }
36
+ ```
37
+
38
+ Edit `~/.opencode/opencode.jsonc`:
39
+
40
+ ```json
41
+ {
42
+ "plugin": ["opencode-qwencode-auth"]
43
+ }
44
+ ```
45
+
46
+ ### 2. Install dependencies
47
+
48
+ ```bash
49
+ cd ~/.opencode && npm install
50
+ ```
51
+
52
+ ## πŸ”‘ Usage
53
+
54
+ ### 1. Login
55
+
56
+ ```bash
57
+ opencode auth login
58
+ ```
59
+
60
+ ### 2. Select Provider
61
+
62
+ Choose **"Other"** and type `qwen-code`
63
+
64
+ ### 3. Authenticate
65
+
66
+ Select **"Qwen Code (qwen.ai OAuth)"**
67
+
68
+ - A browser window will open for you to authorize
69
+ - The plugin automatically detects when you complete authorization
70
+ - No need to copy/paste codes or press Enter!
71
+
72
+ > [!TIP]
73
+ > In the OpenCode TUI (graphical interface), the **Qwen Code** provider appears automatically in the provider list.
74
+
75
+ ## 🎯 Available Models
76
+
77
+ | Model | Context | Max Output | Best For |
78
+ |-------|---------|------------|----------|
79
+ | `qwen3-coder-plus` | 1M tokens | 64K tokens | Complex coding tasks |
80
+ | `qwen3-coder-flash` | 1M tokens | 64K tokens | Fast responses |
81
+
82
+ ### Using a specific model
83
+
84
+ ```bash
85
+ opencode --provider qwen-code --model qwen3-coder-plus
86
+ ```
87
+
88
+ ## βš™οΈ How It Works
89
+
90
+ ```
91
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
92
+ β”‚ OpenCode CLI │────▢│ qwen.ai OAuth │────▢│ Qwen3-Coder β”‚
93
+ β”‚ │◀────│ (Device Flow) │◀────│ API β”‚
94
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
95
+ ```
96
+
97
+ 1. **Device Flow (RFC 8628)**: Opens your browser to `chat.qwen.ai` for authentication
98
+ 2. **Automatic Polling**: Detects authorization completion automatically
99
+ 3. **Token Storage**: Saves credentials to `~/.qwen/oauth_creds.json`
100
+ 4. **Auto-refresh**: Renews tokens 30 seconds before expiration
101
+
102
+ ## πŸ“Š Usage Limits
103
+
104
+ | Plan | Rate Limit | Daily Limit |
105
+ |------|------------|-------------|
106
+ | Free (OAuth) | 60 req/min | 2,000 req/day |
107
+
108
+ > [!NOTE]
109
+ > Limits reset at midnight UTC. For higher limits, consider using an API key from [DashScope](https://dashscope.aliyun.com).
110
+
111
+ ## πŸ”§ Troubleshooting
112
+
113
+ ### Token expired
114
+
115
+ The plugin automatically renews tokens. If issues persist:
116
+
117
+ ```bash
118
+ # Remove old credentials
119
+ rm ~/.qwen/oauth_creds.json
120
+
121
+ # Re-authenticate
122
+ opencode auth login
123
+ ```
124
+
125
+ ### Provider not showing in `auth login`
126
+
127
+ The `qwen-code` provider is added via plugin. In the `opencode auth login` command:
128
+
129
+ 1. Select **"Other"**
130
+ 2. Type `qwen-code`
131
+
132
+ ### Rate limit exceeded (429 errors)
133
+
134
+ - Wait until midnight UTC for quota reset
135
+ - Try using `qwen3-coder-flash` for faster, lighter requests
136
+ - Consider [DashScope API](https://dashscope.aliyun.com) for higher limits
137
+
138
+ ## πŸ› οΈ Development
139
+
140
+ ```bash
141
+ # Clone the repository
142
+ git clone https://github.com/gustavodiasdev/opencode-qwencode-auth.git
143
+ cd opencode-qwencode-auth
144
+
145
+ # Install dependencies
146
+ bun install
147
+
148
+ # Type check
149
+ bun run typecheck
150
+ ```
151
+
152
+ ### Local testing
153
+
154
+ Edit `~/.opencode/package.json`:
155
+
156
+ ```json
157
+ {
158
+ "dependencies": {
159
+ "opencode-qwencode-auth": "file:///absolute/path/to/opencode-qwencode-auth"
160
+ }
161
+ }
162
+ ```
163
+
164
+ Then reinstall:
165
+
166
+ ```bash
167
+ cd ~/.opencode && npm install
168
+ ```
169
+
170
+ ## πŸ“ Project Structure
171
+
172
+ ```
173
+ src/
174
+ β”œβ”€β”€ constants.ts # OAuth endpoints, models config
175
+ β”œβ”€β”€ types.ts # TypeScript interfaces
176
+ β”œβ”€β”€ index.ts # Main plugin entry point
177
+ β”œβ”€β”€ qwen/
178
+ β”‚ └── oauth.ts # OAuth Device Flow + PKCE
179
+ └── plugin/
180
+ β”œβ”€β”€ auth.ts # Credentials management
181
+ └── utils.ts # Helper utilities
182
+ ```
183
+
184
+ ## πŸ”— Related Projects
185
+
186
+ - [qwen-code](https://github.com/QwenLM/qwen-code) - Official Qwen coding CLI
187
+ - [OpenCode](https://opencode.ai) - AI-powered CLI for development
188
+ - [opencode-gemini-auth](https://github.com/jenslys/opencode-gemini-auth) - Similar plugin for Google Gemini
189
+
190
+ ## πŸ“„ License
191
+
192
+ MIT
193
+
194
+ ---
195
+
196
+ <p align="center">
197
+ Made with ❀️ for the OpenCode community
198
+ </p>
@@ -0,0 +1,198 @@
1
+ # πŸ€– Qwen Code OAuth Plugin para OpenCode
2
+
3
+ ![License](https://img.shields.io/github/license/gustavodiasdev/opencode-qwencode-auth)
4
+ ![GitHub stars](https://img.shields.io/github/stars/gustavodiasdev/opencode-qwencode-auth)
5
+
6
+ **Autentique o OpenCode CLI com sua conta qwen.ai.** Este plugin permite usar modelos Qwen3-Coder com **2.000 requisiΓ§Γ΅es gratuitas por dia** - sem API key ou cartΓ£o de crΓ©dito!
7
+
8
+ [πŸ‡ΊπŸ‡Έ Read in English](./README.md)
9
+
10
+ ## ✨ Funcionalidades
11
+
12
+ - πŸ” **OAuth Device Flow** - AutenticaΓ§Γ£o segura via navegador (RFC 8628)
13
+ - ⚑ **Polling AutomÑtico** - Não precisa pressionar Enter após autorizar
14
+ - πŸ†“ **2.000 req/dia grΓ‘tis** - Plano gratuito generoso sem cartΓ£o
15
+ - 🧠 **1M de contexto** - Modelos com 1 milhão de tokens de contexto
16
+ - πŸ”„ **Auto-refresh** - Tokens renovados automaticamente antes de expirar
17
+ - πŸ”— **CompatΓ­vel com qwen-code** - Reutiliza credenciais de `~/.qwen/oauth_creds.json`
18
+
19
+ ## πŸ“‹ PrΓ©-requisitos
20
+
21
+ - [OpenCode CLI](https://opencode.ai) instalado
22
+ - Uma conta [qwen.ai](https://chat.qwen.ai) (gratuita)
23
+
24
+ ## πŸš€ InstalaΓ§Γ£o
25
+
26
+ ### 1. Adicione o plugin ao OpenCode
27
+
28
+ Edite `~/.opencode/package.json`:
29
+
30
+ ```json
31
+ {
32
+ "dependencies": {
33
+ "opencode-qwencode-auth": "github:gustavodiasdev/opencode-qwencode-auth"
34
+ }
35
+ }
36
+ ```
37
+
38
+ Edite `~/.opencode/opencode.jsonc`:
39
+
40
+ ```json
41
+ {
42
+ "plugin": ["opencode-qwencode-auth"]
43
+ }
44
+ ```
45
+
46
+ ### 2. Instale as dependΓͺncias
47
+
48
+ ```bash
49
+ cd ~/.opencode && npm install
50
+ ```
51
+
52
+ ## πŸ”‘ Uso
53
+
54
+ ### 1. Login
55
+
56
+ ```bash
57
+ opencode auth login
58
+ ```
59
+
60
+ ### 2. Selecione o Provider
61
+
62
+ Escolha **"Other"** e digite `qwen-code`
63
+
64
+ ### 3. Autentique
65
+
66
+ Selecione **"Qwen Code (qwen.ai OAuth)"**
67
+
68
+ - Uma janela do navegador abrirΓ‘ para vocΓͺ autorizar
69
+ - O plugin detecta automaticamente quando vocΓͺ completa a autorizaΓ§Γ£o
70
+ - NΓ£o precisa copiar/colar cΓ³digos ou pressionar Enter!
71
+
72
+ > [!TIP]
73
+ > No TUI do OpenCode (interface grΓ‘fica), o provider **Qwen Code** aparece automaticamente na lista de providers.
74
+
75
+ ## 🎯 Modelos Disponíveis
76
+
77
+ | Modelo | Contexto | Max Output | Melhor Para |
78
+ |--------|----------|------------|-------------|
79
+ | `qwen3-coder-plus` | 1M tokens | 64K tokens | Tarefas complexas de cΓ³digo |
80
+ | `qwen3-coder-flash` | 1M tokens | 64K tokens | Respostas rΓ‘pidas |
81
+
82
+ ### Usando um modelo especΓ­fico
83
+
84
+ ```bash
85
+ opencode --provider qwen-code --model qwen3-coder-plus
86
+ ```
87
+
88
+ ## βš™οΈ Como Funciona
89
+
90
+ ```
91
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
92
+ β”‚ OpenCode CLI │────▢│ qwen.ai OAuth │────▢│ Qwen3-Coder β”‚
93
+ β”‚ │◀────│ (Device Flow) │◀────│ API β”‚
94
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
95
+ ```
96
+
97
+ 1. **Device Flow (RFC 8628)**: Abre seu navegador em `chat.qwen.ai` para autenticaΓ§Γ£o
98
+ 2. **Polling AutomΓ‘tico**: Detecta a conclusΓ£o da autorizaΓ§Γ£o automaticamente
99
+ 3. **Armazenamento de Token**: Salva credenciais em `~/.qwen/oauth_creds.json`
100
+ 4. **Auto-refresh**: Renova tokens 30 segundos antes de expirar
101
+
102
+ ## πŸ“Š Limites de Uso
103
+
104
+ | Plano | Rate Limit | Limite DiΓ‘rio |
105
+ |-------|------------|---------------|
106
+ | Gratuito (OAuth) | 60 req/min | 2.000 req/dia |
107
+
108
+ > [!NOTE]
109
+ > Os limites resetam Γ  meia-noite UTC. Para limites maiores, considere usar uma API key do [DashScope](https://dashscope.aliyun.com).
110
+
111
+ ## πŸ”§ SoluΓ§Γ£o de Problemas
112
+
113
+ ### Token expirado
114
+
115
+ O plugin renova tokens automaticamente. Se houver problemas:
116
+
117
+ ```bash
118
+ # Remova credenciais antigas
119
+ rm ~/.qwen/oauth_creds.json
120
+
121
+ # Re-autentique
122
+ opencode auth login
123
+ ```
124
+
125
+ ### Provider nΓ£o aparece no `auth login`
126
+
127
+ O provider `qwen-code` Γ© adicionado via plugin. No comando `opencode auth login`:
128
+
129
+ 1. Selecione **"Other"**
130
+ 2. Digite `qwen-code`
131
+
132
+ ### Rate limit excedido (erros 429)
133
+
134
+ - Aguarde atΓ© meia-noite UTC para reset da cota
135
+ - Tente usar `qwen3-coder-flash` para requisiΓ§Γ΅es mais leves
136
+ - Considere a [API DashScope](https://dashscope.aliyun.com) para limites maiores
137
+
138
+ ## πŸ› οΈ Desenvolvimento
139
+
140
+ ```bash
141
+ # Clone o repositΓ³rio
142
+ git clone https://github.com/gustavodiasdev/opencode-qwencode-auth.git
143
+ cd opencode-qwencode-auth
144
+
145
+ # Instale dependΓͺncias
146
+ bun install
147
+
148
+ # Verifique tipos
149
+ bun run typecheck
150
+ ```
151
+
152
+ ### Teste local
153
+
154
+ Edite `~/.opencode/package.json`:
155
+
156
+ ```json
157
+ {
158
+ "dependencies": {
159
+ "opencode-qwencode-auth": "file:///caminho/absoluto/para/opencode-qwencode-auth"
160
+ }
161
+ }
162
+ ```
163
+
164
+ Depois reinstale:
165
+
166
+ ```bash
167
+ cd ~/.opencode && npm install
168
+ ```
169
+
170
+ ## πŸ“ Estrutura do Projeto
171
+
172
+ ```
173
+ src/
174
+ β”œβ”€β”€ constants.ts # Endpoints OAuth, config de modelos
175
+ β”œβ”€β”€ types.ts # Interfaces TypeScript
176
+ β”œβ”€β”€ index.ts # Entry point principal do plugin
177
+ β”œβ”€β”€ qwen/
178
+ β”‚ └── oauth.ts # OAuth Device Flow + PKCE
179
+ └── plugin/
180
+ β”œβ”€β”€ auth.ts # Gerenciamento de credenciais
181
+ └── utils.ts # UtilitΓ‘rios
182
+ ```
183
+
184
+ ## πŸ”— Projetos Relacionados
185
+
186
+ - [qwen-code](https://github.com/QwenLM/qwen-code) - CLI oficial do Qwen para programaΓ§Γ£o
187
+ - [OpenCode](https://opencode.ai) - CLI com IA para desenvolvimento
188
+ - [opencode-gemini-auth](https://github.com/jenslys/opencode-gemini-auth) - Plugin similar para Google Gemini
189
+
190
+ ## πŸ“„ LicenΓ§a
191
+
192
+ MIT
193
+
194
+ ---
195
+
196
+ <p align="center">
197
+ Feito com ❀️ para a comunidade OpenCode
198
+ </p>
package/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ // Apenas exportar o plugin principal
2
+ // NÃO exportar funçáes utilitÑrias pois o OpenCode trata todas as exportaçáes como plugins
3
+ export { QwenAuthPlugin, default } from "./src/index";
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "opencode-qwencode-auth",
3
+ "version": "1.0.0",
4
+ "description": "Qwen OAuth authentication plugin for OpenCode - Access Qwen3-Coder models with your qwen.ai account",
5
+ "module": "index.ts",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build": "bun build ./src/index.ts --outdir ./dist --target node --format esm && bun build ./src/cli.ts --outdir ./dist --target node --format esm",
9
+ "dev": "bun run --watch src/index.ts",
10
+ "typecheck": "tsc --noEmit"
11
+ },
12
+ "keywords": [
13
+ "opencode",
14
+ "qwen",
15
+ "qwen-code",
16
+ "qwen3-coder",
17
+ "oauth",
18
+ "authentication",
19
+ "ai",
20
+ "llm",
21
+ "opencode-plugins"
22
+ ],
23
+ "author": "Gustavo Dias <me@gustavodias.dev>",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/gustavodiasdev/opencode-qwencode-auth.git"
28
+ },
29
+ "homepage": "https://github.com/gustavodiasdev/opencode-qwencode-auth#readme",
30
+ "bugs": {
31
+ "url": "https://github.com/gustavodiasdev/opencode-qwencode-auth/issues"
32
+ },
33
+ "dependencies": {
34
+ "open": "^10.1.0"
35
+ },
36
+ "devDependencies": {
37
+ "@opencode-ai/plugin": "^1.1.48",
38
+ "@types/node": "^22.0.0",
39
+ "bun-types": "^1.1.0",
40
+ "typescript": "^5.6.0"
41
+ },
42
+ "files": [
43
+ "index.ts",
44
+ "src",
45
+ "README.md"
46
+ ],
47
+ "engines": {
48
+ "node": ">=20.0.0"
49
+ }
50
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Qwen Auth CLI Helper
4
+ *
5
+ * This script helps with manual authentication when the automatic
6
+ * OAuth flow doesn't work (e.g., in SSH sessions, containers, etc.)
7
+ */
8
+
9
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
10
+ import { homedir } from 'node:os';
11
+ import { join } from 'node:path';
12
+ import { createInterface } from 'node:readline';
13
+
14
+ const CREDS_PATH = join(homedir(), '.qwen', 'oauth_creds.json');
15
+
16
+ const rl = createInterface({
17
+ input: process.stdin,
18
+ output: process.stdout,
19
+ });
20
+
21
+ function question(prompt: string): Promise<string> {
22
+ return new Promise((resolve) => {
23
+ rl.question(prompt, resolve);
24
+ });
25
+ }
26
+
27
+ async function main() {
28
+ console.log('\nQwen Auth CLI Helper\n');
29
+ console.log('This tool helps you set up Qwen authentication manually.\n');
30
+
31
+ // Check for existing credentials
32
+ if (existsSync(CREDS_PATH)) {
33
+ const data = JSON.parse(readFileSync(CREDS_PATH, 'utf-8'));
34
+ console.log('Existing credentials found at:', CREDS_PATH);
35
+
36
+ if (data.access_token) {
37
+ console.log('Access token: Present');
38
+ console.log('Email:', data.email || 'Not set');
39
+ console.log('Updated at:', data.updated_at ? new Date(data.updated_at).toISOString() : 'Unknown');
40
+
41
+ const overwrite = await question('\nOverwrite existing credentials? (y/N): ');
42
+ if (overwrite.toLowerCase() !== 'y') {
43
+ console.log('\nKeeping existing credentials. Exiting.');
44
+ rl.close();
45
+ return;
46
+ }
47
+ }
48
+ }
49
+
50
+ console.log('\nInstructions:');
51
+ console.log('1. Open https://chat.qwen.ai in your browser');
52
+ console.log('2. Sign in with your account');
53
+ console.log('3. Open Developer Tools (F12) -> Network tab');
54
+ console.log('4. Make any chat request');
55
+ console.log('5. Find a request to chat.qwen.ai');
56
+ console.log('6. Copy the "Authorization" header value (starts with "Bearer ...")');
57
+ console.log('');
58
+
59
+ const token = await question('Paste your Bearer token (or just the token without "Bearer "): ');
60
+
61
+ if (!token.trim()) {
62
+ console.log('No token provided. Exiting.');
63
+ rl.close();
64
+ return;
65
+ }
66
+
67
+ // Clean up the token
68
+ let accessToken = token.trim();
69
+ if (accessToken.toLowerCase().startsWith('bearer ')) {
70
+ accessToken = accessToken.slice(7);
71
+ }
72
+
73
+ const email = await question('Email (optional, press Enter to skip): ');
74
+
75
+ // Save credentials
76
+ const dir = join(homedir(), '.qwen');
77
+ if (!existsSync(dir)) {
78
+ mkdirSync(dir, { recursive: true });
79
+ }
80
+
81
+ const credentials = {
82
+ access_token: accessToken,
83
+ email: email.trim() || undefined,
84
+ updated_at: Date.now(),
85
+ };
86
+
87
+ writeFileSync(CREDS_PATH, JSON.stringify(credentials, null, 2));
88
+
89
+ console.log('\nCredentials saved to:', CREDS_PATH);
90
+ console.log('\nYou can now use OpenCode with Qwen models:');
91
+ console.log(' opencode --model qwen/qwen3-coder-plus');
92
+
93
+ rl.close();
94
+ }
95
+
96
+ main().catch((error) => {
97
+ console.error('Error:', error);
98
+ rl.close();
99
+ process.exit(1);
100
+ });
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Qwen OAuth and API Constants
3
+ * Based on qwen-code implementation
4
+ */
5
+
6
+ // Provider ID - cria provider separado para OAuth
7
+ export const QWEN_PROVIDER_ID = 'qwen-code';
8
+
9
+ // OAuth Device Flow Endpoints (descobertos do qwen-code)
10
+ export const QWEN_OAUTH_CONFIG = {
11
+ baseUrl: 'https://chat.qwen.ai',
12
+ deviceCodeEndpoint: 'https://chat.qwen.ai/api/v1/oauth2/device/code',
13
+ tokenEndpoint: 'https://chat.qwen.ai/api/v1/oauth2/token',
14
+ clientId: 'f0304373b74a44d2b584a3fb70ca9e56',
15
+ scope: 'openid profile email model.completion',
16
+ grantType: 'urn:ietf:params:oauth:grant-type:device_code',
17
+ } as const;
18
+
19
+ // Qwen API Configuration
20
+ // O resource_url das credenciais Γ© usado para determinar a URL base
21
+ export const QWEN_API_CONFIG = {
22
+ // Default base URL (pode ser sobrescrito pelo resource_url das credenciais)
23
+ defaultBaseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
24
+ // Portal URL (usado quando resource_url = "portal.qwen.ai")
25
+ portalBaseUrl: 'https://portal.qwen.ai/v1',
26
+ // Endpoint de chat completions
27
+ chatEndpoint: '/chat/completions',
28
+ // Endpoint de models
29
+ modelsEndpoint: '/models',
30
+ // Usado pelo OpenCode para configurar o provider
31
+ baseUrl: 'https://portal.qwen.ai/v1',
32
+ } as const;
33
+
34
+ // OAuth callback port (para futuro Device Flow no plugin)
35
+ export const CALLBACK_PORT = 14561;
36
+
37
+ // Available Qwen models through OAuth
38
+ // Baseado nos modelos disponΓ­veis no qwen-code
39
+ export const QWEN_MODELS = {
40
+ 'qwen3-coder-plus': {
41
+ id: 'qwen3-coder-plus',
42
+ name: 'Qwen3 Coder Plus',
43
+ contextWindow: 1048576, // 1M tokens
44
+ maxOutput: 65536, // 64K tokens
45
+ description: 'Most capable Qwen coding model with 1M context window',
46
+ cost: { input: 0, output: 0 }, // Free via OAuth
47
+ },
48
+ 'qwen3-coder-flash': {
49
+ id: 'qwen3-coder-flash',
50
+ name: 'Qwen3 Coder Flash',
51
+ contextWindow: 1048576,
52
+ maxOutput: 65536,
53
+ description: 'Faster Qwen coding model for quick responses',
54
+ cost: { input: 0, output: 0 },
55
+ },
56
+ } as const;