gerege-cli 0.26.5 → 0.26.6

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 (237) hide show
  1. package/README.md +8 -8
  2. package/chunks/{MaxSizedBox-VMVLMS4X.js → MaxSizedBox-QCIXIS4P.js} +1 -1
  3. package/chunks/{StandaloneSessionPicker-UNORCVYY.js → StandaloneSessionPicker-BAFAIRT7.js} +1 -1
  4. package/chunks/{acp-subagent-executor-623ZUTJT.js → acp-subagent-executor-TPVXURLW.js} +1 -1
  5. package/chunks/{acpAgent-MTTDTK2C.js → acpAgent-67UN66PB.js} +3 -3
  6. package/chunks/{advisor-ANUGICJ5.js → advisor-SAXMI4QZ.js} +1 -1
  7. package/chunks/{agent-GNCQDICJ.js → agent-KV7BXY6C.js} +1 -1
  8. package/chunks/{agent-headless-OPUXAXQM.js → agent-headless-FQX3JGG6.js} +1 -1
  9. package/chunks/{agent-host-client-K6GRPTFD.js → agent-host-client-L5EHC4AC.js} +1 -1
  10. package/chunks/{agent-host-connections-MF3YBZU2.js → agent-host-connections-EDBMCVQF.js} +1 -1
  11. package/chunks/{anthropicContentGenerator-OK4PFE5Y.js → anthropicContentGenerator-V7TX2NXP.js} +1 -1
  12. package/chunks/{autofix-pr-MABTGEHZ.js → autofix-pr-WP34NYHL.js} +1 -1
  13. package/chunks/{batch-V2NJT3M5.js → batch-XFVQ4BLM.js} +1 -1
  14. package/chunks/{bridge-BJQ627CX.js → bridge-AE7AFEXB.js} +1 -1
  15. package/chunks/{channel-settings-store-4JMCI4UR.js → channel-settings-store-X63P5OVT.js} +1 -1
  16. package/chunks/{chunk-ZN57TOVA.js → chunk-2DU2WMTL.js} +1 -1
  17. package/chunks/{chunk-Z5XENA4A.js → chunk-2JGTWRZJ.js} +8 -7
  18. package/chunks/{chunk-MTW3A3KT.js → chunk-2LWJGXTW.js} +1 -1
  19. package/chunks/{chunk-OCBJCZC2.js → chunk-2N3NBTYJ.js} +1 -1
  20. package/chunks/{chunk-WI4UMN3Q.js → chunk-2TAJ5STJ.js} +1 -1
  21. package/chunks/{chunk-EIILQ6KT.js → chunk-32XHDDIA.js} +1 -1
  22. package/chunks/{chunk-FNXO5KWB.js → chunk-34HC2AXI.js} +2 -2
  23. package/chunks/{chunk-2X3UF2CF.js → chunk-3W32X2DH.js} +1 -1
  24. package/chunks/{chunk-CKZRJP4F.js → chunk-4ME3BUJK.js} +1 -1
  25. package/chunks/{chunk-NVSKOSFG.js → chunk-4NDJKNN6.js} +1 -1
  26. package/chunks/{chunk-BRPJ5EHA.js → chunk-5EXL4TKQ.js} +1 -1
  27. package/chunks/{chunk-3XBJYUWP.js → chunk-65ME4BOH.js} +1 -1
  28. package/chunks/{chunk-TQTIEK2W.js → chunk-7453BHJO.js} +1 -1
  29. package/chunks/{chunk-HSYBIGMS.js → chunk-76FSYQTG.js} +1 -1
  30. package/chunks/{chunk-FNB3DPQZ.js → chunk-7RNOS7R4.js} +1 -1
  31. package/chunks/{chunk-H57IX45A.js → chunk-AEKEZRIU.js} +1 -1
  32. package/chunks/{chunk-CXGGC4NO.js → chunk-AEZYXPFS.js} +1 -1
  33. package/chunks/{chunk-NGOIJH7K.js → chunk-AFO5ER23.js} +1 -1
  34. package/chunks/{chunk-UY2ET2AL.js → chunk-AYVCT5FF.js} +1 -1
  35. package/chunks/{chunk-QOYRDEXR.js → chunk-B37YY4XU.js} +1 -1
  36. package/chunks/{chunk-IDUGQMTP.js → chunk-BAUMVH4Q.js} +1 -1
  37. package/chunks/{chunk-CAPG7UVH.js → chunk-BCI62WSL.js} +1 -1
  38. package/chunks/{chunk-USJFJZ23.js → chunk-BGELKSQ4.js} +1 -1
  39. package/chunks/{chunk-6X73W4TL.js → chunk-BHIDG6VZ.js} +1 -1
  40. package/chunks/{chunk-26ISBUM7.js → chunk-BPFFRPWE.js} +6 -6
  41. package/chunks/{chunk-YGHM5CDT.js → chunk-BQZF3UKI.js} +1 -1
  42. package/chunks/{chunk-3NQESE5K.js → chunk-CBE6ZIHU.js} +1 -1
  43. package/chunks/{chunk-DEMXCA3K.js → chunk-CF6SZJNP.js} +1 -1
  44. package/chunks/{chunk-2VCDJ6UF.js → chunk-CGDFZEER.js} +1 -1
  45. package/chunks/{chunk-3WQPUP5U.js → chunk-CUP2TNJK.js} +1 -1
  46. package/chunks/{chunk-2IGE2K5V.js → chunk-DA6LOBSB.js} +1 -1
  47. package/chunks/{chunk-HFV6CQWE.js → chunk-EFIRES46.js} +1 -1
  48. package/chunks/{chunk-E5YRAQXM.js → chunk-EKRUF347.js} +1 -1
  49. package/chunks/{chunk-KN27BFXM.js → chunk-ELDZ4MNL.js} +1 -1
  50. package/chunks/{chunk-ADTFKUH2.js → chunk-ET5M5WFN.js} +1 -1
  51. package/chunks/{chunk-IBYFSHBB.js → chunk-EXIFPXMB.js} +1 -1
  52. package/chunks/{chunk-IA4K4PGK.js → chunk-EYPLBTMI.js} +1 -1
  53. package/chunks/{chunk-DTTC4ZKY.js → chunk-FEP6W4NJ.js} +1 -1
  54. package/chunks/{chunk-FHBGTZ4K.js → chunk-FKL3V5BO.js} +1 -1
  55. package/chunks/{chunk-Q5E5SOY2.js → chunk-FKZ46GKL.js} +1 -1
  56. package/chunks/{chunk-OPYGNTZP.js → chunk-FYBJGRX7.js} +1 -1
  57. package/chunks/{chunk-FPZPCZFS.js → chunk-G6DALGGS.js} +1 -1
  58. package/chunks/{chunk-3Y6LSWEW.js → chunk-GBSRWT7J.js} +1 -1
  59. package/chunks/{chunk-SMYBY353.js → chunk-GHIFIXNX.js} +1 -1
  60. package/chunks/{chunk-DE53B2R7.js → chunk-GRAECADD.js} +1 -1
  61. package/chunks/{chunk-UJYOILZR.js → chunk-GSPGIGO5.js} +3 -3
  62. package/chunks/{chunk-5UZT4SXG.js → chunk-H3IR3GIE.js} +1 -1
  63. package/chunks/{chunk-ADZI3OFT.js → chunk-HOG66S6K.js} +1 -1
  64. package/chunks/{chunk-WB34KMOT.js → chunk-HTAUIJB4.js} +1 -1
  65. package/chunks/{chunk-MPAR4JBP.js → chunk-I6PUY2T3.js} +1 -1
  66. package/chunks/{chunk-5ZQWQ3RK.js → chunk-IZ5MWA6E.js} +1 -1
  67. package/chunks/{chunk-7IERHQ63.js → chunk-JEDL4IKF.js} +1 -1
  68. package/chunks/{chunk-RVJJFDF3.js → chunk-JH3V5SPA.js} +1 -1
  69. package/chunks/{chunk-SELRSZFK.js → chunk-JRTOPEM3.js} +1 -1
  70. package/chunks/{chunk-SQQORHMS.js → chunk-JWNKPINR.js} +1 -1
  71. package/chunks/{chunk-55RVKT4O.js → chunk-KJGRCIVY.js} +1 -1
  72. package/chunks/{chunk-GSOBASYW.js → chunk-KZNYALFU.js} +1 -1
  73. package/chunks/{chunk-FDUXQAGW.js → chunk-LBLLWAKK.js} +1 -1
  74. package/chunks/{chunk-ZSVSRF4C.js → chunk-LT3J74BZ.js} +1 -1
  75. package/chunks/{chunk-AMTFJVDD.js → chunk-LTE4N6L3.js} +1 -1
  76. package/chunks/{chunk-F26LTWDZ.js → chunk-M6KB5RVD.js} +1 -1
  77. package/chunks/{chunk-2PY7R7GG.js → chunk-MGATL4OA.js} +1 -1
  78. package/chunks/{chunk-KGJ47CI5.js → chunk-MPVQDYPH.js} +1 -1
  79. package/chunks/{chunk-BBOJUFMW.js → chunk-MTDBCIDA.js} +1 -1
  80. package/chunks/{chunk-ZYTG6R7S.js → chunk-MYV7GY3H.js} +1 -1
  81. package/chunks/{chunk-4GC5HJZO.js → chunk-N7PWZBXV.js} +1 -1
  82. package/chunks/{chunk-2NOMOJWE.js → chunk-NA4ZF2FE.js} +2 -2
  83. package/chunks/{chunk-7MTBINFX.js → chunk-NEKPQLFY.js} +2 -2
  84. package/chunks/{chunk-ABJGFEES.js → chunk-NO7VTKRL.js} +1 -1
  85. package/chunks/{chunk-OHXQYU6S.js → chunk-NONBHCXP.js} +1 -1
  86. package/chunks/{chunk-ZOBX6C7E.js → chunk-NVOI6UDQ.js} +1 -1
  87. package/chunks/{chunk-YLAI26PX.js → chunk-OJ4K62S2.js} +1 -1
  88. package/chunks/{chunk-CCOUFBOY.js → chunk-OK7LBM5G.js} +1 -1
  89. package/chunks/{chunk-POA4NX4N.js → chunk-OOJ2AQT3.js} +1 -1
  90. package/chunks/{chunk-5WLKN3GD.js → chunk-OU7CEG7Q.js} +1 -1
  91. package/chunks/{chunk-4TYTJQWR.js → chunk-P3JEEDQZ.js} +1 -1
  92. package/chunks/{chunk-AQWHCRKY.js → chunk-P62S5JGM.js} +1 -1
  93. package/chunks/{chunk-B6D3KTUK.js → chunk-QDCUR3JB.js} +1 -1
  94. package/chunks/{chunk-XFLLE2J3.js → chunk-RSLTOIG5.js} +2 -2
  95. package/chunks/{chunk-ISGF3BVD.js → chunk-RXN7DUMP.js} +2 -2
  96. package/chunks/{chunk-PN62SUYK.js → chunk-SKGJ26HQ.js} +1 -1
  97. package/chunks/{chunk-62NLMVVT.js → chunk-SP6CQ3MO.js} +1 -1
  98. package/chunks/{chunk-4EQWJTJR.js → chunk-T2YTHAJW.js} +1 -1
  99. package/chunks/{chunk-NO26JN24.js → chunk-T53VMDXH.js} +1 -1
  100. package/chunks/{chunk-X4BFEDWU.js → chunk-T5DKF33F.js} +1 -1
  101. package/chunks/{chunk-KKBOCRPF.js → chunk-TB4AUC2L.js} +1 -1
  102. package/chunks/{chunk-Q6QS5JTK.js → chunk-U3Q72OGV.js} +1 -1
  103. package/chunks/{chunk-FLJLUMQF.js → chunk-UKLXKJKL.js} +1 -1
  104. package/chunks/{chunk-IH2PFVWO.js → chunk-VD2GSW64.js} +1 -1
  105. package/chunks/{chunk-VDRE7U3P.js → chunk-VRKYBH5G.js} +5 -5
  106. package/chunks/{chunk-MOPJNP5I.js → chunk-W2RQIZ6B.js} +1 -1
  107. package/chunks/{chunk-2LLPGSUK.js → chunk-W5Z4BWWA.js} +1 -1
  108. package/chunks/{chunk-CNFA5UUM.js → chunk-W66WWTOP.js} +1 -1
  109. package/chunks/{chunk-C56YJIEI.js → chunk-WGFX3EL3.js} +1 -1
  110. package/chunks/{chunk-6NI33TVK.js → chunk-X2TY7VTY.js} +1 -1
  111. package/chunks/{chunk-FIM7MM25.js → chunk-XISR37DQ.js} +1 -1
  112. package/chunks/{chunk-KDYUZBZC.js → chunk-YH2XRWRF.js} +1 -1
  113. package/chunks/{chunk-UBXLQ6TP.js → chunk-ZENMAISJ.js} +1 -1
  114. package/chunks/{codex-subagent-executor-EK3A2WBH.js → codex-subagent-executor-OLMGVPVS.js} +1 -1
  115. package/chunks/{config-utils-DLOK7OLM.js → config-utils-OWY5G5Y2.js} +1 -1
  116. package/chunks/{contextCommand-AVCUCHQC.js → contextCommand-IXFUZH65.js} +1 -1
  117. package/chunks/{core-runtime-QSS4ZTG6.js → core-runtime-O4LC4NY3.js} +1 -1
  118. package/chunks/{create-sub-session-PNF7QDKC.js → create-sub-session-6F7C3TMT.js} +1 -1
  119. package/chunks/{cron-create-C6JOFIU4.js → cron-create-2422NBSJ.js} +1 -1
  120. package/chunks/{daemon-git-worktree-guard-5XZAZ7D2.js → daemon-git-worktree-guard-EWPQA6NO.js} +1 -1
  121. package/chunks/{daemon-status-provider-MRNELSNJ.js → daemon-status-provider-FAHOXNFW.js} +1 -1
  122. package/chunks/{daemon-trust-policy-26CMW3WY.js → daemon-trust-policy-L3DM6AI5.js} +1 -1
  123. package/chunks/{daemon-trust-policy-monitor-3DWO6NQY.js → daemon-trust-policy-monitor-HNPY5KJ4.js} +1 -1
  124. package/chunks/{deferred-core-runtime-DEC3N46T.js → deferred-core-runtime-JF42NQJK.js} +1 -1
  125. package/chunks/{edit-3HMQPCHN.js → edit-E5LEI2LL.js} +1 -1
  126. package/chunks/{enterPlanMode-QHJF4JXZ.js → enterPlanMode-3COTUV5V.js} +1 -1
  127. package/chunks/{environment-NGIBJWOT.js → environment-XBBIB3VA.js} +1 -1
  128. package/chunks/{errors-MSTGCVGJ.js → errors-LNMQ7TUK.js} +1 -1
  129. package/chunks/{execution-tool-VR4TGOI4.js → execution-tool-QDDKJD2K.js} +1 -1
  130. package/chunks/{execution-worker-EJH7HIE2.js → execution-worker-TXGZRZXE.js} +1 -1
  131. package/chunks/{exitPlanMode-P25OHQJ6.js → exitPlanMode-Z7QEMWPE.js} +1 -1
  132. package/chunks/{fast-path-II433ZDP.js → fast-path-M6K2RACY.js} +1 -1
  133. package/chunks/{glob-4Q6DCT3F.js → glob-N2QT4U7U.js} +1 -1
  134. package/chunks/{goal-tools-FFMAJW6V.js → goal-tools-CUSQD3DG.js} +1 -1
  135. package/chunks/{handleAutoUpdate-QNM26NZK.js → handleAutoUpdate-QF2YQHF6.js} +1 -1
  136. package/chunks/{i18n-L5URVOBB.js → i18n-AGOA6MUI.js} +1 -1
  137. package/chunks/{initializer-NQ2NECYP.js → initializer-FRKYDUSX.js} +1 -1
  138. package/chunks/{installationInfo-BCTXASUM.js → installationInfo-OKA4WXAS.js} +1 -1
  139. package/chunks/{interactive-mod-session-PPTBI37E.js → interactive-mod-session-MWYN5IFK.js} +1 -1
  140. package/chunks/{list-7TE5TUZJ.js → list-DE7VUIR2.js} +1 -1
  141. package/chunks/{llm-BWWKUBBZ.js → llm-N3JGJHYC.js} +4 -4
  142. package/chunks/{llm-content-generator-QOTGPBYC.js → llm-content-generator-VMUBA7OJ.js} +1 -1
  143. package/chunks/{loadedSettingsAdapter-THAGI5M2.js → loadedSettingsAdapter-5C36OZ7N.js} +1 -1
  144. package/chunks/{local-7BTAGV4J.js → local-BE624O3A.js} +1 -1
  145. package/chunks/{local-execution-environment-S3OR4KSC.js → local-execution-environment-OPGM7Y6L.js} +1 -1
  146. package/chunks/{loggingContentGenerator-AXJ5E5RS.js → loggingContentGenerator-2MHAI6JR.js} +1 -1
  147. package/chunks/{loop-wakeup-AJTLMLRX.js → loop-wakeup-BDLATBXH.js} +1 -1
  148. package/chunks/{manage-memory-JHTUVMDJ.js → manage-memory-BBCEIIWB.js} +1 -1
  149. package/chunks/{managed-execution-engine-U6GNJ4U4.js → managed-execution-engine-SRFALTCX.js} +1 -1
  150. package/chunks/{managed-local-serve-P4ZXVRBU.js → managed-local-serve-ICNAS3E6.js} +1 -1
  151. package/chunks/{managed-npm-update-UDUILNR5.js → managed-npm-update-CTL6LH5Z.js} +1 -1
  152. package/chunks/{managed-runtime-attestation-worker-P34ZBNRG.js → managed-runtime-attestation-worker-ZRDWKXCI.js} +1 -1
  153. package/chunks/{managed-runtime-bootstrap-CLMYNPH5.js → managed-runtime-bootstrap-6NTGZXQL.js} +1 -1
  154. package/chunks/{managed-runtime-session-worker-7H7AZJBV.js → managed-runtime-session-worker-RKQBBFR6.js} +1 -1
  155. package/chunks/{managed-runtime-ssh-worker-5KEMC7FD.js → managed-runtime-ssh-worker-FCGV6FSW.js} +1 -1
  156. package/chunks/{managed-session-authority-CFUZ45HT.js → managed-session-authority-C7IW6TJX.js} +1 -1
  157. package/chunks/{mcp-YMG4RVMC.js → mcp-VC4CJPE5.js} +1 -1
  158. package/chunks/{memory-7STURUXK.js → memory-S6OJA3ZD.js} +1 -1
  159. package/chunks/mn-JMS6SWTO.js +8 -0
  160. package/chunks/{model-call-collection-WBWTO3EG.js → model-call-collection-MJZWRQSU.js} +1 -1
  161. package/chunks/{model-configuration-6KCZZSZD.js → model-configuration-SKU6L3QI.js} +1 -1
  162. package/chunks/{modelConfigUtils-Z2EKFSPN.js → modelConfigUtils-TJCB6NXT.js} +1 -1
  163. package/chunks/{monitor-U5E33JO6.js → monitor-M3PNLCYP.js} +1 -1
  164. package/chunks/{nonInteractiveCli-BVCL5I5R.js → nonInteractiveCli-MR7JLAWU.js} +1 -1
  165. package/chunks/{nonInteractiveToolExecutor-B4EUOMYF.js → nonInteractiveToolExecutor-YKA6JMTY.js} +1 -1
  166. package/chunks/{notebook-edit-MXKD5J2C.js → notebook-edit-ENTFB5D7.js} +1 -1
  167. package/chunks/{omni-I5YECZBW.js → omni-6YBX4R6K.js} +1 -1
  168. package/chunks/{openaiContentGenerator-Q5SINFJJ.js → openaiContentGenerator-XRXX33FY.js} +1 -1
  169. package/chunks/{openaiResponsesContentGenerator-R3XCZLZY.js → openaiResponsesContentGenerator-L6ONEHMR.js} +1 -1
  170. package/chunks/{pidfile-UOGUNUTK.js → pidfile-XR4JF2Z6.js} +1 -1
  171. package/chunks/{processUtils-QGQGZHBA.js → processUtils-GQYNJRBJ.js} +1 -1
  172. package/chunks/{prompt-terminal-ledger-L57JMVSR.js → prompt-terminal-ledger-7BM7YDLG.js} +1 -1
  173. package/chunks/{qwenContentGenerator-UKZ237LC.js → qwenContentGenerator-QSA32XEL.js} +1 -1
  174. package/chunks/{reactive-degrade-3OM3HWVA.js → reactive-degrade-TFNBAAPZ.js} +1 -1
  175. package/chunks/{read-file-63ZLWMOW.js → read-file-VD7OFO2E.js} +1 -1
  176. package/chunks/{resumeHistoryUtils-R5YQS4YQ.js → resumeHistoryUtils-2B4KPI7G.js} +1 -1
  177. package/chunks/{review-AT6OWVDO.js → review-C365WGCW.js} +1 -1
  178. package/chunks/{ripGrep-7KBZGTPV.js → ripGrep-D7WPMBXR.js} +1 -1
  179. package/chunks/{run-qwen-serve-CLBG7W6F.js → run-qwen-serve-NZWQHWQA.js} +1 -1
  180. package/chunks/{runtime-R3QIGB7U.js → runtime-J6SPBSCS.js} +1 -1
  181. package/chunks/{sandboxConfig-PM3ZRQYV.js → sandboxConfig-QS2XBPZG.js} +1 -1
  182. package/chunks/{scheduled-tasks-PUMNN5XV.js → scheduled-tasks-YNNIOOPM.js} +1 -1
  183. package/chunks/{scheduler-KTPM226B.js → scheduler-KCMSPHON.js} +1 -1
  184. package/chunks/{search-memory-7I5MGDNV.js → search-memory-EUBJ7IAV.js} +1 -1
  185. package/chunks/{send-message-J526AEBI.js → send-message-CWWZUPSK.js} +1 -1
  186. package/chunks/{serve-KLTMPK4W.js → serve-4CB4BWJ5.js} +1 -1
  187. package/chunks/{server-VLRNY6KG.js → server-JNANUIGC.js} +3 -3
  188. package/chunks/{session-2EB57NXY.js → session-3LQLXPUA.js} +1 -1
  189. package/chunks/{session-attachments-root-I7TESMWL.js → session-attachments-root-BWIVWFHJ.js} +1 -1
  190. package/chunks/{session-execution-engine-selector-5FAMSPSO.js → session-execution-engine-selector-5OLRX57L.js} +1 -1
  191. package/chunks/{session-pr-refresh-JCPVQPNJ.js → session-pr-refresh-RLF3EXS3.js} +1 -1
  192. package/chunks/{sessionService-YRW2IFPR.js → sessionService-U7ACD2HP.js} +1 -1
  193. package/chunks/{settings-KO2Q47JP.js → settings-FTGWYTUH.js} +1 -1
  194. package/chunks/{shell-OLZVNTQZ.js → shell-E4RENYQC.js} +1 -1
  195. package/chunks/{skill-XW2AQS7M.js → skill-OLNPHRWB.js} +1 -1
  196. package/chunks/{skill-settings-TKAVQ4XP.js → skill-settings-R2BV2GEK.js} +1 -1
  197. package/chunks/{spawnChannel-MBGCTK2J.js → spawnChannel-LOPAR5T2.js} +1 -1
  198. package/chunks/{standalone-update-A3YLLIAN.js → standalone-update-IGDX2RGN.js} +1 -1
  199. package/chunks/{start-opentui-ui-G5ROAR4V.js → start-opentui-ui-33QLBNRC.js} +1 -1
  200. package/chunks/{startInteractiveUI-PZQR4U53.js → startInteractiveUI-RQKHD7MM.js} +1 -1
  201. package/chunks/{team-create-S5ZY2UMF.js → team-create-HAVKHNU5.js} +1 -1
  202. package/chunks/{team-plan-approval-KX6RXEST.js → team-plan-approval-7MCQX67C.js} +1 -1
  203. package/chunks/{terminal-image-renderer-SCJREXE6.js → terminal-image-renderer-XT5JVEO6.js} +1 -1
  204. package/chunks/{theme-manager-DZSM4EBR.js → theme-manager-DR5EYGLT.js} +1 -1
  205. package/chunks/{tool-call-UK56SWCT.js → tool-call-LZHZ5RVH.js} +1 -1
  206. package/chunks/{tool-result-media-JLLSLGFL.js → tool-result-media-XCXCF4YC.js} +1 -1
  207. package/chunks/{tool-search-OWPFLVV5.js → tool-search-K6S3ON7M.js} +1 -1
  208. package/chunks/{total-session-admission-NQU4ACKH.js → total-session-admission-LGSS2VWS.js} +1 -1
  209. package/chunks/{trustedFolders-N7GXFYSF.js → trustedFolders-IIR2UZRL.js} +1 -1
  210. package/chunks/{update-relaunch-5SPXXHM2.js → update-relaunch-WVIFX5CN.js} +1 -1
  211. package/chunks/{updateCheck-VXUIX2XG.js → updateCheck-CMEWLLZJ.js} +1 -1
  212. package/chunks/{upload-config-OWLL4SRQ.js → upload-config-TCCFCNCD.js} +1 -1
  213. package/chunks/{useAutoAcceptIndicator-OUYRR56F.js → useAutoAcceptIndicator-5RTTH3OW.js} +1 -1
  214. package/chunks/{validateNonInterActiveAuth-PSVJO5HK.js → validateNonInterActiveAuth-AO336KDX.js} +1 -1
  215. package/chunks/{version-C26S7UAW.js → version-JYWKKMNP.js} +1 -1
  216. package/chunks/{web-fetch-AYOYV7R4.js → web-fetch-HWTAWXFM.js} +1 -1
  217. package/chunks/{web-search-DAREKD3Z.js → web-search-HAI5LW3G.js} +1 -1
  218. package/chunks/{workflow-WBGPKVO6.js → workflow-BZ2YFGF6.js} +1 -1
  219. package/chunks/{workflow-ancestor-trust-GEEB53TB.js → workflow-ancestor-trust-26TFXFPO.js} +1 -1
  220. package/chunks/{workspace-agents-IMAQME4W.js → workspace-agents-DLI4JQJZ.js} +1 -1
  221. package/chunks/{workspace-providers-status-VALHVEU2.js → workspace-providers-status-64C7DJZU.js} +1 -1
  222. package/chunks/{workspace-recovery-worker-AIAVRDGU.js → workspace-recovery-worker-IFRT3KKP.js} +1 -1
  223. package/chunks/{workspace-registration-store-FXEGZG3L.js → workspace-registration-store-MYKJM2SK.js} +1 -1
  224. package/chunks/{workspace-registry-GYFFHWCD.js → workspace-registry-GZJRONAY.js} +1 -1
  225. package/chunks/{workspace-runtime-coordinator-VZ462TLU.js → workspace-runtime-coordinator-44KW6HSN.js} +1 -1
  226. package/chunks/{workspace-service-5DIZM4IZ.js → workspace-service-YHTSZYYD.js} +1 -1
  227. package/chunks/{workspace-skills-status-DOOBVL5N.js → workspace-skills-status-NEB62X24.js} +1 -1
  228. package/chunks/{workspace-trust-reconciler-LOICVUVW.js → workspace-trust-reconciler-HZLOOZWM.js} +1 -1
  229. package/chunks/{write-file-EJNMAHQD.js → write-file-HD5LHXGL.js} +1 -1
  230. package/chunks/{zoom-image-S3OARMYP.js → zoom-image-W4BMRC5T.js} +1 -1
  231. package/cli.js +2 -2
  232. package/execution-worker.js +1 -1
  233. package/export-transcript-document.js +1 -1
  234. package/gerege.mjs +53 -15
  235. package/locales/mn.js +2702 -3774
  236. package/package.json +3 -3
  237. package/chunks/mn-YH2OTBWJ.js +0 -8
