@qwen-code/qwen-code 0.19.12-preview.0 → 0.20.0-nightly.20260720.0c271659d

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 (277) hide show
  1. package/bundled/qc-helper/docs/features/channels/overview.md +4 -2
  2. package/bundled/qc-helper/docs/integration-github-action.md +1 -1
  3. package/bundled/qc-helper/docs/qwen-serve.md +42 -5
  4. package/bundled/review/DESIGN.md +2 -2
  5. package/bundled/review/SKILL.md +13 -9
  6. package/chunks/{MaxSizedBox-3KIWAU6Z.js → MaxSizedBox-ED3QND6V.js} +30 -27
  7. package/chunks/{StandaloneSessionPicker-TF626NO7.js → StandaloneSessionPicker-NQVAOTKS.js} +50 -45
  8. package/chunks/{acpAgent-JDVJXVBO.js → acpAgent-HOBFF5B6.js} +353 -130
  9. package/chunks/{agent-BONWC4VY.js → agent-J7EPFLA6.js} +22 -22
  10. package/chunks/{agent-headless-H7HKMGLZ.js → agent-headless-RRG3JU7Q.js} +22 -22
  11. package/chunks/{anthropicContentGenerator-ZZRGFEES.js → anthropicContentGenerator-HVKLXOOU.js} +6 -5
  12. package/chunks/{artifact-tool-PHO5XEGZ.js → artifact-tool-WBCAMD3O.js} +2 -2
  13. package/chunks/{askUserQuestion-CEPBT47X.js → askUserQuestion-6DZC4UV5.js} +2 -2
  14. package/chunks/{bridge-ATN2TLWJ.js → bridge-OW5FZ6BF.js} +25 -25
  15. package/chunks/build-SSCNEHZZ.js +62 -0
  16. package/chunks/{channel-worker-group-S3H5QHTI.js → channel-worker-group-53CMOPFT.js} +4 -4
  17. package/chunks/{channel-worker-manager-ZJ4HTMO2.js → channel-worker-manager-UTXILKC2.js} +4 -4
  18. package/chunks/{channel-worker-supervisor-JA6VZ5V5.js → channel-worker-supervisor-ZGO2W2MD.js} +3 -3
  19. package/chunks/chunk-27AJEU6G.js +442 -0
  20. package/chunks/{chunk-53UMEONK.js → chunk-2HOVDT7W.js} +1 -1
  21. package/chunks/{chunk-6WZZHJSZ.js → chunk-2JOLZA6L.js} +5 -5
  22. package/chunks/{chunk-NSZJQACR.js → chunk-2TDSM7I6.js} +3 -3
  23. package/chunks/{chunk-ILQ42UG6.js → chunk-2YJLFCYI.js} +7 -7
  24. package/chunks/{chunk-CMHJEUVB.js → chunk-37MGCVTS.js} +1 -1
  25. package/chunks/{chunk-F2YCCUXI.js → chunk-3ML52IFS.js} +4 -4
  26. package/chunks/{chunk-3PE7OY2G.js → chunk-3QR5MOHP.js} +2 -2
  27. package/chunks/{chunk-4AGBO6RB.js → chunk-3SNKL6L6.js} +29 -13
  28. package/chunks/{chunk-OZWJAFFE.js → chunk-3ZL6YMO2.js} +3 -3
  29. package/chunks/chunk-43T5WDQ7.js +127 -0
  30. package/chunks/{chunk-E655RDRL.js → chunk-4ODB7WIB.js} +1 -1
  31. package/chunks/{chunk-66F4IJ4L.js → chunk-4UH63YE5.js} +5 -5
  32. package/chunks/{chunk-QGONRHUS.js → chunk-53OPIXUE.js} +3 -3
  33. package/chunks/{chunk-HTHUX2T5.js → chunk-5QWWOFGG.js} +0 -1
  34. package/chunks/{chunk-3DJY4IFO.js → chunk-5SCI6E3E.js} +1 -1
  35. package/chunks/{chunk-4CHDYDG3.js → chunk-6EFTQYW7.js} +1 -1
  36. package/chunks/{chunk-4W55BHOC.js → chunk-6HQW55TM.js} +29 -2
  37. package/chunks/{chunk-LODZMRXC.js → chunk-6MN6XJTR.js} +2379 -1291
  38. package/chunks/{chunk-EWPLL4OT.js → chunk-6VGRTGOG.js} +1 -1
  39. package/chunks/{chunk-R32BTEZY.js → chunk-7JQK6FXK.js} +198 -120
  40. package/chunks/{chunk-SMASS3CY.js → chunk-A4TJMY65.js} +1 -1
  41. package/chunks/{chunk-JUNVFQVY.js → chunk-AMRWCMX4.js} +4 -4
  42. package/chunks/{chunk-XAAEDML2.js → chunk-AYCDXHZB.js} +1 -1
  43. package/chunks/{chunk-VAJS2E2D.js → chunk-BDBMYST4.js} +1 -1
  44. package/chunks/{chunk-F2RR4HO2.js → chunk-BVLROR2T.js} +1 -1
  45. package/chunks/{chunk-UE5TZ55T.js → chunk-C27BYUX6.js} +29 -2
  46. package/chunks/{chunk-ZPVGEMVC.js → chunk-CL7IRYTA.js} +1 -1
  47. package/chunks/{chunk-DULSE2SH.js → chunk-COWNNAWJ.js} +1 -1
  48. package/chunks/{chunk-UOA2IHRI.js → chunk-CPCVCKKF.js} +1 -1
  49. package/chunks/{chunk-4RPARQ5D.js → chunk-D2VIDMVM.js} +2 -2
  50. package/chunks/{chunk-PTXVHS2O.js → chunk-DCCW7CRR.js} +6 -6
  51. package/chunks/chunk-DIKIJS6Z.js +114 -0
  52. package/chunks/{chunk-NVUGS23Y.js → chunk-DR5AUNJ2.js} +4 -4
  53. package/chunks/{chunk-7KS72E2N.js → chunk-DSBCU6JY.js} +3 -3
  54. package/chunks/{chunk-LKR7QQ63.js → chunk-EAUYY7SS.js} +3 -3
  55. package/chunks/{chunk-J2MKYJKZ.js → chunk-EIAK6Q2B.js} +2 -2
  56. package/chunks/{chunk-WEPXQKGP.js → chunk-EZVDJFZ7.js} +1 -1
  57. package/chunks/{chunk-WHQNBBWW.js → chunk-FLSVD6BS.js} +2 -2
  58. package/chunks/{chunk-XACBIZJB.js → chunk-FODJ5Q5K.js} +3 -3
  59. package/chunks/{chunk-4XCVGEEX.js → chunk-FSL5W5TI.js} +3 -3
  60. package/chunks/{chunk-K7P34F2J.js → chunk-FWT66O5E.js} +2 -2
  61. package/chunks/{chunk-OSSDHJDU.js → chunk-G45X5TRN.js} +1 -1
  62. package/chunks/{chunk-R4RIMOJL.js → chunk-G6MDKXDP.js} +12 -12
  63. package/chunks/{chunk-KANTXY7B.js → chunk-GKY2OJ7R.js} +2 -2
  64. package/chunks/chunk-GMGDLUC7.js +37 -0
  65. package/chunks/{chunk-J6NT5YTN.js → chunk-H2XVO6NE.js} +1 -289
  66. package/chunks/{chunk-7OZGMFHC.js → chunk-I4HZ4GOD.js} +8 -8
  67. package/chunks/{chunk-YN2I5I42.js → chunk-I6JUVU7J.js} +34 -24
  68. package/chunks/{chunk-LLIGYAQU.js → chunk-IDGTC5AS.js} +3 -3
  69. package/chunks/{chunk-LHEQDKAR.js → chunk-INL2RSLA.js} +1 -1
  70. package/chunks/{chunk-CXWUXRD5.js → chunk-INQQM52C.js} +18 -16
  71. package/chunks/{chunk-2DZ7E27L.js → chunk-JBCFW3IL.js} +2 -2
  72. package/chunks/{chunk-LPHGXXZX.js → chunk-JD3MKVKL.js} +1 -1
  73. package/chunks/{chunk-6TDA4EVC.js → chunk-JDPCOUZ3.js} +2282 -662
  74. package/chunks/{chunk-NUHSLBJZ.js → chunk-JNWZQ27S.js} +15 -9
  75. package/chunks/{chunk-IKLWU6YS.js → chunk-JRJ2LV6P.js} +6 -226
  76. package/chunks/{chunk-QSG4ZFG4.js → chunk-KTUQMDEP.js} +1 -1
  77. package/chunks/{chunk-HZXU6YZW.js → chunk-LTQ5C5AB.js} +4 -4
  78. package/chunks/{chunk-V4PCIS25.js → chunk-MAQQGNQ5.js} +44 -1
  79. package/chunks/{chunk-BEFQGC6H.js → chunk-NBMIC7DR.js} +2 -2
  80. package/chunks/{chunk-GEHSF7MS.js → chunk-NEEB7UEN.js} +2545 -1974
  81. package/chunks/{chunk-MHEZV3OY.js → chunk-NIJEXGV6.js} +250 -75
  82. package/chunks/{chunk-NGTQA57Y.js → chunk-NQVA6O7F.js} +2 -2
  83. package/chunks/{chunk-54KPEDM2.js → chunk-NT324EJ6.js} +13 -8
  84. package/chunks/{chunk-WTHRMVKB.js → chunk-O2SPEQFA.js} +5 -5
  85. package/chunks/{chunk-MCYZTKBV.js → chunk-OLMETXLX.js} +2 -2
  86. package/chunks/{chunk-JCJPZMJV.js → chunk-OOCI5VVU.js} +1 -1
  87. package/chunks/{chunk-XSPFQQRE.js → chunk-OONJNQ42.js} +3 -3
  88. package/chunks/{chunk-ANRANWVE.js → chunk-OP4MOGXF.js} +1 -1
  89. package/chunks/{chunk-SGPFJMRP.js → chunk-PBATSWUQ.js} +1 -1
  90. package/chunks/chunk-QKYTTBYW.js +624 -0
  91. package/chunks/{chunk-4OVECYBM.js → chunk-QOSKUG5P.js} +77 -20
  92. package/chunks/{chunk-76BFY7AF.js → chunk-QTERJVPZ.js} +1 -6
  93. package/chunks/{chunk-Y5UDBQYF.js → chunk-RB7NXUP5.js} +3 -3
  94. package/chunks/{chunk-HCCR43AY.js → chunk-RFIAR4YL.js} +1 -1
  95. package/chunks/{chunk-XFJU7SVP.js → chunk-RS5JPH6Y.js} +3 -3
  96. package/chunks/chunk-RS7MT2QG.js +305 -0
  97. package/chunks/{chunk-WACI4VES.js → chunk-SG2PEESS.js} +1106 -592
  98. package/chunks/{chunk-FEZXQXW2.js → chunk-SLLG5XXE.js} +1 -1
  99. package/chunks/{chunk-W4DFAUAO.js → chunk-SQMTULHJ.js} +1 -1
  100. package/chunks/{chunk-Z4ZCVYJ5.js → chunk-STFP7PJR.js} +6 -6
  101. package/chunks/chunk-SV5PQVQE.js +71 -0
  102. package/chunks/{chunk-7LMAKIWE.js → chunk-TFNZCC4B.js} +1 -1
  103. package/chunks/{chunk-ZFHHBRRA.js → chunk-THNJYTA6.js} +2 -2
  104. package/chunks/{chunk-6QGZVKOO.js → chunk-TN2BYMNH.js} +69 -2216
  105. package/chunks/{chunk-TFV3XVAZ.js → chunk-TQBA6DVX.js} +1 -1
  106. package/chunks/{chunk-AWOU24F6.js → chunk-U24E4R5U.js} +3 -3
  107. package/chunks/{chunk-4CA4WUMS.js → chunk-UEY4AYUL.js} +2 -2
  108. package/chunks/{chunk-DYUPBU7H.js → chunk-UGRL5B5F.js} +1 -1
  109. package/chunks/chunk-V7RNNPGC.js +44 -0
  110. package/chunks/{chunk-LYFDJTXE.js → chunk-VGFFYNBD.js} +1 -1
  111. package/chunks/chunk-VIOFKPPN.js +125 -0
  112. package/chunks/{chunk-BEZPRKD3.js → chunk-VLDBVLC4.js} +156 -2
  113. package/chunks/{chunk-HQ7MDVBO.js → chunk-VWLLDHAY.js} +6 -6
  114. package/chunks/chunk-WCDH2CRI.js +1187 -0
  115. package/chunks/{chunk-7SX6WZNO.js → chunk-XVVH63JG.js} +3 -3
  116. package/chunks/{chunk-HVWPSGDY.js → chunk-Y2ENGUD6.js} +1 -1
  117. package/chunks/{chunk-PSISZNIT.js → chunk-Y5534U4G.js} +346 -122
  118. package/chunks/{chunk-IQRQVPGN.js → chunk-YDZ6J2BY.js} +72 -159
  119. package/chunks/{chunk-7O7WZH7N.js → chunk-YNBP3YSU.js} +7 -6
  120. package/chunks/{chunk-NJQPQ4IO.js → chunk-YWEW33JY.js} +7 -7
  121. package/chunks/{chunk-335ECZTA.js → chunk-ZEOZL37W.js} +1 -1
  122. package/chunks/{chunk-SNONG66P.js → chunk-ZGJ4LDD2.js} +53 -28
  123. package/chunks/{computer-use-UY4A72X7.js → computer-use-ET5476VX.js} +22 -22
  124. package/chunks/{config-utils-KWTRFP7D.js → config-utils-AHQ6YZ66.js} +3 -3
  125. package/chunks/{contextCommand-3DZ2SVH6.js → contextCommand-QIULFDBF.js} +25 -26
  126. package/chunks/{create-sub-session-OT7WXLDO.js → create-sub-session-BVL2ZHTM.js} +22 -22
  127. package/chunks/{create-sub-session-DIJOV6HV.js → create-sub-session-P26FE5GG.js} +2 -2
  128. package/chunks/{cron-create-X462ERYA.js → cron-create-JWFHBDRQ.js} +4 -4
  129. package/chunks/{cron-delete-SL5UJUM3.js → cron-delete-GDX4E26G.js} +4 -4
  130. package/chunks/{cron-list-3MD6SVXI.js → cron-list-USMAIWPT.js} +4 -4
  131. package/chunks/{daemon-ZW6LHOXT.js → daemon-EE5T3KOW.js} +169 -84
  132. package/chunks/{daemon-status-provider-GTZOYSBO.js → daemon-status-provider-L5UW7TGV.js} +29 -29
  133. package/chunks/{dist-RZBJT5O2.js → dist-2BHAYBKP.js} +1 -1
  134. package/chunks/{dist-O2IP3G5D.js → dist-2MIU4UUH.js} +1 -1
  135. package/chunks/{dist-HCUUS6IH.js → dist-53PZYC5B.js} +2 -2
  136. package/chunks/{dist-ZJHKKWUD.js → dist-AU7NQQRP.js} +1 -1
  137. package/chunks/{dist-YTPTCUAD.js → dist-FUTEXY6A.js} +1 -1
  138. package/chunks/{dist-Y54RURGT.js → dist-WGTQO7F2.js} +1 -1
  139. package/chunks/{earlyInputCapture-GGWVGBZ7.js → earlyInputCapture-ZLAL5GTE.js} +23 -23
  140. package/chunks/{edit-JN467GIR.js → edit-4ZOPT6OC.js} +23 -23
  141. package/chunks/{enter-worktree-MMO4VBQE.js → enter-worktree-DFP5CZYS.js} +22 -22
  142. package/chunks/{enterPlanMode-BRZOG4DB.js → enterPlanMode-7VEJ7A2A.js} +22 -22
  143. package/chunks/{environment-LOCDCWMZ.js → environment-KHS35XJY.js} +24 -24
  144. package/chunks/{errors-XXSL5HGG.js → errors-574WBU5R.js} +24 -24
  145. package/chunks/{exit-worktree-UD7PI5H5.js → exit-worktree-5Q7V6D4C.js} +22 -22
  146. package/chunks/{exitPlanMode-EIUETQI6.js → exitPlanMode-SX2F6PDJ.js} +22 -22
  147. package/chunks/{fast-path-ULGAEUVK.js → fast-path-G7BLOZVF.js} +2 -2
  148. package/chunks/{gemini-KW3APZ4P.js → gemini-M4JWSTGU.js} +70 -68
  149. package/chunks/{geminiContentGenerator-4BQ5QHPR.js → geminiContentGenerator-MKXLUFUH.js} +4 -4
  150. package/chunks/{glob-FPKAMR6B.js → glob-FPKZY5W6.js} +22 -22
  151. package/chunks/{grep-MOGRCYB4.js → grep-RS22OMZG.js} +22 -22
  152. package/chunks/{handleAutoUpdate-QUMRZZOS.js → handleAutoUpdate-RFNQ36JC.js} +27 -28
  153. package/chunks/{i18n-F3W6YUYP.js → i18n-MAEWSKYF.js} +23 -23
  154. package/chunks/{initializer-KLU2KAIZ.js → initializer-T2BFZJBP.js} +28 -28
  155. package/chunks/{installationInfo-P3ZP2SIZ.js → installationInfo-3UETF773.js} +25 -23
  156. package/chunks/{keychain-token-storage-K23CFKGN.js → keychain-token-storage-DWRJMNH3.js} +2 -2
  157. package/chunks/{list-4X6D5JD2.js → list-FWZUKWD2.js} +30 -30
  158. package/chunks/{loadedSettingsAdapter-446B6WKA.js → loadedSettingsAdapter-3DUNHAPX.js} +27 -27
  159. package/chunks/{loop-wakeup-6H7OENTB.js → loop-wakeup-5GLTUBHA.js} +5 -5
  160. package/chunks/{ls-APTSOOS5.js → ls-FHBY3Y7I.js} +4 -4
  161. package/chunks/{lsp-HPACPJAN.js → lsp-B6VMEW6Y.js} +2 -2
  162. package/chunks/{mcp-JYVOJZOD.js → mcp-POXS7QWD.js} +27 -27
  163. package/chunks/{monitor-KY7YH7TL.js → monitor-2ZZC2NKH.js} +22 -22
  164. package/chunks/nonInteractiveCli-WSJVCB2W.js +126 -0
  165. package/chunks/{notebook-edit-IHGW42QK.js → notebook-edit-BMQLME3Q.js} +23 -23
  166. package/chunks/{openaiContentGenerator-FURUCKQJ.js → openaiContentGenerator-GOREG72R.js} +11 -11
  167. package/chunks/{pidfile-WKUVXDMR.js → pidfile-MVZDE5TC.js} +23 -23
  168. package/chunks/{processUtils-LHSRN76X.js → processUtils-RH5KNLDH.js} +2 -2
  169. package/chunks/{qwenContentGenerator-NRLM7R36.js → qwenContentGenerator-R55BCLRI.js} +24 -24
  170. package/chunks/{qwenOAuth2-5FNX3AWH.js → qwenOAuth2-QZBI2SOZ.js} +11 -11
  171. package/chunks/react-SG7JAQSZ.js +8 -0
  172. package/chunks/{read-file-VLEAEXFP.js → read-file-CPS2CYYG.js} +8 -8
  173. package/chunks/{read-mcp-resource-C6NT52T6.js → read-mcp-resource-AKCL7I43.js} +2 -2
  174. package/chunks/{record-artifact-ENCU7QCL.js → record-artifact-PEUB7727.js} +2 -2
  175. package/chunks/resumeHistoryUtils-YD6DSYHU.js +78 -0
  176. package/chunks/{ripGrep-MT23EIDD.js → ripGrep-UKGJ7RHZ.js} +22 -22
  177. package/chunks/{run-qwen-serve-5HWOQFLI.js → run-qwen-serve-GFKSKLF6.js} +1442 -148
  178. package/chunks/{runtime-6IVKJSLW.js → runtime-4KGNL3TP.js} +31 -31
  179. package/chunks/{scheduler-63GJG75U.js → scheduler-GJ3CELWI.js} +22 -22
  180. package/chunks/{send-message-5GZ4FX2V.js → send-message-3RHE7HSM.js} +3 -3
  181. package/chunks/{serve-3LL7RRDP.js → serve-UU6Z4C7W.js} +27 -27
  182. package/chunks/{server-AA24QLPA.js → server-RTJUMN24.js} +393 -256
  183. package/chunks/{session-LRVCFQQQ.js → session-EYD3CEB5.js} +79 -163
  184. package/chunks/{settings-ZX3OKUT4.js → settings-H5O22TGQ.js} +26 -26
  185. package/chunks/{shell-KR3IMYH6.js → shell-KVNHDHMT.js} +22 -22
  186. package/chunks/{skill-QLM2LSF7.js → skill-32525KCE.js} +10 -10
  187. package/chunks/{spawnChannel-6WFOK3SA.js → spawnChannel-G7DUQKHL.js} +24 -24
  188. package/chunks/{src-ADLNIPHD.js → src-DUFUUEHE.js} +52 -22
  189. package/chunks/{standalone-update-C54OTJWJ.js → standalone-update-UC6CWBLH.js} +24 -24
  190. package/chunks/{startInteractiveUI-KFAOS6HC.js → startInteractiveUI-A5YYAWLF.js} +5455 -2041
  191. package/chunks/{syntheticOutput-ULOVVLY4.js → syntheticOutput-FG5PQKIR.js} +3 -3
  192. package/chunks/{task-create-DUE2PMNI.js → task-create-HX32YXO7.js} +7 -7
  193. package/chunks/{task-list-WVPNX7BZ.js → task-list-QWSY4ZIU.js} +5 -5
  194. package/chunks/{task-stop-CPEQWOT6.js → task-stop-GWC6UWAL.js} +2 -2
  195. package/chunks/{task-update-HY2LNFFB.js → task-update-NCTAB73Q.js} +7 -7
  196. package/chunks/{team-create-Q5B5M7UD.js → team-create-LS2Q32Y4.js} +22 -22
  197. package/chunks/{team-delete-JJV6IUOA.js → team-delete-KK37HTOG.js} +5 -5
  198. package/chunks/{team-plan-approval-J55PXNY2.js → team-plan-approval-DWCZABX6.js} +22 -22
  199. package/chunks/{theme-manager-QWTDRPHV.js → theme-manager-E22CNBIL.js} +23 -23
  200. package/chunks/{todoWrite-JHHIDOIV.js → todoWrite-ERCAMLFS.js} +4 -4
  201. package/chunks/{tool-search-LSSKWZKH.js → tool-search-MHXUDFD2.js} +9 -9
  202. package/chunks/{total-session-admission-S6ATY5HY.js → total-session-admission-KOPTGDJZ.js} +25 -25
  203. package/chunks/{trustedFolders-CY4TUPDJ.js → trustedFolders-ANQXYAQT.js} +23 -23
  204. package/chunks/{update-relaunch-IOKOUV3K.js → update-relaunch-HFGRB7PE.js} +9 -9
  205. package/chunks/{updateCheck-YNRFE4V7.js → updateCheck-EKIPND4B.js} +33 -26
  206. package/chunks/useAutoAcceptIndicator-EE22V2F5.js +80 -0
  207. package/chunks/{validateNonInterActiveAuth-OXTECS4B.js → validateNonInterActiveAuth-RUICXVPH.js} +61 -63
  208. package/chunks/{version-2CZQQDL5.js → version-QLT755OV.js} +1 -1
  209. package/chunks/{web-fetch-7QTEGJI5.js → web-fetch-DINW4Z65.js} +10 -10
  210. package/chunks/{workflow-G3CZU256.js → workflow-GPMXRWKK.js} +23 -23
  211. package/chunks/{workspace-providers-status-UHQOIPAZ.js → workspace-providers-status-XCQKBVSX.js} +30 -30
  212. package/chunks/{workspace-registration-store-5WPCMX4F.js → workspace-registration-store-4I4KL7TN.js} +1 -1
  213. package/chunks/{workspace-registry-LAQCRQTH.js → workspace-registry-N4J57SFQ.js} +25 -25
  214. package/chunks/{workspace-service-6ZEUJY2Z.js → workspace-service-JJNJWVH3.js} +32 -32
  215. package/chunks/{workspace-skills-status-YG6OITSM.js → workspace-skills-status-CEHLAQ2Y.js} +28 -28
  216. package/chunks/{write-file-E7T3PU3B.js → write-file-XRGEJRCC.js} +23 -23
  217. package/cli.js +11 -11
  218. package/package.json +3 -3
  219. package/web-shell/assets/{arc-_dVIKMdB.js → arc-DwJhljn9.js} +1 -1
  220. package/web-shell/assets/{architectureDiagram-3BPJPVTR-MuN3nKpL.js → architectureDiagram-3BPJPVTR-qdxSRav-.js} +1 -1
  221. package/web-shell/assets/{blockDiagram-GPEHLZMM-BtmvJjzx.js → blockDiagram-GPEHLZMM-2-dKM5aM.js} +1 -1
  222. package/web-shell/assets/{c4Diagram-AAUBKEIU-Dvi58_BU.js → c4Diagram-AAUBKEIU-Dt_Nu2HD.js} +1 -1
  223. package/web-shell/assets/channel-C6uyh95L.js +1 -0
  224. package/web-shell/assets/{chunk-2J33WTMH-YqxOVhS1.js → chunk-2J33WTMH-CBCeeNfD.js} +1 -1
  225. package/web-shell/assets/{chunk-4BX2VUAB-DoBgbC9z.js → chunk-4BX2VUAB-DPAzjqNs.js} +1 -1
  226. package/web-shell/assets/{chunk-55IACEB6-3NEQrBAr.js → chunk-55IACEB6-yrqyxvIK.js} +1 -1
  227. package/web-shell/assets/{chunk-727SXJPM-DrCZQxp0.js → chunk-727SXJPM-DguD_BBT.js} +1 -1
  228. package/web-shell/assets/{chunk-AQP2D5EJ-m_g3zjgv.js → chunk-AQP2D5EJ-KRUOG9v0.js} +1 -1
  229. package/web-shell/assets/{chunk-FMBD7UC4-D1_crABJ.js → chunk-FMBD7UC4-C0lilT2U.js} +1 -1
  230. package/web-shell/assets/{chunk-ND2GUHAM-BdhgVtBx.js → chunk-ND2GUHAM-DG9epIWK.js} +1 -1
  231. package/web-shell/assets/{chunk-QZHKN3VN-BlmThhm-.js → chunk-QZHKN3VN-PdJDkYHw.js} +1 -1
  232. package/web-shell/assets/classDiagram-4FO5ZUOK-Cv8Ulf-B.js +1 -0
  233. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-Cv8Ulf-B.js +1 -0
  234. package/web-shell/assets/{cose-bilkent-S5V4N54A-Cbjm_00Z.js → cose-bilkent-S5V4N54A-BAOPPuJm.js} +1 -1
  235. package/web-shell/assets/{dagre-BM42HDAG-C39QNVgC.js → dagre-BM42HDAG-CDHJv82_.js} +1 -1
  236. package/web-shell/assets/{diagram-2AECGRRQ-DNXSAixC.js → diagram-2AECGRRQ-C_hkG5fN.js} +1 -1
  237. package/web-shell/assets/{diagram-5GNKFQAL-BCbGUPEA.js → diagram-5GNKFQAL-e9zo_eKt.js} +1 -1
  238. package/web-shell/assets/{diagram-KO2AKTUF-1eujKSDC.js → diagram-KO2AKTUF-BFN41SCb.js} +1 -1
  239. package/web-shell/assets/{diagram-LMA3HP47-DUMKXgql.js → diagram-LMA3HP47-DG72N0W0.js} +1 -1
  240. package/web-shell/assets/{diagram-OG6HWLK6-BFktU3_u.js → diagram-OG6HWLK6-Dkmp-tdv.js} +1 -1
  241. package/web-shell/assets/{erDiagram-TEJ5UH35-BvJC7DLk.js → erDiagram-TEJ5UH35-CyS0GnQV.js} +1 -1
  242. package/web-shell/assets/{flowDiagram-I6XJVG4X-Cgu3PlOt.js → flowDiagram-I6XJVG4X-Cg1SRmzV.js} +1 -1
  243. package/web-shell/assets/{ganttDiagram-6RSMTGT7-DLNXN5Xh.js → ganttDiagram-6RSMTGT7-CoNkSLs3.js} +1 -1
  244. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-BQFRDv6R.js → gitGraphDiagram-PVQCEYII-DEA6GWPa.js} +1 -1
  245. package/web-shell/assets/index-B49xd8_A.css +5 -0
  246. package/web-shell/assets/{index-CdC3pjP3.js → index-CMaZgs6B.js} +1 -1
  247. package/web-shell/assets/index-D-cDAZgO.js +1192 -0
  248. package/web-shell/assets/{infoDiagram-5YYISTIA-DT2mOSvp.js → infoDiagram-5YYISTIA-BZshyoGT.js} +1 -1
  249. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-9fy_K4bd.js → ishikawaDiagram-YF4QCWOH-CT2ssZqC.js} +1 -1
  250. package/web-shell/assets/{journeyDiagram-JHISSGLW-CoGSEuhE.js → journeyDiagram-JHISSGLW-BtMQ0rDG.js} +1 -1
  251. package/web-shell/assets/{kanban-definition-UN3LZRKU-BP9hHYIj.js → kanban-definition-UN3LZRKU-CoDbK5Db.js} +1 -1
  252. package/web-shell/assets/{linear-uIroDsmp.js → linear-CwhZ6u7u.js} +1 -1
  253. package/web-shell/assets/{mermaid.core-BUwoStsA.js → mermaid.core-C9nn0nrr.js} +5 -5
  254. package/web-shell/assets/{mindmap-definition-RKZ34NQL-DZB-FWim.js → mindmap-definition-RKZ34NQL-BXUbjTeL.js} +1 -1
  255. package/web-shell/assets/{pieDiagram-4H26LBE5-YPptloKl.js → pieDiagram-4H26LBE5-JddiYlWQ.js} +1 -1
  256. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-dgk3DSzm.js → quadrantDiagram-W4KKPZXB-DK5HKzXO.js} +1 -1
  257. package/web-shell/assets/{requirementDiagram-4Y6WPE33-BH2En2i9.js → requirementDiagram-4Y6WPE33-Y-uipa_6.js} +1 -1
  258. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-BB98feeI.js → sankeyDiagram-5OEKKPKP-BbWeqo8H.js} +1 -1
  259. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CunAIGh8.js → sequenceDiagram-3UESZ5HK-tX2gOoo5.js} +1 -1
  260. package/web-shell/assets/{stateDiagram-AJRCARHV-DTJs_-I2.js → stateDiagram-AJRCARHV-CACN457G.js} +1 -1
  261. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DaUeO2zt.js +1 -0
  262. package/web-shell/assets/{timeline-definition-PNZ67QCA-Cd4AN7O0.js → timeline-definition-PNZ67QCA-DnHWKSOq.js} +1 -1
  263. package/web-shell/assets/{vennDiagram-CIIHVFJN-xIG-rUU9.js → vennDiagram-CIIHVFJN-BO8Yl2FG.js} +1 -1
  264. package/web-shell/assets/{wardley-L42UT6IY-D1UyjIcG.js → wardley-L42UT6IY-1NMqqrBi.js} +1 -1
  265. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-BVM0Mb99.js → wardleyDiagram-YWT4CUSO-C3eWgIvD.js} +1 -1
  266. package/web-shell/assets/{xychartDiagram-2RQKCTM6-BX31JDSz.js → xychartDiagram-2RQKCTM6-D0h8FgFX.js} +1 -1
  267. package/web-shell/index.html +2 -2
  268. package/chunks/chunk-675SVDMD.js +0 -3288
  269. package/chunks/chunk-CHVH4DVN.js +0 -368
  270. package/chunks/chunk-JCYMQU5F.js +0 -709
  271. package/chunks/nonInteractiveCli-EK35TLVJ.js +0 -129
  272. package/web-shell/assets/channel-Bi5TehaT.js +0 -1
  273. package/web-shell/assets/classDiagram-4FO5ZUOK-BKhhRdd1.js +0 -1
  274. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BKhhRdd1.js +0 -1
  275. package/web-shell/assets/index-C_ouplMQ.js +0 -1187
  276. package/web-shell/assets/index-XGDFJE-X.css +0 -5
  277. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DrfFMYta.js +0 -1
