@qwen-code/qwen-code 0.16.0-preview.0 → 0.16.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.
Files changed (89) hide show
  1. package/bundled/qc-helper/docs/configuration/settings.md +39 -37
  2. package/bundled/qc-helper/docs/features/_meta.ts +2 -0
  3. package/bundled/qc-helper/docs/features/approval-mode.md +119 -2
  4. package/bundled/qc-helper/docs/features/auto-mode.md +263 -0
  5. package/bundled/qc-helper/docs/features/commands.md +11 -10
  6. package/bundled/qc-helper/docs/features/skills.md +3 -0
  7. package/bundled/qc-helper/docs/features/structured-output.md +309 -0
  8. package/bundled/qc-helper/docs/features/sub-agents.md +47 -5
  9. package/bundled/qc-helper/docs/qwen-serve.md +119 -14
  10. package/bundled/review/SKILL.md +12 -3
  11. package/chunks/{agent-ZNQPH67I.js → agent-2JCG7FDJ.js} +9 -11
  12. package/chunks/{anthropicContentGenerator-ICBDZ6R2.js → anthropicContentGenerator-RQJNXJIY.js} +6 -3
  13. package/chunks/{askUserQuestion-WQILGUSQ.js → askUserQuestion-PQPMPNM3.js} +1 -1
  14. package/chunks/{ca-S3XJMT6P.js → ca-UZ7BANMN.js} +3 -3
  15. package/chunks/{chunk-XVHR7ATJ.js → chunk-4AOCVI6J.js} +1 -0
  16. package/chunks/chunk-7LMPOVYW.js +956 -0
  17. package/chunks/{chunk-MNPZ2WO6.js → chunk-BAZDG3QU.js} +9104 -3955
  18. package/chunks/{chunk-AEJ2DKLP.js → chunk-C6WMLUNB.js} +1 -1
  19. package/chunks/{chunk-PPHYLJSS.js → chunk-CAVZVZX6.js} +2 -2
  20. package/chunks/{chunk-VTPOO6GV.js → chunk-CSWBPY3P.js} +1 -1
  21. package/chunks/chunk-D6LBYOCX.js +19126 -0
  22. package/chunks/{chunk-NAID3ZWF.js → chunk-DMIMF3CG.js} +1 -1
  23. package/chunks/{chunk-2B7UBDY5.js → chunk-GGNTZ2NH.js} +90 -19
  24. package/chunks/chunk-HW5S7L73.js +379 -0
  25. package/chunks/{chunk-C3LHPHN2.js → chunk-JCR2WRXZ.js} +1227 -657
  26. package/chunks/{chunk-EDYSNFEM.js → chunk-L5E26RN6.js} +2 -2
  27. package/chunks/{chunk-CW44BRRA.js → chunk-MAY32HXD.js} +375 -0
  28. package/chunks/{chunk-7QXHXMC6.js → chunk-N6GSJHZ4.js} +96 -20
  29. package/chunks/{chunk-FZIUV27X.js → chunk-PVVL5Q3W.js} +31 -0
  30. package/chunks/{chunk-YHEAJFCI.js → chunk-USE2VQ5P.js} +3 -0
  31. package/chunks/{chunk-JYQUJ5DS.js → chunk-YJLGXDQJ.js} +1 -1
  32. package/chunks/{contextCommand-IGBCEXI4.js → contextCommand-XVRGKS3Q.js} +11 -13
  33. package/chunks/{cron-create-AVI3Q267.js → cron-create-IGYXQVG4.js} +27 -1
  34. package/chunks/{cron-delete-ZCEGDXXV.js → cron-delete-ETKIZCWT.js} +1 -1
  35. package/chunks/{cron-list-VN653OK5.js → cron-list-BVCUSWRU.js} +1 -1
  36. package/chunks/{de-MNR4SMAI.js → de-V4IE2OOZ.js} +3 -3
  37. package/chunks/{dist-RRYNPBOE.js → dist-4L54HRX2.js} +2 -2
  38. package/chunks/{dist-WP4AH3VK.js → dist-BXDUQ2QY.js} +1 -1
  39. package/chunks/{dist-M6GFCZ7S.js → dist-MN2PDDPR.js} +1 -1
  40. package/chunks/{edit-74Q4AFHQ.js → edit-3MLXHQPW.js} +22 -12
  41. package/chunks/{en-FIUWJSZR.js → en-HGJ2SPLM.js} +4 -3
  42. package/chunks/{enter-worktree-H72HXC7D.js → enter-worktree-OCA4SG6D.js} +35 -11
  43. package/chunks/{exit-worktree-FGIQO3S3.js → exit-worktree-6EDLXVEV.js} +35 -11
  44. package/chunks/{exitPlanMode-NBR2PK2D.js → exitPlanMode-H75KHRX4.js} +9 -11
  45. package/chunks/{fr-OFJFHLCR.js → fr-CJULI7ZX.js} +3 -3
  46. package/chunks/{geminiContentGenerator-33RP4WKD.js → geminiContentGenerator-E7Y6TCPU.js} +1 -1
  47. package/chunks/{glob-WEE3CJL6.js → glob-JFFSKARO.js} +9 -11
  48. package/chunks/{grep-DZKSBFZK.js → grep-7TAFR7MX.js} +9 -11
  49. package/chunks/{ja-V6OQ6VL7.js → ja-L7CHRQEW.js} +3 -3
  50. package/chunks/{ls-6F3VSP6S.js → ls-7HD6XG3V.js} +1 -1
  51. package/chunks/{lsp-67Y7DJN5.js → lsp-ZZSFCIWD.js} +1 -1
  52. package/chunks/{monitor-EDZWEZVS.js → monitor-YX2ABLXH.js} +21 -11
  53. package/chunks/notebook-edit-EEJEGFZR.js +756 -0
  54. package/chunks/{openaiContentGenerator-5NQG3W64.js → openaiContentGenerator-BSAWHGQJ.js} +9 -8
  55. package/chunks/{pt-ZLE6SA4A.js → pt-M6JULLEQ.js} +3 -3
  56. package/chunks/{qwenContentGenerator-4DPUUS6R.js → qwenContentGenerator-47XRHQXM.js} +11 -13
  57. package/chunks/{qwenOAuth2-JE7H47TE.js → qwenOAuth2-EEJGROP7.js} +7 -1
  58. package/chunks/{read-file-CQOF7BQ2.js → read-file-O53WD46Y.js} +4 -5
  59. package/chunks/{ripGrep-KR5LKGTI.js → ripGrep-OXNZ5Z3T.js} +9 -11
  60. package/chunks/{ru-A4OHIUNN.js → ru-QILM4HBC.js} +3 -3
  61. package/chunks/{send-message-GB4AQZNC.js → send-message-ULK4MQXJ.js} +22 -1
  62. package/chunks/{serve-GAD2PEST.js → serve-H2REZAYD.js} +13728 -3026
  63. package/chunks/{shell-E2HMCBGR.js → shell-DET66JID.js} +9 -11
  64. package/chunks/{skill-KDZH6UZ6.js → skill-ZIXPX3L3.js} +19 -6
  65. package/chunks/{src-LY4RU5AI.js → src-PN3XGQYP.js} +205 -13
  66. package/chunks/{syntheticOutput-HFL3DE7R.js → syntheticOutput-IS2X5OZ2.js} +2 -2
  67. package/chunks/{task-stop-ZQF26RXS.js → task-stop-7QSJGSSP.js} +1 -1
  68. package/chunks/{todoWrite-U4SC643O.js → todoWrite-7CVACFUX.js} +2 -2
  69. package/chunks/{tool-search-U4XQVLFU.js → tool-search-GTYLSGZ3.js} +4 -5
  70. package/chunks/{web-fetch-BRWZ4WSE.js → web-fetch-ENQ2I5JA.js} +5 -2
  71. package/chunks/{write-file-NBLRMNGB.js → write-file-NILNEZCR.js} +19 -12
  72. package/chunks/{zh-V32QONGV.js → zh-PWL2NKY3.js} +4 -3
  73. package/chunks/{zh-TW-552S24LR.js → zh-TW-S3YGWICZ.js} +4 -3
  74. package/cli.js +14832 -49049
  75. package/locales/ca.js +4 -5
  76. package/locales/de.js +4 -5
  77. package/locales/en.js +6 -5
  78. package/locales/fr.js +4 -5
  79. package/locales/ja.js +4 -5
  80. package/locales/pt.js +4 -5
  81. package/locales/ru.js +4 -5
  82. package/locales/zh-TW.js +5 -4
  83. package/locales/zh.js +5 -4
  84. package/package.json +2 -2
  85. package/chunks/chunk-3MBY4GKN.js +0 -350
  86. package/chunks/chunk-5P5XGNYH.js +0 -93
  87. package/chunks/chunk-JHMX4QTD.js +0 -2306
  88. package/chunks/chunk-SYCJMSIJ.js +0 -82
  89. package/chunks/chunk-Y6Z2O3WR.js +0 -33
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  TextTokenizer,
5
5
  isSupportedImageMimeType
