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.
@@ -1,31 +1,41 @@
1
1
  /**
2
- * Browser utilities for OAuth flow
3
- * Handles platform-specific browser opening
2
+ * @fileoverview Browser utilities for OAuth flow
3
+ * Handles platform-specific browser opening for OAuth authorization URL
4
+ * @license MIT
4
5
  */
6
+
5
7
  import { spawn } from "node:child_process";
6
8
  import { PLATFORM_OPENERS } from "../constants.js";
9
+
7
10
  /**
8
11
  * Gets the platform-specific command to open a URL in the default browser
9
- * @returns Browser opener command for the current platform
12
+ * @returns {string} Browser opener command for the current platform (darwin: 'open', win32: 'start', linux: 'xdg-open')
10
13
  */
11
14
  export function getBrowserOpener() {
12
15
  const platform = process.platform;
16
+ // macOS uses 'open' command
13
17
  if (platform === "darwin")
14
18
  return PLATFORM_OPENERS.darwin;
19
+ // Windows uses 'start' command
15
20
  if (platform === "win32")
16
21
  return PLATFORM_OPENERS.win32;
22
+ // Linux uses 'xdg-open' command
17
23
  return PLATFORM_OPENERS.linux;
18
24
  }
25
+
19
26
  /**
20
27
  * Opens a URL in the default browser
21
28
  * Silently fails if browser cannot be opened (user can copy URL manually)
22
- * @param url - URL to open
29
+ * @param {string} url - The URL to open in browser (typically OAuth verification URL)
30
+ * @returns {void}
23
31
  */
