@qwen-code/qwen-code 0.21.1 → 0.21.2-nightly.20260801.bc382c3ff

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 (367) hide show
  1. package/bundled/qc-helper/docs/configuration/settings.md +9 -7
  2. package/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
  3. package/bundled/qc-helper/docs/features/channels/github.md +49 -10
  4. package/bundled/qc-helper/docs/features/channels/gitlab.md +177 -0
  5. package/bundled/qc-helper/docs/features/code-review.md +20 -0
  6. package/bundled/qc-helper/docs/features/commands.md +1 -0
  7. package/bundled/qc-helper/docs/features/hooks.md +135 -18
  8. package/bundled/qc-helper/docs/features/memory.md +27 -0
  9. package/bundled/qc-helper/docs/features/skills.md +14 -0
  10. package/bundled/qc-helper/docs/features/sub-agents.md +55 -8
  11. package/bundled/qc-helper/docs/features/tool-use-summaries.md +7 -7
  12. package/bundled/qc-helper/docs/qwen-serve.md +28 -6
  13. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +2 -2
  14. package/bundled/review/SKILL.md +1 -1
  15. package/chunks/{MaxSizedBox-VI3ROJJA.js → MaxSizedBox-CDHTDITS.js} +45 -40
  16. package/chunks/{StandaloneSessionPicker-LYXKD2EV.js → StandaloneSessionPicker-L63HUAHP.js} +65 -60
  17. package/chunks/{acp-startup-profiler-DFVPFQ6C.js → acp-startup-profiler-3RICG2YW.js} +2 -2
  18. package/chunks/{acpAgent-WN5SRDQO.js → acpAgent-6WVVT2P3.js} +962 -599
  19. package/chunks/{agent-K6ECSM64.js → agent-KDM4CBOU.js} +40 -35
  20. package/chunks/agent-headless-AS7K2K57.js +79 -0
  21. package/chunks/{anthropicContentGenerator-V2QOGVYD.js → anthropicContentGenerator-WCBYB6JG.js} +337 -27
  22. package/chunks/{artifact-tool-6K6U7XYJ.js → artifact-tool-ANV4CFCR.js} +2 -2
  23. package/chunks/{askUserQuestion-GD2IJJ7I.js → askUserQuestion-MALEB47H.js} +2 -2
  24. package/chunks/{bridge-3KJEWDNE.js → bridge-JNEW6FES.js} +46 -41
  25. package/chunks/{build-S6DO7LMM.js → build-GDBLPA24.js} +1 -1
  26. package/chunks/{ca-6W3SK7OQ.js → ca-4OJN75WT.js} +46 -5
  27. package/chunks/{channel-management-service-XR7GZSWF.js → channel-management-service-QOO7TD3T.js} +21 -6
  28. package/chunks/{channel-settings-store-HW4FXXUA.js → channel-settings-store-4CSMTR4L.js} +47 -42
  29. package/chunks/{channel-worker-group-XDPTDWTX.js → channel-worker-group-ERSUOPIR.js} +8 -8
  30. package/chunks/{channel-worker-manager-YYEHVRRE.js → channel-worker-manager-X247YDQ7.js} +8 -8
  31. package/chunks/{channel-worker-supervisor-74HTWA2G.js → channel-worker-supervisor-ORJIEEPP.js} +4 -4
  32. package/chunks/{chunk-VWOOBLTY.js → chunk-25QQVOCG.js} +5 -5
  33. package/chunks/{chunk-CAPPWD3X.js → chunk-2A6MHYIA.js} +3 -3
  34. package/chunks/{chunk-2XSLTRFZ.js → chunk-2CTKGIFR.js} +2 -2
  35. package/chunks/{chunk-DZLYR4U3.js → chunk-2DNKEBXY.js} +1 -1
  36. package/chunks/{chunk-UWMLWVCA.js → chunk-2IIJTXYF.js} +26 -10
  37. package/chunks/{chunk-JYBU6YUE.js → chunk-2M5N3DHY.js} +1 -1
  38. package/chunks/{chunk-AQIDMUGU.js → chunk-2PNQQ4UR.js} +2 -2
  39. package/chunks/{chunk-OKF7JF3R.js → chunk-2UISUFHQ.js} +3 -3
  40. package/chunks/{chunk-2LQTH543.js → chunk-33FNCQSY.js} +2 -2
  41. package/chunks/{chunk-M7OONWYU.js → chunk-3LGZEYOF.js} +4 -2
  42. package/chunks/{chunk-ZURDMIDR.js → chunk-3MHPWQ2M.js} +242 -76
  43. package/chunks/{chunk-UHUSJ6X7.js → chunk-3RXUYQJI.js} +25 -6
  44. package/chunks/{chunk-E5Z2AVNV.js → chunk-3SH53ANB.js} +0 -11
  45. package/chunks/{chunk-BNWB5CYE.js → chunk-3WXMXT7C.js} +22 -11
  46. package/chunks/{chunk-A2D5BAVP.js → chunk-42IKVPST.js} +1 -1
  47. package/chunks/{chunk-2DN4J57Y.js → chunk-432XCUHF.js} +1 -1
  48. package/chunks/{chunk-EVKE2FZL.js → chunk-433VD3HX.js} +4 -4
  49. package/chunks/{chunk-Q43KPN7X.js → chunk-434YCHSV.js} +6 -6
  50. package/chunks/{chunk-5TBMQLGG.js → chunk-4LKVQFHM.js} +2 -2
  51. package/chunks/{chunk-YDLJGZHL.js → chunk-4NFY2S7N.js} +0 -33
  52. package/chunks/{chunk-6PE7N3A4.js → chunk-5UJ6A3CH.js} +145 -10
  53. package/chunks/{chunk-GNR2RNMP.js → chunk-5UZITEHA.js} +3 -3
  54. package/chunks/chunk-6FMJLI5M.js +1591 -0
  55. package/chunks/{chunk-RPLGZJV2.js → chunk-6O5DVH27.js} +1 -1
  56. package/chunks/{chunk-2RFKHEXL.js → chunk-6PLDPT2C.js} +1 -1
  57. package/chunks/{chunk-7AEJDLRA.js → chunk-7IYLHTTM.js} +3 -3
  58. package/chunks/{chunk-65PQENQP.js → chunk-7K2WTPQO.js} +5 -5
  59. package/chunks/{chunk-P4WOAOJW.js → chunk-7MY2AR5A.js} +72 -26
  60. package/chunks/{chunk-GXIJHV66.js → chunk-A2A34TSB.js} +3 -3
  61. package/chunks/{chunk-XWWKIXVD.js → chunk-A5YZ3FA2.js} +2 -1
  62. package/chunks/{chunk-64LQLPL7.js → chunk-A6SX5TAH.js} +3 -3
  63. package/chunks/{chunk-SZ3KHTDR.js → chunk-AKA24BGO.js} +1 -1
  64. package/chunks/chunk-AQ37AY7B.js +93 -0
  65. package/chunks/{chunk-2N7CODY5.js → chunk-AQEWCKX4.js} +2 -2
  66. package/chunks/{chunk-KCO4FLFJ.js → chunk-AYB4HSBI.js} +3 -3
  67. package/chunks/{chunk-WZRWHXFE.js → chunk-BFHXDAR7.js} +1 -1
  68. package/chunks/{chunk-L55JWS76.js → chunk-BGXZBI5B.js} +1 -1
  69. package/chunks/{chunk-5MKRTI4T.js → chunk-BKUN5QHP.js} +7 -7
  70. package/chunks/{chunk-Y4IHBGBP.js → chunk-BV4QX43X.js} +1 -1
  71. package/chunks/{chunk-PB3MBFKG.js → chunk-C4L2MEIT.js} +4 -4
  72. package/chunks/{chunk-TCIFAA7K.js → chunk-CHCLO3M7.js} +14 -14
  73. package/chunks/{chunk-CVHIL5IG.js → chunk-CWEIMFFW.js} +13 -6
  74. package/chunks/{chunk-2FAK6PNM.js → chunk-DUIJ2IXG.js} +5 -13
  75. package/chunks/{chunk-T2QMKU3R.js → chunk-DVGTU5TC.js} +19 -7
  76. package/chunks/{chunk-LGAOC3ZS.js → chunk-DYA25Y7U.js} +1 -1
  77. package/chunks/{chunk-SGFT55XI.js → chunk-E4WHKETF.js} +32 -4
  78. package/chunks/{chunk-WBL3FJEU.js → chunk-FC4KQFCS.js} +1 -1
  79. package/chunks/{chunk-MHAIJPTD.js → chunk-FJHA23GM.js} +12 -12
  80. package/chunks/{chunk-S7W2GKIO.js → chunk-G7XXKQYS.js} +2 -0
  81. package/chunks/{chunk-MR5EAQ5M.js → chunk-GALUTA2C.js} +1 -1
  82. package/chunks/{chunk-7I5GTCT4.js → chunk-GB3AB7TR.js} +4008 -3648
  83. package/chunks/{chunk-QIZKCVM3.js → chunk-GHJM2C2T.js} +6 -8
  84. package/chunks/chunk-GOFAQQZA.js +132 -0
  85. package/chunks/{chunk-BCZFQXWK.js → chunk-GTM6IHBB.js} +2 -2
  86. package/chunks/{chunk-5ZF5XXTS.js → chunk-GVISB2OH.js} +2 -2
  87. package/chunks/{chunk-FNMZK765.js → chunk-H36SETQS.js} +1 -1
  88. package/chunks/{chunk-UBEPNVDI.js → chunk-H4346YW5.js} +28 -16
  89. package/chunks/{chunk-CQL64ESB.js → chunk-H4DSRWAS.js} +24 -13
  90. package/chunks/{chunk-YGF33UXG.js → chunk-H6MC6VQX.js} +222 -173
  91. package/chunks/{chunk-GZXCZHCT.js → chunk-I3G5JWBV.js} +1 -1
  92. package/chunks/{chunk-Y6AXW2OG.js → chunk-I5GNT6ZS.js} +7 -1
  93. package/chunks/{chunk-GEBV2JGB.js → chunk-I6FAHB4N.js} +1 -1
  94. package/chunks/{chunk-UPUG4GXM.js → chunk-I7JDGNG6.js} +3 -3
  95. package/chunks/{chunk-JHNRZMHI.js → chunk-II6WPWHY.js} +9 -9
  96. package/chunks/{chunk-B4AJNNOL.js → chunk-J26HHFI5.js} +1 -1
  97. package/chunks/{chunk-S3TWXGKA.js → chunk-JE7KQ2UP.js} +4 -2
  98. package/chunks/{chunk-ZHBO7WVX.js → chunk-JELIWHXD.js} +1 -1
  99. package/chunks/{chunk-3EFXSQCM.js → chunk-JRIDA5HF.js} +7 -7
  100. package/chunks/{chunk-TFRMVU6R.js → chunk-K4CGQN4Q.js} +1 -1
  101. package/chunks/{chunk-WUZ7H6DP.js → chunk-K5Q62CGR.js} +1 -1
  102. package/chunks/{chunk-JCW2R7WC.js → chunk-K623ENWT.js} +3 -79
  103. package/chunks/{chunk-T2NCM2ET.js → chunk-K6KS3LTN.js} +2 -749
  104. package/chunks/{chunk-TDL6LB4K.js → chunk-KG22G46Y.js} +22 -10
  105. package/chunks/{chunk-GATT5TKW.js → chunk-KKN2IE7Q.js} +1 -1
  106. package/chunks/{chunk-JMONIXMJ.js → chunk-KVUBYJDM.js} +2 -2
  107. package/chunks/{chunk-TBBV36Y4.js → chunk-KXSYDCP2.js} +4 -4
  108. package/chunks/{chunk-EIF3FXTB.js → chunk-LAPK3GLC.js} +121 -18
  109. package/chunks/chunk-LBOVL47Y.js +29 -0
  110. package/chunks/{chunk-U3E3UQAA.js → chunk-LBWNSLJK.js} +4 -4
  111. package/chunks/{chunk-S4WJVPZW.js → chunk-LL4U3BSH.js} +15 -7
  112. package/chunks/{chunk-657BH7VM.js → chunk-LRJWFR6L.js} +4 -4
  113. package/chunks/{chunk-PT722TDT.js → chunk-M2F5PLOW.js} +770 -125
  114. package/chunks/{chunk-3L2SPEBH.js → chunk-M744OFVE.js} +1 -1
  115. package/chunks/{chunk-VYOXCEPJ.js → chunk-MBKPUM5Y.js} +1 -1
  116. package/chunks/chunk-MISUEWB4.js +8749 -0
  117. package/chunks/{chunk-PONHVBRT.js → chunk-MOHAWIAW.js} +2 -2
  118. package/chunks/{chunk-HMRM2A3U.js → chunk-MSIVKDRC.js} +4 -4
  119. package/chunks/{record-artifact-XAMSFSW4.js → chunk-MYT7N6QH.js} +22 -7
  120. package/chunks/{chunk-X5WNMMIA.js → chunk-NGWYUZZO.js} +11510 -15137
  121. package/chunks/{chunk-PQNHRFJC.js → chunk-NYX53SV4.js} +0 -2
  122. package/chunks/{chunk-6RPMI2AB.js → chunk-NZB4NDJL.js} +10 -10
  123. package/chunks/{chunk-BGTQCTQW.js → chunk-O2ZYHG33.js} +6 -5
  124. package/chunks/chunk-O6GEWCJA.js +21 -0
  125. package/chunks/{chunk-JX27F6QS.js → chunk-OBAIHYFT.js} +1 -1
  126. package/chunks/{chunk-BPZKP57P.js → chunk-OCRM53TT.js} +3 -3
  127. package/chunks/{chunk-V7RNNPGC.js → chunk-P5Y23G2L.js} +18 -1
  128. package/chunks/{chunk-FTD6DP4T.js → chunk-PDDYAXL2.js} +5 -1
  129. package/chunks/{chunk-JSD33JG6.js → chunk-PGEGUNH5.js} +67 -10
  130. package/chunks/{chunk-A4COXFB3.js → chunk-PGP7Y3RQ.js} +5 -5
  131. package/chunks/{chunk-T3O2B4XO.js → chunk-PHODQP2V.js} +6 -6
  132. package/chunks/{chunk-BMFALVGQ.js → chunk-PXA5AWHY.js} +1 -1
  133. package/chunks/chunk-QL4TN4HS.js +59 -0
  134. package/chunks/{chunk-W4MIWP6M.js → chunk-QMBEW7EW.js} +2 -2
  135. package/chunks/{chunk-U4VTUMMK.js → chunk-QONSRAEV.js} +1 -1
  136. package/chunks/{chunk-LW3RFMG7.js → chunk-QYPT3QUD.js} +3 -3
  137. package/chunks/{chunk-TV64SXKD.js → chunk-RGJ4JWSU.js} +131 -48
  138. package/chunks/{chunk-75MIQ3LV.js → chunk-RPYYTL7E.js} +61 -13
  139. package/chunks/{chunk-52ZSWYEG.js → chunk-SK2UKB45.js} +1 -1
  140. package/chunks/{chunk-PLDQBIO6.js → chunk-SWEBEXPI.js} +1 -1
  141. package/chunks/chunk-T3CHYWJZ.js +758 -0
  142. package/chunks/{chunk-VCPIZRYH.js → chunk-TFFMATHX.js} +9 -7
  143. package/chunks/{chunk-J7OACQDE.js → chunk-TNVKFQXQ.js} +458 -97
  144. package/chunks/{chunk-A3NDJ5SB.js → chunk-TYERNYH4.js} +2 -2
  145. package/chunks/{chunk-GKX7E4CO.js → chunk-U25CMJYY.js} +1 -1
  146. package/chunks/{chunk-7XATOOE7.js → chunk-UH7Z7Y45.js} +1 -1
  147. package/chunks/{chunk-XFZYFU3I.js → chunk-UHQ3L6GC.js} +1 -1
  148. package/chunks/{chunk-GZ3RCT54.js → chunk-UHTJC7O3.js} +1 -1
  149. package/chunks/{chunk-XZC5VLBZ.js → chunk-UKZEXS6K.js} +6 -0
  150. package/chunks/{chunk-LO4ROVP4.js → chunk-UOFFZNXV.js} +111 -13
  151. package/chunks/{chunk-5YKDXHUY.js → chunk-URN76TKR.js} +2 -2
  152. package/chunks/{chunk-T4TXDL7G.js → chunk-UWLG4UCE.js} +132 -35
  153. package/chunks/{chunk-KAMYKP7E.js → chunk-UWSXFI6E.js} +1 -1
  154. package/chunks/{chunk-7BAU433D.js → chunk-VS3GXRNZ.js} +1198 -240
  155. package/chunks/{chunk-EJGJIBRS.js → chunk-VWF42XC6.js} +3 -3
  156. package/chunks/{chunk-RCUQIPTN.js → chunk-W7XZ3KP5.js} +1 -1
  157. package/chunks/{chunk-OCESJA77.js → chunk-WISQLM4Q.js} +1197 -1154
  158. package/chunks/{chunk-NOKIVHOL.js → chunk-WK4TJUEA.js} +1 -1
  159. package/chunks/{chunk-JFMA7Y5M.js → chunk-WP4HGHFG.js} +5 -5
  160. package/chunks/{chunk-4G2BISNC.js → chunk-XC2VAFVZ.js} +1 -1
  161. package/chunks/{chunk-2LKVPASC.js → chunk-XC656O42.js} +3 -3
  162. package/chunks/{chunk-5KTQXHPY.js → chunk-XCLLRKY5.js} +3 -3
  163. package/chunks/{chunk-HV26XH34.js → chunk-XFDPIC4P.js} +3 -3
  164. package/chunks/{chunk-JTV5K7NH.js → chunk-XSA5EKTJ.js} +1 -1
  165. package/chunks/{chunk-75GFAX4R.js → chunk-YAVY33G4.js} +1 -1
  166. package/chunks/{chunk-WBSMNTSV.js → chunk-YXEVDA66.js} +2 -2
  167. package/chunks/{chunk-7DXQIJID.js → chunk-ZRFJ75D7.js} +3 -3
  168. package/chunks/{chunk-XBYYDKAZ.js → chunk-ZTN6OA5J.js} +8 -7
  169. package/chunks/{computer-use-ZTIDHMMA.js → computer-use-Z4NCIIJN.js} +40 -35
  170. package/chunks/{config-utils-NYSXDMEQ.js → config-utils-64LM6OEQ.js} +4 -4
  171. package/chunks/{contextCommand-2PIEU37Z.js → contextCommand-HVM7XFCB.js} +43 -38
  172. package/chunks/{core-runtime-3XEYLQFK.js → core-runtime-NL3ZBHBU.js} +40 -35
  173. package/chunks/{create-sub-session-SBYUMSSS.js → create-sub-session-AM32K2HD.js} +2 -2
  174. package/chunks/{create-sub-session-R76FVXCI.js → create-sub-session-XHSCDYFU.js} +43 -38
  175. package/chunks/{cron-create-2QK6TCEC.js → cron-create-HPXYE6C5.js} +4 -4
  176. package/chunks/{cron-delete-FDCDFYMG.js → cron-delete-FPVNTKPK.js} +4 -4
  177. package/chunks/{cron-list-XN3WVBTP.js → cron-list-ZEI6PAAV.js} +4 -4
  178. package/chunks/{daemon-Q2AB5Z23.js → daemon-PCNCI5YU.js} +72 -3
  179. package/chunks/daemon-status-provider-XD23SNAM.js +94 -0
  180. package/chunks/{daemon-trust-policy-ILUDTLHD.js → daemon-trust-policy-NOHK7IW5.js} +46 -41
  181. package/chunks/{daemon-trust-policy-monitor-HS3PKKRO.js → daemon-trust-policy-monitor-ZBTSR333.js} +46 -41
  182. package/chunks/{de-SY6O76BF.js → de-A6TI4LBB.js} +46 -5
  183. package/chunks/{deferred-core-runtime-X4QV662U.js → deferred-core-runtime-JJBHKM2C.js} +40 -35
  184. package/chunks/{dist-HVRQ2CFL.js → dist-4LAMY2SK.js} +1180 -5
  185. package/chunks/{dist-DOLYHMXE.js → dist-4T4NCJFL.js} +2 -2
  186. package/chunks/dist-7KOL6OMD.js +13467 -0
  187. package/chunks/{dist-SSU66DM4.js → dist-BH76AT7N.js} +1 -1
  188. package/chunks/{dist-BSTVRPMT.js → dist-BXA3JXVQ.js} +541 -19
  189. package/chunks/{dist-SV7Q3AWJ.js → dist-OEEFI6UU.js} +12 -9
  190. package/chunks/{dist-YGBBMK3Z.js → dist-SMLVOWKV.js} +5 -4
  191. package/chunks/{dist-IXQEQWRG.js → dist-V2RK6S6Q.js} +1 -1
  192. package/chunks/{earlyInputCapture-XKLZT7ZD.js → earlyInputCapture-KLAZDAIP.js} +41 -36
  193. package/chunks/{edit-HHGIOTQ2.js → edit-YQZWCISX.js} +40 -35
  194. package/chunks/{en-NBK3JKCE.js → en-RESOFG55.js} +46 -5
  195. package/chunks/{enter-worktree-ZN7PUQ46.js → enter-worktree-WLVWI3FP.js} +40 -35
  196. package/chunks/{enterPlanMode-EIFIDSIV.js → enterPlanMode-6RYXFQUD.js} +40 -35
  197. package/chunks/{environment-XXQ75D2Q.js → environment-DXJTXSVT.js} +43 -38
  198. package/chunks/{errors-4GMVU7CK.js → errors-XGAGG2S2.js} +43 -38
  199. package/chunks/{exit-worktree-GXMI4ATY.js → exit-worktree-C4276VPP.js} +40 -35
  200. package/chunks/{exitPlanMode-34UVY7M6.js → exitPlanMode-MM5HIRUF.js} +40 -35
  201. package/chunks/{fast-path-VPIVA7L6.js → fast-path-PIXYOHCH.js} +6 -2
  202. package/chunks/{fr-4KG5V7UT.js → fr-QF7RI5ZE.js} +46 -5
  203. package/chunks/{gemini-4BWIK4WD.js → gemini-43RLVUNP.js} +158 -96
  204. package/chunks/{geminiContentGenerator-3XVV5MSS.js → geminiContentGenerator-PNQ4TSID.js} +6 -6
  205. package/chunks/{glob-TZ2ABCJG.js → glob-ZMBQKAU5.js} +40 -35
  206. package/chunks/goal-tools-Y767F7LZ.js +335 -0
  207. package/chunks/{grep-BEF463NA.js → grep-HSV37W2Q.js} +40 -35
  208. package/chunks/handleAutoUpdate-QDHZPBAY.js +85 -0
  209. package/chunks/{i18n-FMM5FDXR.js → i18n-ME22A6RN.js} +42 -37
  210. package/chunks/{image-gen-HHVLF7HS.js → image-gen-IFC7ZWSB.js} +9 -9
  211. package/chunks/{initializer-625TIAIO.js → initializer-J7H2CHVB.js} +47 -42
  212. package/chunks/{installationInfo-6AM4I2Y3.js → installationInfo-R7FXPQN5.js} +41 -36
  213. package/chunks/{ja-F3GSQXMF.js → ja-URQESVGW.js} +46 -5
  214. package/chunks/{keychain-token-storage-72IYCAZV.js → keychain-token-storage-7BT4TQ2A.js} +2 -2
  215. package/chunks/{kittyProtocolDetector-MBRTDRBK.js → kittyProtocolDetector-BFLAKYXH.js} +1 -1
  216. package/chunks/list-OYDIBA4N.js +93 -0
  217. package/chunks/{list-agents-R6KDXQR3.js → list-agents-GATIBBQQ.js} +2 -2
  218. package/chunks/{loadedSettingsAdapter-SPUTNKAV.js → loadedSettingsAdapter-OK6GK2GE.js} +46 -41
  219. package/chunks/{loggingContentGenerator-LKOF7XI7.js → loggingContentGenerator-U4ZEG4GL.js} +53 -38
  220. package/chunks/{loop-wakeup-3IQKCYAH.js → loop-wakeup-3DZMQQQQ.js} +13 -6
  221. package/chunks/{ls-DKZ37A7N.js → ls-7F4GHXIH.js} +4 -4
  222. package/chunks/{lsp-QNWN7KN3.js → lsp-6FEHVBWI.js} +2 -2
  223. package/chunks/{managed-npm-update-ACQGGIN5.js → managed-npm-update-PGKAJLLO.js} +43 -38
  224. package/chunks/mcp-S4DXJD2G.js +87 -0
  225. package/chunks/{monitor-DF52UVHI.js → monitor-E5ZFMT74.js} +40 -35
  226. package/chunks/nonInteractiveCli-HNOHKEPE.js +149 -0
  227. package/chunks/{notebook-edit-FCWS4XVN.js → notebook-edit-6QDN6VZJ.js} +40 -35
  228. package/chunks/{openaiContentGenerator-7LDK3DCJ.js → openaiContentGenerator-3NLB2C5O.js} +19 -19
  229. package/chunks/{pidfile-6ERW3DF4.js → pidfile-ZMOIUGG6.js} +41 -36
  230. package/chunks/{processUtils-COKZAMUP.js → processUtils-E4QGQVWW.js} +2 -2
  231. package/chunks/{pt-EQ33KWEN.js → pt-EEEQXRUI.js} +46 -5
  232. package/chunks/{qwenContentGenerator-TKWUMR7N.js → qwenContentGenerator-2LFRWJTM.js} +46 -41
  233. package/chunks/{qwenOAuth2-7HMU47SF.js → qwenOAuth2-N32BUQDC.js} +8 -8
  234. package/chunks/{read-file-X6DRC574.js → read-file-GLDCWZBG.js} +11 -11
  235. package/chunks/{read-mcp-resource-GFTWYXMK.js → read-mcp-resource-AFS3UKZO.js} +2 -2
  236. package/chunks/record-artifact-ECZSCEG5.js +21 -0
  237. package/chunks/{resumeHistoryUtils-PFPM2GWM.js → resumeHistoryUtils-F5BE5QDW.js} +48 -43
  238. package/chunks/ripGrep-T23Y4AGY.js +77 -0
  239. package/chunks/{ru-7OZAUKGG.js → ru-WGZDYQAB.js} +46 -5
  240. package/chunks/{run-qwen-serve-TSTCO4XE.js → run-qwen-serve-TI2HGLLU.js} +290 -75
  241. package/chunks/{runtime-DAUPSUKI.js → runtime-WCWM3DO7.js} +53 -46
  242. package/chunks/{scheduler-KMADMT26.js → scheduler-2QZO5AV5.js} +40 -35
  243. package/chunks/{sdk-exporters-http-WO556XNU.js → sdk-exporters-http-IKNWQJNV.js} +3 -3
  244. package/chunks/{sdk-impl-LPAVACSF.js → sdk-impl-7CUUMQDB.js} +3 -3
  245. package/chunks/{send-message-SAWK4DZX.js → send-message-X7G2JSII.js} +6 -11
  246. package/chunks/{serve-NNRWS6F4.js → serve-DZOMYUFU.js} +46 -41
  247. package/chunks/{server-WEH7DVCH.js → server-N4AJRKIQ.js} +2269 -1016
  248. package/chunks/{session-WXC56V2I.js → session-GS6AKMN7.js} +151 -86
  249. package/chunks/{settings-DJDXFDZ3.js → settings-CUN3SELH.js} +50 -45
  250. package/chunks/{shell-JN5VRQXD.js → shell-NGBFVXC5.js} +40 -35
  251. package/chunks/{skill-SGXPKJCS.js → skill-SC2BSO75.js} +30 -16
  252. package/chunks/{skill-settings-VJ5PDMZI.js → skill-settings-XVPCPW5K.js} +45 -40
  253. package/chunks/{spawnChannel-ETMJW7YX.js → spawnChannel-RILO4YY3.js} +42 -37
  254. package/chunks/{standalone-update-MK3Z7KBI.js → standalone-update-TMLT6LVJ.js} +43 -38
  255. package/chunks/{startInteractiveUI-ZCGIXPGT.js → startInteractiveUI-J45WOEOU.js} +883 -1112
  256. package/chunks/{syntheticOutput-355CB6CJ.js → syntheticOutput-FHRY3BPQ.js} +3 -3
  257. package/chunks/{task-create-INGWNUG4.js → task-create-LAQXBIHC.js} +11 -10
  258. package/chunks/{task-list-5XNNGTF4.js → task-list-V6K5DRDH.js} +6 -6
  259. package/chunks/{task-stop-4ROAOBXH.js → task-stop-LQXE52L6.js} +2 -2
  260. package/chunks/{task-update-CRK5VWWZ.js → task-update-NXRCXSPB.js} +11 -10
  261. package/chunks/{team-create-QQGAJG7P.js → team-create-W3EVWCTA.js} +40 -35
  262. package/chunks/{team-delete-S2RCXA4P.js → team-delete-Z4KGO7RC.js} +6 -6
  263. package/chunks/{team-plan-approval-RT7Q5R6O.js → team-plan-approval-URYVKJF4.js} +40 -35
  264. package/chunks/theme-manager-CUAMS2NI.js +81 -0
  265. package/chunks/{todoWrite-7WM3VDMY.js → todoWrite-OFIZDI7P.js} +32 -4
  266. package/chunks/{tool-search-Z3Z4AYKP.js → tool-search-DCICFL32.js} +15 -14
  267. package/chunks/total-session-admission-3ZTAXVUK.js +89 -0
  268. package/chunks/{trustedFolders-X2JEIO57.js → trustedFolders-EVCN36O5.js} +42 -37
  269. package/chunks/{update-relaunch-VWNPYDIP.js → update-relaunch-XLW46RHQ.js} +5 -5
  270. package/chunks/{updateCheck-KAQH67DV.js → updateCheck-ZHVXDAIH.js} +44 -39
  271. package/chunks/{useAutoAcceptIndicator-JH6BCF7S.js → useAutoAcceptIndicator-ZGD6BJSP.js} +50 -45
  272. package/chunks/{validateNonInterActiveAuth-GIUJ2UFS.js → validateNonInterActiveAuth-R3BAQFDY.js} +88 -83
  273. package/chunks/{version-BGLYIJUY.js → version-PMWREGCG.js} +1 -1
  274. package/chunks/{web-fetch-OTDU4VQF.js → web-fetch-PGN27SGF.js} +14 -14
  275. package/chunks/{web-search-FP6SIHPR.js → web-search-KW4UNMRE.js} +8 -8
  276. package/chunks/{workflow-YCIVBYSB.js → workflow-SN3TJBTJ.js} +363 -310
  277. package/chunks/workspace-providers-status-O3HUZGGR.js +90 -0
  278. package/chunks/{workspace-registration-store-OTMS3H4C.js → workspace-registration-store-M3FJ74RS.js} +2 -2
  279. package/chunks/{workspace-registry-O63R6IZ4.js → workspace-registry-U7ISW23N.js} +47 -42
  280. package/chunks/{workspace-service-M6LLHKJ5.js → workspace-service-VH6IWADT.js} +53 -48
  281. package/chunks/{workspace-skills-status-C2V7BAIS.js → workspace-skills-status-XANARSZS.js} +48 -43
  282. package/chunks/{workspace-trust-reconciler-IBUPOUJN.js → workspace-trust-reconciler-35EFR4GC.js} +53 -48
  283. package/chunks/write-file-NCRSGUDT.js +79 -0
  284. package/chunks/{zh-H3YDK5QW.js → zh-OHX23Q44.js} +43 -5
  285. package/chunks/{zh-TW-JYCP7XUA.js → zh-TW-4G7YKDAQ.js} +43 -5
  286. package/chunks/zoom-image-X7CIADYC.js +224 -0
  287. package/cli.js +55 -48
  288. package/locales/ca.js +60 -4
  289. package/locales/de.js +62 -4
  290. package/locales/en.js +59 -4
  291. package/locales/fr.js +64 -4
  292. package/locales/ja.js +61 -4
  293. package/locales/pt.js +60 -4
  294. package/locales/ru.js +63 -4
  295. package/locales/zh-TW.js +52 -4
  296. package/locales/zh.js +52 -4
  297. package/package.json +3 -3
  298. package/web-shell/assets/{arc-75-Wdeo3.js → arc-CaMTqKio.js} +1 -1
  299. package/web-shell/assets/{architectureDiagram-3BPJPVTR-FKeXQbyP.js → architectureDiagram-3BPJPVTR-Bjxztij2.js} +1 -1
  300. package/web-shell/assets/{blockDiagram-GPEHLZMM-CY0vc-A3.js → blockDiagram-GPEHLZMM-BYJzeHi9.js} +1 -1
  301. package/web-shell/assets/{c4Diagram-AAUBKEIU-CNP-A-8u.js → c4Diagram-AAUBKEIU-fYAa-Eil.js} +1 -1
  302. package/web-shell/assets/channel-LEZei0-5.js +1 -0
  303. package/web-shell/assets/{chunk-2J33WTMH-GybS4Gii.js → chunk-2J33WTMH-B1OTlTml.js} +1 -1
  304. package/web-shell/assets/{chunk-4BX2VUAB-02H91V8v.js → chunk-4BX2VUAB-DNj4uy6k.js} +1 -1
  305. package/web-shell/assets/{chunk-55IACEB6-D3M-2VT6.js → chunk-55IACEB6-DAqNmg3c.js} +1 -1
  306. package/web-shell/assets/{chunk-727SXJPM-CCu29u4H.js → chunk-727SXJPM-BwB4ddxE.js} +1 -1
  307. package/web-shell/assets/{chunk-AQP2D5EJ-CaFKWgrn.js → chunk-AQP2D5EJ-DmHR_UZs.js} +1 -1
  308. package/web-shell/assets/{chunk-FMBD7UC4-ZZpPqIwQ.js → chunk-FMBD7UC4-BlfOXumo.js} +1 -1
  309. package/web-shell/assets/{chunk-ND2GUHAM-D22DqGs8.js → chunk-ND2GUHAM-BKogiSy7.js} +1 -1
  310. package/web-shell/assets/{chunk-QZHKN3VN-Bu85S0fw.js → chunk-QZHKN3VN-DEclVrOF.js} +1 -1
  311. package/web-shell/assets/classDiagram-4FO5ZUOK-BiaRhfvf.js +1 -0
  312. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BiaRhfvf.js +1 -0
  313. package/web-shell/assets/{cose-bilkent-S5V4N54A-f1CK1Gwe.js → cose-bilkent-S5V4N54A-CwtS21WT.js} +1 -1
  314. package/web-shell/assets/{dagre-BM42HDAG-D0Ow8F_n.js → dagre-BM42HDAG-BAAIlB4p.js} +1 -1
  315. package/web-shell/assets/{diagram-2AECGRRQ-BPrmTWp8.js → diagram-2AECGRRQ-ChljtF_V.js} +1 -1
  316. package/web-shell/assets/{diagram-5GNKFQAL-HccuFAzy.js → diagram-5GNKFQAL-BIXVd31-.js} +1 -1
  317. package/web-shell/assets/{diagram-KO2AKTUF-BrS76mbA.js → diagram-KO2AKTUF-BEiBaS15.js} +1 -1
  318. package/web-shell/assets/{diagram-LMA3HP47-V7T9lU-5.js → diagram-LMA3HP47-C-g4tWKM.js} +1 -1
  319. package/web-shell/assets/{diagram-OG6HWLK6-DKidyJMR.js → diagram-OG6HWLK6-CNCCbNQG.js} +1 -1
  320. package/web-shell/assets/{erDiagram-TEJ5UH35-DBadZIkp.js → erDiagram-TEJ5UH35-v8ysnsdI.js} +1 -1
  321. package/web-shell/assets/{flowDiagram-I6XJVG4X-BymfqdNJ.js → flowDiagram-I6XJVG4X-LKVlLjwA.js} +1 -1
  322. package/web-shell/assets/{ganttDiagram-6RSMTGT7-DOw340jf.js → ganttDiagram-6RSMTGT7-DA5MrKYG.js} +1 -1
  323. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-_8EiD8sl.js → gitGraphDiagram-PVQCEYII-Cyg5fe6d.js} +1 -1
  324. package/web-shell/assets/index-BgOcEaVt.js +1756 -0
  325. package/web-shell/assets/index-C2GE3DAF.js +74 -0
  326. package/web-shell/assets/{index-CKIadvET.js → index-CKdUkVVS.js} +1 -1
  327. package/web-shell/assets/index-DA5Lvscv.css +5 -0
  328. package/web-shell/assets/{infoDiagram-5YYISTIA-D61KYQBu.js → infoDiagram-5YYISTIA-SLsfu3Qd.js} +1 -1
  329. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-CsiXSpNx.js → ishikawaDiagram-YF4QCWOH-CmHOmTNx.js} +1 -1
  330. package/web-shell/assets/{journeyDiagram-JHISSGLW-Sdfionyh.js → journeyDiagram-JHISSGLW-C3gM_HFQ.js} +1 -1
  331. package/web-shell/assets/{kanban-definition-UN3LZRKU-C3WI3Cnl.js → kanban-definition-UN3LZRKU-BbHD7duM.js} +1 -1
  332. package/web-shell/assets/{linear-Dpigcc62.js → linear-CSBvm435.js} +1 -1
  333. package/web-shell/assets/{mermaid.core-Ct97pqgW.js → mermaid.core-CPMw15lU.js} +5 -5
  334. package/web-shell/assets/{mindmap-definition-RKZ34NQL-BzeaN0rB.js → mindmap-definition-RKZ34NQL-C_tNqXQW.js} +1 -1
  335. package/web-shell/assets/{pieDiagram-4H26LBE5-CvjgcbVD.js → pieDiagram-4H26LBE5-DH_N-8yY.js} +1 -1
  336. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-BUzgTNdH.js → quadrantDiagram-W4KKPZXB-CRbS8UkN.js} +1 -1
  337. package/web-shell/assets/{requirementDiagram-4Y6WPE33-B7zKlgUQ.js → requirementDiagram-4Y6WPE33-DJgdZPZn.js} +1 -1
  338. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-Bb9CQgrT.js → sankeyDiagram-5OEKKPKP-vhL1y5zx.js} +1 -1
  339. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-DJ6V7itG.js → sequenceDiagram-3UESZ5HK-UQthhFwd.js} +1 -1
  340. package/web-shell/assets/{stateDiagram-AJRCARHV-IImflERY.js → stateDiagram-AJRCARHV-CAywEm20.js} +1 -1
  341. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-lfJQHw-7.js +1 -0
  342. package/web-shell/assets/{timeline-definition-PNZ67QCA-6Q_uWHKh.js → timeline-definition-PNZ67QCA-CLO8b3FD.js} +1 -1
  343. package/web-shell/assets/{vennDiagram-CIIHVFJN-TmyKyjwv.js → vennDiagram-CIIHVFJN-BNAAh0Mu.js} +1 -1
  344. package/web-shell/assets/{wardley-L42UT6IY-CRh9uiPv.js → wardley-L42UT6IY-CUY7bLpN.js} +1 -1
  345. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-59TKAW8w.js → wardleyDiagram-YWT4CUSO-CSg_ORdW.js} +1 -1
  346. package/web-shell/assets/{xychartDiagram-2RQKCTM6-GCSUIK2L.js → xychartDiagram-2RQKCTM6-BjffV208.js} +1 -1
  347. package/web-shell/index.html +2 -2
  348. package/chunks/agent-headless-NO4Y2HOE.js +0 -74
  349. package/chunks/chunk-6QIGFD5W.js +0 -82
  350. package/chunks/chunk-HGT6JR3U.js +0 -177
  351. package/chunks/daemon-status-provider-3XJI6CAL.js +0 -89
  352. package/chunks/handleAutoUpdate-L6ERF36Y.js +0 -80
  353. package/chunks/list-L2GA674Y.js +0 -88
  354. package/chunks/mcp-SZLHKFJW.js +0 -82
  355. package/chunks/nonInteractiveCli-5T7KYKLK.js +0 -144
  356. package/chunks/ripGrep-OWV2IVJC.js +0 -72
  357. package/chunks/theme-manager-EEWIQJ7J.js +0 -76
  358. package/chunks/total-session-admission-44JKRWQD.js +0 -84
  359. package/chunks/workspace-providers-status-S35YAIUS.js +0 -85
  360. package/chunks/write-file-3BZC3EAE.js +0 -72
  361. package/chunks/zoom-image-TZ6S2O57.js +0 -351
  362. package/web-shell/assets/channel-DPYMT76A.js +0 -1
  363. package/web-shell/assets/classDiagram-4FO5ZUOK--JstsIgL.js +0 -1
  364. package/web-shell/assets/classDiagram-v2-Q7XG4LA2--JstsIgL.js +0 -1
  365. package/web-shell/assets/index-D1eXNRHe.js +0 -1389
  366. package/web-shell/assets/index-DVLD4CQq.css +0 -5
  367. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CYI_YoNR.js +0 -1
