@qwen-code/qwen-code 0.18.0-preview.2 → 0.18.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/bundled/loop/SKILL.md +2 -1
- package/bundled/qc-helper/docs/_meta.ts +1 -0
- package/bundled/qc-helper/docs/configuration/auth.md +1 -1
- package/bundled/qc-helper/docs/configuration/model-providers.md +12 -5
- package/bundled/qc-helper/docs/configuration/settings.md +33 -32
- package/bundled/qc-helper/docs/features/approval-mode.md +10 -14
- package/bundled/qc-helper/docs/features/commands.md +33 -11
- package/bundled/qc-helper/docs/features/dual-output.md +37 -3
- package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
- package/bundled/qc-helper/docs/features/skills.md +29 -3
- package/bundled/qc-helper/docs/features/sub-agents.md +34 -12
- package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +221 -0
- package/bundled/qc-helper/docs/qwen-serve.md +246 -28
- package/chunks/{agent-QB7TZ4HW.js → agent-XT7NHZ5H.js} +25 -24
- package/chunks/agent-headless-LNRE63ZL.js +51 -0
- package/chunks/{anthropicContentGenerator-M45EVVRM.js → anthropicContentGenerator-DCI26OQF.js} +7 -7
- package/chunks/{askUserQuestion-WM2KHM3K.js → askUserQuestion-ITYUTWLR.js} +45 -3
- package/chunks/{ca-BARBRL6N.js → ca-RK4QPLIX.js} +18 -1
- package/chunks/{chunk-CWV3SJZS.js → chunk-3NRO6NHX.js} +2 -2
- package/chunks/{chunk-BNESGOSJ.js → chunk-55ZMG67I.js} +1 -1
- package/chunks/{chunk-QCG6KPNM.js → chunk-6T7Y7USE.js} +18017 -11621
- package/chunks/{chunk-CNHFPN7T.js → chunk-7KPZFE5A.js} +1 -1
- package/chunks/{chunk-2ZTWI7KH.js → chunk-A2ZIEEGJ.js} +30 -22
- package/chunks/{chunk-JUGRPQAB.js → chunk-B4ZF2KSI.js} +1 -1
- package/chunks/chunk-BJ5HQ23U.js +178 -0
- package/chunks/{chunk-HXJE7VOG.js → chunk-BXYRCW2C.js} +1074 -144
- package/chunks/{chunk-ICOI4E4S.js → chunk-CPVI5J2L.js} +101 -23
- package/chunks/{chunk-HV3ZZ7G4.js → chunk-DHZREJTG.js} +2 -2
- package/chunks/{chunk-GX7VH5JQ.js → chunk-FIQECJTQ.js} +1 -1
- package/chunks/{chunk-SZOEIL6S.js → chunk-H6BD2ELD.js} +1 -0
- package/chunks/{chunk-JXAZUMDW.js → chunk-HA2UEYZP.js} +7 -4
- package/chunks/{chunk-USE2VQ5P.js → chunk-HED55F43.js} +26 -1
- package/chunks/{chunk-PAEBHDIO.js → chunk-HQUWWSSP.js} +1 -1
- package/chunks/{chunk-MVIVIPCU.js → chunk-IDYDPBBN.js} +361 -583
- package/chunks/{chunk-JVQOQ3OU.js → chunk-IQHSD7K5.js} +1 -1
- package/chunks/{chunk-NW5QBUYO.js → chunk-IS7UA4W3.js} +14 -14
- package/chunks/{chunk-UAMOBVVW.js → chunk-LXYWINWF.js} +1 -1
- package/chunks/{chunk-P4J26VDS.js → chunk-LYRSMKLS.js} +2 -2
- package/chunks/{chunk-Y7R6H6FT.js → chunk-LYSND7KR.js} +9 -4
- package/chunks/{chunk-LR62TEET.js → chunk-NNIYWQIS.js} +1 -1
- package/chunks/chunk-OMX7CUOE.js +356 -0
- package/chunks/{chunk-CNSMKPK6.js → chunk-QILTEBWS.js} +1 -1
- package/chunks/chunk-QQDPRDVW.js +25 -0
- package/chunks/{chunk-ZK4AMNIU.js → chunk-RON7LFNH.js} +1294 -314
- package/chunks/chunk-SFRV6BGY.js +243 -0
- package/chunks/{chunk-AVW55ZCO.js → chunk-WJ3SND6W.js} +37 -16
- package/chunks/{chunk-HGJPQK33.js → chunk-WPTCDQN6.js} +188 -534
- package/chunks/{chunk-7YKXFA3D.js → chunk-XZTNBSMW.js} +11 -11
- package/chunks/{chunk-C6WMLUNB.js → chunk-Y7KMDUEP.js} +1 -1
- package/chunks/{chunk-WFVXF3OM.js → chunk-Z2Z3GUXZ.js} +1 -0
- package/chunks/{chunk-KC6ZMJ5X.js → chunk-ZMIBJS45.js} +1 -1
- package/chunks/chunk-ZOFNJQNJ.js +607 -0
- package/chunks/computer-use-4YX3JGBV.js +2052 -0
- package/chunks/contextCommand-KS2H7MW5.js +53 -0
- package/chunks/cron-create-CAPUKK7I.js +184 -0
- package/chunks/{cron-delete-ZGUXWBTG.js → cron-delete-G3KAR26Q.js} +28 -5
- package/chunks/{cron-list-QNNZGMN3.js → cron-list-ZA4ZIUS5.js} +40 -7
- package/chunks/{de-YGKK2BC4.js → de-FGPM4KW5.js} +18 -1
- package/chunks/{devtools-IXE4UP72.js → devtools-FM6GJPYG.js} +1 -1
- package/chunks/{dist-ZMQ4TXD5.js → dist-7YWFWOCJ.js} +2 -2
- package/chunks/{dist-R2SXPG74.js → dist-VEGFONCF.js} +2 -2
- package/chunks/{dist-TE5QKMGR.js → dist-X4EXN7W6.js} +1 -1
- package/chunks/{dist-BXDUQ2QY.js → dist-YLS6NI7H.js} +1 -1
- package/chunks/{edit-6UBTS2J5.js → edit-2ARPEO4B.js} +26 -25
- package/chunks/{en-HSQQNQUB.js → en-VP6XPGEC.js} +9 -2
- package/chunks/{enter-worktree-NN7LIXCM.js → enter-worktree-IXNXNAW5.js} +25 -24
- package/chunks/enterPlanMode-TAKAGAYP.js +159 -0
- package/chunks/{exit-worktree-GGSS5KIE.js → exit-worktree-LHTRV7ML.js} +25 -24
- package/chunks/exitPlanMode-MK5UAITL.js +743 -0
- package/chunks/{fr-JXBKPJKQ.js → fr-ATYBVCLT.js} +18 -1
- package/chunks/{geminiContentGenerator-I4H2NLJG.js → geminiContentGenerator-HFJIGO77.js} +7 -7
- package/chunks/{getMachineId-bsd-F7GNPTER.js → getMachineId-bsd-4CASPIU4.js} +1 -1
- package/chunks/{getMachineId-darwin-T73DJL27.js → getMachineId-darwin-HPQPEMZR.js} +1 -1
- package/chunks/{getMachineId-linux-MKQTFPQM.js → getMachineId-linux-AUARKYHL.js} +1 -1
- package/chunks/{getMachineId-unsupported-MUR5KOQE.js → getMachineId-unsupported-S32ZDA2T.js} +1 -1
- package/chunks/{getMachineId-win-CDYFC6ZM.js → getMachineId-win-4EFLHYIJ.js} +1 -1
- package/chunks/{glob-OLCX57MD.js → glob-I2USLUSC.js} +25 -24
- package/chunks/{grep-7HXIMDOW.js → grep-WBIF7THR.js} +37 -30
- package/chunks/{ja-TGPZSP2B.js → ja-W2QEA2OI.js} +18 -1
- package/chunks/{keychain-token-storage-LB46DAEK.js → keychain-token-storage-QSTRHKKL.js} +3 -3
- package/chunks/{ls-6PEZUK6O.js → ls-2R5RHLX5.js} +4 -4
- package/chunks/{lsp-JZSJOVT7.js → lsp-XKH6ZIAN.js} +3 -3
- package/chunks/{monitor-SQO7MVAV.js → monitor-WU7UFATU.js} +25 -24
- package/chunks/{notebook-edit-72L3EBAL.js → notebook-edit-KUHYPXEM.js} +26 -25
- package/chunks/{openaiContentGenerator-FTR7CDWF.js → openaiContentGenerator-5PLHYJQL.js} +15 -15
- package/chunks/{pt-TIBG6BIO.js → pt-ZKEWJFBW.js} +18 -1
- package/chunks/{qwenContentGenerator-U5UFQ566.js → qwenContentGenerator-TSKW73KY.js} +27 -26
- package/chunks/{qwenOAuth2-EFSECGHF.js → qwenOAuth2-KK433U33.js} +6 -5
- package/chunks/{read-file-UA64EEQC.js → read-file-VIPF2PS6.js} +11 -11
- package/chunks/ripGrep-XLIZTYE7.js +49 -0
- package/chunks/{ru-JBCHCK4L.js → ru-VEKTPJ74.js} +18 -1
- package/chunks/{scheduler-VBASHOCA.js → scheduler-O66SLJGU.js} +25 -24
- package/chunks/{send-message-OYJZ5TPG.js → send-message-CTME7DXD.js} +3 -3
- package/chunks/{serve-A7E2OJDR.js → serve-BWOLYT62.js} +13164 -3840
- package/chunks/{shell-3NFOT6F5.js → shell-XE7UYKOO.js} +25 -24
- package/chunks/{skill-RA5YUREY.js → skill-RZWM6XMC.js} +64 -113
- package/chunks/{src-NFCMARMT.js → src-L5P7K4MH.js} +176 -44
- package/chunks/{syntheticOutput-DETQ2YM6.js → syntheticOutput-ZJGSU7OQ.js} +4 -4
- package/chunks/{task-create-Y3ZKTJIG.js → task-create-EE6JEM7G.js} +8 -7
- package/chunks/{task-list-ONXJ3I3A.js → task-list-EESYAC65.js} +7 -6
- package/chunks/{task-stop-UHDC4N5B.js → task-stop-XZVCFFYY.js} +3 -3
- package/chunks/{task-update-TCNOU3P5.js → task-update-EIO4HNE3.js} +21 -9
- package/chunks/{team-create-6SR4OVRG.js → team-create-R2H7Y3SG.js} +28 -26
- package/chunks/{team-delete-EJ4U4DDP.js → team-delete-A7LXPGV7.js} +9 -6
- package/chunks/{todoWrite-TEYDRS5L.js → todoWrite-VRKSGAWM.js} +5 -5
- package/chunks/{tool-search-OD435A3X.js → tool-search-USSQMTMS.js} +11 -11
- package/chunks/{web-fetch-6W67H5PO.js → web-fetch-GHAZUA54.js} +5 -5
- package/chunks/workflow-5LNNLNUR.js +1414 -0
- package/chunks/{write-file-475L5OPP.js → write-file-2I7HP24C.js} +26 -25
- package/chunks/{zh-VCLWO26Y.js → zh-OIXDDQHB.js} +10 -3
- package/chunks/{zh-TW-G3HFHVVT.js → zh-TW-6YFNCKTA.js} +10 -3
- package/cli-entry.js +19 -0
- package/cli.js +11064 -6628
- package/examples/starter/QWEN.md +30 -0
- package/examples/starter/README.md +59 -0
- package/examples/starter/agents/diary.md +86 -0
- package/examples/starter/commands/writing/polish.md +13 -0
- package/examples/starter/example.ts +64 -0
- package/examples/starter/package.json +18 -0
- package/examples/starter/qwen-extension.json +12 -0
- package/examples/starter/skills/synonyms/SKILL.md +48 -0
- package/examples/starter/tsconfig.json +13 -0
- package/fzfWorker.js +1083 -0
- package/locales/ca.js +20 -2
- package/locales/de.js +21 -2
- package/locales/en.js +13 -4
- package/locales/fr.js +22 -2
- package/locales/ja.js +22 -2
- package/locales/pt.js +21 -2
- package/locales/ru.js +20 -2
- package/locales/zh-TW.js +11 -4
- package/locales/zh.js +11 -4
- package/package.json +5 -3
- package/chunks/agent-headless-APVHH7QM.js +0 -50
- package/chunks/chunk-AJIR24J2.js +0 -59
- package/chunks/chunk-SKBPNJEW.js +0 -45
- package/chunks/chunk-XBFVXFB2.js +0 -216
- package/chunks/computer-use-B7VIUI7F.js +0 -825
- package/chunks/contextCommand-63RZ3O5R.js +0 -52
- package/chunks/cron-create-FI5LJVUS.js +0 -140
- package/chunks/exitPlanMode-H323NHB2.js +0 -235
- package/chunks/ripGrep-WSYCWZVK.js +0 -48
- package/chunks/workflow-62DHH4EO.js +0 -708
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
import {
|
|
4
4
|
formatFetchErrorForUser
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FIQECJTQ.js";
|
|
6
|
+
import {
|
|
7
|
+
combineAbortSignals
|
|
8
|
+
} from "./chunk-64WXLC72.js";
|
|
6
9
|
import {
|
|
7
10
|
atomicWriteFile
|
|
8
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-LXYWINWF.js";
|
|
9
12
|
import {
|
|
10
13
|
Storage,
|
|
11
14
|
createDebugLogger
|
|
12
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-HA2UEYZP.js";
|
|
13
16
|
import {
|
|
14
17
|
init_esbuild_shims
|
|
15
18
|
} from "./chunk-A4BMJM77.js";
|
|
@@ -20,546 +23,294 @@ import {
|
|
|
20
23
|
// packages/core/src/qwen/qwenOAuth2.ts
|
|
21
24
|
init_esbuild_shims();
|
|
22
25
|
import crypto from "crypto";
|
|
23
|
-
import
|
|
24
|
-
import { promises as
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
init_esbuild_shims();
|
|
28
|
-
import process7 from "node:process";
|
|
29
|
-
import { Buffer } from "node:buffer";
|
|
30
|
-
import path from "node:path";
|
|
31
|
-
import { fileURLToPath } from "node:url";
|
|
32
|
-
import { promisify as promisify5 } from "node:util";
|
|
33
|
-
import childProcess from "node:child_process";
|
|
34
|
-
import fs5, { constants as fsConstants2 } from "node:fs/promises";
|
|
35
|
-
|
|
36
|
-
// node_modules/wsl-utils/index.js
|
|
37
|
-
init_esbuild_shims();
|
|
38
|
-
import process3 from "node:process";
|
|
39
|
-
import fs4, { constants as fsConstants } from "node:fs/promises";
|
|
40
|
-
|
|
41
|
-
// node_modules/is-wsl/index.js
|
|
42
|
-
init_esbuild_shims();
|
|
43
|
-
import process2 from "node:process";
|
|
44
|
-
import os from "node:os";
|
|
45
|
-
import fs3 from "node:fs";
|
|
26
|
+
import path2 from "node:path";
|
|
27
|
+
import { promises as fs2 } from "node:fs";
|
|
28
|
+
import { EventEmitter } from "events";
|
|
29
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
46
30
|
|
|
47
|
-
//
|
|
31
|
+
// packages/core/src/utils/secure-browser-launcher.ts
|
|
48
32
|
init_esbuild_shims();
|
|
49
|
-
import
|
|
33
|
+
import { execFile, spawn } from "node:child_process";
|
|
34
|
+
import { promisify } from "node:util";
|
|
35
|
+
import { platform } from "node:os";
|
|
36
|
+
import { resolve } from "node:path";
|
|
37
|
+
import { URL, fileURLToPath } from "node:url";
|
|
50
38
|
|
|
51
|
-
//
|
|
39
|
+
// packages/core/src/utils/browser.ts
|
|
52
40
|
init_esbuild_shims();
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
fs.statSync("/.dockerenv");
|
|
58
|
-
return true;
|
|
59
|
-
} catch {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
__name(hasDockerEnv, "hasDockerEnv");
|
|
64
|
-
function hasDockerCGroup() {
|
|
65
|
-
try {
|
|
66
|
-
return fs.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
67
|
-
} catch {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
__name(hasDockerCGroup, "hasDockerCGroup");
|
|
72
|
-
function isDocker() {
|
|
73
|
-
if (isDockerCached === void 0) {
|
|
74
|
-
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
75
|
-
}
|
|
76
|
-
return isDockerCached;
|
|
41
|
+
var browserBlocklist = ["www-browser"];
|
|
42
|
+
function isBrowserCommandBlocked(command) {
|
|
43
|
+
const commandName = command.replace(/\\/g, "/").split("/").pop();
|
|
44
|
+
return !!commandName && browserBlocklist.includes(commandName);
|
|
77
45
|
}
|
|
78
|
-
__name(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
fs2.statSync("/run/.containerenv");
|
|
85
|
-
return true;
|
|
86
|
-
} catch {
|
|
46
|
+
__name(isBrowserCommandBlocked, "isBrowserCommandBlocked");
|
|
47
|
+
function shouldAttemptBrowserLaunch(options = {}) {
|
|
48
|
+
const browserEnv = process.env["BROWSER"]?.trim();
|
|
49
|
+
const browserCommand = browserEnv?.match(/^\S+/)?.[0];
|
|
50
|
+
if (!options.ignoreBrowserBlocklist && process.platform !== "win32" && browserCommand && isBrowserCommandBlocked(browserCommand)) {
|
|
87
51
|
return false;
|
|
88
52
|
}
|
|
89
|
-
|
|
90
|
-
function isInsideContainer() {
|
|
91
|
-
if (cachedResult === void 0) {
|
|
92
|
-
cachedResult = hasContainerEnv() || isDocker();
|
|
93
|
-
}
|
|
94
|
-
return cachedResult;
|
|
95
|
-
}
|
|
96
|
-
__name(isInsideContainer, "isInsideContainer");
|
|
97
|
-
|
|
98
|
-
// node_modules/is-wsl/index.js
|
|
99
|
-
var isWsl = /* @__PURE__ */ __name(() => {
|
|
100
|
-
if (process2.platform !== "linux") {
|
|
53
|
+
if (process.env["CI"] || process.env["DEBIAN_FRONTEND"] === "noninteractive") {
|
|
101
54
|
return false;
|
|
102
55
|
}
|
|
103
|
-
|
|
104
|
-
|
|
56
|
+
const isSSH = !!process.env["SSH_CONNECTION"];
|
|
57
|
+
if (process.platform === "linux") {
|
|
58
|
+
const displayVariables = ["DISPLAY", "WAYLAND_DISPLAY", "MIR_SOCKET"];
|
|
59
|
+
const hasDisplay = displayVariables.some((v) => !!process.env[v]);
|
|
60
|
+
if (!hasDisplay) {
|
|
105
61
|
return false;
|
|
106
62
|
}
|
|
107
|
-
return true;
|
|
108
63
|
}
|
|
109
|
-
|
|
110
|
-
return fs3.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
|
|
111
|
-
} catch {
|
|
64
|
+
if (isSSH && process.platform !== "linux") {
|
|
112
65
|
return false;
|
|
113
66
|
}
|
|
114
|
-
|
|
115
|
-
var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
116
|
-
|
|
117
|
-
// node_modules/wsl-utils/index.js
|
|
118
|
-
var wslDrivesMountPoint = /* @__PURE__ */ (() => {
|
|
119
|
-
const defaultMountPoint = "/mnt/";
|
|
120
|
-
let mountPoint;
|
|
121
|
-
return async function() {
|
|
122
|
-
if (mountPoint) {
|
|
123
|
-
return mountPoint;
|
|
124
|
-
}
|
|
125
|
-
const configFilePath = "/etc/wsl.conf";
|
|
126
|
-
let isConfigFileExists = false;
|
|
127
|
-
try {
|
|
128
|
-
await fs4.access(configFilePath, fsConstants.F_OK);
|
|
129
|
-
isConfigFileExists = true;
|
|
130
|
-
} catch {
|
|
131
|
-
}
|
|
132
|
-
if (!isConfigFileExists) {
|
|
133
|
-
return defaultMountPoint;
|
|
134
|
-
}
|
|
135
|
-
const configContent = await fs4.readFile(configFilePath, { encoding: "utf8" });
|
|
136
|
-
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
|
|
137
|
-
if (!configMountPoint) {
|
|
138
|
-
return defaultMountPoint;
|
|
139
|
-
}
|
|
140
|
-
mountPoint = configMountPoint.groups.mountPoint.trim();
|
|
141
|
-
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
142
|
-
return mountPoint;
|
|
143
|
-
};
|
|
144
|
-
})();
|
|
145
|
-
var powerShellPathFromWsl = /* @__PURE__ */ __name(async () => {
|
|
146
|
-
const mountPoint = await wslDrivesMountPoint();
|
|
147
|
-
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
148
|
-
}, "powerShellPathFromWsl");
|
|
149
|
-
var powerShellPath = /* @__PURE__ */ __name(async () => {
|
|
150
|
-
if (is_wsl_default) {
|
|
151
|
-
return powerShellPathFromWsl();
|
|
152
|
-
}
|
|
153
|
-
return `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
154
|
-
}, "powerShellPath");
|
|
155
|
-
|
|
156
|
-
// node_modules/define-lazy-prop/index.js
|
|
157
|
-
init_esbuild_shims();
|
|
158
|
-
function defineLazyProperty(object, propertyName, valueGetter) {
|
|
159
|
-
const define = /* @__PURE__ */ __name((value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true }), "define");
|
|
160
|
-
Object.defineProperty(object, propertyName, {
|
|
161
|
-
configurable: true,
|
|
162
|
-
enumerable: true,
|
|
163
|
-
get() {
|
|
164
|
-
const result = valueGetter();
|
|
165
|
-
define(result);
|
|
166
|
-
return result;
|
|
167
|
-
},
|
|
168
|
-
set(value) {
|
|
169
|
-
define(value);
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
return object;
|
|
67
|
+
return true;
|
|
173
68
|
}
|
|
174
|
-
__name(
|
|
175
|
-
|
|
176
|
-
// node_modules/default-browser/index.js
|
|
177
|
-
init_esbuild_shims();
|
|
178
|
-
import { promisify as promisify4 } from "node:util";
|
|
179
|
-
import process6 from "node:process";
|
|
180
|
-
import { execFile as execFile4 } from "node:child_process";
|
|
69
|
+
__name(shouldAttemptBrowserLaunch, "shouldAttemptBrowserLaunch");
|
|
181
70
|
|
|
182
|
-
//
|
|
183
|
-
init_esbuild_shims();
|
|
184
|
-
import { promisify } from "node:util";
|
|
185
|
-
import process4 from "node:process";
|
|
186
|
-
import { execFile } from "node:child_process";
|
|
71
|
+
// packages/core/src/utils/secure-browser-launcher.ts
|
|
187
72
|
var execFileAsync = promisify(execFile);
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
73
|
+
function validateUrl(url, { allowFile = false, allowedFilePaths } = {}) {
|
|
74
|
+
let parsedUrl;
|
|
75
|
+
try {
|
|
76
|
+
parsedUrl = new URL(url);
|
|
77
|
+
} catch (_error) {
|
|
78
|
+
throw new Error(`Invalid URL: ${url}`);
|
|
191
79
|
}
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments]);
|
|
213
|
-
return stdout.trim();
|
|
214
|
-
}
|
|
215
|
-
__name(runAppleScript, "runAppleScript");
|
|
216
|
-
|
|
217
|
-
// node_modules/bundle-name/index.js
|
|
218
|
-
async function bundleName(bundleId) {
|
|
219
|
-
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
220
|
-
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
221
|
-
}
|
|
222
|
-
__name(bundleName, "bundleName");
|
|
223
|
-
|
|
224
|
-
// node_modules/default-browser/windows.js
|
|
225
|
-
init_esbuild_shims();
|
|
226
|
-
import { promisify as promisify3 } from "node:util";
|
|
227
|
-
import { execFile as execFile3 } from "node:child_process";
|
|
228
|
-
var execFileAsync3 = promisify3(execFile3);
|
|
229
|
-
var windowsBrowserProgIds = {
|
|
230
|
-
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
231
|
-
MSEdgeDHTML: { name: "Edge", id: "com.microsoft.edge" },
|
|
232
|
-
// On macOS, it's "com.microsoft.edgemac"
|
|
233
|
-
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
234
|
-
// Newer Edge/Win10 releases
|
|
235
|
-
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" },
|
|
236
|
-
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
237
|
-
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
238
|
-
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
239
|
-
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
240
|
-
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" }
|
|
241
|
-
};
|
|
242
|
-
var UnknownBrowserError = class extends Error {
|
|
243
|
-
static {
|
|
244
|
-
__name(this, "UnknownBrowserError");
|
|
80
|
+
const allowedProtocols = allowFile ? ["http:", "https:", "file:"] : ["http:", "https:"];
|
|
81
|
+
if (!allowedProtocols.includes(parsedUrl.protocol)) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Unsafe protocol: ${parsedUrl.protocol}. Only ${allowedProtocols.join(
|
|
84
|
+
", "
|
|
85
|
+
)} are allowed.`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
if (parsedUrl.protocol === "file:" && allowFile) {
|
|
89
|
+
if (!allowedFilePaths?.length) {
|
|
90
|
+
throw new Error("allowedFilePaths is required when allowFile is true");
|
|
91
|
+
}
|
|
92
|
+
const requestedPath = resolve(fileURLToPath(parsedUrl));
|
|
93
|
+
const allowed = allowedFilePaths.map((filePath) => resolve(filePath));
|
|
94
|
+
if (!allowed.includes(requestedPath)) {
|
|
95
|
+
throw new Error("File URL is not in the allowed file set");
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (/[\r\n\x00-\x1f]/.test(url)) {
|
|
99
|
+
throw new Error("URL contains invalid characters");
|
|
245
100
|
}
|
|
246
|
-
};
|
|
247
|
-
async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
248
|
-
const { stdout } = await _execFileAsync("reg", [
|
|
249
|
-
"QUERY",
|
|
250
|
-
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
251
|
-
"/v",
|
|
252
|
-
"ProgId"
|
|
253
|
-
]);
|
|
254
|
-
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
255
|
-
if (!match) {
|
|
256
|
-
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
257
|
-
}
|
|
258
|
-
const { id } = match.groups;
|
|
259
|
-
const browser = windowsBrowserProgIds[id];
|
|
260
|
-
if (!browser) {
|
|
261
|
-
throw new UnknownBrowserError(`Unknown browser ID: ${id}`);
|
|
262
|
-
}
|
|
263
|
-
return browser;
|
|
264
|
-
}
|
|
265
|
-
__name(defaultBrowser, "defaultBrowser");
|
|
266
|
-
|
|
267
|
-
// node_modules/default-browser/index.js
|
|
268
|
-
var execFileAsync4 = promisify4(execFile4);
|
|
269
|
-
var titleize = /* @__PURE__ */ __name((string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase()), "titleize");
|
|
270
|
-
async function defaultBrowser2() {
|
|
271
|
-
if (process6.platform === "darwin") {
|
|
272
|
-
const id = await defaultBrowserId();
|
|
273
|
-
const name = await bundleName(id);
|
|
274
|
-
return { name, id };
|
|
275
|
-
}
|
|
276
|
-
if (process6.platform === "linux") {
|
|
277
|
-
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
278
|
-
const id = stdout.trim();
|
|
279
|
-
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
280
|
-
return { name, id };
|
|
281
|
-
}
|
|
282
|
-
if (process6.platform === "win32") {
|
|
283
|
-
return defaultBrowser();
|
|
284
|
-
}
|
|
285
|
-
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
286
|
-
}
|
|
287
|
-
__name(defaultBrowser2, "defaultBrowser");
|
|
288
|
-
|
|
289
|
-
// node_modules/open/index.js
|
|
290
|
-
var execFile5 = promisify5(childProcess.execFile);
|
|
291
|
-
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
292
|
-
var localXdgOpenPath = path.join(__dirname, "xdg-open");
|
|
293
|
-
var { platform, arch } = process7;
|
|
294
|
-
async function getWindowsDefaultBrowserFromWsl() {
|
|
295
|
-
const powershellPath = await powerShellPath();
|
|
296
|
-
const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
297
|
-
const encodedCommand = Buffer.from(rawCommand, "utf16le").toString("base64");
|
|
298
|
-
const { stdout } = await execFile5(
|
|
299
|
-
powershellPath,
|
|
300
|
-
[
|
|
301
|
-
"-NoProfile",
|
|
302
|
-
"-NonInteractive",
|
|
303
|
-
"-ExecutionPolicy",
|
|
304
|
-
"Bypass",
|
|
305
|
-
"-EncodedCommand",
|
|
306
|
-
encodedCommand
|
|
307
|
-
],
|
|
308
|
-
{ encoding: "utf8" }
|
|
309
|
-
);
|
|
310
|
-
const progId = stdout.trim();
|
|
311
|
-
const browserMap = {
|
|
312
|
-
ChromeHTML: "com.google.chrome",
|
|
313
|
-
BraveHTML: "com.brave.Browser",
|
|
314
|
-
MSEdgeHTM: "com.microsoft.edge",
|
|
315
|
-
FirefoxURL: "org.mozilla.firefox"
|
|
316
|
-
};
|
|
317
|
-
return browserMap[progId] ? { id: browserMap[progId] } : {};
|
|
318
101
|
}
|
|
319
|
-
__name(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
102
|
+
__name(validateUrl, "validateUrl");
|
|
103
|
+
async function openBrowserSecurely(url, browserOptions = {}) {
|
|
104
|
+
validateUrl(url, browserOptions);
|
|
105
|
+
const platformName = platform();
|
|
106
|
+
let command;
|
|
107
|
+
let args;
|
|
108
|
+
const browserEnv = process.env["BROWSER"]?.trim();
|
|
109
|
+
const browserCommand = platformName === "win32" ? void 0 : buildBrowserCommand(browserEnv, url);
|
|
110
|
+
if (browserCommand) {
|
|
323
111
|
try {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
112
|
+
await launchDetached(browserCommand.command, browserCommand.args);
|
|
113
|
+
return;
|
|
114
|
+
} catch (_error) {
|
|
115
|
+
console.warn(
|
|
116
|
+
`Failed to open BROWSER command ${browserCommand.command}: ${formatLaunchError(
|
|
117
|
+
_error
|
|
118
|
+
)}. Falling back to the platform browser opener.`
|
|
119
|
+
);
|
|
327
120
|
}
|
|
328
121
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
122
|
+
if (!shouldAttemptBrowserLaunch({ ignoreBrowserBlocklist: true })) {
|
|
123
|
+
console.warn(
|
|
124
|
+
`Browser launch is not available in this environment. Please open this URL manually: ${url}`
|
|
125
|
+
);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
{
|
|
129
|
+
switch (platformName) {
|
|
130
|
+
case "darwin":
|
|
131
|
+
command = "open";
|
|
132
|
+
args = [url];
|
|
133
|
+
break;
|
|
134
|
+
case "win32":
|
|
135
|
+
command = "powershell.exe";
|
|
136
|
+
args = [
|
|
137
|
+
"-NoProfile",
|
|
138
|
+
"-NonInteractive",
|
|
139
|
+
"-WindowStyle",
|
|
140
|
+
"Hidden",
|
|
141
|
+
"-Command",
|
|
142
|
+
`Start-Process '${url.replace(/'/g, "''")}'`
|
|
143
|
+
];
|
|
144
|
+
break;
|
|
145
|
+
case "linux":
|
|
146
|
+
case "freebsd":
|
|
147
|
+
case "openbsd":
|
|
148
|
+
command = "xdg-open";
|
|
149
|
+
args = [url];
|
|
150
|
+
break;
|
|
151
|
+
default:
|
|
152
|
+
throw new Error(`Unsupported platform: ${platformName}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const execOptions = {
|
|
156
|
+
// Don't inherit parent's environment to avoid potential issues
|
|
157
|
+
env: {
|
|
158
|
+
...process.env,
|
|
159
|
+
// Ensure we're not in a shell that might interpret special characters
|
|
160
|
+
SHELL: void 0
|
|
161
|
+
},
|
|
162
|
+
// Detach the browser process so it doesn't block
|
|
163
|
+
detached: true,
|
|
164
|
+
stdio: "ignore"
|
|
338
165
|
};
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
"org.mozilla.firefox": "firefox",
|
|
362
|
-
"firefox.desktop": "firefox",
|
|
363
|
-
"com.microsoft.msedge": "edge",
|
|
364
|
-
"com.microsoft.edge": "edge",
|
|
365
|
-
"com.microsoft.edgemac": "edge",
|
|
366
|
-
"microsoft-edge.desktop": "edge"
|
|
367
|
-
};
|
|
368
|
-
const flags = {
|
|
369
|
-
chrome: "--incognito",
|
|
370
|
-
brave: "--incognito",
|
|
371
|
-
firefox: "--private-window",
|
|
372
|
-
edge: "--inPrivate"
|
|
373
|
-
};
|
|
374
|
-
const browser = is_wsl_default ? await getWindowsDefaultBrowserFromWsl() : await defaultBrowser2();
|
|
375
|
-
if (browser.id in ids) {
|
|
376
|
-
const browserName = ids[browser.id];
|
|
377
|
-
if (app === "browserPrivate") {
|
|
378
|
-
appArguments.push(flags[browserName]);
|
|
379
|
-
}
|
|
380
|
-
return baseOpen({
|
|
381
|
-
...options,
|
|
382
|
-
app: {
|
|
383
|
-
name: apps[browserName],
|
|
384
|
-
arguments: appArguments
|
|
166
|
+
try {
|
|
167
|
+
await execFileAsync(command, args, execOptions);
|
|
168
|
+
} catch (_error) {
|
|
169
|
+
if ((platformName === "linux" || platformName === "freebsd" || platformName === "openbsd") && command === "xdg-open") {
|
|
170
|
+
const fallbackCommands = [
|
|
171
|
+
{ command: "gnome-open", detached: false },
|
|
172
|
+
{ command: "kde-open", detached: false },
|
|
173
|
+
{ command: "firefox", detached: true },
|
|
174
|
+
{ command: "chromium", detached: true },
|
|
175
|
+
{ command: "google-chrome", detached: true },
|
|
176
|
+
{ command: "microsoft-edge", detached: true }
|
|
177
|
+
];
|
|
178
|
+
for (const { command: fallbackCommand, detached } of fallbackCommands) {
|
|
179
|
+
try {
|
|
180
|
+
if (detached) {
|
|
181
|
+
await launchDetached(fallbackCommand, [url]);
|
|
182
|
+
} else {
|
|
183
|
+
await execFileAsync(fallbackCommand, [url], execOptions);
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
} catch {
|
|
187
|
+
continue;
|
|
385
188
|
}
|
|
386
|
-
}
|
|
189
|
+
}
|
|
387
190
|
}
|
|
388
|
-
|
|
191
|
+
console.warn(
|
|
192
|
+
`Failed to open browser automatically. Please open this URL manually: ${url}`
|
|
193
|
+
);
|
|
194
|
+
return;
|
|
389
195
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
196
|
+
}
|
|
197
|
+
__name(openBrowserSecurely, "openBrowserSecurely");
|
|
198
|
+
async function launchDetached(command, args) {
|
|
199
|
+
const spawnOptions = {
|
|
200
|
+
env: {
|
|
201
|
+
...process.env,
|
|
202
|
+
SHELL: void 0
|
|
203
|
+
},
|
|
204
|
+
detached: true,
|
|
205
|
+
stdio: "ignore"
|
|
206
|
+
};
|
|
207
|
+
await new Promise((resolve2, reject) => {
|
|
208
|
+
const child = spawn(command, args, spawnOptions);
|
|
209
|
+
let settled = false;
|
|
210
|
+
child.once("error", (error) => {
|
|
211
|
+
if (settled) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
settled = true;
|
|
215
|
+
reject(error);
|
|
216
|
+
});
|
|
217
|
+
child.once("spawn", () => {
|
|
218
|
+
if (settled) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
settled = true;
|
|
222
|
+
child.unref();
|
|
223
|
+
resolve2();
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
__name(launchDetached, "launchDetached");
|
|
228
|
+
function formatLaunchError(error) {
|
|
229
|
+
return error instanceof Error ? error.message : String(error);
|
|
230
|
+
}
|
|
231
|
+
__name(formatLaunchError, "formatLaunchError");
|
|
232
|
+
function buildBrowserCommand(browserEnv, url) {
|
|
233
|
+
if (!browserEnv) {
|
|
234
|
+
return void 0;
|
|
235
|
+
}
|
|
236
|
+
const browserCommand = parseBrowserCommand(browserEnv);
|
|
237
|
+
if (!browserCommand) {
|
|
238
|
+
console.warn(
|
|
239
|
+
"Invalid BROWSER environment variable, falling back to platform default."
|
|
415
240
|
);
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
241
|
+
return void 0;
|
|
242
|
+
}
|
|
243
|
+
if (isBrowserCommandBlocked(browserCommand.command)) {
|
|
244
|
+
return void 0;
|
|
245
|
+
}
|
|
246
|
+
let usedPlaceholder = false;
|
|
247
|
+
const args = browserCommand.args.map((arg) => {
|
|
248
|
+
if (!arg.includes("%s")) {
|
|
249
|
+
return arg;
|
|
422
250
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
251
|
+
usedPlaceholder = true;
|
|
252
|
+
return arg.replace(/%s/g, () => url);
|
|
253
|
+
});
|
|
254
|
+
if (!usedPlaceholder) {
|
|
255
|
+
args.push(url);
|
|
256
|
+
}
|
|
257
|
+
return { command: browserCommand.command, args };
|
|
258
|
+
}
|
|
259
|
+
__name(buildBrowserCommand, "buildBrowserCommand");
|
|
260
|
+
function parseBrowserCommand(browserEnv) {
|
|
261
|
+
const parts = [];
|
|
262
|
+
let current = "";
|
|
263
|
+
let quote;
|
|
264
|
+
for (const char of browserEnv) {
|
|
265
|
+
if (quote) {
|
|
266
|
+
if (char === quote) {
|
|
267
|
+
quote = void 0;
|
|
268
|
+
} else {
|
|
269
|
+
current += char;
|
|
427
270
|
}
|
|
428
|
-
|
|
429
|
-
encodedArguments.push(`"${options.target}"`);
|
|
271
|
+
continue;
|
|
430
272
|
}
|
|
431
|
-
if (
|
|
432
|
-
|
|
433
|
-
|
|
273
|
+
if (char === '"' || char === "'") {
|
|
274
|
+
quote = char;
|
|
275
|
+
continue;
|
|
434
276
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
} else {
|
|
440
|
-
const isBundled = !__dirname || __dirname === "/";
|
|
441
|
-
let exeLocalXdgOpen = false;
|
|
442
|
-
try {
|
|
443
|
-
await fs5.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
444
|
-
exeLocalXdgOpen = true;
|
|
445
|
-
} catch {
|
|
277
|
+
if (/\s/.test(char)) {
|
|
278
|
+
if (current) {
|
|
279
|
+
parts.push(current);
|
|
280
|
+
current = "";
|
|
446
281
|
}
|
|
447
|
-
|
|
448
|
-
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
449
|
-
}
|
|
450
|
-
if (appArguments.length > 0) {
|
|
451
|
-
cliArguments.push(...appArguments);
|
|
452
|
-
}
|
|
453
|
-
if (!options.wait) {
|
|
454
|
-
childProcessOptions.stdio = "ignore";
|
|
455
|
-
childProcessOptions.detached = true;
|
|
282
|
+
continue;
|
|
456
283
|
}
|
|
284
|
+
current += char;
|
|
457
285
|
}
|
|
458
|
-
if (
|
|
459
|
-
|
|
286
|
+
if (quote) {
|
|
287
|
+
return void 0;
|
|
460
288
|
}
|
|
461
|
-
if (
|
|
462
|
-
|
|
289
|
+
if (current) {
|
|
290
|
+
parts.push(current);
|
|
463
291
|
}
|
|
464
|
-
const
|
|
465
|
-
if (
|
|
466
|
-
return
|
|
467
|
-
subprocess.once("error", reject);
|
|
468
|
-
subprocess.once("close", (exitCode) => {
|
|
469
|
-
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
470
|
-
reject(new Error(`Exited with code ${exitCode}`));
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
resolve(subprocess);
|
|
474
|
-
});
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
subprocess.unref();
|
|
478
|
-
return subprocess;
|
|
479
|
-
}, "baseOpen");
|
|
480
|
-
var open = /* @__PURE__ */ __name((target, options) => {
|
|
481
|
-
if (typeof target !== "string") {
|
|
482
|
-
throw new TypeError("Expected a `target`");
|
|
483
|
-
}
|
|
484
|
-
return baseOpen({
|
|
485
|
-
...options,
|
|
486
|
-
target
|
|
487
|
-
});
|
|
488
|
-
}, "open");
|
|
489
|
-
function detectArchBinary(binary) {
|
|
490
|
-
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
491
|
-
return binary;
|
|
492
|
-
}
|
|
493
|
-
const { [arch]: archBinary } = binary;
|
|
494
|
-
if (!archBinary) {
|
|
495
|
-
throw new Error(`${arch} is not supported`);
|
|
292
|
+
const [command, ...args] = parts;
|
|
293
|
+
if (!command) {
|
|
294
|
+
return void 0;
|
|
496
295
|
}
|
|
497
|
-
return
|
|
296
|
+
return { command, args };
|
|
498
297
|
}
|
|
499
|
-
__name(
|
|
500
|
-
function
|
|
501
|
-
|
|
502
|
-
return detectArchBinary(wsl);
|
|
503
|
-
}
|
|
504
|
-
if (!platformBinary) {
|
|
505
|
-
throw new Error(`${platform} is not supported`);
|
|
506
|
-
}
|
|
507
|
-
return detectArchBinary(platformBinary);
|
|
298
|
+
__name(parseBrowserCommand, "parseBrowserCommand");
|
|
299
|
+
function shouldLaunchBrowser() {
|
|
300
|
+
return shouldAttemptBrowserLaunch();
|
|
508
301
|
}
|
|
509
|
-
__name(
|
|
510
|
-
var apps = {};
|
|
511
|
-
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
512
|
-
darwin: "google chrome",
|
|
513
|
-
win32: "chrome",
|
|
514
|
-
linux: ["google-chrome", "google-chrome-stable", "chromium"]
|
|
515
|
-
}, {
|
|
516
|
-
wsl: {
|
|
517
|
-
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
518
|
-
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
519
|
-
}
|
|
520
|
-
}));
|
|
521
|
-
defineLazyProperty(apps, "brave", () => detectPlatformBinary({
|
|
522
|
-
darwin: "brave browser",
|
|
523
|
-
win32: "brave",
|
|
524
|
-
linux: ["brave-browser", "brave"]
|
|
525
|
-
}, {
|
|
526
|
-
wsl: {
|
|
527
|
-
ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
528
|
-
x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
|
|
529
|
-
}
|
|
530
|
-
}));
|
|
531
|
-
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
532
|
-
darwin: "firefox",
|
|
533
|
-
win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
|
|
534
|
-
linux: "firefox"
|
|
535
|
-
}, {
|
|
536
|
-
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
537
|
-
}));
|
|
538
|
-
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
539
|
-
darwin: "microsoft edge",
|
|
540
|
-
win32: "msedge",
|
|
541
|
-
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
542
|
-
}, {
|
|
543
|
-
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
544
|
-
}));
|
|
545
|
-
defineLazyProperty(apps, "browser", () => "browser");
|
|
546
|
-
defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
|
|
547
|
-
var open_default = open;
|
|
548
|
-
|
|
549
|
-
// packages/core/src/qwen/qwenOAuth2.ts
|
|
550
|
-
import { EventEmitter } from "events";
|
|
551
|
-
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
302
|
+
__name(shouldLaunchBrowser, "shouldLaunchBrowser");
|
|
552
303
|
|
|
553
304
|
// packages/core/src/qwen/sharedTokenManager.ts
|
|
554
305
|
init_esbuild_shims();
|
|
555
|
-
import
|
|
556
|
-
import { promises as
|
|
306
|
+
import path from "node:path";
|
|
307
|
+
import { promises as fs, unlinkSync } from "node:fs";
|
|
557
308
|
import { randomUUID } from "node:crypto";
|
|
558
309
|
var debugLogger = createDebugLogger("QWEN_OAUTH");
|
|
559
310
|
var QWEN_CREDENTIAL_FILENAME = "oauth_creds.json";
|
|
560
311
|
var QWEN_LOCK_FILENAME = "oauth_creds.lock";
|
|
561
312
|
var TOKEN_REFRESH_BUFFER_MS = 30 * 1e3;
|
|
562
|
-
var LOCK_TIMEOUT_MS =
|
|
313
|
+
var LOCK_TIMEOUT_MS = 35e3;
|
|
563
314
|
var CACHE_CHECK_INTERVAL_MS = 5e3;
|
|
564
315
|
var DEFAULT_LOCK_CONFIG = {
|
|
565
316
|
maxAttempts: 20,
|
|
@@ -766,7 +517,7 @@ var SharedTokenManager = class _SharedTokenManager {
|
|
|
766
517
|
try {
|
|
767
518
|
const filePath = this.getCredentialFilePath();
|
|
768
519
|
const stats = await this.withTimeout(
|
|
769
|
-
|
|
520
|
+
fs.stat(filePath),
|
|
770
521
|
3e3,
|
|
771
522
|
"File operation"
|
|
772
523
|
);
|
|
@@ -793,7 +544,7 @@ var SharedTokenManager = class _SharedTokenManager {
|
|
|
793
544
|
async forceFileCheck(qwenClient) {
|
|
794
545
|
try {
|
|
795
546
|
const filePath = this.getCredentialFilePath();
|
|
796
|
-
const stats = await
|
|
547
|
+
const stats = await fs.stat(filePath);
|
|
797
548
|
const fileModTime = stats.mtimeMs;
|
|
798
549
|
if (fileModTime > this.memoryCache.fileModTime) {
|
|
799
550
|
await this.reloadCredentialsFromFile(qwenClient);
|
|
@@ -818,7 +569,7 @@ var SharedTokenManager = class _SharedTokenManager {
|
|
|
818
569
|
async reloadCredentialsFromFile(qwenClient) {
|
|
819
570
|
try {
|
|
820
571
|
const filePath = this.getCredentialFilePath();
|
|
821
|
-
const content = await
|
|
572
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
822
573
|
const parsedData = JSON.parse(content);
|
|
823
574
|
const credentials = validateCredentials(parsedData);
|
|
824
575
|
const previousCredentials = this.memoryCache.credentials;
|
|
@@ -946,10 +697,10 @@ var SharedTokenManager = class _SharedTokenManager {
|
|
|
946
697
|
*/
|
|
947
698
|
async saveCredentialsToFile(credentials) {
|
|
948
699
|
const filePath = this.getCredentialFilePath();
|
|
949
|
-
const dirPath =
|
|
700
|
+
const dirPath = path.dirname(filePath);
|
|
950
701
|
try {
|
|
951
702
|
await this.withTimeout(
|
|
952
|
-
|
|
703
|
+
fs.mkdir(dirPath, { recursive: true, mode: 448 }),
|
|
953
704
|
5e3,
|
|
954
705
|
"File operation"
|
|
955
706
|
);
|
|
@@ -968,7 +719,7 @@ var SharedTokenManager = class _SharedTokenManager {
|
|
|
968
719
|
noFollow: true
|
|
969
720
|
});
|
|
970
721
|
const stats = await this.withTimeout(
|
|
971
|
-
|
|
722
|
+
fs.stat(filePath),
|
|
972
723
|
5e3,
|
|
973
724
|
"File operation"
|
|
974
725
|
);
|
|
@@ -999,7 +750,7 @@ var SharedTokenManager = class _SharedTokenManager {
|
|
|
999
750
|
* @returns The absolute path to the credentials file
|
|
1000
751
|
*/
|
|
1001
752
|
getCredentialFilePath() {
|
|
1002
|
-
return
|
|
753
|
+
return path.join(Storage.getGlobalQwenDir(), QWEN_CREDENTIAL_FILENAME);
|
|
1003
754
|
}
|
|
1004
755
|
/**
|
|
1005
756
|
* Get the full path to the lock file
|
|
@@ -1007,7 +758,7 @@ var SharedTokenManager = class _SharedTokenManager {
|
|
|
1007
758
|
* @returns The absolute path to the lock file
|
|
1008
759
|
*/
|
|
1009
760
|
getLockFilePath() {
|
|
1010
|
-
return
|
|
761
|
+
return path.join(Storage.getGlobalQwenDir(), QWEN_LOCK_FILENAME);
|
|
1011
762
|
}
|
|
1012
763
|
/**
|
|
1013
764
|
* Acquire a file lock to prevent other processes from refreshing tokens simultaneously
|
|
@@ -1021,18 +772,18 @@ var SharedTokenManager = class _SharedTokenManager {
|
|
|
1021
772
|
let currentInterval = attemptInterval;
|
|
1022
773
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
1023
774
|
try {
|
|
1024
|
-
await
|
|
775
|
+
await fs.writeFile(lockPath, lockId, { flag: "wx" });
|
|
1025
776
|
return;
|
|
1026
777
|
} catch (error) {
|
|
1027
778
|
if (error.code === "EEXIST") {
|
|
1028
779
|
try {
|
|
1029
|
-
const stats = await
|
|
780
|
+
const stats = await fs.stat(lockPath);
|
|
1030
781
|
const lockAge = Date.now() - stats.mtimeMs;
|
|
1031
782
|
if (lockAge > LOCK_TIMEOUT_MS) {
|
|
1032
783
|
const tempPath = `${lockPath}.stale.${randomUUID()}`;
|
|
1033
784
|
try {
|
|
1034
|
-
await
|
|
1035
|
-
await
|
|
785
|
+
await fs.rename(lockPath, tempPath);
|
|
786
|
+
await fs.unlink(tempPath);
|
|
1036
787
|
debugLogger.warn(
|
|
1037
788
|
`Removed stale lock file: ${lockPath} (age: ${lockAge}ms)`
|
|
1038
789
|
);
|
|
@@ -1048,7 +799,7 @@ var SharedTokenManager = class _SharedTokenManager {
|
|
|
1048
799
|
`Failed to stat lock file ${lockPath}: ${statError instanceof Error ? statError.message : String(statError)}`
|
|
1049
800
|
);
|
|
1050
801
|
}
|
|
1051
|
-
await new Promise((
|
|
802
|
+
await new Promise((resolve2) => setTimeout(resolve2, currentInterval));
|
|
1052
803
|
currentInterval = Math.min(currentInterval * 1.5, maxInterval);
|
|
1053
804
|
} else {
|
|
1054
805
|
throw new TokenManagerError(
|
|
@@ -1071,7 +822,7 @@ var SharedTokenManager = class _SharedTokenManager {
|
|
|
1071
822
|
*/
|
|
1072
823
|
async releaseLock(lockPath) {
|
|
1073
824
|
try {
|
|
1074
|
-
await
|
|
825
|
+
await fs.unlink(lockPath);
|
|
1075
826
|
} catch (error) {
|
|
1076
827
|
if (error.code !== "ENOENT") {
|
|
1077
828
|
debugLogger.warn(
|
|
@@ -1164,6 +915,7 @@ var QWEN_OAUTH_TOKEN_ENDPOINT = `${QWEN_OAUTH_BASE_URL}/api/v1/oauth2/token`;
|
|
|
1164
915
|
var QWEN_OAUTH_CLIENT_ID = "f0304373b74a44d2b584a3fb70ca9e56";
|
|
1165
916
|
var QWEN_OAUTH_SCOPE = "openid profile email model.completion";
|
|
1166
917
|
var QWEN_OAUTH_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
|
|
918
|
+
var QWEN_OAUTH_REFRESH_TIMEOUT_MS = 3e4;
|
|
1167
919
|
var QWEN_CREDENTIAL_FILENAME2 = "oauth_creds.json";
|
|
1168
920
|
function generateCodeVerifier() {
|
|
1169
921
|
return crypto.randomBytes(32).toString("base64url");
|
|
@@ -1185,6 +937,16 @@ function objectToUrlEncoded(data) {
|
|
|
1185
937
|
return Object.keys(data).map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`).join("&");
|
|
1186
938
|
}
|
|
1187
939
|
__name(objectToUrlEncoded, "objectToUrlEncoded");
|
|
940
|
+
function createTokenRefreshNetworkError(error, timedOut) {
|
|
941
|
+
const prefix = timedOut ? "Token refresh timeout" : "Token refresh failed";
|
|
942
|
+
return new Error(
|
|
943
|
+
`${prefix}: ${formatFetchErrorForUser(error, {
|
|
944
|
+
url: QWEN_OAUTH_TOKEN_ENDPOINT
|
|
945
|
+
})}`,
|
|
946
|
+
{ cause: error }
|
|
947
|
+
);
|
|
948
|
+
}
|
|
949
|
+
__name(createTokenRefreshNetworkError, "createTokenRefreshNetworkError");
|
|
1188
950
|
var CredentialsClearRequiredError = class extends Error {
|
|
1189
951
|
constructor(message, originalError) {
|
|
1190
952
|
super(message);
|
|
@@ -1362,59 +1124,78 @@ var QwenOAuth2Client = class {
|
|
|
1362
1124
|
refresh_token: this.credentials.refresh_token,
|
|
1363
1125
|
client_id: QWEN_OAUTH_CLIENT_ID
|
|
1364
1126
|
};
|
|
1365
|
-
const
|
|
1366
|
-
|
|
1367
|
-
headers: {
|
|
1368
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
1369
|
-
Accept: "application/json"
|
|
1370
|
-
},
|
|
1371
|
-
body: objectToUrlEncoded(bodyData)
|
|
1127
|
+
const { signal, cleanup } = combineAbortSignals([], {
|
|
1128
|
+
timeoutMs: QWEN_OAUTH_REFRESH_TIMEOUT_MS
|
|
1372
1129
|
});
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1130
|
+
debugLogger2.debug("Refreshing access token...");
|
|
1131
|
+
try {
|
|
1132
|
+
let response;
|
|
1133
|
+
try {
|
|
1134
|
+
response = await fetch(QWEN_OAUTH_TOKEN_ENDPOINT, {
|
|
1135
|
+
method: "POST",
|
|
1136
|
+
headers: {
|
|
1137
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
1138
|
+
Accept: "application/json"
|
|
1139
|
+
},
|
|
1140
|
+
body: objectToUrlEncoded(bodyData),
|
|
1141
|
+
signal
|
|
1142
|
+
});
|
|
1143
|
+
} catch (error) {
|
|
1144
|
+
throw createTokenRefreshNetworkError(error, signal.aborted);
|
|
1145
|
+
}
|
|
1146
|
+
if (!response.ok) {
|
|
1147
|
+
let errorData;
|
|
1148
|
+
try {
|
|
1149
|
+
errorData = await response.text();
|
|
1150
|
+
} catch (error) {
|
|
1151
|
+
throw createTokenRefreshNetworkError(error, signal.aborted);
|
|
1152
|
+
}
|
|
1153
|
+
if (response.status === 400 || response.status === 401) {
|
|
1154
|
+
await clearQwenCredentials();
|
|
1155
|
+
throw new CredentialsClearRequiredError(
|
|
1156
|
+
"Refresh token expired or invalid. Please use '/auth' to re-authenticate.",
|
|
1157
|
+
{ status: response.status, response: errorData }
|
|
1158
|
+
);
|
|
1159
|
+
}
|
|
1160
|
+
throw new Error(
|
|
1161
|
+
`Token refresh failed: ${response.status} ${response.statusText}. Response: ${errorData}`
|
|
1380
1162
|
);
|
|
1381
1163
|
}
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1164
|
+
let responseText;
|
|
1165
|
+
try {
|
|
1166
|
+
responseText = await response.text();
|
|
1167
|
+
} catch (error) {
|
|
1168
|
+
throw createTokenRefreshNetworkError(error, signal.aborted);
|
|
1169
|
+
}
|
|
1170
|
+
let responseData;
|
|
1171
|
+
try {
|
|
1172
|
+
responseData = JSON.parse(responseText);
|
|
1173
|
+
} catch {
|
|
1174
|
+
throw new Error(
|
|
1175
|
+
`Qwen OAuth refresh returned invalid JSON: ${responseText || "(empty response body)"}`
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1178
|
+
if (isErrorResponse(responseData)) {
|
|
1179
|
+
const errorData = responseData;
|
|
1180
|
+
throw new Error(
|
|
1181
|
+
`Token refresh failed: ${errorData?.error || "Unknown error"} - ${errorData?.error_description || "No details provided"}`
|
|
1182
|
+
);
|
|
1183
|
+
}
|
|
1184
|
+
const tokenData = responseData;
|
|
1185
|
+
const tokens = {
|
|
1186
|
+
access_token: tokenData.access_token,
|
|
1187
|
+
token_type: tokenData.token_type,
|
|
1188
|
+
// Use new refresh token if provided, otherwise preserve existing one
|
|
1189
|
+
refresh_token: tokenData.refresh_token || this.credentials.refresh_token,
|
|
1190
|
+
resource_url: tokenData.resource_url,
|
|
1191
|
+
// Include resource_url if provided
|
|
1192
|
+
expiry_date: Date.now() + tokenData.expires_in * 1e3
|
|
1193
|
+
};
|
|
1194
|
+
this.setCredentials(tokens);
|
|
1195
|
+
return responseData;
|
|
1196
|
+
} finally {
|
|
1197
|
+
cleanup();
|
|
1405
1198
|
}
|
|
1406
|
-
const tokenData = responseData;
|
|
1407
|
-
const tokens = {
|
|
1408
|
-
access_token: tokenData.access_token,
|
|
1409
|
-
token_type: tokenData.token_type,
|
|
1410
|
-
// Use new refresh token if provided, otherwise preserve existing one
|
|
1411
|
-
refresh_token: tokenData.refresh_token || this.credentials.refresh_token,
|
|
1412
|
-
resource_url: tokenData.resource_url,
|
|
1413
|
-
// Include resource_url if provided
|
|
1414
|
-
expiry_date: Date.now() + tokenData.expires_in * 1e3
|
|
1415
|
-
};
|
|
1416
|
-
this.setCredentials(tokens);
|
|
1417
|
-
return responseData;
|
|
1418
1199
|
}
|
|
1419
1200
|
};
|
|
1420
1201
|
var QwenOAuth2Event = /* @__PURE__ */ ((QwenOAuth2Event2) => {
|
|
@@ -1572,19 +1353,8 @@ async function authWithQwenDeviceFlow(client, config) {
|
|
|
1572
1353
|
qwenOAuth2Events.emit("auth-progress" /* AuthProgress */, status, message);
|
|
1573
1354
|
}, "emitAuthProgress");
|
|
1574
1355
|
const launchBrowser = /* @__PURE__ */ __name(async (url) => {
|
|
1575
|
-
let childProcess2;
|
|
1576
1356
|
try {
|
|
1577
|
-
|
|
1578
|
-
if (childProcess2 && typeof childProcess2.on === "function") {
|
|
1579
|
-
childProcess2.on("error", (err) => {
|
|
1580
|
-
debugLogger2.warn(`Browser launch process error: ${err.message}`);
|
|
1581
|
-
debugLogger2.info(`Please open this URL manually: ${url}`);
|
|
1582
|
-
});
|
|
1583
|
-
} else {
|
|
1584
|
-
debugLogger2.debug(
|
|
1585
|
-
"open() did not return a valid child process object."
|
|
1586
|
-
);
|
|
1587
|
-
}
|
|
1357
|
+
await openBrowserSecurely(url);
|
|
1588
1358
|
} catch (err) {
|
|
1589
1359
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
1590
1360
|
debugLogger2.warn(`Failed to open browser automatically: ${errorMessage}`);
|
|
@@ -1664,19 +1434,19 @@ Server requested to slow down, increasing poll interval to ${pollInterval}ms'`
|
|
|
1664
1434
|
"polling",
|
|
1665
1435
|
`Polling... (attempt ${attempt + 1}/${maxAttempts})`
|
|
1666
1436
|
);
|
|
1667
|
-
await new Promise((
|
|
1437
|
+
await new Promise((resolve2) => {
|
|
1668
1438
|
const checkInterval = 100;
|
|
1669
1439
|
let elapsedTime = 0;
|
|
1670
1440
|
const intervalId = setInterval(() => {
|
|
1671
1441
|
elapsedTime += checkInterval;
|
|
1672
1442
|
if (isCancelled) {
|
|
1673
1443
|
clearInterval(intervalId);
|
|
1674
|
-
|
|
1444
|
+
resolve2();
|
|
1675
1445
|
return;
|
|
1676
1446
|
}
|
|
1677
1447
|
if (elapsedTime >= pollInterval) {
|
|
1678
1448
|
clearInterval(intervalId);
|
|
1679
|
-
|
|
1449
|
+
resolve2();
|
|
1680
1450
|
return;
|
|
1681
1451
|
}
|
|
1682
1452
|
}, checkInterval);
|
|
@@ -1722,7 +1492,7 @@ Server requested to slow down, increasing poll interval to ${pollInterval}ms'`
|
|
|
1722
1492
|
}
|
|
1723
1493
|
const message = `Error polling for token: ${errorMessage}`;
|
|
1724
1494
|
emitAuthProgress("error", message);
|
|
1725
|
-
await new Promise((
|
|
1495
|
+
await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
|
|
1726
1496
|
}
|
|
1727
1497
|
}
|
|
1728
1498
|
const timeoutMessage = "Authorization timeout, please restart the process.";
|
|
@@ -1744,16 +1514,16 @@ var QWEN_CREDENTIAL_FILE_MODE = 384;
|
|
|
1744
1514
|
async function cacheQwenCredentials(credentials, opts) {
|
|
1745
1515
|
const filePath = getQwenCachedCredentialPath();
|
|
1746
1516
|
try {
|
|
1747
|
-
await
|
|
1517
|
+
await fs2.mkdir(path2.dirname(filePath), { recursive: true });
|
|
1748
1518
|
const credString = JSON.stringify(credentials, null, 2);
|
|
1749
1519
|
const tempPath = `${filePath}.tmp.${process.pid}.${randomUUID2()}`;
|
|
1750
1520
|
try {
|
|
1751
|
-
await
|
|
1521
|
+
await fs2.writeFile(tempPath, credString, {
|
|
1752
1522
|
mode: QWEN_CREDENTIAL_FILE_MODE,
|
|
1753
1523
|
...opts?.signal ? { signal: opts.signal } : {}
|
|
1754
1524
|
});
|
|
1755
1525
|
try {
|
|
1756
|
-
await
|
|
1526
|
+
await fs2.chmod(tempPath, QWEN_CREDENTIAL_FILE_MODE);
|
|
1757
1527
|
} catch (chmodErr) {
|
|
1758
1528
|
if (process.platform !== "win32") {
|
|
1759
1529
|
throw new Error(
|
|
@@ -1764,10 +1534,10 @@ async function cacheQwenCredentials(credentials, opts) {
|
|
|
1764
1534
|
`cacheQwenCredentials: chmod 0o${QWEN_CREDENTIAL_FILE_MODE.toString(8)} on Windows temp file ${tempPath} failed; relying on NTFS ACL: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}`
|
|
1765
1535
|
);
|
|
1766
1536
|
}
|
|
1767
|
-
await
|
|
1537
|
+
await fs2.rename(tempPath, filePath);
|
|
1768
1538
|
} catch (writeErr) {
|
|
1769
1539
|
try {
|
|
1770
|
-
await
|
|
1540
|
+
await fs2.unlink(tempPath);
|
|
1771
1541
|
} catch {
|
|
1772
1542
|
}
|
|
1773
1543
|
throw writeErr;
|
|
@@ -1788,7 +1558,7 @@ async function cacheQwenCredentials(credentials, opts) {
|
|
|
1788
1558
|
);
|
|
1789
1559
|
}
|
|
1790
1560
|
throw new Error(
|
|
1791
|
-
`Failed to cache credentials: error when creating folder \`${
|
|
1561
|
+
`Failed to cache credentials: error when creating folder \`${path2.dirname(filePath)}\` and writing to \`${filePath}\`. ${errorMessage}. Please check permissions.`
|
|
1792
1562
|
);
|
|
1793
1563
|
}
|
|
1794
1564
|
}
|
|
@@ -1796,7 +1566,7 @@ __name(cacheQwenCredentials, "cacheQwenCredentials");
|
|
|
1796
1566
|
async function clearQwenCredentials() {
|
|
1797
1567
|
try {
|
|
1798
1568
|
const filePath = getQwenCachedCredentialPath();
|
|
1799
|
-
await
|
|
1569
|
+
await fs2.unlink(filePath);
|
|
1800
1570
|
debugLogger2.debug("Cached Qwen credentials cleared successfully.");
|
|
1801
1571
|
} catch (error) {
|
|
1802
1572
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -1815,13 +1585,16 @@ async function clearQwenCredentials() {
|
|
|
1815
1585
|
}
|
|
1816
1586
|
__name(clearQwenCredentials, "clearQwenCredentials");
|
|
1817
1587
|
function getQwenCachedCredentialPath() {
|
|
1818
|
-
return
|
|
1588
|
+
return path2.join(Storage.getGlobalQwenDir(), QWEN_CREDENTIAL_FILENAME2);
|
|
1819
1589
|
}
|
|
1820
1590
|
__name(getQwenCachedCredentialPath, "getQwenCachedCredentialPath");
|
|
1821
1591
|
var clearCachedCredentialFile = clearQwenCredentials;
|
|
1822
1592
|
|
|
1823
1593
|
export {
|
|
1824
|
-
|
|
1594
|
+
isBrowserCommandBlocked,
|
|
1595
|
+
shouldAttemptBrowserLaunch,
|
|
1596
|
+
openBrowserSecurely,
|
|
1597
|
+
shouldLaunchBrowser,
|
|
1825
1598
|
SharedTokenManager,
|
|
1826
1599
|
generateCodeVerifier,
|
|
1827
1600
|
generateCodeChallenge,
|
|
@@ -1841,6 +1614,11 @@ export {
|
|
|
1841
1614
|
clearQwenCredentials,
|
|
1842
1615
|
clearCachedCredentialFile
|
|
1843
1616
|
};
|
|
1617
|
+
/**
|
|
1618
|
+
* @license
|
|
1619
|
+
* Copyright 2025 Google LLC
|
|
1620
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
1621
|
+
*/
|
|
1844
1622
|
/**
|
|
1845
1623
|
* @license
|
|
1846
1624
|
* Copyright 2025 Qwen
|