24
32
  export function openBrowserUrl(url) {
25
33
  try {
26
34
  const opener = getBrowserOpener();
35
+ // Spawn browser process with detached stdio to avoid blocking
27
36
  spawn(opener, [url], {
28
37
  stdio: "ignore",
38
+ // Use shell on Windows for 'start' command to work properly
29
39
  shell: process.platform === "win32",
30
40
  });
31
41
  }
@@ -29,6 +29,14 @@ export declare function getTokenPath(): string;
29
29
  * Get token lock path for multi-process refresh coordination
30
30
  */
31
31
  export declare function getTokenLockPath(): string;
32
+ /**
33
+ * Get multi-account storage path
34
+ */
35
+ export declare function getAccountsPath(): string;
36
+ /**
37
+ * Get multi-account lock path
38
+ */
39
+ export declare function getAccountsLockPath(): string;
32
40
  /**
33
41
  * Get legacy token storage path used by old plugin versions
34
42
  */
@@ -1,30 +1,90 @@
1
+ /**
2
+ * @fileoverview Configuration utilities for Qwen OAuth Plugin
3
+ * Manages paths for configuration, tokens, and cache directories
4
+ * @license MIT
5
+ */
6
+
1
7
  import { homedir } from "os";
2
- import { join } from "path";
8
+ import { join, resolve, relative, isAbsolute, parse, dirname } from "path";
3
9
  import { readFileSync, existsSync } from "fs";
10
+
4
11
  /**
5
12
  * Get plugin configuration directory
13
+ * @returns {string} Path to ~/.opencode/qwen/
6
14
  */
7
15
  export function getConfigDir() {
8
16
  return join(homedir(), ".opencode", "qwen");
9
17
  }
18
+
10
19
  /**
11
20
  * Get Qwen CLI credential directory (~/.qwen)
21
+ * This directory is shared with the official qwen-code CLI for token storage
22
+ * @returns {string} Path to ~/.qwen/
12
23
  */
13
24
  export function getQwenDir() {
14
25
  return join(homedir(), ".qwen");
15
26
  }
27
+
28
+ const ACCOUNTS_FILENAME = "oauth_accounts.json";
29
+ const DEFAULT_ACCOUNTS_PATH = join(getQwenDir(), ACCOUNTS_FILENAME);
30
+
31
+ function isRootPath(pathValue) {
32
+ const parsed = parse(pathValue);
33
+ return pathValue === parsed.root;
34
+ }
35
+
36
+ function isPathInsideBase(pathValue, baseDir) {
37
+ const rel = relative(baseDir, pathValue);
38
+ if (rel === "") {
39
+ return true;
40
+ }
41
+ return !rel.startsWith("..") && !isAbsolute(rel);
42
+ }
43
+
44
+ function resolveAccountsPathFromEnv() {
45
+ const envPath = process.env.OPENCODE_QWEN_ACCOUNTS_PATH;
46
+ if (typeof envPath !== "string" || envPath.trim().length === 0) {
47
+ return null;
48
+ }
49
+ const trimmed = envPath.trim();
50
+ if (trimmed.includes("\0")) {
51
+ console.warn("[qwen-oauth-plugin] Ignoring OPENCODE_QWEN_ACCOUNTS_PATH with invalid null-byte");
52
+ return null;
53
+ }
54
+ const resolved = resolve(trimmed);
55
+ if (isRootPath(resolved)) {
56
+ console.warn("[qwen-oauth-plugin] Ignoring OPENCODE_QWEN_ACCOUNTS_PATH pointing to root path");
57
+ return null;
58
+ }
59
+ const baseDir = getQwenDir();
60
+ if (!isPathInsideBase(resolved, baseDir)) {
61
+ console.warn("[qwen-oauth-plugin] Ignoring OPENCODE_QWEN_ACCOUNTS_PATH outside ~/.qwen for safety");
62
+ return null;
63
+ }
64
+ const parsed = parse(resolved);
65
+ if (!parsed.base || parsed.base.length === 0) {
66
+ console.warn("[qwen-oauth-plugin] Ignoring OPENCODE_QWEN_ACCOUNTS_PATH without filename");
67
+ return null;
68
+ }
69
+ return resolved;
70
+ }
71
+
16
72
  /**
17
73
  * Get plugin configuration file path
74
+ * @returns {string} Path to ~/.opencode/qwen/auth-config.json
18
75
  */
19
76
  export function getConfigPath() {
20
77
  return join(getConfigDir(), "auth-config.json");
21
78
  }
79
+
22
80
  /**
23
81
  * Load plugin configuration from ~/.opencode/qwen/auth-config.json
24
82
  * Returns default config if file doesn't exist
83
+ * @returns {{ qwenMode: boolean }} Configuration object with qwenMode flag
25
84
  */
26
85
  export function loadPluginConfig() {
27
86
  const configPath = getConfigPath();
87
+ // Return default config if config file doesn't exist
28
88
  if (!existsSync(configPath)) {
29
89
  return { qwenMode: true }; // Default: QWEN_MODE enabled
30
90
  }
@@ -33,15 +93,20 @@ export function loadPluginConfig() {
33
93
  return JSON.parse(content);
34
94
  }
35
95
  catch (error) {
96
+ // Log warning and return default config on parse error
36
97
  console.warn(`[qwen-oauth-plugin] Failed to load config from ${configPath}:`, error);
37
98
  return { qwenMode: true };
38
99
  }
39
100
  }
101
+
40
102
  /**
41
103
  * Get QWEN_MODE setting
42
104
  * Priority: QWEN_MODE env var > config file > default (true)
105
+ * @param {{ qwenMode?: boolean|string|null }} config - Configuration object from file
106
+ * @returns {boolean} True if QWEN_MODE is enabled, false otherwise
43
107
  */
44
108
  export function getQwenMode(config) {
109
+ // Environment variable takes highest priority
45
110
  const envValue = process.env.QWEN_MODE;
46
111
  if (envValue !== undefined) {
47
112
  return envValue === "1" || envValue.toLowerCase() === "true";
@@ -49,31 +114,64 @@ export function getQwenMode(config) {
49
114
  // Ensure boolean type, avoid string "false" being truthy
50
115
  const val = config.qwenMode;
51
116
  if (val === undefined || val === null) return true; // default: enabled
117
+ // Handle string values from config file
52
118
  if (typeof val === "string") {
53
119
  return val === "1" || val.toLowerCase() === "true";
54
120
  }
121
+ // Convert to boolean for actual boolean values
55
122
  return !!val;
56
123
  }
124
+
57
125
  /**
58
126
  * Get token storage path
127
+ * Token file contains OAuth credentials: access_token, refresh_token, expiry_date, resource_url
128
+ * @returns {string} Path to ~/.qwen/oauth_creds.json
59
129
  */
60
130
  export function getTokenPath() {
61
131
  return join(getQwenDir(), "oauth_creds.json");
62
132
  }
133
+
63
134
  /**
64
135
  * Get token lock path for multi-process refresh coordination
136
+ * Prevents concurrent token refresh operations across multiple processes
137
+ * @returns {string} Path to ~/.qwen/oauth_creds.lock
65
138
  */
66
139
  export function getTokenLockPath() {
67
140
  return join(getQwenDir(), "oauth_creds.lock");
68
141
  }
142
+
143
+ /**
144
+ * Get multi-account storage path
145
+ * @returns {string} Path to ~/.qwen/oauth_accounts.json or OPENCODE_QWEN_ACCOUNTS_PATH override
146
+ */
147
+ export function getAccountsPath() {
148
+ return resolveAccountsPathFromEnv() || DEFAULT_ACCOUNTS_PATH;
149
+ }
150
+
151
+ /**
152
+ * Get multi-account lock path
153
+ * @returns {string} Path to ~/.qwen/oauth_accounts.lock (or sidecar lock for override path)
154
+ */
155
+ export function getAccountsLockPath() {
156
+ const accountsPath = getAccountsPath();
157
+ if (dirname(accountsPath) !== getQwenDir()) {
158
+ return `${accountsPath}.lock`;
159
+ }
160
+ return join(getQwenDir(), "oauth_accounts.lock");
161
+ }
162
+
69
163
  /**
70
164
  * Get legacy token storage path used by old plugin versions
165
+ * Used for backward compatibility and token migration
166
+ * @returns {string} Path to ~/.opencode/qwen/oauth_token.json
71
167
  */
72
168
  export function getLegacyTokenPath() {
73
169
  return join(getConfigDir(), "oauth_token.json");
74
170
  }
171
+
75
172
  /**
76
173
  * Get cache directory for prompts
174
+ * @returns {string} Path to ~/.opencode/cache/
77
175
  */
78
176
  export function getCacheDir() {
79
177
  return join(homedir(), ".opencode", "cache");
@@ -1,12 +1,24 @@
1
1
  /**
2
- * Constants for Qwen OAuth Plugin
2
+ * @fileoverview Constants for Qwen OAuth Plugin
3
+ * Centralized configuration for OAuth endpoints, headers, error codes, and other constants
4
+ * @license MIT
3
5
  */
4
- /** Plugin identifier */
6
+
7
+ /** Plugin identifier for logging and debugging */
5
8
  export const PLUGIN_NAME = "qwen-oauth-plugin";
6
- /** Provider ID for opencode configuration (used in model references like qwen-code/coder-model) */
9
+
10
+ /**
11
+ * Provider ID for opencode configuration
12
+ * Used in model references like qwen-code/coder-model
13
+ */
7
14
  export const PROVIDER_ID = "qwen-code";
8
- /** Dummy API key (actual auth via OAuth) */
15
+
16
+ /**
17
+ * Dummy API key placeholder
18
+ * Actual authentication is handled via OAuth flow, not API key
19
+ */
9
20
  export const DUMMY_API_KEY = "qwen-oauth";
21
+
10
22
  /**
11
23
  * Default Qwen DashScope base URL (fallback if resource_url is missing)
12
24
  * Note: This plugin is for OAuth authentication only. For API key authentication,
@@ -15,27 +27,43 @@ export const DUMMY_API_KEY = "qwen-oauth";
15
27
  * IMPORTANT: OAuth endpoints use /api/v1, DashScope OpenAI-compatible uses /compatible-mode/v1
16
28
  * - OAuth endpoints: /api/v1/oauth2/ (for authentication)
17
29
  * - Chat API: /v1/ (for completions)
30
+ *
31
+ * @constant {string}
18
32
  */
19
33
  // NOTE:
20
34
  // qwen-code (official CLI) defaults to DashScope OpenAI-compatible endpoint when
21
35
  // `resource_url` is missing. This is required for the free OAuth flow to behave
22
36
  // the same as the CLI.
23
37
  export const DEFAULT_QWEN_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
24
- /** Qwen OAuth endpoints and configuration */
38
+
39
+ /**
40
+ * Qwen OAuth endpoints and configuration
41
+ * Source: Qwen Code CLI (https://github.com/QwenLM/qwen-code)
42
+ * @namespace
43
+ */
25
44
  export const QWEN_OAUTH = {
45
+ /** OAuth 2.0 Device Code endpoint */
26
46
  DEVICE_CODE_URL: "https://chat.qwen.ai/api/v1/oauth2/device/code",
47
+ /** OAuth 2.0 Token endpoint */
27
48
  TOKEN_URL: "https://chat.qwen.ai/api/v1/oauth2/token",
28
49
  /**
29
50
  * Qwen OAuth Client ID
30
- * Source: Qwen Code CLI (https://github.com/QwenLM/qwen-code)
31
51
  * This is a public client ID used for OAuth Device Authorization Grant flow (RFC 8628)
52
+ * @constant {string}
32
53
  */
33
54
  CLIENT_ID: "f0304373b74a44d2b584a3fb70ca9e56",
55
+ /** OAuth scopes requested: openid, profile, email, and model completion access */
34
56
  SCOPE: "openid profile email model.completion",
57
+ /** OAuth 2.0 Device Code grant type (RFC 8628) */
35
58
  GRANT_TYPE_DEVICE: "urn:ietf:params:oauth:grant-type:device_code",
59
+ /** OAuth 2.0 Refresh Token grant type */
36
60
  GRANT_TYPE_REFRESH: "refresh_token",
37
61
  };
38
- /** HTTP Status Codes */
62
+
63
+ /**
64
+ * HTTP Status Codes for error handling
65
+ * @namespace
66
+ */
39
67
  export const HTTP_STATUS = {
40
68
  OK: 200,
41
69
  BAD_REQUEST: 400,
@@ -43,21 +71,37 @@ export const HTTP_STATUS = {
43
71
  FORBIDDEN: 403,
44
72
  TOO_MANY_REQUESTS: 429,
45
73
  };
74
+
46
75
  /**
47
- * DashScope headers
76
+ * DashScope headers for OAuth authentication
48
77
  * Note: OAuth requires X-DashScope-AuthType to indicate qwen-oauth authentication
78
+ * @namespace
49
79
  */
50
80
  export const PORTAL_HEADERS = {
81
+ /** Header name for auth type specification */
51
82
  AUTH_TYPE: "X-DashScope-AuthType",
83
+ /** Header value for qwen-oauth authentication */
52
84
  AUTH_TYPE_VALUE: "qwen-oauth",
53
85
  };
54
- /** Device flow polling configuration */
86
+
87
+ /**
88
+ * Device flow polling configuration
89
+ * Controls backoff strategy for OAuth token polling
90
+ * @namespace
91
+ */
55
92
  export const DEVICE_FLOW = {
93
+ /** Initial polling interval in milliseconds */
56
94
  INITIAL_POLL_INTERVAL: 2000, // 2 seconds
95
+ /** Maximum polling interval in milliseconds */
57
96
  MAX_POLL_INTERVAL: 10000, // 10 seconds
97
+ /** Backoff multiplier for exponential backoff */
58
98
  BACKOFF_MULTIPLIER: 1.5,
59
99
  };
60
- /** Error messages */
100
+
101
+ /**
102
+ * Error messages for user-facing errors
103
+ * @namespace
104
+ */
61
105
  export const ERROR_MESSAGES = {
62
106
  TOKEN_REFRESH_FAILED: "Failed to refresh token, authentication required",
63
107
  DEVICE_AUTH_TIMEOUT: "Device authorization timed out",
@@ -65,14 +109,27 @@ export const ERROR_MESSAGES = {
65
109
  REQUEST_PARSE_ERROR: "Error parsing request",
66
110
  NO_RESOURCE_URL: "No resource_url in token response, using default",
67
111
  };
68
- /** OAuth error codes */
112
+
113
+ /**
114
+ * OAuth error codes from RFC 8628 Device Flow
115
+ * @namespace
116
+ */
69
117
  export const OAUTH_ERRORS = {
118
+ /** User has not yet authorized the device code */
70
119
  AUTHORIZATION_PENDING: "authorization_pending",
120
+ /** Server requests slower polling (slow_down error) */
71
121
  SLOW_DOWN: "slow_down",
122
+ /** User denied the authorization request */
72
123
  ACCESS_DENIED: "access_denied",
124
+ /** Device code has expired */
73
125
  EXPIRED_TOKEN: "expired_token",
74
126
  };
75
- /** Log stages for request logging */
127
+
128
+ /**
129
+ * Log stages for request logging
130
+ * Used for debugging and tracing request lifecycle
131
+ * @namespace
132
+ */
76
133
  export const LOG_STAGES = {
77
134
  BEFORE_TRANSFORM: "before-transform",
78
135
  AFTER_TRANSFORM: "after-transform",
@@ -81,29 +138,53 @@ export const LOG_STAGES = {
81
138
  DEVICE_CODE_REQUEST: "device-code-request",
82
139
  TOKEN_POLL: "token-poll",
83
140
  };
84
- /** Platform-specific browser opener commands */
141
+
142
+ /**
143
+ * Platform-specific browser opener commands
144
+ * Used for opening OAuth verification URL in default browser
145
+ * @namespace
146
+ */
85
147
  export const PLATFORM_OPENERS = {
86
148
  darwin: "open",
87
149
  win32: "start",
88
150
  linux: "xdg-open",
89
151
  };
90
- /** OAuth authorization labels */
152
+
153
+ /**
154
+ * OAuth authorization labels for UI display
155
+ * @namespace
156
+ */
91
157
  export const AUTH_LABELS = {
158
+ /** Label shown in OpenCode auth provider selection */
92
159
  OAUTH: "Qwen Code (qwen.ai OAuth)",
160
+ /** Instructions shown to user during OAuth flow */
93
161
  INSTRUCTIONS: "Visit the URL shown in your browser to complete authentication.",
94
162
  };
95
- /** OAuth verification URI parameters */
163
+
164
+ /**
165
+ * OAuth verification URI parameters
166
+ * Used to construct complete verification URL with client identification
167
+ * @namespace
168
+ */
96
169
  export const VERIFICATION_URI = {
97
170
  /** Query parameter key for client identification */
98
171
  CLIENT_PARAM_KEY: "client=",
99
172
  /** Full query parameter for Qwen Code client */
100
173
  CLIENT_PARAM_VALUE: "client=qwen-code",
101
174
  };
102
- /** Token refresh buffer (refresh 30 seconds before expiry) */
175
+
176
+ /**
177
+ * Token refresh buffer in milliseconds
178
+ * Tokens are refreshed 30 seconds before expiry to avoid race conditions
179
+ * @constant {number}
180
+ */
103
181
  export const TOKEN_REFRESH_BUFFER_MS = 30 * 1000; // 30 seconds
104
- /** Stream processing configuration */
182
+
183
+ /**
184
+ * Stream processing configuration
185
+ * @namespace
186
+ */
105
187
  export const STREAM_CONFIG = {
106
188
  /** Maximum buffer size for SSE pass-through mode (1MB) */
107
189
  MAX_BUFFER_SIZE: 1024 * 1024,
108
190
  };
109
- //# sourceMappingURL=constants.js.map
@@ -1,10 +1,34 @@
1
+ /**
2
+ * @fileoverview Logging utilities for Qwen OAuth Plugin
3
+ * Provides configurable logging for debugging and request tracing
4
+ * @license MIT
5
+ */
6
+
1
7
  import { writeFileSync, mkdirSync, existsSync } from "node:fs";
2
8
  import { join } from "node:path";
3
9
  import { homedir } from "node:os";
4
- // Logging configuration
10
+
11
+ /**
12
+ * Flag to enable request logging to file
13
+ * Controlled by ENABLE_PLUGIN_REQUEST_LOGGING environment variable
14
+ * @constant {boolean}
15
+ */
5
16
  export const LOGGING_ENABLED = process.env.ENABLE_PLUGIN_REQUEST_LOGGING === "1";
17
+
18
+ /**
19
+ * Flag to enable debug logging to console
20
+ * Controlled by DEBUG_QWEN_PLUGIN or ENABLE_PLUGIN_REQUEST_LOGGING environment variables
21
+ * @constant {boolean}
22
+ */
6
23
  export const DEBUG_ENABLED = process.env.DEBUG_QWEN_PLUGIN === "1" || LOGGING_ENABLED;
24
+
25
+ /**
26
+ * Directory path for log files
27
+ * Logs are stored in ~/.opencode/logs/qwen-plugin/
28
+ * @constant {string}
29
+ */
7
30
  const LOG_DIR = join(homedir(), ".opencode", "logs", "qwen-plugin");
31
+
8
32
  // Log startup message about logging state
9
33
  if (LOGGING_ENABLED) {
10
34
  console.log("[qwen-oauth-plugin] Request logging ENABLED - logs will be saved to:", LOG_DIR);
@@ -12,23 +36,34 @@ if (LOGGING_ENABLED) {
12
36
  if (DEBUG_ENABLED && !LOGGING_ENABLED) {
13
37
  console.log("[qwen-oauth-plugin] Debug logging ENABLED");
14
38
  }
39
+
40
+ /**
41
+ * Request counter for generating unique request IDs in logs
42
+ * @type {number}
43
+ */
15
44
  let requestCounter = 0;
45
+
16
46
  /**
17
47
  * Log request data to file (only when LOGGING_ENABLED is true)
18
- * @param stage - The stage of the request (e.g., "before-transform", "after-transform")
19
- * @param data - The data to log
48
+ * Creates JSON files with request/response data for debugging
49
+ * @param {string} stage - The stage of the request (e.g., "before-transform", "after-transform", "response")
50
+ * @param {Object} data - The data to log (request/response objects, metadata, etc.)
51
+ * @returns {void}
20
52
  */
21
53
  export function logRequest(stage, data) {
22
54
  // Only log if explicitly enabled via environment variable
23
55
  if (!LOGGING_ENABLED)
24
56
  return;
57
+
25
58
  // Ensure log directory exists on first log
26
59
  if (!existsSync(LOG_DIR)) {
27
60
  mkdirSync(LOG_DIR, { recursive: true });
28
61
  }
62
+
29
63
  const timestamp = new Date().toISOString();
30
64
  const requestId = ++requestCounter;
31
65
  const filename = join(LOG_DIR, `request-${requestId}-${stage}.json`);
66
+
32
67
  try {
33
68
  writeFileSync(filename, JSON.stringify({
34
69
  timestamp,
@@ -43,10 +78,13 @@ export function logRequest(stage, data) {
43
78
  console.error("[qwen-oauth-plugin] Failed to write log:", error.message);
44
79
  }
45
80
  }
81
+
46
82
  /**
47
83
  * Log debug information (only when DEBUG_ENABLED is true)
48
- * @param message - Debug message
49
- * @param data - Optional data to log
84
+ * Used for detailed debugging during development
85
+ * @param {string} message - Debug message describing the context
86
+ * @param {*} [data] - Optional data to log (objects, values, etc.)
87
+ * @returns {void}
50
88
  */
51
89
  export function logDebug(message, data) {
52
90
  if (!DEBUG_ENABLED)
@@ -58,10 +96,13 @@ export function logDebug(message, data) {
58
96
  console.log(`[qwen-oauth-plugin] ${message}`);
59
97
  }
60
98
  }
99
+
61
100
  /**
62
101
  * Log error (always enabled for important issues)
63
- * @param message - Error message
64
- * @param data - Optional data to log
102
+ * Used for critical errors that need attention
103
+ * @param {string} message - Error message describing what went wrong
104
+ * @param {*} [data] - Optional data to log (error objects, context, etc.)
105
+ * @returns {void}
65
106
  */
66
107
  export function logError(message, data) {
67
108
  if (data !== undefined) {
@@ -71,10 +112,13 @@ export function logError(message, data) {
71
112
  console.error(`[qwen-oauth-plugin] ${message}`);
72
113
  }
73
114
  }
115
+
74
116
  /**
75
117
  * Log warning (always enabled for important issues)
76
- * @param message - Warning message
77
- * @param data - Optional data to log
118
+ * Used for non-critical issues that may need attention
119
+ * @param {string} message - Warning message describing the issue
120
+ * @param {*} [data] - Optional data to log (context, values, etc.)
121
+ * @returns {void}
78
122
  */
79
123
  export function logWarn(message, data) {
80
124
  if (data !== undefined) {
@@ -84,10 +128,13 @@ export function logWarn(message, data) {
84
128
  console.warn(`[qwen-oauth-plugin] ${message}`);
85
129
  }
86
130
  }
131
+
87
132
  /**
88
133
  * Log info message (always enabled)
89
- * @param message - Info message
90
- * @param data - Optional data to log
134
+ * Used for general informational messages
135
+ * @param {string} message - Info message describing the event
136
+ * @param {*} [data] - Optional data to log (context, values, etc.)
137
+ * @returns {void}
91
138
  */
92
139
  export function logInfo(message, data) {
93
140
  if (data !== undefined) {
@@ -97,4 +144,3 @@ export function logInfo(message, data) {
97
144
  console.log(`[qwen-oauth-plugin] ${message}`);
98
145
  }
99
146
  }
100
- //# sourceMappingURL=logger.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-qwen-cli-auth",
3
- "version": "2.2.9",
3
+ "version": "2.3.1",
4
4
  "description": "Qwen OAuth authentication plugin for opencode - use your Qwen account instead of API keys",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",