@@ -5,6 +5,7 @@ import {
5
5
  computeCpuPercent
6
6
  } from "./chunk-HGT6JR3U.js";
7
7
  import {
8
+ ACCESS_LOG_CONTROLLER_LOCAL,
8
9
  CAPABILITIES_SCHEMA_VERSION,
9
10
  ClientMcpSenderRegistry,
10
11
  PathMutexRegistry,
@@ -29,7 +30,7 @@ import {
29
30
  require_express,
30
31
  resolveWebShellDir,
31
32
  setDeferredRuntimeRequestTiming
32
- } from "./chunk-BEZPRKD3.js";
33
+ } from "./chunk-VLDBVLC4.js";
33
34
  import {
34
35
  isLoopbackBind
35
36
  } from "./chunk-RXFQM6FQ.js";
@@ -46,7 +47,7 @@ import {
46
47
  import "./chunk-WBL3FJEU.js";
47
48
  import {
48
49
  resolveChannelCwd
49
- } from "./chunk-E655RDRL.js";
50
+ } from "./chunk-4ODB7WIB.js";
50
51
  import {
51
52
  loadServeFastPathSettings,
52
53
  preResolveServeFastPathHomeEnvOverrides
@@ -55,16 +56,16 @@ import {
55
56
  MAX_REGISTERED_WORKSPACES,
56
57
  resolveWorkspaceInputs,
57
58
  workspaceRegistrationId
58
- } from "./chunk-EWPLL4OT.js";
59
+ } from "./chunk-6VGRTGOG.js";
59
60
  import {
60
61
  canonicalizeWorkspace
61
62
  } from "./chunk-W7FJ3N32.js";