@@ -2,19 +2,16 @@
2
2
  "use strict";
3
3
  import {
4
4
  listCommand
5
- } from "./chunk-EVKE2FZL.js";
5
+ } from "./chunk-433VD3HX.js";
6
6
  import {
7
7
  getErrorMessage as getErrorMessage2
8
- } from "./chunk-T3O2B4XO.js";
9
- import {
10
- serveCommand
11
- } from "./chunk-S4WJVPZW.js";
8
+ } from "./chunk-PHODQP2V.js";
12
9
  import {
13
10
  ObservedChannelContactStore
14
- } from "./chunk-LGAOC3ZS.js";
11
+ } from "./chunk-DYA25Y7U.js";
15
12
  import {
16
13
  escapeAnsiCtrlCodes
17
- } from "./chunk-YDLJGZHL.js";
14
+ } from "./chunk-4NFY2S7N.js";
18
15
  import {
19
16
  stringWidth
20
17
  } from "./chunk-2MIN6GRR.js";
@@ -24,14 +21,17 @@ import {
24
21
  import {
25
22
  isLoopbackBind
26
23
  } from "./chunk-RXFQM6FQ.js";
24
+ import {
25
+ serveCommand
26
+ } from "./chunk-LL4U3BSH.js";
27
27
  import {
28
28
  resolvePath
29
- } from "./chunk-ZHBO7WVX.js";
29
+ } from "./chunk-JELIWHXD.js";
30
30
  import {
31
31
  collectProviderModelsForProtocol,
32
32
  getAuthTypeFromEnv,
33
33
  resolveCliGenerationConfig
34
- } from "./chunk-KCO4FLFJ.js";
34
+ } from "./chunk-AYB4HSBI.js";
35
35
  import {
36
36
  resolveSkillSettings
37
37
  } from "./chunk-Z4X5MTRT.js";
