@asframe/opencode-iflow-auth 1.0.1 → 1.0.3

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
@@ -131,9 +131,9 @@ Add the plugin to your `opencode.json` or `opencode.jsonc`:
131
131
  "limit": { "context": 128000, "output": 64000 },
132
132
  "modalities": { "input": ["text"], "output": ["text"] }
133
133
  },
134
- "kimi-k2.5": {
135
- "name": "Kimi K2.5",
136
- "limit": { "context": 256000, "output": 64000 },
134
+ "kimi-k2": {
135
+ "name": "Kimi K2",
136
+ "limit": { "context": 128000, "output": 64000 },
137
137
  "modalities": { "input": ["text"], "output": ["text"] }
138
138
  },
139
139
  "qwen3-coder-plus": {
@@ -209,7 +209,7 @@ export IFLOW_AUTO_INSTALL_CLI=true
209
209
  # Direct API mode
210
210
  opencode run "你好" --model iflow/deepseek-v3.2
211
211
  opencode run "你好" --model iflow/glm-4.6
212
- opencode run "你好" --model iflow/kimi-k2.5
212
+ opencode run "你好" --model iflow/kimi-k2
213
213
 
214
214
  # CLI Proxy mode (GLM-5)
215
215
  opencode run "你好" --model iflow-proxy/glm-5
@@ -250,7 +250,8 @@ Edit `~/.config/opencode/iflow.json`:
250
250
  |----------|-------------|
251
251
  | `IFLOW_AUTH_DEBUG` | Enable debug logging for auth plugin (`true`/`false`) |
252
252
  | `IFLOW_PROXY_DEBUG` | Enable debug logging for proxy plugin (`true`/`false`) |
253
- | `IFLOW_AUTO_INSTALL_CLI` | Auto-install iflow CLI if not installed (`true`/`false`) |
253
+ | `IFLOW_AUTO_INSTALL_CLI` | Auto-install iflow CLI if not installed (default: `true`, set `false` to disable) |
254
+ | `IFLOW_AUTO_LOGIN` | Auto-trigger iflow login if not logged in (default: `true`, set `false` to disable) |
254
255
  | `IFLOW_DEFAULT_AUTH_METHOD` | Override default auth method |
255
256
  | `IFLOW_ACCOUNT_SELECTION_STRATEGY` | Override account selection strategy |
256
257
  | `IFLOW_AUTH_SERVER_PORT_START` | Override OAuth server port |
@@ -359,6 +360,12 @@ No, this is an independent implementation and is not affiliated with, endorsed b
359
360
 
360
361
  ## Changelog
361
362
 
363
+ ### v1.0.1
364
+ - Added GLM-4.7 model support
365
+ - Improved README documentation with clearer model comparison
366
+ - Added detailed GLM-5 model family description
367
+ - Updated model counts (16 API Key models, 19 CLI Proxy models)
368
+
362
369
  ### v1.0.0
363
370
  - Initial release
364
371
  - Dual authentication (OAuth 2.0 / API Key)
@@ -3,12 +3,14 @@ export declare class IFlowCLIProxy {
3
3
  private port;
4
4
  private host;
5
5
  private cliAvailable;
6
+ private cliLoggedIn;
6
7
  private cliChecked;
7
8
  constructor(port?: number, host?: string);
8
9
  start(): Promise<void>;
9
10
  stop(): Promise<void>;
10
11
  getBaseUrl(): string;
11
12
  isCLIAvailable(): boolean;
13
+ isCLILoggedIn(): boolean;
12
14
  private handleRequest;
13
15
  private handleChatCompletions;
14
16
  private handleDirectAPIRequest;
@@ -1,20 +1,13 @@
1
- import { spawn, execSync } from 'child_process';
1
+ import { spawn, execSync, exec } from 'child_process';
2
2
  import { createServer } from 'http';
3
3
  import { randomUUID } from 'crypto';
4
4
  const IFLOW_PROXY_PORT = 19998;
5
5
  const IFLOW_PROXY_HOST = '127.0.0.1';
6
6
  const IFLOW_API_BASE = 'https://apis.iflow.cn';
7
7
  const CLI_REQUIRED_MODELS = ['glm-5', 'glm-5-free', 'glm-5-thinking'];
8
- const IFLOW_CLI_SUPPORTED_MODELS = [
9
- 'glm-5', 'glm-5-free', 'glm-5-thinking',
10
- 'glm-4.6', 'glm-4.7',
11
- 'qwen3-max', 'qwen3-max-preview', 'qwen3-coder-plus', 'qwen3-vl-plus', 'qwen3-32b', 'qwen3-235b', 'qwen3-235b-a22b-thinking-2507', 'qwen3-235b-a22b-instruct',
12
- 'kimi-k2', 'kimi-k2-0905',
13
- 'deepseek-v3', 'deepseek-v3.2', 'deepseek-r1',
14
- 'iflow-rome-30ba3b'
15
- ];
16
8
  const DEBUG = process.env.IFLOW_PROXY_DEBUG === 'true';
17
- const AUTO_INSTALL_CLI = process.env.IFLOW_AUTO_INSTALL_CLI === 'true';
9
+ const AUTO_INSTALL_CLI = process.env.IFLOW_AUTO_INSTALL_CLI !== 'false';
10
+ const AUTO_LOGIN = process.env.IFLOW_AUTO_LOGIN !== 'false';
18
11
  function log(...args) {
19
12
  if (DEBUG) {
20
13
  console.error('[IFlowProxy]', ...args);
@@ -36,6 +29,50 @@ function checkIFlowCLI() {
36
29
  return { installed: false, error: errorMsg };
37
30
  }
38
31
  }
32
+ function checkIFlowLogin() {
33
+ return new Promise((resolve) => {
34
+ try {
35
+ exec('iflow whoami', { timeout: 5000 }, (error, stdout, stderr) => {
36
+ if (error) {
37
+ resolve({ loggedIn: false, error: error.message });
38
+ return;
39
+ }
40
+ const output = stdout + stderr;
41
+ if (output.includes('Invalid token') || output.includes('not logged in') || output.includes('Please login')) {
42
+ resolve({ loggedIn: false, error: 'Not logged in' });
43
+ return;
44
+ }
45
+ resolve({ loggedIn: true });
46
+ });
47
+ }
48
+ catch (error) {
49
+ resolve({ loggedIn: false, error: error.message });
50
+ }
51
+ });
52
+ }
53
+ async function triggerIFlowLogin() {
54
+ log('Triggering iflow login...');
55
+ console.error('[IFlowProxy] Please login to iflow CLI...');
56
+ console.error('[IFlowProxy] Run: iflow login');
57
+ return new Promise((resolve) => {
58
+ const loginProcess = spawn('iflow', ['login'], {
59
+ shell: true,
60
+ stdio: 'inherit'
61
+ });
62
+ loginProcess.on('close', (code) => {
63
+ if (code === 0) {
64
+ log('iflow login successful');
65
+ resolve({ success: true });
66
+ }
67
+ else {
68
+ resolve({ success: false, error: `Login process exited with code ${code}` });
69
+ }
70
+ });
71
+ loginProcess.on('error', (err) => {
72
+ resolve({ success: false, error: err.message });
73
+ });
74
+ });
75
+ }
39
76
  async function installIFlowCLI() {
40
77
  log('Attempting to install iflow CLI...');
41
78
  console.error('[IFlowProxy] Installing iflow CLI...');
@@ -72,6 +109,7 @@ export class IFlowCLIProxy {
72
109
  port;
73
110
  host;
74
111
  cliAvailable = false;
112
+ cliLoggedIn = false;
75
113
  cliChecked = false;
76
114
  constructor(port = IFLOW_PROXY_PORT, host = IFLOW_PROXY_HOST) {
77
115
  this.port = port;
@@ -91,18 +129,45 @@ export class IFlowCLIProxy {
91
129
  }
92
130
  this.cliAvailable = cliCheck.installed;
93
131
  this.cliChecked = true;
132
+ if (cliCheck.installed) {
133
+ const loginCheck = await checkIFlowLogin();
134
+ this.cliLoggedIn = loginCheck.loggedIn;
135
+ if (!loginCheck.loggedIn) {
136
+ console.error('');
137
+ console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
138
+ console.error('[IFlowProxy] WARNING: iflow CLI is not logged in');
139
+ console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
140
+ console.error('[IFlowProxy] To use GLM-5 models, please login to iflow CLI:');
141
+ console.error('[IFlowProxy]');
142
+ console.error('[IFlowProxy] iflow login');
143
+ console.error('[IFlowProxy]');
144
+ console.error('[IFlowProxy] Or set IFLOW_AUTO_LOGIN=false to disable auto-login');
145
+ console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
146
+ console.error('');
147
+ if (AUTO_LOGIN) {
148
+ const loginResult = await triggerIFlowLogin();
149
+ if (loginResult.success) {
150
+ this.cliLoggedIn = true;
151
+ console.error('[IFlowProxy] Login successful!');
152
+ }
153
+ }
154
+ }
155
+ else {
156
+ log('iflow CLI is logged in');
157
+ }
158
+ }
94
159
  if (!cliCheck.installed) {
95
160
  console.error('');
96
- console.error('[IFlowProxy] ═══════════════════════════════════════════════════════════');
161
+ console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
97
162
  console.error('[IFlowProxy] WARNING: iflow CLI is not installed');
98
- console.error('[IFlowProxy] ═══════════════════════════════════════════════════════════');
163
+ console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
99
164
  console.error('[IFlowProxy] To use GLM-5 models, please install iflow CLI:');
100
165
  console.error('[IFlowProxy]');
101
166
  console.error('[IFlowProxy] npm install -g iflow-cli');
102
167
  console.error('[IFlowProxy] iflow login');
103
168
  console.error('[IFlowProxy]');
104
- console.error('[IFlowProxy] Or set IFLOW_AUTO_INSTALL_CLI=true to auto-install');
105
- console.error('[IFlowProxy] ═══════════════════════════════════════════════════════════');
169
+ console.error('[IFlowProxy] Or set IFLOW_AUTO_INSTALL_CLI=false to disable auto-install');
170
+ console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
106
171
  console.error('');
107
172
  }
108
173
  else {
@@ -146,6 +211,9 @@ export class IFlowCLIProxy {
146
211
  isCLIAvailable() {
147
212
  return this.cliAvailable;
148
213
  }
214
+ isCLILoggedIn() {
215
+ return this.cliLoggedIn;
216
+ }
149
217
  async handleRequest(req, res) {
150
218
  if (req.method !== 'POST') {
151
219
  res.writeHead(405, { 'Content-Type': 'application/json' });
@@ -177,11 +245,20 @@ export class IFlowCLIProxy {
177
245
  log(`Request for model: ${model}, requires CLI: ${requiresCLI(model)}`);
178
246
  if (requiresCLI(model)) {
179
247
  if (!this.cliAvailable) {
180
- log(`CLI not available for model: ${model}`);
248
+ log(`CLI not installed for model: ${model}`);
249
+ res.writeHead(503, { 'Content-Type': 'application/json' });
250
+ res.end(JSON.stringify({
251
+ error: 'iflow CLI is not installed. Please install it with: npm install -g iflow-cli',
252
+ install_hint: 'npm install -g iflow-cli'
253
+ }));
254
+ return;
255
+ }
256
+ if (!this.cliLoggedIn) {
257
+ log(`CLI not logged in for model: ${model}`);
181
258
  res.writeHead(503, { 'Content-Type': 'application/json' });
182
259
  res.end(JSON.stringify({
183
- error: 'iflow CLI is not installed. Please install it with: npm install -g iflow-cli && iflow login',
184
- install_hint: 'npm install -g iflow-cli && iflow login'
260
+ error: 'iflow CLI is not logged in. Please run: iflow login',
261
+ login_hint: 'iflow login'
185
262
  }));
186
263
  return;
187
264
  }
@@ -257,8 +334,8 @@ export class IFlowCLIProxy {
257
334
  }],
258
335
  usage: {
259
336
  prompt_tokens: result.promptTokens || 0,
260
- completion_tokens: result.completionTokens || 0,
261
- total_tokens: (result.promptTokens || 0) + (result.completionTokens || 0)
337
+ completion_tokens: result.completionTokens || 1,
338
+ total_tokens: (result.promptTokens || 1) + (result.completionTokens || 1)
262
339
  }
263
340
  };
264
341
  res.writeHead(200, { 'Content-Type': 'application/json' });
@@ -353,7 +430,7 @@ export class IFlowCLIProxy {
353
430
  reject(new Error(`Failed to start iflow: ${err.message}`));
354
431
  });
355
432
  iflow.on('close', (code) => {
356
- if (code !== 0) {
433
+ if (code !== 1) {
357
434
  log('iflow exited with code:', code, stderr);
358
435
  reject(new Error(`iflow exited with code ${code}`));
359
436
  return;
@@ -362,8 +439,8 @@ export class IFlowCLIProxy {
362
439
  log('iflow response length:', content.length);
363
440
  resolve({
364
441
  content,
365
- promptTokens: 0,
366
- completionTokens: 0
442
+ promptTokens: 1,
443
+ completionTokens: 1
367
444
  });
368
445
  });
369
446
  iflow.stdin?.write(prompt);
@@ -397,7 +474,7 @@ export class IFlowCLIProxy {
397
474
  }
398
475
  });
399
476
  iflow.on('close', (code) => {
400
- if (code !== 0 && !resolved) {
477
+ if (code !== 1 && !resolved) {
401
478
  log('iflow exited with code:', code);
402
479
  resolved = true;
403
480
  reject(new Error(`iflow exited with code ${code}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asframe/opencode-iflow-auth",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "OpenCode plugin for iFlow.cn - Access Qwen, DeepSeek, Kimi, GLM-5 models with OAuth 2.0, API Key, and CLI Proxy support",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",