62
- import "./chunk-MCYZTKBV.js";
63
- import "./chunk-BEFQGC6H.js";
63
+ import "./chunk-OLMETXLX.js";
64
+ import "./chunk-NBMIC7DR.js";
64
65
  import {
65
66
  ChannelWebhookEnqueueError,
66
67
  QWEN_SERVER_TOKEN_ENV
67
- } from "./chunk-HVWPSGDY.js";
68
+ } from "./chunk-Y2ENGUD6.js";
68
69
  import {
69
70
  channelSelectionNames
70
71
  } from "./chunk-TJTKSVIV.js";
@@ -73,7 +74,7 @@ import "./chunk-5HBA2Z7V.js";
73
74
  import "./chunk-T2NCM2ET.js";
74
75
  import {
75
76
  sanitizeLogText
76
- } from "./chunk-MHEZV3OY.js";
77
+ } from "./chunk-NIJEXGV6.js";
77
78
  import "./chunk-UDXSXLER.js";
78
79
  import "./chunk-GOXKNSDZ.js";
79
80
  import {
@@ -83,7 +84,7 @@ import {
83
84
  import "./chunk-QRUIS3DN.js";
84
85
  import {
85
86
  getCliVersion
86
- } from "./chunk-W4DFAUAO.js";
87
+ } from "./chunk-SQMTULHJ.js";
87
88
  import "./chunk-VJNBRRZG.js";
88
89
  import "./chunk-ALGGS7UH.js";
89
90
  import {
@@ -96,7 +97,9 @@ import {
96
97
  import "./chunk-5M6IDOMF.js";
97
98
  import "./chunk-T4TZQJ7W.js";
98
99
  import "./chunk-H6XPXXMH.js";
99
- import "./chunk-E2UVIFI2.js";
100
+ import {
101
+ require_proper_lockfile
102
+ } from "./chunk-E2UVIFI2.js";
100
103
  import "./chunk-CR3C7WXL.js";
101
104
  import "./chunk-XWRJCPHC.js";
102
105
  import {
@@ -122,7 +125,7 @@ import * as fs from "node:fs";
122
125
  import * as https from "node:https";
123
126
  import * as path from "node:path";
124
127
  import * as os from "node:os";
125
- import { monitorEventLoopDelay, performance } from "node:perf_hooks";
128
+ import { monitorEventLoopDelay, performance as performance2 } from "node:perf_hooks";
126
129
 
127
130
  // packages/cli/src/serve/permission-audit.ts
128
131
  init_esbuild_shims();
@@ -243,9 +246,11 @@ __name(createPermissionAuditPublisher, "createPermissionAuditPublisher");
243
246
 
244
247
  // packages/cli/src/serve/daemon-logger.ts
245
248
  init_esbuild_shims();
249
+ var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
246
250
  import * as nodeFs from "node:fs";
247
251
  import * as nodePath from "node:path";
248
252
  import * as crypto from "node:crypto";
253
+ import { performance } from "node:perf_hooks";
249
254
  var FIXED_CTX_ORDER = [
250
255
  "route",
251
256
  "sessionId",
@@ -254,6 +259,31 @@ var FIXED_CTX_ORDER = [
254
259
  "channelId"
255
260
  ];
256
261
  var FIXED_CTX_SET = new Set(FIXED_CTX_ORDER);
262
+ var ISSUE_ORDER = [
263
+ "init_failed",
264
+ "rotation_failed",
265
+ "retention_failed",
266
+ "queue_overflow",
267
+ "write_failed",
268
+ "lease_compromised"
269
+ ];
270
+ var DEFAULT_POLICY = {
271
+ maxBytes: 10 * 1024 * 1024,
272
+ maxArchives: 4,
273
+ maxRecordBytes: 256 * 1024,
274
+ maxPendingBytes: 4 * 1024 * 1024,
275
+ stableAcquireBudgetMs: 1e3,
276
+ maintenanceAcquireBudgetMs: 250,
277
+ lockStaleMs: 6e4,
278
+ lockUpdateMs: 1e4,
279
+ rotationRetryIntervalMs: 6e4,
280
+ closeDrainBudgetMs: 2e3
281
+ };
282
+ var ARCHIVE_RE = /^daemon-(\d{12})-(\d{8}T\d{9}Z)-([0-9a-f]{8})\.log$/;
283
+ var FALLBACK_DIR_RE = /^run-[0-9a-f]{32}$/;
284
+ var ARCHIVE_NAME_ATTEMPTS = 3;
285
+ var FILE_MODE = 384;
286
+ var DIRECTORY_MODE = 448;
257
287
  function renderCtxValue(value) {
258
288
  const s = String(value);
259
289
  return /[\s=]/.test(s) ? JSON.stringify(s) : s;
@@ -269,7 +299,7 @@ function renderCtx(ctx) {
269
299
  }
270
300
  }
271
301
  const extraKeys = Object.keys(ctx).filter(
272
- (k) => !FIXED_CTX_SET.has(k) && ctx[k] !== void 0 && ctx[k] !== null
302
+ (key) => !FIXED_CTX_SET.has(key) && ctx[key] !== void 0 && ctx[key] !== null
273
303
  ).sort();
274
304
  for (const key of extraKeys) {
275
305
  parts.push(`${key}=${renderCtxValue(ctx[key])}`);
@@ -280,7 +310,7 @@ __name(renderCtx, "renderCtx");
280
310
  function renderErr(err) {
281
311
  if (!err) return "";
282
312
  const body = err.stack ?? `${err.name ?? "Error"}: ${err.message}`;
283
- return body.split("\n").map((l) => ` ${l}`).join("\n") + "\n";
313
+ return body.split("\n").map((line) => ` ${line}`).join("\n") + "\n";
284
314
  }
285
315
  __name(renderErr, "renderErr");
286
316
  function buildDaemonLogLine(args) {
@@ -290,19 +320,17 @@ function buildDaemonLogLine(args) {
290
320
  ${renderErr(args.err)}`;
291
321
  }
292
322
  __name(buildDaemonLogLine, "buildDaemonLogLine");
293
- var NOOP_LOGGER = {
294
- info: /* @__PURE__ */ __name(() => {
295
- }, "info"),
296
- warn: /* @__PURE__ */ __name(() => {
297
- }, "warn"),
298
- error: /* @__PURE__ */ __name(() => {
299
- }, "error"),
300
- raw: /* @__PURE__ */ __name(() => {
301
- }, "raw"),
302
- getLogPath: /* @__PURE__ */ __name(() => "", "getLogPath"),
303
- getDaemonId: /* @__PURE__ */ __name(() => "", "getDaemonId"),
304
- flush: /* @__PURE__ */ __name(() => Promise.resolve(), "flush")
305
- };
323
+ function buildDaemonFileLogLine(args, runId, pid) {
324
+ const callerCtx = args.ctx ? Object.fromEntries(
325
+ Object.entries(args.ctx).filter(
326
+ ([key]) => key !== "runId" && key !== "pid"
327
+ )
328
+ ) : void 0;
329
+ const ctxStr = renderCtx(callerCtx);
330
+ return `${args.now.toISOString()} [${args.level}] [DAEMON] runId=${runId} pid=${pid} ${ctxStr}${args.message}
331
+ ${renderErr(args.err)}`;
332
+ }
333
+ __name(buildDaemonFileLogLine, "buildDaemonFileLogLine");
306
334
  function getRuntimeBaseDir(runtimeOutputDir, cwd) {
307
335
  const envDir = process.env["QWEN_RUNTIME_DIR"];
308
336
  if (envDir) return resolveConfigPathLite(envDir);
@@ -314,19 +342,6 @@ function resolveDaemonLogBaseDir(runtimeOutputDir, cwd) {
314
342
  return nodePath.join(getRuntimeBaseDir(runtimeOutputDir, cwd), "debug");
315
343
  }
316
344
  __name(resolveDaemonLogBaseDir, "resolveDaemonLogBaseDir");
317
- async function updateSymlinkBestEffort(linkPath, targetPath) {
318
- const linkDir = nodePath.dirname(linkPath);
319
- const relativeTarget = nodePath.relative(linkDir, targetPath);
320
- try {
321
- await nodeFs.promises.unlink(linkPath);
322
- } catch {
323
- }
324
- try {
325
- await nodeFs.promises.symlink(relativeTarget, linkPath);
326
- } catch {
327
- }
328
- }
329
- __name(updateSymlinkBestEffort, "updateSymlinkBestEffort");
330
345
  function isOptedOut() {
331
346
  const raw = process.env["QWEN_DAEMON_LOG_FILE"];
332
347
  if (!raw) return false;
@@ -341,73 +356,1252 @@ function computeDaemonId(pid) {
341
356
  return `daemon:${pid}`;
342
357
  }
343
358
  __name(computeDaemonId, "computeDaemonId");
344
- function computeDaemonLogFileName(pid) {
345
- return `serve-${pid}.log`;
359
+ function isErrno(error, code) {
360
+ return error instanceof Error && "code" in error && error.code === code;
346
361
  }
347
- __name(computeDaemonLogFileName, "computeDaemonLogFileName");
348
- function initDaemonLogger(opts) {
349
- if (isOptedOut()) return NOOP_LOGGER;
350
- const pid = opts.pid ?? process.pid;
351
- const now = opts.now ?? (() => /* @__PURE__ */ new Date());
352
- const stderr = opts.stderr ?? writeStderrLine;
353
- const baseDir = opts.baseDir ?? resolveDaemonLogBaseDir();
354
- const daemonId = computeDaemonId(pid);
355
- const workspaceHash = computeWorkspaceHash(opts.boundWorkspace);
356
- const daemonDir = nodePath.join(baseDir, "daemon");
357
- const logPath = nodePath.join(daemonDir, computeDaemonLogFileName(pid));
362
+ __name(isErrno, "isErrno");
363
+ function resolvePolicy(overrides) {
364
+ const policy = { ...DEFAULT_POLICY, ...overrides };
365
+ for (const [name, value] of Object.entries(policy)) {
366
+ if (!Number.isFinite(value) || value < 0) {
367
+ throw new TypeError(`Invalid daemon logger policy ${name}=${value}`);
368
+ }
369
+ }
370
+ if (policy.maxBytes === 0 || policy.maxArchives === 0 || policy.maxRecordBytes === 0 || policy.maxPendingBytes === 0) {
371
+ throw new TypeError(
372
+ "Daemon logger size/count policy values must be positive"
373
+ );
374
+ }
375
+ if (policy.maxRecordBytes > policy.maxBytes) {
376
+ throw new TypeError(
377
+ "Daemon logger maxRecordBytes must not exceed maxBytes"
378
+ );
379
+ }
380
+ if (policy.maxRecordBytes > policy.maxPendingBytes) {
381
+ throw new TypeError(
382
+ "Daemon logger maxRecordBytes must not exceed maxPendingBytes"
383
+ );
384
+ }
385
+ return policy;
386
+ }
387
+ __name(resolvePolicy, "resolvePolicy");
388
+ function statusSnapshot(runId, mode, issues, droppedRecords, droppedBytes) {
389
+ return {
390
+ runId,
391
+ mode,
392
+ health: issues.size === 0 ? "ok" : "degraded",
393
+ issues: ISSUE_ORDER.filter((issue) => issues.has(issue)),
394
+ droppedRecords,
395
+ droppedBytes
396
+ };
397
+ }
398
+ __name(statusSnapshot, "statusSnapshot");
399
+ function createStderrOnlyLogger(input) {
400
+ const tee = /* @__PURE__ */ __name((level, message, ctx, err) => {
401
+ input.stderr(
402
+ buildDaemonLogLine({
403
+ level,
404
+ message,
405
+ now: input.now(),
406
+ ctx,
407
+ err
408
+ }).trimEnd()
409
+ );
410
+ }, "tee");
411
+ return {
412
+ info: /* @__PURE__ */ __name((message, ctx) => tee("INFO", message, ctx), "info"),
413
+ warn: /* @__PURE__ */ __name((message, ctx) => tee("WARN", message, ctx), "warn"),
414
+ error: /* @__PURE__ */ __name((message, err, ctx) => tee("ERROR", message, ctx, err ?? void 0), "error"),
415
+ raw: /* @__PURE__ */ __name(() => {
416
+ }, "raw"),
417
+ getLogPath: /* @__PURE__ */ __name(() => "", "getLogPath"),
418
+ getDaemonId: /* @__PURE__ */ __name(() => input.daemonId, "getDaemonId"),
419
+ getStatus: /* @__PURE__ */ __name(() => statusSnapshot(input.runId, "stderr-only", input.issues, 0, 0), "getStatus"),
420
+ flush: /* @__PURE__ */ __name(() => Promise.resolve(), "flush"),
421
+ close: /* @__PURE__ */ __name(() => Promise.resolve(), "close")
422
+ };
423
+ }
424
+ __name(createStderrOnlyLogger, "createStderrOnlyLogger");
425
+ function capUtf8Record(record, maxBytes) {
426
+ const bytes = Buffer.from(record, "utf8");
427
+ if (bytes.length <= maxBytes) return record;
428
+ const marker = `
429
+ [truncated originalBytes=${bytes.length}]
430
+ `;
431
+ const markerBytes = Buffer.from(marker, "utf8");
432
+ if (markerBytes.length >= maxBytes) {
433
+ return Buffer.from("[truncated]\n", "utf8").subarray(0, maxBytes).toString("utf8");
434
+ }
435
+ let prefixBytes = maxBytes - markerBytes.length;
436
+ while (prefixBytes > 0 && (bytes[prefixBytes] & 192) === 128) {
437
+ prefixBytes -= 1;
438
+ }
439
+ return bytes.subarray(0, prefixBytes).toString("utf8") + marker;
440
+ }
441
+ __name(capUtf8Record, "capUtf8Record");
442
+ async function ensureRealDirectory(fs2, dirPath, mutationAllowed = () => true) {
443
+ try {
444
+ const existing = await fs2.lstat(dirPath);
445
+ if (!existing.isDirectory() || existing.isSymbolicLink()) {
446
+ throw new Error(`${dirPath} is not a real directory`);
447
+ }
448
+ return;
449
+ } catch (error) {
450
+ if (!isErrno(error, "ENOENT")) throw error;
451
+ }
452
+ if (!mutationAllowed()) {
453
+ throw new Error(`File mutation is no longer allowed for ${dirPath}`);
454
+ }
455
+ await fs2.mkdir(dirPath, { recursive: true, mode: DIRECTORY_MODE });
456
+ const created = await fs2.lstat(dirPath);
457
+ if (!created.isDirectory() || created.isSymbolicLink()) {
458
+ throw new Error(`${dirPath} is not a real directory`);
459
+ }
460
+ }
461
+ __name(ensureRealDirectory, "ensureRealDirectory");
462
+ async function activeFileSize(fs2, activePath) {
358
463
  try {
359
- nodeFs.mkdirSync(daemonDir, { recursive: true });
360
- const firstLine = buildDaemonLogLine({
361
- level: "INFO",
362
- message: `daemon started pid=${pid}`,
363
- now: now(),
364
- ctx: { workspace: opts.boundWorkspace, workspaceHash }
464
+ const stat = await fs2.lstat(activePath);
465
+ if (!stat.isFile() || stat.isSymbolicLink()) {
466
+ throw new Error(`${activePath} is not a regular file`);
467
+ }
468
+ return stat.size;
469
+ } catch (error) {
470
+ if (isErrno(error, "ENOENT")) return 0;
471
+ throw error;
472
+ }
473
+ }
474
+ __name(activeFileSize, "activeFileSize");
475
+ async function lastByteIsNewline(fs2, activePath, size) {
476
+ if (size === 0) return true;
477
+ const handle = await fs2.open(activePath, "r");
478
+ try {
479
+ const buffer = Buffer.allocUnsafe(1);
480
+ const result = await handle.read(buffer, 0, 1, size - 1);
481
+ return result.bytesRead === 1 && buffer[0] === 10;
482
+ } finally {
483
+ await handle.close();
484
+ }
485
+ }
486
+ __name(lastByteIsNewline, "lastByteIsNewline");
487
+ function archiveTimestamp(now) {
488
+ return now.toISOString().replace(/[-:.]/g, "");
489
+ }
490
+ __name(archiveTimestamp, "archiveTimestamp");
491
+ async function scanArchives(fs2, archiveDir) {
492
+ const entries = await fs2.readdir(archiveDir, { withFileTypes: true });
493
+ const archives = [];
494
+ for (const entry of entries) {
495
+ if (!entry.isFile()) continue;
496
+ const match = ARCHIVE_RE.exec(entry.name);
497
+ if (!match) continue;
498
+ archives.push({ name: entry.name, generation: Number(match[1]) });
499
+ }
500
+ archives.sort(
501
+ (a, b) => a.generation - b.generation || a.name.localeCompare(b.name)
502
+ );
503
+ return archives;
504
+ }
505
+ __name(scanArchives, "scanArchives");
506
+ function lockRetries(maxRetryTime) {
507
+ if (maxRetryTime <= 0) return 0;
508
+ return {
509
+ retries: 4,
510
+ factor: 2,
511
+ minTimeout: 50,
512
+ maxTimeout: 400,
513
+ randomize: true,
514
+ maxRetryTime
515
+ };
516
+ }
517
+ __name(lockRetries, "lockRetries");
518
+ async function acquireLease(input) {
519
+ const lease = {
520
+ compromised: false,
521
+ released: false,
522
+ release: /* @__PURE__ */ __name(async () => {
523
+ }, "release")
524
+ };
525
+ const release = await input.acquireLock(input.targetPath, {
526
+ lockfilePath: input.lockPath,
527
+ realpath: true,
528
+ stale: input.policy.lockStaleMs,
529
+ update: input.policy.lockUpdateMs,
530
+ retries: lockRetries(input.retryBudgetMs),
531
+ onCompromised: /* @__PURE__ */ __name((error) => {
532
+ if (lease.released) return;
533
+ lease.compromised = true;
534
+ try {
535
+ input.onCompromised?.(error);
536
+ } catch {
537
+ }
538
+ }, "onCompromised")
539
+ });
540
+ try {
541
+ if (lease.compromised) {
542
+ throw new Error(
543
+ `Lease was compromised while acquiring ${input.lockPath}`
544
+ );
545
+ }
546
+ await input.fs.chmod(input.lockPath, DIRECTORY_MODE);
547
+ } catch (error) {
548
+ lease.released = true;
549
+ await release().catch(() => {
365
550
  });
366
- nodeFs.appendFileSync(logPath, firstLine);
367
- } catch (err) {
368
- stderr(
369
- `qwen serve: daemon log disabled \u2014 init failed: ${err instanceof Error ? err.message : String(err)}`
551
+ throw error;
552
+ }
553
+ lease.release = async () => {
554
+ if (lease.released) return;
555
+ lease.released = true;
556
+ await release();
557
+ };
558
+ return lease;
559
+ }
560
+ __name(acquireLease, "acquireLease");
561
+ async function updateLatestBestEffort(fs2, daemonDir, targetPath, mutationAllowed) {
562
+ const linkPath = nodePath.join(daemonDir, "latest");
563
+ if (!mutationAllowed()) return;
564
+ try {
565
+ await fs2.unlink(linkPath);
566
+ } catch {
567
+ }
568
+ if (!mutationAllowed()) return;
569
+ try {
570
+ await fs2.symlink(nodePath.relative(daemonDir, targetPath), linkPath);
571
+ } catch {
572
+ }
573
+ }
574
+ __name(updateLatestBestEffort, "updateLatestBestEffort");
575
+ async function readRecentFallback(fs2, runsDir) {
576
+ try {
577
+ const raw = await fs2.readFile(
578
+ nodePath.join(runsDir, "recent-fallback"),
579
+ "utf8"
370
580
  );
371
- return NOOP_LOGGER;
581
+ const name = raw.trim();
582
+ return FALLBACK_DIR_RE.test(name) ? name : void 0;
583
+ } catch {
584
+ return void 0;
585
+ }
586
+ }
587
+ __name(readRecentFallback, "readRecentFallback");
588
+ async function writeRecentFallback(fs2, runsDir, name, mutationAllowed = () => true) {
589
+ const locatorPath = nodePath.join(runsDir, "recent-fallback");
590
+ if (!name) {
591
+ if (!mutationAllowed()) {
592
+ throw new Error("Fallback locator mutation is no longer allowed");
593
+ }
594
+ try {
595
+ await fs2.unlink(locatorPath);
596
+ } catch (error) {
597
+ if (!isErrno(error, "ENOENT")) throw error;
598
+ }
599
+ return;
600
+ }
601
+ if (!FALLBACK_DIR_RE.test(name)) {
602
+ throw new Error(`Invalid fallback locator target: ${name}`);
372
603
  }
604
+ const tempPath = nodePath.join(runsDir, ".recent-fallback.tmp");
373
605
  try {
374
- const aliasPath = nodePath.join(daemonDir, "latest");
375
- void updateSymlinkBestEffort(aliasPath, logPath);
606
+ const tempStat = await fs2.lstat(tempPath);
607
+ if (!tempStat.isFile() || tempStat.isSymbolicLink()) {
608
+ throw new Error(`${tempPath} is not a regular file`);
609
+ }
610
+ if (!mutationAllowed()) {
611
+ throw new Error("Fallback locator mutation is no longer allowed");
612
+ }
613
+ await fs2.unlink(tempPath);
614
+ } catch (error) {
615
+ if (!isErrno(error, "ENOENT")) throw error;
616
+ }
617
+ if (!mutationAllowed()) {
618
+ throw new Error("Fallback locator mutation is no longer allowed");
619
+ }
620
+ await fs2.writeFile(tempPath, `${name}
621
+ `, {
622
+ encoding: "utf8",
623
+ mode: FILE_MODE,
624
+ flag: "wx"
625
+ });
626
+ if (!mutationAllowed()) {
627
+ throw new Error("Fallback locator mutation is no longer allowed");
628
+ }
629
+ await fs2.rename(tempPath, locatorPath);
630
+ }
631
+ __name(writeRecentFallback, "writeRecentFallback");
632
+ async function listFallbackDirectories(fs2, runsDir) {
633
+ const entries = await fs2.readdir(runsDir, { withFileTypes: true });
634
+ return entries.filter((entry) => entry.isDirectory() && FALLBACK_DIR_RE.test(entry.name)).map((entry) => entry.name).sort();
635
+ }
636
+ __name(listFallbackDirectories, "listFallbackDirectories");
637
+ async function fallbackActivityMtime(fs2, familyDir) {
638
+ try {
639
+ return (await fs2.lstat(nodePath.join(familyDir, "daemon.log"))).mtimeMs;
640
+ } catch (error) {
641
+ if (!isErrno(error, "ENOENT")) throw error;
642
+ return (await fs2.lstat(familyDir)).mtimeMs;
643
+ }
644
+ }
645
+ __name(fallbackActivityMtime, "fallbackActivityMtime");
646
+ async function cleanupFallbackFamilies(input) {
647
+ const mutationAllowed = input.mutationAllowed ?? (() => true);
648
+ const locator = await readRecentFallback(input.fs, input.runsDir);
649
+ const names = await listFallbackDirectories(input.fs, input.runsDir);
650
+ const live = /* @__PURE__ */ new Set();
651
+ const inactive = [];
652
+ try {
653
+ for (const name of names) {
654
+ if (!mutationAllowed()) {
655
+ throw new Error("Fallback cleanup lease was compromised");
656
+ }
657
+ const familyDir = nodePath.join(input.runsDir, name);
658
+ let lease;
659
+ try {
660
+ lease = await acquireLease({
661
+ fs: input.fs,
662
+ acquireLock: input.acquireLock,
663
+ targetPath: familyDir,
664
+ lockPath: nodePath.join(familyDir, ".owner.lock"),
665
+ policy: input.policy,
666
+ retryBudgetMs: 0
667
+ });
668
+ if (!mutationAllowed()) {
669
+ throw new Error("Fallback cleanup lease was compromised");
670
+ }
671
+ if (lease.compromised) {
672
+ await lease.release().catch(() => {
673
+ });
674
+ throw new Error(`Fallback owner lease was compromised: ${familyDir}`);
675
+ }
676
+ inactive.push({
677
+ name,
678
+ mtimeMs: await fallbackActivityMtime(input.fs, familyDir),
679
+ lease
680
+ });
681
+ } catch (error) {
682
+ await lease?.release().catch(() => {
683
+ });
684
+ if (isErrno(error, "ELOCKED")) {
685
+ live.add(name);
686
+ continue;
687
+ }
688
+ throw error;
689
+ }
690
+ }
691
+ const inactiveNames = new Set(inactive.map((entry) => entry.name));
692
+ const retainedInactive = (input.preferredInactive && inactiveNames.has(input.preferredInactive) ? input.preferredInactive : void 0) ?? (locator && inactiveNames.has(locator) ? locator : void 0) ?? inactive.slice().sort(
693
+ (a, b) => b.mtimeMs - a.mtimeMs || b.name.localeCompare(a.name)
694
+ )[0]?.name;
695
+ for (const entry of inactive) {
696
+ await entry.lease.release();
697
+ if (entry.name === retainedInactive) continue;
698
+ if (!mutationAllowed()) {
699
+ throw new Error("Fallback cleanup lease was compromised");
700
+ }
701
+ await input.fs.rm(nodePath.join(input.runsDir, entry.name), {
702
+ recursive: true,
703
+ force: true
704
+ });
705
+ }
706
+ const remaining = [...live, ...retainedInactive ? [retainedInactive] : []].filter((name, index, all) => all.indexOf(name) === index).sort();
707
+ const nextLocator = retainedInactive ?? (locator && remaining.includes(locator) ? locator : remaining.at(-1));
708
+ if (locator !== nextLocator) {
709
+ await writeRecentFallback(
710
+ input.fs,
711
+ input.runsDir,
712
+ nextLocator,
713
+ mutationAllowed
714
+ ).catch(() => {
715
+ });
716
+ }
717
+ } finally {
718
+ await Promise.all(
719
+ inactive.filter((entry) => !entry.lease.released).map((entry) => entry.lease.release().catch(() => {
720
+ }))
721
+ );
722
+ }
723
+ }
724
+ __name(cleanupFallbackFamilies, "cleanupFallbackFamilies");
725
+ async function acquireMaintenanceLease(input) {
726
+ await ensureRealDirectory(input.fs, input.runsDir);
727
+ return acquireLease({
728
+ fs: input.fs,
729
+ acquireLock: input.acquireLock,
730
+ targetPath: input.runsDir,
731
+ lockPath: nodePath.join(input.runsDir, ".maintenance.lock"),
732
+ policy: input.policy,
733
+ retryBudgetMs: input.retryBudgetMs
734
+ });
735
+ }
736
+ __name(acquireMaintenanceLease, "acquireMaintenanceLease");
737
+ async function allocateFallbackFamily(input) {
738
+ const runsDir = nodePath.join(input.daemonDir, "runs");
739
+ const maintenance = await acquireMaintenanceLease({
740
+ ...input,
741
+ runsDir,
742
+ retryBudgetMs: input.policy.maintenanceAcquireBudgetMs
743
+ });
744
+ let familyDir;
745
+ let familyCreated = false;
746
+ let lease;
747
+ const maintenanceAllowsMutation = /* @__PURE__ */ __name(() => !maintenance.compromised && !maintenance.released, "maintenanceAllowsMutation");
748
+ try {
749
+ if (!maintenanceAllowsMutation()) {
750
+ throw new Error("Fallback maintenance lease was compromised");
751
+ }
752
+ await cleanupFallbackFamilies({
753
+ ...input,
754
+ runsDir,
755
+ mutationAllowed: maintenanceAllowsMutation
756
+ });
757
+ if (!maintenanceAllowsMutation()) {
758
+ throw new Error("Fallback maintenance lease was compromised");
759
+ }
760
+ const name = `run-${input.runId}`;
761
+ familyDir = nodePath.join(runsDir, name);
762
+ await input.fs.mkdir(familyDir, { mode: DIRECTORY_MODE });
763
+ familyCreated = true;
764
+ if (!maintenanceAllowsMutation()) {
765
+ throw new Error("Fallback maintenance lease was compromised");
766
+ }
767
+ lease = await acquireLease({
768
+ fs: input.fs,
769
+ acquireLock: input.acquireLock,
770
+ targetPath: familyDir,
771
+ lockPath: nodePath.join(familyDir, ".owner.lock"),
772
+ policy: input.policy,
773
+ retryBudgetMs: 0,
774
+ onCompromised: input.onCompromised
775
+ });
776
+ if (!maintenanceAllowsMutation()) {
777
+ throw new Error("Fallback maintenance lease was compromised");
778
+ }
779
+ } catch (error) {
780
+ await lease?.release().catch(() => {
781
+ });
782
+ if (familyCreated && familyDir && maintenanceAllowsMutation()) {
783
+ await input.fs.rm(familyDir, { recursive: true, force: true }).catch(() => {
784
+ });
785
+ }
786
+ await maintenance.release().catch(() => {
787
+ });
788
+ throw error;
789
+ }
790
+ try {
791
+ await maintenance.release();
792
+ } catch (error) {
793
+ await lease.release().catch(() => {
794
+ });
795
+ throw error;
796
+ }
797
+ return {
798
+ mode: "fallback",
799
+ activePath: nodePath.join(familyDir, "daemon.log"),
800
+ archiveDir: nodePath.join(familyDir, "archive"),
801
+ familyDir,
802
+ lease,
803
+ releaseLease: lease.release
804
+ };
805
+ }
806
+ __name(allocateFallbackFamily, "allocateFallbackFamily");
807
+ async function removeFailedFallbackBestEffort(input) {
808
+ if (input.family.lease.compromised) {
809
+ await input.family.releaseLease().catch(() => {
810
+ });
811
+ return;
812
+ }
813
+ const runsDir = nodePath.dirname(input.family.familyDir);
814
+ let maintenance;
815
+ try {
816
+ maintenance = await acquireMaintenanceLease({
817
+ ...input,
818
+ runsDir,
819
+ retryBudgetMs: 0
820
+ });
376
821
  } catch {
822
+ await input.family.releaseLease().catch(() => {
823
+ });
824
+ return;
825
+ }
826
+ try {
827
+ if (maintenance.compromised) {
828
+ await input.family.releaseLease().catch(() => {
829
+ });
830
+ return;
831
+ }
832
+ try {
833
+ await input.family.releaseLease();
834
+ } catch {
835
+ return;
836
+ }
837
+ if (maintenance.compromised || input.family.lease.compromised) return;
838
+ await input.fs.rm(input.family.familyDir, { recursive: true, force: true }).catch(() => {
839
+ });
840
+ } finally {
841
+ await maintenance.release().catch(() => {
842
+ });
843
+ }
844
+ }
845
+ __name(removeFailedFallbackBestEffort, "removeFailedFallbackBestEffort");
846
+ async function closeFallbackFamily(input) {
847
+ if (input.family.lease.compromised) {
848
+ await input.family.releaseLease().catch(() => {
849
+ });
850
+ return;
851
+ }
852
+ const runsDir = nodePath.dirname(input.family.familyDir);
853
+ let maintenance;
854
+ try {
855
+ maintenance = await acquireMaintenanceLease({
856
+ ...input,
857
+ runsDir,
858
+ retryBudgetMs: 0
859
+ });
860
+ } catch {
861
+ await input.family.releaseLease().catch(input.onRetentionError);
862
+ return;
377
863
  }
864
+ try {
865
+ if (maintenance.compromised) {
866
+ throw new Error("Fallback maintenance lease was compromised");
867
+ }
868
+ await input.family.releaseLease();
869
+ const name = nodePath.basename(input.family.familyDir);
870
+ const mutationAllowed = /* @__PURE__ */ __name(() => !maintenance.compromised && !input.family.lease.compromised, "mutationAllowed");
871
+ await cleanupFallbackFamilies({
872
+ ...input,
873
+ runsDir,
874
+ preferredInactive: name,
875
+ mutationAllowed
876
+ });
877
+ await writeRecentFallback(input.fs, runsDir, name, mutationAllowed);
878
+ } catch (error) {
879
+ await input.family.releaseLease().catch(input.onRetentionError);
880
+ input.onRetentionError(error);
881
+ } finally {
882
+ await maintenance.release().catch(input.onRetentionError);
883
+ }
884
+ }
885
+ __name(closeFallbackFamily, "closeFallbackFamily");
886
+ async function cleanupFallbacksBestEffort(input) {
887
+ const runsDir = nodePath.join(input.daemonDir, "runs");
888
+ try {
889
+ const stat = await input.fs.lstat(runsDir);
890
+ if (!stat.isDirectory() || stat.isSymbolicLink()) {
891
+ throw new Error(`${runsDir} is not a real directory`);
892
+ }
893
+ } catch (error) {
894
+ if (isErrno(error, "ENOENT")) return;
895
+ input.onRetentionError(error);
896
+ return;
897
+ }
898
+ let maintenance;
899
+ try {
900
+ const currentMaintenance = await acquireMaintenanceLease({
901
+ ...input,
902
+ runsDir,
903
+ retryBudgetMs: 0
904
+ });
905
+ maintenance = currentMaintenance;
906
+ const mutationAllowed = /* @__PURE__ */ __name(() => !currentMaintenance.compromised && !currentMaintenance.released && (input.mutationAllowed?.() ?? true), "mutationAllowed");
907
+ if (!mutationAllowed()) {
908
+ throw new Error("Fallback maintenance lease was compromised");
909
+ }
910
+ await cleanupFallbackFamilies({
911
+ ...input,
912
+ runsDir,
913
+ mutationAllowed
914
+ });
915
+ } catch (error) {
916
+ if (!isErrno(error, "ELOCKED")) input.onRetentionError(error);
917
+ } finally {
918
+ await maintenance?.release().catch(input.onRetentionError);
919
+ }
920
+ }
921
+ __name(cleanupFallbacksBestEffort, "cleanupFallbacksBestEffort");
922
+ function createConcreteLogger(input) {
378
923
  let pending = Promise.resolve();
379
- let degraded = false;
380
- const enqueueAppend = /* @__PURE__ */ __name((line) => {
381
- pending = pending.then(
382
- () => nodeFs.promises.appendFile(logPath, line).catch((err) => {
383
- if (!degraded) {
384
- degraded = true;
385
- stderr(
386
- `qwen serve: daemon log write failed \u2014 entering degraded mode: ${err instanceof Error ? err.message : String(err)}`
387
- );
924
+ let pendingBytes = 0;
925
+ let droppedRecords = 0;
926
+ let droppedBytes = 0;
927
+ let reportedDroppedRecords = 0;
928
+ let reportedDroppedBytes = 0;
929
+ let overflowEpisode = false;
930
+ let dropSummaryPending = false;
931
+ let acceptingFileRecords = true;
932
+ let closePromise;
933
+ const markDropped = /* @__PURE__ */ __name((bytes, queueOverflow = false) => {
934
+ droppedRecords += 1;
935
+ droppedBytes += bytes;
936
+ if (queueOverflow) {
937
+ input.issues.add("queue_overflow");
938
+ if (!overflowEpisode) {
939
+ overflowEpisode = true;
940
+ input.stderr(
941
+ "qwen serve: daemon log queue limit reached; dropping file copies until capacity recovers"
942
+ );
943
+ }
944
+ }
945
+ }, "markDropped");
946
+ const markRotationFailure = /* @__PURE__ */ __name((message, error) => {
947
+ input.issues.add("rotation_failed");
948
+ input.state.nextRotationRetryAt = input.monotonicNow() + input.policy.rotationRetryIntervalMs;
949
+ input.warnOnce(
950
+ `rotation:${message}`,
951
+ `qwen serve: daemon log rotation failed; ${message}${error ? `: ${error instanceof Error ? error.message : String(error)}` : ""}`
952
+ );
953
+ }, "markRotationFailure");
954
+ const markRetentionFailure = /* @__PURE__ */ __name((error) => {
955
+ input.issues.add("retention_failed");
956
+ input.warnOnce(
957
+ "retention",
958
+ `qwen serve: daemon log retention cleanup failed: ${error instanceof Error ? error.message : String(error)}`
959
+ );
960
+ }, "markRetentionFailure");
961
+ const fileMutationAllowed = /* @__PURE__ */ __name(() => !input.state.poisoned && !input.family.lease.compromised && !input.family.lease.released, "fileMutationAllowed");
962
+ const prepareArchives = /* @__PURE__ */ __name(async () => {
963
+ if (!input.state.archiveAvailable && input.monotonicNow() < input.state.nextRotationRetryAt) {
964
+ return false;
965
+ }
966
+ try {
967
+ await ensureRealDirectory(
968
+ input.fs,
969
+ input.family.archiveDir,
970
+ fileMutationAllowed
971
+ );
972
+ if (!fileMutationAllowed()) return false;
973
+ input.state.archives = await scanArchives(
974
+ input.fs,
975
+ input.family.archiveDir
976
+ );
977
+ input.state.nextArchiveGeneration = (input.state.archives.at(-1)?.generation ?? 0) + 1;
978
+ input.state.archiveAvailable = true;
979
+ input.state.nextRotationRetryAt = 0;
980
+ return true;
981
+ } catch (error) {
982
+ if (!fileMutationAllowed()) return false;
983
+ input.state.archiveAvailable = false;
984
+ markRotationFailure("continuing without file rotation", error);
985
+ return false;
986
+ }
987
+ }, "prepareArchives");
988
+ const pruneForRotation = /* @__PURE__ */ __name(async () => {
989
+ while (input.state.archives.length >= input.policy.maxArchives) {
990
+ if (!fileMutationAllowed()) return false;
991
+ const oldest = input.state.archives[0];
992
+ try {
993
+ await input.fs.unlink(
994
+ nodePath.join(input.family.archiveDir, oldest.name)
995
+ );
996
+ input.state.archives.shift();
997
+ } catch (error) {
998
+ if (isErrno(error, "ENOENT")) {
999
+ input.state.archives.shift();
1000
+ continue;
388
1001
  }
389
- })
1002
+ markRetentionFailure(error);
1003
+ input.state.nextRotationRetryAt = input.monotonicNow() + input.policy.rotationRetryIntervalMs;
1004
+ return false;
1005
+ }
1006
+ }
1007
+ return true;
1008
+ }, "pruneForRotation");
1009
+ const archivePath = /* @__PURE__ */ __name(async () => {
1010
+ const generation = input.state.nextArchiveGeneration;
1011
+ if (generation > 999999999999) {
1012
+ markRotationFailure("archive generation limit reached");
1013
+ return void 0;
1014
+ }
1015
+ for (let attempt = 0; attempt < ARCHIVE_NAME_ATTEMPTS; attempt += 1) {
1016
+ let name;
1017
+ try {
1018
+ name = `daemon-${String(generation).padStart(12, "0")}-${archiveTimestamp(input.now())}-${crypto.randomBytes(4).toString("hex")}.log`;
1019
+ } catch (error) {
1020
+ markRotationFailure("archive filename generation failed", error);
1021
+ return void 0;
1022
+ }
1023
+ const candidate = nodePath.join(input.family.archiveDir, name);
1024
+ try {
1025
+ await input.fs.lstat(candidate);
1026
+ } catch (error) {
1027
+ if (isErrno(error, "ENOENT")) return { name, generation };
1028
+ markRotationFailure("archive target validation failed", error);
1029
+ return void 0;
1030
+ }
1031
+ }
1032
+ markRotationFailure("archive filename collision limit reached");
1033
+ return void 0;
1034
+ }, "archivePath");
1035
+ const appendActive = /* @__PURE__ */ __name(async (record, forceRotation = false) => {
1036
+ if (!fileMutationAllowed()) return "dropped";
1037
+ const bytes = Buffer.byteLength(record, "utf8");
1038
+ const needsRotation = input.state.currentBytes > 0 && (forceRotation || input.state.currentBytes + bytes > input.policy.maxBytes);
1039
+ if (needsRotation) {
1040
+ if (input.monotonicNow() < input.state.nextRotationRetryAt) {
1041
+ return "dropped";
1042
+ }
1043
+ if (!await prepareArchives()) return "dropped";
1044
+ if (!fileMutationAllowed()) return "dropped";
1045
+ if (!await pruneForRotation()) return "dropped";
1046
+ const archive = await archivePath();
1047
+ if (!archive) return "dropped";
1048
+ if (!fileMutationAllowed()) return "dropped";
1049
+ try {
1050
+ await input.fs.rename(
1051
+ input.family.activePath,
1052
+ nodePath.join(input.family.archiveDir, archive.name)
1053
+ );
1054
+ } catch (error) {
1055
+ markRotationFailure("active file rename failed", error);
1056
+ return "dropped";
1057
+ }
1058
+ input.state.archives.push(archive);
1059
+ input.state.archives.sort(
1060
+ (a, b) => a.generation - b.generation || a.name.localeCompare(b.name)
1061
+ );
1062
+ input.state.nextArchiveGeneration = archive.generation + 1;
1063
+ input.state.currentBytes = 0;
1064
+ if (!fileMutationAllowed()) return "dropped";
1065
+ }
1066
+ if (!fileMutationAllowed()) return "dropped";
1067
+ try {
1068
+ if (input.state.exclusiveBootCreate) {
1069
+ await input.fs.writeFile(input.family.activePath, record, {
1070
+ encoding: "utf8",
1071
+ mode: FILE_MODE,
1072
+ flag: "wx"
1073
+ });
1074
+ input.state.exclusiveBootCreate = false;
1075
+ } else {
1076
+ await input.fs.appendFile(input.family.activePath, record, {
1077
+ encoding: "utf8",
1078
+ mode: FILE_MODE,
1079
+ flag: "a"
1080
+ });
1081
+ }
1082
+ input.state.currentBytes += bytes;
1083
+ return "written";
1084
+ } catch (error) {
1085
+ input.state.poisoned = true;
1086
+ input.issues.add("write_failed");
1087
+ input.warnOnce(
1088
+ "write-failed",
1089
+ `qwen serve: daemon log write failed; file logging disabled for this run: ${error instanceof Error ? error.message : String(error)}`
1090
+ );
1091
+ return "unknown";
1092
+ }
1093
+ }, "appendActive");
1094
+ const unreportedDropRecord = /* @__PURE__ */ __name(() => {
1095
+ const records = droppedRecords - reportedDroppedRecords;
1096
+ const bytes = droppedBytes - reportedDroppedBytes;
1097
+ if (records <= 0) return void 0;
1098
+ return capUtf8Record(
1099
+ buildDaemonFileLogLine(
1100
+ {
1101
+ level: "WARN",
1102
+ message: "daemon file log records dropped",
1103
+ now: input.now(),
1104
+ ctx: { droppedRecords: records, droppedBytes: bytes }
1105
+ },
1106
+ input.runId,
1107
+ input.pid
1108
+ ),
1109
+ input.policy.maxRecordBytes
390
1110
  );
391
- }, "enqueueAppend");
392
- const teeLine = /* @__PURE__ */ __name((level, message, ctx, err) => {
393
- const line = buildDaemonLogLine({ level, message, now: now(), ctx, err });
394
- stderr(line.trimEnd());
395
- enqueueAppend(line);
396
- }, "teeLine");
397
- return {
398
- info: /* @__PURE__ */ __name((message, ctx) => teeLine("INFO", message, ctx), "info"),
399
- warn: /* @__PURE__ */ __name((message, ctx) => teeLine("WARN", message, ctx), "warn"),
400
- error: /* @__PURE__ */ __name((message, err, ctx) => teeLine("ERROR", message, ctx, err ?? void 0), "error"),
1111
+ }, "unreportedDropRecord");
1112
+ const enqueueRecord = /* @__PURE__ */ __name((record, callerOriginated, onSettled) => {
1113
+ const bytes = Buffer.byteLength(record, "utf8");
1114
+ if (pendingBytes + bytes > input.policy.maxPendingBytes) {
1115
+ if (callerOriginated) markDropped(bytes, true);
1116
+ return false;
1117
+ }
1118
+ pendingBytes += bytes;
1119
+ pending = pending.then(async () => {
1120
+ let outcome = "unknown";
1121
+ try {
1122
+ outcome = await appendActive(record);
1123
+ if (callerOriginated && outcome === "dropped") markDropped(bytes);
1124
+ } catch (error) {
1125
+ input.state.poisoned = true;
1126
+ input.issues.add("write_failed");
1127
+ input.warnOnce(
1128
+ "queue-failed",
1129
+ `qwen serve: daemon log queue failed; file logging disabled for this run: ${error instanceof Error ? error.message : String(error)}`
1130
+ );
1131
+ } finally {
1132
+ onSettled?.(outcome);
1133
+ }
1134
+ }).catch(() => {
1135
+ }).finally(() => {
1136
+ pendingBytes -= bytes;
1137
+ });
1138
+ return true;
1139
+ }, "enqueueRecord");
1140
+ const enqueueDropSummary = /* @__PURE__ */ __name(() => {
1141
+ if (dropSummaryPending) return;
1142
+ const summary = unreportedDropRecord();
1143
+ if (!summary) return;
1144
+ const summaryRecords = droppedRecords;
1145
+ const summaryBytes = droppedBytes;
1146
+ if (enqueueRecord(summary, false, (outcome) => {
1147
+ if (outcome === "written") {
1148
+ reportedDroppedRecords = summaryRecords;
1149
+ reportedDroppedBytes = summaryBytes;
1150
+ }
1151
+ dropSummaryPending = false;
1152
+ })) {
1153
+ dropSummaryPending = true;
1154
+ overflowEpisode = false;
1155
+ }
1156
+ }, "enqueueDropSummary");
1157
+ const submitFileRecord = /* @__PURE__ */ __name((record) => {
1158
+ if (!acceptingFileRecords) return;
1159
+ const bytes = Buffer.byteLength(record, "utf8");
1160
+ if (!fileMutationAllowed()) {
1161
+ markDropped(bytes);
1162
+ return;
1163
+ }
1164
+ enqueueDropSummary();
1165
+ enqueueRecord(record, true);
1166
+ }, "submitFileRecord");
1167
+ const tee = /* @__PURE__ */ __name((level, message, ctx, err) => {
1168
+ const timestamp = input.now();
1169
+ input.stderr(
1170
+ buildDaemonLogLine({
1171
+ level,
1172
+ message,
1173
+ now: timestamp,
1174
+ ctx,
1175
+ err
1176
+ }).trimEnd()
1177
+ );
1178
+ submitFileRecord(
1179
+ capUtf8Record(
1180
+ buildDaemonFileLogLine(
1181
+ { level, message, now: timestamp, ctx, err },
1182
+ input.runId,
1183
+ input.pid
1184
+ ),
1185
+ input.policy.maxRecordBytes
1186
+ )
1187
+ );
1188
+ }, "tee");
1189
+ const finalize = /* @__PURE__ */ __name(async () => {
1190
+ await pending;
1191
+ const summary = unreportedDropRecord();
1192
+ if (summary && !input.state.poisoned && !input.family.lease.compromised) {
1193
+ if (await appendActive(summary) === "written") {
1194
+ reportedDroppedRecords = droppedRecords;
1195
+ reportedDroppedBytes = droppedBytes;
1196
+ }
1197
+ }
1198
+ if (input.family.mode === "fallback") {
1199
+ await closeFallbackFamily({
1200
+ ...input,
1201
+ onRetentionError: markRetentionFailure
1202
+ });
1203
+ } else {
1204
+ await input.family.releaseLease().catch((error) => {
1205
+ input.warnOnce(
1206
+ "release-failed",
1207
+ `qwen serve: daemon log lease release failed: ${error instanceof Error ? error.message : String(error)}`
1208
+ );
1209
+ });
1210
+ }
1211
+ }, "finalize");
1212
+ const logger = {
1213
+ info: /* @__PURE__ */ __name((message, ctx) => tee("INFO", message, ctx), "info"),
1214
+ warn: /* @__PURE__ */ __name((message, ctx) => tee("WARN", message, ctx), "warn"),
1215
+ error: /* @__PURE__ */ __name((message, err, ctx) => tee("ERROR", message, ctx, err ?? void 0), "error"),
401
1216
  raw: /* @__PURE__ */ __name((line, level = "info") => {
402
- const upper = level.toUpperCase();
403
- const formatted = `${now().toISOString()} [${upper}] [DAEMON] ${line}
404
- `;
405
- enqueueAppend(formatted);
1217
+ submitFileRecord(
1218
+ capUtf8Record(
1219
+ buildDaemonFileLogLine(
1220
+ {
1221
+ level: level.toUpperCase(),
1222
+ message: line,
1223
+ now: input.now()
1224
+ },
1225
+ input.runId,
1226
+ input.pid
1227
+ ),
1228
+ input.policy.maxRecordBytes
1229
+ )
1230
+ );
406
1231
  }, "raw"),
407
- getLogPath: /* @__PURE__ */ __name(() => logPath, "getLogPath"),
408
- getDaemonId: /* @__PURE__ */ __name(() => daemonId, "getDaemonId"),
409
- flush: /* @__PURE__ */ __name(() => pending, "flush")
1232
+ getLogPath: /* @__PURE__ */ __name(() => input.family.activePath, "getLogPath"),
1233
+ getDaemonId: /* @__PURE__ */ __name(() => input.daemonId, "getDaemonId"),
1234
+ getStatus: /* @__PURE__ */ __name(() => statusSnapshot(
1235
+ input.runId,
1236
+ input.family.mode,
1237
+ input.issues,
1238
+ droppedRecords,
1239
+ droppedBytes
1240
+ ), "getStatus"),
1241
+ flush: /* @__PURE__ */ __name(() => pending, "flush"),
1242
+ close: /* @__PURE__ */ __name(() => {
1243
+ if (closePromise) return closePromise;
1244
+ acceptingFileRecords = false;
1245
+ const finalizer = finalize().catch((error) => {
1246
+ try {
1247
+ input.warnOnce(
1248
+ "close-failed",
1249
+ `qwen serve: daemon log close failed: ${error instanceof Error ? error.message : String(error)}`
1250
+ );
1251
+ } catch {
1252
+ }
1253
+ });
1254
+ let timeout;
1255
+ const deadline = new Promise((resolve) => {
1256
+ timeout = setTimeout(() => {
1257
+ try {
1258
+ input.warnOnce(
1259
+ "close-timeout",
1260
+ `qwen serve: daemon log close drain exceeded ${input.policy.closeDrainBudgetMs}ms; ownership will release after pending I/O settles or process exit`
1261
+ );
1262
+ } catch {
1263
+ } finally {
1264
+ resolve();
1265
+ }
1266
+ }, input.policy.closeDrainBudgetMs);
1267
+ timeout.unref();
1268
+ });
1269
+ closePromise = Promise.race([finalizer, deadline]).then(() => {
1270
+ if (timeout) clearTimeout(timeout);
1271
+ });
1272
+ return closePromise;
1273
+ }, "close")
410
1274
  };
1275
+ return { logger, writeInitialRecord: appendActive };
1276
+ }
1277
+ __name(createConcreteLogger, "createConcreteLogger");
1278
+ async function initDaemonLogger(opts) {
1279
+ const pid = opts.pid ?? process.pid;
1280
+ const now = opts.now ?? (() => /* @__PURE__ */ new Date());
1281
+ const monotonicNow = opts.monotonicNow ?? (() => performance.now());
1282
+ const stderr = opts.stderr ?? writeStderrLine;
1283
+ const baseDir = opts.baseDir ?? resolveDaemonLogBaseDir();
1284
+ const runId = opts.runId ?? crypto.randomBytes(16).toString("hex");
1285
+ const policy = resolvePolicy(opts.policy);
1286
+ const fs2 = opts.fs ?? nodeFs.promises;
1287
+ const acquireLock = opts.acquireLock ?? import_proper_lockfile.default.lock;
1288
+ const issues = /* @__PURE__ */ new Set();
1289
+ const warned = /* @__PURE__ */ new Set();
1290
+ const warnOnce = /* @__PURE__ */ __name((key, message) => {
1291
+ if (warned.has(key)) return;
1292
+ warned.add(key);
1293
+ try {
1294
+ stderr(message);
1295
+ } catch {
1296
+ }
1297
+ }, "warnOnce");
1298
+ if (isOptedOut()) {
1299
+ return createStderrOnlyLogger({
1300
+ runId,
1301
+ daemonId: computeDaemonId(pid),
1302
+ now,
1303
+ stderr,
1304
+ issues
1305
+ });
1306
+ }
1307
+ const daemonDir = nodePath.join(baseDir, "daemon");
1308
+ try {
1309
+ await ensureRealDirectory(fs2, daemonDir);
1310
+ } catch (error) {
1311
+ issues.add("init_failed");
1312
+ warnOnce(
1313
+ "init",
1314
+ `qwen serve: daemon log disabled \u2014 init failed: ${error instanceof Error ? error.message : String(error)}`
1315
+ );
1316
+ return createStderrOnlyLogger({
1317
+ runId,
1318
+ daemonId: computeDaemonId(pid),
1319
+ now,
1320
+ stderr,
1321
+ issues
1322
+ });
1323
+ }
1324
+ let currentState;
1325
+ const onCompromised = /* @__PURE__ */ __name((error) => {
1326
+ issues.add("lease_compromised");
1327
+ if (currentState) currentState.poisoned = true;
1328
+ warnOnce(
1329
+ "lease-compromised",
1330
+ `qwen serve: daemon log lease compromised; file logging disabled for this run: ${error.message}`
1331
+ );
1332
+ }, "onCompromised");
1333
+ const tryFamily = /* @__PURE__ */ __name(async (family) => {
1334
+ let state;
1335
+ try {
1336
+ const currentBytes = await activeFileSize(fs2, family.activePath);
1337
+ if (family.mode === "fallback" && currentBytes !== 0) {
1338
+ throw new Error(
1339
+ "New fallback family unexpectedly contains an active log"
1340
+ );
1341
+ }
1342
+ const completeTail = await lastByteIsNewline(
1343
+ fs2,
1344
+ family.activePath,
1345
+ currentBytes
1346
+ );
1347
+ let archiveAvailable = true;
1348
+ let archives = [];
1349
+ const familyMutationAllowed = /* @__PURE__ */ __name(() => !family.lease.compromised && !family.lease.released, "familyMutationAllowed");
1350
+ try {
1351
+ await ensureRealDirectory(fs2, family.archiveDir, familyMutationAllowed);
1352
+ if (!familyMutationAllowed()) {
1353
+ throw new Error("Daemon log family lease was compromised");
1354
+ }
1355
+ archives = await scanArchives(fs2, family.archiveDir);
1356
+ } catch (error) {
1357
+ archiveAvailable = false;
1358
+ if (familyMutationAllowed()) {
1359
+ issues.add("rotation_failed");
1360
+ warnOnce(
1361
+ `archive-init:${family.mode}`,
1362
+ `qwen serve: daemon log archive unavailable; active file will remain bounded: ${error instanceof Error ? error.message : String(error)}`
1363
+ );
1364
+ }
1365
+ }
1366
+ state = {
1367
+ currentBytes,
1368
+ archives,
1369
+ nextArchiveGeneration: (archives.at(-1)?.generation ?? 0) + 1,
1370
+ archiveAvailable,
1371
+ exclusiveBootCreate: family.mode === "fallback",
1372
+ poisoned: false,
1373
+ nextRotationRetryAt: archiveAvailable ? 0 : monotonicNow() + policy.rotationRetryIntervalMs
1374
+ };
1375
+ currentState = state;
1376
+ const concrete = createConcreteLogger({
1377
+ fs: fs2,
1378
+ acquireLock,
1379
+ policy,
1380
+ family,
1381
+ state,
1382
+ runId,
1383
+ pid,
1384
+ daemonId: computeDaemonId(pid),
1385
+ now,
1386
+ monotonicNow,
1387
+ stderr,
1388
+ issues,
1389
+ warnOnce
1390
+ });
1391
+ const bootCtx = {
1392
+ workspace: opts.boundWorkspace,
1393
+ workspaceHash: computeWorkspaceHash(opts.boundWorkspace)
1394
+ };
1395
+ const bootTime = now();
1396
+ const plainBoot = capUtf8Record(
1397
+ buildDaemonFileLogLine(
1398
+ {
1399
+ level: "INFO",
1400
+ message: "daemon started",
1401
+ now: bootTime,
1402
+ ctx: bootCtx
1403
+ },
1404
+ runId,
1405
+ pid
1406
+ ),
1407
+ policy.maxRecordBytes
1408
+ );
1409
+ const incompleteTailBoot = !completeTail ? `
1410
+ ${capUtf8Record(
1411
+ buildDaemonFileLogLine(
1412
+ {
1413
+ level: "INFO",
1414
+ message: "daemon started",
1415
+ now: bootTime,
1416
+ ctx: { ...bootCtx, previousTailIncomplete: true }
1417
+ },
1418
+ runId,
1419
+ pid
1420
+ ),
1421
+ policy.maxRecordBytes - 1
1422
+ )}` : plainBoot;
1423
+ const wouldRotate = currentBytes > 0 && currentBytes + Buffer.byteLength(incompleteTailBoot, "utf8") > policy.maxBytes;
1424
+ const bootRecord = !completeTail && !wouldRotate ? incompleteTailBoot : plainBoot;
1425
+ const bootOutcome = await concrete.writeInitialRecord(
1426
+ bootRecord,
1427
+ wouldRotate
1428
+ );
1429
+ if (bootOutcome !== "written" || state.poisoned || family.lease.compromised) {
1430
+ return void 0;
1431
+ }
1432
+ if (state.archiveAvailable && state.archives.length > policy.maxArchives) {
1433
+ try {
1434
+ while (state.archives.length > policy.maxArchives) {
1435
+ if (family.lease.compromised || family.lease.released) break;
1436
+ const oldest = state.archives[0];
1437
+ if (!oldest) break;
1438
+ try {
1439
+ await fs2.unlink(nodePath.join(family.archiveDir, oldest.name));
1440
+ } catch (error) {
1441
+ if (!isErrno(error, "ENOENT")) throw error;
1442
+ }
1443
+ state.archives.shift();
1444
+ }
1445
+ } catch (error) {
1446
+ issues.add("retention_failed");
1447
+ state.nextRotationRetryAt = monotonicNow() + policy.rotationRetryIntervalMs;
1448
+ warnOnce(
1449
+ "startup-retention",
1450
+ `qwen serve: daemon log retention cleanup failed: ${error instanceof Error ? error.message : String(error)}`
1451
+ );
1452
+ }
1453
+ }
1454
+ return concrete.logger;
1455
+ } catch (error) {
1456
+ warnOnce(
1457
+ `family-init:${family.mode}`,
1458
+ `qwen serve: daemon ${family.mode} log initialization failed: ${error instanceof Error ? error.message : String(error)}`
1459
+ );
1460
+ return void 0;
1461
+ }
1462
+ }, "tryFamily");
1463
+ try {
1464
+ const stableLease = await acquireLease({
1465
+ fs: fs2,
1466
+ acquireLock,
1467
+ targetPath: daemonDir,
1468
+ lockPath: nodePath.join(daemonDir, ".stable-writer.lock"),
1469
+ policy,
1470
+ retryBudgetMs: policy.stableAcquireBudgetMs,
1471
+ onCompromised
1472
+ });
1473
+ const stableFamily = {
1474
+ mode: "stable",
1475
+ activePath: nodePath.join(daemonDir, "daemon.log"),
1476
+ archiveDir: nodePath.join(daemonDir, "archive"),
1477
+ familyDir: daemonDir,
1478
+ lease: stableLease,
1479
+ releaseLease: stableLease.release
1480
+ };
1481
+ const stableLogger = await tryFamily(stableFamily);
1482
+ if (stableLogger) {
1483
+ if (!stableLease.compromised && !stableLease.released) {
1484
+ await updateLatestBestEffort(
1485
+ fs2,
1486
+ daemonDir,
1487
+ stableFamily.activePath,
1488
+ () => !stableLease.compromised && !stableLease.released
1489
+ );
1490
+ }
1491
+ if (!stableLease.compromised && !stableLease.released) {
1492
+ await cleanupFallbacksBestEffort({
1493
+ fs: fs2,
1494
+ acquireLock,
1495
+ policy,
1496
+ daemonDir,
1497
+ mutationAllowed: /* @__PURE__ */ __name(() => !stableLease.compromised && !stableLease.released, "mutationAllowed"),
1498
+ onRetentionError: /* @__PURE__ */ __name((error) => {
1499
+ issues.add("retention_failed");
1500
+ warnOnce(
1501
+ "fallback-retention",
1502
+ `qwen serve: daemon fallback log cleanup failed: ${error instanceof Error ? error.message : String(error)}`
1503
+ );
1504
+ }, "onRetentionError")
1505
+ });
1506
+ }
1507
+ return stableLogger;
1508
+ }
1509
+ issues.add("init_failed");
1510
+ try {
1511
+ await stableLease.release();
1512
+ } catch (error) {
1513
+ warnOnce(
1514
+ "stable-release",
1515
+ `qwen serve: daemon stable log lease release failed; trying fallback: ${error instanceof Error ? error.message : String(error)}`
1516
+ );
1517
+ }
1518
+ } catch (error) {
1519
+ if (isErrno(error, "ELOCKED")) {
1520
+ warnOnce(
1521
+ "stable-contention",
1522
+ `qwen serve: daemon stable log is owned by another daemon instance; using a fallback log for runId=${runId}`
1523
+ );
1524
+ } else {
1525
+ issues.add("init_failed");
1526
+ warnOnce(
1527
+ "stable-lock",
1528
+ `qwen serve: daemon stable log unavailable; trying a fallback: ${error instanceof Error ? error.message : String(error)}`
1529
+ );
1530
+ }
1531
+ }
1532
+ let fallbackFamily;
1533
+ try {
1534
+ fallbackFamily = await allocateFallbackFamily({
1535
+ fs: fs2,
1536
+ acquireLock,
1537
+ policy,
1538
+ daemonDir,
1539
+ runId,
1540
+ onCompromised
1541
+ });
1542
+ const activeFallbackFamily = fallbackFamily;
1543
+ const fallbackLogger = await tryFamily(activeFallbackFamily);
1544
+ if (!fallbackLogger) {
1545
+ issues.add("init_failed");
1546
+ await removeFailedFallbackBestEffort({
1547
+ fs: fs2,
1548
+ acquireLock,
1549
+ policy,
1550
+ family: activeFallbackFamily
1551
+ });
1552
+ return createStderrOnlyLogger({
1553
+ runId,
1554
+ daemonId: computeDaemonId(pid),
1555
+ now,
1556
+ stderr,
1557
+ issues
1558
+ });
1559
+ }
1560
+ const runsDir = nodePath.dirname(activeFallbackFamily.familyDir);
1561
+ try {
1562
+ if (activeFallbackFamily.lease.compromised) return fallbackLogger;
1563
+ const maintenance = await acquireMaintenanceLease({
1564
+ fs: fs2,
1565
+ acquireLock,
1566
+ policy,
1567
+ runsDir,
1568
+ retryBudgetMs: 0
1569
+ });
1570
+ try {
1571
+ if (!activeFallbackFamily.lease.compromised) {
1572
+ await writeRecentFallback(
1573
+ fs2,
1574
+ runsDir,
1575
+ nodePath.basename(activeFallbackFamily.familyDir),
1576
+ () => !maintenance.compromised && !maintenance.released && !activeFallbackFamily.lease.compromised
1577
+ );
1578
+ }
1579
+ } finally {
1580
+ await maintenance.release();
1581
+ }
1582
+ } catch (error) {
1583
+ warnOnce(
1584
+ "fallback-locator",
1585
+ `qwen serve: daemon fallback locator update failed; use ${activeFallbackFamily.activePath}: ${error instanceof Error ? error.message : String(error)}`
1586
+ );
1587
+ }
1588
+ return fallbackLogger;
1589
+ } catch (error) {
1590
+ issues.add("init_failed");
1591
+ await fallbackFamily?.releaseLease().catch(() => {
1592
+ });
1593
+ warnOnce(
1594
+ "fallback-init",
1595
+ `qwen serve: daemon log disabled \u2014 fallback init failed: ${error instanceof Error ? error.message : String(error)}`
1596
+ );
1597
+ return createStderrOnlyLogger({
1598
+ runId,
1599
+ daemonId: computeDaemonId(pid),
1600
+ now,
1601
+ stderr,
1602
+ issues
1603
+ });
1604
+ }
411
1605
  }
412
1606
  __name(initDaemonLogger, "initDaemonLogger");
413
1607
 
@@ -941,6 +2135,30 @@ var QWEN_SERVE_CDP_TUNNEL_OVER_WS_ENV = "QWEN_SERVE_CDP_TUNNEL_OVER_WS";
941
2135
  var QWEN_SERVE_PROMPT_DEADLINE_MS_ENV = "QWEN_SERVE_PROMPT_DEADLINE_MS";
942
2136
  var QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS_ENV = "QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS";
943
2137
  var SHUTDOWN_FORCE_CLOSE_MS = 5e3;
2138
+ var DAEMON_LOG_FORCED_FLUSH_BUDGET_MS = 250;
2139
+ async function flushDaemonLogBounded(daemonLog, budgetMs) {
2140
+ let timer;
2141
+ try {
2142
+ await Promise.race([
2143
+ daemonLog.flush().catch(() => {
2144
+ }),
2145
+ new Promise((resolve) => {
2146
+ timer = setTimeout(resolve, budgetMs);
2147
+ timer.unref();
2148
+ })
2149
+ ]);
2150
+ } finally {
2151
+ if (timer) clearTimeout(timer);
2152
+ }
2153
+ }
2154
+ __name(flushDaemonLogBounded, "flushDaemonLogBounded");
2155
+ function writeDaemonLifecycleBestEffort(write) {
2156
+ try {
2157
+ write();
2158
+ } catch {
2159
+ }
2160
+ }
2161
+ __name(writeDaemonLifecycleBestEffort, "writeDaemonLifecycleBestEffort");
944
2162
  function daemonPipeDirection(direction) {
945
2163
  switch (direction) {
946
2164
  case "sent":
@@ -1139,12 +2357,12 @@ __name(withSettingsLock, "withSettingsLock");
1139
2357
  var channelWorkerRuntimePromise;
1140
2358
  async function loadChannelWorkerRuntime() {
1141
2359
  channelWorkerRuntimePromise ??= Promise.all([
1142
- import("./channel-worker-supervisor-JA6VZ5V5.js"),
1143
- import("./pidfile-WKUVXDMR.js"),
1144
- import("./runtime-6IVKJSLW.js"),
2360
+ import("./channel-worker-supervisor-ZGO2W2MD.js"),
2361
+ import("./pidfile-MVZDE5TC.js"),
2362
+ import("./runtime-4KGNL3TP.js"),
1145
2363
  import("./cli-entry-path-4VJ3Y6T2.js"),
1146
- import("./channel-worker-group-S3H5QHTI.js"),
1147
- import("./channel-worker-manager-ZJ4HTMO2.js")
2364
+ import("./channel-worker-group-53CMOPFT.js"),
2365
+ import("./channel-worker-manager-UTXILKC2.js")
1148
2366
  ]).then(
1149
2367
  ([
1150
2368
  supervisor,
@@ -1249,7 +2467,7 @@ function shouldPreheatBridge(deps) {
1249
2467
  __name(shouldPreheatBridge, "shouldPreheatBridge");
1250
2468
  var coreRuntimePromise;
1251
2469
  function loadCoreRuntime() {
1252
- coreRuntimePromise ??= import("./src-ADLNIPHD.js");
2470
+ coreRuntimePromise ??= import("./src-DUFUUEHE.js");
1253
2471
  return coreRuntimePromise;
1254
2472
  }
1255
2473
  __name(loadCoreRuntime, "loadCoreRuntime");
@@ -1279,10 +2497,10 @@ __name(resolveDaemonLogBaseDirForRun, "resolveDaemonLogBaseDirForRun");
1279
2497
  var settingsRuntimePromise;
1280
2498
  function loadSettingsRuntimeModules() {
1281
2499
  settingsRuntimePromise ??= Promise.all([
1282
- import("./settings-ZX3OKUT4.js"),
1283
- import("./environment-LOCDCWMZ.js"),
1284
- import("./loadedSettingsAdapter-446B6WKA.js"),
1285
- import("./trustedFolders-CY4TUPDJ.js")
2500
+ import("./settings-H5O22TGQ.js"),
2501
+ import("./environment-KHS35XJY.js"),
2502
+ import("./loadedSettingsAdapter-3DUNHAPX.js"),
2503
+ import("./trustedFolders-ANQXYAQT.js")
1286
2504
  ]).then(([settings, environment, loadedSettingsAdapter, trustedFolders]) => ({
1287
2505
  settings,
1288
2506
  environment,
@@ -1295,8 +2513,8 @@ __name(loadSettingsRuntimeModules, "loadSettingsRuntimeModules");
1295
2513
  var channelWebhookConfigRuntimePromise;
1296
2514
  function loadChannelWebhookConfigRuntime() {
1297
2515
  channelWebhookConfigRuntimePromise ??= Promise.all([
1298
- import("./runtime-6IVKJSLW.js"),
1299
- import("./config-utils-KWTRFP7D.js")
2516
+ import("./runtime-4KGNL3TP.js"),
2517
+ import("./config-utils-AHQ6YZ66.js")
1300
2518
  ]).then(([channelRuntime, configUtils]) => ({
1301
2519
  loadChannelsConfig: channelRuntime.loadChannelsConfig,
1302
2520
  parseChannelWebhookConfig: configUtils.parseChannelWebhookConfig
@@ -1320,16 +2538,16 @@ async function loadServeRuntimeModules() {
1320
2538
  totalSessionAdmissionModule,
1321
2539
  workspaceRegistryModule
1322
2540
  ] = await Promise.all([
1323
- import("./server-AA24QLPA.js"),
1324
- import("./bridge-ATN2TLWJ.js"),
1325
- import("./spawnChannel-6WFOK3SA.js"),
1326
- import("./workspace-service-6ZEUJY2Z.js"),
2541
+ import("./server-RTJUMN24.js"),
2542
+ import("./bridge-OW5FZ6BF.js"),
2543
+ import("./spawnChannel-G7DUQKHL.js"),
2544
+ import("./workspace-service-JJNJWVH3.js"),
1327
2545
  import("./types-ML3TRJQ5.js"),
1328
- import("./daemon-status-provider-GTZOYSBO.js"),
1329
- import("./workspace-providers-status-UHQOIPAZ.js"),
1330
- import("./workspace-skills-status-YG6OITSM.js"),
1331
- import("./total-session-admission-S6ATY5HY.js"),
1332
- import("./workspace-registry-LAQCRQTH.js")
2546
+ import("./daemon-status-provider-L5UW7TGV.js"),
2547
+ import("./workspace-providers-status-XCQKBVSX.js"),
2548
+ import("./workspace-skills-status-CEHLAQ2Y.js"),
2549
+ import("./total-session-admission-KOPTGDJZ.js"),
2550
+ import("./workspace-registry-N4J57SFQ.js")
1333
2551
  ]);
1334
2552
  return {
1335
2553
  createServeApp: serverModule.createServeApp,
@@ -1640,12 +2858,21 @@ function createBootstrapServeApp(input) {
1640
2858
  severity: "warning",
1641
2859
  message: "Daemon runtime is still starting."
1642
2860
  };
2861
+ const daemonLogStatus = daemonLog.getStatus();
2862
+ const issues = [issue];
2863
+ if (daemonLogStatus.health === "degraded") {
2864
+ issues.push({
2865
+ code: "daemon_log_degraded",
2866
+ severity: "warning",
2867
+ message: "Daemon file logging is degraded; inspect full status for details."
2868
+ });
2869
+ }
1643
2870
  const response = {
1644
2871
  v: 1,
1645
2872
  detail: detail.detail,
1646
2873
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1647
2874
  status: runtimeFailed ? "error" : "warning",
1648
- issues: [issue],
2875
+ issues,
1649
2876
  daemon: {
1650
2877
  pid: process.pid,
1651
2878
  uptimeMs: Math.round(process.uptime() * 1e3),
@@ -1657,7 +2884,15 @@ function createBootstrapServeApp(input) {
1657
2884
  },
1658
2885
  ...qwenCodeVersion ? { qwenCodeVersion } : {},
1659
2886
  ...daemonLog.getDaemonId() ? { daemonId: daemonLog.getDaemonId() } : {},
1660
- ...detail.detail === "full" && daemonLog.getLogPath() ? { logPath: daemonLog.getLogPath() } : {}
2887
+ runId: daemonLogStatus.runId,
2888
+ logMode: daemonLogStatus.mode,
2889
+ logHealth: daemonLogStatus.health,
2890
+ ...detail.detail === "full" && daemonLog.getLogPath() ? { logPath: daemonLog.getLogPath() } : {},
2891
+ ...detail.detail === "full" ? {
2892
+ logIssues: daemonLogStatus.issues,
2893
+ logDroppedRecords: daemonLogStatus.droppedRecords,
2894
+ logDroppedBytes: daemonLogStatus.droppedBytes
2895
+ } : {}
1661
2896
  },
1662
2897
  security: {
1663
2898
  tokenConfigured: Boolean(opts.token),
@@ -1761,7 +2996,7 @@ function createDelegatingServeApp(bootstrapApp, getRuntimeApp, options = {}) {
1761
2996
  const dispatch = /* @__PURE__ */ __name(async () => {
1762
2997
  let target = getRuntimeApp();
1763
2998
  if (!target && options.waitForDeferredRuntimeRoutes === true && !isBootstrapServeRoute(req) && !isCorsPreflightRequest(req) && options.startRuntime && options.runtimeReady) {
1764
- const waitStartedAt = performance.now();
2999
+ const waitStartedAt = performance2.now();
1765
3000
  const timing = {
1766
3001
  startedAt: /* @__PURE__ */ new Date(),
1767
3002
  path: "joined"
@@ -1781,7 +3016,7 @@ function createDelegatingServeApp(bootstrapApp, getRuntimeApp, options = {}) {
1781
3016
  await options.runtimeReady;
1782
3017
  } catch {
1783
3018
  } finally {
1784
- timing.waitMs = Math.round((performance.now() - waitStartedAt) * 100) / 100;
3019
+ timing.waitMs = Math.round((performance2.now() - waitStartedAt) * 100) / 100;
1785
3020
  }
1786
3021
  target = getRuntimeApp();
1787
3022
  }
@@ -1894,7 +3129,37 @@ function runSynchronousRequestGate(handler, req, res, next) {
1894
3129
  }
1895
3130
  __name(runSynchronousRequestGate, "runSynchronousRequestGate");
1896
3131
  async function runQwenServe(optsIn, deps = {}) {
1897
- const runStartedAt = performance.now();
3132
+ let daemonLog;
3133
+ let owner = "startup";
3134
+ try {
3135
+ return await runQwenServeImpl(optsIn, deps, {
3136
+ initialized: /* @__PURE__ */ __name((logger) => {
3137
+ daemonLog = logger;
3138
+ }, "initialized"),
3139
+ published: /* @__PURE__ */ __name(() => {
3140
+ if (owner === "startup") owner = "handle";
3141
+ }, "published"),
3142
+ signalOwned: /* @__PURE__ */ __name(() => {
3143
+ if (owner === "startup") owner = "signal";
3144
+ }, "signalOwned")
3145
+ });
3146
+ } catch (error) {
3147
+ if (daemonLog && owner === "startup") {
3148
+ const startupLog = daemonLog;
3149
+ writeDaemonLifecycleBestEffort(
3150
+ () => startupLog.error(
3151
+ "daemon startup failed",
3152
+ error instanceof Error ? error : new Error(String(error))
3153
+ )
3154
+ );
3155
+ await startupLog.close();
3156
+ }
3157
+ throw error;
3158
+ }
3159
+ }
3160
+ __name(runQwenServe, "runQwenServe");
3161
+ async function runQwenServeImpl(optsIn, deps, loggerLifecycle) {
3162
+ const runStartedAt = performance2.now();
1898
3163
  const shouldPreheat = !deps.bridge && shouldPreheatBridge(deps);
1899
3164
  const startup = {
1900
3165
  processStartedAt: new Date(
@@ -2160,7 +3425,7 @@ async function runQwenServe(optsIn, deps = {}) {
2160
3425
  }
2161
3426
  let workspaceRegistrationStore = deps.workspaceRegistrationStore;
2162
3427
  if (workspaceRegistrationStore === void 0 && process.env["QWEN_SERVE_NO_PERSISTENT_REGISTRATION"] !== "1") {
2163
- const { WorkspaceRegistrationStore } = await import("./workspace-registration-store-5WPCMX4F.js");
3428
+ const { WorkspaceRegistrationStore } = await import("./workspace-registration-store-4I4KL7TN.js");
2164
3429
  workspaceRegistrationStore = new WorkspaceRegistrationStore(boundWorkspace);
2165
3430
  }
2166
3431
  if (workspaceRegistrationStore) {
@@ -2251,10 +3516,13 @@ async function runQwenServe(optsIn, deps = {}) {
2251
3516
  bootSettings,
2252
3517
  boundWorkspace
2253
3518
  });
2254
- const daemonLog = initDaemonLogger({
3519
+ const daemonLog = await initDaemonLogger({
2255
3520
  boundWorkspace,
2256
3521
  baseDir: daemonLogBaseDir
2257
3522
  });
3523
+ loggerLifecycle.initialized(daemonLog);
3524
+ let loggerPublished = false;
3525
+ let loggerSignalOwned = false;
2258
3526
  writeStderrLine(
2259
3527
  `qwen serve: daemon log \u2192 ${daemonLog.getLogPath() || "(disabled)"}`
2260
3528
  );
@@ -3008,7 +4276,7 @@ async function runQwenServe(optsIn, deps = {}) {
3008
4276
  );
3009
4277
  }
3010
4278
  }), "persistSettingsFn");
3011
- const { createSubSessionLauncher } = await import("./create-sub-session-OT7WXLDO.js");
4279
+ const { createSubSessionLauncher } = await import("./create-sub-session-BVL2ZHTM.js");
3012
4280
  const subSessionLauncher = createSubSessionLauncher({
3013
4281
  getBridge: /* @__PURE__ */ __name(() => bridgeRef, "getBridge"),
3014
4282
  boundWorkspace
@@ -4004,7 +5272,7 @@ async function runQwenServe(optsIn, deps = {}) {
4004
5272
  startup.listenerReadyAt = (/* @__PURE__ */ new Date()).toISOString();
4005
5273
  startup.processToListenMs = Math.round(process.uptime() * 1e3);
4006
5274
  startup.runQwenServeToListenMs = Math.round(
4007
- performance.now() - runStartedAt
5275
+ performance2.now() - runStartedAt
4008
5276
  );
4009
5277
  profileCheckpoint("serve_listener_ready");
4010
5278
  finalizeStartupProfile(`serve-${process.pid}`);
@@ -4340,17 +5608,17 @@ async function runQwenServe(optsIn, deps = {}) {
4340
5608
  }, "completeRuntimeStartup");
4341
5609
  const startBridgePreheat = /* @__PURE__ */ __name((bridge) => {
4342
5610
  startup.preheat.status = "running";
4343
- const preheatStartedAt = performance.now();
5611
+ const preheatStartedAt = performance2.now();
4344
5612
  bridge.preheat().then(() => {
4345
5613
  startup.preheat.status = "succeeded";
4346
5614
  startup.preheat.durationMs = Math.round(
4347
- performance.now() - preheatStartedAt
5615
+ performance2.now() - preheatStartedAt
4348
5616
  );
4349
5617
  }).catch((err) => {
4350
5618
  const message = err instanceof Error ? err.message : String(err);
4351
5619
  startup.preheat.status = "failed";
4352
5620
  startup.preheat.durationMs = Math.round(
4353
- performance.now() - preheatStartedAt
5621
+ performance2.now() - preheatStartedAt
4354
5622
  );
4355
5623
  startup.preheat.error = message;
4356
5624
  writeStderrLine(
@@ -4430,28 +5698,33 @@ async function runQwenServe(optsIn, deps = {}) {
4430
5698
  err instanceof Error ? err : null
4431
5699
  );
4432
5700
  }
4433
- await daemonLog.flush().catch(() => {
4434
- });
5701
+ await flushDaemonLogBounded(
5702
+ daemonLog,
5703
+ DAEMON_LOG_FORCED_FLUSH_BUDGET_MS
5704
+ );
4435
5705
  process.exit(1);
4436
5706
  return;
4437
5707
  }
5708
+ if (!loggerPublished) {
5709
+ loggerSignalOwned = true;
5710
+ loggerLifecycle.signalOwned();
5711
+ }
4438
5712
  daemonLog.warn(`received ${signal}, draining`);
4439
5713
  try {
4440
5714
  await handle.close();
4441
- await daemonLog.flush();
4442
5715
  process.exit(runtimeStartupError === void 0 ? 0 : 1);
4443
5716
  } catch (err) {
4444
5717
  daemonLog.error("shutdown error", err instanceof Error ? err : null);
4445
- await daemonLog.flush().catch(() => {
4446
- });
4447
5718
  if (channelWorkerManager?.state().enabled) {
4448
5719
  daemonLog.error(
4449
5720
  "refusing to exit while a channel worker or service lease remains; signal again to retry after the child exits (another signal during that retry forces exit)"
4450
5721
  );
4451
- await daemonLog.flush().catch(() => {
4452
- });
4453
5722
  return;
4454
5723
  }
5724
+ await flushDaemonLogBounded(
5725
+ daemonLog,
5726
+ DAEMON_LOG_FORCED_FLUSH_BUDGET_MS
5727
+ );
4455
5728
  process.exit(1);
4456
5729
  }
4457
5730
  }, "onSignal");
@@ -4484,6 +5757,8 @@ async function runQwenServe(optsIn, deps = {}) {
4484
5757
  const finish = /* @__PURE__ */ __name((err) => {
4485
5758
  if (settled) return;
4486
5759
  settled = true;
5760
+ const accessLogController = (runtimeApp ?? runtimeAppForCleanup)?.locals?.[ACCESS_LOG_CONTROLLER_LOCAL];
5761
+ accessLogController?.sealAndFlushSuppressed();
4487
5762
  const preserveSignalHandlers = channelWorkerShutdownError !== void 0 && channelWorkerManager?.state().enabled === true;
4488
5763
  if (!preserveSignalHandlers) {
4489
5764
  process.removeListener("SIGINT", onSignal);
@@ -4497,19 +5772,28 @@ async function runQwenServe(optsIn, deps = {}) {
4497
5772
  writeStderrLine(
4498
5773
  `qwen serve: telemetry shutdown error: ${telemetryErr instanceof Error ? telemetryErr.message : String(telemetryErr)}`
4499
5774
  );
4500
- }).finally(() => daemonLog.flush().catch(() => {
4501
- })).finally(() => {
5775
+ }).finally(async () => {
4502
5776
  const finalErr = err ?? bridgeShutdownError ?? channelWorkerShutdownError;
4503
- if (finalErr) {
4504
- if (channelWorkerShutdownError && channelWorkerManager?.state().enabled) {
4505
- closePromise = void 0;
4506
- shuttingDown = false;
4507
- channelControlDraining = false;
4508
- }
5777
+ const retryableChannelClose = channelWorkerShutdownError !== void 0 && channelWorkerManager?.state().enabled === true;
5778
+ if (retryableChannelClose) {
5779
+ await flushDaemonLogBounded(
5780
+ daemonLog,
5781
+ DAEMON_LOG_FORCED_FLUSH_BUDGET_MS
5782
+ );
5783
+ closePromise = void 0;
5784
+ shuttingDown = false;
5785
+ channelControlDraining = false;
4509
5786
  rej(finalErr);
4510
- } else {
4511
- res();
5787
+ return;
5788
+ }
5789
+ if (loggerPublished || loggerSignalOwned) {
5790
+ writeDaemonLifecycleBestEffort(
5791
+ () => daemonLog.info("daemon stopped")
5792
+ );
5793
+ await daemonLog.close();
4512
5794
  }
5795
+ if (finalErr) rej(finalErr);
5796
+ else res();
4513
5797
  });
4514
5798
  }, "finish");
4515
5799
  void (coreRuntimePromise ? coreRuntimePromise.then((core) => core.forceFlushMetrics()) : Promise.resolve()).catch((flushErr) => {
@@ -4638,23 +5922,33 @@ async function runQwenServe(optsIn, deps = {}) {
4638
5922
  startRuntime();
4639
5923
  }
4640
5924
  if (deps.resolveOnListen) {
5925
+ loggerPublished = true;
5926
+ loggerLifecycle.published();
4641
5927
  resolve(handle);
4642
5928
  } else {
4643
5929
  void runtimeReady.then(
4644
- () => resolve(handle),
5930
+ () => {
5931
+ loggerPublished = true;
5932
+ loggerLifecycle.published();
5933
+ resolve(handle);
5934
+ },
4645
5935
  (err) => {
4646
5936
  void handle.close().then(
4647
5937
  () => {
4648
5938
  reject(err instanceof Error ? err : new Error(String(err)));
4649
5939
  },
4650
5940
  (closeErr) => {
4651
- daemonLog.error(
4652
- "shutdown after runtime startup error failed",
4653
- closeErr instanceof Error ? closeErr : null
5941
+ writeDaemonLifecycleBestEffort(
5942
+ () => daemonLog.error(
5943
+ "shutdown after runtime startup error failed",
5944
+ closeErr instanceof Error ? closeErr : null
5945
+ )
4654
5946
  );
4655
5947
  if (channelWorkerManager?.state().enabled) {
4656
- daemonLog.error(
4657
- "runtime startup failed, but qwen serve remains alive to retain the channel service lease until worker exit is confirmed"
5948
+ writeDaemonLifecycleBestEffort(
5949
+ () => daemonLog.error(
5950
+ "runtime startup failed, but qwen serve remains alive to retain the channel service lease until worker exit is confirmed"
5951
+ )
4658
5952
  );
4659
5953
  return;
4660
5954
  }
@@ -4714,7 +6008,7 @@ async function runQwenServe(optsIn, deps = {}) {
4714
6008
  tryListen(opts.port, 0);
4715
6009
  });
4716
6010
  }
4717
- __name(runQwenServe, "runQwenServe");
6011
+ __name(runQwenServeImpl, "runQwenServeImpl");
4718
6012
  export {
4719
6013
  InvalidPolicyConfigError,
4720
6014
  createDisabledChannelWorkerSupervisor,