@@ -39,6 +39,7 @@ import {
39
39
  channelLoopPath,
40
40
  createChannel,
41
41
  daemonChannelLoopPath,
42
+ daemonChannelStateDir,
42
43
  daemonObservedContactsPath,
43
44
  daemonSessionRoutesPath,
44
45
  loadChannelsConfig,
@@ -50,23 +51,23 @@ import {
50
51
  registerToolCallDispatch,
51
52
  selectFirstModel,
52
53
  sessionsPath
53
- } from "./chunk-BNWB5CYE.js";
54
+ } from "./chunk-3WXMXT7C.js";
54
55
  import {
55
56
  getExtensionManager,
56
57
  requestChoicePluginNonInteractive,
57
58
  requestConsentNonInteractive,
58
59
  requestConsentOrFail,
59
60
  resolveExtensionCommandScope
60
- } from "./chunk-5MKRTI4T.js";
61
+ } from "./chunk-BKUN5QHP.js";
61
62
  import {
62
63
  parseChannelConfig
63
- } from "./chunk-2XSLTRFZ.js";
64
+ } from "./chunk-2CTKGIFR.js";
64
65
  import {
65
66
  findCliEntryPath
66
67
  } from "./chunk-V6WHFGST.js";
67
68
  import {
68
69
  canonicalizeWorkspace
69
- } from "./chunk-2RFKHEXL.js";
70
+ } from "./chunk-6PLDPT2C.js";
70
71
  import {
71
72
  ChannelLoopMcpWorkerHost
72
73
  } from "./chunk-FYJ7W2PI.js";
@@ -87,11 +88,11 @@ import {
87
88
  isChannelDeliveryMessage,
88
89
  isChannelStartupReportAckMessage,
89
90
  isChannelWebhookTaskMessage
90
- } from "./chunk-U4VTUMMK.js";
91
+ } from "./chunk-QONSRAEV.js";
91
92
  import {
92
93
  normalizeWorkerDiagnostic,
93
94
  sanitizeWorkerDiagnostic
94
- } from "./chunk-GZ3RCT54.js";
95
+ } from "./chunk-UHTJC7O3.js";
95
96
  import {
96
97
  normalizeServeChannelSelection
97
98
  } from "./chunk-ALMR3E6Q.js";
@@ -104,14 +105,14 @@ import {
104
105
  signalService,
105
106
  waitForExit,
106
107
  writeServiceInfo
107
- } from "./chunk-4G2BISNC.js";
108
+ } from "./chunk-XC2VAFVZ.js";
108
109
  import {
109
110
  DEFAULT_BASE_URL,
110
111
  buildHeaders,
111
112
  clearAccount,
112
113
  loadAccount,
113
114
  saveAccount
114
- } from "./chunk-GEBV2JGB.js";
115
+ } from "./chunk-I6FAHB4N.js";
115
116
  import {
116
117
  AcpBridge,
117
118
  ChannelLoopScheduler,
@@ -122,45 +123,41 @@ import {
122
123
  isChannelProactiveDeliveryError,
123
124
  sanitizeLogText,
124
125
  sanitizePromptText
125
- } from "./chunk-7I5GTCT4.js";
126
+ } from "./chunk-GB3AB7TR.js";
126
127
  import {
127
128
  assembleMcpServers,
128
129
  getPendingGatedMcpServers,
129
130
  mcpCommand
130
- } from "./chunk-6RPMI2AB.js";
131
+ } from "./chunk-NZB4NDJL.js";
131
132
  import {
132
133
  loadSettings
133
- } from "./chunk-EIF3FXTB.js";
134
+ } from "./chunk-LAPK3GLC.js";
134
135
  import {
135
136
  detectSystemLanguage,
136
137
  getCurrentLanguage,
137
138
  initializeI18n,
138
139
  resolveLanguageSetting,
139
140
  t
140
- } from "./chunk-TCIFAA7K.js";
141
+ } from "./chunk-CHCLO3M7.js";
141
142
  import {
142
143
  loadEnvironment
143
- } from "./chunk-2N7CODY5.js";
144
+ } from "./chunk-AQEWCKX4.js";
145
+ import {
146
+ isWorkspaceTrusted
147
+ } from "./chunk-434YCHSV.js";
148
+ import {
149
+ require_strip_json_comments
150
+ } from "./chunk-ALGGS7UH.js";
144
151
  import {
145
152
  hideBin,
146
153
  yargs_default
147
154
  } from "./chunk-XFSFZCM5.js";
148
155
  import {
149
156
  getCliVersion
150
- } from "./chunk-VYOXCEPJ.js";
157
+ } from "./chunk-MBKPUM5Y.js";
151
158
  import {
152
159
  getPackageJson
153
160
  } from "./chunk-VJNBRRZG.js";
154
- import {
155
- isWorkspaceTrusted
156
- } from "./chunk-Q43KPN7X.js";
157
- import {
158
- require_strip_json_comments
159
- } from "./chunk-ALGGS7UH.js";
160
- import {
161
- writeStderrLine,
162
- writeStdoutLine
163
- } from "./chunk-OWAK7LMW.js";
164
161
  import {
165
162
  Config,
166
163
  DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
@@ -194,7 +191,7 @@ import {
194
191
  unquoteCStylePath,
195
192
  updateChannelMemoryEntry,
196
193
  updateSetting
197
- } from "./chunk-X5WNMMIA.js";
194
+ } from "./chunk-NGWYUZZO.js";
198
195
  import {
199
196
  nextFireTime,
200
197
  parseCron
@@ -202,27 +199,27 @@ import {
202
199
  import {
203
200
  parseBooleanEnvFlag,
204
201
  resolveTelemetrySettings
205
- } from "./chunk-75MIQ3LV.js";
202
+ } from "./chunk-RPYYTL7E.js";
206
203
  import {
207
204
  getAllGeminiMdFilenames,
208
205
  setGeminiMdFilename
209
- } from "./chunk-PT722TDT.js";
206
+ } from "./chunk-M2F5PLOW.js";
210
207
  import {
211
208
  SchemaValidator,
212
209
  ToolNames
213
- } from "./chunk-Y6AXW2OG.js";
210
+ } from "./chunk-I5GNT6ZS.js";
214
211
  import {
215
212
  DEFAULT_QWEN_EMBEDDING_MODEL
216
- } from "./chunk-VCPIZRYH.js";
213
+ } from "./chunk-TFFMATHX.js";
217
214
  import {
218
215
  isTlsVerificationDisabled
219
- } from "./chunk-WZRWHXFE.js";
216
+ } from "./chunk-BFHXDAR7.js";
220
217
  import {
221
218
  atomicWriteFileSync
222
- } from "./chunk-7XATOOE7.js";
219
+ } from "./chunk-UH7Z7Y45.js";
223
220
  import {
224
221
  recordChannelMemoryRecallMetrics
225
- } from "./chunk-BGTQCTQW.js";
222
+ } from "./chunk-O2ZYHG33.js";
226
223
  import {
227
224
  FatalConfigError,
228
225
  FatalSandboxError,
@@ -230,7 +227,12 @@ import {
230
227
  createDebugLogger,
231
228
  getErrorMessage,
232
229
  isNodeError
233
- } from "./chunk-UHUSJ6X7.js";
230
+ } from "./chunk-3RXUYQJI.js";
231
+ import {
232
+ writeStderrLine,
233
+ writeStderrLineSafe,
234
+ writeStdoutLine
235
+ } from "./chunk-OWAK7LMW.js";
234
236
  import {
235
237
  init_esbuild_shims
236
238
  } from "./chunk-5O2XNYP6.js";