6
- } from "./chunk-VTPOO6GV.js";
6
+ } from "./chunk-CSWBPY3P.js";
7
7
  import {
8
8
  createDebugLogger
9
9
  } from "./chunk-XP27SJMH.js";
@@ -1202,6 +1202,23 @@ var CredentialsClearRequiredError = class extends Error {
1202
1202
  __name(this, "CredentialsClearRequiredError");
1203
1203
  }
1204
1204
  };
1205
+ var QwenOAuthPollError = class extends Error {
1206
+ static {
1207
+ __name(this, "QwenOAuthPollError");
1208
+ }
1209
+ status;
1210
+ oauthError;
1211
+ description;
1212
+ constructor(opts) {
1213
+ super(
1214
+ `Device token poll failed: ${opts.oauthError ?? "Unknown error"} - ${opts.description ?? "(no description)"}`
1215
+ );
1216
+ this.name = "QwenOAuthPollError";
1217
+ this.oauthError = opts.oauthError;
1218
+ this.description = opts.description;
1219
+ this.status = opts.status;
1220
+ }
1221
+ };
1205
1222
  function isDeviceAuthorizationSuccess(response) {
1206
1223
  return "device_code" in response;
1207
1224
  }
@@ -1245,7 +1262,7 @@ var QwenOAuth2Client = class {
1245
1262
  return { token: void 0 };
1246
1263
  }
