@qwen-code/qwen-code 0.19.2 → 0.19.3-nightly.20260630.e00fe6a27

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 (286) hide show
  1. package/bundled/extension-creator/SKILL.md +357 -0
  2. package/bundled/loop/SKILL.md +21 -7
  3. package/bundled/loop/SKILL.test.ts +41 -0
  4. package/bundled/loop/loop-task-file.test.ts +1064 -0
  5. package/bundled/loop/loop-task-file.ts +404 -0
  6. package/bundled/loop/loop-tick-resolver.test.ts +665 -0
  7. package/bundled/loop/loop-tick-resolver.ts +347 -0
  8. package/bundled/qc-helper/SKILL.md +26 -19
  9. package/bundled/qc-helper/docs/configuration/auth.md +11 -11
  10. package/bundled/qc-helper/docs/configuration/model-providers.md +13 -13
  11. package/bundled/qc-helper/docs/configuration/settings.md +76 -75
  12. package/bundled/qc-helper/docs/features/channels/plugins.md +1 -1
  13. package/bundled/qc-helper/docs/features/commands.md +108 -77
  14. package/bundled/qc-helper/docs/features/hooks.md +6 -1
  15. package/bundled/qc-helper/docs/features/memory.md +52 -0
  16. package/bundled/qc-helper/docs/qwen-serve.md +24 -2
  17. package/bundled/qc-helper/docs/support/tos-privacy.md +16 -3
  18. package/bundled/qc-helper/docs/support/troubleshooting.md +6 -0
  19. package/chunks/{MaxSizedBox-7RERNLFK.js → MaxSizedBox-T5X5MN5Q.js} +29 -27
  20. package/chunks/{StandaloneSessionPicker-S22XBSN6.js → StandaloneSessionPicker-P3E3WTOQ.js} +42 -37
  21. package/chunks/{acpAgent-4MCETHF2.js → acpAgent-QEP6DXFW.js} +864 -175
  22. package/chunks/{agent-K3ENVYSB.js → agent-UDANDUF7.js} +24 -23
  23. package/chunks/{agent-headless-HO3V3A3A.js → agent-headless-KYVSZHSO.js} +24 -23
  24. package/chunks/{anthropicContentGenerator-E3TQ5XJJ.js → anthropicContentGenerator-KWSJAQ7B.js} +33 -12
  25. package/chunks/{artifact-tool-QA4KRO3B.js → artifact-tool-D2X7G3C3.js} +2 -2
  26. package/chunks/{askUserQuestion-HMWXW6VN.js → askUserQuestion-UGETICJQ.js} +2 -2
  27. package/chunks/{bridge-4LV2HBH2.js → bridge-X42LXPTA.js} +31 -30
  28. package/chunks/{ca-7WC7ELX6.js → ca-IUFWESZL.js} +1 -0
  29. package/chunks/{chunk-JXQ23SNT.js → chunk-2JKEQWDZ.js} +623 -78
  30. package/chunks/{chunk-2TJ3YN6Q.js → chunk-2RJA6J57.js} +416 -401
  31. package/chunks/{chunk-3UALQ56H.js → chunk-3227DZO4.js} +1 -1
  32. package/chunks/{chunk-BGUDAULQ.js → chunk-3CPCDXFR.js} +5 -5
  33. package/chunks/{chunk-5RVSM6NW.js → chunk-3HUHAQF3.js} +1 -1
  34. package/chunks/{chunk-D5E5TMYH.js → chunk-3M4W4U5G.js} +16 -2
  35. package/chunks/{chunk-DBZUXSSV.js → chunk-4X7NIEQJ.js} +3 -3
  36. package/chunks/chunk-5GOVVXEV.js +73 -0
  37. package/chunks/{chunk-2BAQ3ACS.js → chunk-5SM4VT6V.js} +405 -5
  38. package/chunks/{chunk-NYOHZYHM.js → chunk-5XQ4A26L.js} +45 -3
  39. package/chunks/{chunk-CI5O6SQL.js → chunk-6FKEVYCD.js} +4 -4
  40. package/chunks/{chunk-ZD3NW5KL.js → chunk-7LM4XHPE.js} +63 -9
  41. package/chunks/chunk-7UNP2XM7.js +840 -0
  42. package/chunks/{chunk-OQHQHJRK.js → chunk-ARYCHZ4B.js} +151 -4775
  43. package/chunks/chunk-BC3C4F3Q.js +40 -0
  44. package/chunks/{chunk-CGEGHF2C.js → chunk-BKXBARJZ.js} +1 -1
  45. package/chunks/chunk-BMFMJINR.js +45 -0
  46. package/chunks/chunk-BOJWHRMX.js +11273 -0
  47. package/chunks/{chunk-CGOMICBE.js → chunk-BSZEQNUA.js} +34 -1
  48. package/chunks/{chunk-OIC6S73E.js → chunk-BUUQ5HPX.js} +1 -1
  49. package/chunks/{chunk-2BIF2NVV.js → chunk-BVSVIN45.js} +2 -2
  50. package/chunks/{chunk-TOEGRAVX.js → chunk-BX5YO7UW.js} +17 -5
  51. package/chunks/{chunk-4W4T77MO.js → chunk-BXVWV4GI.js} +109 -6
  52. package/chunks/{chunk-VQRYPFCV.js → chunk-CYHVPQYT.js} +10 -460
  53. package/chunks/{chunk-PRYMDRBV.js → chunk-DDMOU62Q.js} +1 -1
  54. package/chunks/{chunk-S566HKUS.js → chunk-DHXWNSJA.js} +15 -1
  55. package/chunks/{chunk-F6XNTYNE.js → chunk-E6XQPQXW.js} +30 -307
  56. package/chunks/{chunk-QBZ22PQX.js → chunk-EWALXUAD.js} +3 -1
  57. package/chunks/{chunk-EL5IHQON.js → chunk-EWYQFWYF.js} +6 -27
  58. package/chunks/{chunk-HG6YKEBI.js → chunk-F2DOT6UZ.js} +161 -30
  59. package/chunks/{chunk-JTYRZODB.js → chunk-FOOIZCWL.js} +16 -7
  60. package/chunks/{chunk-EX4W6ZYG.js → chunk-G5G4TFZ7.js} +1 -1
  61. package/chunks/{chunk-EW6C27XX.js → chunk-GEHVIWAT.js} +9 -3
  62. package/chunks/chunk-HEVBZSXG.js +4923 -0
  63. package/chunks/chunk-HFQ2XSE7.js +690 -0
  64. package/chunks/{chunk-PF523XJX.js → chunk-HPGTGMP3.js} +1 -1
  65. package/chunks/{chunk-OTBK43JR.js → chunk-HYCC3XM3.js} +1 -1
  66. package/chunks/{chunk-TMBPDHXD.js → chunk-I4H7PRWQ.js} +1 -1
  67. package/chunks/{chunk-EEEZIVFJ.js → chunk-JOLIREYR.js} +1 -1
  68. package/chunks/{chunk-TZM5JIAX.js → chunk-JYPQTRA3.js} +10 -7
  69. package/chunks/chunk-K5XU6E4T.js +167 -0
  70. package/chunks/{chunk-BS64PXY3.js → chunk-KFVU7ODN.js} +1 -1
  71. package/chunks/{chunk-3RJ3ZPPR.js → chunk-KKQWC6WS.js} +7 -7
  72. package/chunks/{chunk-3QFE4OTE.js → chunk-LBW7NW7X.js} +4 -4
  73. package/chunks/{chunk-Z7XXFPGP.js → chunk-LDWTYE33.js} +1 -1
  74. package/chunks/{chunk-EXMX5YHG.js → chunk-LP5E4YIH.js} +1 -1
  75. package/chunks/{chunk-ZUAXI2OA.js → chunk-M2U5NM24.js} +188 -11366
  76. package/chunks/{chunk-I5T6PIBQ.js → chunk-MBV2CTRL.js} +1010 -925
  77. package/chunks/{chunk-5JZLXFPD.js → chunk-MTHMXSNT.js} +11 -11
  78. package/chunks/{chunk-FPACXT7T.js → chunk-MTJVHQDP.js} +534 -164
  79. package/chunks/chunk-NDOC6M5S.js +481 -0
  80. package/chunks/{chunk-HGNSRCRB.js → chunk-NL4C3H6C.js} +1 -1
  81. package/chunks/{chunk-GZCJS5WH.js → chunk-O2VBQ3Y2.js} +2 -2
  82. package/chunks/{chunk-UN3C6GOR.js → chunk-PPFWEV7G.js} +10 -108
  83. package/chunks/{chunk-RS4HRC75.js → chunk-QI2CFVRF.js} +85 -8
  84. package/chunks/{chunk-XU5P23GN.js → chunk-QLDPRILK.js} +3 -3
  85. package/chunks/chunk-QYUE6W3T.js +123 -0
  86. package/chunks/{chunk-USGMPVOY.js → chunk-R3LHDWF2.js} +21 -12
  87. package/chunks/{chunk-BNXANYLH.js → chunk-RD6YJJJ6.js} +81 -1
  88. package/chunks/{chunk-PXFFKNCO.js → chunk-RIP623NO.js} +4877 -2469
  89. package/chunks/{chunk-XKBP7M7A.js → chunk-RYBSUGOR.js} +142 -30
  90. package/chunks/{chunk-BG4BIP7F.js → chunk-SBBN4BWR.js} +4 -2
  91. package/chunks/{chunk-T2VDEFUU.js → chunk-SKQZZVAV.js} +2 -2
  92. package/chunks/{chunk-5R4SBCX6.js → chunk-SL5MOGQH.js} +3 -3
  93. package/chunks/chunk-SMXULRAN.js +37 -0
  94. package/chunks/{chunk-WA5OJGFL.js → chunk-SS6WJMQK.js} +363 -76
  95. package/chunks/{chunk-UAARVVBI.js → chunk-TNWFHGN6.js} +1 -1
  96. package/chunks/{chunk-I2RFAW6Q.js → chunk-TT6Q3EN4.js} +7 -5
  97. package/chunks/chunk-UAKXW3DN.js +30 -0
  98. package/chunks/{chunk-C4K3FEQ2.js → chunk-UX4SGCGN.js} +32 -3
  99. package/chunks/{chunk-J6AW7O5D.js → chunk-WHDQZHRU.js} +2 -2
  100. package/chunks/{chunk-WGAEWQTF.js → chunk-WN6K47NR.js} +1 -2
  101. package/chunks/{chunk-UAARJR2G.js → chunk-WQT5SOI6.js} +2 -2
  102. package/chunks/{chunk-VYFMN7C6.js → chunk-WUMVIRTN.js} +225 -37
  103. package/chunks/{chunk-R36VMVEP.js → chunk-XJMKOTVV.js} +5 -5
  104. package/chunks/{chunk-TXVGVZYR.js → chunk-XJYUPHRC.js} +3 -3
  105. package/chunks/{chunk-2JD55C6G.js → chunk-Y6YMRS3U.js} +2 -2
  106. package/chunks/{chunk-LLFFKXZZ.js → chunk-YALKC62D.js} +56 -29
  107. package/chunks/{chunk-GYZQA2FO.js → chunk-YLZJCUH6.js} +1 -1
  108. package/chunks/chunk-YTFBURQD.js +313 -0
  109. package/chunks/{chunk-KBXLIVWQ.js → chunk-ZFPRYHWR.js} +2 -2
  110. package/chunks/{chunk-X6EDWN44.js → chunk-ZP6UKOPB.js} +1 -1
  111. package/chunks/{computer-use-6BBRNT6S.js → computer-use-LF2S6LUZ.js} +103 -49
  112. package/chunks/{contextCommand-UJAJ6N57.js → contextCommand-VPX5UG55.js} +26 -25
  113. package/chunks/{cron-create-4KQE6YLH.js → cron-create-SKEY55RG.js} +4 -4
  114. package/chunks/{cron-delete-THME66UP.js → cron-delete-I3NAT32Z.js} +6 -6
  115. package/chunks/{cron-list-7A54SJ5N.js → cron-list-6XRRL6TH.js} +5 -5
  116. package/chunks/{daemon-status-provider-CSL3BUOY.js → daemon-status-provider-5JAWZS4V.js} +34 -34
  117. package/chunks/{de-ACHALDED.js → de-EOW5PVHF.js} +1 -0
  118. package/chunks/{dist-BD27IA3L.js → dist-4FCNM6KJ.js} +2 -2
  119. package/chunks/{dist-OD2FY543.js → dist-O3H4PABL.js} +2 -2
  120. package/chunks/{dist-BOOH5JWN.js → dist-SCAAUWPS.js} +18 -4
  121. package/chunks/{dist-QHJRBCMP.js → dist-UKPWQJCL.js} +44 -2
  122. package/chunks/{dist-QFFZWACU.js → dist-VD7HXTML.js} +20 -9
  123. package/chunks/{earlyInputCapture-X6KMCSHD.js → earlyInputCapture-7FRQMU4P.js} +25 -24
  124. package/chunks/{edit-7J6WXARF.js → edit-REKJDIRL.js} +68 -27
  125. package/chunks/{en-NCUBOJOY.js → en-HPWEJBTR.js} +8 -0
  126. package/chunks/{enter-worktree-KULCKJPJ.js → enter-worktree-GBKUDCD3.js} +24 -23
  127. package/chunks/{enterPlanMode-H2CIOLMH.js → enterPlanMode-WB3Y4FGT.js} +24 -23
  128. package/chunks/{errors-6G2JYR54.js → errors-2XJDYO3M.js} +26 -25
  129. package/chunks/{exit-worktree-ECBWBVC5.js → exit-worktree-KKC7O2ZV.js} +24 -23
  130. package/chunks/{exitPlanMode-DQV56GTW.js → exitPlanMode-7HMS3TF7.js} +24 -23
  131. package/chunks/{fast-path-35JJFS3C.js → fast-path-XVNIYWGG.js} +4 -4
  132. package/chunks/{fast-path-settings-TSVI53EB.js → fast-path-settings-UQLRFDQP.js} +3 -2
  133. package/chunks/{fr-GVKZ27MF.js → fr-BN5NKSAC.js} +1 -0
  134. package/chunks/{gemini-NDTG7WAX.js → gemini-U5TPU3IQ.js} +210 -104
  135. package/chunks/{geminiContentGenerator-XTG6SFLA.js → geminiContentGenerator-ZVWRHXOO.js} +4 -4
  136. package/chunks/{glob-SJ2JBZK4.js → glob-FEJWIH2W.js} +24 -23
  137. package/chunks/{grep-BRMWFEWR.js → grep-KMP25IIA.js} +24 -23
  138. package/chunks/{headlessSafetyWarnings-LJ6FJX77.js → headlessSafetyWarnings-5DEDET4M.js} +24 -23
  139. package/chunks/{initializer-P5AXF7PV.js → initializer-FJTACLOH.js} +31 -28
  140. package/chunks/{ja-FKZ2WZ4D.js → ja-7DEUB2TS.js} +1 -0
  141. package/chunks/{keychain-token-storage-CSYMNRPP.js → keychain-token-storage-YLMDLKXT.js} +2 -2
  142. package/chunks/{list-6COK34BP.js → list-SCQXYJUW.js} +32 -29
  143. package/chunks/{loadedSettingsAdapter-XIUTN245.js → loadedSettingsAdapter-P6KPNAG7.js} +30 -27
  144. package/chunks/{loop-wakeup-33GPXJLA.js → loop-wakeup-FYEQEJUA.js} +7 -7
  145. package/chunks/{ls-BYQY7RVV.js → ls-R5WP4BGZ.js} +4 -4
  146. package/chunks/{lsp-X54RO4IV.js → lsp-GSICJMMW.js} +2 -2
  147. package/chunks/{monitor-DH7KFSJV.js → monitor-JU3HHHVY.js} +24 -23
  148. package/chunks/nonInteractiveCli-IZEKUHU3.js +100 -0
  149. package/chunks/{notebook-edit-D4R4ZLMA.js → notebook-edit-YHY3Z2QQ.js} +52 -23
  150. package/chunks/{openaiContentGenerator-F74IPQ6E.js → openaiContentGenerator-4WUVA3Q2.js} +13 -12
  151. package/chunks/{pt-SY5NCFGR.js → pt-TNZRNLQB.js} +1 -0
  152. package/chunks/{qwenContentGenerator-ATTK5P4D.js → qwenContentGenerator-MVYYR44B.js} +26 -25
  153. package/chunks/{qwenOAuth2-K4AASPCV.js → qwenOAuth2-6HNGHALT.js} +5 -4
  154. package/chunks/{read-file-767G23OY.js → read-file-NABEO2X4.js} +8 -8
  155. package/chunks/{read-mcp-resource-I5HCZJ6X.js → read-mcp-resource-DQQW7H7T.js} +2 -2
  156. package/chunks/{ripGrep-4OMMGSWX.js → ripGrep-YXLK6UTX.js} +24 -23
  157. package/chunks/{ru-FWNXJG4F.js → ru-NIAUBKCN.js} +1 -0
  158. package/chunks/{run-qwen-serve-REKSTYRA.js → run-qwen-serve-4B5QBMLQ.js} +144 -41
  159. package/chunks/{scheduler-UNTFDQLG.js → scheduler-XAKIYBDL.js} +24 -23
  160. package/chunks/{send-message-2DAFXEYP.js → send-message-EE4TWKVU.js} +2 -2
  161. package/chunks/{serve-KZ56QB5S.js → serve-4RXVLUKD.js} +30 -28
  162. package/chunks/{server-BV5TZUMU.js → server-7PA5QGIA.js} +11037 -8747
  163. package/chunks/{session-OIBXFSGD.js → session-WNVWRYAH.js} +194 -57
  164. package/chunks/{settings-WJTCBIRA.js → settings-YJH32TFF.js} +30 -27
  165. package/chunks/{shell-WC52IBHW.js → shell-YFLABOS5.js} +24 -23
  166. package/chunks/{skill-U7F7JR4M.js → skill-N3J7FUAY.js} +38 -11
  167. package/chunks/{spawnChannel-EI2E5BCW.js → spawnChannel-D6WVMFZJ.js} +26 -25
  168. package/chunks/{src-4F6FBZFI.js → src-IU5GDBEH.js} +88 -28
  169. package/chunks/{startInteractiveUI-SFRVB3CE.js → startInteractiveUI-QIPQTRT4.js} +2784 -2474
  170. package/chunks/{syntheticOutput-PPS3HDVA.js → syntheticOutput-T5YHQ6S2.js} +3 -3
  171. package/chunks/{task-create-OUYCA553.js → task-create-BLY7RHXX.js} +6 -6
  172. package/chunks/{task-list-WAX7I2IA.js → task-list-3QUYNVYR.js} +5 -5
  173. package/chunks/{task-stop-CAIL6FNH.js → task-stop-U4RATK2V.js} +2 -2
  174. package/chunks/{task-update-AHEO5OUT.js → task-update-U54O7KJX.js} +6 -6
  175. package/chunks/{team-create-3WC7CIIW.js → team-create-TP4CLLM3.js} +24 -23
  176. package/chunks/{team-delete-HGHFG23B.js → team-delete-LKBYPASD.js} +5 -5
  177. package/chunks/{theme-manager-DICFCT3P.js → theme-manager-N2TBIBZT.js} +25 -24
  178. package/chunks/{todoWrite-IFBMN3FH.js → todoWrite-OYXKTVYN.js} +4 -4
  179. package/chunks/{tool-search-L5K7HLER.js → tool-search-GBBSICYB.js} +101 -16
  180. package/chunks/trustedFolders-F7TBU5CD.js +76 -0
  181. package/chunks/types-QX5C3CHJ.js +12 -0
  182. package/chunks/{validateNonInterActiveAuth-GCH4Z6KI.js → validateNonInterActiveAuth-EQDQPSMI.js} +55 -50
  183. package/chunks/{web-fetch-B5IIQ5TT.js → web-fetch-PCVCML2X.js} +29 -15
  184. package/chunks/{workflow-OB3AND7I.js → workflow-ANJ4FYBK.js} +32 -30
  185. package/chunks/{workspace-providers-status-ZIR5EPOO.js → workspace-providers-status-462QQKQM.js} +32 -29
  186. package/chunks/workspace-service-VTG4G6CW.js +75 -0
  187. package/chunks/{write-file-SEXBNDZM.js → write-file-3P3WMQQW.js} +63 -27
  188. package/chunks/{zh-RBEGQVQT.js → zh-5EUYXASN.js} +8 -0
  189. package/chunks/{zh-TW-QGAVRXT3.js → zh-TW-TR3XYGE5.js} +8 -0
  190. package/cli-entry.js +20 -9
  191. package/cli.js +6 -6
  192. package/locales/ca.js +2 -0
  193. package/locales/de.js +2 -0
  194. package/locales/en.js +14 -0
  195. package/locales/fr.js +2 -0
  196. package/locales/ja.js +1 -0
  197. package/locales/pt.js +2 -0
  198. package/locales/ru.js +2 -0
  199. package/locales/zh-TW.js +12 -0
  200. package/locales/zh.js +12 -0
  201. package/node_modules/@qwen-code/audio-capture/dist/index.d.ts +35 -0
  202. package/node_modules/@qwen-code/audio-capture/dist/index.js +48 -0
  203. package/node_modules/@qwen-code/audio-capture/dist/index.js.map +1 -0
  204. package/node_modules/@qwen-code/audio-capture/dist/platform.d.ts +7 -0
  205. package/node_modules/@qwen-code/audio-capture/dist/platform.js +18 -0
  206. package/node_modules/@qwen-code/audio-capture/dist/platform.js.map +1 -0
  207. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/LICENSE +21 -0
  208. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/README.md +58 -0
  209. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/SECURITY.md +5 -0
  210. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/bin.js +84 -0
  211. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/build-test.js +19 -0
  212. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/index.js +6 -0
  213. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/node-gyp-build.js +207 -0
  214. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/optional.js +7 -0
  215. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/package.json +43 -0
  216. package/node_modules/@qwen-code/audio-capture/package.json +30 -0
  217. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
  218. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
  219. package/node_modules/@qwen-code/audio-capture/prebuilds/linux-arm64/@qwen-code+audio-capture.node +0 -0
  220. package/node_modules/@qwen-code/audio-capture/prebuilds/linux-x64/@qwen-code+audio-capture.node +0 -0
  221. package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
  222. package/package.json +18 -6
  223. package/patches/chrome-devtools-mcp+1.4.0.patch +31 -0
  224. package/postinstall.js +50 -0
  225. package/web-shell/assets/{arc-D_ae_Y9k.js → arc-DIemsO_F.js} +1 -1
  226. package/web-shell/assets/{architectureDiagram-3BPJPVTR-BMLRjppa.js → architectureDiagram-3BPJPVTR-CTlUvIQv.js} +1 -1
  227. package/web-shell/assets/{blockDiagram-GPEHLZMM-qVDQC8KL.js → blockDiagram-GPEHLZMM-DG0jmIZK.js} +1 -1
  228. package/web-shell/assets/{c4Diagram-AAUBKEIU-CxWS6MBd.js → c4Diagram-AAUBKEIU-WljDBi55.js} +1 -1
  229. package/web-shell/assets/channel-CbzRbdpA.js +1 -0
  230. package/web-shell/assets/{chunk-2J33WTMH-BtNuY5Yp.js → chunk-2J33WTMH-8nc6onr2.js} +1 -1
  231. package/web-shell/assets/{chunk-4BX2VUAB-BU-x368d.js → chunk-4BX2VUAB-EopXix8Z.js} +1 -1
  232. package/web-shell/assets/{chunk-55IACEB6-DRgTLvBu.js → chunk-55IACEB6-BE4Jz3N3.js} +1 -1
  233. package/web-shell/assets/{chunk-727SXJPM-D2aElv7q.js → chunk-727SXJPM-C_eErgDN.js} +1 -1
  234. package/web-shell/assets/{chunk-AQP2D5EJ-BwHCMRQ0.js → chunk-AQP2D5EJ-DFtVW-Is.js} +1 -1
  235. package/web-shell/assets/{chunk-FMBD7UC4-BMyPH-ku.js → chunk-FMBD7UC4-CJPyxIg9.js} +1 -1
  236. package/web-shell/assets/{chunk-ND2GUHAM-BNKTstUf.js → chunk-ND2GUHAM-Bk-xgj6M.js} +1 -1
  237. package/web-shell/assets/{chunk-QZHKN3VN-gD3vsFId.js → chunk-QZHKN3VN-p3Y4yaFB.js} +1 -1
  238. package/web-shell/assets/classDiagram-4FO5ZUOK-BFdyQ52h.js +1 -0
  239. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BFdyQ52h.js +1 -0
  240. package/web-shell/assets/{cose-bilkent-S5V4N54A-BG9FAsXE.js → cose-bilkent-S5V4N54A-BCMO6Js3.js} +1 -1
  241. package/web-shell/assets/{dagre-BM42HDAG-Cy1sR7om.js → dagre-BM42HDAG-DUMrwASf.js} +1 -1
  242. package/web-shell/assets/default-aEtf0G7-.svg +1 -0
  243. package/web-shell/assets/{diagram-2AECGRRQ-Bxi1I_Vu.js → diagram-2AECGRRQ-C5d7qJbL.js} +1 -1
  244. package/web-shell/assets/{diagram-5GNKFQAL-BGCJjO6y.js → diagram-5GNKFQAL-CjLzMhbT.js} +1 -1
  245. package/web-shell/assets/{diagram-KO2AKTUF-CMTeLXp7.js → diagram-KO2AKTUF-RCoNWeAm.js} +1 -1
  246. package/web-shell/assets/{diagram-LMA3HP47-BN1wyAGh.js → diagram-LMA3HP47-KThXjaNV.js} +1 -1
  247. package/web-shell/assets/{diagram-OG6HWLK6-UYSG_zcp.js → diagram-OG6HWLK6-DKsC2BWz.js} +1 -1
  248. package/web-shell/assets/{erDiagram-TEJ5UH35-DqXL08lw.js → erDiagram-TEJ5UH35-DJ2ukmq0.js} +1 -1
  249. package/web-shell/assets/{flowDiagram-I6XJVG4X-BPJ9SFji.js → flowDiagram-I6XJVG4X-zzqaARRX.js} +1 -1
  250. package/web-shell/assets/{ganttDiagram-6RSMTGT7-BEd9Pnms.js → ganttDiagram-6RSMTGT7-kFUg-gqT.js} +1 -1
  251. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-DrNRH3oi.js → gitGraphDiagram-PVQCEYII-C6JnMVzD.js} +1 -1
  252. package/web-shell/assets/index-B3XUm7dw.js +713 -0
  253. package/web-shell/assets/index-CHmzAWys.css +5 -0
  254. package/web-shell/assets/{infoDiagram-5YYISTIA-CFYBrkVI.js → infoDiagram-5YYISTIA-XqPVhp89.js} +1 -1
  255. package/web-shell/assets/insert-DmRbh9Rv.svg +1 -0
  256. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-Dxsddth7.js → ishikawaDiagram-YF4QCWOH-D2k8sGpf.js} +1 -1
  257. package/web-shell/assets/{journeyDiagram-JHISSGLW-DxaDK80t.js → journeyDiagram-JHISSGLW-CQEST1GE.js} +1 -1
  258. package/web-shell/assets/{kanban-definition-UN3LZRKU-Q0jQCOct.js → kanban-definition-UN3LZRKU-DZ7kqVBC.js} +1 -1
  259. package/web-shell/assets/{linear-DGGM2kcP.js → linear-B6C_6q_E.js} +1 -1
  260. package/web-shell/assets/{mermaid.core-ByoxnWut.js → mermaid.core-CsyNP1qt.js} +5 -5
  261. package/web-shell/assets/{mindmap-definition-RKZ34NQL-C0ZseHsi.js → mindmap-definition-RKZ34NQL-B1VDIzJq.js} +1 -1
  262. package/web-shell/assets/{pieDiagram-4H26LBE5-MQXNhl5A.js → pieDiagram-4H26LBE5-DN0E7Jwu.js} +1 -1
  263. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-DIR4ee2A.js → quadrantDiagram-W4KKPZXB-UKTQdHKm.js} +1 -1
  264. package/web-shell/assets/queue-DWpnpFgW.svg +1 -0
  265. package/web-shell/assets/{requirementDiagram-4Y6WPE33-BTR0UdYQ.js → requirementDiagram-4Y6WPE33-BRGceQvN.js} +1 -1
  266. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-sfnhMELN.js → sankeyDiagram-5OEKKPKP-2DDyu41v.js} +1 -1
  267. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-DXczHOHH.js → sequenceDiagram-3UESZ5HK-CT5iE8ZU.js} +1 -1
  268. package/web-shell/assets/{stateDiagram-AJRCARHV-DdE_KQFH.js → stateDiagram-AJRCARHV-CqMQ_s4G.js} +1 -1
  269. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CamhV5pM.js +1 -0
  270. package/web-shell/assets/{timeline-definition-PNZ67QCA-DIc61uE8.js → timeline-definition-PNZ67QCA-Di37QSZU.js} +1 -1
  271. package/web-shell/assets/{vennDiagram-CIIHVFJN-BF7ODmxB.js → vennDiagram-CIIHVFJN-DCXvpz5S.js} +1 -1
  272. package/web-shell/assets/{wardley-L42UT6IY-3pc1MEaw.js → wardley-L42UT6IY-CpUCk6OX.js} +1 -1
  273. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-9jnPcZuP.js → wardleyDiagram-YWT4CUSO-D01pVEBg.js} +1 -1
  274. package/web-shell/assets/{xychartDiagram-2RQKCTM6-DcthaZK6.js → xychartDiagram-2RQKCTM6-DOu5JDoz.js} +1 -1
  275. package/web-shell/index.html +2 -2
  276. package/chunks/chunk-B6HQGTYR.js +0 -410
  277. package/chunks/chunk-R2BXK7SX.js +0 -13
  278. package/chunks/chunk-RKIZXJMB.js +0 -13
  279. package/chunks/nonInteractiveCli-7575LBXP.js +0 -91
  280. package/chunks/workspace-service-OM5D4OI2.js +0 -60
  281. package/web-shell/assets/channel-DYPNiTww.js +0 -1
  282. package/web-shell/assets/classDiagram-4FO5ZUOK-p_g25Tni.js +0 -1
  283. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-p_g25Tni.js +0 -1
  284. package/web-shell/assets/index-CpOXWDPh.js +0 -714
  285. package/web-shell/assets/index-oVK7qhre.css +0 -5
  286. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BHUSEndU.js +0 -1