@@ -363,10 +365,10 @@ var require_command_exists = __commonJS({
363
365
  module.exports = /* @__PURE__ */ __name(function commandExists2(commandName, callback) {
364
366
  var cleanedCommandName = cleanInput(commandName);
365
367
  if (!callback && typeof Promise !== "undefined") {
366
- return new Promise(function(resolve14, reject) {
368
+ return new Promise(function(resolve15, reject) {
367
369
  commandExists2(commandName, function(error, output) {
368
370
  if (output) {
369
- resolve14(commandName);
371
+ resolve15(commandName);
370
372
  } else {
371
373
  reject(error);
372
374
  }
@@ -2183,6 +2185,7 @@ __name(isChannelCronEnabled, "isChannelCronEnabled");
2183
2185
  var MAX_CRASH_RESTARTS = 3;
2184
2186
  var CRASH_WINDOW_MS = 5 * 60 * 1e3;
2185
2187
  var RESTART_DELAY_MS = 3e3;
2188
+ var BRIDGE_SESSION_RESTORE_TIMEOUT_MS = 60 * 1e3;
2186
2189
  function isFileExistsError(err) {
2187
2190
  return typeof err === "object" && err !== null && err.code === "EEXIST";
2188
2191
  }
@@ -2238,6 +2241,134 @@ function cleanupStartedChannels(channels, bridge, router) {
2238
2241
  }
2239
2242
  }
2240
2243
  __name(cleanupStartedChannels, "cleanupStartedChannels");
2244
+ function createBridgeReadinessGate() {
2245
+ let pending;
2246
+ let releasePending;
2247
+ return {
2248
+ current: /* @__PURE__ */ __name(() => pending, "current"),
2249
+ block: /* @__PURE__ */ __name(() => {
2250
+ if (pending) return;
2251
+ pending = new Promise((resolve15) => {
2252
+ releasePending = resolve15;
2253
+ });
2254
+ }, "block"),
2255
+ release: /* @__PURE__ */ __name(() => {
2256
+ const release = releasePending;
2257
+ pending = void 0;
2258
+ releasePending = void 0;
2259
+ release?.();
2260
+ }, "release")
2261
+ };
2262
+ }
2263
+ __name(createBridgeReadinessGate, "createBridgeReadinessGate");
2264
+ async function restoreBridgeSessions(router) {
2265
+ let timeout;
2266
+ const expired = new Promise((_, reject) => {
2267
+ timeout = setTimeout(
2268
+ () => reject(
2269
+ new Error(
2270
+ `Session restore timed out after ${BRIDGE_SESSION_RESTORE_TIMEOUT_MS}ms`
2271
+ )
2272
+ ),
2273
+ BRIDGE_SESSION_RESTORE_TIMEOUT_MS
2274
+ );
2275
+ timeout.unref?.();
2276
+ });
2277
+ try {
2278
+ return await Promise.race([router.restoreSessions(), expired]);
2279
+ } finally {
2280
+ clearTimeout(timeout);
2281
+ }
2282
+ }
2283
+ __name(restoreBridgeSessions, "restoreBridgeSessions");
2284
+ function createBridgeRecovery(options) {
2285
+ const {
2286
+ bridgeOpts,
2287
+ router,
2288
+ channels,
2289
+ scheduler,
2290
+ bridgeReadiness,
2291
+ isShuttingDown,
2292
+ getBridge,
2293
+ setBridge
2294
+ } = options;
2295
+ const crashTimestamps = [];
2296
+ let recoveryTask;
2297
+ let recoveryRequested = false;
2298
+ let recoverySourceBridge;
2299
+ const attachDisconnectHandler = /* @__PURE__ */ __name((failedBridge) => {
2300
+ failedBridge.on("disconnected", () => {
2301
+ if (isShuttingDown() || failedBridge !== getBridge()) return;
2302
+ if (recoveryTask) {
2303
+ if (failedBridge !== recoverySourceBridge) recoveryRequested = true;
2304
+ return;
2305
+ }
2306
+ recoverBridge();
2307
+ });
2308
+ }, "attachDisconnectHandler");
2309
+ const recoverBridge = /* @__PURE__ */ __name(() => {
2310
+ bridgeReadiness.block();
2311
+ scheduler?.markBridgeRecovery();
2312
+ const task = (async () => {
2313
+ do {
2314
+ recoveryRequested = false;
2315
+ recoverySourceBridge = getBridge();
2316
+ const now = Date.now();
2317
+ crashTimestamps.push(now);
2318
+ while (now - crashTimestamps[0] >= CRASH_WINDOW_MS) {
2319
+ crashTimestamps.shift();
2320
+ }
2321
+ const recentCrashCount = crashTimestamps.length;
2322
+ if (recentCrashCount > MAX_CRASH_RESTARTS) {
2323
+ writeStderrLine(
2324
+ `[Channel] Bridge crashed ${recentCrashCount} times in ${CRASH_WINDOW_MS / 1e3}s. Giving up.`
2325
+ );
2326
+ scheduler?.stop();
2327
+ cleanupStartedChannels(channels.values(), getBridge(), router);
2328
+ removeServiceInfo();
2329
+ process.exit(1);
2330
+ }
2331
+ writeStderrLine(
2332
+ `[Channel] Bridge crashed (${recentCrashCount}/${MAX_CRASH_RESTARTS} in window). Restarting in ${RESTART_DELAY_MS / 1e3}s...`
2333
+ );
2334
+ await new Promise((resolve15) => setTimeout(resolve15, RESTART_DELAY_MS));
2335
+ const bridge = new AcpBridge(bridgeOpts);
2336
+ setBridge(bridge);
2337
+ attachDisconnectHandler(bridge);
2338
+ await bridge.start();
2339
+ router.setBridge(bridge);
2340
+ for (const channel of channels.values()) {
2341
+ channel.setBridge(bridge);
2342
+ }
2343
+ registerToolCallDispatch(bridge, router, channels);
2344
+ registerBackgroundResponseRelay(bridge, router, channels);
2345
+ registerPermissionRelay(bridge, router, channels);
2346
+ registerSessionCleanup(bridge, router, channels);
2347
+ const result = await restoreBridgeSessions(router);
2348
+ writeStdoutLine(
2349
+ `[Channel] Bridge restarted. Sessions restored: ${result.restored}, failed: ${result.failed}`
2350
+ );
2351
+ } while (recoveryRequested && !isShuttingDown());
2352
+ })().catch((err) => {
2353
+ writeStderrLine(
2354
+ `[Channel] Failed to restart bridge: ${err instanceof Error ? err.message : String(err)}`
2355
+ );
2356
+ scheduler?.stop();
2357
+ cleanupStartedChannels(channels.values(), getBridge(), router);
2358
+ removeServiceInfo();
2359
+ process.exit(1);
2360
+ }).finally(() => {
2361
+ if (recoveryTask === task) {
2362
+ recoveryTask = void 0;
2363
+ recoverySourceBridge = void 0;
2364
+ bridgeReadiness.release();
2365
+ }
2366
+ });
2367
+ recoveryTask = task;
2368
+ }, "recoverBridge");
2369
+ return { attachDisconnectHandler };
2370
+ }
2371
+ __name(createBridgeRecovery, "createBridgeRecovery");
2241
2372
  function checkDuplicateInstance() {
2242
2373
  const existing = readServiceInfo();
2243
2374
  if (existing) {
@@ -2282,7 +2413,7 @@ async function startSingle(name, proxy, cronEnabled) {
2282
2413
  }
2283
2414
  const cliEntryPath = findCliEntryPath();
2284
2415
  let shuttingDown = false;
2285
- const crashTimestamps = [];
2416
+ const bridgeReadiness = createBridgeReadinessGate();
2286
2417
  const bridgeOpts = { cliEntryPath, cwd: config.cwd, model: config.model };
2287
2418
  let bridge = new AcpBridge(bridgeOpts);
2288
2419
  await bridge.start();
@@ -2299,7 +2430,8 @@ async function startSingle(name, proxy, cronEnabled) {
2299
2430
  router,
2300
2431
  proxy,
2301
2432
  ...channelMemoryOptions(() => bridge, config.cwd),
2302
- ...loopController ? { loopController } : {}
2433
+ ...loopController ? { loopController } : {},
2434
+ bridgeRecovery: bridgeReadiness.current
2303
2435
  });
2304
2436
  channels.set(name, channel);
2305
2437
  const scheduler = loopStore ? new ChannelLoopScheduler({
@@ -2326,57 +2458,18 @@ async function startSingle(name, proxy, cronEnabled) {
2326
2458
  );
2327
2459
  scheduler?.start();
2328
2460
  writeStdoutLine(`[Channel] "${name}" is running. Press Ctrl+C to stop.`);
2329
- const attachDisconnectHandler = /* @__PURE__ */ __name((b) => {
2330
- b.on("disconnected", async () => {
2331
- if (shuttingDown) return;
2332
- const now = Date.now();
2333
- crashTimestamps.push(now);
2334
- const recentCrashes = crashTimestamps.filter(
2335
- (ts) => now - ts < CRASH_WINDOW_MS
2336
- );
2337
- if (recentCrashes.length > MAX_CRASH_RESTARTS) {
2338
- writeStderrLine(
2339
- `[Channel] Bridge crashed ${recentCrashes.length} times in ${CRASH_WINDOW_MS / 1e3}s. Giving up.`
2340
- );
2341
- scheduler?.stop();
2342
- channel.disconnect();
2343
- router.clearAll();
2344
- removeServiceInfo();
2345
- process.exit(1);
2346
- }
2347
- writeStderrLine(
2348
- `[Channel] Bridge crashed (${recentCrashes.length}/${MAX_CRASH_RESTARTS} in window). Restarting in ${RESTART_DELAY_MS / 1e3}s...`
2349
- );
2350
- scheduler?.stop();
2351
- await new Promise((r) => setTimeout(r, RESTART_DELAY_MS));
2352
- try {
2353
- bridge = new AcpBridge(bridgeOpts);
2354
- await bridge.start();
2355
- router.setBridge(bridge);
2356
- channel.setBridge(bridge);
2357
- channel.disconnect();
2358
- await channel.connect();
2359
- registerToolCallDispatch(bridge, router, channels);
2360
- registerBackgroundResponseRelay(bridge, router, channels);
2361
- registerPermissionRelay(bridge, router, channels);
2362
- registerSessionCleanup(bridge, router, channels);
2363
- attachDisconnectHandler(bridge);
2364
- const result = await router.restoreSessions();
2365
- scheduler?.start();
2366
- writeStdoutLine(
2367
- `[Channel] Bridge restarted. Sessions restored: ${result.restored}, failed: ${result.failed}`
2368
- );
2369
- } catch (err) {
2370
- writeStderrLine(
2371
- `[Channel] Failed to restart bridge: ${err instanceof Error ? err.message : String(err)}`
2372
- );
2373
- channel.disconnect();
2374
- router.clearAll();
2375
- removeServiceInfo();
2376
- process.exit(1);
2377
- }
2378
- });
2379
- }, "attachDisconnectHandler");
2461
+ const { attachDisconnectHandler } = createBridgeRecovery({
2462
+ bridgeOpts,
2463
+ router,
2464
+ channels,
2465
+ scheduler,
2466
+ bridgeReadiness,
2467
+ isShuttingDown: /* @__PURE__ */ __name(() => shuttingDown, "isShuttingDown"),
2468
+ getBridge: /* @__PURE__ */ __name(() => bridge, "getBridge"),
2469
+ setBridge: /* @__PURE__ */ __name((next) => {
2470
+ bridge = next;
2471
+ }, "setBridge")
2472
+ });
2380
2473
  attachDisconnectHandler(bridge);
2381
2474
  const shutdown = /* @__PURE__ */ __name(() => {
2382
2475
  shuttingDown = true;
@@ -2417,7 +2510,7 @@ async function startAll(proxy, cronEnabled) {
2417
2510
  const cliEntryPath = findCliEntryPath();
2418
2511
  const defaultCwd = process.cwd();
2419
2512
  let shuttingDown = false;
2420
- const crashTimestamps = [];
2513
+ const bridgeReadiness = createBridgeReadinessGate();
2421
2514
  const bridgeOpts = {
2422
2515
  cliEntryPath,
2423
2516
  cwd: defaultCwd,
@@ -2442,7 +2535,8 @@ async function startAll(proxy, cronEnabled) {
2442
2535
  router,
2443
2536
  proxy,
2444
2537
  ...channelMemoryOptions(() => bridge, config.cwd),
2445
- ...loopController ? { loopController } : {}
2538
+ ...loopController ? { loopController } : {},
2539
+ bridgeRecovery: bridgeReadiness.current
2446
2540
  })
2447
2541
  );
2448
2542
  }
@@ -2482,85 +2576,18 @@ async function startAll(proxy, cronEnabled) {
2482
2576
  writeStdoutLine(
2483
2577
  `[Channel] Running ${connectedCount} channel(s). Press Ctrl+C to stop.`
2484
2578
  );
2485
- const attachDisconnectHandler = /* @__PURE__ */ __name((b) => {
2486
- b.on("disconnected", async () => {
2487
- if (shuttingDown) return;
2488
- const now = Date.now();
2489
- crashTimestamps.push(now);
2490
- const recentCrashes = crashTimestamps.filter(
2491
- (ts) => now - ts < CRASH_WINDOW_MS
2492
- );
2493
- if (recentCrashes.length > MAX_CRASH_RESTARTS) {
2494
- writeStderrLine(
2495
- `[Channel] Bridge crashed ${recentCrashes.length} times in ${CRASH_WINDOW_MS / 1e3}s. Giving up.`
2496
- );
2497
- scheduler?.stop();
2498
- for (const channel of channels.values()) {
2499
- try {
2500
- channel.disconnect();
2501
- } catch {
2502
- }
2503
- }
2504
- router.clearAll();
2505
- removeServiceInfo();
2506
- process.exit(1);
2507
- }
2508
- writeStderrLine(
2509
- `[Channel] Bridge crashed (${recentCrashes.length}/${MAX_CRASH_RESTARTS} in window). Restarting in ${RESTART_DELAY_MS / 1e3}s...`
2510
- );
2511
- scheduler?.stop();
2512
- await new Promise((r) => setTimeout(r, RESTART_DELAY_MS));
2513
- try {
2514
- bridge = new AcpBridge(bridgeOpts);
2515
- await bridge.start();
2516
- router.setBridge(bridge);
2517
- for (const channel of channels.values()) {
2518
- channel.setBridge(bridge);
2519
- }
2520
- for (const [name, channel] of connectedChannels) {
2521
- try {
2522
- channel.disconnect();
2523
- await channel.connect();
2524
- } catch (err) {
2525
- writeStderrLine(
2526
- `[Channel] "${name}" failed to reconnect: ${err instanceof Error ? err.message : String(err)}`
2527
- );
2528
- connectedChannels.delete(name);
2529
- }
2530
- }
2531
- if (connectedChannels.size === 0) {
2532
- writeStderrLine("[Channel] No channels reconnected. Exiting.");
2533
- bridge.stop();
2534
- router.clearAll();
2535
- removeServiceInfo();
2536
- process.exit(1);
2537
- }
2538
- registerToolCallDispatch(bridge, router, channels);
2539
- registerBackgroundResponseRelay(bridge, router, channels);
2540
- registerPermissionRelay(bridge, router, channels);
2541
- registerSessionCleanup(bridge, router, channels);
2542
- attachDisconnectHandler(bridge);
2543
- const result = await router.restoreSessions();
2544
- scheduler?.start();
2545
- writeStdoutLine(
2546
- `[Channel] Bridge restarted. Sessions restored: ${result.restored}, failed: ${result.failed}`
2547
- );
2548
- } catch (err) {
2549
- writeStderrLine(
2550
- `[Channel] Failed to restart bridge: ${err instanceof Error ? err.message : String(err)}`
2551
- );
2552
- for (const channel of channels.values()) {
2553
- try {
2554
- channel.disconnect();
2555
- } catch {
2556
- }
2557
- }
2558
- router.clearAll();
2559
- removeServiceInfo();
2560
- process.exit(1);
2561
- }
2562
- });
2563
- }, "attachDisconnectHandler");
2579
+ const { attachDisconnectHandler } = createBridgeRecovery({
2580
+ bridgeOpts,
2581
+ router,
2582
+ channels,
2583
+ scheduler,
2584
+ bridgeReadiness,
2585
+ isShuttingDown: /* @__PURE__ */ __name(() => shuttingDown, "isShuttingDown"),
2586
+ getBridge: /* @__PURE__ */ __name(() => bridge, "getBridge"),
2587
+ setBridge: /* @__PURE__ */ __name((next) => {
2588
+ bridge = next;
2589
+ }, "setBridge")
2590
+ });
2564
2591
  attachDisconnectHandler(bridge);
2565
2592
  const shutdown = /* @__PURE__ */ __name(() => {
2566
2593
  shuttingDown = true;
@@ -2622,7 +2649,7 @@ var stopCommand = {
2622
2649
  if (argv["daemon-url"]) {
2623
2650
  const token = argv.token ?? process.env[QWEN_SERVER_TOKEN_ENV] ?? process.env[QWEN_DAEMON_TOKEN_ENV];
2624
2651
  try {
2625
- const sdk = await import("./daemon-Q2AB5Z23.js");
2652
+ const sdk = await import("./daemon-PCNCI5YU.js");
2626
2653
  const client = new sdk.DaemonClient({
2627
2654
  baseUrl: argv["daemon-url"],
2628
2655
  ...token ? { token } : {}
@@ -2808,7 +2835,7 @@ var statusCommand = {
2808
2835
  if (argv["daemon-url"]) {
2809
2836
  const token = argv.token ?? process.env[QWEN_SERVER_TOKEN_ENV] ?? process.env[QWEN_DAEMON_TOKEN_ENV];
2810
2837
  try {
2811
- const sdk = await import("./daemon-Q2AB5Z23.js");
2838
+ const sdk = await import("./daemon-PCNCI5YU.js");
2812
2839
  const client = new sdk.DaemonClient({
2813
2840
  baseUrl: argv["daemon-url"],
2814
2841
  ...token ? { token } : {}
@@ -2919,7 +2946,7 @@ var reloadCommand = {
2919
2946
  const token = resolveToken(argv.token);
2920
2947
  let sdk;
2921
2948
  try {
2922
- sdk = await import("./daemon-Q2AB5Z23.js");
2949
+ sdk = await import("./daemon-PCNCI5YU.js");
2923
2950
  } catch (err) {
2924
2951
  writeStderrLine(
2925
2952
  `[Channel] Failed to load daemon SDK: ${safeChannelCommandErrorMessage(err)}`
@@ -2999,7 +3026,7 @@ var setCommand2 = {
2999
3026
  const selection = names[0] === "all" ? { mode: "all" } : { mode: "names", names };
3000
3027
  let sdk;
3001
3028
  try {
3002
- sdk = await import("./daemon-Q2AB5Z23.js");
3029
+ sdk = await import("./daemon-PCNCI5YU.js");
3003
3030
  } catch (error) {
3004
3031
  writeStderrLine(
3005
3032
  `[Channel] Failed to load daemon SDK: ${safeChannelCommandErrorMessage(error)}`
@@ -3125,7 +3152,7 @@ function createDaemonChannelBridgeFacade(bridge, opts) {
3125
3152
  }
3126
3153
  __name(createDaemonChannelBridgeFacade, "createDaemonChannelBridgeFacade");
3127
3154
  async function loadDaemonSdk() {
3128
- return await import("./daemon-Q2AB5Z23.js");
3155
+ return await import("./daemon-PCNCI5YU.js");
3129
3156
  }
3130
3157
  __name(loadDaemonSdk, "loadDaemonSdk");
3131
3158
  function selectedChannelNames(channelsConfig, selection) {
@@ -3172,12 +3199,12 @@ async function abortableStartup(value, signal) {
3172
3199
  const promise = Promise.resolve(value);
3173
3200
  if (!signal) return await promise;
3174
3201
  if (signal.aborted) throw startupAbortError();
3175
- return await new Promise((resolve14, reject) => {
3202
+ return await new Promise((resolve15, reject) => {
3176
3203
  const onAbort = /* @__PURE__ */ __name(() => {
3177
3204
  reject(startupAbortError());
3178
3205
  }, "onAbort");
3179
3206
  signal.addEventListener("abort", onAbort, { once: true });
3180
- promise.then(resolve14, reject).finally(() => {
3207
+ promise.then(resolve15, reject).finally(() => {
3181
3208
  signal.removeEventListener("abort", onAbort);
3182
3209
  });
3183
3210
  });
@@ -3351,6 +3378,7 @@ async function runChannelDaemonWorker(opts) {
3351
3378
  createChannel(name, config, bridgeFacade, {
3352
3379
  ...proxy ? { proxy } : {},
3353
3380
  router: createdRouter,
3381
+ stateDir: daemonChannelStateDir(daemonWorkspace, name),
3354
3382
  channelMemory: {
3355
3383
  readChannelMemory,
3356
3384
  getChannelMemoryRevision,
@@ -3584,7 +3612,7 @@ function reportStartupToSupervisor(message, signal, subscribeMessage = (listener
3584
3612
  if (!send) {
3585
3613
  return Promise.reject(new Error("Channel worker IPC is unavailable."));
3586
3614
  }
3587
- return new Promise((resolve14, reject) => {
3615
+ return new Promise((resolve15, reject) => {
3588
3616
  let settled = false;
3589
3617
  let unsubscribeMessage = /* @__PURE__ */ __name(() => {
3590
3618
  }, "unsubscribeMessage");
@@ -3598,7 +3626,7 @@ function reportStartupToSupervisor(message, signal, subscribeMessage = (listener
3598
3626
  settled = true;
3599
3627
  cleanup();
3600
3628
  if (error) reject(error);
3601
- else resolve14();
3629
+ else resolve15();
3602
3630
  }, "finish");
3603
3631
  const onMessage = /* @__PURE__ */ __name((value) => {
3604
3632
  if (isChannelStartupReportAckMessage(value)) {
@@ -3846,8 +3874,8 @@ var daemonWorkerCommand = {
3846
3874
  let shuttingDown = false;
3847
3875
  let exitCode = 0;
3848
3876
  let finish;
3849
- const finished = new Promise((resolve14) => {
3850
- finish = resolve14;
3877
+ const finished = new Promise((resolve15) => {
3878
+ finish = resolve15;
3851
3879
  });
3852
3880
  const shutdown = /* @__PURE__ */ __name(async (reason) => {
3853
3881
  if (shuttingDown) {
@@ -3875,8 +3903,8 @@ var daemonWorkerCommand = {
3875
3903
  ...activeChannelDeliveries.values(),
3876
3904
  ...activeWebhookTasks.values()
3877
3905
  ]),
3878
- new Promise((resolve14) => {
3879
- const timer = setTimeout(resolve14, WORKER_SHUTDOWN_DRAIN_MS);
3906
+ new Promise((resolve15) => {
3907
+ const timer = setTimeout(resolve15, WORKER_SHUTDOWN_DRAIN_MS);
3880
3908
  timer.unref();
3881
3909
  })
3882
3910
  ]);
@@ -6683,6 +6711,7 @@ function unmarkedComments(comments) {
6683
6711
  __name(unmarkedComments, "unmarkedComments");
6684
6712
 
6685
6713
  // packages/cli/src/commands/review/compose-review.ts
6714
+ var LOW_SIGNAL_SRC_DIFF_LINES = 100;
6686
6715
  function withMarker(line) {
6687
6716
  return line.startsWith(CRITICAL_PREFIX) ? line : `${CRITICAL_PREFIX} ${line}`;
6688
6717
  }
@@ -6927,6 +6956,19 @@ function composeReview(input) {
6927
6956
  downgraded = true;
6928
6957
  downgradedFrom = "Request changes";
6929
6958
  }
6959
+ let lowSignal = null;
6960
+ if (event === "APPROVE" && input.planPath) {
6961
+ try {
6962
+ const plan = JSON.parse(
6963
+ readFileSync8(input.planPath, "utf8")
6964
+ );
6965
+ const src = Number(plan.srcDiffLines ?? 0);
6966
+ if (src > LOW_SIGNAL_SRC_DIFF_LINES) {
6967
+ lowSignal = { agents: requiredAgents(plan).length, srcDiffLines: src };
6968
+ }
6969
+ } catch {
6970
+ }
6971
+ }
6930
6972
  const footer = `_\u2014 ${modelId} via Qwen Code /review_`;
6931
6973
  const bilingual = bilingualFromPlan(input.planPath, input.prBodyFetcher);
6932
6974
  const render = /* @__PURE__ */ __name((parts, sep4) => {
@@ -7075,7 +7117,8 @@ ${footer}`;
7075
7117
  cappedBy,
7076
7118
  downgraded,
7077
7119
  downgradedFrom,
7078
- remediation
7120
+ remediation,
7121
+ lowSignal
7079
7122
  };
7080
7123
  }
7081
7124
  if (event === "APPROVE") {
@@ -7092,7 +7135,8 @@ ${footer}`;
7092
7135
  cappedBy,
7093
7136
  downgraded,
7094
7137
  downgradedFrom,
7095
- remediation
7138
+ remediation,
7139
+ lowSignal
7096
7140
  };
7097
7141
  }
7098
7142
  const clauses = [];
@@ -7146,7 +7190,8 @@ ${footer}`;
7146
7190
  cappedBy,
7147
7191
  downgraded,
7148
7192
  downgradedFrom,
7149
- remediation
7193
+ remediation,
7194
+ lowSignal
7150
7195
  };
7151
7196
  }
7152
7197
  __name(composeReview, "composeReview");
@@ -7400,6 +7445,9 @@ function verdictLine(r) {
7400
7445
  } else if (r.downgraded) {
7401
7446
  line += " \u2014 downgraded by a presubmit check";
7402
7447
  }
7448
+ if (r.event === "APPROVE" && r.lowSignal) {
7449
+ line += ` \u2014 low signal: none of the ${r.lowSignal.agents} review agents reported a finding on a non-trivial diff (${r.lowSignal.srcDiffLines} source diff lines)`;
7450
+ }
7403
7451
  return line;
7404
7452
  }
7405
7453
  __name(verdictLine, "verdictLine");
@@ -9991,6 +10039,7 @@ var GITHUB_ACTIONS = {
9991
10039
  - **A fork guard this diff removes or fails to add on a newly-privileged path.** For any trigger a fork can fire, the guard is what makes everything above unreachable: \`if: github.event.pull_request.head.repo.full_name == github.repository\`, an author-association check, or a \`github.repository == '<owner>/<repo>'\` gate on a scheduled job. A diff that adds a privileged trigger without one has added the vulnerability, not inherited it.
9992
10040
  - **\`$GITHUB_OUTPUT\` / \`$GITHUB_ENV\` written from untrusted data.** \`echo "x=$UNTRUSTED" >> "$GITHUB_OUTPUT"\` with a value containing a newline injects a second, arbitrary variable \u2014 \`PATH\` or \`NODE_OPTIONS\` among them. Multi-line values need the heredoc form with an unguessable delimiter.
9993
10041
  - **Artifact or cache poisoning across a trigger boundary.** A \`workflow_run\` job that downloads an artifact a \`pull_request\` job uploaded is pulling contributor-controlled bytes into a privileged context. So is a cache key a fork can populate.
10042
+ - **A cache or reuse mechanism whose two sides never agree on identity.** \`actions/cache\` matches an entry on \`(key | restore-key)\` **and** a \`version\` that hashes the literal \`path\` strings plus the compression method \u2014 not the key alone. So two jobs can share a key, share the \`path:\` line *as written*, and never hit once: \`\${{ runner.temp }}\` expands to a different string on \`ubuntu-latest\` than in a container job or on a self-hosted runner, and an image without the \`zstd\` binary picks gzip where a hosted runner picks zstd. Compare the **environments** \u2014 \`runs-on\`, \`container\`, what each path expression expands to, what each image ships \u2014 never the YAML strings, which match in exactly the case that fails. The same question governs any restore/skip/reuse mechanism a diff introduces: does the side that writes agree with the side that reads? A mechanism that can never fire is not a slow optimisation, it is a no-op carrying maintenance cost, and no assertion about the YAML's *shape* will ever say so \u2014 tests that the two sides' \`key:\` and \`path:\` strings match pass just as happily when neither side can reach the other's cache. If a hit leaves no observable signal either \u2014 a restore step with no \`id:\`, nothing written to \`$GITHUB_STEP_SUMMARY\` \u2014 the failure is silent and permanent; say that as part of the finding.
9994
10043
 
9995
10044
  **Recommendations (Suggestion) \u2014 say the cost, do not block on them:**
9996
10045
 
@@ -10390,7 +10439,7 @@ function buildRoleBrief(report, role, opts = {}) {
10390
10439
  if (typeof base === "string" && base && pr !== void 0 && opts.planPath) {
10391
10440
  parts.push(
10392
10441
  "",
10393
- "**Then run the test-efficacy probe.** A green suite says the tests pass. It does not say they would have failed had the change been wrong, and those are different claims:",
10442
+ "**Then run the test-efficacy probe.** A green suite says the tests pass. It does not say they would have failed had the change been wrong, and those are different claims. Give this call `timeout: 600000` too \u2014 besides the revert probe it runs up to 8 single-statement deletion mutants, each a suite run, and it budgets itself to finish inside that ceiling:",
10394
10443
  "",
10395
10444
  "```bash",
10396
10445
  `"\${QWEN_CODE_CLI:-qwen}" review test-efficacy ${resolve11(opts.planPath)} \\`,
@@ -10399,7 +10448,7 @@ function buildRoleBrief(report, role, opts = {}) {
10399
10448
  ` --out ${resolve11(dirname12(opts.planPath), `qwen-review-pr-${pr}-efficacy.json`)}`,
10400
10449
  "```",
10401
10450
  "",
10402
- 'Read its `findings[]`. `kind: "unreachable"` is a test the project\'s test command never collects \u2014 it did not run here and it does not run in CI. `kind: "inert"` is a test that **still passed with the change reverted**: it is green whether or not the feature exists, so it cannot catch a regression in it. Report each as a **Suggestion** with `Source: [test]`, saying plainly which behaviour ships unprotected. **`inconclusive` is not a finding** \u2014 reverting the source often breaks the test\'s own compile, and that is not the test catching anything. Note it and move on.'
10451
+ 'Read its `findings[]`. `kind: "unreachable"` is a test the project\'s test command never collects \u2014 it did not run here and it does not run in CI. `kind: "inert"` is a test that **still passed with the change reverted**: it is green whether or not the feature exists, so it cannot catch a regression in it. `kind: "mutant-survived"` is a single safety statement the diff added (a `.clear()`, an `.abort(\u2026)`, a reset-to-empty) that was **deleted and every affected test stayed green** \u2014 no test in the diff fails when it is removed, which the whole-file revert cannot see when the file\'s other, tested behaviours mask it. Report each as a **Suggestion** with `Source: [test]`, saying plainly which behaviour has no test in this diff that would catch its removal. **`inconclusive` is not a finding** \u2014 for probes and mutants alike, reverting or mutating the source often breaks the test\'s own compile, and that is not the test catching anything. Mutants counted in `mutants.skippedForBudget`, `mutants.skippedForCap`, or `mutants.skippedForBaseline` never ran \u2014 not findings either. `mutants.note`, when present, explains why no mutants ran at all. Note them and move on.'
10403
10452
  );
10404
10453
  }
10405
10454
  }
@@ -10880,7 +10929,13 @@ var agentPromptCommand = {
10880
10929
  // packages/cli/src/commands/review/build-test.ts
10881
10930
  init_esbuild_shims();
10882
10931
  import { spawnSync as spawnSync2 } from "node:child_process";
10883
- import { existsSync as existsSync5, readFileSync as readFileSync16, rmSync as rmSync4, writeFileSync as writeFileSync15 } from "node:fs";
10932
+ import {
10933
+ existsSync as existsSync5,
10934
+ readFileSync as readFileSync16,
10935
+ rmSync as rmSync4,
10936
+ statfsSync,
10937
+ writeFileSync as writeFileSync15
10938
+ } from "node:fs";
10884
10939
  import { join as join12, resolve as resolve12 } from "node:path";
10885
10940
 
10886
10941
  // packages/cli/src/commands/review/lib/workspaces.ts
@@ -11081,6 +11136,18 @@ ${rescued.join("\n")}
11081
11136
  return s.slice(0, KEEP_HEAD) + marker + s.slice(-KEEP_TAIL);
11082
11137
  }
11083
11138
  __name(trimOutput, "trimOutput");
11139
+ var INSTALL_MIN_FREE_BYTES = 3 * 1024 ** 3;
11140
+ var BUILD_MIN_FREE_BYTES = 1024 ** 3;
11141
+ function freeDiskBytes(dir) {
11142
+ try {
11143
+ const s = statfsSync(dir);
11144
+ return s.bavail * s.bsize;
11145
+ } catch {
11146
+ return null;
11147
+ }
11148
+ }
11149
+ __name(freeDiskBytes, "freeDiskBytes");
11150
+ var gib = /* @__PURE__ */ __name((bytes) => (bytes / 1024 ** 3).toFixed(1), "gib");
11084
11151
  function buildRunEnv(base = process.env) {
11085
11152
  return {
11086
11153
  ...base,
@@ -11226,7 +11293,14 @@ function runBuildTest(args) {
11226
11293
  );
11227
11294
  }
11228
11295
  if (args.install && npmLock && !installComplete()) {
11229
- const install = exec("npm ci --no-audit --no-fund", root, perCommandMs);
11296
+ const installCmd = "npm ci --no-audit --no-fund";
11297
+ const free = freeDiskBytes(root);
11298
+ if (free !== null && free < INSTALL_MIN_FREE_BYTES) {
11299
+ results.ok = false;
11300
+ results.note = `Insufficient disk space (${gib(free)}G free, need ~${gib(INSTALL_MIN_FREE_BYTES)}G): skipped \`${installCmd}\`, so nothing could be built or tested. This is an environment issue, not a code finding \u2014 report it as informational.`;
11301
+ return results;
11302
+ }
11303
+ const install = exec(installCmd, root, perCommandMs);
11230
11304
  results.install = install;
11231
11305
  if (install.timedOut) results.timedOut.push(install.command);
11232
11306
  if (install.timedOut) {
@@ -11245,6 +11319,12 @@ function runBuildTest(args) {
11245
11319
  return results;
11246
11320
  }
11247
11321
  }
11322
+ const freeForBuild = freeDiskBytes(root);
11323
+ if (freeForBuild !== null && freeForBuild < BUILD_MIN_FREE_BYTES) {
11324
+ results.ok = false;
11325
+ results.note = `Insufficient disk space (${gib(freeForBuild)}G free, need ~${gib(BUILD_MIN_FREE_BYTES)}G): skipped the build and tests rather than fill the disk mid-compile. This is an environment issue, not a code finding \u2014 report it as informational.`;
11326
+ return results;
11327
+ }
11248
11328
  const alsoBuild = [];
11249
11329
  let set = buildSetFor(affected, packages);
11250
11330
  const built = /* @__PURE__ */ new Set();
@@ -11419,6 +11499,12 @@ function writeSkillArgs(skillName, args) {
11419
11499
  );
11420
11500
  return null;
11421
11501
  }
11502
+ if (lstatSync3(path3, { throwIfNoEntry: false })?.isSymbolicLink()) {
11503
+ debugLogger3.warn(
11504
+ `Skill args file ${path3} is a symlink; refusing to write through it.`
11505
+ );
11506
+ return null;
11507
+ }
11422
11508
  const fd = openSync2(
11423
11509
  path3,
11424
11510
  constants.O_WRONLY | constants.O_CREAT | constants.O_TRUNC | constants.O_NOFOLLOW,
@@ -11791,12 +11877,16 @@ init_esbuild_shims();
11791
11877
  import { spawnSync as spawnSync3 } from "node:child_process";
11792
11878
  import {
11793
11879
  mkdirSync as mkdirSync16,
11880
+ readdirSync as readdirSync5,
11794
11881
  writeFileSync as writeFileSync16,
11795
11882
  readFileSync as readFileSync18,
11796
11883
  rmSync as rmSync6,
11797
11884
  lstatSync as lstatSync4,
11798
- existsSync as existsSync7
11885
+ existsSync as existsSync7,
11886
+ statSync as statSync5,
11887
+ symlinkSync
11799
11888
  } from "node:fs";
11889
+ import { createRequire } from "node:module";
11800
11890
  import { dirname as dirname13, join as join14, isAbsolute as isAbsolute3, sep as sep3 } from "node:path";
11801
11891
  var FIXTURE_DIR_RE = /(^|\/)(__fixtures__|__mocks__|__snapshots__|fixtures)\//;
11802
11892
  function planTestEfficacy(files, workspaceGlobs) {
@@ -11813,6 +11903,288 @@ function planTestEfficacy(files, workspaceGlobs) {
11813
11903
  };
11814
11904
  }
11815
11905
  __name(planTestEfficacy, "planTestEfficacy");
11906
+ var MAX_MUTANTS = 8;
11907
+ var PROBE_RUN_TIMEOUT_MS = 3e5;
11908
+ var TOTAL_BUDGET_MS = 54e4;
11909
+ var RUN_ESTIMATE_MARGIN_MS = 15e3;
11910
+ var SAFETY_VERB_RE = /\.(?:clear|delete|reset|abort|removeListener|unref)\(|=\s*\[\]\s*;$|=\s*new\s+(?:Map|Set|WeakMap|WeakSet)(?:<[^=;]*>)?\(\)\s*;$/;
11911
+ var MUTANT_SOURCE_RE = /\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/;
11912
+ var DECLARATION_FILE_RE = /\.d\.[cm]?ts$/;
11913
+ var NON_STATEMENT_START_RE = /^(?:const|let|var|function|class|interface|type|enum|import|export|return|throw|yield|if|for|while|switch|do|else|try|catch|finally|case|default|break|continue|async|public|private|protected|readonly|static)\b/;
11914
+ function skipTemplateOnLine(line, start) {
11915
+ let depth = 0;
11916
+ for (let i = start + 1; i < line.length; i++) {
11917
+ const ch = line[i];
11918
+ if (ch === "\\") {
11919
+ i++;
11920
+ } else if (depth === 0) {
11921
+ if (ch === "`") return i;
11922
+ if (ch === "$" && line[i + 1] === "{") {
11923
+ depth = 1;
11924
+ i++;
11925
+ }
11926
+ } else if (ch === "{") {
11927
+ depth++;
11928
+ } else if (ch === "}") {
11929
+ depth--;
11930
+ }
11931
+ }
11932
+ return -1;
11933
+ }
11934
+ __name(skipTemplateOnLine, "skipTemplateOnLine");
11935
+ function scanLineDelimiters(line) {
11936
+ let paren = 0;
11937
+ let bracket = 0;
11938
+ let brace = 0;
11939
+ for (let i = 0; i < line.length; i++) {
11940
+ const ch = line[i];
11941
+ if (ch === "`") {
11942
+ const close = skipTemplateOnLine(line, i);
11943
+ if (close < 0) return null;
11944
+ i = close;
11945
+ continue;
11946
+ }
11947
+ if (ch === '"' || ch === "'") {
11948
+ i++;
11949
+ while (i < line.length && line[i] !== ch) {
11950
+ if (line[i] === "\\") i++;
11951
+ i++;
11952
+ }
11953
+ if (i >= line.length) return null;
11954
+ continue;
11955
+ }
11956
+ if (ch === "/" && line[i + 1] === "/") break;
11957
+ if (ch === "/" && line[i + 1] === "*") {
11958
+ const close = line.indexOf("*/", i + 2);
11959
+ if (close < 0) return null;
11960
+ i = close + 1;
11961
+ continue;
11962
+ }
11963
+ if (ch === "(") paren++;
11964
+ else if (ch === ")") paren--;
11965
+ else if (ch === "[") bracket++;
11966
+ else if (ch === "]") bracket--;
11967
+ else if (ch === "{") brace++;
11968
+ else if (ch === "}") brace--;
11969
+ if (paren < 0 || bracket < 0 || brace < 0) return null;
11970
+ }
11971
+ return { paren, bracket, brace };
11972
+ }
11973
+ __name(scanLineDelimiters, "scanLineDelimiters");
11974
+ function scanFileLines(content) {
11975
+ const inLiteral = [];
11976
+ const codeLines = [];
11977
+ let state = "code";
11978
+ const templates = [];
11979
+ let buf = "";
11980
+ let lineStart = 0;
11981
+ let rawLine = false;
11982
+ const inTemplateOrComment = /* @__PURE__ */ __name(() => state !== "code" || templates.length > 0, "inTemplateOrComment");
11983
+ inLiteral.push(inTemplateOrComment());
11984
+ const endLine = /* @__PURE__ */ __name((i) => {
11985
+ codeLines.push(rawLine ? content.slice(lineStart, i).trim() : buf.trim());
11986
+ buf = "";
11987
+ rawLine = false;
11988
+ lineStart = i + 1;
11989
+ }, "endLine");
11990
+ for (let i = 0; i < content.length; i++) {
11991
+ const ch = content[i];
11992
+ if (ch === "\n") {
11993
+ endLine(i);
11994
+ inLiteral.push(inTemplateOrComment());
11995
+ continue;
11996
+ }
11997
+ if (templates.length > 0) {
11998
+ const top = templates.length - 1;
11999
+ if (ch === "\\" && content[i + 1] !== "\n") {
12000
+ i++;
12001
+ } else if (templates[top] < 0) {
12002
+ if (ch === "`") {
12003
+ templates.pop();
12004
+ if (templates.length === 0) buf += "`";
12005
+ } else if (ch === "$" && content[i + 1] === "{") {
12006
+ templates[top] = 0;
12007
+ i++;
12008
+ }
12009
+ } else if (ch === "`") {
12010
+ templates.push(-1);
12011
+ } else if (ch === "{") {
12012
+ templates[top]++;
12013
+ } else if (ch === "}") {
12014
+ if (templates[top] === 0) templates[top] = -1;
12015
+ else templates[top]--;
12016
+ }
12017
+ continue;
12018
+ }
12019
+ if (state === "comment") {
12020
+ if (ch === "*" && content[i + 1] === "/") {
12021
+ state = "code";
12022
+ i++;
12023
+ }
12024
+ continue;
12025
+ }
12026
+ if (ch === "`") {
12027
+ buf += "`";
12028
+ templates.push(-1);
12029
+ } else if (ch === "/" && content[i + 1] === "*") {
12030
+ state = "comment";
12031
+ i++;
12032
+ } else if (ch === "/" && content[i + 1] === "/") {
12033
+ while (i + 1 < content.length && content[i + 1] !== "\n") i++;
12034
+ } else if (ch === '"' || ch === "'") {
12035
+ let k = i + 1;
12036
+ while (k < content.length && content[k] !== ch && content[k] !== "\n") {
12037
+ if (content[k] === "\\" && content[k + 1] !== "\n") k++;
12038
+ k++;
12039
+ }
12040
+ if (k < content.length && content[k] === ch) {
12041
+ buf += ch + ch;
12042
+ i = k;
12043
+ } else {
12044
+ rawLine = true;
12045
+ i = k < content.length && content[k] === "\n" ? k - 1 : k;
12046
+ }
12047
+ } else {
12048
+ buf += ch;
12049
+ }
12050
+ }
12051
+ endLine(content.length);
12052
+ return {
12053
+ inLiteral,
12054
+ codeLines,
12055
+ endState: templates.length > 0 ? "template" : state
12056
+ };
12057
+ }
12058
+ __name(scanFileLines, "scanFileLines");
12059
+ function insideClassBody(codeLines, idx) {
12060
+ let depth = 0;
12061
+ for (let j = idx - 1; j >= 0; j--) {
12062
+ const code = codeLines[j];
12063
+ for (let i = code.length - 1; i >= 0; i--) {
12064
+ const ch = code[i];
12065
+ if (ch === "}") depth++;
12066
+ else if (ch === "{") {
12067
+ if (depth === 0) {
12068
+ if (/\bclass\b/.test(code.slice(0, i))) return true;
12069
+ for (let k = j - 1; k >= 0; k--) {
12070
+ const prev = codeLines[k];
12071
+ if (prev.includes(";")) break;
12072
+ const d = scanLineDelimiters(prev);
12073
+ if (!d || d.brace !== 0) break;
12074
+ if (/\bclass\b/.test(prev)) return true;
12075
+ }
12076
+ return false;
12077
+ }
12078
+ depth--;
12079
+ }
12080
+ }
12081
+ }
12082
+ return false;
12083
+ }
12084
+ __name(insideClassBody, "insideClassBody");
12085
+ function isRemovableStatement(lines2, codeLines, idx) {
12086
+ const t2 = (lines2[idx] ?? "").trim();
12087
+ if (!(codeLines[idx] ?? "").endsWith(";")) return false;
12088
+ if ((codeLines[idx] ?? "").slice(0, -1).includes(";")) return false;
12089
+ if (!/^(?:await\s+)?[A-Za-z_$]/.test(t2)) return false;
12090
+ if (NON_STATEMENT_START_RE.test(t2)) return false;
12091
+ if (insideClassBody(codeLines, idx)) return false;
12092
+ const depth = scanLineDelimiters(t2);
12093
+ if (!depth || depth.paren !== 0 || depth.bracket !== 0 || depth.brace !== 0) {
12094
+ return false;
12095
+ }
12096
+ let j = idx - 1;
12097
+ while (j >= 0 && codeLines[j] === "") j--;
12098
+ if (j < 0) return true;
12099
+ return /[;{}]$/.test(codeLines[j]);
12100
+ }
12101
+ __name(isRemovableStatement, "isRemovableStatement");
12102
+ function selectMutants(files, cap = MAX_MUTANTS) {
12103
+ const preferred = [];
12104
+ const rest = [];
12105
+ const derailed = [];
12106
+ for (const f of files) {
12107
+ const lines2 = f.content.split("\n");
12108
+ const { inLiteral, codeLines, endState } = scanFileLines(f.content);
12109
+ if (endState !== "code") {
12110
+ derailed.push(f.file);
12111
+ continue;
12112
+ }
12113
+ for (const n of [...f.addedLines].sort((a, b) => a - b)) {
12114
+ const raw = lines2[n - 1];
12115
+ if (raw === void 0) continue;
12116
+ const t2 = raw.trim();
12117
+ if (!SAFETY_VERB_RE.test(codeLines[n - 1] ?? "")) continue;
12118
+ if (inLiteral[n - 1]) continue;
12119
+ if (!isRemovableStatement(lines2, codeLines, n - 1)) continue;
12120
+ (f.hasNewTests ? preferred : rest).push({
12121
+ file: f.file,
12122
+ line: n,
12123
+ statement: t2
12124
+ });
12125
+ }
12126
+ }
12127
+ const eligible = [...preferred, ...rest];
12128
+ return {
12129
+ selected: eligible.slice(0, cap),
12130
+ skippedForCap: Math.max(0, eligible.length - cap),
12131
+ derailed
12132
+ };
12133
+ }
12134
+ __name(selectMutants, "selectMutants");
12135
+ function parseAddedLines(diffText) {
12136
+ const added = /* @__PURE__ */ new Map();
12137
+ let file = null;
12138
+ let inHunk = false;
12139
+ let newLine = 0;
12140
+ for (const line of diffText.split("\n")) {
12141
+ if (line.startsWith("diff --git ")) {
12142
+ inHunk = false;
12143
+ continue;
12144
+ }
12145
+ if (!inHunk && line.startsWith("+++ ")) {
12146
+ const p = line.slice(4).split(" ")[0];
12147
+ file = p === "/dev/null" ? null : p.replace(/^b\//, "");
12148
+ continue;
12149
+ }
12150
+ const m = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(line);
12151
+ if (m) {
12152
+ newLine = Number(m[1]);
12153
+ inHunk = true;
12154
+ continue;
12155
+ }
12156
+ if (!inHunk || !file) continue;
12157
+ if (line.startsWith("+")) {
12158
+ const list = added.get(file);
12159
+ if (list) list.push(newLine);
12160
+ else added.set(file, [newLine]);
12161
+ newLine++;
12162
+ } else if (!line.startsWith("-") && !line.startsWith("\\")) {
12163
+ newLine++;
12164
+ }
12165
+ }
12166
+ return added;
12167
+ }
12168
+ __name(parseAddedLines, "parseAddedLines");
12169
+ function hasCollocatedNewTest(file, testPaths) {
12170
+ const stem = file.replace(/\.[^./]+$/, "");
12171
+ return testPaths.some((t2) => {
12172
+ const tstem = t2.replace(/\.[^./]+$/, "");
12173
+ return tstem === `${stem}.test` || tstem === `${stem}.spec`;
12174
+ });
12175
+ }
12176
+ __name(hasCollocatedNewTest, "hasCollocatedNewTest");
12177
+ function classifyMutantRun(perFile) {
12178
+ if (perFile.some((r) => r.verdict === "gated")) return "killed";
12179
+ if (perFile.length === 0 || perFile.some((r) => r.verdict === "inconclusive"))
12180
+ return "inconclusive";
12181
+ return "survived";
12182
+ }
12183
+ __name(classifyMutantRun, "classifyMutantRun");
12184
+ function fitsAnotherMutantRun(remainingMs, estimatedRunMs) {
12185
+ return remainingMs >= estimatedRunMs;
12186
+ }
12187
+ __name(fitsAnotherMutantRun, "fitsAnotherMutantRun");
11816
12188
  function classifyProbeRun(exitCode, stdout, probes, stderr = "") {
11817
12189
  let parsed;
11818
12190
  const start = stdout.indexOf("{");
@@ -11833,9 +12205,12 @@ function classifyProbeRun(exitCode, stdout, probes, stderr = "") {
11833
12205
  }
11834
12206
  const byFile = parsed.testResults ?? [];
11835
12207
  return probes.map((file) => {
11836
- const result = byFile.find(
11837
- (r) => (r.name ?? "").endsWith(`/${file}`) || r.name === file
11838
- );
12208
+ const probe = process.platform === "win32" ? file.replace(/\\/g, "/").toLowerCase() : file;
12209
+ const result = byFile.find((r) => {
12210
+ const raw = r.name ?? "";
12211
+ const name = process.platform === "win32" ? raw.replace(/\\/g, "/").toLowerCase() : raw;
12212
+ return name.endsWith(`/${probe}`) || name === probe;
12213
+ });
11839
12214
  const assertions = result?.assertionResults ?? [];
11840
12215
  const failed = assertions.filter((a) => a.status === "failed").length;
11841
12216
  const passed = assertions.filter((a) => a.status === "passed").length;
@@ -11885,6 +12260,38 @@ function gitOut(cwd, ...args) {
11885
12260
  return (r.stdout ?? "").trim();
11886
12261
  }
11887
12262
  __name(gitOut, "gitOut");
12263
+ function findVitestBin(worktree) {
12264
+ const req = createRequire(join14(worktree, "noop.js"));
12265
+ let pkgPath;
12266
+ try {
12267
+ pkgPath = req.resolve("vitest/package.json");
12268
+ } catch (error) {
12269
+ if (error.code === "MODULE_NOT_FOUND") {
12270
+ throw new Error(`vitest not found searching up from ${worktree}`);
12271
+ }
12272
+ throw error;
12273
+ }
12274
+ const pkg = JSON.parse(readFileSync18(pkgPath, "utf8"));
12275
+ const bin = pkg.bin?.vitest;
12276
+ if (!bin) {
12277
+ throw new Error(`vitest package at ${pkgPath} declares no "vitest" bin`);
12278
+ }
12279
+ return join14(dirname13(pkgPath), bin);
12280
+ }
12281
+ __name(findVitestBin, "findVitestBin");
12282
+ function gitCapture(cwd, ...args) {
12283
+ const r = spawnSync3("git", args, {
12284
+ cwd,
12285
+ encoding: "utf8",
12286
+ maxBuffer: 64 * 1024 * 1024
12287
+ });
12288
+ if (r.error) throw r.error;
12289
+ if (r.status !== 0) {
12290
+ throw new Error(`git ${args.join(" ")} failed: ${r.stderr ?? ""}`);
12291
+ }
12292
+ return r.stdout ?? "";
12293
+ }
12294
+ __name(gitCapture, "gitCapture");
11888
12295
  function existsAtRev(cwd, rev, path3) {
11889
12296
  const r = spawnSync3("git", ["cat-file", "-e", `${rev}:${path3}`], { cwd });
11890
12297
  if (r.error) throw r.error;
@@ -11931,7 +12338,130 @@ function probeCleanupFailureDetail(probeTree, removeError, sweepStderr) {
11931
12338
  return `could not remove probe worktree ${probeTree}${why ? `: ${why}` : ""}`;
11932
12339
  }
11933
12340
  __name(probeCleanupFailureDetail, "probeCleanupFailureDetail");
12341
+ function exposeDependencies(probeTree, dependencyRoot) {
12342
+ const done = { linked: 0, failed: 0 };
12343
+ if (probeTree === dependencyRoot) return done;
12344
+ const source = join14(dependencyRoot, "node_modules");
12345
+ const target = join14(probeTree, "node_modules");
12346
+ if (!existsSync7(source) || existsSync7(target)) return done;
12347
+ mkdirSync16(target);
12348
+ const linkType = process.platform === "win32" ? "junction" : "dir";
12349
+ for (const entry of readdirSync5(source, { withFileTypes: true })) {
12350
+ if (entry.name === ".vite" || entry.name === ".vite-temp") continue;
12351
+ const sourceEntry = join14(source, entry.name);
12352
+ const targetEntry = join14(target, entry.name);
12353
+ let sourceStats;
12354
+ try {
12355
+ sourceStats = lstatSync4(sourceEntry);
12356
+ } catch {
12357
+ done.failed++;
12358
+ continue;
12359
+ }
12360
+ if (sourceStats.isSymbolicLink()) {
12361
+ try {
12362
+ if (!statSync5(sourceEntry).isDirectory()) continue;
12363
+ } catch {
12364
+ continue;
12365
+ }
12366
+ } else if (!sourceStats.isDirectory()) {
12367
+ continue;
12368
+ }
12369
+ if (entry.name.startsWith("@")) {
12370
+ let pkgs;
12371
+ try {
12372
+ mkdirSync16(targetEntry);
12373
+ pkgs = readdirSync5(sourceEntry);
12374
+ } catch {
12375
+ done.failed++;
12376
+ continue;
12377
+ }
12378
+ for (const pkg of pkgs) {
12379
+ try {
12380
+ symlinkSync(join14(sourceEntry, pkg), join14(targetEntry, pkg), linkType);
12381
+ done.linked++;
12382
+ } catch {
12383
+ done.failed++;
12384
+ }
12385
+ }
12386
+ } else {
12387
+ try {
12388
+ symlinkSync(sourceEntry, targetEntry, linkType);
12389
+ done.linked++;
12390
+ } catch {
12391
+ done.failed++;
12392
+ }
12393
+ }
12394
+ }
12395
+ return done;
12396
+ }
12397
+ __name(exposeDependencies, "exposeDependencies");
12398
+ function runProbeSuite(probeTree, probes, deadlineAt, now = Date.now, dependencyRoot = probeTree) {
12399
+ const started = now();
12400
+ const timeout = deadlineAt !== void 0 ? Math.max(1, Math.min(PROBE_RUN_TIMEOUT_MS, deadlineAt - started)) : PROBE_RUN_TIMEOUT_MS;
12401
+ const exposed = exposeDependencies(probeTree, dependencyRoot);
12402
+ const r = spawnSync3(
12403
+ process.execPath,
12404
+ [findVitestBin(dependencyRoot), "run", "--reporter=json", ...probes],
12405
+ {
12406
+ cwd: probeTree,
12407
+ encoding: "utf8",
12408
+ timeout,
12409
+ // Vitest's JSON reporter on a large suite easily exceeds spawnSync's
12410
+ // 1 MiB default stdout buffer, which returns ENOBUFS and turns every
12411
+ // probe `inconclusive`. Match the 64 MiB ceiling the gh wrapper uses.
12412
+ maxBuffer: 64 * 1024 * 1024
12413
+ }
12414
+ );
12415
+ if (r.error) throw r.error;
12416
+ if (r.signal) {
12417
+ throw new Error(
12418
+ `runner killed by ${r.signal}${r.signal === "SIGTERM" ? ` (probe timed out after ${Math.round(timeout / 1e3)}s)` : ""}`
12419
+ );
12420
+ }
12421
+ return {
12422
+ perFile: classifyProbeRun(
12423
+ r.status ?? 1,
12424
+ `${r.stdout ?? ""}`,
12425
+ probes,
12426
+ `${r.stderr ?? ""}`
12427
+ ),
12428
+ ms: now() - started,
12429
+ exposed
12430
+ };
12431
+ }
12432
+ __name(runProbeSuite, "runProbeSuite");
12433
+ function runOneMutant(probeTree, mutant, probes, deadlineAt, now = Date.now, dependencyRoot = probeTree) {
12434
+ const abs = join14(probeTree, mutant.file);
12435
+ const original = readFileSync18(abs, "utf8");
12436
+ const lines2 = original.split("\n");
12437
+ if ((lines2[mutant.line - 1] ?? "").trim() !== mutant.statement) {
12438
+ return {
12439
+ ...mutant,
12440
+ verdict: "inconclusive",
12441
+ detail: "the probe tree does not match the selected statement at this line \u2014 nothing was mutated"
12442
+ };
12443
+ }
12444
+ lines2.splice(mutant.line - 1, 1);
12445
+ try {
12446
+ writeFileSync16(abs, lines2.join("\n"), "utf8");
12447
+ const { perFile } = runProbeSuite(
12448
+ probeTree,
12449
+ probes,
12450
+ deadlineAt,
12451
+ now,
12452
+ dependencyRoot
12453
+ );
12454
+ const verdict = classifyMutantRun(perFile);
12455
+ const detail = verdict === "killed" ? "the suite went red with this statement deleted \u2014 a test catches its removal" : verdict === "survived" ? "every affected test still PASSED with this statement deleted \u2014 no test fails when it is removed" : "the mutated tree produced no clean verdict (likely a compile or import error) \u2014 not evidence either way";
12456
+ return { ...mutant, verdict, detail };
12457
+ } finally {
12458
+ writeFileSync16(abs, original, "utf8");
12459
+ }
12460
+ }
12461
+ __name(runOneMutant, "runOneMutant");
11934
12462
  async function runTestEfficacy(args) {
12463
+ const now = args.now ?? Date.now;
12464
+ const startedAt = now();
11935
12465
  const { report, worktree, base, out } = args;
11936
12466
  const plan = JSON.parse(readFileSync18(report, "utf8"));
11937
12467
  const rootPkg = JSON.parse(
@@ -11953,8 +12483,69 @@ async function runTestEfficacy(args) {
11953
12483
  }
11954
12484
  const results = [];
11955
12485
  let cleanupFailure;
12486
+ const mutantResults = [];
12487
+ let mutantsSkippedForBudget = 0;
12488
+ let mutantsSkippedForCap = 0;
12489
+ let mutantsSkippedForBaseline = 0;
12490
+ let mutantsNote;
12491
+ const noteMutants = /* @__PURE__ */ __name((note) => {
12492
+ mutantsNote = mutantsNote ? `${mutantsNote}; ${note}` : note;
12493
+ }, "noteMutants");
12494
+ const noteDependencyFarm = /* @__PURE__ */ __name((exposed) => {
12495
+ if (exposed.failed > 0) {
12496
+ noteMutants(
12497
+ `dependency farm incomplete: exposed ${exposed.linked}/${exposed.linked + exposed.failed} dependencies into the probe tree (${exposed.failed} failed to link) \u2014 probe results may not be evidence`
12498
+ );
12499
+ }
12500
+ }, "noteDependencyFarm");
11956
12501
  if (probes.length > 0 && revert.length > 0) {
11957
12502
  const headSha = gitOut(worktree, "rev-parse", "HEAD");
12503
+ let candidates = [];
12504
+ try {
12505
+ const mutantFiles = revert.filter(
12506
+ (p) => MUTANT_SOURCE_RE.test(p) && !DECLARATION_FILE_RE.test(p)
12507
+ );
12508
+ if (mutantFiles.length > 0) {
12509
+ const added = parseAddedLines(
12510
+ gitCapture(
12511
+ worktree,
12512
+ "-c",
12513
+ "core.quotePath=false",
12514
+ "diff",
12515
+ "--unified=0",
12516
+ "--no-color",
12517
+ "--src-prefix=a/",
12518
+ "--dst-prefix=b/",
12519
+ "--no-ext-diff",
12520
+ "--no-textconv",
12521
+ base,
12522
+ headSha,
12523
+ "--",
12524
+ ...mutantFiles
12525
+ )
12526
+ );
12527
+ const selection = selectMutants(
12528
+ mutantFiles.filter((p) => (added.get(p) ?? []).length > 0).map((p) => ({
12529
+ file: p,
12530
+ content: gitCapture(worktree, "show", `${headSha}:${p}`),
12531
+ addedLines: added.get(p) ?? [],
12532
+ hasNewTests: hasCollocatedNewTest(p, probes)
12533
+ }))
12534
+ );
12535
+ candidates = selection.selected;
12536
+ mutantsSkippedForCap = selection.skippedForCap;
12537
+ if (selection.derailed.length > 0) {
12538
+ noteMutants(
12539
+ `mutant selection dropped ${selection.derailed.length} file(s) whose literal scan derailed (${selection.derailed.join(", ")}) \u2014 a regex literal holding a quote or backtick can do this; their candidates were not probed`
12540
+ );
12541
+ }
12542
+ }
12543
+ } catch (e) {
12544
+ noteMutants(
12545
+ `mutant selection failed: ${e instanceof Error ? e.message : String(e)} \u2014 no mutants were run`
12546
+ );
12547
+ candidates = [];
12548
+ }
11958
12549
  const probeTree = probeWorktreePath(worktree);
11959
12550
  let created = false;
11960
12551
  let sweep;
@@ -11967,6 +12558,57 @@ async function runTestEfficacy(args) {
11967
12558
  for (const file of probes) {
11968
12559
  results.push({ file, verdict: "inconclusive", detail });
11969
12560
  }
12561
+ for (const c of candidates) {
12562
+ mutantResults.push({ ...c, verdict: "inconclusive", detail });
12563
+ }
12564
+ }
12565
+ if (created && candidates.length > 0) {
12566
+ try {
12567
+ const mutantDeadline = startedAt + TOTAL_BUDGET_MS - PROBE_RUN_TIMEOUT_MS;
12568
+ const baseline = runProbeSuite(
12569
+ probeTree,
12570
+ probes,
12571
+ mutantDeadline,
12572
+ now,
12573
+ worktree
12574
+ );
12575
+ noteDependencyFarm(baseline.exposed);
12576
+ const greenProbes = baseline.perFile.filter((r) => r.verdict === "inert").map((r) => r.file);
12577
+ if (greenProbes.length === 0) {
12578
+ mutantsSkippedForBaseline = candidates.length;
12579
+ noteMutants(
12580
+ "mutants not run: no probe file was green in the unmutated baseline (every file was red or collected nothing), so a red mutant run would prove nothing"
12581
+ );
12582
+ } else {
12583
+ const estimatedRunMs = baseline.ms + RUN_ESTIMATE_MARGIN_MS;
12584
+ for (const c of candidates) {
12585
+ const remaining = mutantDeadline - now();
12586
+ if (!fitsAnotherMutantRun(remaining, estimatedRunMs)) {
12587
+ mutantsSkippedForBudget = candidates.length - mutantResults.length;
12588
+ break;
12589
+ }
12590
+ mutantResults.push(
12591
+ runOneMutant(
12592
+ probeTree,
12593
+ c,
12594
+ greenProbes,
12595
+ mutantDeadline,
12596
+ now,
12597
+ worktree
12598
+ )
12599
+ );
12600
+ }
12601
+ }
12602
+ } catch (e) {
12603
+ const detail = `mutation probe could not run: ${e instanceof Error ? e.message : String(e)}`;
12604
+ for (const c of candidates.slice(mutantResults.length)) {
12605
+ mutantResults.push({
12606
+ ...c,
12607
+ verdict: "inconclusive",
12608
+ detail
12609
+ });
12610
+ }
12611
+ }
11970
12612
  }
11971
12613
  if (created) {
11972
12614
  try {
@@ -11979,33 +12621,15 @@ async function runTestEfficacy(args) {
11979
12621
  git2(probeTree, "checkout", base, "--", ...modified);
11980
12622
  }
11981
12623
  for (const p of added) safeRmWithin(probeTree, p);
11982
- const r = spawnSync3(
11983
- "npx",
11984
- ["vitest", "run", "--reporter=json", ...probes],
11985
- {
11986
- cwd: probeTree,
11987
- encoding: "utf8",
11988
- timeout: 3e5,
11989
- // Vitest's JSON reporter on a large suite easily exceeds spawnSync's
11990
- // 1 MiB default stdout buffer, which returns ENOBUFS and turns every
11991
- // probe `inconclusive`. Match the 64 MiB ceiling the gh wrapper uses.
11992
- maxBuffer: 64 * 1024 * 1024
11993
- }
11994
- );
11995
- if (r.error) throw r.error;
11996
- if (r.signal) {
11997
- throw new Error(
11998
- `runner killed by ${r.signal}${r.signal === "SIGTERM" ? " (probe timed out after 300s)" : ""}`
11999
- );
12000
- }
12001
- results.push(
12002
- ...classifyProbeRun(
12003
- r.status ?? 1,
12004
- `${r.stdout ?? ""}`,
12005
- probes,
12006
- `${r.stderr ?? ""}`
12007
- )
12624
+ const revertRun = runProbeSuite(
12625
+ probeTree,
12626
+ probes,
12627
+ startedAt + TOTAL_BUDGET_MS,
12628
+ now,
12629
+ worktree
12008
12630
  );
12631
+ noteDependencyFarm(revertRun.exposed);
12632
+ results.push(...revertRun.perFile);
12009
12633
  } catch (e) {
12010
12634
  const detail = `probe could not run: ${e instanceof Error ? e.message : String(e)}`;
12011
12635
  results.push(
@@ -12043,23 +12667,57 @@ async function runTestEfficacy(args) {
12043
12667
  file: r.file,
12044
12668
  kind: "inert",
12045
12669
  message: `\`${r.file}\`: ${r.detail}. It passes whether or not the change is present, so it cannot catch a regression in it.`
12670
+ })),
12671
+ ...mutantResults.filter((m) => m.verdict === "survived").map((m) => ({
12672
+ file: m.file,
12673
+ kind: "mutant-survived",
12674
+ message: `\`${m.file}:${m.line}\`: deleting the added safety statement \`${m.statement}\` leaves every affected test green. No test in this diff fails when it is removed \u2014 confirm an existing test covers it, or add one, so a regression that drops or skips this statement is caught.`
12046
12675
  }))
12047
12676
  ];
12677
+ const count = /* @__PURE__ */ __name((v) => mutantResults.filter((m) => m.verdict === v).length, "count");
12048
12678
  const result = {
12049
12679
  unreachable,
12050
12680
  probed: results,
12051
12681
  inconclusive: results.filter((r) => r.verdict === "inconclusive"),
12682
+ mutants: {
12683
+ probed: mutantResults,
12684
+ killed: count("killed"),
12685
+ survived: count("survived"),
12686
+ inconclusive: count("inconclusive"),
12687
+ skippedForBudget: mutantsSkippedForBudget,
12688
+ skippedForCap: mutantsSkippedForCap,
12689
+ skippedForBaseline: mutantsSkippedForBaseline,
12690
+ ...mutantsNote ? { note: mutantsNote } : {}
12691
+ },
12052
12692
  findings,
12053
12693
  cleanupFailure
12054
12694
  };
12055
12695
  mkdirSync16(dirname13(out), { recursive: true });
12056
12696
  writeFileSync16(out, JSON.stringify(result, null, 2), "utf8");
12057
12697
  writeStdoutLine(
12058
- `Wrote test-efficacy report to ${out} (${unreachable.length} unreachable, ${results.length} probed, ${findings.length} finding(s))`
12698
+ `Wrote test-efficacy report to ${out} (${unreachable.length} unreachable, ${results.length} probed, ${mutantResults.length} mutant(s), ${findings.length} finding(s))`
12059
12699
  );
12060
12700
  for (const f of findings) {
12061
12701
  writeStdoutLine(` [test] ${f.kind}: ${f.file}`);
12062
12702
  }
12703
+ if (mutantsSkippedForCap > 0) {
12704
+ writeStdoutLine(
12705
+ ` ${mutantsSkippedForCap} mutant(s) skipped: more candidates than the cap of ${MAX_MUTANTS}`
12706
+ );
12707
+ }
12708
+ if (mutantsSkippedForBaseline > 0) {
12709
+ writeStdoutLine(
12710
+ ` ${mutantsSkippedForBaseline} mutant(s) skipped: no probe file was green in the unmutated baseline`
12711
+ );
12712
+ }
12713
+ if (mutantsSkippedForBudget > 0) {
12714
+ writeStdoutLine(
12715
+ ` ${mutantsSkippedForBudget} mutant(s) skipped: the remaining budget cannot fit another suite run`
12716
+ );
12717
+ }
12718
+ if (mutantsNote) {
12719
+ writeStdoutLine(` ${mutantsNote}`);
12720
+ }
12063
12721
  if (cleanupFailure) {
12064
12722
  writeStderrLine(`WARNING: ${cleanupFailure}`);
12065
12723
  }
@@ -12067,7 +12725,7 @@ async function runTestEfficacy(args) {
12067
12725
  __name(runTestEfficacy, "runTestEfficacy");
12068
12726
  var testEfficacyCommand = {
12069
12727
  command: "test-efficacy <report>",
12070
- describe: "Check whether the diff's new tests actually gate its new behaviour (unreachable + revert probe)",
12728
+ describe: "Check whether the diff's new tests actually gate its new behaviour (unreachable + revert probe + statement-deletion mutants)",
12071
12729
  builder: /* @__PURE__ */ __name((yargs) => yargs.positional("report", {
12072
12730
  type: "string",
12073
12731
  demandOption: true,
@@ -12093,7 +12751,7 @@ var testEfficacyCommand = {
12093
12751
  // packages/cli/src/commands/review/cleanup.ts
12094
12752
  init_esbuild_shims();
12095
12753
  import { execFileSync as execFileSync5 } from "node:child_process";
12096
- import { existsSync as existsSync8, readFileSync as readFileSync19, readdirSync as readdirSync5, rmSync as rmSync7 } from "node:fs";
12754
+ import { existsSync as existsSync8, readFileSync as readFileSync19, readdirSync as readdirSync6, rmSync as rmSync7 } from "node:fs";
12097
12755
  import { join as join15 } from "node:path";
12098
12756
  var AUTOMATION_MARKER = "<!-- qwen-";
12099
12757
  function isAutomationComment(body) {
@@ -12291,7 +12949,7 @@ function runCleanup(target) {
12291
12949
  const prefix = tmpPrefix(target);
12292
12950
  let tmpEntries = [];
12293
12951
  try {
12294
- tmpEntries = existsSync8(REVIEW_TMP_DIR) ? readdirSync5(REVIEW_TMP_DIR) : [];
12952
+ tmpEntries = existsSync8(REVIEW_TMP_DIR) ? readdirSync6(REVIEW_TMP_DIR) : [];
12295
12953
  } catch (err) {
12296
12954
  writeStderrLine(
12297
12955
  `Failed to read ${REVIEW_TMP_DIR}: ${err.message}`
@@ -12330,13 +12988,285 @@ var cleanupCommand = {
12330
12988
  }, "handler")
12331
12989
  };
12332
12990
 
12991
+ // packages/cli/src/commands/review/run.ts
12992
+ init_esbuild_shims();
12993
+ import { spawn, execFileSync as execFileSync6 } from "node:child_process";
12994
+ import { readdirSync as readdirSync7, readFileSync as readFileSync20, statSync as statSync6 } from "node:fs";
12995
+ import { join as join16, resolve as resolve13 } from "node:path";
12996
+ var COMPOSED_PATTERN = /^qwen-review-.*composed\.json$/;
12997
+ var COMPOSED_POLL_MS = 250;
12998
+ var SIGNAL_EXIT_CODES = {
12999
+ SIGHUP: 129,
13000
+ SIGINT: 130,
13001
+ SIGTERM: 143
13002
+ };
13003
+ var PARENT_SIGNALS = Object.keys(SIGNAL_EXIT_CODES);
13004
+ function buildReviewPrompt(args) {
13005
+ const parts = ["/review"];
13006
+ if (args.target) {
13007
+ if (/\s/.test(args.target) || args.target.startsWith("-") || /['"]/.test(args.target)) {
13008
+ throw new Error(
13009
+ `Invalid review target ${JSON.stringify(args.target)}: expected a single PR number, PR URL, or file path`
13010
+ );
13011
+ }
13012
+ parts.push(args.target);
13013
+ }
13014
+ if (args.effort) parts.push(`--effort ${args.effort}`);
13015
+ if (args.comment) parts.push("--comment");
13016
+ return parts.join(" ");
13017
+ }
13018
+ __name(buildReviewPrompt, "buildReviewPrompt");
13019
+ function newestArtifactSince(dir, pattern, startMs) {
13020
+ let best = null;
13021
+ let names;
13022
+ try {
13023
+ names = readdirSync7(dir);
13024
+ } catch {
13025
+ return null;
13026
+ }
13027
+ for (const name of names) {
13028
+ if (!pattern.test(name)) continue;
13029
+ const path3 = join16(dir, name);
13030
+ let mtime;
13031
+ try {
13032
+ mtime = statSync6(path3).mtimeMs;
13033
+ } catch {
13034
+ continue;
13035
+ }
13036
+ if (mtime < startMs) continue;
13037
+ if (!best || mtime > best.mtime) best = { path: path3, mtime };
13038
+ }
13039
+ return best ? best.path : null;
13040
+ }
13041
+ __name(newestArtifactSince, "newestArtifactSince");
13042
+ function exitCodeFor(completed, event, failOn) {
13043
+ if (!completed) return 1;
13044
+ if (failOn === "request-changes" && event === "REQUEST_CHANGES") return 3;
13045
+ return 0;
13046
+ }
13047
+ __name(exitCodeFor, "exitCodeFor");
13048
+ function readComposed(path3) {
13049
+ try {
13050
+ const parsed = JSON.parse(readFileSync20(path3, "utf8"));
13051
+ return typeof parsed.event === "string" ? parsed : null;
13052
+ } catch {
13053
+ return null;
13054
+ }
13055
+ }
13056
+ __name(readComposed, "readComposed");
13057
+ function killProcessGroup(pid, signal) {
13058
+ if (process.platform === "win32") {
13059
+ try {
13060
+ execFileSync6("taskkill", ["/pid", String(pid), "/T", "/F"], {
13061
+ stdio: "ignore"
13062
+ });
13063
+ } catch {
13064
+ }
13065
+ return;
13066
+ }
13067
+ try {
13068
+ process.kill(-pid, signal);
13069
+ } catch {
13070
+ }
13071
+ }
13072
+ __name(killProcessGroup, "killProcessGroup");
13073
+ async function runReview(args) {
13074
+ const startMs = Date.now();
13075
+ const prompt = buildReviewPrompt(args);
13076
+ const cutoffMs = startMs - 2e3;
13077
+ const child = spawn(
13078
+ process.execPath,
13079
+ [
13080
+ "--expose-gc",
13081
+ process.argv[1],
13082
+ "--prompt",
13083
+ prompt,
13084
+ "--approval-mode",
13085
+ args.approvalMode
13086
+ ],
13087
+ {
13088
+ // stdin CLOSED, not inherited: piped input would be prepended to the
13089
+ // prompt and the leading `/` would no longer be the first character —
13090
+ // the slash command would reach the model as plain text.
13091
+ stdio: ["ignore", "pipe", "pipe"],
13092
+ // The CLI relaunches itself in a child (for --max-old-space-size), so
13093
+ // the pid we spawn is a wrapper whose grandchild is the real review.
13094
+ // A new process group lets the timeout kill reach both.
13095
+ detached: true
13096
+ }
13097
+ );
13098
+ if (!args.quiet) {
13099
+ const writeProgress = /* @__PURE__ */ __name((chunk) => {
13100
+ try {
13101
+ process.stderr.write(chunk);
13102
+ } catch {
13103
+ }
13104
+ }, "writeProgress");
13105
+ child.stdout?.on("data", writeProgress);
13106
+ child.stderr?.on("data", writeProgress);
13107
+ } else {
13108
+ child.stdout?.resume();
13109
+ child.stderr?.resume();
13110
+ }
13111
+ let capturedPath = null;
13112
+ let capturedVerdict = null;
13113
+ const captureTimer = setInterval(() => {
13114
+ if (capturedVerdict !== null) return;
13115
+ const path3 = newestArtifactSince(
13116
+ REVIEW_TMP_DIR,
13117
+ COMPOSED_PATTERN,
13118
+ cutoffMs
13119
+ );
13120
+ if (path3 === null) return;
13121
+ const verdict = readComposed(path3);
13122
+ if (verdict !== null) {
13123
+ capturedPath = path3;
13124
+ capturedVerdict = verdict;
13125
+ }
13126
+ }, COMPOSED_POLL_MS);
13127
+ let timedOut = false;
13128
+ const timeoutMs = args.timeoutMinutes * 6e4;
13129
+ const timer = setTimeout(() => {
13130
+ timedOut = true;
13131
+ writeStderrLineSafe(
13132
+ `review run: timeout after ${args.timeoutMinutes} minutes \u2014 terminating the review`
13133
+ );
13134
+ const pid = child.pid;
13135
+ if (pid !== void 0) {
13136
+ killProcessGroup(pid, "SIGTERM");
13137
+ setTimeout(() => killProcessGroup(pid, "SIGKILL"), 1e4).unref();
13138
+ }
13139
+ }, timeoutMs);
13140
+ const onParentSignal = /* @__PURE__ */ __name((signal) => {
13141
+ clearTimeout(timer);
13142
+ clearInterval(captureTimer);
13143
+ const pid = child.pid;
13144
+ if (pid !== void 0) {
13145
+ killProcessGroup(pid, "SIGTERM");
13146
+ }
13147
+ process.exit(SIGNAL_EXIT_CODES[signal] ?? 1);
13148
+ }, "onParentSignal");
13149
+ for (const signal of PARENT_SIGNALS) process.on(signal, onParentSignal);
13150
+ const childOutcome = await new Promise((resolvePromise) => {
13151
+ child.on("close", (code, signal) => resolvePromise({ code, signal }));
13152
+ child.on("error", (err) => {
13153
+ writeStderrLineSafe(
13154
+ `review run: failed to launch the CLI: ${err.message}`
13155
+ );
13156
+ resolvePromise({ code: null, signal: null });
13157
+ });
13158
+ });
13159
+ const childExitCode = childOutcome.code;
13160
+ const childSignal = childOutcome.signal;
13161
+ clearTimeout(timer);
13162
+ clearInterval(captureTimer);
13163
+ for (const signal of PARENT_SIGNALS) process.off(signal, onParentSignal);
13164
+ let composedPath = capturedPath;
13165
+ let composed = capturedVerdict;
13166
+ if (composed === null) {
13167
+ composedPath = newestArtifactSince(
13168
+ REVIEW_TMP_DIR,
13169
+ COMPOSED_PATTERN,
13170
+ cutoffMs
13171
+ );
13172
+ composed = composedPath ? readComposed(composedPath) : null;
13173
+ }
13174
+ const reportPath = newestArtifactSince(REVIEWS_DIR, /\.md$/, cutoffMs);
13175
+ const completed = composed !== null;
13176
+ const result = {
13177
+ completed,
13178
+ event: composed?.event ?? null,
13179
+ verdictLine: composed?.verdictLine ?? null,
13180
+ baseEvent: composed?.baseEvent ?? null,
13181
+ cappedBy: composed?.cappedBy ?? [],
13182
+ downgraded: composed?.downgraded ?? false,
13183
+ downgradedFrom: composed?.downgradedFrom ?? null,
13184
+ remediation: composed?.remediation ?? [],
13185
+ composedPath: composedPath ? resolve13(composedPath) : null,
13186
+ reportPath: reportPath ? resolve13(reportPath) : null,
13187
+ childExitCode,
13188
+ childSignal,
13189
+ timedOut,
13190
+ durationMs: Date.now() - startMs
13191
+ };
13192
+ process.exitCode = exitCodeFor(completed, result.event, args.failOn);
13193
+ try {
13194
+ if (args.json) {
13195
+ writeStdoutLine(JSON.stringify(result, null, 2));
13196
+ } else if (completed) {
13197
+ writeStdoutLine(result.verdictLine ?? `Event: ${result.event}`);
13198
+ if (result.reportPath) writeStdoutLine(`Report: ${result.reportPath}`);
13199
+ } else {
13200
+ const detail = composedPath !== null ? `a composed verdict was found at ${resolve13(composedPath)} but could not be parsed` : "no composed verdict was produced";
13201
+ writeStdoutLine(
13202
+ timedOut ? "Review did not complete: timed out." : `Review did not complete: ${detail}${childExitCode !== null ? ` (CLI exit ${childExitCode})` : ""}${childSignal !== null ? ` (killed by ${childSignal})` : ""}.`
13203
+ );
13204
+ }
13205
+ } catch {
13206
+ }
13207
+ }
13208
+ __name(runReview, "runReview");
13209
+ var runCommand = {
13210
+ command: "run [target]",
13211
+ describe: "Run a full /review non-interactively and print the verdict (machine-readable with --json)",
13212
+ builder: /* @__PURE__ */ __name((yargs) => yargs.positional("target", {
13213
+ type: "string",
13214
+ describe: "What to review: a PR number, a PR URL, or a file path; omit to review the local working tree"
13215
+ }).option("effort", {
13216
+ type: "string",
13217
+ choices: [...EFFORT_LEVELS],
13218
+ describe: "The review effort. Defaults to the skill default for the target (high for a PR, medium locally)."
13219
+ }).option("comment", {
13220
+ type: "boolean",
13221
+ default: false,
13222
+ describe: "Authorise posting the review to GitHub (PR targets only) \u2014 same meaning as `/review <pr> --comment`"
13223
+ }).option("json", {
13224
+ type: "boolean",
13225
+ default: false,
13226
+ describe: "Print the full result as JSON on stdout"
13227
+ }).option("fail-on", {
13228
+ type: "string",
13229
+ choices: ["none", "request-changes"],
13230
+ default: "none",
13231
+ describe: "Exit 3 when the review completes with this outcome \u2014 lets CI gate on the verdict without parsing output"
13232
+ }).option("timeout-minutes", {
13233
+ type: "number",
13234
+ default: 120,
13235
+ describe: "Terminate the review after this long without a verdict (exit 1)"
13236
+ }).option("approval-mode", {
13237
+ type: "string",
13238
+ default: "yolo",
13239
+ choices: ["plan", "default", "auto-edit", "auto", "yolo"],
13240
+ describe: "Approval mode for the child CLI. The default is yolo: headless runs cannot answer confirmation prompts, and anything still unapproved would be auto-denied mid-review."
13241
+ }).option("quiet", {
13242
+ type: "boolean",
13243
+ default: false,
13244
+ describe: "Suppress the child CLI progress stream on stderr"
13245
+ }), "builder"),
13246
+ handler: /* @__PURE__ */ __name(async (argv) => {
13247
+ await runReview({
13248
+ target: argv["target"],
13249
+ effort: argv["effort"],
13250
+ comment: Boolean(argv["comment"]),
13251
+ json: Boolean(argv["json"]),
13252
+ failOn: argv["fail-on"] ?? "none",
13253
+ // `|| 120` would treat an explicit `--timeout-minutes 0` as falsy and
13254
+ // silently substitute the default; decide default-vs-value by finiteness
13255
+ // so 0 still reaches the 1-minute floor.
13256
+ timeoutMinutes: Number.isFinite(Number(argv["timeout-minutes"])) ? Math.max(1, Number(argv["timeout-minutes"])) : 120,
13257
+ approvalMode: String(argv["approval-mode"] ?? "yolo"),
13258
+ quiet: Boolean(argv["quiet"])
13259
+ });
13260
+ }, "handler")
13261
+ };
13262
+
12333
13263
  // packages/cli/src/commands/review.ts
12334
13264
  var reviewCommand = {
12335
13265
  command: "review",
12336
- describe: "Internal helpers used by the /review skill (PR worktree setup, context fetch, rules loading, presubmit checks, cleanup)",
12337
- builder: /* @__PURE__ */ __name((yargs) => yargs.command(parseArgsCommand).command(fetchPrCommand).command(captureLocalCommand).command(planDiffCommand).command(prContextCommand).command(commentStatusCommand).command(loadRulesCommand).command(agentPromptCommand).command(buildTestCommand).command(scriptLintCommand).command(resolveAnchorsCommand).command(checkCoverageCommand).command(presubmitCommand).command(testEfficacyCommand).command(composeReviewCommand).command(submitCommand).command(cleanupCommand).demandCommand(
13266
+ describe: "Run a review non-interactively (`run`), plus the internal helpers used by the /review skill (PR worktree setup, context fetch, rules loading, presubmit checks, cleanup)",
13267
+ builder: /* @__PURE__ */ __name((yargs) => yargs.command(runCommand).command(parseArgsCommand).command(fetchPrCommand).command(captureLocalCommand).command(planDiffCommand).command(prContextCommand).command(commentStatusCommand).command(loadRulesCommand).command(agentPromptCommand).command(buildTestCommand).command(scriptLintCommand).command(resolveAnchorsCommand).command(checkCoverageCommand).command(presubmitCommand).command(testEfficacyCommand).command(composeReviewCommand).command(submitCommand).command(cleanupCommand).demandCommand(
12338
13268
  1,
12339
- "Specify a subcommand: parse-args, fetch-pr, capture-local, plan-diff, pr-context, comment-status, load-rules, agent-prompt, build-test, script-lint, resolve-anchors, check-coverage, presubmit, test-efficacy, compose-review, submit, or cleanup."
13269
+ "Specify a subcommand: run, parse-args, fetch-pr, capture-local, plan-diff, pr-context, comment-status, load-rules, agent-prompt, build-test, script-lint, resolve-anchors, check-coverage, presubmit, test-efficacy, compose-review, submit, or cleanup."
12340
13270
  ).version(false), "builder"),
12341
13271
  handler: /* @__PURE__ */ __name(() => {
12342
13272
  }, "handler")
@@ -12536,10 +13466,10 @@ var updateCommand3 = {
12536
13466
  stdioHelpers,
12537
13467
  { updateEventEmitter }
12538
13468
  ] = await Promise.all([
12539
- import("./settings-DJDXFDZ3.js"),
12540
- import("./updateCheck-KAQH67DV.js"),
12541
- import("./installationInfo-6AM4I2Y3.js"),
12542
- import("./standalone-update-MK3Z7KBI.js"),
13469
+ import("./settings-CUN3SELH.js"),
13470
+ import("./updateCheck-ZHVXDAIH.js"),
13471
+ import("./installationInfo-R7FXPQN5.js"),
13472
+ import("./standalone-update-TMLT6LVJ.js"),
12543
13473
  import("./stdioHelpers-HGIYTWAY.js"),
12544
13474
  import("./updateEventEmitter-5MKC7BLQ.js")
12545
13475
  ]);
@@ -12649,6 +13579,16 @@ var VALID_APPROVAL_MODE_VALUES = [
12649
13579
  "auto",
12650
13580
  "yolo"
12651
13581
  ];
13582
+ var SKILL_LEVELS = [
13583
+ "project",
13584
+ "user",
13585
+ "extension",
13586
+ "bundled"
13587
+ ];
13588
+ function isSkillLevel(value) {
13589
+ return SKILL_LEVELS.includes(value);
13590
+ }
13591
+ __name(isSkillLevel, "isSkillLevel");
12652
13592
  function formatApprovalModeError(value) {
12653
13593
  return new Error(
12654
13594
  `Invalid approval mode: ${value}. Valid values are: ${VALID_APPROVAL_MODE_VALUES.join(
@@ -13364,7 +14304,18 @@ function buildDisabledSkillNamesProvider(loadedSettings) {
13364
14304
  return () => resolveSkillSettings(loadedSettings).disabledNames;
13365
14305
  }
13366
14306
  __name(buildDisabledSkillNamesProvider, "buildDisabledSkillNamesProvider");
13367
- async function loadCliConfig(settings, argv, cwd = process.cwd(), overrideExtensions, hooksConfig, disabledSkillNamesProvider, sessionMcpServers, settingsWatcher) {
14307
+ var SessionIdConflictError = class extends Error {
14308
+ static {
14309
+ __name(this, "SessionIdConflictError");
14310
+ }
14311
+ sessionId;
14312
+ constructor(sessionId, message) {
14313
+ super(message);
14314
+ this.name = "SessionIdConflictError";
14315
+ this.sessionId = sessionId;
14316
+ }
14317
+ };
14318
+ async function loadCliConfig(settings, argv, cwd = process.cwd(), overrideExtensions, hooksConfig, disabledSkillNamesProvider, sessionMcpServers, settingsWatcher, throwOnSessionIdConflict = false) {
13368
14319
  const debugMode = isDebugMode(argv);
13369
14320
  if (debugMode && process.env["QWEN_DEBUG_LOG_FILE"] === void 0) {
13370
14321
  process.env["QWEN_DEBUG_LOG_FILE"] = "1";
@@ -13651,6 +14602,9 @@ async function loadCliConfig(settings, argv, cwd = process.cwd(), overrideExtens
13651
14602
  );
13652
14603
  if (exists) {
13653
14604
  const message = `Error: Session Id ${argv["sessionId"]} already exists (active or archived). Delete or unarchive it first.`;
14605
+ if (throwOnSessionIdConflict) {
14606
+ throw new SessionIdConflictError(argv["sessionId"], message);
14607
+ }
13654
14608
  writeStderrLine(message);
13655
14609
  process.exit(1);
13656
14610
  }
@@ -13681,11 +14635,13 @@ async function loadCliConfig(settings, argv, cwd = process.cwd(), overrideExtens
13681
14635
  excludeTools: mergedDeny,
13682
14636
  disabledSlashCommands: disabledSlashCommands.length > 0 ? disabledSlashCommands : void 0,
13683
14637
  disabledSkillNamesProvider: bareMode || safeMode ? void 0 : disabledSkillNamesProvider,
14638
+ disabledSkillLevels: bareMode || safeMode || !Array.isArray(settings.skills?.disabledLevels) ? void 0 : settings.skills.disabledLevels.filter(isSkillLevel),
13684
14639
  customSkillDirs: bareMode || safeMode ? void 0 : (Array.isArray(settings.skills?.directories) ? settings.skills.directories : []).filter(
13685
14640
  (d) => typeof d === "string" && d.trim().length > 0
13686
14641
  ).map((d) => d.trim()),
13687
14642
  disabledTools: disabledTools.length > 0 ? disabledTools : void 0,
13688
14643
  visibleTools: visibleTools.length > 0 ? visibleTools : void 0,
14644
+ toolSearchThreshold: bareMode || safeMode ? 0 : settings.tools?.toolSearch?.threshold,
13689
14645
  // New unified permissions (PermissionManager source of truth).
13690
14646
  permissions: {
13691
14647
  allow: mergedAllow.length > 0 ? mergedAllow : void 0,
@@ -13796,6 +14752,7 @@ async function loadCliConfig(settings, argv, cwd = process.cwd(), overrideExtens
13796
14752
  bareMode,
13797
14753
  safeMode,
13798
14754
  allowedHttpHookUrls: bareMode || safeMode ? [] : settings.security?.allowedHttpHookUrls ?? [],
14755
+ allowPrivateNetworkHooks: bareMode || safeMode ? false : settings.security?.allowPrivateNetworkHooks ?? false,
13799
14756
  cliVersion: await getCliVersion(),
13800
14757
  ideMode,
13801
14758
  chatCompression: settings.model?.chatCompression,
@@ -14089,6 +15046,7 @@ export {
14089
15046
  loadHierarchicalGeminiMemory,
14090
15047
  isDebugMode,
14091
15048
  buildDisabledSkillNamesProvider,
15049
+ SessionIdConflictError,
14092
15050
  loadCliConfig,
14093
15051
  EXTENSION_RELOAD_FAILED_REASON,
14094
15052
  ExtensionRefreshState