1247
1264
  }
1248
- async requestDeviceAuthorization(options) {
1265
+ async requestDeviceAuthorization(options, fetchOpts) {
1249
1266
  const bodyData = {
1250
1267
  client_id: QWEN_OAUTH_CLIENT_ID,
1251
1268
  scope: options.scope,
@@ -1259,7 +1276,13 @@ var QwenOAuth2Client = class {
1259
1276
  Accept: "application/json",
1260
1277
  "x-request-id": randomUUID2()
1261
1278
  },
1262
- body: objectToUrlEncoded(bodyData)
1279
+ body: objectToUrlEncoded(bodyData),
1280
+ // PR #4255 — daemon device-flow registry passes its
1281
+ // `cancelController.signal` so dispose / cancel during a slow
1282
+ // device-authorization request actually aborts the in-flight
1283
+ // socket immediately. Pre-existing CLI callers omit it; the
1284
+ // optional shape preserves backward compatibility.
1285
+ ...fetchOpts?.signal ? { signal: fetchOpts.signal } : {}
1263
1286
  });
1264
1287
  if (!response.ok) {
1265
1288
  const errorData = await response.text();
@@ -1268,7 +1291,18 @@ var QwenOAuth2Client = class {
1268
1291
  );
1269
1292
  }
1270
1293
  const result = await response.json();
1271
- debugLogger2.debug("Device authorization result:", result);
1294
+ if (isDeviceAuthorizationSuccess(result)) {
1295
+ debugLogger2.debug("Device authorization result (sanitized):", {
1296
+ ok: true,
1297
+ expires_in: result.expires_in
1298
+ });
1299
+ } else {
1300
+ const errorData = result;
1301
+ debugLogger2.debug("Device authorization result (sanitized):", {
1302
+ ok: false,
1303
+ error: errorData?.error
1304
+ });
1305
+ }
1272
1306
  if (!isDeviceAuthorizationSuccess(result)) {
1273
1307
  const errorData = result;
1274
1308
  throw new Error(
@@ -1277,7 +1311,7 @@ var QwenOAuth2Client = class {
1277
1311
  }
1278
1312
  return result;
1279
1313
  }
1280
- async pollDeviceToken(options) {
1314
+ async pollDeviceToken(options, fetchOpts) {
1281
1315
  const bodyData = {
1282
1316
  grant_type: QWEN_OAUTH_GRANT_TYPE,
1283
1317
  client_id: QWEN_OAUTH_CLIENT_ID,
@@ -1290,7 +1324,12 @@ var QwenOAuth2Client = class {
1290
1324
  "Content-Type": "application/x-www-form-urlencoded",
1291
1325
  Accept: "application/json"
1292
1326
  },
1293
- body: objectToUrlEncoded(bodyData)
1327
+ body: objectToUrlEncoded(bodyData),
1328
+ // PR #4255 — daemon device-flow registry passes its per-entry
1329
+ // `cancelController.signal` so cancel() / dispose() during a
1330
+ // slow IdP response actually aborts the in-flight socket
1331
+ // instead of waiting for the upstream timeout.
1332
+ ...fetchOpts?.signal ? { signal: fetchOpts.signal } : {}
1294
1333
  });
1295
1334
  if (!response.ok) {
1296
1335
  const responseText = await response.text();
@@ -1298,11 +1337,11 @@ var QwenOAuth2Client = class {
1298
1337
  try {
1299
1338
  errorData = JSON.parse(responseText);
1300
1339
  } catch (_parseError) {
1301
- const error2 = new Error(
1340
+ const error = new Error(
1302
1341
  `Device token poll failed: ${response.status} ${response.statusText}. Response: ${responseText}`
1303
1342
  );
1304
- error2.status = response.status;
1305
- throw error2;
1343
+ error.status = response.status;
1344
+ throw error;
1306
1345
  }
1307
1346
  if (response.status === 400 && errorData.error === "authorization_pending") {
1308
1347
  return { status: "pending" };
@@ -1313,11 +1352,11 @@ var QwenOAuth2Client = class {
1313
1352
  slowDown: true
1314
1353
  };
1315
1354
  }
1316
- const error = new Error(
1317
- `Device token poll failed: ${errorData.error || "Unknown error"} - ${errorData.error_description}`
1318
- );
1319
- error.status = response.status;
1320
- throw error;
1355
+ throw new QwenOAuthPollError({
1356
+ oauthError: errorData.error,
1357
+ description: errorData.error_description,
1358
+ status: response.status
1359
+ });
1321
1360
  }
1322
1361
  return await response.json();
1323
1362
  }
@@ -1608,10 +1647,6 @@ async function authWithQwenDeviceFlow(client, config) {
1608
1647
  };
1609
1648
  client.setCredentials(credentials);
1610
1649
  await cacheQwenCredentials(credentials);
1611
- try {
1612
- SharedTokenManager.getInstance().clearCache();
1613
- } catch {
1614
- }
1615
1650
  emitAuthProgress(
1616
1651
  "success",
1617
1652
  "Authentication successful! Access token obtained."
@@ -1712,12 +1747,45 @@ Server requested to slow down, increasing poll interval to ${pollInterval}ms'`
1712
1747
  }
1713
1748
  }
1714
1749
  __name(authWithQwenDeviceFlow, "authWithQwenDeviceFlow");
1715
- async function cacheQwenCredentials(credentials) {
1750
+ var QWEN_CREDENTIAL_FILE_MODE = 384;
1751
+ async function cacheQwenCredentials(credentials, opts) {
1716
1752
  const filePath = getQwenCachedCredentialPath();
1717
1753
  try {
1718
1754
  await fs7.mkdir(path3.dirname(filePath), { recursive: true });
1719
1755
  const credString = JSON.stringify(credentials, null, 2);
1720
- await fs7.writeFile(filePath, credString);
1756
+ const tempPath = `${filePath}.tmp.${process.pid}.${randomUUID2()}`;
1757
+ try {
1758
+ await fs7.writeFile(tempPath, credString, {
1759
+ mode: QWEN_CREDENTIAL_FILE_MODE,
1760
+ ...opts?.signal ? { signal: opts.signal } : {}
1761
+ });
1762
+ try {
1763
+ await fs7.chmod(tempPath, QWEN_CREDENTIAL_FILE_MODE);
1764
+ } catch (chmodErr) {
1765
+ if (process.platform !== "win32") {
1766
+ throw new Error(
1767
+ `cacheQwenCredentials: refusing to publish credentials \u2014 chmod 0o${QWEN_CREDENTIAL_FILE_MODE.toString(8)} on temp file failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}`
1768
+ );
1769
+ }
1770
+ debugLogger2.warn(
1771
+ `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)}`
1772
+ );
1773
+ }
1774
+ await fs7.rename(tempPath, filePath);
1775
+ } catch (writeErr) {
1776
+ try {
1777
+ await fs7.unlink(tempPath);
1778
+ } catch {
1779
+ }
1780
+ throw writeErr;
1781
+ }
1782
+ try {
1783
+ SharedTokenManager.getInstance().clearCache();
1784
+ } catch (clearErr) {
1785
+ debugLogger2.warn(
1786
+ `cacheQwenCredentials: SharedTokenManager.clearCache failed; in-process callers may serve stale credentials until the next mtime poll: ${clearErr instanceof Error ? clearErr.message : String(clearErr)}`
1787
+ );
1788
+ }
1721
1789
  } catch (error) {
1722
1790
  const errorMessage = error instanceof Error ? error.message : String(error);
1723
1791
  const errorCode = error instanceof Error && "code" in error ? error.code : void 0;
@@ -1766,6 +1834,7 @@ export {
1766
1834
  generateCodeChallenge,
1767
1835
  generatePKCEPair,
1768
1836
  CredentialsClearRequiredError,
1837
+ QwenOAuthPollError,
1769
1838
  isDeviceAuthorizationSuccess,
1770
1839
  isDeviceTokenSuccess,
1771
1840
  isDeviceTokenPending,
@@ -1774,6 +1843,8 @@ export {
1774
1843
  QwenOAuth2Event,
1775
1844
  qwenOAuth2Events,
1776
1845
  getQwenOAuthClient,
1846
+ QWEN_CREDENTIAL_FILE_MODE,
1847
+ cacheQwenCredentials,
1777
1848
  clearQwenCredentials,
1778
1849
  clearCachedCredentialFile
1779
1850
  };
@@ -0,0 +1,379 @@
1
+ // Force strict mode and setup for ESM
2
+ "use strict";
3
+ import {
4
+ resolveBundleDir
5
+ } from "./chunk-BAZDG3QU.js";
6
+ import {
7
+ Storage
8
+ } from "./chunk-XP27SJMH.js";
9
+ import {
10
+ init_esbuild_shims
11
+ } from "./chunk-A4BMJM77.js";
12
+ import {
13
+ __glob,
14
+ __name
15
+ } from "./chunk-J2S4EL5Y.js";
16
+
17
+ // packages/cli/src/utils/stdioHelpers.ts
18
+ init_esbuild_shims();
19
+ var writeStdoutLine = /* @__PURE__ */ __name((message) => {
20
+ process.stdout.write(message.endsWith("\n") ? message : `${message}
21
+ `);
22
+ }, "writeStdoutLine");
23
+ var writeStderrLine = /* @__PURE__ */ __name((message) => {
24
+ process.stderr.write(message.endsWith("\n") ? message : `${message}
25
+ `);
26
+ }, "writeStderrLine");
27
+ var clearScreen = /* @__PURE__ */ __name(() => {
28
+ console.clear();
29
+ }, "clearScreen");
30
+
31
+ // packages/cli/src/i18n/index.ts
32
+ init_esbuild_shims();
33
+ import * as fs from "node:fs";
34
+ import * as path from "node:path";
35
+ import { pathToFileURL } from "node:url";
36
+
37
+ // packages/cli/src/i18n/languages.ts
38
+ init_esbuild_shims();
39
+ var SUPPORTED_LANGUAGES = [
40
+ {
41
+ code: "en",
42
+ id: "en-US",
43
+ fullName: "English",
44
+ nativeName: "English"
45
+ },
46
+ {
47
+ code: "zh-TW",
48
+ id: "zh-TW",
49
+ fullName: "Traditional Chinese",
50
+ nativeName: "\u7E41\u9AD4\u4E2D\u6587",
51
+ strictParity: true
52
+ },
53
+ {
54
+ code: "zh",
55
+ id: "zh-CN",
56
+ fullName: "Chinese",
57
+ nativeName: "\u4E2D\u6587",
58
+ strictParity: true
59
+ },
60
+ {
61
+ code: "ru",
62
+ id: "ru-RU",
63
+ fullName: "Russian",
64
+ nativeName: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439"
65
+ },
66
+ {
67
+ code: "de",
68
+ id: "de-DE",
69
+ fullName: "German",
70
+ nativeName: "Deutsch"
71
+ },
72
+ {
73
+ code: "ja",
74
+ id: "ja-JP",
75
+ fullName: "Japanese",
76
+ nativeName: "\u65E5\u672C\u8A9E"
77
+ },
78
+ {
79
+ code: "pt",
80
+ id: "pt-BR",
81
+ fullName: "Portuguese",
82
+ nativeName: "Portugu\xEAs"
83
+ },
84
+ {
85
+ code: "fr",
86
+ id: "fr-FR",
87
+ fullName: "French",
88
+ nativeName: "Fran\xE7ais"
89
+ },
90
+ {
91
+ code: "ca",
92
+ id: "ca-ES",
93
+ fullName: "Catalan",
94
+ nativeName: "Catal\xE0"
95
+ }
96
+ ];
97
+ function normalizeLanguageCandidate(input) {
98
+ return input.trim().replace(/_/g, "-").toLowerCase();
99
+ }
100
+ __name(normalizeLanguageCandidate, "normalizeLanguageCandidate");
101
+ function matchesLocaleToken(candidate, token) {
102
+ return candidate === token || candidate.startsWith(`${token}-`) || candidate.startsWith(`${token}.`) || candidate.startsWith(`${token}@`);
103
+ }
104
+ __name(matchesLocaleToken, "matchesLocaleToken");
105
+ function getMatchedLocaleTokenLength(candidate, language) {
106
+ const code = language.code.toLowerCase();
107
+ const id = language.id.toLowerCase();
108
+ if (matchesLocaleToken(candidate, id)) {
109
+ return id.length;
110
+ }
111
+ if (matchesLocaleToken(candidate, code)) {
112
+ return code.length;
113
+ }
114
+ return void 0;
115
+ }
116
+ __name(getMatchedLocaleTokenLength, "getMatchedLocaleTokenLength");
117
+ function resolveSupportedLanguage(input) {
118
+ const normalized = normalizeLanguageCandidate(input);
119
+ if (!normalized) {
120
+ return void 0;
121
+ }
122
+ let bestMatch;
123
+ for (const language of SUPPORTED_LANGUAGES) {
124
+ if (normalized === language.fullName.toLowerCase() || language.nativeName && normalized === language.nativeName.toLowerCase()) {
125
+ return language.code;
126
+ }
127
+ const tokenLength = getMatchedLocaleTokenLength(normalized, language);
128
+ if (tokenLength !== void 0 && (!bestMatch || tokenLength > bestMatch.tokenLength)) {
129
+ bestMatch = { code: language.code, tokenLength };
130
+ }
131
+ }
132
+ return bestMatch?.code;
133
+ }
134
+ __name(resolveSupportedLanguage, "resolveSupportedLanguage");
135
+ function getLanguageNameFromLocale(locale) {
136
+ const resolved = resolveSupportedLanguage(locale);
137
+ const lang = resolved ? SUPPORTED_LANGUAGES.find((language) => language.code === resolved) : void 0;
138
+ return lang?.fullName || "English";
139
+ }
140
+ __name(getLanguageNameFromLocale, "getLanguageNameFromLocale");
141
+ function getLanguageSettingsOptions() {
142
+ return [
143
+ { value: "auto", label: "Auto (detect from system)" },
144
+ ...SUPPORTED_LANGUAGES.map((l) => ({
145
+ value: l.code,
146
+ label: l.nativeName ? `${l.nativeName} (${l.fullName})` : `${l.fullName} (${l.id})`
147
+ }))
148
+ ];
149
+ }
150
+ __name(getLanguageSettingsOptions, "getLanguageSettingsOptions");
151
+ function getSupportedLanguageIds(separator = "|") {
152
+ return SUPPORTED_LANGUAGES.map((l) => l.id).join(separator);
153
+ }
154
+ __name(getSupportedLanguageIds, "getSupportedLanguageIds");
155
+
156
+ // packages/cli/src/i18n/translationDict.ts
157
+ init_esbuild_shims();
158
+ function getTranslationModuleExport(module) {
159
+ return Object.prototype.hasOwnProperty.call(module, "default") ? module["default"] : module;
160
+ }
161
+ __name(getTranslationModuleExport, "getTranslationModuleExport");
162
+ function isTranslationDict(value) {
163
+ return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length > 0;
164
+ }
165
+ __name(isTranslationDict, "isTranslationDict");
166
+
167
+ // packages/cli/src/i18n/mustTranslateKeys.ts
168
+ init_esbuild_shims();
169
+
170
+ // import("./locales/**/*.js") in packages/cli/src/i18n/index.ts
171
+ var globImport_locales_js = __glob({
172
+ "./locales/ca.js": () => import("./ca-UZ7BANMN.js"),
173
+ "./locales/de.js": () => import("./de-V4IE2OOZ.js"),
174
+ "./locales/en.js": () => import("./en-HGJ2SPLM.js"),
175
+ "./locales/fr.js": () => import("./fr-CJULI7ZX.js"),
176
+ "./locales/ja.js": () => import("./ja-L7CHRQEW.js"),
177
+ "./locales/pt.js": () => import("./pt-M6JULLEQ.js"),
178
+ "./locales/ru.js": () => import("./ru-QILM4HBC.js"),
179
+ "./locales/zh-TW.js": () => import("./zh-TW-S3YGWICZ.js"),
180
+ "./locales/zh.js": () => import("./zh-PWL2NKY3.js")
181
+ });
182
+
183
+ // packages/cli/src/i18n/index.ts
184
+ var currentLanguage = "en";
185
+ var translations = {};
186
+ var translationCache = {};
187
+ var loadingPromises = {};
188
+ var getBuiltinLocalesDir = /* @__PURE__ */ __name(() => path.join(resolveBundleDir(import.meta.url), "locales"), "getBuiltinLocalesDir");
189
+ var getUserLocalesDir = /* @__PURE__ */ __name(() => path.join(Storage.getGlobalQwenDir(), "locales"), "getUserLocalesDir");
190
+ var getLocalePath = /* @__PURE__ */ __name((lang, useUserDir = false) => {
191
+ const baseDir = useUserDir ? getUserLocalesDir() : getBuiltinLocalesDir();
192
+ return path.join(baseDir, `${lang}.js`);
193
+ }, "getLocalePath");
194
+ function detectSystemLanguage() {
195
+ const envLang = process.env["QWEN_CODE_LANG"] || process.env["LANG"];
196
+ if (envLang) {
197
+ const resolved = resolveSupportedLanguage(envLang);
198
+ if (resolved) {
199
+ return resolved;
200
+ }
201
+ }
202
+ try {
203
+ const locale = Intl.DateTimeFormat().resolvedOptions().locale;
204
+ const resolved = resolveSupportedLanguage(locale);
205
+ if (resolved) {
206
+ return resolved;
207
+ }
208
+ } catch {
209
+ }
210
+ return "en";
211
+ }
212
+ __name(detectSystemLanguage, "detectSystemLanguage");
213
+ async function tryImportTranslations(moduleSpecifier) {
214
+ try {
215
+ const module = await import(moduleSpecifier);
216
+ const result = getTranslationModuleExport(module);
217
+ if (isTranslationDict(result)) {
218
+ return { translations: result };
219
+ }
220
+ return {
221
+ error: new Error("Module loaded but result is empty or invalid")
222
+ };
223
+ } catch (error) {
224
+ return {
225
+ error: error instanceof Error ? error : new Error(String(error))
226
+ };
227
+ }
228
+ }
229
+ __name(tryImportTranslations, "tryImportTranslations");
230
+ async function tryImportBundledTranslations(lang) {
231
+ try {
232
+ const module = await globImport_locales_js(`./locales/${lang}.js`);
233
+ const result = getTranslationModuleExport(module);
234
+ if (isTranslationDict(result)) {
235
+ return { translations: result };
236
+ }
237
+ return {
238
+ error: new Error("Module loaded but result is empty or invalid")
239
+ };
240
+ } catch (error) {
241
+ return {
242
+ error: error instanceof Error ? error : new Error(String(error))
243
+ };
244
+ }
245
+ }
246
+ __name(tryImportBundledTranslations, "tryImportBundledTranslations");
247
+ async function loadTranslationsAsync(lang) {
248
+ if (translationCache[lang]) {
249
+ return translationCache[lang];
250
+ }
251
+ const existingPromise = loadingPromises[lang];
252
+ if (existingPromise) {
253
+ return existingPromise;
254
+ }
255
+ const loadPromise = (async () => {
256
+ const userJsPath = getLocalePath(lang, true);
257
+ if (fs.existsSync(getUserLocalesDir()) && fs.existsSync(userJsPath)) {
258
+ const userResult = await tryImportTranslations(
259
+ pathToFileURL(userJsPath).href
260
+ );
261
+ if (userResult.translations) {
262
+ translationCache[lang] = userResult.translations;
263
+ return userResult.translations;
264
+ }
265
+ writeStderrLine(
266
+ `Failed to load translations from user directory for ${lang}: ${userResult.error.message}`
267
+ );
268
+ }
269
+ const builtinJsPath = getLocalePath(lang, false);
270
+ const builtinModuleSpecifiers = [];
271
+ if (fs.existsSync(getBuiltinLocalesDir()) && fs.existsSync(builtinJsPath)) {
272
+ builtinModuleSpecifiers.push(pathToFileURL(builtinJsPath).href);
273
+ }
274
+ let lastBuiltinError;
275
+ for (const moduleSpecifier of builtinModuleSpecifiers) {
276
+ const builtinResult = await tryImportTranslations(moduleSpecifier);
277
+ if (builtinResult.translations) {
278
+ translationCache[lang] = builtinResult.translations;
279
+ return builtinResult.translations;
280
+ }
281
+ lastBuiltinError = builtinResult.error;
282
+ }
283
+ const bundledBuiltinResult = await tryImportBundledTranslations(lang);
284
+ if (bundledBuiltinResult.translations) {
285
+ translationCache[lang] = bundledBuiltinResult.translations;
286
+ return bundledBuiltinResult.translations;
287
+ }
288
+ lastBuiltinError = bundledBuiltinResult.error;
289
+ if (lastBuiltinError) {
290
+ writeStderrLine(
291
+ `Failed to load JS translations for ${lang}: ${lastBuiltinError.message}`
292
+ );
293
+ }
294
+ translationCache[lang] = {};
295
+ return {};
296
+ })();
297
+ loadingPromises[lang] = loadPromise;
298
+ loadPromise.finally(() => {
299
+ delete loadingPromises[lang];
300
+ });
301
+ return loadPromise;
302
+ }
303
+ __name(loadTranslationsAsync, "loadTranslationsAsync");
304
+ function interpolate(template, params) {
305
+ if (!params) return template;
306
+ return template.replace(
307
+ /\{\{(\w+)\}\}/g,
308
+ (match, key) => params[key] ?? match
309
+ );
310
+ }
311
+ __name(interpolate, "interpolate");
312
+ function resolveLanguage(lang) {
313
+ if (lang === "auto") {
314
+ return detectSystemLanguage();
315
+ }
316
+ return resolveSupportedLanguage(lang) ?? lang;
317
+ }
318
+ __name(resolveLanguage, "resolveLanguage");
319
+ async function setLanguageAsync(lang) {
320
+ currentLanguage = resolveLanguage(lang);
321
+ translations = await loadTranslationsAsync(currentLanguage);
322
+ }
323
+ __name(setLanguageAsync, "setLanguageAsync");
324
+ function getCurrentLanguage() {
325
+ return currentLanguage;
326
+ }
327
+ __name(getCurrentLanguage, "getCurrentLanguage");
328
+ function t(key, params) {
329
+ const translation = translations[key] ?? key;
330
+ if (Array.isArray(translation)) {
331
+ return key;
332
+ }
333
+ return interpolate(translation, params);
334
+ }
335
+ __name(t, "t");
336
+ function ta(key) {
337
+ const translation = translations[key];
338
+ if (Array.isArray(translation)) {
339
+ return translation;
340
+ }
341
+ return [];
342
+ }
343
+ __name(ta, "ta");
344
+ async function initializeI18n(lang) {
345
+ await setLanguageAsync(lang ?? "auto");
346
+ }
347
+ __name(initializeI18n, "initializeI18n");
348
+
349
+ export {
350
+ writeStdoutLine,
351
+ writeStderrLine,
352
+ clearScreen,
353
+ SUPPORTED_LANGUAGES,
354
+ resolveSupportedLanguage,
355
+ getLanguageNameFromLocale,
356
+ getLanguageSettingsOptions,
357
+ getSupportedLanguageIds,
358
+ detectSystemLanguage,
359
+ setLanguageAsync,
360
+ getCurrentLanguage,
361
+ t,
362
+ ta,
363
+ initializeI18n
364
+ };
365
+ /**
366
+ * @license
367
+ * Copyright 2025 Qwen Team
368
+ * SPDX-License-Identifier: Apache-2.0
369
+ */
370
+ /**
371
+ * @license
372
+ * Copyright 2025 Qwen team
373
+ * SPDX-License-Identifier: Apache-2.0
374
+ */
375
+ /**
376
+ * @license
377
+ * Copyright 2026 Qwen Team
378
+ * SPDX-License-Identifier: Apache-2.0
379
+ */