@@ -1,7 +1,7 @@
1
1
  // Force strict mode and setup for ESM
2
2
  "use strict";
3
- import{HEADLESS_YOLO_NO_SANDBOX_WARNING}from"./chunk-Z57KDB5F.js";import{DEFAULT_RING_SIZE}from"./chunk-BWQ5AIEA.js";import{DEFAULT_COMPACTED_REPLAY_MAX_BYTES,DEFAULT_MAX_JOURNAL_BYTES,DEFAULT_MAX_JOURNAL_EVENTS,JOURNAL_GROWTH_HARD_CAP_BYTES}from"./chunk-WDR5XP3Y.js";import{JOURNAL_GROWTH_POOL_FRACTION,MAX_JOURNAL_GROWTH_POOL_MB,MIN_MEMORY_BUDGET_MB,isValidMemoryBudgetMb,memoryBudgetRangeError}from"./chunk-2QYDBHYZ.js";import{normalizeServeChannelSelection}from"./chunk-KOJ7WZ63.js";import{EXTERNAL_TOOL_GUARD_TOKEN_ENV}from"./chunk-NIEO2TBE.js";import{loadSettings}from"./chunk-WI4UMN3Q.js";import{MCP_BUDGET_WARN_FRACTION}from"./chunk-Z5XENA4A.js";import{parsePositiveIntegerEnv}from"./chunk-BG67XABA.js";import{openBrowserSecurely,shouldLaunchBrowser}from"./chunk-3YWXKSOI.js";import{MEMORY_PROJECT_SCOPES}from"./chunk-PWOQASXT.js";import{writeStderrLine,writeStdoutLine}from"./chunk-M4ECEHLX.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();init_esbuild_shims();var SEGMENT=/^[A-Za-z0-9_-]{1,256}$/;function parseJoinLink(link){let url;try{url=new URL(link.trim())}catch{throw new Error("--join expects the link shown by the coordinator.")}const marker=url.pathname.lastIndexOf("/join/");const[workspaceId,...rest]=marker>=0?url.pathname.slice(marker+"/join/".length).split("/"):[];if(url.protocol!=="http:"&&url.protocol!=="https:"||url.username||url.password||url.search||url.hash||!workspaceId||rest.some(Boolean)||!SEGMENT.test(workspaceId)){throw new Error("--join expects a link like https://host:4170/join/<workspace>.")}const base=url.pathname.slice(0,marker).replace(/\/+$/,"");return{serverUrl:`${url.origin}${base}`,workspaceId}}__name(parseJoinLink,"parseJoinLink");function blockForever(){return new Promise(()=>{})}__name(blockForever,"blockForever");var DEFAULT_SERVE_HOSTNAME="127.0.0.1";function validateManagedLocalFlags(args){const supported=new Set(["--managed","--managed-data-dir","--port","--hostname","--open","--no-open","--open-with-auth","--no-open-with-auth","--web","--require-auth","--http-bridge"]);const unsupported=args.find(arg=>arg.startsWith("--")&&!supported.has(arg.split("=")[0]));if(unsupported){throw new Error(`${unsupported.split("=")[0]} is not supported with --managed. Use --port, --managed-data-dir, and --open.`)}}__name(validateManagedLocalFlags,"validateManagedLocalFlags");function validateManagedWebFlags(args){const supported=new Set(["--managed-web-config","--hostname","--port","--allow-origin","--token","--require-auth"]);const unsupported=args.find(arg=>arg.startsWith("--")&&!supported.has(arg.split("=")[0]));if(unsupported){throw new Error(`${unsupported.split("=")[0]} is not supported with --managed-web-config. Only hostname, port, allow-origin and browser authentication options are supported.`)}}__name(validateManagedWebFlags,"validateManagedWebFlags");async function startLocalControl(handle,address){await handle.runtimeReady;if(!handle.webShellMounted){throw new Error("Local Control requires the Web Shell.")}const service=handle.getLocalControl();if(!service){throw new Error("Local Control is unavailable on this daemon.")}let status;try{status=await service.enable(address?{address}:{})}catch(err){if(err instanceof Error&&err.code==="ambiguous_lan_interface"){throw new Error(`${err.message}. Pass --local-control-address <ip>.`)}throw err}if(!status.url){throw new Error("Local Control did not return a pairing URL.")}const{default:qrcode}=await import("./main-5IVKRF6Q.js");qrcode.setErrorLevel("Q");writeStdoutLine("\nLocal Control is on. Scan this QR code from the same network:");writeStdoutLine(`
4
- ${status.interfaceName}: ${status.url}`);qrcode.generate(status.url,{small:true},code=>{writeStdoutLine(code.trimEnd())});writeStdoutLine("\nKeep this terminal open. "+(status.sleepInhibited?"Sleep is inhibited while this session is active. ":"Sleep inhibition is unavailable here, so the host may sleep. ")+(status.encrypted?"Traffic is encrypted.":"Traffic is unencrypted \u2014 use it only on a network you trust.")+" Turn Local Control off from the Web Shell Settings card, or press Ctrl+C to exit the daemon.")}__name(startLocalControl,"startLocalControl");async function maybeOpenWebShellBrowser(handle,open,manualFallbackWhenIneligible=false){if(!open||!handle.webShellMounted)return;const shouldLaunch=shouldLaunchBrowser();if(!shouldLaunch&&!manualFallbackWhenIneligible)return;try{await handle.runtimeReady}catch(runtimeErr){writeStderrLine(`qwen serve: Web Shell runtime not ready; skipping --open: ${runtimeErr instanceof Error?runtimeErr.message:String(runtimeErr)}`);return}let target;try{target=new URL(handle.url);if(target.hostname==="0.0.0.0"||target.hostname==="[::]"){target.hostname="127.0.0.1"}if(handle.resolvedToken){target.hash=`token=${encodeURIComponent(handle.resolvedToken)}`}if(!shouldLaunch){writeStderrLine(`Browser launch is not available in this environment. Please open this URL manually: ${target.toString()}`);return}if(handle.resolvedToken){writeStderrLine("qwen serve: --open passes the token in the browser launch command (visible via `ps` / /proc); on a multi-user host open the URL manually instead.")}await openBrowserSecurely(target.toString())}catch(browserErr){const manualUrl=manualFallbackWhenIneligible&&target?`. Please open this URL manually: ${target.toString()}`:"";writeStderrLine(`qwen serve: failed to open browser: ${browserErr instanceof Error?browserErr.message:String(browserErr)}${manualUrl}`)}}__name(maybeOpenWebShellBrowser,"maybeOpenWebShellBrowser");function primaryWorkspaceArg(workspace){return Array.isArray(workspace)?workspace[0]:workspace}__name(primaryWorkspaceArg,"primaryWorkspaceArg");var serveCommand={command:"serve",describe:"Run Qwen Code as a local HTTP daemon (Stage 1 experimental: --http-bridge)",builder:__name(yargs=>yargs.option("port",{type:"number",default:4170,description:"TCP port to bind (use 0 for an OS-assigned ephemeral port)"}).option("hostname",{type:"string",default:DEFAULT_SERVE_HOSTNAME,description:"Interface to bind. Loopback (127.0.0.0/8, localhost, ::1, [::1]) is auth-free; anything else requires a token (one is generated and printed when neither --token nor QWEN_SERVER_TOKEN supplies one). A localhost bind that resolves off-loopback never generates, and still refuses when no token source resolved; an empty value is rejected as operator error."}).option("profile",{choices:["default","hosted-harness"],default:"default",description:"Deployment profile. hosted-harness enables the private no-tool Managed Session API on loopback."}).option("hosted-harness-capability-digest",{type:"string",description:"SHA-256 capability digest for the private Hosted Harness profile. Falls back to QWEN_HOSTED_HARNESS_CAPABILITY_DIGEST."}).option("managed",{type:"boolean",default:false,description:"Start the daemon and Managed Agent with shared WebShell and embedded storage; downloads the server on first use and requires Java 21."}).option("managed-data-dir",{type:"string",requiresArg:true,description:"Private persistent data directory for --managed; defaults to <Qwen home>/managed-local."}).option("managed-web-config",{type:"string",requiresArg:true,description:"Run only the authenticated Managed Web gateway using a JSON file with apiUrl, tenantId, actorId and signingKeyFile. Requires an independent browser token of at least 32 bytes via QWEN_SERVER_TOKEN or --token."}).option("token",{type:"string",description:"Bearer token required on every request. Falls back to the QWEN_SERVER_TOKEN env var; a non-loopback bind with neither generates an ephemeral token at startup, while loopback keeps the trusted tokenless mode unless --require-auth is set."}).option("max-sessions",{type:"number",description:"Cap on concurrent live sessions. New spawn requests beyond this return 503; attach to existing sessions still works. Set to 0 to disable. Defaults to 32, or to the serve.maxSessions setting (user, system, and system-defaults scopes only); the flag wins when passed."}).option("max-total-sessions",{type:"number",description:"Non-negative integer cap on concurrent live sessions across all workspace runtimes. Set to 0 to disable."}).option("max-pending-prompts-per-session",{type:"number",default:5,description:"Per-session cap on accepted prompts waiting or running. New prompts beyond this return 503. Set to 0 to disable."}).option("workspace",{type:"string",array:true,requiresArg:true,description:"Absolute workspace path to register with this daemon. POST /session requests with a mismatched cwd return 400 workspace_mismatch. Defaults to process.cwd() when omitted. Repeat to register isolated workspace runtimes; the first is primary."}).option("memory-project-scope",{type:"string",choices:MEMORY_PROJECT_SCOPES,description:'Choose how project memory is partitioned. Defaults to "workspace" so each daemon workspace stays isolated; "git-root" preserves the legacy shared scope. Overrides QWEN_CODE_MEMORY_PROJECT_SCOPE when provided.'}).option("max-connections",{type:"number",default:256,description:"Listener-level TCP connection cap (server.maxConnections). Bounds raw sockets \u2014 slow/phantom SSE clients get rejected at accept time once full. Set to 0 to disable."}).option("require-auth",{type:"boolean",default:false,description:"Refuse to start without a bearer token, even on loopback. Hardens the loopback developer default for shared dev hosts / CI runners / multi-tenant workstations where any local user can hit 127.0.0.1. Requires --token, QWEN_SERVER_TOKEN, or --open-with-auth (which installs its own generated loopback token); on non-loopback binds the generated ephemeral token also satisfies it, so the no-configured-secret fail-fast is loopback-only. /health also requires Authorization when enabled (no loopback exemption \u2014 k8s/Compose probes must pass the bearer too)."}).option("enable-session-shell",{type:"boolean",default:false,description:"Enable direct POST /session/:id/shell execution. Available with bearer auth or trusted loopback; each call still requires a session-bound client id."}).option("tls-cert",{type:"string",description:"Path to a PEM certificate file. Serve over HTTPS instead of HTTP. Required for secure-context browser APIs (voice input/getUserMedia, WebRTC) when accessed over a LAN IP. Must be used together with --tls-key. Generate a local cert with mkcert."}).option("tls-key",{type:"string",description:"Path to a PEM private key file. Must be used together with --tls-cert."}).option("experimental-lsp",{type:"boolean",default:false,description:"Forward the experimental LSP opt-in to spawned agent sessions."}).option("restore-ask-user-question",{type:"boolean",default:false,description:"On session load/resume, re-hang a trailing unanswered ask_user_question instead of synthesizing a failed tool result."}).option("channel",{type:"string",array:true,description:"Experimental: start a daemon-managed channel worker for the named channel. Repeat to select multiple channels, or use --channel all."}).option("web",{type:"boolean",default:true,description:"Serve the Web Shell UI at the daemon root path. Use --no-web for an API-only daemon."}).option("open",{type:"boolean",default:false,description:"Open the Web Shell in a browser once the daemon is listening. With a token configured, the launch URL (token included) is handed to the browser launcher and is visible in the process list, so prefer opening the URL manually on multi-user hosts. No-op with --no-web, when the UI assets are absent, or in headless/CI/SSH environments."}).option("open-with-auth",{type:"boolean",default:false,description:"Open the Web Shell with bearer authentication on loopback. Reuse --token or QWEN_SERVER_TOKEN, or generate a temporary 256-bit token and deliver it in the URL fragment. In headless environments, print the fragment URL for manual opening."}).option("token-qr",{type:"boolean",description:"Print the token-bearing QR even when stdout is captured (not an interactive terminal) and the bearer is an operator-supplied (stable) token, which is withheld by default to keep stable credentials out of collected logs. Enable only when the log pipeline is as trusted as the daemon host. Can also be set via the serve.tokenQr setting (user, system, and system-defaults scopes only); the flag wins when passed. --no-token-qr suppresses the startup quickstart token QR for that run on every quickstart path \u2014 interactive terminal and generated token included. It does not govern the Local Control pairing QR, which --local-control prints by design."}).option("local-control",{type:"boolean",default:false,description:"Share the Web Shell on the local IPv4 network with its own revocable pairing token, terminal QR code, and best-effort sleep inhibition. Ctrl+C turns it off by ending the whole daemon; the Web Shell Settings card turns it off while the daemon keeps running."}).option("local-control-address",{type:"string",description:"Which local IPv4 address to share when the host is on more than one network. Only needed if --local-control reports an ambiguous choice."}).option("join",{type:"string",description:"Join another Qwen Code as a runtime, with the one-line link it shows under Agent \u2192 Runtime \u2192 Add runtime."}).option("agent-host-server",{type:"string",description:"Register this daemon as an Agent Host with a primary Qwen daemon."}).option("agent-host-workspace-id",{type:"string",description:"Control-plane workspace id printed by the primary daemon."}).option("agent-host-name",{type:"string",description:"Display name advertised for this Agent Host."}).option("agent-host-allow-http",{type:"boolean",default:false,description:"Allow unencrypted Agent Host HTTP connections outside loopback (trusted demo networks only)."}).check(argv=>{if(argv["local-control"]===true&&argv["web"]===false){throw new Error("Local Control requires the Web Shell.")}if(argv["local-control"]===true&&argv.hostname!==DEFAULT_SERVE_HOSTNAME){throw new Error(`Local Control requires --hostname ${DEFAULT_SERVE_HOSTNAME}.`)}if(argv["local-control"]!==true&&argv["local-control-address"]!==void 0){throw new Error("--local-control-address requires --local-control.")}if(argv["local-control-address"]===""){throw new Error("--local-control-address must not be empty.")}if(Boolean(argv["agent-host-server"])!==Boolean(argv["agent-host-workspace-id"])){throw new Error("--agent-host-server and --agent-host-workspace-id must be used together.")}if(argv["agent-host-name"]===""){throw new Error("--agent-host-name must not be empty.")}if(argv["join"]!==void 0){if(argv["agent-host-server"]||argv["agent-host-workspace-id"]){throw new Error("--join already names the coordinator and workspace; drop --agent-host-server and --agent-host-workspace-id.")}parseJoinLink(argv["join"])}return true}).option("event-ring-size",{type:"number",default:DEFAULT_RING_SIZE,description:"Per-session SSE replay ring depth. Sets the replay backlog available to `GET /session/:id/events` reconnects that send a `Last-Event-ID: N` header. Larger = more reconnect headroom at the cost of a few hundred KB extra RAM per session. Must be a positive finite integer."}).option("compacted-replay-max-bytes",{type:"number",default:DEFAULT_COMPACTED_REPLAY_MAX_BYTES,description:"Per-session in-memory compacted replay snapshot byte cap for `POST /session/:id/load` late attaches. Larger = more recent history in load snapshots at higher heap cost. Must be a positive safe integer no larger than 256 MiB."}).option("max-journal-events",{type:"number",nargs:1,description:"Per-session baseline cap on replay entries retained in the in-flight live journal (current unfinished turn). Compatible text/thought chunks share bounded entries. When exceeded, the daemon first tries adaptive growth (see --max-journal-bytes); without granted headroom the oldest entries are dropped. Pinning this flag (or --max-journal-bytes) disables adaptive growth. Defaults to "+DEFAULT_MAX_JOURNAL_EVENTS+" when unset. Must be a positive safe integer."}).option("max-journal-bytes",{type:"number",nargs:1,description:"Per-session baseline source-event byte cap on the in-flight live journal. When a turn outgrows it, adaptive growth raises the session's caps (per-session hard cap "+JOURNAL_GROWTH_HARD_CAP_BYTES/(1024*1024)+" MiB) within a growth pool derived from the daemon memory budget (see --memory-budget-mb); without granted headroom the oldest entries are dropped whole (at least one is always kept), so the retained tail can be much smaller than the cap. Pinning this flag (or --max-journal-events) disables adaptive growth. Defaults to "+DEFAULT_MAX_JOURNAL_BYTES+" bytes when unset. Must be a positive safe integer."}).option("http-bridge",{type:"boolean",default:true,description:"HTTP bridge mode: attempt to preheat the primary `qwen --acp` child; trusted secondaries start one on demand. Stage 2 native in-process mode is not yet implemented; this flag will become opt-in then."}).option("memory-budget-mb",{type:"number",description:"Total memory budget in MB for the daemon process tree. When unset, derived as 50% of cgroup-constrained or host memory, and capped at the resolved available memory either way. In `admit` and `enforce` modes it determines managed ACP child capacity; `enforce` also applies the modeled per-child old-space ceiling. It also sizes one daemon-wide pool of "+JOURNAL_GROWTH_POOL_FRACTION*100+"% of the effective budget (capped at "+MAX_JOURNAL_GROWTH_POOL_MB+" MB; 0, growth disabled, when the effective budget falls below the "+MIN_MEMORY_BUDGET_MB+" MB minimum; see --max-journal-bytes). Reported under `limits.memory` in daemon status, alongside a modeled per-child partition under `limits.memory.childHeap`. Must be an integer in [1024, 1048576]."}).option("memory-pressure-mode",{choices:["off","observe"],default:"observe",description:"Whether the daemon derives a memory-pressure level from its own RSS and V8 heap. `observe` (default) reports the level in daemon status and raises a status issue when it leaves normal. `off` still reports the underlying figures but raises no issue, so the overall status rollup is unchanged \u2014 use it while calibrating, or if you alert on the top-level status. Nothing remediates in either mode."}).option("child-heap-mode",{choices:["off","observe","admit","enforce"],default:"observe",description:"Whether the daemon models a per-child heap partition of the memory budget. `observe` (default) reports the partition it would apply \u2014 `limits.memory.childHeap.perChildCeilingMb` and `maxConcurrentChildren` \u2014 and counts spawns that would have exceeded it. Nothing is applied: no child is sized from the budget and no spawn is refused. `off` models nothing. Note a refusal count of 0 does NOT mean the partition would be safe to apply; children still run on the much larger host-derived ceiling, so a workload needing more old space than the modeled ceiling looks healthy here. `admit` rejects starts past the modeled process limit but keeps the existing child heap arguments. Experimental `enforce` also applies the fixed modeled old-space ceiling to each managed child; it does not cap total process RSS."}).option("mcp-client-budget",{type:"number",description:"Cap on live MCP clients spawned inside the ACP child for the bound workspace. Positive integer. Combine with --mcp-budget-mode to control behavior at the cap. When unset, mode defaults to off (no accounting-driven enforcement, but GET /workspace/mcp still reports `clientCount`). Distinct from claude-code MCP_SERVER_CONNECTION_BATCH_SIZE which gates startup concurrency, not the total client count."}).option("mcp-budget-mode",{choices:["enforce","warn","off"],description:'How --mcp-client-budget is enforced. `warn` (default when budget set): no refusal, snapshot surfaces warning at >=75% of budget. `enforce`: connects past the cap are refused (`disabledReason: "budget"`, deterministic by mcpServers declaration order). `off`: pure observability. Boot rejects `enforce` without a budget.'}).option("allow-origin",{type:"string",array:true,description:"Cross-origin allowlist for browser clients. Accepts `*`, a canonical origin, or a loopback port wildcard like `http://127.0.0.1:*` (requires a bearer token)."}).option("allow-private-auth-base-url",{type:"boolean",default:false,description:"Allow /workspace/auth/provider to install localhost/private-network baseUrl values. Use only for local development with trusted clients."}).option("prompt-deadline-ms",{type:"number",description:"Server-side wallclock cap on POST /session/:id/prompt (ms). Falls back to QWEN_SERVE_PROMPT_DEADLINE_MS. Positive integer."}).option("experimental-paired-engines",{type:"boolean",default:false,description:"Experimental: build workspace runtimes, other than the private Conversations one, with paired Legacy and Managed engines. No Managed engine is available yet, so sessions run on Legacy with a durable owner."}).option("experimental-managed-agents",{type:"boolean",default:false,description:"Reserved experimental mode; not implemented and rejects startup."}).option("experimental-managed-runtime-worker",{type:"boolean",default:false,description:"Reserved experimental mode; not implemented and rejects startup."}).option("experimental-managed-runtime-auto-local",{type:"boolean",default:false,description:"Reserved experimental mode; not implemented and rejects startup."}).option("experimental-managed-runtime-url",{type:"string",requiresArg:true,description:"Reserved experimental Runtime URL; not implemented and rejects startup."}).option("experimental-managed-runtime-token",{type:"string",requiresArg:true,description:"Reserved experimental Runtime credential; not implemented and rejects startup."}).option("managed-runtime-broker-url",{type:"string",requiresArg:true,description:"Private Broker URL for --profile hosted-harness; required together with token for Workspace tool turns. Falls back to QWEN_MANAGED_RUNTIME_BROKER_URL."}).option("managed-runtime-broker-token",{type:"string",requiresArg:true,description:"Private Broker credential for --profile hosted-harness; required together with URL for Workspace tool turns. Falls back to QWEN_MANAGED_RUNTIME_BROKER_TOKEN; prefer the variable, since this option puts the credential in the process list."}).option("writer-idle-timeout-ms",{type:"number",description:"Per-SSE-connection idle deadline (ms). Falls back to QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS. Positive integer."}).option("channel-idle-timeout-ms",{type:"number",description:"Compatibility auto-reap delay for an idle workspace ACP child. 0 or unset = reap after work drains; keepalive windows may extend it (default)."}).option("initialize-timeout-ms",{type:"number",description:"ACP child request timeout, including the initialize handshake (ms). Default: 10000 (10 s)."}).option("session-restore-timeout-ms",{type:"number",description:"ACP session load/resume timeout (ms). Default: 60000. An explicit --initialize-timeout-ms can raise (but never lower) this default."}).option("session-reap-interval-ms",{type:"number",description:"Session reaper scan interval (ms). 0 = disabled. Default: 60000."}).option("session-idle-timeout-ms",{type:"number",description:"Idle timeout before a disconnected session is reaped (ms). 0 = disabled. Default: 1800000 (30 min)."}).option("session-prompt-settled-close-grace-ms",{type:"number",description:"Grace period after a prompt settles before an otherwise-idle session may be auto-closed (ms). Poll-based SSE clients use this window to reconnect without triggering a session rebuild. 0 = disabled (immediate close). Default: 0."}).option("permission-response-timeout-ms",{type:"number",description:"Wall-clock timeout for a human permission / ask_user_question response in daemon (ACP) mode (ms). 0 or unset = disabled (wait indefinitely). Default: 0."}).option("external-tool-guard-mode",{choices:["off","required"],default:"off",description:"Managed ACP pre-execution policy mode. Default off preserves current CLI and daemon behavior. Required fails startup unless a compatible loopback provider is available."}).option("external-tool-guard-endpoint",{type:"string",description:"Origin-only loopback HTTP(S) endpoint for required external tool guarding, for example http://127.0.0.1:8787."}).option("external-tool-guard-timeout-ms",{type:"number",description:"Per-handshake/prepare external tool guard timeout in milliseconds. Default: 3000."}).option("rate-limit",{type:"boolean",description:"Enable per-tier HTTP rate limiting. Tiers: prompt (10/min), mutation (30/min), read (120/min). Health, heartbeat, SSE, and /acp are exempt."}).option("rate-limit-prompt",{type:"number",description:"Max prompt requests per window per client (default 10). Requires --rate-limit."}).option("rate-limit-mutation",{type:"number",description:"Max mutation requests per window per client (default 30). Requires --rate-limit."}).option("rate-limit-read",{type:"number",description:"Max read requests per window per client (default 120). Requires --rate-limit."}).option("rate-limit-window-ms",{type:"number",description:"Rate limit window duration in ms (default 60000). Requires --rate-limit."}),"builder"),handler:__name(async argv=>{if(argv["managed-web-config"]!==void 0){try{const serveIndex=process.argv.indexOf("serve");if(serveIndex>=0)validateManagedWebFlags(process.argv.slice(serveIndex+1));if(argv.managed||argv.profile!=="default"||!argv.web||argv.workspace!==void 0){throw new Error("--managed-web-config cannot be combined with daemon execution or Managed local mode.")}const{runManagedWebServe}=await import("./managed-web-serve-JPJBFJMR.js");const handle=await runManagedWebServe({configFile:argv["managed-web-config"],hostname:argv.hostname,port:argv.port,token:argv.token,allowOrigins:argv["allow-origin"]});writeStdoutLine(`Managed WebShell: ${handle.url}`);process.exit(await handle.finished)}catch(error){writeStderrLine(`qwen serve: ${error instanceof Error?error.message:String(error)}`);process.exit(1)}}if(argv.managed){try{const serveIndex=process.argv.indexOf("serve");if(serveIndex>=0)validateManagedLocalFlags(process.argv.slice(serveIndex+1));if(argv.hostname!==DEFAULT_SERVE_HOSTNAME||argv.profile!=="default"||!argv.web||argv.workspace!==void 0||argv.token!==void 0||argv["tls-cert"]||argv["tls-key"]||argv["local-control"]||argv.join||argv["agent-host-server"]||argv.channel!==void 0||argv["experimental-paired-engines"]||argv["experimental-managed-agents"]||argv["experimental-managed-runtime-worker"]||argv["experimental-managed-runtime-auto-local"]||argv["experimental-managed-runtime-url"]!==void 0||argv["managed-runtime-broker-url"]!==void 0||argv["managed-runtime-broker-token"]!==void 0||argv["allow-origin"]?.length||argv["enable-session-shell"]||!argv["http-bridge"]){throw new Error("--managed uses its own loopback services, persistent credentials, and application-owned Workspaces. Use --port, --managed-data-dir, and --open; other deployment, workspace-import, or execution modes cannot be combined.")}const{runManagedLocalServe}=await import("./managed-local-serve-P4ZXVRBU.js");const handle=await runManagedLocalServe({port:argv.port,dataDirectory:argv["managed-data-dir"]});await maybeOpenWebShellBrowser(handle,argv.open||argv["open-with-auth"],argv["open-with-auth"]);process.exit(await handle.finished)}catch(error){writeStderrLine(`qwen serve: ${error instanceof Error?error.message:String(error)}`);process.exit(1)}}if(argv["managed-data-dir"]!==void 0){writeStderrLine("qwen serve: --managed-data-dir requires --managed.");process.exit(1)}const managedRuntimeBrokerUrl=argv["managed-runtime-broker-url"]??process.env["QWEN_MANAGED_RUNTIME_BROKER_URL"];const managedRuntimeBrokerToken=argv["managed-runtime-broker-token"]??process.env["QWEN_MANAGED_RUNTIME_BROKER_TOKEN"];delete process.env["QWEN_MANAGED_RUNTIME_BROKER_URL"];delete process.env["QWEN_MANAGED_RUNTIME_BROKER_TOKEN"];const agentHostEnrollmentToken=process.env["QWEN_AGENT_HOST_ENROLLMENT_TOKEN"]?.trim();delete process.env["QWEN_AGENT_HOST_ENROLLMENT_TOKEN"];if(!argv["http-bridge"]){writeStderrLine("qwen serve: --no-http-bridge (native mode) is not yet implemented; falling back to http-bridge.")}if(argv.token){writeStderrLine("qwen serve: --token is visible in the process command line; prefer the QWEN_SERVER_TOKEN env var for any non-trivial deployment.")}if(argv["managed-runtime-broker-token"]!==void 0){writeStderrLine("qwen serve: --managed-runtime-broker-token is visible in the process command line; prefer the QWEN_MANAGED_RUNTIME_BROKER_TOKEN env var.")}let channelSelection;try{channelSelection=normalizeServeChannelSelection(argv.channel)}catch(err){writeStderrLine(`qwen serve: ${err instanceof Error?err.message:String(err)}`);process.exit(1)}const mcpClientBudget=argv["mcp-client-budget"];const mcpBudgetMode=argv["mcp-budget-mode"];if(mcpClientBudget!==void 0){if(!Number.isFinite(mcpClientBudget)||!Number.isInteger(mcpClientBudget)||mcpClientBudget<=0){writeStderrLine("qwen serve: --mcp-client-budget must be a positive integer.");process.exit(1)}}if(mcpBudgetMode==="enforce"&&mcpClientBudget===void 0){writeStderrLine("qwen serve: --mcp-budget-mode=enforce requires --mcp-client-budget=N.");process.exit(1)}const resolvedMcpMode=mcpBudgetMode??(mcpClientBudget!==void 0?"warn":"off");const memoryBudgetMb=argv["memory-budget-mb"];if(memoryBudgetMb!==void 0&&!isValidMemoryBudgetMb(memoryBudgetMb)){writeStderrLine(memoryBudgetRangeError());process.exit(1)}const maxPendingPromptsPerSession=argv["max-pending-prompts-per-session"];if(maxPendingPromptsPerSession!==Number.POSITIVE_INFINITY&&(!Number.isFinite(maxPendingPromptsPerSession)||!Number.isInteger(maxPendingPromptsPerSession)||maxPendingPromptsPerSession<0)){writeStderrLine("qwen serve: --max-pending-prompts-per-session must be a non-negative integer (0 / Infinity = unlimited).");process.exit(1)}if(mcpClientBudget!==void 0){writeStderrLine(`qwen serve: --mcp-client-budget=${mcpClientBudget} mode=${resolvedMcpMode}`+(resolvedMcpMode==="enforce"?" (servers past the cap will be refused at discovery)":resolvedMcpMode==="warn"?` (warnings at >=${Math.ceil(mcpClientBudget*MCP_BUDGET_WARN_FRACTION)}, no refusal)`:""))}try{const loaded=loadSettings(primaryWorkspaceArg(argv.workspace)??process.cwd());const merged=loaded.merged;const approvalMode=merged.tools?.approvalMode;const sandbox=merged.tools?.sandbox;const sandboxEnv=process.env["SANDBOX"];const suppress=process.env["QWEN_CODE_SUPPRESS_YOLO_WARNING"];const suppressed=suppress==="1"||suppress==="true";if(approvalMode==="yolo"&&!sandbox&&!sandboxEnv&&!suppressed){writeStderrLine(HEADLESS_YOLO_NO_SANDBOX_WARNING)}}catch{}const rateLimit=argv["rate-limit"]??(process.env["QWEN_SERVE_RATE_LIMIT"]==="1"||process.env["QWEN_SERVE_RATE_LIMIT"]==="true");let rateLimitPrompt;let rateLimitMutation;let rateLimitRead;let rateLimitWindowMs;if(rateLimit){const envInt=__name(key=>{const raw=process.env[key];if(raw===void 0||raw==="")return void 0;return parsePositiveIntegerEnv(raw,Number.NaN)},"envInt");rateLimitPrompt=argv["rate-limit-prompt"]??envInt("QWEN_SERVE_RATE_LIMIT_PROMPT");rateLimitMutation=argv["rate-limit-mutation"]??envInt("QWEN_SERVE_RATE_LIMIT_MUTATION");rateLimitRead=argv["rate-limit-read"]??envInt("QWEN_SERVE_RATE_LIMIT_READ");rateLimitWindowMs=argv["rate-limit-window-ms"]??envInt("QWEN_SERVE_RATE_LIMIT_WINDOW_MS");for(const[name,value]of[["--rate-limit-prompt",rateLimitPrompt],["--rate-limit-mutation",rateLimitMutation],["--rate-limit-read",rateLimitRead]]){if(value!==void 0&&(!Number.isFinite(value)||!Number.isInteger(value)||value<=0)){writeStderrLine(`qwen serve: ${name} must be a positive integer.`);process.exit(1)}}if(rateLimitWindowMs!==void 0&&(!Number.isFinite(rateLimitWindowMs)||!Number.isInteger(rateLimitWindowMs)||rateLimitWindowMs<1e3)){writeStderrLine("qwen serve: --rate-limit-window-ms must be an integer >= 1000.");process.exit(1)}}const externalToolGuardToken=process.env[EXTERNAL_TOOL_GUARD_TOKEN_ENV]??"";delete process.env[EXTERNAL_TOOL_GUARD_TOKEN_ENV];const openWithAuth=argv["open-with-auth"];const open=argv.open||openWithAuth;const{runQwenServe}=await import("./run-qwen-serve-CLBG7W6F.js");try{const serveOptions={port:argv.port,hostname:argv.hostname,profile:argv.profile,token:argv.token,mode:"http-bridge",maxSessions:argv["max-sessions"],...argv["max-total-sessions"]!==void 0?{maxTotalSessions:argv["max-total-sessions"]}:{},maxPendingPromptsPerSession,maxConnections:argv["max-connections"],eventRingSize:argv["event-ring-size"],compactedReplayMaxBytes:argv["compacted-replay-max-bytes"],...argv["max-journal-events"]!==void 0?{maxJournalEvents:argv["max-journal-events"]}:{},...argv["max-journal-bytes"]!==void 0?{maxJournalBytes:argv["max-journal-bytes"]}:{},workspace:argv.workspace,...argv["memory-project-scope"]!==void 0?{memoryProjectScope:argv["memory-project-scope"]}:{},requireAuth:argv["require-auth"],enableSessionShell:argv["enable-session-shell"],serveWebShell:argv.web,...argv["token-qr"]!==void 0?{tokenQr:argv["token-qr"]}:{},...argv["tls-cert"]!==void 0?{tlsCert:argv["tls-cert"]}:{},...argv["tls-key"]!==void 0?{tlsKey:argv["tls-key"]}:{},allowPrivateAuthBaseUrl:argv["allow-private-auth-base-url"],mcpClientBudget,mcpBudgetMode:resolvedMcpMode,...memoryBudgetMb!==void 0?{memoryBudgetMb}:{},memoryPressureMode:argv["memory-pressure-mode"],childHeapMode:argv["child-heap-mode"],...argv["allow-origin"]&&argv["allow-origin"].length>0?{allowOrigins:argv["allow-origin"]}:{},...argv["prompt-deadline-ms"]!==void 0?{promptDeadlineMs:argv["prompt-deadline-ms"]}:{},...argv["experimental-paired-engines"]?{experimentalPairedEngines:true}:{},...argv["experimental-managed-agents"]?{experimentalManagedAgents:true}:{},...argv["experimental-managed-runtime-auto-local"]?{experimentalManagedRuntimeAutoLocal:true}:{},...argv["experimental-managed-runtime-worker"]?{experimentalManagedRuntimeWorker:true}:{},...argv["experimental-managed-runtime-url"]!==void 0?{experimentalManagedRuntimeUrl:argv["experimental-managed-runtime-url"]}:{},...argv["experimental-managed-runtime-token"]!==void 0?{experimentalManagedRuntimeToken:argv["experimental-managed-runtime-token"]}:{},...managedRuntimeBrokerUrl!==void 0?{managedRuntimeBrokerUrl}:{},...managedRuntimeBrokerToken!==void 0?{managedRuntimeBrokerToken}:{},...argv["hosted-harness-capability-digest"]!==void 0?{hostedHarnessCapabilityDigest:argv["hosted-harness-capability-digest"]}:{},...argv["writer-idle-timeout-ms"]!==void 0?{writerIdleTimeoutMs:argv["writer-idle-timeout-ms"]}:{},...argv["channel-idle-timeout-ms"]!==void 0?{channelIdleTimeoutMs:argv["channel-idle-timeout-ms"]}:{},...argv["initialize-timeout-ms"]!==void 0?{initializeTimeoutMs:argv["initialize-timeout-ms"]}:{},...argv["session-restore-timeout-ms"]!==void 0?{sessionRestoreTimeoutMs:argv["session-restore-timeout-ms"]}:{},...argv["session-reap-interval-ms"]!==void 0?{sessionReapIntervalMs:argv["session-reap-interval-ms"]}:{},...argv["session-idle-timeout-ms"]!==void 0?{sessionIdleTimeoutMs:argv["session-idle-timeout-ms"]}:{},...argv["session-prompt-settled-close-grace-ms"]!==void 0?{sessionPromptSettledCloseGraceMs:argv["session-prompt-settled-close-grace-ms"]}:{},...argv["permission-response-timeout-ms"]!==void 0?{permissionResponseTimeoutMs:argv["permission-response-timeout-ms"]}:{},...argv["external-tool-guard-mode"]==="required"?{externalToolGuard:{mode:"required",endpoint:argv["external-tool-guard-endpoint"]??"",token:externalToolGuardToken,...argv["external-tool-guard-timeout-ms"]!==void 0?{timeoutMs:argv["external-tool-guard-timeout-ms"]}:{}}}:{},...rateLimit?{rateLimit:true}:{},...rateLimitPrompt!==void 0?{rateLimitPrompt}:{},...rateLimitMutation!==void 0?{rateLimitMutation}:{},...rateLimitRead!==void 0?{rateLimitRead}:{},...rateLimitWindowMs!==void 0?{rateLimitWindowMs}:{},...argv.experimentalLsp===true?{experimentalLsp:true}:{},...argv.restoreAskUserQuestion===true?{restoreAskUserQuestion:true}:{},...channelSelection!==void 0?{channelSelection}:{}};if(openWithAuth){const{applyOpenWithAuth}=await import("./open-with-auth-Z6WKB2OO.js");applyOpenWithAuth(serveOptions)}const handle=await runQwenServe(serveOptions,{updateRestartArgv:process.argv.slice(2)});const joined=argv["join"]?parseJoinLink(argv["join"]):void 0;const hostTarget=joined?{...joined,token:agentHostEnrollmentToken}:argv["agent-host-server"]&&argv["agent-host-workspace-id"]?{serverUrl:argv["agent-host-server"],workspaceId:argv["agent-host-workspace-id"],token:agentHostEnrollmentToken}:void 0;if(hostTarget){try{await handle.runtimeReady;const runtime=handle.getPrimaryWorkspaceRuntime();if(!runtime?.trusted||!runtime.generationGuard||runtime.generationGuard.closed){throw new Error("Agent Host join requires a trusted active workspace.")}const{startAgentHostConnection}=await import("./agent-host-client-K6GRPTFD.js");await startAgentHostConnection({bridge:runtime.bridge,serverUrl:hostTarget.serverUrl,workspaceId:hostTarget.workspaceId,workspaceCwd:runtime.workspaceCwd,allowHttp:argv["agent-host-allow-http"]===true,generationGuard:runtime.generationGuard,...hostTarget.token?{enrollmentToken:hostTarget.token}:{},...argv["agent-host-name"]?{name:argv["agent-host-name"]}:{}})}catch(error){await handle.close().catch(()=>void 0);throw error}}if(argv["local-control"]){try{await startLocalControl(handle,argv["local-control-address"])}catch(err){await handle.close().catch(()=>void 0);throw err}}await maybeOpenWebShellBrowser(handle,open,openWithAuth)}catch(err){writeStderrLine(`qwen serve: ${err instanceof Error?err.message:String(err)}`);process.exit(1)}await blockForever()},"handler")};export{parseJoinLink,validateManagedLocalFlags,validateManagedWebFlags,maybeOpenWebShellBrowser,serveCommand};
3
+ import{HEADLESS_YOLO_NO_SANDBOX_WARNING}from"./chunk-Z57KDB5F.js";import{DEFAULT_RING_SIZE}from"./chunk-BWQ5AIEA.js";import{DEFAULT_COMPACTED_REPLAY_MAX_BYTES,DEFAULT_MAX_JOURNAL_BYTES,DEFAULT_MAX_JOURNAL_EVENTS,JOURNAL_GROWTH_HARD_CAP_BYTES}from"./chunk-WDR5XP3Y.js";import{JOURNAL_GROWTH_POOL_FRACTION,MAX_JOURNAL_GROWTH_POOL_MB,MIN_MEMORY_BUDGET_MB,isValidMemoryBudgetMb,memoryBudgetRangeError}from"./chunk-2QYDBHYZ.js";import{normalizeServeChannelSelection}from"./chunk-KOJ7WZ63.js";import{EXTERNAL_TOOL_GUARD_TOKEN_ENV}from"./chunk-NIEO2TBE.js";import{loadSettings}from"./chunk-2TAJ5STJ.js";import{MCP_BUDGET_WARN_FRACTION}from"./chunk-2JGTWRZJ.js";import{parsePositiveIntegerEnv}from"./chunk-BG67XABA.js";import{openBrowserSecurely,shouldLaunchBrowser}from"./chunk-3YWXKSOI.js";import{MEMORY_PROJECT_SCOPES}from"./chunk-PWOQASXT.js";import{writeStderrLine,writeStdoutLine}from"./chunk-M4ECEHLX.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();init_esbuild_shims();var SEGMENT=/^[A-Za-z0-9_-]{1,256}$/;function parseJoinLink(link){let url;try{url=new URL(link.trim())}catch{throw new Error("--join expects the link shown by the coordinator.")}const marker=url.pathname.lastIndexOf("/join/");const[workspaceId,...rest]=marker>=0?url.pathname.slice(marker+"/join/".length).split("/"):[];if(url.protocol!=="http:"&&url.protocol!=="https:"||url.username||url.password||url.search||url.hash||!workspaceId||rest.some(Boolean)||!SEGMENT.test(workspaceId)){throw new Error("--join expects a link like https://host:4170/join/<workspace>.")}const base=url.pathname.slice(0,marker).replace(/\/+$/,"");return{serverUrl:`${url.origin}${base}`,workspaceId}}__name(parseJoinLink,"parseJoinLink");function blockForever(){return new Promise(()=>{})}__name(blockForever,"blockForever");var DEFAULT_SERVE_HOSTNAME="127.0.0.1";function validateManagedLocalFlags(args){const supported=new Set(["--managed","--managed-data-dir","--port","--hostname","--open","--no-open","--open-with-auth","--no-open-with-auth","--web","--require-auth","--http-bridge"]);const unsupported=args.find(arg=>arg.startsWith("--")&&!supported.has(arg.split("=")[0]));if(unsupported){throw new Error(`${unsupported.split("=")[0]} is not supported with --managed. Use --port, --managed-data-dir, and --open.`)}}__name(validateManagedLocalFlags,"validateManagedLocalFlags");function validateManagedWebFlags(args){const supported=new Set(["--managed-web-config","--hostname","--port","--allow-origin","--token","--require-auth"]);const unsupported=args.find(arg=>arg.startsWith("--")&&!supported.has(arg.split("=")[0]));if(unsupported){throw new Error(`${unsupported.split("=")[0]} is not supported with --managed-web-config. Only hostname, port, allow-origin and browser authentication options are supported.`)}}__name(validateManagedWebFlags,"validateManagedWebFlags");async function startLocalControl(handle,address){await handle.runtimeReady;if(!handle.webShellMounted){throw new Error("Local Control requires the Web Shell.")}const service=handle.getLocalControl();if(!service){throw new Error("Local Control is unavailable on this daemon.")}let status;try{status=await service.enable(address?{address}:{})}catch(err){if(err instanceof Error&&err.code==="ambiguous_lan_interface"){throw new Error(`${err.message}. Pass --local-control-address <ip>.`)}throw err}if(!status.url){throw new Error("Local Control did not return a pairing URL.")}const{default:qrcode}=await import("./main-5IVKRF6Q.js");qrcode.setErrorLevel("Q");writeStdoutLine("\nLocal Control is on. Scan this QR code from the same network:");writeStdoutLine(`
4
+ ${status.interfaceName}: ${status.url}`);qrcode.generate(status.url,{small:true},code=>{writeStdoutLine(code.trimEnd())});writeStdoutLine("\nKeep this terminal open. "+(status.sleepInhibited?"Sleep is inhibited while this session is active. ":"Sleep inhibition is unavailable here, so the host may sleep. ")+(status.encrypted?"Traffic is encrypted.":"Traffic is unencrypted \u2014 use it only on a network you trust.")+" Turn Local Control off from the Web Shell Settings card, or press Ctrl+C to exit the daemon.")}__name(startLocalControl,"startLocalControl");async function maybeOpenWebShellBrowser(handle,open,manualFallbackWhenIneligible=false){if(!open||!handle.webShellMounted)return;const shouldLaunch=shouldLaunchBrowser();if(!shouldLaunch&&!manualFallbackWhenIneligible)return;try{await handle.runtimeReady}catch(runtimeErr){writeStderrLine(`qwen serve: Web Shell runtime not ready; skipping --open: ${runtimeErr instanceof Error?runtimeErr.message:String(runtimeErr)}`);return}let target;try{target=new URL(handle.url);if(target.hostname==="0.0.0.0"||target.hostname==="[::]"){target.hostname="127.0.0.1"}if(handle.resolvedToken){target.hash=`token=${encodeURIComponent(handle.resolvedToken)}`}if(!shouldLaunch){writeStderrLine(`Browser launch is not available in this environment. Please open this URL manually: ${target.toString()}`);return}if(handle.resolvedToken){writeStderrLine("qwen serve: --open passes the token in the browser launch command (visible via `ps` / /proc); on a multi-user host open the URL manually instead.")}await openBrowserSecurely(target.toString())}catch(browserErr){const manualUrl=manualFallbackWhenIneligible&&target?`. Please open this URL manually: ${target.toString()}`:"";writeStderrLine(`qwen serve: failed to open browser: ${browserErr instanceof Error?browserErr.message:String(browserErr)}${manualUrl}`)}}__name(maybeOpenWebShellBrowser,"maybeOpenWebShellBrowser");function primaryWorkspaceArg(workspace){return Array.isArray(workspace)?workspace[0]:workspace}__name(primaryWorkspaceArg,"primaryWorkspaceArg");var serveCommand={command:"serve",describe:"Run Qwen Code as a local HTTP daemon (Stage 1 experimental: --http-bridge)",builder:__name(yargs=>yargs.option("port",{type:"number",default:4170,description:"TCP port to bind (use 0 for an OS-assigned ephemeral port)"}).option("hostname",{type:"string",default:DEFAULT_SERVE_HOSTNAME,description:"Interface to bind. Loopback (127.0.0.0/8, localhost, ::1, [::1]) is auth-free; anything else requires a token (one is generated and printed when neither --token nor QWEN_SERVER_TOKEN supplies one). A localhost bind that resolves off-loopback never generates, and still refuses when no token source resolved; an empty value is rejected as operator error."}).option("profile",{choices:["default","hosted-harness"],default:"default",description:"Deployment profile. hosted-harness enables the private no-tool Managed Session API on loopback."}).option("hosted-harness-capability-digest",{type:"string",description:"SHA-256 capability digest for the private Hosted Harness profile. Falls back to QWEN_HOSTED_HARNESS_CAPABILITY_DIGEST."}).option("managed",{type:"boolean",default:false,description:"Start the daemon and Managed Agent with shared WebShell and embedded storage; downloads the server on first use and requires Java 21."}).option("managed-data-dir",{type:"string",requiresArg:true,description:"Private persistent data directory for --managed; defaults to <Qwen home>/managed-local."}).option("managed-web-config",{type:"string",requiresArg:true,description:"Run only the authenticated Managed Web gateway using a JSON file with apiUrl, tenantId, actorId and signingKeyFile. Requires an independent browser token of at least 32 bytes via QWEN_SERVER_TOKEN or --token."}).option("token",{type:"string",description:"Bearer token required on every request. Falls back to the QWEN_SERVER_TOKEN env var; a non-loopback bind with neither generates an ephemeral token at startup, while loopback keeps the trusted tokenless mode unless --require-auth is set."}).option("max-sessions",{type:"number",description:"Cap on concurrent live sessions. New spawn requests beyond this return 503; attach to existing sessions still works. Set to 0 to disable. Defaults to 32, or to the serve.maxSessions setting (user, system, and system-defaults scopes only); the flag wins when passed."}).option("max-total-sessions",{type:"number",description:"Non-negative integer cap on concurrent live sessions across all workspace runtimes. Set to 0 to disable."}).option("max-pending-prompts-per-session",{type:"number",default:5,description:"Per-session cap on accepted prompts waiting or running. New prompts beyond this return 503. Set to 0 to disable."}).option("workspace",{type:"string",array:true,requiresArg:true,description:"Absolute workspace path to register with this daemon. POST /session requests with a mismatched cwd return 400 workspace_mismatch. Defaults to process.cwd() when omitted. Repeat to register isolated workspace runtimes; the first is primary."}).option("memory-project-scope",{type:"string",choices:MEMORY_PROJECT_SCOPES,description:'Choose how project memory is partitioned. Defaults to "workspace" so each daemon workspace stays isolated; "git-root" preserves the legacy shared scope. Overrides QWEN_CODE_MEMORY_PROJECT_SCOPE when provided.'}).option("max-connections",{type:"number",default:256,description:"Listener-level TCP connection cap (server.maxConnections). Bounds raw sockets \u2014 slow/phantom SSE clients get rejected at accept time once full. Set to 0 to disable."}).option("require-auth",{type:"boolean",default:false,description:"Refuse to start without a bearer token, even on loopback. Hardens the loopback developer default for shared dev hosts / CI runners / multi-tenant workstations where any local user can hit 127.0.0.1. Requires --token, QWEN_SERVER_TOKEN, or --open-with-auth (which installs its own generated loopback token); on non-loopback binds the generated ephemeral token also satisfies it, so the no-configured-secret fail-fast is loopback-only. /health also requires Authorization when enabled (no loopback exemption \u2014 k8s/Compose probes must pass the bearer too)."}).option("enable-session-shell",{type:"boolean",default:false,description:"Enable direct POST /session/:id/shell execution. Available with bearer auth or trusted loopback; each call still requires a session-bound client id."}).option("tls-cert",{type:"string",description:"Path to a PEM certificate file. Serve over HTTPS instead of HTTP. Required for secure-context browser APIs (voice input/getUserMedia, WebRTC) when accessed over a LAN IP. Must be used together with --tls-key. Generate a local cert with mkcert."}).option("tls-key",{type:"string",description:"Path to a PEM private key file. Must be used together with --tls-cert."}).option("experimental-lsp",{type:"boolean",default:false,description:"Forward the experimental LSP opt-in to spawned agent sessions."}).option("restore-ask-user-question",{type:"boolean",default:false,description:"On session load/resume, re-hang a trailing unanswered ask_user_question instead of synthesizing a failed tool result."}).option("channel",{type:"string",array:true,description:"Experimental: start a daemon-managed channel worker for the named channel. Repeat to select multiple channels, or use --channel all."}).option("web",{type:"boolean",default:true,description:"Serve the Web Shell UI at the daemon root path. Use --no-web for an API-only daemon."}).option("open",{type:"boolean",default:false,description:"Open the Web Shell in a browser once the daemon is listening. With a token configured, the launch URL (token included) is handed to the browser launcher and is visible in the process list, so prefer opening the URL manually on multi-user hosts. No-op with --no-web, when the UI assets are absent, or in headless/CI/SSH environments."}).option("open-with-auth",{type:"boolean",default:false,description:"Open the Web Shell with bearer authentication on loopback. Reuse --token or QWEN_SERVER_TOKEN, or generate a temporary 256-bit token and deliver it in the URL fragment. In headless environments, print the fragment URL for manual opening."}).option("token-qr",{type:"boolean",description:"Print the token-bearing QR even when stdout is captured (not an interactive terminal) and the bearer is an operator-supplied (stable) token, which is withheld by default to keep stable credentials out of collected logs. Enable only when the log pipeline is as trusted as the daemon host. Can also be set via the serve.tokenQr setting (user, system, and system-defaults scopes only); the flag wins when passed. --no-token-qr suppresses the startup quickstart token QR for that run on every quickstart path \u2014 interactive terminal and generated token included. It does not govern the Local Control pairing QR, which --local-control prints by design."}).option("local-control",{type:"boolean",default:false,description:"Share the Web Shell on the local IPv4 network with its own revocable pairing token, terminal QR code, and best-effort sleep inhibition. Ctrl+C turns it off by ending the whole daemon; the Web Shell Settings card turns it off while the daemon keeps running."}).option("local-control-address",{type:"string",description:"Which local IPv4 address to share when the host is on more than one network. Only needed if --local-control reports an ambiguous choice."}).option("join",{type:"string",description:"Join another Qwen Code as a runtime, with the one-line link it shows under Agent \u2192 Runtime \u2192 Add runtime."}).option("agent-host-server",{type:"string",description:"Register this daemon as an Agent Host with a primary Qwen daemon."}).option("agent-host-workspace-id",{type:"string",description:"Control-plane workspace id printed by the primary daemon."}).option("agent-host-name",{type:"string",description:"Display name advertised for this Agent Host."}).option("agent-host-allow-http",{type:"boolean",default:false,description:"Allow unencrypted Agent Host HTTP connections outside loopback (trusted demo networks only)."}).check(argv=>{if(argv["local-control"]===true&&argv["web"]===false){throw new Error("Local Control requires the Web Shell.")}if(argv["local-control"]===true&&argv.hostname!==DEFAULT_SERVE_HOSTNAME){throw new Error(`Local Control requires --hostname ${DEFAULT_SERVE_HOSTNAME}.`)}if(argv["local-control"]!==true&&argv["local-control-address"]!==void 0){throw new Error("--local-control-address requires --local-control.")}if(argv["local-control-address"]===""){throw new Error("--local-control-address must not be empty.")}if(Boolean(argv["agent-host-server"])!==Boolean(argv["agent-host-workspace-id"])){throw new Error("--agent-host-server and --agent-host-workspace-id must be used together.")}if(argv["agent-host-name"]===""){throw new Error("--agent-host-name must not be empty.")}if(argv["join"]!==void 0){if(argv["agent-host-server"]||argv["agent-host-workspace-id"]){throw new Error("--join already names the coordinator and workspace; drop --agent-host-server and --agent-host-workspace-id.")}parseJoinLink(argv["join"])}return true}).option("event-ring-size",{type:"number",default:DEFAULT_RING_SIZE,description:"Per-session SSE replay ring depth. Sets the replay backlog available to `GET /session/:id/events` reconnects that send a `Last-Event-ID: N` header. Larger = more reconnect headroom at the cost of a few hundred KB extra RAM per session. Must be a positive finite integer."}).option("compacted-replay-max-bytes",{type:"number",default:DEFAULT_COMPACTED_REPLAY_MAX_BYTES,description:"Per-session in-memory compacted replay snapshot byte cap for `POST /session/:id/load` late attaches. Larger = more recent history in load snapshots at higher heap cost. Must be a positive safe integer no larger than 256 MiB."}).option("max-journal-events",{type:"number",nargs:1,description:"Per-session baseline cap on replay entries retained in the in-flight live journal (current unfinished turn). Compatible text/thought chunks share bounded entries. When exceeded, the daemon first tries adaptive growth (see --max-journal-bytes); without granted headroom the oldest entries are dropped. Pinning this flag (or --max-journal-bytes) disables adaptive growth. Defaults to "+DEFAULT_MAX_JOURNAL_EVENTS+" when unset. Must be a positive safe integer."}).option("max-journal-bytes",{type:"number",nargs:1,description:"Per-session baseline source-event byte cap on the in-flight live journal. When a turn outgrows it, adaptive growth raises the session's caps (per-session hard cap "+JOURNAL_GROWTH_HARD_CAP_BYTES/(1024*1024)+" MiB) within a growth pool derived from the daemon memory budget (see --memory-budget-mb); without granted headroom the oldest entries are dropped whole (at least one is always kept), so the retained tail can be much smaller than the cap. Pinning this flag (or --max-journal-events) disables adaptive growth. Defaults to "+DEFAULT_MAX_JOURNAL_BYTES+" bytes when unset. Must be a positive safe integer."}).option("http-bridge",{type:"boolean",default:true,description:"HTTP bridge mode: attempt to preheat the primary `qwen --acp` child; trusted secondaries start one on demand. Stage 2 native in-process mode is not yet implemented; this flag will become opt-in then."}).option("memory-budget-mb",{type:"number",description:"Total memory budget in MB for the daemon process tree. When unset, derived as 50% of cgroup-constrained or host memory, and capped at the resolved available memory either way. In `admit` and `enforce` modes it determines managed ACP child capacity; `enforce` also applies the modeled per-child old-space ceiling. It also sizes one daemon-wide pool of "+JOURNAL_GROWTH_POOL_FRACTION*100+"% of the effective budget (capped at "+MAX_JOURNAL_GROWTH_POOL_MB+" MB; 0, growth disabled, when the effective budget falls below the "+MIN_MEMORY_BUDGET_MB+" MB minimum; see --max-journal-bytes). Reported under `limits.memory` in daemon status, alongside a modeled per-child partition under `limits.memory.childHeap`. Must be an integer in [1024, 1048576]."}).option("memory-pressure-mode",{choices:["off","observe"],default:"observe",description:"Whether the daemon derives a memory-pressure level from its own RSS and V8 heap. `observe` (default) reports the level in daemon status and raises a status issue when it leaves normal. `off` still reports the underlying figures but raises no issue, so the overall status rollup is unchanged \u2014 use it while calibrating, or if you alert on the top-level status. Nothing remediates in either mode."}).option("child-heap-mode",{choices:["off","observe","admit","enforce"],default:"observe",description:"Whether the daemon models a per-child heap partition of the memory budget. `observe` (default) reports the partition it would apply \u2014 `limits.memory.childHeap.perChildCeilingMb` and `maxConcurrentChildren` \u2014 and counts spawns that would have exceeded it. Nothing is applied: no child is sized from the budget and no spawn is refused. `off` models nothing. Note a refusal count of 0 does NOT mean the partition would be safe to apply; children still run on the much larger host-derived ceiling, so a workload needing more old space than the modeled ceiling looks healthy here. `admit` rejects starts past the modeled process limit but keeps the existing child heap arguments. Experimental `enforce` also applies the fixed modeled old-space ceiling to each managed child; it does not cap total process RSS."}).option("mcp-client-budget",{type:"number",description:"Cap on live MCP clients spawned inside the ACP child for the bound workspace. Positive integer. Combine with --mcp-budget-mode to control behavior at the cap. When unset, mode defaults to off (no accounting-driven enforcement, but GET /workspace/mcp still reports `clientCount`). Distinct from claude-code MCP_SERVER_CONNECTION_BATCH_SIZE which gates startup concurrency, not the total client count."}).option("mcp-budget-mode",{choices:["enforce","warn","off"],description:'How --mcp-client-budget is enforced. `warn` (default when budget set): no refusal, snapshot surfaces warning at >=75% of budget. `enforce`: connects past the cap are refused (`disabledReason: "budget"`, deterministic by mcpServers declaration order). `off`: pure observability. Boot rejects `enforce` without a budget.'}).option("allow-origin",{type:"string",array:true,description:"Cross-origin allowlist for browser clients. Accepts `*`, a canonical origin, or a loopback port wildcard like `http://127.0.0.1:*` (requires a bearer token)."}).option("allow-private-auth-base-url",{type:"boolean",default:false,description:"Allow /workspace/auth/provider to install localhost/private-network baseUrl values. Use only for local development with trusted clients."}).option("prompt-deadline-ms",{type:"number",description:"Server-side wallclock cap on POST /session/:id/prompt (ms). Falls back to QWEN_SERVE_PROMPT_DEADLINE_MS. Positive integer."}).option("experimental-paired-engines",{type:"boolean",default:false,description:"Experimental: build workspace runtimes, other than the private Conversations one, with paired Legacy and Managed engines. No Managed engine is available yet, so sessions run on Legacy with a durable owner."}).option("experimental-managed-agents",{type:"boolean",default:false,description:"Reserved experimental mode; not implemented and rejects startup."}).option("experimental-managed-runtime-worker",{type:"boolean",default:false,description:"Reserved experimental mode; not implemented and rejects startup."}).option("experimental-managed-runtime-auto-local",{type:"boolean",default:false,description:"Reserved experimental mode; not implemented and rejects startup."}).option("experimental-managed-runtime-url",{type:"string",requiresArg:true,description:"Reserved experimental Runtime URL; not implemented and rejects startup."}).option("experimental-managed-runtime-token",{type:"string",requiresArg:true,description:"Reserved experimental Runtime credential; not implemented and rejects startup."}).option("managed-runtime-broker-url",{type:"string",requiresArg:true,description:"Private Broker URL for --profile hosted-harness; required together with token for Workspace tool turns. Falls back to QWEN_MANAGED_RUNTIME_BROKER_URL."}).option("managed-runtime-broker-token",{type:"string",requiresArg:true,description:"Private Broker credential for --profile hosted-harness; required together with URL for Workspace tool turns. Falls back to QWEN_MANAGED_RUNTIME_BROKER_TOKEN; prefer the variable, since this option puts the credential in the process list."}).option("writer-idle-timeout-ms",{type:"number",description:"Per-SSE-connection idle deadline (ms). Falls back to QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS. Positive integer."}).option("channel-idle-timeout-ms",{type:"number",description:"Compatibility auto-reap delay for an idle workspace ACP child. 0 or unset = reap after work drains; keepalive windows may extend it (default)."}).option("initialize-timeout-ms",{type:"number",description:"ACP child request timeout, including the initialize handshake (ms). Default: 10000 (10 s)."}).option("session-restore-timeout-ms",{type:"number",description:"ACP session load/resume timeout (ms). Default: 60000. An explicit --initialize-timeout-ms can raise (but never lower) this default."}).option("session-reap-interval-ms",{type:"number",description:"Session reaper scan interval (ms). 0 = disabled. Default: 60000."}).option("session-idle-timeout-ms",{type:"number",description:"Idle timeout before a disconnected session is reaped (ms). 0 = disabled. Default: 1800000 (30 min)."}).option("session-prompt-settled-close-grace-ms",{type:"number",description:"Grace period after a prompt settles before an otherwise-idle session may be auto-closed (ms). Poll-based SSE clients use this window to reconnect without triggering a session rebuild. 0 = disabled (immediate close). Default: 0."}).option("permission-response-timeout-ms",{type:"number",description:"Wall-clock timeout for a human permission / ask_user_question response in daemon (ACP) mode (ms). 0 or unset = disabled (wait indefinitely). Default: 0."}).option("external-tool-guard-mode",{choices:["off","required"],default:"off",description:"Managed ACP pre-execution policy mode. Default off preserves current CLI and daemon behavior. Required fails startup unless a compatible loopback provider is available."}).option("external-tool-guard-endpoint",{type:"string",description:"Origin-only loopback HTTP(S) endpoint for required external tool guarding, for example http://127.0.0.1:8787."}).option("external-tool-guard-timeout-ms",{type:"number",description:"Per-handshake/prepare external tool guard timeout in milliseconds. Default: 3000."}).option("rate-limit",{type:"boolean",description:"Enable per-tier HTTP rate limiting. Tiers: prompt (10/min), mutation (30/min), read (120/min). Health, heartbeat, SSE, and /acp are exempt."}).option("rate-limit-prompt",{type:"number",description:"Max prompt requests per window per client (default 10). Requires --rate-limit."}).option("rate-limit-mutation",{type:"number",description:"Max mutation requests per window per client (default 30). Requires --rate-limit."}).option("rate-limit-read",{type:"number",description:"Max read requests per window per client (default 120). Requires --rate-limit."}).option("rate-limit-window-ms",{type:"number",description:"Rate limit window duration in ms (default 60000). Requires --rate-limit."}),"builder"),handler:__name(async argv=>{if(argv["managed-web-config"]!==void 0){try{const serveIndex=process.argv.indexOf("serve");if(serveIndex>=0)validateManagedWebFlags(process.argv.slice(serveIndex+1));if(argv.managed||argv.profile!=="default"||!argv.web||argv.workspace!==void 0){throw new Error("--managed-web-config cannot be combined with daemon execution or Managed local mode.")}const{runManagedWebServe}=await import("./managed-web-serve-JPJBFJMR.js");const handle=await runManagedWebServe({configFile:argv["managed-web-config"],hostname:argv.hostname,port:argv.port,token:argv.token,allowOrigins:argv["allow-origin"]});writeStdoutLine(`Managed WebShell: ${handle.url}`);process.exit(await handle.finished)}catch(error){writeStderrLine(`qwen serve: ${error instanceof Error?error.message:String(error)}`);process.exit(1)}}if(argv.managed){try{const serveIndex=process.argv.indexOf("serve");if(serveIndex>=0)validateManagedLocalFlags(process.argv.slice(serveIndex+1));if(argv.hostname!==DEFAULT_SERVE_HOSTNAME||argv.profile!=="default"||!argv.web||argv.workspace!==void 0||argv.token!==void 0||argv["tls-cert"]||argv["tls-key"]||argv["local-control"]||argv.join||argv["agent-host-server"]||argv.channel!==void 0||argv["experimental-paired-engines"]||argv["experimental-managed-agents"]||argv["experimental-managed-runtime-worker"]||argv["experimental-managed-runtime-auto-local"]||argv["experimental-managed-runtime-url"]!==void 0||argv["managed-runtime-broker-url"]!==void 0||argv["managed-runtime-broker-token"]!==void 0||argv["allow-origin"]?.length||argv["enable-session-shell"]||!argv["http-bridge"]){throw new Error("--managed uses its own loopback services, persistent credentials, and application-owned Workspaces. Use --port, --managed-data-dir, and --open; other deployment, workspace-import, or execution modes cannot be combined.")}const{runManagedLocalServe}=await import("./managed-local-serve-ICNAS3E6.js");const handle=await runManagedLocalServe({port:argv.port,dataDirectory:argv["managed-data-dir"]});await maybeOpenWebShellBrowser(handle,argv.open||argv["open-with-auth"],argv["open-with-auth"]);process.exit(await handle.finished)}catch(error){writeStderrLine(`qwen serve: ${error instanceof Error?error.message:String(error)}`);process.exit(1)}}if(argv["managed-data-dir"]!==void 0){writeStderrLine("qwen serve: --managed-data-dir requires --managed.");process.exit(1)}const managedRuntimeBrokerUrl=argv["managed-runtime-broker-url"]??process.env["QWEN_MANAGED_RUNTIME_BROKER_URL"];const managedRuntimeBrokerToken=argv["managed-runtime-broker-token"]??process.env["QWEN_MANAGED_RUNTIME_BROKER_TOKEN"];delete process.env["QWEN_MANAGED_RUNTIME_BROKER_URL"];delete process.env["QWEN_MANAGED_RUNTIME_BROKER_TOKEN"];const agentHostEnrollmentToken=process.env["QWEN_AGENT_HOST_ENROLLMENT_TOKEN"]?.trim();delete process.env["QWEN_AGENT_HOST_ENROLLMENT_TOKEN"];if(!argv["http-bridge"]){writeStderrLine("qwen serve: --no-http-bridge (native mode) is not yet implemented; falling back to http-bridge.")}if(argv.token){writeStderrLine("qwen serve: --token is visible in the process command line; prefer the QWEN_SERVER_TOKEN env var for any non-trivial deployment.")}if(argv["managed-runtime-broker-token"]!==void 0){writeStderrLine("qwen serve: --managed-runtime-broker-token is visible in the process command line; prefer the QWEN_MANAGED_RUNTIME_BROKER_TOKEN env var.")}let channelSelection;try{channelSelection=normalizeServeChannelSelection(argv.channel)}catch(err){writeStderrLine(`qwen serve: ${err instanceof Error?err.message:String(err)}`);process.exit(1)}const mcpClientBudget=argv["mcp-client-budget"];const mcpBudgetMode=argv["mcp-budget-mode"];if(mcpClientBudget!==void 0){if(!Number.isFinite(mcpClientBudget)||!Number.isInteger(mcpClientBudget)||mcpClientBudget<=0){writeStderrLine("qwen serve: --mcp-client-budget must be a positive integer.");process.exit(1)}}if(mcpBudgetMode==="enforce"&&mcpClientBudget===void 0){writeStderrLine("qwen serve: --mcp-budget-mode=enforce requires --mcp-client-budget=N.");process.exit(1)}const resolvedMcpMode=mcpBudgetMode??(mcpClientBudget!==void 0?"warn":"off");const memoryBudgetMb=argv["memory-budget-mb"];if(memoryBudgetMb!==void 0&&!isValidMemoryBudgetMb(memoryBudgetMb)){writeStderrLine(memoryBudgetRangeError());process.exit(1)}const maxPendingPromptsPerSession=argv["max-pending-prompts-per-session"];if(maxPendingPromptsPerSession!==Number.POSITIVE_INFINITY&&(!Number.isFinite(maxPendingPromptsPerSession)||!Number.isInteger(maxPendingPromptsPerSession)||maxPendingPromptsPerSession<0)){writeStderrLine("qwen serve: --max-pending-prompts-per-session must be a non-negative integer (0 / Infinity = unlimited).");process.exit(1)}if(mcpClientBudget!==void 0){writeStderrLine(`qwen serve: --mcp-client-budget=${mcpClientBudget} mode=${resolvedMcpMode}`+(resolvedMcpMode==="enforce"?" (servers past the cap will be refused at discovery)":resolvedMcpMode==="warn"?` (warnings at >=${Math.ceil(mcpClientBudget*MCP_BUDGET_WARN_FRACTION)}, no refusal)`:""))}try{const loaded=loadSettings(primaryWorkspaceArg(argv.workspace)??process.cwd());const merged=loaded.merged;const approvalMode=merged.tools?.approvalMode;const sandbox=merged.tools?.sandbox;const sandboxEnv=process.env["SANDBOX"];const suppress=process.env["QWEN_CODE_SUPPRESS_YOLO_WARNING"];const suppressed=suppress==="1"||suppress==="true";if(approvalMode==="yolo"&&!sandbox&&!sandboxEnv&&!suppressed){writeStderrLine(HEADLESS_YOLO_NO_SANDBOX_WARNING)}}catch{}const rateLimit=argv["rate-limit"]??(process.env["QWEN_SERVE_RATE_LIMIT"]==="1"||process.env["QWEN_SERVE_RATE_LIMIT"]==="true");let rateLimitPrompt;let rateLimitMutation;let rateLimitRead;let rateLimitWindowMs;if(rateLimit){const envInt=__name(key=>{const raw=process.env[key];if(raw===void 0||raw==="")return void 0;return parsePositiveIntegerEnv(raw,Number.NaN)},"envInt");rateLimitPrompt=argv["rate-limit-prompt"]??envInt("QWEN_SERVE_RATE_LIMIT_PROMPT");rateLimitMutation=argv["rate-limit-mutation"]??envInt("QWEN_SERVE_RATE_LIMIT_MUTATION");rateLimitRead=argv["rate-limit-read"]??envInt("QWEN_SERVE_RATE_LIMIT_READ");rateLimitWindowMs=argv["rate-limit-window-ms"]??envInt("QWEN_SERVE_RATE_LIMIT_WINDOW_MS");for(const[name,value]of[["--rate-limit-prompt",rateLimitPrompt],["--rate-limit-mutation",rateLimitMutation],["--rate-limit-read",rateLimitRead]]){if(value!==void 0&&(!Number.isFinite(value)||!Number.isInteger(value)||value<=0)){writeStderrLine(`qwen serve: ${name} must be a positive integer.`);process.exit(1)}}if(rateLimitWindowMs!==void 0&&(!Number.isFinite(rateLimitWindowMs)||!Number.isInteger(rateLimitWindowMs)||rateLimitWindowMs<1e3)){writeStderrLine("qwen serve: --rate-limit-window-ms must be an integer >= 1000.");process.exit(1)}}const externalToolGuardToken=process.env[EXTERNAL_TOOL_GUARD_TOKEN_ENV]??"";delete process.env[EXTERNAL_TOOL_GUARD_TOKEN_ENV];const openWithAuth=argv["open-with-auth"];const open=argv.open||openWithAuth;const{runQwenServe}=await import("./run-qwen-serve-NZWQHWQA.js");try{const serveOptions={port:argv.port,hostname:argv.hostname,profile:argv.profile,token:argv.token,mode:"http-bridge",maxSessions:argv["max-sessions"],...argv["max-total-sessions"]!==void 0?{maxTotalSessions:argv["max-total-sessions"]}:{},maxPendingPromptsPerSession,maxConnections:argv["max-connections"],eventRingSize:argv["event-ring-size"],compactedReplayMaxBytes:argv["compacted-replay-max-bytes"],...argv["max-journal-events"]!==void 0?{maxJournalEvents:argv["max-journal-events"]}:{},...argv["max-journal-bytes"]!==void 0?{maxJournalBytes:argv["max-journal-bytes"]}:{},workspace:argv.workspace,...argv["memory-project-scope"]!==void 0?{memoryProjectScope:argv["memory-project-scope"]}:{},requireAuth:argv["require-auth"],enableSessionShell:argv["enable-session-shell"],serveWebShell:argv.web,...argv["token-qr"]!==void 0?{tokenQr:argv["token-qr"]}:{},...argv["tls-cert"]!==void 0?{tlsCert:argv["tls-cert"]}:{},...argv["tls-key"]!==void 0?{tlsKey:argv["tls-key"]}:{},allowPrivateAuthBaseUrl:argv["allow-private-auth-base-url"],mcpClientBudget,mcpBudgetMode:resolvedMcpMode,...memoryBudgetMb!==void 0?{memoryBudgetMb}:{},memoryPressureMode:argv["memory-pressure-mode"],childHeapMode:argv["child-heap-mode"],...argv["allow-origin"]&&argv["allow-origin"].length>0?{allowOrigins:argv["allow-origin"]}:{},...argv["prompt-deadline-ms"]!==void 0?{promptDeadlineMs:argv["prompt-deadline-ms"]}:{},...argv["experimental-paired-engines"]?{experimentalPairedEngines:true}:{},...argv["experimental-managed-agents"]?{experimentalManagedAgents:true}:{},...argv["experimental-managed-runtime-auto-local"]?{experimentalManagedRuntimeAutoLocal:true}:{},...argv["experimental-managed-runtime-worker"]?{experimentalManagedRuntimeWorker:true}:{},...argv["experimental-managed-runtime-url"]!==void 0?{experimentalManagedRuntimeUrl:argv["experimental-managed-runtime-url"]}:{},...argv["experimental-managed-runtime-token"]!==void 0?{experimentalManagedRuntimeToken:argv["experimental-managed-runtime-token"]}:{},...managedRuntimeBrokerUrl!==void 0?{managedRuntimeBrokerUrl}:{},...managedRuntimeBrokerToken!==void 0?{managedRuntimeBrokerToken}:{},...argv["hosted-harness-capability-digest"]!==void 0?{hostedHarnessCapabilityDigest:argv["hosted-harness-capability-digest"]}:{},...argv["writer-idle-timeout-ms"]!==void 0?{writerIdleTimeoutMs:argv["writer-idle-timeout-ms"]}:{},...argv["channel-idle-timeout-ms"]!==void 0?{channelIdleTimeoutMs:argv["channel-idle-timeout-ms"]}:{},...argv["initialize-timeout-ms"]!==void 0?{initializeTimeoutMs:argv["initialize-timeout-ms"]}:{},...argv["session-restore-timeout-ms"]!==void 0?{sessionRestoreTimeoutMs:argv["session-restore-timeout-ms"]}:{},...argv["session-reap-interval-ms"]!==void 0?{sessionReapIntervalMs:argv["session-reap-interval-ms"]}:{},...argv["session-idle-timeout-ms"]!==void 0?{sessionIdleTimeoutMs:argv["session-idle-timeout-ms"]}:{},...argv["session-prompt-settled-close-grace-ms"]!==void 0?{sessionPromptSettledCloseGraceMs:argv["session-prompt-settled-close-grace-ms"]}:{},...argv["permission-response-timeout-ms"]!==void 0?{permissionResponseTimeoutMs:argv["permission-response-timeout-ms"]}:{},...argv["external-tool-guard-mode"]==="required"?{externalToolGuard:{mode:"required",endpoint:argv["external-tool-guard-endpoint"]??"",token:externalToolGuardToken,...argv["external-tool-guard-timeout-ms"]!==void 0?{timeoutMs:argv["external-tool-guard-timeout-ms"]}:{}}}:{},...rateLimit?{rateLimit:true}:{},...rateLimitPrompt!==void 0?{rateLimitPrompt}:{},...rateLimitMutation!==void 0?{rateLimitMutation}:{},...rateLimitRead!==void 0?{rateLimitRead}:{},...rateLimitWindowMs!==void 0?{rateLimitWindowMs}:{},...argv.experimentalLsp===true?{experimentalLsp:true}:{},...argv.restoreAskUserQuestion===true?{restoreAskUserQuestion:true}:{},...channelSelection!==void 0?{channelSelection}:{}};if(openWithAuth){const{applyOpenWithAuth}=await import("./open-with-auth-Z6WKB2OO.js");applyOpenWithAuth(serveOptions)}const handle=await runQwenServe(serveOptions,{updateRestartArgv:process.argv.slice(2)});const joined=argv["join"]?parseJoinLink(argv["join"]):void 0;const hostTarget=joined?{...joined,token:agentHostEnrollmentToken}:argv["agent-host-server"]&&argv["agent-host-workspace-id"]?{serverUrl:argv["agent-host-server"],workspaceId:argv["agent-host-workspace-id"],token:agentHostEnrollmentToken}:void 0;if(hostTarget){try{await handle.runtimeReady;const runtime=handle.getPrimaryWorkspaceRuntime();if(!runtime?.trusted||!runtime.generationGuard||runtime.generationGuard.closed){throw new Error("Agent Host join requires a trusted active workspace.")}const{startAgentHostConnection}=await import("./agent-host-client-L5EHC4AC.js");await startAgentHostConnection({bridge:runtime.bridge,serverUrl:hostTarget.serverUrl,workspaceId:hostTarget.workspaceId,workspaceCwd:runtime.workspaceCwd,allowHttp:argv["agent-host-allow-http"]===true,generationGuard:runtime.generationGuard,...hostTarget.token?{enrollmentToken:hostTarget.token}:{},...argv["agent-host-name"]?{name:argv["agent-host-name"]}:{}})}catch(error){await handle.close().catch(()=>void 0);throw error}}if(argv["local-control"]){try{await startLocalControl(handle,argv["local-control-address"])}catch(err){await handle.close().catch(()=>void 0);throw err}}await maybeOpenWebShellBrowser(handle,open,openWithAuth)}catch(err){writeStderrLine(`qwen serve: ${err instanceof Error?err.message:String(err)}`);process.exit(1)}await blockForever()},"handler")};export{parseJoinLink,validateManagedLocalFlags,validateManagedWebFlags,maybeOpenWebShellBrowser,serveCommand};
5
5
  /**
6
6
  * @license
7
7
  * Copyright 2026 Qwen Team
@@ -1,6 +1,6 @@
1
1
  // Force strict mode and setup for ESM
2
2
  "use strict";
3
- import{t}from"./chunk-ABJGFEES.js";import{computeThresholds,estimateContextTextTokens,formatContextFileDisplayPath,getAutoMemorySnapshot,getMainSessionBaseSystemPrompt,withoutAutoMemorySnapshots}from"./chunk-Z5XENA4A.js";import{stripTerminalControlSequences}from"./chunk-R2EHHA2C.js";import{qualifySkillName}from"./chunk-CV2UAEZA.js";import{isMediaPolicyToolHiddenFromModel}from"./chunk-S2ZKZXHX.js";import{DiscoveredMCPTool,uiTelemetryService}from"./chunk-ZWPSBU7K.js";import{getAllMemoryFilenames}from"./chunk-Y6HHV4LC.js";import{resolveSlimmingConfig}from"./chunk-Q6UAOTP3.js";import{DEFAULT_TOKEN_LIMIT}from"./chunk-GOR7FFVE.js";import{AUTO_MEMORY_SNAPSHOT_METADATA,buildAvailableSkillsReminder,getStartupContextLength,isSkillListingReminder}from"./chunk-B3ZFUGTC.js";import{ToolNames}from"./chunk-SBZFGYYS.js";import{Storage}from"./chunk-EPODBRBP.js";import{isSubpath}from"./chunk-OKN3Z5C5.js";import{getErrorMessage}from"./chunk-XYB7GC5U.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import*as path from"node:path";init_esbuild_shims();import*as fs from"node:fs/promises";var EXTENSION_REF_PREFIX="ext:";var EXTENSION_CONTEXT_BUDGET=2e5;var EXTENSION_CONTEXT_FILE_CAP=5e4;function parseExtensionRef(pathName){if(!pathName.startsWith(EXTENSION_REF_PREFIX))return null;const name=pathName.slice(EXTENSION_REF_PREFIX.length);if(!name)return null;return{name}}__name(parseExtensionRef,"parseExtensionRef");function buildExtensionRef(extensionName){return`${EXTENSION_REF_PREFIX}${extensionName}`}__name(buildExtensionRef,"buildExtensionRef");function matchExtensionByRef(name,extensions){const lower=name.toLowerCase();return extensions.find(ext=>ext.name.toLowerCase()===lower||ext.config.name.toLowerCase()===lower)}__name(matchExtensionByRef,"matchExtensionByRef");var BIDI_CONTROL_RE=/[‎‏؜⁦⁧⁨⁩‪‫‬‭‮]/g;function sanitizeDisplayText(raw){const stripped=stripTerminalControlSequences(raw).replace(BIDI_CONTROL_RE,"").replace(/\s+/g," ").trim();return stripped.length>0?stripped:null}__name(sanitizeDisplayText,"sanitizeDisplayText");function getSanitizedExtensionDisplayName(extension){return sanitizeDisplayText(extension.displayName||extension.name)||extension.name}__name(getSanitizedExtensionDisplayName,"getSanitizedExtensionDisplayName");function buildExtensionContextText(extension){const displayName=getSanitizedExtensionDisplayName(extension);const lines=[];lines.push(`--- Extension: ${displayName} (untrusted third-party content) ---`);if(extension.config.description){const desc=sanitizeDisplayText(extension.config.description);if(desc){lines.push(desc);lines.push("")}}const capabilities=[];if(extension.skills&&extension.skills.length>0){const skillNames=extension.skills.map(s=>sanitizeDisplayText(qualifySkillName(extension.name,s.name))||s.name).join(", ");capabilities.push(`- Skills: ${skillNames} (invoke via /<skill-name>)`)}if(extension.mcpServers&&Object.keys(extension.mcpServers).length>0){const serverNames=Object.keys(extension.mcpServers).map(n=>sanitizeDisplayText(n)||n).join(", ");capabilities.push(`- MCP Servers: ${serverNames}`)}if(extension.agents&&extension.agents.length>0){const agentNames=extension.agents.map(a=>sanitizeDisplayText(a.name)||a.name).join(", ");capabilities.push(`- Agents: ${agentNames}`)}if(capabilities.length>0){lines.push("Available capabilities from this extension:");lines.push(...capabilities);lines.push("")}lines.push(`--- End Extension: ${displayName} ---`);return lines.join("\n")}__name(buildExtensionContextText,"buildExtensionContextText");async function buildExtensionMentionContext(extension,options){let contextText=buildExtensionContextText(extension);let remainingBudget=options.remainingBudget;if(extension.contextFiles.length===0){return{text:contextText,remainingBudget}}const fileReads=await Promise.allSettled(extension.contextFiles.map(async contextFilePath=>{let realPath;let realExtPath;try{realPath=await fs.realpath(contextFilePath);realExtPath=await fs.realpath(extension.path)}catch{options.onDebugMessage?.(`Skipping unreadable context file: ${contextFilePath}`);return null}if(!isSubpath(realExtPath,realPath)){options.onDebugMessage?.(`Skipping context file outside extension directory: ${contextFilePath}`);return null}return fs.readFile(realPath,{encoding:"utf-8",signal:options.signal})}));for(let i=0;i<fileReads.length;i++){const outcome=fileReads[i];if(outcome.status==="rejected"){options.onDebugMessage?.(`Failed to read extension context file ${extension.contextFiles[i]}: ${getErrorMessage(outcome.reason)}`);continue}const content=outcome.value;if(!content||!content.trim())continue;if(remainingBudget<=0){options.onDebugMessage?.("Extension context budget exhausted, skipping remaining files.");break}const cap=Math.min(EXTENSION_CONTEXT_FILE_CAP,remainingBudget);const cappedContent=content.length>cap?content.slice(0,cap)+"\n... (truncated)":content;contextText+=`
3
+ import{t}from"./chunk-NO7VTKRL.js";import{computeThresholds,estimateContextTextTokens,formatContextFileDisplayPath,getAutoMemorySnapshot,getMainSessionBaseSystemPrompt,withoutAutoMemorySnapshots}from"./chunk-2JGTWRZJ.js";import{stripTerminalControlSequences}from"./chunk-R2EHHA2C.js";import{qualifySkillName}from"./chunk-CV2UAEZA.js";import{isMediaPolicyToolHiddenFromModel}from"./chunk-S2ZKZXHX.js";import{DiscoveredMCPTool,uiTelemetryService}from"./chunk-ZWPSBU7K.js";import{getAllMemoryFilenames}from"./chunk-Y6HHV4LC.js";import{resolveSlimmingConfig}from"./chunk-Q6UAOTP3.js";import{DEFAULT_TOKEN_LIMIT}from"./chunk-GOR7FFVE.js";import{AUTO_MEMORY_SNAPSHOT_METADATA,buildAvailableSkillsReminder,getStartupContextLength,isSkillListingReminder}from"./chunk-B3ZFUGTC.js";import{ToolNames}from"./chunk-SBZFGYYS.js";import{Storage}from"./chunk-EPODBRBP.js";import{isSubpath}from"./chunk-OKN3Z5C5.js";import{getErrorMessage}from"./chunk-XYB7GC5U.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import*as path from"node:path";init_esbuild_shims();import*as fs from"node:fs/promises";var EXTENSION_REF_PREFIX="ext:";var EXTENSION_CONTEXT_BUDGET=2e5;var EXTENSION_CONTEXT_FILE_CAP=5e4;function parseExtensionRef(pathName){if(!pathName.startsWith(EXTENSION_REF_PREFIX))return null;const name=pathName.slice(EXTENSION_REF_PREFIX.length);if(!name)return null;return{name}}__name(parseExtensionRef,"parseExtensionRef");function buildExtensionRef(extensionName){return`${EXTENSION_REF_PREFIX}${extensionName}`}__name(buildExtensionRef,"buildExtensionRef");function matchExtensionByRef(name,extensions){const lower=name.toLowerCase();return extensions.find(ext=>ext.name.toLowerCase()===lower||ext.config.name.toLowerCase()===lower)}__name(matchExtensionByRef,"matchExtensionByRef");var BIDI_CONTROL_RE=/[‎‏؜⁦⁧⁨⁩‪‫‬‭‮]/g;function sanitizeDisplayText(raw){const stripped=stripTerminalControlSequences(raw).replace(BIDI_CONTROL_RE,"").replace(/\s+/g," ").trim();return stripped.length>0?stripped:null}__name(sanitizeDisplayText,"sanitizeDisplayText");function getSanitizedExtensionDisplayName(extension){return sanitizeDisplayText(extension.displayName||extension.name)||extension.name}__name(getSanitizedExtensionDisplayName,"getSanitizedExtensionDisplayName");function buildExtensionContextText(extension){const displayName=getSanitizedExtensionDisplayName(extension);const lines=[];lines.push(`--- Extension: ${displayName} (untrusted third-party content) ---`);if(extension.config.description){const desc=sanitizeDisplayText(extension.config.description);if(desc){lines.push(desc);lines.push("")}}const capabilities=[];if(extension.skills&&extension.skills.length>0){const skillNames=extension.skills.map(s=>sanitizeDisplayText(qualifySkillName(extension.name,s.name))||s.name).join(", ");capabilities.push(`- Skills: ${skillNames} (invoke via /<skill-name>)`)}if(extension.mcpServers&&Object.keys(extension.mcpServers).length>0){const serverNames=Object.keys(extension.mcpServers).map(n=>sanitizeDisplayText(n)||n).join(", ");capabilities.push(`- MCP Servers: ${serverNames}`)}if(extension.agents&&extension.agents.length>0){const agentNames=extension.agents.map(a=>sanitizeDisplayText(a.name)||a.name).join(", ");capabilities.push(`- Agents: ${agentNames}`)}if(capabilities.length>0){lines.push("Available capabilities from this extension:");lines.push(...capabilities);lines.push("")}lines.push(`--- End Extension: ${displayName} ---`);return lines.join("\n")}__name(buildExtensionContextText,"buildExtensionContextText");async function buildExtensionMentionContext(extension,options){let contextText=buildExtensionContextText(extension);let remainingBudget=options.remainingBudget;if(extension.contextFiles.length===0){return{text:contextText,remainingBudget}}const fileReads=await Promise.allSettled(extension.contextFiles.map(async contextFilePath=>{let realPath;let realExtPath;try{realPath=await fs.realpath(contextFilePath);realExtPath=await fs.realpath(extension.path)}catch{options.onDebugMessage?.(`Skipping unreadable context file: ${contextFilePath}`);return null}if(!isSubpath(realExtPath,realPath)){options.onDebugMessage?.(`Skipping context file outside extension directory: ${contextFilePath}`);return null}return fs.readFile(realPath,{encoding:"utf-8",signal:options.signal})}));for(let i=0;i<fileReads.length;i++){const outcome=fileReads[i];if(outcome.status==="rejected"){options.onDebugMessage?.(`Failed to read extension context file ${extension.contextFiles[i]}: ${getErrorMessage(outcome.reason)}`);continue}const content=outcome.value;if(!content||!content.trim())continue;if(remainingBudget<=0){options.onDebugMessage?.("Extension context budget exhausted, skipping remaining files.");break}const cap=Math.min(EXTENSION_CONTEXT_FILE_CAP,remainingBudget);const cappedContent=content.length>cap?content.slice(0,cap)+"\n... (truncated)":content;contextText+=`
4
4
 
5
5
  ${cappedContent}`;remainingBudget-=cappedContent.length}return{text:contextText,remainingBudget}}__name(buildExtensionMentionContext,"buildExtensionMentionContext");function currentTier(tokens,thresholds){if(tokens>=thresholds.hard)return"hard";if(tokens>=thresholds.auto)return"auto";if(tokens>=thresholds.warn)return"warn";return"safe"}__name(currentTier,"currentTier");function extensionContextFileOwners(config,workingDir){const owners=new Map;for(const extension of config.getActiveExtensions?.()??[]){const displayName=getSanitizedExtensionDisplayName(extension);for(const contextFile of extension.contextFiles??[]){const absolutePath=path.resolve(workingDir,contextFile);const fileLabel=formatContextFileDisplayPath(absolutePath,extension.path);owners.set(absolutePath,`${t("Extension")}: ${displayName} \xB7 ${fileLabel}`)}}return owners}__name(extensionContextFileOwners,"extensionContextFileOwners");function parseMemoryFiles(memoryContent,workingDir,extensionOwners=new Map,admissionRoot=workingDir){if(!memoryContent||memoryContent.trim().length===0)return[];const results=[];const root=path.resolve(admissionRoot);const globalDir=path.resolve(Storage.getGlobalQwenDir());const memoryFilenames=new Set(getAllMemoryFilenames());const openablePath=__name(absolutePath=>isSubpath(root,absolutePath)||path.resolve(path.dirname(absolutePath))===globalDir&&memoryFilenames.has(path.basename(absolutePath))?absolutePath:void 0,"openablePath");const regex=/--- Context from: (.+?) ---\n([\s\S]*?)--- End of Context from: \1 ---/g;let match;while((match=regex.exec(memoryContent))!==null){const filePath=match[1];const content=match[2];const absolutePath=path.resolve(workingDir,filePath);const owner=extensionOwners.get(absolutePath);const openPath=openablePath(absolutePath);results.push({path:owner??formatContextFileDisplayPath(absolutePath,workingDir),tokens:estimateContextTextTokens(content),...openPath!==void 0?{absolutePath:openPath}:{}})}if(results.length===0&&memoryContent.trim().length>0){results.push({path:t("memory"),tokens:estimateContextTextTokens(memoryContent)})}return results}__name(parseMemoryFiles,"parseMemoryFiles");function unescapeXml(text){return text.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&amp;/g,"&")}__name(unescapeXml,"unescapeXml");var SKILL_LISTING_ENTRY=/<skill>\n<name>\n([\s\S]*?)\n<\/name>[\s\S]*?<\/skill>/g;function measureSkillListing(text){const byName=new Map;for(const match of text.matchAll(SKILL_LISTING_ENTRY)){const name=unescapeXml(match[1]);byName.set(name.toLowerCase(),{name,tokens:estimateContextTextTokens(match[0])})}return{tokens:estimateContextTextTokens(text),byName}}__name(measureSkillListing,"measureSkillListing");function mergeSkillListing(into,from){into.tokens+=from.tokens;for(const[name,entry]of from.byName){into.byName.set(name,entry)}}__name(mergeSkillListing,"mergeSkillListing");function measureTailSkillListings(conversation){const listing={tokens:0,byName:new Map};const billedTexts=new Set;for(const content of conversation){for(const part of content.parts??[]){const text=part.text;if(typeof text!=="string"||!isSkillListingReminder(text))continue;const measured=measureSkillListing(text);if(measured.byName.size===0)continue;mergeSkillListing(listing,measured);billedTexts.add(text)}}return{listing,billedTexts}}__name(measureTailSkillListings,"measureTailSkillListings");function measureStartupPrelude(prelude){const skillListing={tokens:0,byName:new Map};let startupContextTokens=0;for(const content of prelude){for(const part of content.parts??[]){if(typeof part.text!=="string")continue;if(isSkillListingReminder(part.text)){mergeSkillListing(skillListing,measureSkillListing(part.text))}else{startupContextTokens+=estimateContextTextTokens(part.text)}}}return{skillListing,startupContextTokens}}__name(measureStartupPrelude,"measureStartupPrelude");function estimateFunctionResponseTokens(part,imageTokenEstimate){const response=part.functionResponse;let tokens=estimateContextTextTokens(JSON.stringify({id:response.id,name:response.name,response:response.response}));const nested=response.parts;if(Array.isArray(nested)){for(const inner of nested){if(inner.inlineData||inner.fileData){tokens+=imageTokenEstimate}else if(typeof inner.text==="string"){tokens+=estimateContextTextTokens(inner.text)}}}return tokens}__name(estimateFunctionResponseTokens,"estimateFunctionResponseTokens");function consumeBilledSkillBody(part,billedSkillBodies){if(billedSkillBodies.size===0)return false;const output=part.functionResponse?.response?.output;if(typeof output!=="string")return false;if(billedSkillBodies.delete(output))return true;for(const body of billedSkillBodies){if(output.startsWith(`${body}
6
6
  `)){billedSkillBodies.delete(body);return true}}return false}__name(consumeBilledSkillBody,"consumeBilledSkillBody");function estimateConversationTokens(conversation,billing){let tokens=0;const remainingSkillBodies=new Set(billing.billedSkillBodies);for(const content of conversation){for(const part of content.parts??[]){if(typeof part.text==="string"){if(billing.billedListingTexts.has(part.text))continue;tokens+=estimateContextTextTokens(part.text)}else if(part.inlineData||part.fileData){tokens+=billing.imageTokenEstimate}else if(part.functionCall){tokens+=estimateContextTextTokens(JSON.stringify(part.functionCall))}else if(part.functionResponse){if(part.functionResponse.name===ToolNames.SKILL&&consumeBilledSkillBody(part,remainingSkillBodies)){continue}tokens+=estimateFunctionResponseTokens(part,billing.imageTokenEstimate)}}}return tokens}__name(estimateConversationTokens,"estimateConversationTokens");async function collectContextData(config,showDetails){const modelName=config.getModel()||"unknown";const contentGeneratorConfig=config.getContentGeneratorConfig();const contextWindowSize=contentGeneratorConfig.contextWindowSize??DEFAULT_TOKEN_LIMIT;const llmClient=config.getLlmClient?.();const activeChat=llmClient?.isInitialized?.()?llmClient.getChat():void 0;const apiTotalTokens=activeChat?activeChat.getLastPromptTokenCount():uiTelemetryService.getLastPromptTokenCount();const apiCachedTokens=activeChat?.getLastCachedContentTokenCount?.()??uiTelemetryService.getLastCachedContentTokenCount();const history=activeChat?.getHistoryShallow?.()??activeChat?.getHistory?.()??[];const preludeLength=getStartupContextLength(history);const prelude=measureStartupPrelude(withoutAutoMemorySnapshots(history.slice(0,preludeLength)));const conversationHistory=withoutAutoMemorySnapshots(history.slice(preludeLength));const tailSkillListings=measureTailSkillListings(conversationHistory);let conversationTokens=0;const systemPromptText=getMainSessionBaseSystemPrompt(config);const systemPromptTokens=estimateContextTextTokens(systemPromptText);const toolRegistry=config.getToolRegistry();const allTools=toolRegistry?toolRegistry.getAllTools():[];const toolDeclarations=toolRegistry?toolRegistry.getFunctionDeclarations():[];const toolsJsonStr=JSON.stringify(toolDeclarations);const allToolsTokens=estimateContextTextTokens(toolsJsonStr);const builtinTools=[];const mcpTools=[];for(const tool of allTools){if(toolRegistry?.isDeferredAndHidden(tool.name)){continue}if(isMediaPolicyToolHiddenFromModel(config,tool)){continue}const toolJsonStr=JSON.stringify(tool.schema);const tokens=estimateContextTextTokens(toolJsonStr);if(tool instanceof DiscoveredMCPTool){mcpTools.push({name:`${tool.serverName}__${tool.serverToolName||tool.name}`,tokens})}else if(tool.name!==ToolNames.SKILL){builtinTools.push({name:tool.name,tokens})}}const memoryContent=config.getUserMemory();const instructionFiles=parseMemoryFiles(memoryContent,config.getWorkingDir(),extensionContextFileOwners(config,config.getWorkingDir()),config.storage.getProjectRoot());const memoryFiles=[];const instructionFilesTokens=instructionFiles.reduce((sum,f)=>sum+f.tokens,0);const catalog=config.getAutoMemoryContext?.()??"";const snapshots=catalog?history.flatMap(content=>(content.parts??[]).filter(part=>part.partMetadata?.[AUTO_MEMORY_SNAPSHOT_METADATA]===true)):[];const pendingSnapshot=getAutoMemorySnapshot(history,catalog);if(pendingSnapshot)snapshots.push(pendingSnapshot);const autoMemoryTokens=estimateContextTextTokens(config.getAutoMemoryPrompt())+snapshots.reduce((sum,part)=>sum+estimateContextTextTokens(part.text??""),0);if(autoMemoryTokens>0){memoryFiles.push({path:t("auto memory"),tokens:autoMemoryTokens})}const memoryFilesTokens=memoryFiles.reduce((sum,f)=>sum+f.tokens,0);const skillTool=allTools.find(tool=>tool.name===ToolNames.SKILL);const skillToolDefinitionTokens=skillTool?estimateContextTextTokens(JSON.stringify(skillTool.schema)):0;const loadedContentNames=skillTool&&"getLoadedSkillContentNames"in skillTool?skillTool.getLoadedSkillContentNames():new Map;const bodyTokensByName=new Map;for(const[content,name]of loadedContentNames){bodyTokensByName.set(name,(bodyTokensByName.get(name)??0)+estimateContextTextTokens(content))}const loadedBodiesTokens=[...bodyTokensByName.values()].reduce((sum,tokens)=>sum+tokens,0);const skillManager=config.getSkillManager();const skillConfigs=skillManager?await skillManager.listSkills():[];const enabledSkillNames=new Set(skillConfigs.filter(skill=>config.isSkillEnabled(skill)).map(skill=>skill.name.toLowerCase()));let skillListing=prelude.skillListing;if(!activeChat){const reminder=await buildAvailableSkillsReminder(config);if(reminder){skillListing=measureSkillListing(reminder.reminder)}}mergeSkillListing(skillListing,tailSkillListings.listing);const billedSkillBodies=new Set(loadedContentNames.keys());const skills=skillConfigs.map(skill=>{const listingTokens=skillListing.byName.get(skill.name.toLowerCase())?.tokens??0;const bodyTokens=bodyTokensByName.get(skill.name);const isLoaded=bodyTokens!==void 0;return{name:skill.name,tokens:listingTokens,loaded:isLoaded,bodyTokens}});const discoveredNames=new Set(skillConfigs.map(skill=>skill.name));for(const[name,bodyTokens]of bodyTokensByName){if(!discoveredNames.has(name)){skills.push({name,tokens:skillListing.byName.get(name.toLowerCase())?.tokens??0,loaded:true,bodyTokens})}}const rowedNames=new Set(skills.map(s=>s.name.toLowerCase()));for(const[key,entry]of skillListing.byName){enabledSkillNames.add(key);if(rowedNames.has(key))continue;rowedNames.add(key);skills.push({name:entry.name,tokens:entry.tokens,loaded:false})}conversationTokens=estimateConversationTokens(conversationHistory,{imageTokenEstimate:resolveSlimmingConfig(config.getChatCompression?.()).imageTokenEstimate,billedSkillBodies,billedListingTexts:tailSkillListings.billedTexts});const skillsTokens=skillToolDefinitionTokens+skillListing.tokens+loadedBodiesTokens;const startupContextTokens=prelude.startupContextTokens;const thresholds=computeThresholds(contextWindowSize,config.getAutoCompactThreshold());const autocompactBuffer=Math.max(0,Math.round(contextWindowSize-thresholds.auto));const rawOverhead=systemPromptTokens+allToolsTokens+instructionFilesTokens+memoryFilesTokens+skillListing.tokens+loadedBodiesTokens+startupContextTokens;const rawContent=rawOverhead+conversationTokens;const hasTokenCount=apiTotalTokens>0;const isEstimated=!hasTokenCount||activeChat?.isLastPromptTokenCountEstimated()===true;const mcpToolsTotalTokens=mcpTools.reduce((sum,tool)=>sum+tool.tokens,0);let totalTokens;let displaySystemPrompt;let displayBuiltinTools;let displayMcpTools;let displayInstructionFiles;let displayMemoryFiles;let displaySkills;let displayStartupContext;let messagesTokens;let unattributedTokens=0;let freeSpace;let detailBuiltinTools;let detailMcpTools;let detailInstructionFiles;let detailMemoryFiles;let detailSkills;const clampDeficit=Math.max(0,skillToolDefinitionTokens+mcpToolsTotalTokens-allToolsTokens);const clampedMcpTools=Math.max(0,mcpToolsTotalTokens-clampDeficit);const clampedSkills=skillsTokens-Math.max(0,clampDeficit-mcpToolsTotalTokens);const clampedBuiltinTools=Math.max(0,allToolsTokens-skillToolDefinitionTokens-clampedMcpTools);const mcpDetailShare=mcpToolsTotalTokens>0?clampedMcpTools/mcpToolsTotalTokens:1;const scaleTokens=__name((items,factor)=>factor<1?items.map(item=>({...item,tokens:Math.round(item.tokens*factor)})):items,"scaleTokens");if(!hasTokenCount){totalTokens=0;displaySystemPrompt=systemPromptTokens;displaySkills=clampedSkills;displayStartupContext=startupContextTokens;displayBuiltinTools=clampedBuiltinTools;displayMcpTools=clampedMcpTools;displayInstructionFiles=instructionFilesTokens;displayMemoryFiles=memoryFilesTokens;messagesTokens=conversationTokens;freeSpace=Math.max(0,contextWindowSize-rawContent-autocompactBuffer);detailBuiltinTools=builtinTools;detailMcpTools=scaleTokens(mcpTools,mcpDetailShare);detailInstructionFiles=instructionFiles;detailMemoryFiles=memoryFiles;detailSkills=skills}else{totalTokens=apiTotalTokens;const scale=rawOverhead>totalTokens?totalTokens/rawOverhead:1;displaySystemPrompt=Math.floor(systemPromptTokens*scale);displayBuiltinTools=Math.floor(clampedBuiltinTools*scale);displayMcpTools=Math.floor(clampedMcpTools*scale);displayInstructionFiles=Math.floor(instructionFilesTokens*scale);displayMemoryFiles=Math.floor(memoryFilesTokens*scale);displaySkills=Math.floor(clampedSkills*scale);displayStartupContext=Math.floor(startupContextTokens*scale);const attributedOverhead=displaySystemPrompt+displayBuiltinTools+displayMcpTools+displayInstructionFiles+displayMemoryFiles+displaySkills+displayStartupContext;if(scale<1){messagesTokens=Math.max(0,totalTokens-attributedOverhead)}else{messagesTokens=Math.min(conversationTokens,Math.max(0,totalTokens-attributedOverhead));unattributedTokens=Math.max(0,totalTokens-attributedOverhead-messagesTokens)}freeSpace=Math.max(0,contextWindowSize-totalTokens-autocompactBuffer);detailBuiltinTools=scaleTokens(builtinTools,scale);detailMcpTools=scaleTokens(mcpTools,scale*mcpDetailShare);detailInstructionFiles=scaleTokens(instructionFiles,scale);detailMemoryFiles=scaleTokens(memoryFiles,scale);detailSkills=scale<1?skills.map(item=>({...item,tokens:Math.round(item.tokens*scale),bodyTokens:item.bodyTokens?Math.round(item.bodyTokens*scale):void 0})):skills}const tierTokens=hasTokenCount?apiTotalTokens:rawContent;const breakdown={systemPrompt:displaySystemPrompt,builtinTools:displayBuiltinTools,mcpTools:displayMcpTools,instructionFiles:displayInstructionFiles,memoryFiles:displayMemoryFiles,skills:displaySkills,startupContext:displayStartupContext,messages:messagesTokens,unattributed:unattributedTokens,cachedTokens:hasTokenCount?apiCachedTokens:0,freeSpace,autocompactBuffer,thresholds,currentTier:currentTier(tierTokens,thresholds)};return{type:"context_usage",modelName,totalTokens,contextWindowSize,breakdown,builtinTools:showDetails?detailBuiltinTools:[],mcpTools:showDetails?detailMcpTools:[],instructionFiles:showDetails?detailInstructionFiles:[],memoryFiles:showDetails?detailMemoryFiles:[],skills:showDetails?detailSkills.filter(skill=>skill.loaded||enabledSkillNames.has(skill.name.toLowerCase())):[],isEstimated,showDetails}}__name(collectContextData,"collectContextData");function fmtTokens(tokens){if(tokens>=999950){return`${(tokens/1e6).toFixed(1)}m`}if(tokens>=1e3){return`${(tokens/1e3).toFixed(1)}k`}return`${tokens}`}__name(fmtTokens,"fmtTokens");function fmtCategoryRow(label,tokens,contextWindowSize,indent=" "){const percentage=contextWindowSize>0?(tokens/contextWindowSize*100).toFixed(1):"0.0";const right=`${fmtTokens(tokens)} tokens (${percentage}%)`;const leftPart=`${indent}${label}`;const totalWidth=56;const dots=Math.max(1,totalWidth-leftPart.length-right.length);return`${leftPart}${" ".repeat(dots)}${right}`}__name(fmtCategoryRow,"fmtCategoryRow");function formatNum(n){return Math.round(n).toLocaleString("en-US")}__name(formatNum,"formatNum");function formatContextUsageText(data){const{modelName,totalTokens,contextWindowSize,breakdown,builtinTools,mcpTools,instructionFiles=[],memoryFiles,skills,isEstimated,showDetails}=data;const hasTokenCount=totalTokens>0;const memoryLabel=breakdown.instructionFiles===void 0?"Memory files":"Auto memory";const lines=[];lines.push("## Context Usage");lines.push("");if(!hasTokenCount){const includesConversation=breakdown.messages>0;lines.push(includesConversation?"*No provider usage yet. These are local estimates, including the conversation.*":"*No API response yet. Send a message to see actual usage.*");lines.push("");lines.push(includesConversation?"**Estimated usage, including the conversation**":"**Estimated pre-conversation overhead**");lines.push(`Model: ${modelName} Context window: ${fmtTokens(contextWindowSize)} tokens`);lines.push("")}else{lines.push(`Model: ${modelName} Context window: ${fmtTokens(contextWindowSize)} tokens`);lines.push("");if(isEstimated){lines.push("*Token usage is estimated until provider usage is received.*");lines.push("")}lines.push(fmtCategoryRow("Used",totalTokens,contextWindowSize));if((breakdown.cachedTokens??0)>0){lines.push(fmtCategoryRow("Cached prefix",breakdown.cachedTokens,contextWindowSize," \u2514 "))}lines.push(fmtCategoryRow("Free",breakdown.freeSpace,contextWindowSize));lines.push("");lines.push("**Compaction thresholds**");lines.push(` Effective window: ${formatNum(breakdown.thresholds.effectiveWindow)} (window \u2212 ${formatNum(contextWindowSize-breakdown.thresholds.effectiveWindow)} reserve)`);lines.push(` Warn threshold: ${formatNum(breakdown.thresholds.warn)}`);lines.push(` Auto threshold: ${formatNum(breakdown.thresholds.auto)}`);lines.push(` Hard threshold: ${formatNum(breakdown.thresholds.hard)}`);lines.push(` Current tier: ${breakdown.currentTier}`);lines.push("");lines.push("**Usage by category**")}lines.push(fmtCategoryRow("System prompt",breakdown.systemPrompt,contextWindowSize));lines.push(fmtCategoryRow("Built-in tools",breakdown.builtinTools,contextWindowSize));if(breakdown.mcpTools>0){lines.push(fmtCategoryRow("MCP tools",breakdown.mcpTools,contextWindowSize))}if(breakdown.instructionFiles!==void 0){lines.push(fmtCategoryRow("Instruction files",breakdown.instructionFiles,contextWindowSize))}lines.push(fmtCategoryRow(memoryLabel,breakdown.memoryFiles,contextWindowSize));lines.push(fmtCategoryRow("Skills",breakdown.skills,contextWindowSize));if((breakdown.startupContext??0)>0){lines.push(fmtCategoryRow("Startup context",breakdown.startupContext,contextWindowSize))}if(hasTokenCount||breakdown.messages>0){lines.push(fmtCategoryRow("Messages",breakdown.messages,contextWindowSize));if((breakdown.unattributed??0)>0){lines.push(fmtCategoryRow("Unattributed",breakdown.unattributed,contextWindowSize))}}if(showDetails){const sortedBuiltin=[...builtinTools].sort((a,b)=>b.tokens-a.tokens);const sortedMcp=[...mcpTools].sort((a,b)=>b.tokens-a.tokens);const sortedMemory=[...memoryFiles].sort((a,b)=>b.tokens-a.tokens);const sortedSkills=[...skills].sort((a,b)=>{if(!a.loaded!==!b.loaded)return a.loaded?-1:1;return b.tokens+(b.bodyTokens??0)-(a.tokens+(a.bodyTokens??0))});if(sortedBuiltin.length>0){lines.push("");lines.push("**Built-in tools**");for(const tool of sortedBuiltin){lines.push(fmtCategoryRow(tool.name,tool.tokens,contextWindowSize," \u2514 "))}}if(sortedMcp.length>0){lines.push("");lines.push("**MCP tools**");for(const tool of sortedMcp){lines.push(fmtCategoryRow(tool.name,tool.tokens,contextWindowSize," \u2514 "))}}if(instructionFiles.length>0){lines.push("","**Instruction files**");for(const file of[...instructionFiles].sort((a,b)=>b.tokens-a.tokens)){lines.push(fmtCategoryRow(file.path,file.tokens,contextWindowSize," \u2514 "))}}if(sortedMemory.length>0){lines.push("");lines.push("**"+memoryLabel+"**");for(const file of sortedMemory){lines.push(fmtCategoryRow(file.path,file.tokens,contextWindowSize," \u2514 "))}}if(sortedSkills.length>0){lines.push("");lines.push("**Skills**");for(const skill of sortedSkills){lines.push(fmtCategoryRow(skill.name,skill.tokens,contextWindowSize," \u2514 "));if(skill.loaded&&skill.bodyTokens&&skill.bodyTokens>0){lines.push(fmtCategoryRow("body loaded",skill.bodyTokens,contextWindowSize," \u2514 "))}}}}else{lines.push("");lines.push("*Run /context detail for per-item breakdown.*")}return lines.join("\n")}__name(formatContextUsageText,"formatContextUsageText");var contextCommand={name:"context",get description(){return t('Show context window usage breakdown. Use "/context detail" for per-item breakdown.')},kind:"built-in",supportedModes:["interactive","non_interactive","acp"],action:__name(async(context,args)=>{const normalizedArgs=args?.trim().toLowerCase();const showDetails=normalizedArgs==="detail"||normalizedArgs==="-d";const executionMode=context.executionMode??"interactive";const{config}=context.services;if(!config){if(executionMode==="interactive"){context.ui.addItem({type:"error",text:t("Config not loaded.")},Date.now());return}return{type:"message",messageType:"error",content:t("Config not loaded.")}}const contextUsageItem=await collectContextData(config,showDetails);if(executionMode==="interactive"){context.ui.addItem(contextUsageItem,Date.now());return}return{type:"message",messageType:"info",content:formatContextUsageText(contextUsageItem)}},"action"),subCommands:[{name:"detail",get description(){return t("Show per-item context usage breakdown.")},kind:"built-in",supportedModes:["interactive","non_interactive","acp"],action:__name(async context=>{await contextCommand.action(context,"detail")},"action")}]};export{EXTENSION_CONTEXT_BUDGET,parseExtensionRef,buildExtensionRef,matchExtensionByRef,sanitizeDisplayText,getSanitizedExtensionDisplayName,buildExtensionMentionContext,collectContextData,formatContextUsageText,contextCommand};
@@ -1,6 +1,6 @@
1
1
  // Force strict mode and setup for ESM
2
2
  "use strict";
3
- import{formatUnsupportedVoiceModelMessage,isTranscribableVoiceModel,readVoiceLanguage,resolveVoiceTransport}from"./chunk-E5YRAQXM.js";import{resolvePath}from"./chunk-G2SXDY2E.js";import{createDebugLogger}from"./chunk-JAUJI56S.js";import{isSubpath}from"./chunk-OKN3Z5C5.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import process from"node:process";import{lookup as dnsLookup}from"node:dns/promises";import{BlockList,isIP}from"node:net";init_esbuild_shims();import*as fs from"node:fs";import*as path from"node:path";var GLOBAL_KEYTERMS=["Qwen","MCP","grep","regex","localhost","codebase","TypeScript","JavaScript","JSON","YAML","OAuth","webhook","gRPC","dotfiles","subagent","worktree","stdout","stderr","async","await","API","CLI","npm","pnpm","commit","rebase","refactor","endpoint","middleware","schema","tokenizer"];var DEFAULT_KEYTERMS_FILENAME="voice-keyterms.txt";var MAX_KEYTERMS=200;var MAX_KEYTERMS_BYTES=2e3;var MAX_KEYTERMS_FILE_BYTES=64*1024;function buildVoiceKeyterms(settings){const userTerms=settings?readUserKeyterms(settings):[];return capKeyterms(dedupeKeyterms([...GLOBAL_KEYTERMS,...userTerms]))}__name(buildVoiceKeyterms,"buildVoiceKeyterms");function dedupeKeyterms(terms){const seen=new Set;const out=[];for(const term of terms){const key=term.toLowerCase();if(seen.has(key)){continue}seen.add(key);out.push(term)}return out}__name(dedupeKeyterms,"dedupeKeyterms");function capKeyterms(terms){const out=[];let bytes=0;for(const term of terms){if(out.length>=MAX_KEYTERMS){break}const next=bytes+Buffer.byteLength(term,"utf8")+(out.length>0?1:0);if(next>MAX_KEYTERMS_BYTES){continue}out.push(term);bytes=next}return out}__name(capKeyterms,"capKeyterms");function readUserKeyterms(settings){if(!settings.isTrusted){return[]}for(const resolved of resolveKeytermsFiles(settings)){try{const file=canonicalizeKeytermsFile(resolved);if(!file){continue}const content=readRegularFileNoFollow(file);if(content===void 0){continue}const parsed=parseKeyterms(content);if(parsed.length>0){return parsed}}catch{}}return[]}__name(readUserKeyterms,"readUserKeyterms");function resolveKeytermsFiles(settings){const workspacePath=settings.workspace?.path;if(!workspacePath){return[]}const qwenDir=path.dirname(workspacePath);const workspaceRoot=path.dirname(qwenDir);const configured=readKeytermsFileSettings(settings);if(configured.length>0){return configured.map(({path:configuredPath,scope})=>{const expanded=resolvePath(configuredPath);const isAbsolute2=path.isAbsolute(expanded);return{filePath:isAbsolute2?expanded:path.resolve(workspaceRoot,expanded),workspaceRoot,mustBeInWorkspace:scope==="system"||!isAbsolute2}})}return[{filePath:path.join(qwenDir,DEFAULT_KEYTERMS_FILENAME),workspaceRoot,mustBeInWorkspace:true}]}__name(resolveKeytermsFiles,"resolveKeytermsFiles");function canonicalizeKeytermsFile({filePath,workspaceRoot,mustBeInWorkspace}){const stat=fs.lstatSync(filePath,{throwIfNoEntry:false});if(!stat||stat.isSymbolicLink()||!stat.isFile()||stat.nlink>1||stat.size>MAX_KEYTERMS_FILE_BYTES){return void 0}const realFilePath=fs.realpathSync(filePath);if(mustBeInWorkspace){const realWorkspaceRoot=fs.realpathSync(workspaceRoot);if(!isSubpath(realWorkspaceRoot,realFilePath)){return void 0}}return{filePath:realFilePath,stat}}__name(canonicalizeKeytermsFile,"canonicalizeKeytermsFile");function readRegularFileNoFollow({filePath,stat:expectedStat}){let fd;try{let flags=fs.constants.O_RDONLY;if(typeof fs.constants.O_NOFOLLOW==="number"){flags|=fs.constants.O_NOFOLLOW}if(typeof fs.constants.O_NONBLOCK==="number"){flags|=fs.constants.O_NONBLOCK}fd=fs.openSync(filePath,flags);const stat=fs.fstatSync(fd);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){return void 0}const content=fs.readFileSync(fd,"utf-8");if(Buffer.byteLength(content,"utf8")>MAX_KEYTERMS_FILE_BYTES){return void 0}return content}finally{if(fd!==void 0){fs.closeSync(fd)}}}__name(readRegularFileNoFollow,"readRegularFileNoFollow");function parseKeyterms(content){return content.split(/\r?\n/).map(line=>line.replace(/^\s*#.*$/,"").trim()).filter(line=>line.length>0)}__name(parseKeyterms,"parseKeyterms");function readKeytermsFileSettings(settings){const out=[];const system=readKeytermsFileSettingFromScope(settings.system?.settings);if(system){out.push({path:system,scope:"system"})}const user=readKeytermsFileSettingFromScope(settings.user?.settings);if(user){out.push({path:user,scope:"user"})}return out}__name(readKeytermsFileSettings,"readKeytermsFileSettings");function readKeytermsFileSettingFromScope(settings){const value=settings?.general?.voice?.keytermsFile;if(typeof value!=="string"){return void 0}const trimmed=value.trim();return trimmed.length>0?trimmed:void 0}__name(readKeytermsFileSettingFromScope,"readKeytermsFileSettingFromScope");var DEFAULT_OPENAI_API_KEY="OPENAI_API_KEY";var INFERENCE_TIMEOUT_MS=6e4;var MIN_KEYTERM_ECHO_TOKENS=8;var MIN_ABSOLUTE_KEYTERM_ECHO_TOKENS=10;var MIN_KEYTERM_SET_ECHO_RATIO=.3;var debugLogger=createDebugLogger("VOICE_TRANSCRIBER");var BLOCKED_TRANSITION_IPV6_ADDRESSES=new BlockList;for(const[address,prefix]of[["64:ff9b:1::",48],["2001::",23],["2002::",16]]){BLOCKED_TRANSITION_IPV6_ADDRESSES.addSubnet(address,prefix,"ipv6")}function trimTrailingSlashes(value){return value.replace(/\/+$/,"")}__name(trimTrailingSlashes,"trimTrailingSlashes");function readSettingsEnv(settings,envKey){const env=settings.merged.env;const value=env?.[envKey];return typeof value==="string"&&value.trim().length>0?value.trim():void 0}__name(readSettingsEnv,"readSettingsEnv");function isQwenBaseUrl(baseUrl){try{const hostname=new URL(baseUrl).hostname.toLowerCase();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")}catch{return false}}__name(isQwenBaseUrl,"isQwenBaseUrl");function normalizeBaseUrl(baseUrl,modelName){let url;try{url=new URL(baseUrl)}catch{throw new Error(`Voice model '${modelName}' has an invalid baseUrl.`)}if(url.username||url.password){throw new Error(`Voice model '${modelName}' baseUrl must not contain embedded credentials.`)}return trimTrailingSlashes(url.toString())}__name(normalizeBaseUrl,"normalizeBaseUrl");function normalizeAllowedVoiceBaseUrl(baseUrl){try{const url=new URL(baseUrl.trim());if(url.username||url.password){return void 0}return trimTrailingSlashes(url.toString())}catch{return void 0}}__name(normalizeAllowedVoiceBaseUrl,"normalizeAllowedVoiceBaseUrl");function isInsecureVoiceBaseUrlAllowed(settings,normalizedBaseUrl){const allowed=settings.merged.security?.allowedInsecureVoiceBaseUrls;return Array.isArray(allowed)&&allowed.some(candidate=>typeof candidate==="string"&&normalizeAllowedVoiceBaseUrl(candidate)===normalizedBaseUrl)}__name(isInsecureVoiceBaseUrlAllowed,"isInsecureVoiceBaseUrlAllowed");function normalizeHostname(hostname){return hostname.toLowerCase().replace(/^\[|\]$/g,"")}__name(normalizeHostname,"normalizeHostname");function normalizeIpAddress(address){const host=normalizeHostname(address);if(isIP(host)!==6){return host}try{return normalizeHostname(new URL(`http://[${host}]/`).hostname)}catch{return host}}__name(normalizeIpAddress,"normalizeIpAddress");function isLoopbackHost(hostname){const host=normalizeHostname(hostname);return host==="localhost"||host==="127.0.0.1"||host==="::1"}__name(isLoopbackHost,"isLoopbackHost");function isAwsIpv6MetadataAddress(hostname){const host=normalizeHostname(hostname);if(isIP(host)!==6){return false}try{return normalizeHostname(new URL(`http://[${host}]/`).hostname)==="fd00:ec2::254"}catch{return false}}__name(isAwsIpv6MetadataAddress,"isAwsIpv6MetadataAddress");function readIpv4CompatibleIpv6(host){if(!host.startsWith("::")||host.startsWith("::ffff:")){return void 0}const parts=host.slice(2).split(":");if(parts.length===0||parts.length>2||parts.some(part=>!part)){return void 0}if(parts.some(part=>!/^[0-9a-f]{1,4}$/i.test(part))){return void 0}const hextets=parts.map(part=>Number.parseInt(part,16));const value=hextets.length===1?hextets[0]:hextets[0]<<16|hextets[1];return[value>>>24&255,value>>>16&255,value>>>8&255,value&255].join(".")}__name(readIpv4CompatibleIpv6,"readIpv4CompatibleIpv6");function readIpv4MappedIpv6(host){const dotted=host.match(/^::ffff:(\d+(?:\.\d+){3})$/i);if(dotted&&isIP(dotted[1])===4){return dotted[1]}const hex=host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);if(!hex){return void 0}return readIpv4HexPair(hex[1],hex[2])}__name(readIpv4MappedIpv6,"readIpv4MappedIpv6");function readIpv4HexPair(highHex,lowHex){const high=Number.parseInt(highHex,16);const low=Number.parseInt(lowHex,16);return[high>>>8,high&255,low>>>8,low&255].join(".")}__name(readIpv4HexPair,"readIpv4HexPair");function readWellKnownNat64Ipv6(host){const prefix="64:ff9b::";if(!host.startsWith(prefix)){return void 0}const suffix=host.slice(prefix.length);if(!suffix){return"0.0.0.0"}const groups=suffix.split(":");if(groups.length>2||groups.some(group=>!/^[0-9a-f]{1,4}$/i.test(group))){return void 0}return groups.length===1?readIpv4HexPair("0",groups[0]):readIpv4HexPair(groups[0],groups[1])}__name(readWellKnownNat64Ipv6,"readWellKnownNat64Ipv6");function isBlockedTransitionIpv6Address(host){return isIP(host)===6&&BLOCKED_TRANSITION_IPV6_ADDRESSES.check(host,"ipv6")}__name(isBlockedTransitionIpv6Address,"isBlockedTransitionIpv6Address");function unwrapIpv6TransitionStep(host){const ipv4Mapped=readIpv4MappedIpv6(host);if(ipv4Mapped){return{address:ipv4Mapped}}const ipv4Compatible=readIpv4CompatibleIpv6(host);if(ipv4Compatible){return{address:ipv4Compatible}}const nat64=readWellKnownNat64Ipv6(host);if(nat64){return{address:nat64}}if(host.startsWith("::ffff:")){return"blocked"}return void 0}__name(unwrapIpv6TransitionStep,"unwrapIpv6TransitionStep");function isPrivateNetworkIp(hostname){const host=normalizeIpAddress(hostname);if(isBlockedTransitionIpv6Address(host)){return true}if(isLoopbackHost(host)){return false}const step=unwrapIpv6TransitionStep(host);if(step==="blocked"){return true}if(step){return isPrivateNetworkIp(step.address)}if(isIP(host)===4){const[first=0,second=0]=host.split(".").map(Number);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}if(isIP(host)===6){const firstHextet=Number.parseInt(host.split(":",1)[0]||"0",16);return host==="::"||(firstHextet&65472)===65152||(firstHextet&65024)===64512}return false}__name(isPrivateNetworkIp,"isPrivateNetworkIp");function isAlwaysBlockedVoiceAddress(address){const host=normalizeIpAddress(address);if(isBlockedTransitionIpv6Address(host)){return true}if(isLoopbackHost(host)){return true}const step=unwrapIpv6TransitionStep(host);if(step==="blocked"){return true}if(step){return isAlwaysBlockedVoiceAddress(step.address)}if(isIP(host)===4){const[first=0,second=0]=host.split(".").map(Number);return first===0||first===127||first===169&&second===254||host==="100.100.100.200"}if(isIP(host)===6){const firstHextet=Number.parseInt(host.split(":",1)[0]||"0",16);return host==="::"||isAwsIpv6MetadataAddress(host)||(firstHextet&65472)===65152}return false}__name(isAlwaysBlockedVoiceAddress,"isAlwaysBlockedVoiceAddress");function isLoopbackVoiceAddress(address){const host=normalizeIpAddress(address);if(isLoopbackHost(host)){return true}const step=unwrapIpv6TransitionStep(host);if(step&&step!=="blocked"){return isLoopbackVoiceAddress(step.address)}if(isIP(host)===4){return host.startsWith("127.")}return false}__name(isLoopbackVoiceAddress,"isLoopbackVoiceAddress");async function defaultLookupHost(hostname){return dnsLookup(hostname,{all:true})}__name(defaultLookupHost,"defaultLookupHost");async function assertVoiceBaseUrlNetworkAllowed(voiceConfig,lookupHost,abortSignal){const hostname=normalizeHostname(new URL(voiceConfig.baseUrl).hostname);if(isLoopbackHost(hostname)){return}if(isIP(hostname)!==0){if(isAlwaysBlockedVoiceAddress(hostname)||!voiceConfig.allowInsecureBaseUrl&&isPrivateNetworkIp(hostname)){throw new Error(isLoopbackVoiceAddress(hostname)?`Voice model '${voiceConfig.model}' uses a loopback address outside the accepted spellings. To use a local ASR endpoint, set the baseUrl to http://localhost, http://127.0.0.1, or http://[::1].`:`Voice model '${voiceConfig.model}' resolved to a private-network address.`)}return}let result;let onAbort;try{if(abortSignal?.aborted){throw abortSignal.reason}const lookup=(lookupHost??defaultLookupHost)(hostname);result=abortSignal?await Promise.race([lookup,new Promise((_resolve,reject)=>{onAbort=__name(()=>reject(abortSignal.reason),"onAbort");if(abortSignal.aborted)onAbort();else abortSignal.addEventListener("abort",onAbort,{once:true})})]):await lookup}catch{if(abortSignal?.aborted){throw abortSignal.reason instanceof Error?abortSignal.reason:new Error("Voice request was aborted.")}throw new Error(`Voice model '${voiceConfig.model}': DNS lookup failed for ${hostname}. Cannot verify network safety.`)}finally{if(onAbort)abortSignal?.removeEventListener("abort",onAbort)}const records=Array.isArray(result)?result:[result];if(records.some(record=>isAlwaysBlockedVoiceAddress(record.address)||!voiceConfig.allowInsecureBaseUrl&&isPrivateNetworkIp(record.address))){throw new Error(records.some(record=>isLoopbackVoiceAddress(record.address))?`Voice model '${voiceConfig.model}' resolved to a loopback address. Loopback DNS results are always blocked; to use a local ASR endpoint, configure an explicit loopback baseUrl: http://localhost, http://127.0.0.1, or http://[::1].`:voiceConfig.allowInsecureBaseUrl&&records.some(record=>isAlwaysBlockedVoiceAddress(record.address))?`Voice model '${voiceConfig.model}' resolved to an address that is always blocked (metadata, link-local, or transition range), even when the baseUrl is listed in security.allowedInsecureVoiceBaseUrls.`:`Voice model '${voiceConfig.model}' resolved to a private-network address.`)}}__name(assertVoiceBaseUrlNetworkAllowed,"assertVoiceBaseUrlNetworkAllowed");function readApiKey(settings,model,baseUrl,env){if(!model.envKey&&!isQwenBaseUrl(baseUrl)){return void 0}const envKey=model.envKey??DEFAULT_OPENAI_API_KEY;const envSource=env??process.env;const envValue=Object.hasOwn(envSource,envKey)?envSource[envKey]:void 0;if(envValue&&envValue.trim().length>0){return envValue.trim()}const settingsEnvValue=readSettingsEnv(settings,envKey);if(settingsEnvValue){return settingsEnvValue}if(!model.envKey&&isQwenBaseUrl(baseUrl)){const authApiKey=settings.merged.security?.auth?.apiKey;return typeof authApiKey==="string"&&authApiKey.trim().length>0?authApiKey.trim():void 0}return void 0}__name(readApiKey,"readApiKey");function resolveVoiceTranscriptionConfig({config,settings,voiceModel,env}){const matches=config.getAllConfiguredModels().filter(model2=>model2.id===voiceModel);if(matches.length===0){throw new Error(`Voice model '${voiceModel}' is not configured. Run /model --voice to choose a configured model.`)}if(matches.length>1){throw new Error(`Voice model '${voiceModel}' is ambiguous.`)}const model=matches[0];if(!isTranscribableVoiceModel(model)){throw new Error(formatUnsupportedVoiceModelMessage(voiceModel))}const baseUrl=model.baseUrl?.trim();if(!baseUrl){throw new Error(`Voice model '${voiceModel}' does not define a baseUrl.`)}const normalizedBaseUrl=normalizeBaseUrl(baseUrl,voiceModel);const parsedBaseUrl=new URL(normalizedBaseUrl);const isLocalhost=isLoopbackHost(parsedBaseUrl.hostname);const allowInsecureBaseUrl=isInsecureVoiceBaseUrlAllowed(settings,normalizedBaseUrl);if(parsedBaseUrl.protocol!=="http:"&&parsedBaseUrl.protocol!=="https:"){throw new Error(`Voice model '${voiceModel}' must use an http or https baseUrl.`)}if(!isLocalhost&&isAlwaysBlockedVoiceAddress(parsedBaseUrl.hostname)){throw new Error(isLoopbackVoiceAddress(parsedBaseUrl.hostname)?`Voice model '${voiceModel}' uses a loopback address outside the accepted spellings. To use a local ASR endpoint, set the baseUrl to http://localhost, http://127.0.0.1, or http://[::1].`:`Voice model '${voiceModel}' must not use a private-network baseUrl.`)}if(parsedBaseUrl.protocol!=="https:"&&!isLocalhost&&!allowInsecureBaseUrl){throw new Error(`Voice model '${voiceModel}' must use an https baseUrl. Voice audio must not be transmitted in cleartext. To trust this managed endpoint, add its exact complete normalized URL (${normalizedBaseUrl}) to security.allowedInsecureVoiceBaseUrls. This setting is only honored from User, System, or SystemDefaults scope settings; Workspace entries are ignored.`)}if(!isLocalhost&&!allowInsecureBaseUrl&&isPrivateNetworkIp(parsedBaseUrl.hostname)){throw new Error(`Voice model '${voiceModel}' must not use a private-network baseUrl. To trust this managed endpoint, add its exact complete normalized URL (${normalizedBaseUrl}) to security.allowedInsecureVoiceBaseUrls. This setting is only honored from User, System, or SystemDefaults scope settings; Workspace entries are ignored.`)}const apiKey=readApiKey(settings,model,normalizedBaseUrl,env);if(model.envKey&&!apiKey){throw new Error(`Voice model '${voiceModel}' requires ${model.envKey}.`)}return{model:voiceModel,baseUrl:normalizedBaseUrl,...apiKey?{apiKey}:{},...allowInsecureBaseUrl?{allowInsecureBaseUrl:true}:{}}}__name(resolveVoiceTranscriptionConfig,"resolveVoiceTranscriptionConfig");function isStreamingVoiceModel(model){const transport=resolveVoiceTransport(model);return transport==="qwen-asr-realtime"||transport==="dashscope-task-realtime"}__name(isStreamingVoiceModel,"isStreamingVoiceModel");function resolveVoiceStreamConfig(args){const base=resolveVoiceTranscriptionConfig(args);const transport=resolveVoiceTransport(base.model);if(transport!=="qwen-asr-realtime"&&transport!=="dashscope-task-realtime"){throw new Error(`Voice model '${base.model}' does not support streaming transcription.`)}const language=resolveLanguageCode(readVoiceLanguage(args.settings));const keytermsContext=transport==="qwen-asr-realtime"?buildKeytermsContext(args.settings):void 0;return{transport,baseUrl:base.baseUrl,model:base.model,...base.apiKey?{apiKey:base.apiKey}:{},...base.allowInsecureBaseUrl?{allowInsecureBaseUrl:true}:{},...language?{language}:{},...keytermsContext?{keytermsContext}:{}}}__name(resolveVoiceStreamConfig,"resolveVoiceStreamConfig");var LANGUAGE_CODES={english:"en",chinese:"zh",mandarin:"zh",cantonese:"yue",japanese:"ja",korean:"ko",french:"fr",german:"de",spanish:"es",italian:"it",portuguese:"pt",russian:"ru",arabic:"ar"};function resolveLanguageCode(language){if(!language){return void 0}const lower=language.toLowerCase();if(LANGUAGE_CODES[lower]){return LANGUAGE_CODES[lower]}return/^[a-z]{2,3}$/.test(lower)?lower:void 0}__name(resolveLanguageCode,"resolveLanguageCode");function buildKeytermsContext(settings){try{const keyterms=buildVoiceKeyterms(settings);return keyterms.length>0?keyterms.join(" "):void 0}catch{return void 0}}__name(buildKeytermsContext,"buildKeytermsContext");function tokenize(value){return value.toLowerCase().replace(/[^\p{L}\p{N}\s]/gu," ").split(/\s+/).filter(Boolean)}__name(tokenize,"tokenize");function isKeytermEcho(transcript,keytermsContext){if(!keytermsContext){return false}const tokens=tokenize(transcript);if(tokens.length<4){return false}const keyset=new Set(tokenize(keytermsContext));const overlap=tokens.filter(t=>keyset.has(t)).length;const transcriptRatio=overlap/tokens.length;const keytermRatio=overlap/keyset.size;const isEcho=overlap>=MIN_KEYTERM_ECHO_TOKENS&&transcriptRatio>=.9&&(keytermRatio>=MIN_KEYTERM_SET_ECHO_RATIO||overlap>=MIN_ABSOLUTE_KEYTERM_ECHO_TOKENS);if(isEcho){const branch=keytermRatio>=MIN_KEYTERM_SET_ECHO_RATIO?"ratio":"absolute";debugLogger.debug(`[voice] dropped likely keyterm echo (${branch}): overlap=${overlap} keysetSize=${keyset.size} transcriptRatio=${transcriptRatio.toFixed(2)} keytermRatio=${keytermRatio.toFixed(2)} text="${transcript}"`)}return isEcho}__name(isKeytermEcho,"isKeytermEcho");var MAX_AUDIO_BYTES=10*1024*1024;var MAX_TRANSCRIPTION_ERROR_LENGTH=200;function escapeRegExp(value){return value.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}__name(escapeRegExp,"escapeRegExp");function sanitizeVoiceErrorMessage(raw,apiKey){let redacted=raw.replace(/Authorization:\s*(?:Bearer|ApiKey|Basic|Token)?\s*\S+/gi,"Authorization: [REDACTED]").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]");if(apiKey){redacted=redacted.replace(new RegExp(escapeRegExp(apiKey),"g"),"[REDACTED]")}return redacted.length>MAX_TRANSCRIPTION_ERROR_LENGTH?`${redacted.slice(0,MAX_TRANSCRIPTION_ERROR_LENGTH)}...`:redacted}__name(sanitizeVoiceErrorMessage,"sanitizeVoiceErrorMessage");function inputAudioFormat(mimeType){const subtype=mimeType.split(";",1)[0]?.trim().toLowerCase()??"";return subtype.startsWith("audio/")?subtype.slice("audio/".length)||"wav":"wav"}__name(inputAudioFormat,"inputAudioFormat");function transcriptionAbortSignal(abortSignal){const timeoutSignal=AbortSignal.timeout(INFERENCE_TIMEOUT_MS);return abortSignal?AbortSignal.any([abortSignal,timeoutSignal]):timeoutSignal}__name(transcriptionAbortSignal,"transcriptionAbortSignal");async function transcribeViaQwenAsr(audio,voiceConfig,options,fetchFn){if(audio.data.byteLength>MAX_AUDIO_BYTES){throw new Error("Recording is too long for transcription (max ~5 minutes / 10 MB). Try a shorter dictation.")}const dataUrl=`data:${audio.mimeType};base64,${Buffer.from(audio.data).toString("base64")}`;const messages=[];if(options.keytermsContext){messages.push({role:"system",content:[{type:"text",text:options.keytermsContext}]})}messages.push({role:"user",content:[{type:"input_audio",input_audio:{data:dataUrl,format:inputAudioFormat(audio.mimeType)}}]});const asrOptions={enable_itn:true};if(options.language){asrOptions["language"]=options.language}const headers={"Content-Type":"application/json"};if(voiceConfig.apiKey){headers["Authorization"]=`Bearer ${voiceConfig.apiKey}`}let response;try{options.onEgress?.();response=await fetchFn(`${trimTrailingSlashes(voiceConfig.baseUrl)}/chat/completions`,{method:"POST",headers,redirect:"manual",body:JSON.stringify({model:voiceConfig.model,messages,asr_options:asrOptions}),signal:transcriptionAbortSignal(options.abortSignal)})}catch(error){if(error instanceof DOMException&&error.name==="TimeoutError"){throw new Error(`Voice transcription timed out after ${INFERENCE_TIMEOUT_MS/1e3}s. Check ASR service health and retry.`)}throw error}if(response.status>=300&&response.status<400){throw new Error("Voice transcription request redirected.")}if(!response.ok){let details="";try{details=sanitizeVoiceErrorMessage(await response.text(),voiceConfig.apiKey)}catch{details=""}if(/model_not_supported|unsupported model/i.test(details)){throw new Error("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.")}const suffix=details?`: ${details}`:"";throw new Error(`Voice transcription request failed (${response.status} ${response.statusText})${suffix}`)}const json=await response.json();const content=json.choices?.[0]?.message?.content;if(typeof content!=="string"){throw new Error("Voice transcription response did not include text.")}const text=content.trim();if(isKeytermEcho(text,options.keytermsContext)){return""}return text}__name(transcribeViaQwenAsr,"transcribeViaQwenAsr");async function transcribeVoiceAudio(audio,args){const voiceConfig=resolveVoiceTranscriptionConfig(args);await assertVoiceBaseUrlNetworkAllowed(voiceConfig,args.lookupHost,args.abortSignal);const fetchFn=args.fetchFn??fetch;const language=resolveLanguageCode(readVoiceLanguage(args.settings));const keytermsContext=buildKeytermsContext(args.settings);const transport=resolveVoiceTransport(voiceConfig.model);switch(transport){case"qwen-asr-chat":return transcribeViaQwenAsr(audio,voiceConfig,{language,keytermsContext,abortSignal:args.abortSignal,...args.onEgress?{onEgress:args.onEgress}:{}},fetchFn);case"qwen-asr-realtime":case"dashscope-task-realtime":throw new Error(`Voice model '${voiceConfig.model}' requires streaming transcription.`);case"unsupported":default:throw new Error(`Voice model '${voiceConfig.model}' is not a supported transcription model.`)}}__name(transcribeVoiceAudio,"transcribeVoiceAudio");export{assertVoiceBaseUrlNetworkAllowed,resolveVoiceTranscriptionConfig,isStreamingVoiceModel,resolveVoiceStreamConfig,isKeytermEcho,MAX_AUDIO_BYTES,sanitizeVoiceErrorMessage,transcribeVoiceAudio};
3
+ import{formatUnsupportedVoiceModelMessage,isTranscribableVoiceModel,readVoiceLanguage,resolveVoiceTransport}from"./chunk-EKRUF347.js";import{resolvePath}from"./chunk-G2SXDY2E.js";import{createDebugLogger}from"./chunk-JAUJI56S.js";import{isSubpath}from"./chunk-OKN3Z5C5.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import process from"node:process";import{lookup as dnsLookup}from"node:dns/promises";import{BlockList,isIP}from"node:net";init_esbuild_shims();import*as fs from"node:fs";import*as path from"node:path";var GLOBAL_KEYTERMS=["Qwen","MCP","grep","regex","localhost","codebase","TypeScript","JavaScript","JSON","YAML","OAuth","webhook","gRPC","dotfiles","subagent","worktree","stdout","stderr","async","await","API","CLI","npm","pnpm","commit","rebase","refactor","endpoint","middleware","schema","tokenizer"];var DEFAULT_KEYTERMS_FILENAME="voice-keyterms.txt";var MAX_KEYTERMS=200;var MAX_KEYTERMS_BYTES=2e3;var MAX_KEYTERMS_FILE_BYTES=64*1024;function buildVoiceKeyterms(settings){const userTerms=settings?readUserKeyterms(settings):[];return capKeyterms(dedupeKeyterms([...GLOBAL_KEYTERMS,...userTerms]))}__name(buildVoiceKeyterms,"buildVoiceKeyterms");function dedupeKeyterms(terms){const seen=new Set;const out=[];for(const term of terms){const key=term.toLowerCase();if(seen.has(key)){continue}seen.add(key);out.push(term)}return out}__name(dedupeKeyterms,"dedupeKeyterms");function capKeyterms(terms){const out=[];let bytes=0;for(const term of terms){if(out.length>=MAX_KEYTERMS){break}const next=bytes+Buffer.byteLength(term,"utf8")+(out.length>0?1:0);if(next>MAX_KEYTERMS_BYTES){continue}out.push(term);bytes=next}return out}__name(capKeyterms,"capKeyterms");function readUserKeyterms(settings){if(!settings.isTrusted){return[]}for(const resolved of resolveKeytermsFiles(settings)){try{const file=canonicalizeKeytermsFile(resolved);if(!file){continue}const content=readRegularFileNoFollow(file);if(content===void 0){continue}const parsed=parseKeyterms(content);if(parsed.length>0){return parsed}}catch{}}return[]}__name(readUserKeyterms,"readUserKeyterms");function resolveKeytermsFiles(settings){const workspacePath=settings.workspace?.path;if(!workspacePath){return[]}const qwenDir=path.dirname(workspacePath);const workspaceRoot=path.dirname(qwenDir);const configured=readKeytermsFileSettings(settings);if(configured.length>0){return configured.map(({path:configuredPath,scope})=>{const expanded=resolvePath(configuredPath);const isAbsolute2=path.isAbsolute(expanded);return{filePath:isAbsolute2?expanded:path.resolve(workspaceRoot,expanded),workspaceRoot,mustBeInWorkspace:scope==="system"||!isAbsolute2}})}return[{filePath:path.join(qwenDir,DEFAULT_KEYTERMS_FILENAME),workspaceRoot,mustBeInWorkspace:true}]}__name(resolveKeytermsFiles,"resolveKeytermsFiles");function canonicalizeKeytermsFile({filePath,workspaceRoot,mustBeInWorkspace}){const stat=fs.lstatSync(filePath,{throwIfNoEntry:false});if(!stat||stat.isSymbolicLink()||!stat.isFile()||stat.nlink>1||stat.size>MAX_KEYTERMS_FILE_BYTES){return void 0}const realFilePath=fs.realpathSync(filePath);if(mustBeInWorkspace){const realWorkspaceRoot=fs.realpathSync(workspaceRoot);if(!isSubpath(realWorkspaceRoot,realFilePath)){return void 0}}return{filePath:realFilePath,stat}}__name(canonicalizeKeytermsFile,"canonicalizeKeytermsFile");function readRegularFileNoFollow({filePath,stat:expectedStat}){let fd;try{let flags=fs.constants.O_RDONLY;if(typeof fs.constants.O_NOFOLLOW==="number"){flags|=fs.constants.O_NOFOLLOW}if(typeof fs.constants.O_NONBLOCK==="number"){flags|=fs.constants.O_NONBLOCK}fd=fs.openSync(filePath,flags);const stat=fs.fstatSync(fd);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){return void 0}const content=fs.readFileSync(fd,"utf-8");if(Buffer.byteLength(content,"utf8")>MAX_KEYTERMS_FILE_BYTES){return void 0}return content}finally{if(fd!==void 0){fs.closeSync(fd)}}}__name(readRegularFileNoFollow,"readRegularFileNoFollow");function parseKeyterms(content){return content.split(/\r?\n/).map(line=>line.replace(/^\s*#.*$/,"").trim()).filter(line=>line.length>0)}__name(parseKeyterms,"parseKeyterms");function readKeytermsFileSettings(settings){const out=[];const system=readKeytermsFileSettingFromScope(settings.system?.settings);if(system){out.push({path:system,scope:"system"})}const user=readKeytermsFileSettingFromScope(settings.user?.settings);if(user){out.push({path:user,scope:"user"})}return out}__name(readKeytermsFileSettings,"readKeytermsFileSettings");function readKeytermsFileSettingFromScope(settings){const value=settings?.general?.voice?.keytermsFile;if(typeof value!=="string"){return void 0}const trimmed=value.trim();return trimmed.length>0?trimmed:void 0}__name(readKeytermsFileSettingFromScope,"readKeytermsFileSettingFromScope");var DEFAULT_OPENAI_API_KEY="OPENAI_API_KEY";var INFERENCE_TIMEOUT_MS=6e4;var MIN_KEYTERM_ECHO_TOKENS=8;var MIN_ABSOLUTE_KEYTERM_ECHO_TOKENS=10;var MIN_KEYTERM_SET_ECHO_RATIO=.3;var debugLogger=createDebugLogger("VOICE_TRANSCRIBER");var BLOCKED_TRANSITION_IPV6_ADDRESSES=new BlockList;for(const[address,prefix]of[["64:ff9b:1::",48],["2001::",23],["2002::",16]]){BLOCKED_TRANSITION_IPV6_ADDRESSES.addSubnet(address,prefix,"ipv6")}function trimTrailingSlashes(value){return value.replace(/\/+$/,"")}__name(trimTrailingSlashes,"trimTrailingSlashes");function readSettingsEnv(settings,envKey){const env=settings.merged.env;const value=env?.[envKey];return typeof value==="string"&&value.trim().length>0?value.trim():void 0}__name(readSettingsEnv,"readSettingsEnv");function isQwenBaseUrl(baseUrl){try{const hostname=new URL(baseUrl).hostname.toLowerCase();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")}catch{return false}}__name(isQwenBaseUrl,"isQwenBaseUrl");function normalizeBaseUrl(baseUrl,modelName){let url;try{url=new URL(baseUrl)}catch{throw new Error(`Voice model '${modelName}' has an invalid baseUrl.`)}if(url.username||url.password){throw new Error(`Voice model '${modelName}' baseUrl must not contain embedded credentials.`)}return trimTrailingSlashes(url.toString())}__name(normalizeBaseUrl,"normalizeBaseUrl");function normalizeAllowedVoiceBaseUrl(baseUrl){try{const url=new URL(baseUrl.trim());if(url.username||url.password){return void 0}return trimTrailingSlashes(url.toString())}catch{return void 0}}__name(normalizeAllowedVoiceBaseUrl,"normalizeAllowedVoiceBaseUrl");function isInsecureVoiceBaseUrlAllowed(settings,normalizedBaseUrl){const allowed=settings.merged.security?.allowedInsecureVoiceBaseUrls;return Array.isArray(allowed)&&allowed.some(candidate=>typeof candidate==="string"&&normalizeAllowedVoiceBaseUrl(candidate)===normalizedBaseUrl)}__name(isInsecureVoiceBaseUrlAllowed,"isInsecureVoiceBaseUrlAllowed");function normalizeHostname(hostname){return hostname.toLowerCase().replace(/^\[|\]$/g,"")}__name(normalizeHostname,"normalizeHostname");function normalizeIpAddress(address){const host=normalizeHostname(address);if(isIP(host)!==6){return host}try{return normalizeHostname(new URL(`http://[${host}]/`).hostname)}catch{return host}}__name(normalizeIpAddress,"normalizeIpAddress");function isLoopbackHost(hostname){const host=normalizeHostname(hostname);return host==="localhost"||host==="127.0.0.1"||host==="::1"}__name(isLoopbackHost,"isLoopbackHost");function isAwsIpv6MetadataAddress(hostname){const host=normalizeHostname(hostname);if(isIP(host)!==6){return false}try{return normalizeHostname(new URL(`http://[${host}]/`).hostname)==="fd00:ec2::254"}catch{return false}}__name(isAwsIpv6MetadataAddress,"isAwsIpv6MetadataAddress");function readIpv4CompatibleIpv6(host){if(!host.startsWith("::")||host.startsWith("::ffff:")){return void 0}const parts=host.slice(2).split(":");if(parts.length===0||parts.length>2||parts.some(part=>!part)){return void 0}if(parts.some(part=>!/^[0-9a-f]{1,4}$/i.test(part))){return void 0}const hextets=parts.map(part=>Number.parseInt(part,16));const value=hextets.length===1?hextets[0]:hextets[0]<<16|hextets[1];return[value>>>24&255,value>>>16&255,value>>>8&255,value&255].join(".")}__name(readIpv4CompatibleIpv6,"readIpv4CompatibleIpv6");function readIpv4MappedIpv6(host){const dotted=host.match(/^::ffff:(\d+(?:\.\d+){3})$/i);if(dotted&&isIP(dotted[1])===4){return dotted[1]}const hex=host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);if(!hex){return void 0}return readIpv4HexPair(hex[1],hex[2])}__name(readIpv4MappedIpv6,"readIpv4MappedIpv6");function readIpv4HexPair(highHex,lowHex){const high=Number.parseInt(highHex,16);const low=Number.parseInt(lowHex,16);return[high>>>8,high&255,low>>>8,low&255].join(".")}__name(readIpv4HexPair,"readIpv4HexPair");function readWellKnownNat64Ipv6(host){const prefix="64:ff9b::";if(!host.startsWith(prefix)){return void 0}const suffix=host.slice(prefix.length);if(!suffix){return"0.0.0.0"}const groups=suffix.split(":");if(groups.length>2||groups.some(group=>!/^[0-9a-f]{1,4}$/i.test(group))){return void 0}return groups.length===1?readIpv4HexPair("0",groups[0]):readIpv4HexPair(groups[0],groups[1])}__name(readWellKnownNat64Ipv6,"readWellKnownNat64Ipv6");function isBlockedTransitionIpv6Address(host){return isIP(host)===6&&BLOCKED_TRANSITION_IPV6_ADDRESSES.check(host,"ipv6")}__name(isBlockedTransitionIpv6Address,"isBlockedTransitionIpv6Address");function unwrapIpv6TransitionStep(host){const ipv4Mapped=readIpv4MappedIpv6(host);if(ipv4Mapped){return{address:ipv4Mapped}}const ipv4Compatible=readIpv4CompatibleIpv6(host);if(ipv4Compatible){return{address:ipv4Compatible}}const nat64=readWellKnownNat64Ipv6(host);if(nat64){return{address:nat64}}if(host.startsWith("::ffff:")){return"blocked"}return void 0}__name(unwrapIpv6TransitionStep,"unwrapIpv6TransitionStep");function isPrivateNetworkIp(hostname){const host=normalizeIpAddress(hostname);if(isBlockedTransitionIpv6Address(host)){return true}if(isLoopbackHost(host)){return false}const step=unwrapIpv6TransitionStep(host);if(step==="blocked"){return true}if(step){return isPrivateNetworkIp(step.address)}if(isIP(host)===4){const[first=0,second=0]=host.split(".").map(Number);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}if(isIP(host)===6){const firstHextet=Number.parseInt(host.split(":",1)[0]||"0",16);return host==="::"||(firstHextet&65472)===65152||(firstHextet&65024)===64512}return false}__name(isPrivateNetworkIp,"isPrivateNetworkIp");function isAlwaysBlockedVoiceAddress(address){const host=normalizeIpAddress(address);if(isBlockedTransitionIpv6Address(host)){return true}if(isLoopbackHost(host)){return true}const step=unwrapIpv6TransitionStep(host);if(step==="blocked"){return true}if(step){return isAlwaysBlockedVoiceAddress(step.address)}if(isIP(host)===4){const[first=0,second=0]=host.split(".").map(Number);return first===0||first===127||first===169&&second===254||host==="100.100.100.200"}if(isIP(host)===6){const firstHextet=Number.parseInt(host.split(":",1)[0]||"0",16);return host==="::"||isAwsIpv6MetadataAddress(host)||(firstHextet&65472)===65152}return false}__name(isAlwaysBlockedVoiceAddress,"isAlwaysBlockedVoiceAddress");function isLoopbackVoiceAddress(address){const host=normalizeIpAddress(address);if(isLoopbackHost(host)){return true}const step=unwrapIpv6TransitionStep(host);if(step&&step!=="blocked"){return isLoopbackVoiceAddress(step.address)}if(isIP(host)===4){return host.startsWith("127.")}return false}__name(isLoopbackVoiceAddress,"isLoopbackVoiceAddress");async function defaultLookupHost(hostname){return dnsLookup(hostname,{all:true})}__name(defaultLookupHost,"defaultLookupHost");async function assertVoiceBaseUrlNetworkAllowed(voiceConfig,lookupHost,abortSignal){const hostname=normalizeHostname(new URL(voiceConfig.baseUrl).hostname);if(isLoopbackHost(hostname)){return}if(isIP(hostname)!==0){if(isAlwaysBlockedVoiceAddress(hostname)||!voiceConfig.allowInsecureBaseUrl&&isPrivateNetworkIp(hostname)){throw new Error(isLoopbackVoiceAddress(hostname)?`Voice model '${voiceConfig.model}' uses a loopback address outside the accepted spellings. To use a local ASR endpoint, set the baseUrl to http://localhost, http://127.0.0.1, or http://[::1].`:`Voice model '${voiceConfig.model}' resolved to a private-network address.`)}return}let result;let onAbort;try{if(abortSignal?.aborted){throw abortSignal.reason}const lookup=(lookupHost??defaultLookupHost)(hostname);result=abortSignal?await Promise.race([lookup,new Promise((_resolve,reject)=>{onAbort=__name(()=>reject(abortSignal.reason),"onAbort");if(abortSignal.aborted)onAbort();else abortSignal.addEventListener("abort",onAbort,{once:true})})]):await lookup}catch{if(abortSignal?.aborted){throw abortSignal.reason instanceof Error?abortSignal.reason:new Error("Voice request was aborted.")}throw new Error(`Voice model '${voiceConfig.model}': DNS lookup failed for ${hostname}. Cannot verify network safety.`)}finally{if(onAbort)abortSignal?.removeEventListener("abort",onAbort)}const records=Array.isArray(result)?result:[result];if(records.some(record=>isAlwaysBlockedVoiceAddress(record.address)||!voiceConfig.allowInsecureBaseUrl&&isPrivateNetworkIp(record.address))){throw new Error(records.some(record=>isLoopbackVoiceAddress(record.address))?`Voice model '${voiceConfig.model}' resolved to a loopback address. Loopback DNS results are always blocked; to use a local ASR endpoint, configure an explicit loopback baseUrl: http://localhost, http://127.0.0.1, or http://[::1].`:voiceConfig.allowInsecureBaseUrl&&records.some(record=>isAlwaysBlockedVoiceAddress(record.address))?`Voice model '${voiceConfig.model}' resolved to an address that is always blocked (metadata, link-local, or transition range), even when the baseUrl is listed in security.allowedInsecureVoiceBaseUrls.`:`Voice model '${voiceConfig.model}' resolved to a private-network address.`)}}__name(assertVoiceBaseUrlNetworkAllowed,"assertVoiceBaseUrlNetworkAllowed");function readApiKey(settings,model,baseUrl,env){if(!model.envKey&&!isQwenBaseUrl(baseUrl)){return void 0}const envKey=model.envKey??DEFAULT_OPENAI_API_KEY;const envSource=env??process.env;const envValue=Object.hasOwn(envSource,envKey)?envSource[envKey]:void 0;if(envValue&&envValue.trim().length>0){return envValue.trim()}const settingsEnvValue=readSettingsEnv(settings,envKey);if(settingsEnvValue){return settingsEnvValue}if(!model.envKey&&isQwenBaseUrl(baseUrl)){const authApiKey=settings.merged.security?.auth?.apiKey;return typeof authApiKey==="string"&&authApiKey.trim().length>0?authApiKey.trim():void 0}return void 0}__name(readApiKey,"readApiKey");function resolveVoiceTranscriptionConfig({config,settings,voiceModel,env}){const matches=config.getAllConfiguredModels().filter(model2=>model2.id===voiceModel);if(matches.length===0){throw new Error(`Voice model '${voiceModel}' is not configured. Run /model --voice to choose a configured model.`)}if(matches.length>1){throw new Error(`Voice model '${voiceModel}' is ambiguous.`)}const model=matches[0];if(!isTranscribableVoiceModel(model)){throw new Error(formatUnsupportedVoiceModelMessage(voiceModel))}const baseUrl=model.baseUrl?.trim();if(!baseUrl){throw new Error(`Voice model '${voiceModel}' does not define a baseUrl.`)}const normalizedBaseUrl=normalizeBaseUrl(baseUrl,voiceModel);const parsedBaseUrl=new URL(normalizedBaseUrl);const isLocalhost=isLoopbackHost(parsedBaseUrl.hostname);const allowInsecureBaseUrl=isInsecureVoiceBaseUrlAllowed(settings,normalizedBaseUrl);if(parsedBaseUrl.protocol!=="http:"&&parsedBaseUrl.protocol!=="https:"){throw new Error(`Voice model '${voiceModel}' must use an http or https baseUrl.`)}if(!isLocalhost&&isAlwaysBlockedVoiceAddress(parsedBaseUrl.hostname)){throw new Error(isLoopbackVoiceAddress(parsedBaseUrl.hostname)?`Voice model '${voiceModel}' uses a loopback address outside the accepted spellings. To use a local ASR endpoint, set the baseUrl to http://localhost, http://127.0.0.1, or http://[::1].`:`Voice model '${voiceModel}' must not use a private-network baseUrl.`)}if(parsedBaseUrl.protocol!=="https:"&&!isLocalhost&&!allowInsecureBaseUrl){throw new Error(`Voice model '${voiceModel}' must use an https baseUrl. Voice audio must not be transmitted in cleartext. To trust this managed endpoint, add its exact complete normalized URL (${normalizedBaseUrl}) to security.allowedInsecureVoiceBaseUrls. This setting is only honored from User, System, or SystemDefaults scope settings; Workspace entries are ignored.`)}if(!isLocalhost&&!allowInsecureBaseUrl&&isPrivateNetworkIp(parsedBaseUrl.hostname)){throw new Error(`Voice model '${voiceModel}' must not use a private-network baseUrl. To trust this managed endpoint, add its exact complete normalized URL (${normalizedBaseUrl}) to security.allowedInsecureVoiceBaseUrls. This setting is only honored from User, System, or SystemDefaults scope settings; Workspace entries are ignored.`)}const apiKey=readApiKey(settings,model,normalizedBaseUrl,env);if(model.envKey&&!apiKey){throw new Error(`Voice model '${voiceModel}' requires ${model.envKey}.`)}return{model:voiceModel,baseUrl:normalizedBaseUrl,...apiKey?{apiKey}:{},...allowInsecureBaseUrl?{allowInsecureBaseUrl:true}:{}}}__name(resolveVoiceTranscriptionConfig,"resolveVoiceTranscriptionConfig");function isStreamingVoiceModel(model){const transport=resolveVoiceTransport(model);return transport==="qwen-asr-realtime"||transport==="dashscope-task-realtime"}__name(isStreamingVoiceModel,"isStreamingVoiceModel");function resolveVoiceStreamConfig(args){const base=resolveVoiceTranscriptionConfig(args);const transport=resolveVoiceTransport(base.model);if(transport!=="qwen-asr-realtime"&&transport!=="dashscope-task-realtime"){throw new Error(`Voice model '${base.model}' does not support streaming transcription.`)}const language=resolveLanguageCode(readVoiceLanguage(args.settings));const keytermsContext=transport==="qwen-asr-realtime"?buildKeytermsContext(args.settings):void 0;return{transport,baseUrl:base.baseUrl,model:base.model,...base.apiKey?{apiKey:base.apiKey}:{},...base.allowInsecureBaseUrl?{allowInsecureBaseUrl:true}:{},...language?{language}:{},...keytermsContext?{keytermsContext}:{}}}__name(resolveVoiceStreamConfig,"resolveVoiceStreamConfig");var LANGUAGE_CODES={english:"en",chinese:"zh",mandarin:"zh",cantonese:"yue",japanese:"ja",korean:"ko",french:"fr",german:"de",spanish:"es",italian:"it",portuguese:"pt",russian:"ru",arabic:"ar"};function resolveLanguageCode(language){if(!language){return void 0}const lower=language.toLowerCase();if(LANGUAGE_CODES[lower]){return LANGUAGE_CODES[lower]}return/^[a-z]{2,3}$/.test(lower)?lower:void 0}__name(resolveLanguageCode,"resolveLanguageCode");function buildKeytermsContext(settings){try{const keyterms=buildVoiceKeyterms(settings);return keyterms.length>0?keyterms.join(" "):void 0}catch{return void 0}}__name(buildKeytermsContext,"buildKeytermsContext");function tokenize(value){return value.toLowerCase().replace(/[^\p{L}\p{N}\s]/gu," ").split(/\s+/).filter(Boolean)}__name(tokenize,"tokenize");function isKeytermEcho(transcript,keytermsContext){if(!keytermsContext){return false}const tokens=tokenize(transcript);if(tokens.length<4){return false}const keyset=new Set(tokenize(keytermsContext));const overlap=tokens.filter(t=>keyset.has(t)).length;const transcriptRatio=overlap/tokens.length;const keytermRatio=overlap/keyset.size;const isEcho=overlap>=MIN_KEYTERM_ECHO_TOKENS&&transcriptRatio>=.9&&(keytermRatio>=MIN_KEYTERM_SET_ECHO_RATIO||overlap>=MIN_ABSOLUTE_KEYTERM_ECHO_TOKENS);if(isEcho){const branch=keytermRatio>=MIN_KEYTERM_SET_ECHO_RATIO?"ratio":"absolute";debugLogger.debug(`[voice] dropped likely keyterm echo (${branch}): overlap=${overlap} keysetSize=${keyset.size} transcriptRatio=${transcriptRatio.toFixed(2)} keytermRatio=${keytermRatio.toFixed(2)} text="${transcript}"`)}return isEcho}__name(isKeytermEcho,"isKeytermEcho");var MAX_AUDIO_BYTES=10*1024*1024;var MAX_TRANSCRIPTION_ERROR_LENGTH=200;function escapeRegExp(value){return value.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}__name(escapeRegExp,"escapeRegExp");function sanitizeVoiceErrorMessage(raw,apiKey){let redacted=raw.replace(/Authorization:\s*(?:Bearer|ApiKey|Basic|Token)?\s*\S+/gi,"Authorization: [REDACTED]").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]");if(apiKey){redacted=redacted.replace(new RegExp(escapeRegExp(apiKey),"g"),"[REDACTED]")}return redacted.length>MAX_TRANSCRIPTION_ERROR_LENGTH?`${redacted.slice(0,MAX_TRANSCRIPTION_ERROR_LENGTH)}...`:redacted}__name(sanitizeVoiceErrorMessage,"sanitizeVoiceErrorMessage");function inputAudioFormat(mimeType){const subtype=mimeType.split(";",1)[0]?.trim().toLowerCase()??"";return subtype.startsWith("audio/")?subtype.slice("audio/".length)||"wav":"wav"}__name(inputAudioFormat,"inputAudioFormat");function transcriptionAbortSignal(abortSignal){const timeoutSignal=AbortSignal.timeout(INFERENCE_TIMEOUT_MS);return abortSignal?AbortSignal.any([abortSignal,timeoutSignal]):timeoutSignal}__name(transcriptionAbortSignal,"transcriptionAbortSignal");async function transcribeViaQwenAsr(audio,voiceConfig,options,fetchFn){if(audio.data.byteLength>MAX_AUDIO_BYTES){throw new Error("Recording is too long for transcription (max ~5 minutes / 10 MB). Try a shorter dictation.")}const dataUrl=`data:${audio.mimeType};base64,${Buffer.from(audio.data).toString("base64")}`;const messages=[];if(options.keytermsContext){messages.push({role:"system",content:[{type:"text",text:options.keytermsContext}]})}messages.push({role:"user",content:[{type:"input_audio",input_audio:{data:dataUrl,format:inputAudioFormat(audio.mimeType)}}]});const asrOptions={enable_itn:true};if(options.language){asrOptions["language"]=options.language}const headers={"Content-Type":"application/json"};if(voiceConfig.apiKey){headers["Authorization"]=`Bearer ${voiceConfig.apiKey}`}let response;try{options.onEgress?.();response=await fetchFn(`${trimTrailingSlashes(voiceConfig.baseUrl)}/chat/completions`,{method:"POST",headers,redirect:"manual",body:JSON.stringify({model:voiceConfig.model,messages,asr_options:asrOptions}),signal:transcriptionAbortSignal(options.abortSignal)})}catch(error){if(error instanceof DOMException&&error.name==="TimeoutError"){throw new Error(`Voice transcription timed out after ${INFERENCE_TIMEOUT_MS/1e3}s. Check ASR service health and retry.`)}throw error}if(response.status>=300&&response.status<400){throw new Error("Voice transcription request redirected.")}if(!response.ok){let details="";try{details=sanitizeVoiceErrorMessage(await response.text(),voiceConfig.apiKey)}catch{details=""}if(/model_not_supported|unsupported model/i.test(details)){throw new Error("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.")}const suffix=details?`: ${details}`:"";throw new Error(`Voice transcription request failed (${response.status} ${response.statusText})${suffix}`)}const json=await response.json();const content=json.choices?.[0]?.message?.content;if(typeof content!=="string"){throw new Error("Voice transcription response did not include text.")}const text=content.trim();if(isKeytermEcho(text,options.keytermsContext)){return""}return text}__name(transcribeViaQwenAsr,"transcribeViaQwenAsr");async function transcribeVoiceAudio(audio,args){const voiceConfig=resolveVoiceTranscriptionConfig(args);await assertVoiceBaseUrlNetworkAllowed(voiceConfig,args.lookupHost,args.abortSignal);const fetchFn=args.fetchFn??fetch;const language=resolveLanguageCode(readVoiceLanguage(args.settings));const keytermsContext=buildKeytermsContext(args.settings);const transport=resolveVoiceTransport(voiceConfig.model);switch(transport){case"qwen-asr-chat":return transcribeViaQwenAsr(audio,voiceConfig,{language,keytermsContext,abortSignal:args.abortSignal,...args.onEgress?{onEgress:args.onEgress}:{}},fetchFn);case"qwen-asr-realtime":case"dashscope-task-realtime":throw new Error(`Voice model '${voiceConfig.model}' requires streaming transcription.`);case"unsupported":default:throw new Error(`Voice model '${voiceConfig.model}' is not a supported transcription model.`)}}__name(transcribeVoiceAudio,"transcribeVoiceAudio");export{assertVoiceBaseUrlNetworkAllowed,resolveVoiceTranscriptionConfig,isStreamingVoiceModel,resolveVoiceStreamConfig,isKeytermEcho,MAX_AUDIO_BYTES,sanitizeVoiceErrorMessage,transcribeVoiceAudio};
4
4
  /**
5
5
  * @license
6
6
  * Copyright 2025 Qwen