@@ -0,0 +1,690 @@
1
+ // Force strict mode and setup for ESM
2
+ "use strict";
3
+ import {
4
+ formatUnsupportedVoiceModelMessage,
5
+ isTranscribableVoiceModel,
6
+ readVoiceLanguage,
7
+ resolveVoiceTransport
8
+ } from "./chunk-5XQ4A26L.js";
9
+ import {
10
+ resolvePath
11
+ } from "./chunk-BC3C4F3Q.js";
12
+ import {
13
+ createDebugLogger,
14
+ isSubpath
15
+ } from "./chunk-UX4SGCGN.js";
16
+ import {
17
+ init_esbuild_shims
18
+ } from "./chunk-A4BMJM77.js";
19
+ import {
20
+ __name
21
+ } from "./chunk-J2S4EL5Y.js";
22
+
23
+ // packages/cli/src/services/voice-transcriber.ts
24
+ init_esbuild_shims();
25
+ import process from "node:process";
26
+ import { lookup as dnsLookup } from "node:dns/promises";
27
+ import { isIP } from "node:net";
28
+
29
+ // packages/cli/src/services/voice-keyterms.ts
30
+ init_esbuild_shims();
31
+ import * as fs from "node:fs";
32
+ import * as path from "node:path";
33
+ var GLOBAL_KEYTERMS = [
34
+ "Qwen",
35
+ "MCP",
36
+ "grep",
37
+ "regex",
38
+ "localhost",
39
+ "codebase",
40
+ "TypeScript",
41
+ "JavaScript",
42
+ "JSON",
43
+ "YAML",
44
+ "OAuth",
45
+ "webhook",
46
+ "gRPC",
47
+ "dotfiles",
48
+ "subagent",
49
+ "worktree",
50
+ "stdout",
51
+ "stderr",
52
+ "async",
53
+ "await",
54
+ "API",
55
+ "CLI",
56
+ "npm",
57
+ "pnpm",
58
+ "commit",
59
+ "rebase",
60
+ "refactor",
61
+ "endpoint",
62
+ "middleware",
63
+ "schema",
64
+ "tokenizer"
65
+ ];
66
+ var DEFAULT_KEYTERMS_FILENAME = "voice-keyterms.txt";
67
+ var MAX_KEYTERMS = 200;
68
+ var MAX_KEYTERMS_BYTES = 2e3;
69
+ var MAX_KEYTERMS_FILE_BYTES = 64 * 1024;
70
+ function buildVoiceKeyterms(settings) {
71
+ const userTerms = settings ? readUserKeyterms(settings) : [];
72
+ return capKeyterms(dedupeKeyterms([...GLOBAL_KEYTERMS, ...userTerms]));
73
+ }
74
+ __name(buildVoiceKeyterms, "buildVoiceKeyterms");
75
+ function dedupeKeyterms(terms) {
76
+ const seen = /* @__PURE__ */ new Set();
77
+ const out = [];
78
+ for (const term of terms) {
79
+ const key = term.toLowerCase();
80
+ if (seen.has(key)) {
81
+ continue;
82
+ }
83
+ seen.add(key);
84
+ out.push(term);
85
+ }
86
+ return out;
87
+ }
88
+ __name(dedupeKeyterms, "dedupeKeyterms");
89
+ function capKeyterms(terms) {
90
+ const out = [];
91
+ let bytes = 0;
92
+ for (const term of terms) {
93
+ if (out.length >= MAX_KEYTERMS) {
94
+ break;
95
+ }
96
+ const next = bytes + Buffer.byteLength(term, "utf8") + (out.length > 0 ? 1 : 0);
97
+ if (next > MAX_KEYTERMS_BYTES) {
98
+ continue;
99
+ }
100
+ out.push(term);
101
+ bytes = next;
102
+ }
103
+ return out;
104
+ }
105
+ __name(capKeyterms, "capKeyterms");
106
+ function readUserKeyterms(settings) {
107
+ if (!settings.isTrusted) {
108
+ return [];
109
+ }
110
+ for (const resolved of resolveKeytermsFiles(settings)) {
111
+ try {
112
+ const file = canonicalizeKeytermsFile(resolved);
113
+ if (!file) {
114
+ continue;
115
+ }
116
+ const content = readRegularFileNoFollow(file);
117
+ if (content === void 0) {
118
+ continue;
119
+ }
120
+ const parsed = parseKeyterms(content);
121
+ if (parsed.length > 0) {
122
+ return parsed;
123
+ }
124
+ } catch {
125
+ }
126
+ }
127
+ return [];
128
+ }
129
+ __name(readUserKeyterms, "readUserKeyterms");
130
+ function resolveKeytermsFiles(settings) {
131
+ const workspacePath = settings.workspace?.path;
132
+ if (!workspacePath) {
133
+ return [];
134
+ }
135
+ const qwenDir = path.dirname(workspacePath);
136
+ const workspaceRoot = path.dirname(qwenDir);
137
+ const configured = readKeytermsFileSettings(settings);
138
+ if (configured.length > 0) {
139
+ return configured.map(({ path: configuredPath, scope }) => {
140
+ const expanded = resolvePath(configuredPath);
141
+ const isAbsolute2 = path.isAbsolute(expanded);
142
+ return {
143
+ filePath: isAbsolute2 ? expanded : path.resolve(workspaceRoot, expanded),
144
+ workspaceRoot,
145
+ mustBeInWorkspace: scope === "system" || !isAbsolute2
146
+ };
147
+ });
148
+ }
149
+ return [
150
+ {
151
+ filePath: path.join(qwenDir, DEFAULT_KEYTERMS_FILENAME),
152
+ workspaceRoot,
153
+ mustBeInWorkspace: true
154
+ }
155
+ ];
156
+ }
157
+ __name(resolveKeytermsFiles, "resolveKeytermsFiles");
158
+ function canonicalizeKeytermsFile({
159
+ filePath,
160
+ workspaceRoot,
161
+ mustBeInWorkspace
162
+ }) {
163
+ const stat = fs.lstatSync(filePath, { throwIfNoEntry: false });
164
+ if (!stat || stat.isSymbolicLink() || !stat.isFile() || stat.nlink > 1 || stat.size > MAX_KEYTERMS_FILE_BYTES) {
165
+ return void 0;
166
+ }
167
+ const realFilePath = fs.realpathSync(filePath);
168
+ if (mustBeInWorkspace) {
169
+ const realWorkspaceRoot = fs.realpathSync(workspaceRoot);
170
+ if (!isSubpath(realWorkspaceRoot, realFilePath)) {
171
+ return void 0;
172
+ }
173
+ }
174
+ return { filePath: realFilePath, stat };
175
+ }
176
+ __name(canonicalizeKeytermsFile, "canonicalizeKeytermsFile");
177
+ function readRegularFileNoFollow({
178
+ filePath,
179
+ stat: expectedStat
180
+ }) {
181
+ let fd;
182
+ try {
183
+ let flags = fs.constants.O_RDONLY;
184
+ if (typeof fs.constants.O_NOFOLLOW === "number") {
185
+ flags |= fs.constants.O_NOFOLLOW;
186
+ }
187
+ if (typeof fs.constants.O_NONBLOCK === "number") {
188
+ flags |= fs.constants.O_NONBLOCK;
189
+ }
190
+ fd = fs.openSync(filePath, flags);
191
+ const stat = fs.fstatSync(fd);
192
+ if (stat.dev !== expectedStat.dev || stat.ino !== expectedStat.ino || stat.mode !== expectedStat.mode || stat.size !== expectedStat.size || stat.mtimeMs !== expectedStat.mtimeMs || stat.ctimeMs !== expectedStat.ctimeMs || !stat.isFile() || stat.nlink > 1 || stat.size > MAX_KEYTERMS_FILE_BYTES) {
193
+ return void 0;
194
+ }
195
+ const content = fs.readFileSync(fd, "utf-8");
196
+ if (Buffer.byteLength(content, "utf8") > MAX_KEYTERMS_FILE_BYTES) {
197
+ return void 0;
198
+ }
199
+ return content;
200
+ } finally {
201
+ if (fd !== void 0) {
202
+ fs.closeSync(fd);
203
+ }
204
+ }
205
+ }
206
+ __name(readRegularFileNoFollow, "readRegularFileNoFollow");
207
+ function parseKeyterms(content) {
208
+ return content.split(/\r?\n/).map((line) => line.replace(/^\s*#.*$/, "").trim()).filter((line) => line.length > 0);
209
+ }
210
+ __name(parseKeyterms, "parseKeyterms");
211
+ function readKeytermsFileSettings(settings) {
212
+ const out = [];
213
+ const system = readKeytermsFileSettingFromScope(settings.system?.settings);
214
+ if (system) {
215
+ out.push({ path: system, scope: "system" });
216
+ }
217
+ const user = readKeytermsFileSettingFromScope(settings.user?.settings);
218
+ if (user) {
219
+ out.push({ path: user, scope: "user" });
220
+ }
221
+ return out;
222
+ }
223
+ __name(readKeytermsFileSettings, "readKeytermsFileSettings");
224
+ function readKeytermsFileSettingFromScope(settings) {
225
+ const value = settings?.general?.voice?.keytermsFile;
226
+ if (typeof value !== "string") {
227
+ return void 0;
228
+ }
229
+ const trimmed = value.trim();
230
+ return trimmed.length > 0 ? trimmed : void 0;
231
+ }
232
+ __name(readKeytermsFileSettingFromScope, "readKeytermsFileSettingFromScope");
233
+
234
+ // packages/cli/src/services/voice-transcriber.ts
235
+ var DEFAULT_OPENAI_API_KEY = "OPENAI_API_KEY";
236
+ var INFERENCE_TIMEOUT_MS = 6e4;
237
+ var MIN_KEYTERM_ECHO_TOKENS = 8;
238
+ var MIN_ABSOLUTE_KEYTERM_ECHO_TOKENS = 10;
239
+ var MIN_KEYTERM_SET_ECHO_RATIO = 0.3;
240
+ var debugLogger = createDebugLogger("VOICE_TRANSCRIBER");
241
+ function trimTrailingSlashes(value) {
242
+ return value.replace(/\/+$/, "");
243
+ }
244
+ __name(trimTrailingSlashes, "trimTrailingSlashes");
245
+ function readSettingsEnv(settings, envKey) {
246
+ const env = settings.merged.env;
247
+ const value = env?.[envKey];
248
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
249
+ }
250
+ __name(readSettingsEnv, "readSettingsEnv");
251
+ function isQwenBaseUrl(baseUrl) {
252
+ try {
253
+ const hostname = new URL(baseUrl).hostname.toLowerCase();
254
+ return hostname === "dashscope.aliyuncs.com" || hostname === "dashscope-intl.aliyuncs.com" || hostname === "dashscope-us.aliyuncs.com" || hostname.endsWith(".dashscope.aliyuncs.com") || hostname.endsWith(".dashscope-intl.aliyuncs.com") || hostname.endsWith(".dashscope-us.aliyuncs.com");
255
+ } catch {
256
+ return false;
257
+ }
258
+ }
259
+ __name(isQwenBaseUrl, "isQwenBaseUrl");
260
+ function normalizeBaseUrl(baseUrl, modelName) {
261
+ let url;
262
+ try {
263
+ url = new URL(baseUrl);
264
+ } catch {
265
+ throw new Error(`Voice model '${modelName}' has an invalid baseUrl.`);
266
+ }
267
+ url.username = "";
268
+ url.password = "";
269
+ return trimTrailingSlashes(url.toString());
270
+ }
271
+ __name(normalizeBaseUrl, "normalizeBaseUrl");
272
+ function normalizeHostname(hostname) {
273
+ return hostname.toLowerCase().replace(/^\[|\]$/g, "");
274
+ }
275
+ __name(normalizeHostname, "normalizeHostname");
276
+ function isLoopbackHost(hostname) {
277
+ const host = normalizeHostname(hostname);
278
+ return host === "localhost" || host === "127.0.0.1" || host === "::1";
279
+ }
280
+ __name(isLoopbackHost, "isLoopbackHost");
281
+ function readIpv4CompatibleIpv6(host) {
282
+ if (!host.startsWith("::") || host.startsWith("::ffff:")) {
283
+ return void 0;
284
+ }
285
+ const parts = host.slice(2).split(":");
286
+ if (parts.length === 0 || parts.length > 2 || parts.some((p) => !p)) {
287
+ return void 0;
288
+ }
289
+ if (parts.some((part) => !/^[0-9a-f]{1,4}$/i.test(part))) {
290
+ return void 0;
291
+ }
292
+ const hextets = parts.map((part) => Number.parseInt(part, 16));
293
+ if (hextets.some((part) => !Number.isInteger(part) || part < 0 || part > 65535)) {
294
+ return void 0;
295
+ }
296
+ const value = hextets.length === 1 ? hextets[0] : hextets[0] << 16 | hextets[1];
297
+ return [
298
+ value >>> 24 & 255,
299
+ value >>> 16 & 255,
300
+ value >>> 8 & 255,
301
+ value & 255
302
+ ].join(".");
303
+ }
304
+ __name(readIpv4CompatibleIpv6, "readIpv4CompatibleIpv6");
305
+ function isPrivateNetworkIp(hostname) {
306
+ const host = normalizeHostname(hostname);
307
+ if (isLoopbackHost(host)) {
308
+ return false;
309
+ }
310
+ const ipv4Mapped = host.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
311
+ if (ipv4Mapped) {
312
+ return isPrivateNetworkIp(ipv4Mapped[1]);
313
+ }
314
+ const ipv4Compatible = host.match(/^::(\d+\.\d+\.\d+\.\d+)$/);
315
+ if (ipv4Compatible) {
316
+ return isPrivateNetworkIp(ipv4Compatible[1]);
317
+ }
318
+ const normalizedIpv4Compatible = readIpv4CompatibleIpv6(host);
319
+ if (normalizedIpv4Compatible) {
320
+ return isPrivateNetworkIp(normalizedIpv4Compatible);
321
+ }
322
+ if (host.startsWith("::ffff:")) {
323
+ return true;
324
+ }
325
+ if (isIP(host) === 4) {
326
+ const [first = 0, second = 0] = host.split(".").map(Number);
327
+ return first === 0 || first === 10 || first === 127 || first === 169 && second === 254 || first === 172 && second >= 16 && second <= 31 || first === 192 && second === 168 || first === 100 && second >= 64 && second <= 127;
328
+ }
329
+ if (isIP(host) === 6) {
330
+ const firstHextet = Number.parseInt(host.split(":", 1)[0] || "", 16);
331
+ const isLinkLocal = firstHextet >= 65152 && firstHextet <= 65215;
332
+ const isUniqueLocal = (firstHextet & 65024) === 64512;
333
+ return host === "::" || isLinkLocal || isUniqueLocal;
334
+ }
335
+ return false;
336
+ }
337
+ __name(isPrivateNetworkIp, "isPrivateNetworkIp");
338
+ async function defaultLookupHost(hostname) {
339
+ return dnsLookup(hostname, { all: true });
340
+ }
341
+ __name(defaultLookupHost, "defaultLookupHost");
342
+ async function assertVoiceBaseUrlNetworkAllowed(voiceConfig, lookupHost) {
343
+ const hostname = normalizeHostname(new URL(voiceConfig.baseUrl).hostname);
344
+ if (isLoopbackHost(hostname)) {
345
+ return;
346
+ }
347
+ if (isIP(hostname) !== 0) {
348
+ if (isPrivateNetworkIp(hostname)) {
349
+ throw new Error(
350
+ `Voice model '${voiceConfig.model}' resolved to a private-network address.`
351
+ );
352
+ }
353
+ return;
354
+ }
355
+ let result;
356
+ try {
357
+ result = await (lookupHost ?? defaultLookupHost)(hostname);
358
+ } catch {
359
+ throw new Error(
360
+ `Voice model '${voiceConfig.model}': DNS lookup failed for ${hostname}. Cannot verify network safety.`
361
+ );
362
+ }
363
+ const records = Array.isArray(result) ? result : [result];
364
+ if (records.some((record) => isPrivateNetworkIp(record.address))) {
365
+ throw new Error(
366
+ `Voice model '${voiceConfig.model}' resolved to a private-network address.`
367
+ );
368
+ }
369
+ }
370
+ __name(assertVoiceBaseUrlNetworkAllowed, "assertVoiceBaseUrlNetworkAllowed");
371
+ function readApiKey(settings, model, baseUrl) {
372
+ if (!model.envKey && !isQwenBaseUrl(baseUrl)) {
373
+ return void 0;
374
+ }
375
+ const envKey = model.envKey ?? DEFAULT_OPENAI_API_KEY;
376
+ const envValue = process.env[envKey];
377
+ if (envValue && envValue.trim().length > 0) {
378
+ return envValue.trim();
379
+ }
380
+ const settingsEnvValue = readSettingsEnv(settings, envKey);
381
+ if (settingsEnvValue) {
382
+ return settingsEnvValue;
383
+ }
384
+ if (!model.envKey && isQwenBaseUrl(baseUrl)) {
385
+ const authApiKey = settings.merged.security?.auth?.apiKey;
386
+ return typeof authApiKey === "string" && authApiKey.trim().length > 0 ? authApiKey.trim() : void 0;
387
+ }
388
+ return void 0;
389
+ }
390
+ __name(readApiKey, "readApiKey");
391
+ function resolveVoiceTranscriptionConfig({
392
+ config,
393
+ settings,
394
+ voiceModel
395
+ }) {
396
+ const matches = config.getAllConfiguredModels().filter((model2) => model2.id === voiceModel);
397
+ if (matches.length === 0) {
398
+ throw new Error(
399
+ `Voice model '${voiceModel}' is not configured. Run /model --voice to choose a configured model.`
400
+ );
401
+ }
402
+ if (matches.length > 1) {
403
+ throw new Error(`Voice model '${voiceModel}' is ambiguous.`);
404
+ }
405
+ const model = matches[0];
406
+ if (!isTranscribableVoiceModel(model)) {
407
+ throw new Error(formatUnsupportedVoiceModelMessage(voiceModel));
408
+ }
409
+ const baseUrl = model.baseUrl?.trim();
410
+ if (!baseUrl) {
411
+ throw new Error(`Voice model '${voiceModel}' does not define a baseUrl.`);
412
+ }
413
+ const normalizedBaseUrl = normalizeBaseUrl(baseUrl, voiceModel);
414
+ const parsedBaseUrl = new URL(normalizedBaseUrl);
415
+ const isLocalhost = isLoopbackHost(parsedBaseUrl.hostname);
416
+ if (parsedBaseUrl.protocol !== "https:" && !isLocalhost) {
417
+ throw new Error(
418
+ `Voice model '${voiceModel}' must use an https baseUrl. Voice audio must not be transmitted in cleartext.`
419
+ );
420
+ }
421
+ if (isPrivateNetworkIp(parsedBaseUrl.hostname)) {
422
+ throw new Error(
423
+ `Voice model '${voiceModel}' must not use a private-network baseUrl.`
424
+ );
425
+ }
426
+ const apiKey = readApiKey(settings, model, normalizedBaseUrl);
427
+ if (model.envKey && !apiKey) {
428
+ throw new Error(`Voice model '${voiceModel}' requires ${model.envKey}.`);
429
+ }
430
+ return {
431
+ model: voiceModel,
432
+ baseUrl: normalizedBaseUrl,
433
+ ...apiKey ? { apiKey } : {}
434
+ };
435
+ }
436
+ __name(resolveVoiceTranscriptionConfig, "resolveVoiceTranscriptionConfig");
437
+ function isStreamingVoiceModel(model) {
438
+ const transport = resolveVoiceTransport(model);
439
+ return transport === "qwen-asr-realtime" || transport === "dashscope-task-realtime";
440
+ }
441
+ __name(isStreamingVoiceModel, "isStreamingVoiceModel");
442
+ function resolveVoiceStreamConfig(args) {
443
+ const base = resolveVoiceTranscriptionConfig(args);
444
+ const transport = resolveVoiceTransport(base.model);
445
+ if (transport !== "qwen-asr-realtime" && transport !== "dashscope-task-realtime") {
446
+ throw new Error(
447
+ `Voice model '${base.model}' does not support streaming transcription.`
448
+ );
449
+ }
450
+ const language = resolveLanguageCode(readVoiceLanguage(args.settings));
451
+ const keytermsContext = transport === "qwen-asr-realtime" ? buildKeytermsContext(args.settings) : void 0;
452
+ return {
453
+ transport,
454
+ baseUrl: base.baseUrl,
455
+ model: base.model,
456
+ ...base.apiKey ? { apiKey: base.apiKey } : {},
457
+ ...language ? { language } : {},
458
+ ...keytermsContext ? { keytermsContext } : {}
459
+ };
460
+ }
461
+ __name(resolveVoiceStreamConfig, "resolveVoiceStreamConfig");
462
+ var LANGUAGE_CODES = {
463
+ english: "en",
464
+ chinese: "zh",
465
+ mandarin: "zh",
466
+ cantonese: "yue",
467
+ japanese: "ja",
468
+ korean: "ko",
469
+ french: "fr",
470
+ german: "de",
471
+ spanish: "es",
472
+ italian: "it",
473
+ portuguese: "pt",
474
+ russian: "ru",
475
+ arabic: "ar"
476
+ };
477
+ function resolveLanguageCode(language) {
478
+ if (!language) {
479
+ return void 0;
480
+ }
481
+ const lower = language.toLowerCase();
482
+ if (LANGUAGE_CODES[lower]) {
483
+ return LANGUAGE_CODES[lower];
484
+ }
485
+ return /^[a-z]{2,3}$/.test(lower) ? lower : void 0;
486
+ }
487
+ __name(resolveLanguageCode, "resolveLanguageCode");
488
+ function buildKeytermsContext(settings) {
489
+ try {
490
+ const keyterms = buildVoiceKeyterms(settings);
491
+ return keyterms.length > 0 ? keyterms.join(" ") : void 0;
492
+ } catch {
493
+ return void 0;
494
+ }
495
+ }
496
+ __name(buildKeytermsContext, "buildKeytermsContext");
497
+ function tokenize(value) {
498
+ return value.toLowerCase().replace(/[^\p{L}\p{N}\s]/gu, " ").split(/\s+/).filter(Boolean);
499
+ }
500
+ __name(tokenize, "tokenize");
501
+ function isKeytermEcho(transcript, keytermsContext) {
502
+ if (!keytermsContext) {
503
+ return false;
504
+ }
505
+ const tokens = tokenize(transcript);
506
+ if (tokens.length < 4) {
507
+ return false;
508
+ }
509
+ const keyset = new Set(tokenize(keytermsContext));
510
+ const overlap = tokens.filter((t) => keyset.has(t)).length;
511
+ const transcriptRatio = overlap / tokens.length;
512
+ const keytermRatio = overlap / keyset.size;
513
+ const isEcho = overlap >= MIN_KEYTERM_ECHO_TOKENS && transcriptRatio >= 0.9 && (keytermRatio >= MIN_KEYTERM_SET_ECHO_RATIO || overlap >= MIN_ABSOLUTE_KEYTERM_ECHO_TOKENS);
514
+ if (isEcho) {
515
+ const branch = keytermRatio >= MIN_KEYTERM_SET_ECHO_RATIO ? "ratio" : "absolute";
516
+ debugLogger.debug(
517
+ `[voice] dropped likely keyterm echo (${branch}): overlap=${overlap} keysetSize=${keyset.size} transcriptRatio=${transcriptRatio.toFixed(2)} keytermRatio=${keytermRatio.toFixed(2)} text="${transcript}"`
518
+ );
519
+ }
520
+ return isEcho;
521
+ }
522
+ __name(isKeytermEcho, "isKeytermEcho");
523
+ var MAX_AUDIO_BYTES = 10 * 1024 * 1024;
524
+ var MAX_TRANSCRIPTION_ERROR_LENGTH = 200;
525
+ function escapeRegExp(value) {
526
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
527
+ }
528
+ __name(escapeRegExp, "escapeRegExp");
529
+ function sanitizeVoiceErrorMessage(raw, apiKey) {
530
+ let redacted = raw.replace(
531
+ /Authorization:\s*(?:Bearer|ApiKey|Basic|Token)?\s*\S+/gi,
532
+ "Authorization: [REDACTED]"
533
+ ).replace(/Bearer\s+\S+/gi, "Bearer [REDACTED]").replace(/\b(?:api[-_ ]?key|token|secret)=\S+/gi, "[REDACTED]").replace(/\bsk-[A-Za-z0-9._-]{4,}\b/g, "[REDACTED]");
534
+ if (apiKey) {
535
+ redacted = redacted.replace(
536
+ new RegExp(escapeRegExp(apiKey), "g"),
537
+ "[REDACTED]"
538
+ );
539
+ }
540
+ return redacted.length > MAX_TRANSCRIPTION_ERROR_LENGTH ? `${redacted.slice(0, MAX_TRANSCRIPTION_ERROR_LENGTH)}...` : redacted;
541
+ }
542
+ __name(sanitizeVoiceErrorMessage, "sanitizeVoiceErrorMessage");
543
+ function inputAudioFormat(mimeType) {
544
+ const subtype = mimeType.split(";", 1)[0]?.trim().toLowerCase() ?? "";
545
+ return subtype.startsWith("audio/") ? subtype.slice("audio/".length) || "wav" : "wav";
546
+ }
547
+ __name(inputAudioFormat, "inputAudioFormat");
548
+ function transcriptionAbortSignal(abortSignal) {
549
+ const timeoutSignal = AbortSignal.timeout(INFERENCE_TIMEOUT_MS);
550
+ return abortSignal ? AbortSignal.any([abortSignal, timeoutSignal]) : timeoutSignal;
551
+ }
552
+ __name(transcriptionAbortSignal, "transcriptionAbortSignal");
553
+ async function transcribeViaQwenAsr(audio, voiceConfig, options, fetchFn) {
554
+ if (audio.data.byteLength > MAX_AUDIO_BYTES) {
555
+ throw new Error(
556
+ "Recording is too long for transcription (max ~5 minutes / 10 MB). Try a shorter dictation."
557
+ );
558
+ }
559
+ const dataUrl = `data:${audio.mimeType};base64,${Buffer.from(audio.data).toString("base64")}`;
560
+ const messages = [];
561
+ if (options.keytermsContext) {
562
+ messages.push({
563
+ role: "system",
564
+ content: [{ type: "text", text: options.keytermsContext }]
565
+ });
566
+ }
567
+ messages.push({
568
+ role: "user",
569
+ content: [
570
+ {
571
+ type: "input_audio",
572
+ input_audio: {
573
+ data: dataUrl,
574
+ format: inputAudioFormat(audio.mimeType)
575
+ }
576
+ }
577
+ ]
578
+ });
579
+ const asrOptions = { enable_itn: true };
580
+ if (options.language) {
581
+ asrOptions["language"] = options.language;
582
+ }
583
+ const headers = {
584
+ "Content-Type": "application/json"
585
+ };
586
+ if (voiceConfig.apiKey) {
587
+ headers["Authorization"] = `Bearer ${voiceConfig.apiKey}`;
588
+ }
589
+ let response;
590
+ try {
591
+ response = await fetchFn(
592
+ `${trimTrailingSlashes(voiceConfig.baseUrl)}/chat/completions`,
593
+ {
594
+ method: "POST",
595
+ headers,
596
+ redirect: "manual",
597
+ body: JSON.stringify({
598
+ model: voiceConfig.model,
599
+ messages,
600
+ asr_options: asrOptions
601
+ }),
602
+ signal: transcriptionAbortSignal(options.abortSignal)
603
+ }
604
+ );
605
+ } catch (error) {
606
+ if (error instanceof DOMException && error.name === "TimeoutError") {
607
+ throw new Error(
608
+ `Voice transcription timed out after ${INFERENCE_TIMEOUT_MS / 1e3}s. Check ASR service health and retry.`
609
+ );
610
+ }
611
+ throw error;
612
+ }
613
+ if (response.status >= 300 && response.status < 400) {
614
+ throw new Error("Voice transcription request redirected.");
615
+ }
616
+ if (!response.ok) {
617
+ let details = "";
618
+ try {
619
+ details = sanitizeVoiceErrorMessage(
620
+ await response.text(),
621
+ voiceConfig.apiKey
622
+ );
623
+ } catch {
624
+ details = "";
625
+ }
626
+ if (/model_not_supported|unsupported model/i.test(details)) {
627
+ throw new Error(
628
+ "This voice model cannot be used for batch transcription. Use qwen3-asr-flash for batch or choose a realtime voice model such as qwen3-asr-flash-realtime / fun-asr-realtime / paraformer-realtime-v2."
629
+ );
630
+ }
631
+ const suffix = details ? `: ${details}` : "";
632
+ throw new Error(
633
+ `Voice transcription request failed (${response.status} ${response.statusText})${suffix}`
634
+ );
635
+ }
636
+ const json = await response.json();
637
+ const content = json.choices?.[0]?.message?.content;
638
+ if (typeof content !== "string") {
639
+ throw new Error("Voice transcription response did not include text.");
640
+ }
641
+ const text = content.trim();
642
+ if (isKeytermEcho(text, options.keytermsContext)) {
643
+ return "";
644
+ }
645
+ return text;
646
+ }
647
+ __name(transcribeViaQwenAsr, "transcribeViaQwenAsr");
648
+ async function transcribeVoiceAudio(audio, args) {
649
+ const voiceConfig = resolveVoiceTranscriptionConfig(args);
650
+ await assertVoiceBaseUrlNetworkAllowed(voiceConfig, args.lookupHost);
651
+ const fetchFn = args.fetchFn ?? fetch;
652
+ const language = resolveLanguageCode(readVoiceLanguage(args.settings));
653
+ const keytermsContext = buildKeytermsContext(args.settings);
654
+ const transport = resolveVoiceTransport(voiceConfig.model);
655
+ switch (transport) {
656
+ case "qwen-asr-chat":
657
+ return transcribeViaQwenAsr(
658
+ audio,
659
+ voiceConfig,
660
+ { language, keytermsContext, abortSignal: args.abortSignal },
661
+ fetchFn
662
+ );
663
+ case "qwen-asr-realtime":
664
+ case "dashscope-task-realtime":
665
+ throw new Error(
666
+ `Voice model '${voiceConfig.model}' requires streaming transcription.`
667
+ );
668
+ case "unsupported":
669
+ default:
670
+ throw new Error(
671
+ `Voice model '${voiceConfig.model}' is not a supported transcription model.`
672
+ );
673
+ }
674
+ }
675
+ __name(transcribeVoiceAudio, "transcribeVoiceAudio");
676
+
677
+ export {
678
+ assertVoiceBaseUrlNetworkAllowed,
679
+ resolveVoiceTranscriptionConfig,
680
+ isStreamingVoiceModel,
681
+ resolveVoiceStreamConfig,
682
+ isKeytermEcho,
683
+ sanitizeVoiceErrorMessage,
684
+ transcribeVoiceAudio
685
+ };
686
+ /**
687
+ * @license
688
+ * Copyright 2025 Qwen
689
+ * SPDX-License-Identifier: Apache-2.0
690
+ */
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
  import {
4
4
  registerCleanup
5
- } from "./chunk-GYZQA2FO.js";
5
+ } from "./chunk-YLZJCUH6.js";
6
6
  import {
7
7
  init_esbuild_shims
8
8
  } from "./chunk-A4BMJM77.js";
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
  import {
4
4
  createDebugLogger
5
- } from "./chunk-C4K3FEQ2.js";
5
+ } from "./chunk-UX4SGCGN.js";
6
6
  import {
7
7
  init_esbuild_shims
8
8
  } from "./chunk-A4BMJM77.js";