@qwen-code/qwen-code 0.23.1-preview.1 → 0.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/bundled/computer-use/SKILL.md +189 -116
  2. package/bundled/goal-draft/SKILL.md +23 -13
  3. package/bundled/qc-helper/docs/_meta.ts +1 -0
  4. package/bundled/qc-helper/docs/configuration/model-providers.md +47 -1
  5. package/bundled/qc-helper/docs/configuration/settings.md +57 -7
  6. package/bundled/qc-helper/docs/conversations-recovery.md +102 -0
  7. package/bundled/qc-helper/docs/features/channels/dingtalk.md +26 -0
  8. package/bundled/qc-helper/docs/features/channels/overview.md +1 -1
  9. package/bundled/qc-helper/docs/features/commands.md +71 -6
  10. package/bundled/qc-helper/docs/features/computer-use.md +9 -7
  11. package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
  12. package/bundled/qc-helper/docs/features/goals.md +15 -3
  13. package/bundled/qc-helper/docs/features/skills.md +40 -0
  14. package/bundled/qc-helper/docs/qwen-serve.md +19 -1
  15. package/chunks/{MaxSizedBox-5ARLO5PR.js → MaxSizedBox-UDO6Y7RB.js} +35 -36
  16. package/chunks/{StandaloneSessionPicker-T6B322CB.js → StandaloneSessionPicker-D4CUOO4H.js} +55 -56
  17. package/chunks/{acp-startup-profiler-6ULXXQMS.js → acp-startup-profiler-KEU6VAYR.js} +2 -2
  18. package/chunks/{acpAgent-WTDEY5KD.js → acpAgent-KWLJFADK.js} +210 -131
  19. package/chunks/{agent-NXPUXEVZ.js → agent-GSUPGEOL.js} +24 -25
  20. package/chunks/{agent-headless-QQZTWOKO.js → agent-headless-HNYCQUJB.js} +24 -25
  21. package/chunks/{anthropicContentGenerator-6XDHXIII.js → anthropicContentGenerator-I7LQZH26.js} +30 -7
  22. package/chunks/{artifact-tool-DFVVJXL2.js → artifact-tool-P52OKKEF.js} +1 -1
  23. package/chunks/{askUserQuestion-GF7VQ44M.js → askUserQuestion-I5W5S3D6.js} +2 -2
  24. package/chunks/{bridge-OHY5OGOZ.js → bridge-B7CV6RVI.js} +40 -41
  25. package/chunks/{channel-management-service-ZDDG3G5S.js → channel-management-service-TRTLQTSV.js} +4 -4
  26. package/chunks/{channel-settings-store-7BJAS2SU.js → channel-settings-store-FW45IRUP.js} +46 -47
  27. package/chunks/{channel-worker-group-2ISMRENV.js → channel-worker-group-PIYPVCTF.js} +6 -6
  28. package/chunks/{channel-worker-manager-VSRPVPRH.js → channel-worker-manager-FQHEDTD2.js} +6 -6
  29. package/chunks/{channel-worker-supervisor-SRJBK72Z.js → channel-worker-supervisor-XJPZZ3VK.js} +3 -3
  30. package/chunks/{chunk-2WGJG2KW.js → chunk-25CBAK3H.js} +4 -4
  31. package/chunks/{chunk-XUSOYE2I.js → chunk-27LTEY6D.js} +1 -1
  32. package/chunks/{chunk-WTW36TJ3.js → chunk-2EKVPSIJ.js} +1 -1
  33. package/chunks/{chunk-NAKALAL4.js → chunk-2TMJRF46.js} +116 -15
  34. package/chunks/{chunk-E4L5BM2B.js → chunk-2YS3NU4A.js} +4 -4
  35. package/chunks/chunk-2Z3T52OC.js +82 -0
  36. package/chunks/{chunk-ER273QE6.js → chunk-2ZFO5JD7.js} +21 -4
  37. package/chunks/{chunk-WXC6OAWD.js → chunk-3BTHHXXE.js} +1 -1
  38. package/chunks/{chunk-GXZHYPHZ.js → chunk-3LPJ776W.js} +5 -2
  39. package/chunks/{chunk-XY3USGFE.js → chunk-3VDLQUR2.js} +1 -1
  40. package/chunks/{chunk-LK7S2D6V.js → chunk-3VWPPK5Q.js} +58 -4
  41. package/chunks/{chunk-IKLFS6SC.js → chunk-3YQMUBTS.js} +3 -3
  42. package/chunks/{chunk-P4RUUG64.js → chunk-45ROPFQY.js} +1 -1
  43. package/chunks/{chunk-W4LL5RZO.js → chunk-4ALNJDHL.js} +52 -13
  44. package/chunks/{chunk-D6PIMKY3.js → chunk-4VY3ITHR.js} +4 -4
  45. package/chunks/{chunk-H3UDNQLO.js → chunk-5CVY5Q2P.js} +3 -3
  46. package/chunks/{chunk-6UIACMGH.js → chunk-5DQ4YTIZ.js} +1 -1
  47. package/chunks/{chunk-P6LATTDG.js → chunk-5IL2BZHW.js} +3 -3
  48. package/chunks/{chunk-537SQ2AI.js → chunk-5WC2ECUK.js} +104 -16
  49. package/chunks/{chunk-HFTB354P.js → chunk-5Z4FCEPY.js} +60 -6
  50. package/chunks/{chunk-3K65MUKD.js → chunk-65I7S4Z3.js} +2 -1
  51. package/chunks/{chunk-AQ5NAGWI.js → chunk-66JBCTJF.js} +8 -7
  52. package/chunks/{chunk-54TF2ZIQ.js → chunk-6JXHO7LG.js} +3 -3
  53. package/chunks/{chunk-YCDL2SAS.js → chunk-6QILGINT.js} +2 -2
  54. package/chunks/{chunk-P5LDR7FI.js → chunk-6QV7Z74P.js} +3 -3
  55. package/chunks/{chunk-4HC4DYKN.js → chunk-6RZX2HIH.js} +1 -1
  56. package/chunks/{chunk-O45WBTNS.js → chunk-6SADVYQQ.js} +3 -3
  57. package/chunks/{chunk-KE3Q4JMY.js → chunk-6TPVIESH.js} +5 -7
  58. package/chunks/{chunk-2LD5U7Q3.js → chunk-6YEOCHSE.js} +29 -1
  59. package/chunks/{chunk-QWZOOIR3.js → chunk-75LBC7SV.js} +69 -12
  60. package/chunks/{chunk-7BZS4ZDV.js → chunk-7SL55L5H.js} +25 -18
  61. package/chunks/{chunk-O2GG7H4C.js → chunk-ARYNBBBM.js} +3 -3
  62. package/chunks/{chunk-CZACBHAW.js → chunk-B3EL44K3.js} +5 -5
  63. package/chunks/{chunk-VY6UVU7G.js → chunk-CABDNUJ4.js} +2 -2
  64. package/chunks/{chunk-RVNS7NWN.js → chunk-CALNF3Z3.js} +1 -1
  65. package/chunks/{chunk-MWHY26G3.js → chunk-CHVU543W.js} +1 -1
  66. package/chunks/{chunk-GZWW2QWR.js → chunk-CIKL2DQP.js} +2 -2
  67. package/chunks/{chunk-R355CUNQ.js → chunk-CLKE4IY3.js} +1 -77
  68. package/chunks/{chunk-MUZCSTOO.js → chunk-CRZBDVP2.js} +5 -4
  69. package/chunks/{chunk-SFMCYMVF.js → chunk-D6AQNMUA.js} +4 -4
  70. package/chunks/{chunk-D4CU6DKR.js → chunk-DO5SMV52.js} +10 -8
  71. package/chunks/{chunk-ZAZ3NFL6.js → chunk-DXQ6Z7AH.js} +315 -63
  72. package/chunks/{chunk-IXSGOSEG.js → chunk-DZ6D4B3K.js} +28 -25
  73. package/chunks/{chunk-GMNLYQOS.js → chunk-E6TI726I.js} +1 -1
  74. package/chunks/{chunk-JBTZUFR4.js → chunk-E7XSUYCZ.js} +6 -6
  75. package/chunks/{chunk-AHBLRVD5.js → chunk-EEKU6COG.js} +4 -4
  76. package/chunks/{chunk-47BZVBTE.js → chunk-EHTKOO6W.js} +4 -4
  77. package/chunks/{chunk-HJ34U5J4.js → chunk-ENZDGHGJ.js} +4 -4
  78. package/chunks/{chunk-IFD3BTEA.js → chunk-EOET4H7C.js} +3 -3
  79. package/chunks/{chunk-ZTAVGFKA.js → chunk-ERXNTINK.js} +1 -1
  80. package/chunks/{chunk-F47DITLZ.js → chunk-FAWTMDX7.js} +14 -0
  81. package/chunks/{chunk-KPXRFTT7.js → chunk-FETY36NQ.js} +1 -1
  82. package/chunks/{chunk-5JLQWQK6.js → chunk-FV4DM2M4.js} +2 -2
  83. package/chunks/{chunk-4F2QRVW6.js → chunk-FW4E4QPG.js} +1 -1
  84. package/chunks/{chunk-KJJPJYHI.js → chunk-FWRRUITH.js} +8 -8
  85. package/chunks/{chunk-4VUVBN3Y.js → chunk-G6UUOCUT.js} +87 -0
  86. package/chunks/{chunk-4JAGXZR3.js → chunk-GM44O6F7.js} +1 -1
  87. package/chunks/{chunk-4MCY33Y2.js → chunk-GNY7B3CA.js} +1 -1
  88. package/chunks/{chunk-VEFRT7NX.js → chunk-H3Q3RSKZ.js} +1 -1
  89. package/chunks/{chunk-43NOB5NM.js → chunk-HIXUUCGY.js} +188 -13
  90. package/chunks/{chunk-EJNYBDYC.js → chunk-HNLMYDQE.js} +1 -1
  91. package/chunks/{chunk-JOPC3FND.js → chunk-HUX2DOTF.js} +5 -5
  92. package/chunks/{chunk-GCFZ2LAX.js → chunk-HZ2HUXX7.js} +2 -2
  93. package/chunks/{chunk-CWNC7M73.js → chunk-IKG2YVRZ.js} +2 -2
  94. package/chunks/{chunk-L4R7BCVV.js → chunk-J3TJH52D.js} +1 -1
  95. package/chunks/{chunk-QMFOYPGV.js → chunk-J3VZF2AL.js} +2 -2
  96. package/chunks/{chunk-ZJ2LM2SI.js → chunk-JGDRB4FP.js} +104 -33
  97. package/chunks/{chunk-LMJQSPWB.js → chunk-KA5HR3G2.js} +1 -1
  98. package/chunks/{chunk-G34YLYCS.js → chunk-L7V52QEZ.js} +10 -10
  99. package/chunks/{chunk-GVVCLL2P.js → chunk-LNCNUMJ5.js} +451 -396
  100. package/chunks/{chunk-RDKXZ2LS.js → chunk-LYT2OU7D.js} +1 -1
  101. package/chunks/{chunk-SAZS4IWW.js → chunk-LZGFVUWZ.js} +3 -3
  102. package/chunks/{chunk-32YDNYXP.js → chunk-M73KHGNR.js} +13 -66
  103. package/chunks/{chunk-ADJD4LZF.js → chunk-MA5OUNN6.js} +1 -1
  104. package/chunks/{chunk-2RYWGYB3.js → chunk-MFYH2VXV.js} +3 -3
  105. package/chunks/{chunk-RPBMP6BN.js → chunk-MWIO7MF6.js} +3 -0
  106. package/chunks/{chunk-OECNP26L.js → chunk-N6S3NUYJ.js} +1 -1
  107. package/chunks/{chunk-5MTARK4Y.js → chunk-N7YQEKGX.js} +6 -6
  108. package/chunks/{chunk-XOVVCGZX.js → chunk-NB3NDQQK.js} +1 -1
  109. package/chunks/chunk-NOO4QFXM.js +171 -0
  110. package/chunks/{chunk-NGX4NUNP.js → chunk-O2FEO2CB.js} +131 -6
  111. package/chunks/{chunk-XHGGYCTA.js → chunk-O2JBJQCF.js} +1 -1
  112. package/chunks/{chunk-LPBQODMR.js → chunk-OESZTXTG.js} +4 -4
  113. package/chunks/{chunk-UKADFFL2.js → chunk-OFVAS4AR.js} +1 -1
  114. package/chunks/{chunk-TDP7UULF.js → chunk-OPMKGOLD.js} +1 -1
  115. package/chunks/{chunk-LDS57224.js → chunk-OWCFKIFQ.js} +1 -1
  116. package/chunks/{chunk-I72PHOKL.js → chunk-PDUMGZ2P.js} +1524 -1382
  117. package/chunks/{chunk-JRYL3T2O.js → chunk-PQSCGZT2.js} +1 -1
  118. package/chunks/{chunk-WEXA2DNG.js → chunk-PSPAM24S.js} +14 -0
  119. package/chunks/{chunk-UKKYOIVT.js → chunk-QAZ2MGYT.js} +2 -2
  120. package/chunks/{chunk-J3O5I5ZD.js → chunk-QK4K76T6.js} +3 -3
  121. package/chunks/{chunk-NUQFUXOG.js → chunk-QTNCGZHQ.js} +2 -0
  122. package/chunks/{chunk-5YY5MZT6.js → chunk-QZOXVQPK.js} +1 -1
  123. package/chunks/{chunk-QJVZLILI.js → chunk-R7OO56VZ.js} +1 -1
  124. package/chunks/{chunk-IQN2CCIE.js → chunk-RNYENHN5.js} +398 -55
  125. package/chunks/{chunk-64MQTIX7.js → chunk-RPFJJ33Z.js} +2 -2
  126. package/chunks/{chunk-4VZCORNT.js → chunk-RXT4QBDX.js} +1 -1
  127. package/chunks/{chunk-SN5FV4FY.js → chunk-S6QVI3MV.js} +3 -3
  128. package/chunks/{chunk-NXWYCSPL.js → chunk-SOA4HKRJ.js} +1 -1
  129. package/chunks/{chunk-JLWFGYXU.js → chunk-T2IHCZLS.js} +2 -2
  130. package/chunks/{chunk-DNPHKA72.js → chunk-TGC4264Q.js} +6 -6
  131. package/chunks/{chunk-PZV2FASB.js → chunk-TRWQQBVH.js} +1 -1
  132. package/chunks/{chunk-Y3ZKI4RQ.js → chunk-TWAMIEQ2.js} +85 -22
  133. package/chunks/{chunk-KK2GZGBK.js → chunk-TWWS7XUW.js} +14 -11
  134. package/chunks/{chunk-4IQKBLTQ.js → chunk-UHUT4IDM.js} +18 -9
  135. package/chunks/{chunk-BKNY7PDI.js → chunk-USN6VNTO.js} +1 -1
  136. package/chunks/{chunk-TMWB67LS.js → chunk-UXDVUFKU.js} +3 -3
  137. package/chunks/{chunk-HY3DXYZK.js → chunk-UYDQYDW2.js} +1 -1
  138. package/chunks/{chunk-3K456UJF.js → chunk-VF6D6EGV.js} +12 -4
  139. package/chunks/{chunk-PZUOHCWI.js → chunk-WAASYFPK.js} +2 -2
  140. package/chunks/{chunk-OHOO527W.js → chunk-WG7BL3FY.js} +52 -2
  141. package/chunks/{chunk-JPEAQJNS.js → chunk-WJDXKQIO.js} +1 -1
  142. package/chunks/{chunk-MNEYUNOE.js → chunk-WNISCNTA.js} +40 -2
  143. package/chunks/{chunk-Z6WZPXQH.js → chunk-WQMUGQ6G.js} +2 -2
  144. package/chunks/{chunk-N7VURC4O.js → chunk-WXFCI3O5.js} +2 -2
  145. package/chunks/{chunk-VU7O7CGQ.js → chunk-XDNFODER.js} +1 -1
  146. package/chunks/{chunk-N7EYO2E7.js → chunk-XQ4RDO5B.js} +1 -1
  147. package/chunks/{chunk-VDXYYVCD.js → chunk-XVTCSVBK.js} +579 -57
  148. package/chunks/{chunk-PTFFWTTO.js → chunk-XZ3Z43XL.js} +3 -3
  149. package/chunks/{chunk-QSC5YOEC.js → chunk-YAC7H4K3.js} +2 -2
  150. package/chunks/{chunk-43JNQAHO.js → chunk-YCEKI7QX.js} +51 -10
  151. package/chunks/{chunk-7IKXTGZT.js → chunk-YI2YCNSP.js} +1 -1
  152. package/chunks/{chunk-VUSSAGKI.js → chunk-YZTGGCEE.js} +10 -2
  153. package/chunks/{chunk-WR3SH3EY.js → chunk-ZNO5BUAD.js} +149 -66
  154. package/chunks/{chunk-URSCX7S7.js → chunk-ZPL2TZNA.js} +353 -11
  155. package/chunks/{chunk-UEZOXZNI.js → chunk-ZU2T5JIS.js} +804 -371
  156. package/chunks/{config-utils-QXDOTXEQ.js → config-utils-KTDSQ4MU.js} +39 -40
  157. package/chunks/{contextCommand-RN4KARWC.js → contextCommand-UQ3KRYGK.js} +37 -38
  158. package/chunks/{core-runtime-NAZCOKHB.js → core-runtime-JR34JAFH.js} +35 -36
  159. package/chunks/{create-sub-session-BCSM4WKB.js → create-sub-session-RGPJOI4S.js} +45 -40
  160. package/chunks/{create-sub-session-BQ3SE4TX.js → create-sub-session-TGIX63YU.js} +2 -2
  161. package/chunks/{cron-create-D6HQ7I7I.js → cron-create-GTPVMJCF.js} +1 -1
  162. package/chunks/{cron-delete-KK3D2SQV.js → cron-delete-ZBK27Z4K.js} +1 -1
  163. package/chunks/{cron-list-VBF3IZMF.js → cron-list-KTFKFDKC.js} +1 -1
  164. package/chunks/{daemon-LCUELM6E.js → daemon-UI6SQSBV.js} +1 -1
  165. package/chunks/{daemon-git-worktree-guard-3K5CAU36.js → daemon-git-worktree-guard-H3OA26KQ.js} +35 -36
  166. package/chunks/{daemon-status-provider-4X3ZZQTZ.js → daemon-status-provider-6WZLKSZU.js} +45 -46
  167. package/chunks/{daemon-trust-policy-R45CFUJA.js → daemon-trust-policy-3EDP2BYD.js} +42 -43
  168. package/chunks/{daemon-trust-policy-monitor-DSSFCO3K.js → daemon-trust-policy-monitor-CRHZPK52.js} +42 -43
  169. package/chunks/{deferred-core-runtime-UO2M6WYI.js → deferred-core-runtime-LO5NTQQ4.js} +35 -36
  170. package/chunks/{discovery-TUM3ZQ6U.js → discovery-XP4RMDUM.js} +4 -2
  171. package/chunks/{display-image-EVVTBVYE.js → display-image-CTNHJRZC.js} +4 -4
  172. package/chunks/{dist-SIHF5MU2.js → dist-24TCWK5H.js} +1 -1
  173. package/chunks/{dist-AFH3BMZZ.js → dist-5I4HLUTO.js} +1 -1
  174. package/chunks/{dist-3T5MDUHP.js → dist-FDISN4AK.js} +1 -1
  175. package/chunks/{dist-SB2XRXZA.js → dist-M4CBX53H.js} +1 -1
  176. package/chunks/{dist-UVHW2U56.js → dist-NQ2636VT.js} +1 -1
  177. package/chunks/{dist-PH5RSTEA.js → dist-OR2ZQTXZ.js} +1 -1
  178. package/chunks/{dist-MK5PPBRF.js → dist-STAGIFNB.js} +1099 -67
  179. package/chunks/{dist-R5Y34V6T.js → dist-WZTUKIDR.js} +2 -2
  180. package/chunks/{dist-QUU7TVE3.js → dist-XJ25G6OH.js} +1 -1
  181. package/chunks/{edit-VNBCTRWP.js → edit-LB7Z7XK5.js} +24 -25
  182. package/chunks/{en-JMR535HP.js → en-YJNRUQG4.js} +1 -1
  183. package/chunks/{enter-worktree-CEVK7MQ2.js → enter-worktree-YFTKHXHZ.js} +4 -4
  184. package/chunks/{enterPlanMode-4KMZMUIA.js → enterPlanMode-P6TVUFIY.js} +24 -25
  185. package/chunks/{environment-S2HYQDON.js → environment-QATJNNKI.js} +38 -39
  186. package/chunks/{errors-DAAN5TL7.js → errors-3XJ37PS2.js} +37 -38
  187. package/chunks/{exit-worktree-D3YE6MUN.js → exit-worktree-NF2XEMES.js} +5 -5
  188. package/chunks/{exitPlanMode-HR36HG3D.js → exitPlanMode-A3OKL5UO.js} +24 -25
  189. package/chunks/{fast-path-4IWSW3UV.js → fast-path-DBIT5YQQ.js} +3 -3
  190. package/chunks/{fast-path-settings-ISEJPRYE.js → fast-path-settings-SATXY3PD.js} +3 -3
  191. package/chunks/{glob-IZYB2XH2.js → glob-73EDTXUE.js} +24 -25
  192. package/chunks/{goal-tools-VGUPKQDJ.js → goal-tools-DFI6YMSD.js} +24 -25
  193. package/chunks/{grep-OUVLNXG7.js → grep-BLHF2S5D.js} +2 -2
  194. package/chunks/{handleAutoUpdate-D56FMDTW.js → handleAutoUpdate-2FUNJO3B.js} +38 -39
  195. package/chunks/{i18n-BKE5WO6T.js → i18n-FDIA6KFI.js} +38 -37
  196. package/chunks/{image-gen-SHVQ3XID.js → image-gen-XP4NNIYG.js} +5 -5
  197. package/chunks/{initializer-MS4SGEHF.js → initializer-4MJTJOTW.js} +42 -43
  198. package/chunks/{installationInfo-542MGC4S.js → installationInfo-232RA2OK.js} +35 -36
  199. package/chunks/{list-H6XTKUWL.js → list-WN6WSGEB.js} +45 -46
  200. package/chunks/{list-agents-ULYBGJXC.js → list-agents-I5TRH3J7.js} +2 -2
  201. package/chunks/{llm-3NUC4EJY.js → llm-UDFWQWZA.js} +77 -78
  202. package/chunks/{llm-content-generator-R4NL3OQN.js → llm-content-generator-VLMZ2A7A.js} +23 -8
  203. package/chunks/{loadedSettingsAdapter-3XLKYDVT.js → loadedSettingsAdapter-OBQEIXM7.js} +42 -43
  204. package/chunks/{loggingContentGenerator-ZYSWVNEO.js → loggingContentGenerator-RGVUMUVX.js} +26 -27
  205. package/chunks/{loop-wakeup-B27BEYRL.js → loop-wakeup-HL6XOWI4.js} +2 -2
  206. package/chunks/{ls-3IIMMVKF.js → ls-YV7RKLKY.js} +1 -1
  207. package/chunks/{lsp-VJAT7XKS.js → lsp-NO3AMRZT.js} +1 -1
  208. package/chunks/{managed-npm-update-L2I53ZAI.js → managed-npm-update-QBAJYCFU.js} +35 -36
  209. package/chunks/{mcp-4PIXQASW.js → mcp-OTIZZCPY.js} +42 -43
  210. package/chunks/{monitor-O2YQTOZZ.js → monitor-BV5XF6LL.js} +24 -25
  211. package/chunks/{nonInteractiveCli-LV7CDBA2.js → nonInteractiveCli-W6MUKDVJ.js} +79 -77
  212. package/chunks/{notebook-edit-4RE2ALH4.js → notebook-edit-HGBEKGTE.js} +24 -25
  213. package/chunks/{openaiContentGenerator-7ND7K5CP.js → openaiContentGenerator-NSU3ERBH.js} +15 -15
  214. package/chunks/{pidfile-UFTLQ7NP.js → pidfile-LE3TU4GE.js} +35 -36
  215. package/chunks/{processUtils-3XBB4FYV.js → processUtils-YFBGJK67.js} +2 -2
  216. package/chunks/{prompt-terminal-ledger-2QASOGMM.js → prompt-terminal-ledger-4W4W7DSO.js} +36 -37
  217. package/chunks/{qwenContentGenerator-AELTUTH6.js → qwenContentGenerator-HTA57WFC.js} +28 -29
  218. package/chunks/{qwenOAuth2-BS5D2LYV.js → qwenOAuth2-KX6LVYQ3.js} +4 -4
  219. package/chunks/{read-file-PDWHZPHX.js → read-file-KHPQ2MB6.js} +4 -4
  220. package/chunks/{read-mcp-resource-YXJZ75UB.js → read-mcp-resource-D3N75DGF.js} +1 -1
  221. package/chunks/{record-artifact-WJDOV6XU.js → record-artifact-Q5CRGJTP.js} +2 -2
  222. package/chunks/{report-findings-Q4UACKWR.js → report-findings-TJ34R7QK.js} +3 -3
  223. package/chunks/{request-shutdown-2YZ3E3GH.js → request-shutdown-LRKMTBAD.js} +6 -6
  224. package/chunks/{resumeHistoryUtils-QRXZEEBA.js → resumeHistoryUtils-K7RV3QBN.js} +39 -40
  225. package/chunks/{ripGrep-KSOOLE6H.js → ripGrep-NBBVCMG4.js} +7 -7
  226. package/chunks/{run-qwen-serve-RTAREPT6.js → run-qwen-serve-A3JBOZCM.js} +58 -60
  227. package/chunks/{runtime-ESFSCJRZ.js → runtime-7YOU2KJ3.js} +47 -48
  228. package/chunks/{scheduled-tasks-6ZHRNBH6.js → scheduled-tasks-52LXK7LN.js} +42 -43
  229. package/chunks/{scheduler-DQI6KV7T.js → scheduler-J44M72VM.js} +37 -38
  230. package/chunks/{send-message-PQCVSVMN.js → send-message-AWKUDJBH.js} +8 -8
  231. package/chunks/{serve-FY7ZEW52.js → serve-TRC6XJUB.js} +42 -43
  232. package/chunks/{server-KNDY6K5F.js → server-YPNTJLX2.js} +1314 -841
  233. package/chunks/{session-MCEPXAZP.js → session-FMMIBFYX.js} +98 -84
  234. package/chunks/{session-attachments-root-OLNAE6GF.js → session-attachments-root-LDJMNK7K.js} +35 -36
  235. package/chunks/{session-pr-refresh-HKJHQQQK.js → session-pr-refresh-NLR4EK2J.js} +41 -42
  236. package/chunks/{settings-VXO4WBMK.js → settings-A46L577J.js} +41 -42
  237. package/chunks/{shell-U263OTES.js → shell-Q5LSQPPY.js} +24 -25
  238. package/chunks/{skill-SDODGBKL.js → skill-75KPJRCM.js} +10 -57
  239. package/chunks/{skill-settings-YEIA22QJ.js → skill-settings-775YT4YR.js} +41 -42
  240. package/chunks/{spawnChannel-4WJZVFPP.js → spawnChannel-XY73I5CU.js} +37 -38
  241. package/chunks/{standalone-update-ZWVQUO64.js → standalone-update-L46XXNQ2.js} +37 -38
  242. package/chunks/{start-opentui-ui-BFYCJQRZ.js → start-opentui-ui-WLV43247.js} +2007 -1003
  243. package/chunks/{startInteractiveUI-JYAFCMHL.js → startInteractiveUI-F5DKMLOV.js} +1231 -1528
  244. package/chunks/{syntheticOutput-AUAJBNXR.js → syntheticOutput-D2P5V6RG.js} +2 -2
  245. package/chunks/{task-create-LD5ISM3E.js → task-create-PMAFST2T.js} +7 -7
  246. package/chunks/{task-list-YISJ4RJA.js → task-list-R2HSY2NC.js} +1 -1
  247. package/chunks/{task-stop-65ZOVATJ.js → task-stop-BFSKRTGV.js} +1 -1
  248. package/chunks/{task-update-AAN4ZVEY.js → task-update-JYC57USF.js} +7 -7
  249. package/chunks/{team-create-KU7MABNO.js → team-create-2PATB77U.js} +24 -25
  250. package/chunks/{team-delete-XFRRTJTT.js → team-delete-CBHVBTPB.js} +1 -1
  251. package/chunks/{team-plan-approval-DPB377A3.js → team-plan-approval-QTANEWOS.js} +24 -25
  252. package/chunks/{terminal-image-renderer-WGWRENOF.js → terminal-image-renderer-OGULCFNF.js} +37 -38
  253. package/chunks/{theme-manager-GBUFULSO.js → theme-manager-CNO3QERP.js} +35 -36
  254. package/chunks/{todoWrite-G7NT4IFP.js → todoWrite-5ERKFWAK.js} +3 -5
  255. package/chunks/{tool-search-6YUXHBPT.js → tool-search-VXWEOZE7.js} +9 -9
  256. package/chunks/{total-session-admission-54R2JQ5L.js → total-session-admission-4KAADZPB.js} +41 -42
  257. package/chunks/{trustedFolders-KAJIDJTH.js → trustedFolders-PPJSOPOT.js} +36 -37
  258. package/chunks/{update-relaunch-XM4IWBFD.js → update-relaunch-4PT4MW7B.js} +5 -5
  259. package/chunks/{updateCheck-W6UZFURI.js → updateCheck-WAVFLWNG.js} +37 -38
  260. package/chunks/{useAutoAcceptIndicator-LAWYHY3U.js → useAutoAcceptIndicator-XNED4NRB.js} +44 -45
  261. package/chunks/{validateNonInterActiveAuth-7WCKHRN2.js → validateNonInterActiveAuth-J676DUQ2.js} +74 -74
  262. package/chunks/{version-3ZU43RJ6.js → version-J6SRRQB2.js} +1 -1
  263. package/chunks/{web-fetch-QHI2SQL4.js → web-fetch-FMZZYX44.js} +7 -7
  264. package/chunks/{web-search-3KZZKWNY.js → web-search-3G2KXCX5.js} +19 -8
  265. package/chunks/{workflow-HRW7Y2X4.js → workflow-PPZZICQ7.js} +26 -27
  266. package/chunks/{workspace-providers-status-KTGCWCPC.js → workspace-providers-status-IIYTAQST.js} +46 -47
  267. package/chunks/{workspace-registration-store-LHLPPWNE.js → workspace-registration-store-VHCDXAV7.js} +1 -1
  268. package/chunks/{workspace-registry-X34MLN52.js → workspace-registry-I7VQIPS2.js} +41 -42
  269. package/chunks/{workspace-runtime-coordinator-U4PW4P7K.js → workspace-runtime-coordinator-DBGNY32G.js} +41 -42
  270. package/chunks/{workspace-service-KD7BCGYL.js → workspace-service-QSKB2T54.js} +47 -48
  271. package/chunks/{workspace-skills-status-YJGO6Y3T.js → workspace-skills-status-T7GPT65J.js} +43 -44
  272. package/chunks/{workspace-trust-reconciler-EUYHISCH.js → workspace-trust-reconciler-2PKRDAU4.js} +48 -49
  273. package/chunks/{write-file-EBSB34NJ.js → write-file-L76CGFTQ.js} +26 -27
  274. package/chunks/{zh-TW-W2GNP2IU.js → zh-TW-N2TBF2F2.js} +1 -1
  275. package/chunks/{zh-DVFYHRK5.js → zh-VBFCRQBL.js} +1 -1
  276. package/chunks/{zoom-image-UJ5VKWKP.js → zoom-image-TDJJY2VZ.js} +4 -4
  277. package/cli.js +13 -13
  278. package/export-transcript-document.js +126 -122
  279. package/locales/en.js +2 -2
  280. package/locales/zh-TW.js +2 -2
  281. package/locales/zh.js +2 -2
  282. package/package.json +3 -3
  283. package/web-shell/assets/{abnfDiagram-VCTEODGH-Dur--luQ.js → abnfDiagram-VCTEODGH-DHc6plZn.js} +1 -1
  284. package/web-shell/assets/{arc-tYLobxFi.js → arc-BQ9m8TDV.js} +1 -1
  285. package/web-shell/assets/{architectureDiagram-5GKGNRK7-IG6aXD03.js → architectureDiagram-5GKGNRK7-D5ap3oVB.js} +1 -1
  286. package/web-shell/assets/{blockDiagram-NRAW4CY4-C6eBSkfA.js → blockDiagram-NRAW4CY4-BIbnyNph.js} +1 -1
  287. package/web-shell/assets/{c4Diagram-UCG6FXSJ-BrX3HJqB.js → c4Diagram-UCG6FXSJ-BRsdx_iG.js} +1 -1
  288. package/web-shell/assets/channel-uMMdTrYk.js +1 -0
  289. package/web-shell/assets/{chunk-2Q5K7J3B-B3fcJ8ee.js → chunk-2Q5K7J3B-3lf1fNlx.js} +1 -1
  290. package/web-shell/assets/{chunk-5VM5RSS4-CeC90yKM.js → chunk-5VM5RSS4-DP8VNRc4.js} +1 -1
  291. package/web-shell/assets/{chunk-F27PBJKO-CW44RVki.js → chunk-F27PBJKO-DrohDmZ6.js} +1 -1
  292. package/web-shell/assets/{chunk-G27WJ6UU-D1PAMukD.js → chunk-G27WJ6UU-UZ2QhSx6.js} +1 -1
  293. package/web-shell/assets/{chunk-JWPE2WC7-Dt3Y2Fvx.js → chunk-JWPE2WC7-BIMHVcZK.js} +1 -1
  294. package/web-shell/assets/{chunk-LCL6LL3I-CZHw2lLI.js → chunk-LCL6LL3I-izRxdSDd.js} +1 -1
  295. package/web-shell/assets/{chunk-POPQ4Y6H-ysNAdTGx.js → chunk-POPQ4Y6H-CXADD4PP.js} +1 -1
  296. package/web-shell/assets/{chunk-SVP7TREG-BdNXW6YQ.js → chunk-SVP7TREG-B96d8Y_1.js} +1 -1
  297. package/web-shell/assets/{chunk-XXDRQBXY-DgqQ9UA8.js → chunk-XXDRQBXY-CF2sVQpv.js} +1 -1
  298. package/web-shell/assets/classDiagram-DTDB5LWJ-DcY-26Ig.js +1 -0
  299. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DcY-26Ig.js +1 -0
  300. package/web-shell/assets/{cose-bilkent-JH36ORCC-BILImXzJ.js → cose-bilkent-JH36ORCC-CT6tXVAS.js} +1 -1
  301. package/web-shell/assets/csv-CX7rUNeC.svg +1 -0
  302. package/web-shell/assets/{cynefin-OW5HDTMX-DR88Pund.js → cynefin-OW5HDTMX-X1NS4vtV.js} +1 -1
  303. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BYFbfkA6.js → cynefinDiagram-5FMLGOSQ-DNsKNOT4.js} +1 -1
  304. package/web-shell/assets/{dagre-3AP2YEHR-rfpyc6sX.js → dagre-3AP2YEHR-9-AHKqsb.js} +1 -1
  305. package/web-shell/assets/{diagram-S7CK7UJ4-BJxLmEwH.js → diagram-S7CK7UJ4-Bjgms7j6.js} +1 -1
  306. package/web-shell/assets/{diagram-UQ7AKVKN-H34xm7k3.js → diagram-UQ7AKVKN-h6bCprbE.js} +1 -1
  307. package/web-shell/assets/{diagram-VSXAHHWV-HYxhwNLx.js → diagram-VSXAHHWV-4SbQXVLt.js} +1 -1
  308. package/web-shell/assets/{diagram-VX7I27RA-BJazso8F.js → diagram-VX7I27RA-B5gPCzzB.js} +1 -1
  309. package/web-shell/assets/{diagram-Z3DM3KII-Clje1aNy.js → diagram-Z3DM3KII-DFJXIA3A.js} +1 -1
  310. package/web-shell/assets/{ebnfDiagram-PWID7BFC-M93YBkFh.js → ebnfDiagram-PWID7BFC-FwyaU7VY.js} +1 -1
  311. package/web-shell/assets/{erDiagram-SSCWMZ5O-DY8XzSHU.js → erDiagram-SSCWMZ5O-8vJQh2te.js} +1 -1
  312. package/web-shell/assets/{flowDiagram-A5DVABFB-CE6Aylcq.js → flowDiagram-A5DVABFB-BzA_1gMN.js} +1 -1
  313. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-DI-5LL22.js → ganttDiagram-EL5Y4UJY-Co-ABbVX.js} +1 -1
  314. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-C7BZWElk.js → gitGraphDiagram-WWUBYQGX-DW_FcyrX.js} +1 -1
  315. package/web-shell/assets/{index-DclFHns9.js → index-BbMXfhNG.js} +1 -1
  316. package/web-shell/assets/{index-CVyqwW7y.js → index-Bu-rZoJ-.js} +483 -475
  317. package/web-shell/assets/index-CsPwZ1ut.css +36 -0
  318. package/web-shell/assets/{infoDiagram-RXCK75RN-CGUSy4Pc.js → infoDiagram-RXCK75RN-BEgfhUFN.js} +1 -1
  319. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-B5BVks9q.js → ishikawaDiagram-5VMMS53U-DCsMxQmc.js} +1 -1
  320. package/web-shell/assets/{journeyDiagram-EYS64GPL-CFh6Tf7h.js → journeyDiagram-EYS64GPL-DyIEYoHz.js} +1 -1
  321. package/web-shell/assets/{kanban-definition-3QL26DDD-B7TlxP7c.js → kanban-definition-3QL26DDD-CkxjqCNr.js} +1 -1
  322. package/web-shell/assets/{layout-Br_pZq2Q.js → layout-BEWc0Al9.js} +1 -1
  323. package/web-shell/assets/{linear-BVlP6fte.js → linear-CNuNxirL.js} +1 -1
  324. package/web-shell/assets/{mermaid.core-TrcYWoiF.js → mermaid.core-DZBre674.js} +6 -6
  325. package/web-shell/assets/{mindmap-definition-FBJOCRG2-BJ4LzqjZ.js → mindmap-definition-FBJOCRG2-CpafFz_F.js} +1 -1
  326. package/web-shell/assets/{pegDiagram-XKGWAZYB-1b_MxlOl.js → pegDiagram-XKGWAZYB-DfZqk_dq.js} +1 -1
  327. package/web-shell/assets/{pieDiagram-E7YTZNPT-B8zl0YhY.js → pieDiagram-E7YTZNPT-S0UWXlgC.js} +1 -1
  328. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-CIZO8ukl.js → quadrantDiagram-AXDQQJYC-dd37_Ohj.js} +1 -1
  329. package/web-shell/assets/{railroadDiagram-O6MQD6OU-CepHSbCj.js → railroadDiagram-O6MQD6OU-CH8NJZ7u.js} +1 -1
  330. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-BCgxkcSW.js → requirementDiagram-EFPCY7ZU-CFdqWYih.js} +1 -1
  331. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-CE5CcoMM.js → sankeyDiagram-P5KCCOFB-CsddcEGD.js} +1 -1
  332. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DvgHi-d5.js → sequenceDiagram-WJ2MYXX4-BZ270mGw.js} +1 -1
  333. package/web-shell/assets/{sizeCapture-X5ZJPWSS-T-fAsCPX.js → sizeCapture-X5ZJPWSS-CGaS4DBV.js} +1 -1
  334. package/web-shell/assets/{stateDiagram-HBIQ2CUA-DYHaul-5.js → stateDiagram-HBIQ2CUA-COpIzMu6.js} +1 -1
  335. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-D6qEVAji.js +1 -0
  336. package/web-shell/assets/{swimlanes-XN3QIQJK-Dbz3Qiej.js → swimlanes-XN3QIQJK-CMF889m3.js} +1 -1
  337. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-mem5Jj4m.js +8 -0
  338. package/web-shell/assets/{timeline-definition-24CTP7MA-9NVRts3N.js → timeline-definition-24CTP7MA-BelnxYz5.js} +1 -1
  339. package/web-shell/assets/{vennDiagram-4TSXK5OY-C7cb7vnH.js → vennDiagram-4TSXK5OY-CU-NRqIB.js} +1 -1
  340. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CG-8Ddjm.js → wardleyDiagram-VM6X3IG4-CDNKqWh-.js} +1 -1
  341. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-iGeYAcP4.js → xychartDiagram-S5SC5T6Z-CLqguL5D.js} +1 -1
  342. package/web-shell/index.html +6 -3
  343. package/chunks/chunk-3UMWOKJC.js +0 -78
  344. package/chunks/chunk-FKJM6JKY.js +0 -98
  345. package/chunks/chunk-IQAFKVXS.js +0 -22
  346. package/web-shell/assets/channel-uEkvKckd.js +0 -1
  347. package/web-shell/assets/classDiagram-DTDB5LWJ-DuPsnhWS.js +0 -1
  348. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DuPsnhWS.js +0 -1
  349. package/web-shell/assets/index-FO7JXPnH.css +0 -36
  350. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-BcYho9a4.js +0 -1
  351. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-D6HsOIgX.js +0 -8
@@ -5,7 +5,7 @@ import {
5
5
  DualOutputBridge,
6
6
  EDITOR_DISPLAY_NAMES,
7
7
  RemoteInputWatcher,
8
- STATUS_LINE_PRESET_ITEMS,
8
+ addShellCommandToLlmHistory,
9
9
  computeWindowTitle,
10
10
  editorSettingsManager,
11
11
  fmtTokens,
@@ -15,26 +15,29 @@ import {
15
15
  getToolInvalidReasons,
16
16
  isToolValid,
17
17
  normalizeModelIds,
18
+ useFollowupSuggestionsCLI,
18
19
  useLogger,
19
20
  useProviderSetupFlow,
20
21
  writeTerminalTitle
21
- } from "./chunk-GVVCLL2P.js";
22
- import "./chunk-RVNS7NWN.js";
23
- import "./chunk-LK7S2D6V.js";
22
+ } from "./chunk-LNCNUMJ5.js";
23
+ import "./chunk-CALNF3Z3.js";
24
+ import "./chunk-3VWPPK5Q.js";
24
25
  import {
25
26
  startPostRenderPrefetches
26
- } from "./chunk-G34YLYCS.js";
27
+ } from "./chunk-L7V52QEZ.js";
27
28
  import {
29
+ STATUS_LINE_PRESET_ITEMS,
28
30
  SessionStatsProvider,
29
31
  TOOL_DISPLAY_BY_NAME,
30
32
  TOOL_SUCCESS_RATE_HIGH,
31
33
  TOOL_SUCCESS_RATE_MEDIUM,
32
34
  flattenModelsBySource,
35
+ formatTokenCount,
33
36
  getArenaStatusLabel,
34
37
  getStatusColor,
35
38
  keyMatchers,
36
39
  useSessionStats
37
- } from "./chunk-IQN2CCIE.js";
40
+ } from "./chunk-RNYENHN5.js";
38
41
  import {
39
42
  ICON,
40
43
  applyCollapsePolicyAndSummary,
@@ -43,7 +46,7 @@ import {
43
46
  isFindingsListDisplay,
44
47
  shouldDisplayGoalStateCause,
45
48
  waitForGoalRuntime
46
- } from "./chunk-JBTZUFR4.js";
49
+ } from "./chunk-E7XSUYCZ.js";
47
50
  import {
48
51
  stopAndGetCapturedInput
49
52
  } from "./chunk-EWNKP4V4.js";
@@ -54,7 +57,7 @@ import {
54
57
  MAX_SUGGESTIONS_TO_SHOW,
55
58
  handleAtCommand,
56
59
  sanitizeDisplayText
57
- } from "./chunk-HJ34U5J4.js";
60
+ } from "./chunk-ENZDGHGJ.js";
58
61
  import {
59
62
  BuiltinCommandLoader,
60
63
  BundledSkillLoader,
@@ -86,18 +89,18 @@ import {
86
89
  refreshExtensionContentRuntime,
87
90
  resetBackgroundStateForSessionSwitch,
88
91
  serializeUserPromptExpansionPrompt
89
- } from "./chunk-WR3SH3EY.js";
92
+ } from "./chunk-ZNO5BUAD.js";
90
93
  import {
91
94
  EXTENSION_RELOAD_FAILED_REASON,
92
95
  ExtensionRefreshState
93
- } from "./chunk-ZAZ3NFL6.js";
96
+ } from "./chunk-DXQ6Z7AH.js";
94
97
  import {
95
98
  formatSupportedModes,
96
99
  getCommandDisplayName,
97
100
  getCommandSourceBadge,
98
101
  getCommandSourceGroup,
99
102
  getCommandSubcommandNames
100
- } from "./chunk-XHGGYCTA.js";
103
+ } from "./chunk-O2JBJQCF.js";
101
104
  import {
102
105
  calculateCost,
103
106
  computeSessionStats,
@@ -105,7 +108,7 @@ import {
105
108
  getSystemInfoFields,
106
109
  levelLabel,
107
110
  redactProxy
108
- } from "./chunk-2RYWGYB3.js";
111
+ } from "./chunk-MFYH2VXV.js";
109
112
  import {
110
113
  formatDuration
111
114
  } from "./chunk-3SH53ANB.js";
@@ -115,8 +118,8 @@ import {
115
118
  cleanupOldClipboardImages,
116
119
  clipboardHasImage,
117
120
  saveClipboardImage
118
- } from "./chunk-HY3DXYZK.js";
119
- import "./chunk-JOPC3FND.js";
121
+ } from "./chunk-UYDQYDW2.js";
122
+ import "./chunk-HUX2DOTF.js";
120
123
  import "./chunk-4WGODMVR.js";
121
124
  import "./chunk-4LIPOIXS.js";
122
125
  import {
@@ -133,25 +136,25 @@ import {
133
136
  import {
134
137
  require_react
135
138
  } from "./chunk-5QWWOFGG.js";
136
- import "./chunk-SFMCYMVF.js";
139
+ import "./chunk-D6AQNMUA.js";
137
140
  import {
138
141
  getErrorMessage as getErrorMessage2
139
- } from "./chunk-54TF2ZIQ.js";
140
- import "./chunk-4VZCORNT.js";
141
- import "./chunk-N7EYO2E7.js";
142
+ } from "./chunk-6JXHO7LG.js";
143
+ import "./chunk-RXT4QBDX.js";
144
+ import "./chunk-XQ4RDO5B.js";
142
145
  import {
143
146
  setUpdateHandler
144
- } from "./chunk-JLWFGYXU.js";
147
+ } from "./chunk-T2IHCZLS.js";
145
148
  import "./chunk-EKTCKZV5.js";
146
- import "./chunk-43JNQAHO.js";
149
+ import "./chunk-YCEKI7QX.js";
147
150
  import "./chunk-YAF2MQZ6.js";
148
151
  import "./chunk-24FVUD5P.js";
149
- import "./chunk-IKLFS6SC.js";
152
+ import "./chunk-3YQMUBTS.js";
150
153
  import "./chunk-6H67XLET.js";
151
- import "./chunk-KK2GZGBK.js";
154
+ import "./chunk-TWWS7XUW.js";
152
155
  import "./chunk-M3JGHRMQ.js";
153
156
  import "./chunk-VFFQAOPR.js";
154
- import "./chunk-ZTAVGFKA.js";
157
+ import "./chunk-ERXNTINK.js";
155
158
  import {
156
159
  cpLen,
157
160
  escapeAnsiCtrlCodes,
@@ -174,48 +177,51 @@ import {
174
177
  import {
175
178
  formatUnsupportedVoiceModelMessage,
176
179
  isSelectableVoiceModel
177
- } from "./chunk-XOVVCGZX.js";
180
+ } from "./chunk-NB3NDQQK.js";
178
181
  import "./chunk-Y53DG2HA.js";
179
182
  import {
180
183
  getExtendedSystemInfo
181
- } from "./chunk-P6LATTDG.js";
182
- import "./chunk-YCDL2SAS.js";
184
+ } from "./chunk-5IL2BZHW.js";
185
+ import "./chunk-6QILGINT.js";
183
186
  import "./chunk-7U5G6JXI.js";
184
187
  import "./chunk-WCCLLK7X.js";
185
- import "./chunk-O2GG7H4C.js";
188
+ import {
189
+ getReasoningEffortsForConfig
190
+ } from "./chunk-JGDRB4FP.js";
191
+ import "./chunk-ARYNBBBM.js";
186
192
  import "./chunk-HWVUSYSN.js";
187
- import "./chunk-537SQ2AI.js";
188
- import "./chunk-IXSGOSEG.js";
189
- import "./chunk-AHBLRVD5.js";
193
+ import "./chunk-5WC2ECUK.js";
194
+ import "./chunk-DZ6D4B3K.js";
195
+ import "./chunk-EEKU6COG.js";
190
196
  import "./chunk-57OAHC2Y.js";
191
- import "./chunk-TMWB67LS.js";
192
- import "./chunk-4IQKBLTQ.js";
193
- import "./chunk-WXC6OAWD.js";
197
+ import "./chunk-UXDVUFKU.js";
198
+ import "./chunk-UHUT4IDM.js";
199
+ import "./chunk-3BTHHXXE.js";
194
200
  import "./chunk-V6WHFGST.js";
195
201
  import {
196
202
  createLoadedSettingsAdapter
197
- } from "./chunk-4F2QRVW6.js";
198
- import "./chunk-P4RUUG64.js";
203
+ } from "./chunk-FW4E4QPG.js";
204
+ import "./chunk-45ROPFQY.js";
199
205
  import "./chunk-2AUM35J5.js";
200
206
  import "./chunk-N6VQ37ZZ.js";
201
- import "./chunk-WEXA2DNG.js";
207
+ import "./chunk-PSPAM24S.js";
202
208
  import "./chunk-6PLDPT2C.js";
203
209
  import "./chunk-FYJ7W2PI.js";
204
210
  import "./chunk-STUJ7IMZ.js";
205
- import "./chunk-4JAGXZR3.js";
211
+ import "./chunk-GM44O6F7.js";
206
212
  import "./chunk-GYTKQYDB.js";
207
213
  import "./chunk-ALMR3E6Q.js";
208
214
  import "./chunk-RKFGE7JH.js";
209
215
  import "./chunk-UDG5EZJI.js";
210
216
  import "./chunk-M5GB774H.js";
211
217
  import "./chunk-3VUENPWF.js";
212
- import "./chunk-VDXYYVCD.js";
218
+ import "./chunk-XVTCSVBK.js";
213
219
  import "./chunk-IW6RQPQB.js";
214
220
  import "./chunk-5HBA2Z7V.js";
215
221
  import "./chunk-X35VIWWJ.js";
216
222
  import {
217
223
  loadMcpApprovals
218
- } from "./chunk-DNPHKA72.js";
224
+ } from "./chunk-TGC4264Q.js";
219
225
  import {
220
226
  getDefaultValue,
221
227
  getDialogSettingKeys,
@@ -231,26 +237,26 @@ import {
231
237
  saveModifiedSettings,
232
238
  setPendingSettingValueAny,
233
239
  validateSettingValue
234
- } from "./chunk-AQ5NAGWI.js";
240
+ } from "./chunk-66JBCTJF.js";
235
241
  import {
236
242
  TOGGLE_TYPES
237
- } from "./chunk-ER273QE6.js";
243
+ } from "./chunk-2ZFO5JD7.js";
238
244
  import "./chunk-RKUWKYED.js";
239
245
  import "./chunk-BW4333PP.js";
240
246
  import "./chunk-IDS7MSUP.js";
241
247
  import {
242
248
  t
243
- } from "./chunk-MUZCSTOO.js";
249
+ } from "./chunk-CRZBDVP2.js";
244
250
  import "./chunk-5EJZE3FP.js";
245
- import "./chunk-H3UDNQLO.js";
246
- import "./chunk-NUQFUXOG.js";
251
+ import "./chunk-5CVY5Q2P.js";
252
+ import "./chunk-QTNCGZHQ.js";
247
253
  import "./chunk-2EAZ43JQ.js";
248
254
  import "./chunk-NF5J2WFA.js";
249
255
  import {
250
256
  getCliVersion
251
- } from "./chunk-XUSOYE2I.js";
257
+ } from "./chunk-27LTEY6D.js";
252
258
  import "./chunk-W3N5XAZ6.js";
253
- import "./chunk-XY3USGFE.js";
259
+ import "./chunk-3VDLQUR2.js";
254
260
  import "./chunk-NPQ5ZKRP.js";
255
261
  import "./chunk-MR3PXB6E.js";
256
262
  import {
@@ -265,26 +271,27 @@ import {
265
271
  findExistingProviderModels,
266
272
  findProviderByCredentials,
267
273
  findProviderById,
274
+ generatePromptSuggestion,
268
275
  getDefaultModelIds,
269
276
  resolveMetadataKey
270
- } from "./chunk-UEZOXZNI.js";
277
+ } from "./chunk-ZU2T5JIS.js";
271
278
  import "./chunk-GELRJXE2.js";
272
279
  import "./chunk-32CM56LO.js";
273
- import "./chunk-JPEAQJNS.js";
280
+ import "./chunk-WJDXKQIO.js";
274
281
  import "./chunk-XFSFZCM5.js";
275
- import "./chunk-WTW36TJ3.js";
282
+ import "./chunk-2EKVPSIJ.js";
276
283
  import "./chunk-LJZSMWOH.js";
277
- import "./chunk-VUSSAGKI.js";
278
- import "./chunk-O45WBTNS.js";
284
+ import "./chunk-YZTGGCEE.js";
285
+ import "./chunk-6SADVYQQ.js";
279
286
  import "./chunk-DJXSOEFB.js";
280
- import "./chunk-2WGJG2KW.js";
281
- import "./chunk-QMFOYPGV.js";
282
- import "./chunk-LDS57224.js";
287
+ import "./chunk-25CBAK3H.js";
288
+ import "./chunk-J3VZF2AL.js";
289
+ import "./chunk-OWCFKIFQ.js";
283
290
  import "./chunk-ZPJWUGCS.js";
284
- import "./chunk-HFTB354P.js";
291
+ import "./chunk-5Z4FCEPY.js";
285
292
  import "./chunk-BUQN5LTI.js";
286
- import "./chunk-VU7O7CGQ.js";
287
- import "./chunk-QSC5YOEC.js";
293
+ import "./chunk-XDNFODER.js";
294
+ import "./chunk-YAC7H4K3.js";
288
295
  import "./chunk-VNOVK4I7.js";
289
296
  import {
290
297
  CoreToolScheduler,
@@ -294,6 +301,7 @@ import {
294
301
  OAUTH_AUTH_URL_EVENT,
295
302
  OAUTH_DISPLAY_MESSAGE_EVENT,
296
303
  SessionService,
304
+ ShellExecutionService,
297
305
  allowEditorTypeInSandbox,
298
306
  checkForExtensionUpdate,
299
307
  checkHasEditorType,
@@ -306,6 +314,7 @@ import {
306
314
  isGatedMcpScope,
307
315
  isImageGenerationCapable,
308
316
  isSettledStatus,
317
+ isSignalTermination,
309
318
  isSuccessStatus,
310
319
  matchesAnyServerPattern,
311
320
  mcpServerRequiresOAuth,
@@ -313,18 +322,18 @@ import {
313
322
  parseRule,
314
323
  parseVisionModelSetting,
315
324
  refreshMemoryInstruction
316
- } from "./chunk-I72PHOKL.js";
325
+ } from "./chunk-PDUMGZ2P.js";
317
326
  import "./chunk-GOFAQQZA.js";
318
- import "./chunk-3K65MUKD.js";
327
+ import "./chunk-65I7S4Z3.js";
319
328
  import "./chunk-6HUXPLB5.js";
320
329
  import "./chunk-TWPJO254.js";
321
330
  import "./chunk-CQ35AJ4Z.js";
322
331
  import "./chunk-YHDGABDC.js";
323
- import "./chunk-RDKXZ2LS.js";
332
+ import "./chunk-LYT2OU7D.js";
324
333
  import "./chunk-B54PFQS5.js";
325
334
  import {
326
335
  writeRuntimeStatus
327
- } from "./chunk-43NOB5NM.js";
336
+ } from "./chunk-HIXUUCGY.js";
328
337
  import "./chunk-6PVPNMXU.js";
329
338
  import {
330
339
  resolveModelId
@@ -335,14 +344,14 @@ import "./chunk-QHWCP53L.js";
335
344
  import "./chunk-F53KKZUD.js";
336
345
  import {
337
346
  resolveBundleDir
338
- } from "./chunk-PZV2FASB.js";
347
+ } from "./chunk-TRWQQBVH.js";
339
348
  import "./chunk-QJNDUTOL.js";
340
- import "./chunk-OECNP26L.js";
349
+ import "./chunk-N6S3NUYJ.js";
341
350
  import "./chunk-O6GEWCJA.js";
342
351
  import {
343
352
  formatMemoryUsage
344
353
  } from "./chunk-CHEIIBT3.js";
345
- import "./chunk-UKKYOIVT.js";
354
+ import "./chunk-QAZ2MGYT.js";
346
355
  import {
347
356
  registerSession
348
357
  } from "./chunk-B44JBZBB.js";
@@ -350,34 +359,34 @@ import "./chunk-BF3RUIVP.js";
350
359
  import {
351
360
  APPROVAL_MODES
352
361
  } from "./chunk-JX6XHPTX.js";
353
- import "./chunk-R355CUNQ.js";
354
- import "./chunk-4VUVBN3Y.js";
362
+ import "./chunk-CLKE4IY3.js";
355
363
  import "./chunk-ZSTCM3MX.js";
356
- import "./chunk-NXWYCSPL.js";
364
+ import "./chunk-SOA4HKRJ.js";
357
365
  import "./chunk-MLXTMF7H.js";
358
- import "./chunk-GXZHYPHZ.js";
366
+ import "./chunk-3LPJ776W.js";
359
367
  import "./chunk-3CZ2BQV6.js";
360
368
  import "./chunk-PQEISIKS.js";
361
- import "./chunk-3K456UJF.js";
362
- import "./chunk-VEFRT7NX.js";
369
+ import "./chunk-VF6D6EGV.js";
370
+ import "./chunk-H3Q3RSKZ.js";
363
371
  import "./chunk-S6LOFUVP.js";
364
372
  import "./chunk-NAVJD2PQ.js";
365
- import "./chunk-UKADFFL2.js";
366
- import "./chunk-EJNYBDYC.js";
373
+ import "./chunk-OFVAS4AR.js";
374
+ import "./chunk-HNLMYDQE.js";
367
375
  import "./chunk-QHMLYMMS.js";
368
376
  import "./chunk-CFKIH3D3.js";
369
377
  import {
370
378
  REASONING_EFFORT_TIERS,
371
379
  applyReasoningEffort
372
- } from "./chunk-2LD5U7Q3.js";
380
+ } from "./chunk-6YEOCHSE.js";
373
381
  import "./chunk-DJ2GSRLV.js";
374
- import "./chunk-W4LL5RZO.js";
375
- import "./chunk-3UMWOKJC.js";
382
+ import "./chunk-4ALNJDHL.js";
383
+ import "./chunk-NOO4QFXM.js";
376
384
  import "./chunk-KFFCDLKV.js";
377
385
  import "./chunk-7OCIQNKX.js";
378
386
  import {
379
387
  AuthEvent,
380
388
  ModelSlashCommandEvent,
389
+ PromptSuggestionEvent,
381
390
  collectText,
382
391
  formatFullTurnVisionNotice,
383
392
  formatVisionBridgeNotice,
@@ -387,6 +396,7 @@ import {
387
396
  isImageCapable,
388
397
  logAuth,
389
398
  logModelSlashCommand,
399
+ logPromptSuggestion,
390
400
  logSlashCommand,
391
401
  makeSlashCommandEvent,
392
402
  normalizeParts,
@@ -396,7 +406,7 @@ import {
396
406
  shouldRunVisionBridge,
397
407
  splitImageParts,
398
408
  uiTelemetryService
399
- } from "./chunk-P5LDR7FI.js";
409
+ } from "./chunk-6QV7Z74P.js";
400
410
  import "./chunk-5ETULJLP.js";
401
411
  import "./chunk-XBVNNDPK.js";
402
412
  import "./chunk-VGC4I5JJ.js";
@@ -410,25 +420,26 @@ import "./chunk-HD7O6WLV.js";
410
420
  import "./chunk-WZAD4ZNJ.js";
411
421
  import "./chunk-FPGTNKCP.js";
412
422
  import "./chunk-TIGXX4PA.js";
413
- import "./chunk-5MTARK4Y.js";
423
+ import "./chunk-N7YQEKGX.js";
414
424
  import "./chunk-XFFRI3WM.js";
415
425
  import "./chunk-4HOEU2OR.js";
416
426
  import "./chunk-HHJLM3WQ.js";
417
427
  import {
428
+ isBinary,
418
429
  redactUrlCredentials
419
430
  } from "./chunk-7VEYUF3N.js";
420
431
  import "./chunk-74TONY4F.js";
421
- import "./chunk-GMNLYQOS.js";
422
- import "./chunk-D6PIMKY3.js";
423
- import "./chunk-NGX4NUNP.js";
424
- import "./chunk-FKJM6JKY.js";
432
+ import "./chunk-E6TI726I.js";
433
+ import "./chunk-4VY3ITHR.js";
434
+ import "./chunk-O2FEO2CB.js";
435
+ import "./chunk-G6UUOCUT.js";
425
436
  import {
426
437
  isPathWithinRoot
427
438
  } from "./chunk-IZ2U57NY.js";
428
439
  import {
429
440
  ToolNames,
430
441
  isShellProgressData
431
- } from "./chunk-RPBMP6BN.js";
442
+ } from "./chunk-MWIO7MF6.js";
432
443
  import {
433
444
  Storage,
434
445
  createDebugLogger,
@@ -436,12 +447,12 @@ import {
436
447
  getErrorMessage,
437
448
  isDebugLogFileEnabled
438
449
  } from "./chunk-ZAFYHRVY.js";
439
- import "./chunk-TDP7UULF.js";
450
+ import "./chunk-OPMKGOLD.js";
440
451
  import "./chunk-HRPFBHW7.js";
441
452
  import {
442
453
  registerCleanup,
443
454
  runExitCleanup
444
- } from "./chunk-BKNY7PDI.js";
455
+ } from "./chunk-USN6VNTO.js";
445
456
  import {
446
457
  profileCheckpoint
447
458
  } from "./chunk-QILD6R27.js";
@@ -453,7 +464,10 @@ import {
453
464
  import "./chunk-75DOP5OR.js";
454
465
  import "./chunk-DMTGGOSA.js";
455
466
  import "./chunk-YQ3U5MUC.js";
467
+ import "./chunk-EFT7OMDN.js";
456
468
  import "./chunk-MATEIJZF.js";
469
+ import "./chunk-J5TTWBZK.js";
470
+ import "./chunk-RVIGZBIT.js";
457
471
  import "./chunk-TBWQLLFO.js";
458
472
  import {
459
473
  init_esbuild_shims
@@ -490,7 +504,7 @@ var require_jsx_dev_runtime = __commonJS({
490
504
 
491
505
  // packages/cli/src/ui/opentui/start-opentui-ui.tsx
492
506
  init_esbuild_shims();
493
- var import_react52 = __toESM(require_react(), 1);
507
+ var import_react55 = __toESM(require_react(), 1);
494
508
  import { stat as stat2 } from "node:fs/promises";
495
509
  import { basename as basename3 } from "node:path";
496
510
 
@@ -539,9 +553,9 @@ function requiredOpenTuiAssetKeys(platform = process.platform, arch = process.ar
539
553
  ];
540
554
  }
541
555
  __name(requiredOpenTuiAssetKeys, "requiredOpenTuiAssetKeys");
542
- function isFile(path6) {
556
+ function isFile(path7) {
543
557
  try {
544
- return statSync(path6).isFile();
558
+ return statSync(path7).isFile();
545
559
  } catch {
546
560
  return false;
547
561
  }
@@ -926,11 +940,11 @@ function toBunPointer(pointer) {
926
940
  __name(toBunPointer, "toBunPointer");
927
941
  function createBunBackend(bun2) {
928
942
  return {
929
- dlopen(path6, symbols) {
930
- if (path6 === null) {
943
+ dlopen(path7, symbols) {
944
+ if (path7 === null) {
931
945
  throw new Error(BUN_DLOPEN_NULL);
932
946
  }
933
- const library = bun2.dlopen(path6, normalizeBunDefinitions(symbols));
947
+ const library = bun2.dlopen(path7, normalizeBunDefinitions(symbols));
934
948
  const callbacks = /* @__PURE__ */ new Set();
935
949
  let closed = false;
936
950
  return {
@@ -967,8 +981,8 @@ function createBunBackend(bun2) {
967
981
  __name(createBunBackend, "createBunBackend");
968
982
  function createNodeBackend(nodeFfi) {
969
983
  return {
970
- dlopen(path6, symbols) {
971
- const { lib: lib2, functions } = nodeFfi.dlopen(toNodeLibraryPath(path6), normalizeNodeDefinitions(symbols));
984
+ dlopen(path7, symbols) {
985
+ const { lib: lib2, functions } = nodeFfi.dlopen(toNodeLibraryPath(path7), normalizeNodeDefinitions(symbols));
972
986
  const callbacks = /* @__PURE__ */ new Set();
973
987
  let closed = false;
974
988
  let libraryClosed = false;
@@ -1019,8 +1033,8 @@ function createNodeBackend(nodeFfi) {
1019
1033
  };
1020
1034
  }
1021
1035
  __name(createNodeBackend, "createNodeBackend");
1022
- function toNodeLibraryPath(path6) {
1023
- return path6 instanceof URL ? fileURLToPath(path6) : path6;
1036
+ function toNodeLibraryPath(path7) {
1037
+ return path7 instanceof URL ? fileURLToPath(path7) : path7;
1024
1038
  }
1025
1039
  __name(toNodeLibraryPath, "toNodeLibraryPath");
1026
1040
  function normalizeNodeDefinitions(definitions) {
@@ -8340,8 +8354,8 @@ function resolveParserAsset(relativePath) {
8340
8354
  return resolveDefaultParserAsset(relativePath, new URL(`./${relativePath}`, import.meta.url));
8341
8355
  }
8342
8356
  __name(resolveParserAsset, "resolveParserAsset");
8343
- function isBunfsPath(path6) {
8344
- return path6.includes("$bunfs") || /^B:[\\/]~BUN/i.test(path6);
8357
+ function isBunfsPath(path7) {
8358
+ return path7.includes("$bunfs") || /^B:[\\/]~BUN/i.test(path7);
8345
8359
  }
8346
8360
  __name(isBunfsPath, "isBunfsPath");
8347
8361
  function getBunfsRootPath() {
@@ -8626,7 +8640,7 @@ registerEnvVar({
8626
8640
  default: ""
8627
8641
  });
8628
8642
  var DEFAULT_PARSER_OVERRIDES = [];
8629
- var isUrl = /* @__PURE__ */ __name((path6) => path6.startsWith("http://") || path6.startsWith("https://"), "isUrl");
8643
+ var isUrl = /* @__PURE__ */ __name((path7) => path7.startsWith("http://") || path7.startsWith("https://"), "isUrl");
8630
8644
  var TreeSitterClient = class extends EventEmitter2 {
8631
8645
  static {
8632
8646
  __name(this, "TreeSitterClient");
@@ -8857,17 +8871,17 @@ var TreeSitterClient = class extends EventEmitter2 {
8857
8871
  worker.postMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser: this.resolveFiletypeParser(parser) });
8858
8872
  }
8859
8873
  }
8860
- resolvePath(path6) {
8861
- if (isUrl(path6)) {
8862
- return path6;
8874
+ resolvePath(path7) {
8875
+ if (isUrl(path7)) {
8876
+ return path7;
8863
8877
  }
8864
- if (isBunfsPath(path6)) {
8865
- return normalizeBunfsPath(parse(path6).base);
8878
+ if (isBunfsPath(path7)) {
8879
+ return normalizeBunfsPath(parse(path7).base);
8866
8880
  }
8867
- if (!isAbsolute3(path6)) {
8868
- return resolve2(path6);
8881
+ if (!isAbsolute3(path7)) {
8882
+ return resolve2(path7);
8869
8883
  }
8870
- return path6;
8884
+ return path7;
8871
8885
  }
8872
8886
  addFiletypeParser(filetypeParser) {
8873
8887
  this.sendWorkerMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser: this.resolveFiletypeParser(filetypeParser) });
@@ -8878,8 +8892,8 @@ var TreeSitterClient = class extends EventEmitter2 {
8878
8892
  aliases: filetypeParser.aliases ? [...new Set(filetypeParser.aliases.filter((alias) => alias !== filetypeParser.filetype))] : void 0,
8879
8893
  wasm: this.resolvePath(filetypeParser.wasm),
8880
8894
  queries: {
8881
- highlights: filetypeParser.queries.highlights.map((path6) => this.resolvePath(path6)),
8882
- injections: filetypeParser.queries.injections?.map((path6) => this.resolvePath(path6))
8895
+ highlights: filetypeParser.queries.highlights.map((path7) => this.resolvePath(path7)),
8896
+ injections: filetypeParser.queries.injections?.map((path7) => this.resolvePath(path7))
8883
8897
  }
8884
8898
  };
8885
8899
  }
@@ -31202,11 +31216,11 @@ async function readResponseBytes(response, signal) {
31202
31216
  return data.byteLength === total ? data : data.slice(0, total);
31203
31217
  }
31204
31218
  __name(readResponseBytes, "readResponseBytes");
31205
- async function readFileBytes(path6, signal) {
31219
+ async function readFileBytes(path7, signal) {
31206
31220
  signal?.throwIfAborted();
31207
- if ((await stat(path6)).size > MAX_ENCODED_BYTES)
31221
+ if ((await stat(path7)).size > MAX_ENCODED_BYTES)
31208
31222
  throw imageError(6);
31209
- const file = await open(path6, "r");
31223
+ const file = await open(path7, "r");
31210
31224
  const chunks = [];
31211
31225
  let total = 0;
31212
31226
  try {
@@ -31298,10 +31312,10 @@ var NativeImage = class _NativeImage {
31298
31312
  }
31299
31313
  const url = source instanceof URL ? source : (/^(?:https?|file|blob|data):/i.test(source) || /^[a-z][a-z0-9+.-]*:\/\//i.test(source)) && !/^[a-z]:[\\/]/i.test(source) ? new URL(source) : null;
31300
31314
  if (!url || url.protocol === "file:") {
31301
- const path6 = url ?? source;
31315
+ const path7 = url ?? source;
31302
31316
  let data;
31303
31317
  try {
31304
- data = await readFileBytes(path6, options.signal);
31318
+ data = await readFileBytes(path7, options.signal);
31305
31319
  } catch (error) {
31306
31320
  if (options.signal?.aborted)
31307
31321
  throw options.signal.reason;
@@ -40990,9 +41004,27 @@ var PluginErrorBoundary = class extends import_react14.default.Component {
40990
41004
  };
40991
41005
  extend({ "time-to-first-draw": TimeToFirstDrawRenderable });
40992
41006
 
41007
+ // packages/cli/src/ui/opentui/use-update-notice-flush.ts
41008
+ init_esbuild_shims();
41009
+ var import_react17 = __toESM(require_react(), 1);
41010
+ function useUpdateNoticeFlush(addItem, setUpdateInfo, isIdleRef, streaming) {
41011
+ const updateHandlerRef = (0, import_react17.useRef)(
41012
+ null
41013
+ );
41014
+ (0, import_react17.useEffect)(() => {
41015
+ const handler = setUpdateHandler(addItem, setUpdateInfo, isIdleRef);
41016
+ updateHandlerRef.current = handler;
41017
+ return handler.cleanup;
41018
+ }, [addItem, setUpdateInfo, isIdleRef]);
41019
+ (0, import_react17.useEffect)(() => {
41020
+ if (!streaming) updateHandlerRef.current?.flush();
41021
+ }, [streaming]);
41022
+ }
41023
+ __name(useUpdateNoticeFlush, "useUpdateNoticeFlush");
41024
+
40993
41025
  // packages/cli/src/ui/opentui/opentui-app-shell.tsx
40994
41026
  init_esbuild_shims();
40995
- var import_react49 = __toESM(require_react(), 1);
41027
+ var import_react50 = __toESM(require_react(), 1);
40996
41028
 
40997
41029
  // packages/cli/src/ui/opentui/opentui-host.ts
40998
41030
  init_esbuild_shims();
@@ -42232,6 +42264,22 @@ function projectItemToStreamEvent(item, ctx) {
42232
42264
  type: "warning",
42233
42265
  text: formatUserPromptSubmitBlocked(item.reason, item.originalPrompt)
42234
42266
  };
42267
+ case "away_recap":
42268
+ return { type: "away-recap", text: item.text };
42269
+ case "user_shell":
42270
+ return { type: "user-shell", text: item.text };
42271
+ case "advisor":
42272
+ return { type: "advisor", text: item.text, model: item.model };
42273
+ case "arena_agent_complete":
42274
+ return { type: "arena-agent", agent: item.agent };
42275
+ case "arena_session_complete":
42276
+ return {
42277
+ type: "arena-session",
42278
+ sessionStatus: item.sessionStatus,
42279
+ task: item.task,
42280
+ totalDurationMs: item.totalDurationMs,
42281
+ agents: item.agents
42282
+ };
42235
42283
  case "about":
42236
42284
  case "tools_list":
42237
42285
  case "model_stats":
@@ -42258,11 +42306,10 @@ function projectItemToStreamEvent(item, ctx) {
42258
42306
  // - `help`: `/help` resolves to a dialog and the overlay renders from
42259
42307
  // help-content.ts; no command returns a HELP message, so nothing writes
42260
42308
  // this item in either renderer.
42261
- // - the rest: ink renders these through dedicated components and this
42262
- // renderer has no row shape for them yet. `/advisor`, `/arena` and
42263
- // `/recap` are registered here and do write four of these kinds, so
42264
- // their output stays invisible a registered gap (U-34), not an
42265
- // accident of the switch.
42309
+ // - the rest: ink renders these through dedicated components and no
42310
+ // OpenTUI writer produces them (tool_use_summary is written by ink's
42311
+ // use-llm-stream only; diff_stats comes from the file-history rewind
42312
+ // flow, which has no OpenTUI seam; notification has no writer yet).
42266
42313
  case "tool_group":
42267
42314
  case "retry_countdown":
42268
42315
  case "vision_notice":
@@ -42272,11 +42319,6 @@ function projectItemToStreamEvent(item, ctx) {
42272
42319
  case "gemini_thought_content":
42273
42320
  case "help":
42274
42321
  case "notification":
42275
- case "user_shell":
42276
- case "advisor":
42277
- case "arena_agent_complete":
42278
- case "arena_session_complete":
42279
- case "away_recap":
42280
42322
  case "tool_use_summary":
42281
42323
  case "diff_stats":
42282
42324
  return null;
@@ -42313,8 +42355,10 @@ function transcribeSession(jsonl, opts = {}) {
42313
42355
  }
42314
42356
  const parts = o.message?.parts ?? [];
42315
42357
  if (o.type === "user") {
42316
- if (o.subtype) continue;
42317
- const text = parts.filter((p2) => p2.text && !p2.thought).map((p2) => p2.text).join("\n");
42358
+ if (o.subtype && o.subtype !== "mid_turn_user_message") continue;
42359
+ const partsText = parts.filter((p2) => p2.text && !p2.thought).map((p2) => p2.text).join("\n");
42360
+ const hasAttachmentReferences = Array.isArray(o.systemPayload?.attachmentReferences) && o.systemPayload.attachmentReferences.length > 0;
42361
+ const text = o.systemPayload?.displayText || (hasAttachmentReferences ? "[User message with attachments]" : partsText);
42318
42362
  if (text) {
42319
42363
  events.push({ type: "user", text });
42320
42364
  prompts.push(text);
@@ -42883,6 +42927,620 @@ var OpenTuiAppHost = class {
42883
42927
  }
42884
42928
  };
42885
42929
 
42930
+ // packages/cli/src/ui/opentui/shell-mode.ts
42931
+ init_esbuild_shims();
42932
+ import crypto from "node:crypto";
42933
+ import fs2 from "node:fs";
42934
+ import os2 from "node:os";
42935
+ import path4 from "node:path";
42936
+ var OUTPUT_UPDATE_INTERVAL_MS = 1e3;
42937
+ async function executeUserShell(config, rawQuery, emit, signal, terminalSize) {
42938
+ const callId = `shell-${crypto.randomUUID()}`;
42939
+ emit({ type: "user-shell", text: rawQuery });
42940
+ emit({
42941
+ type: "tool-start",
42942
+ id: callId,
42943
+ tool: "run_shell_command",
42944
+ title: "run_shell_command"
42945
+ });
42946
+ emit({ type: "tool-description", id: callId, description: rawQuery });
42947
+ const targetDir = config.getTargetDir();
42948
+ let commandToExecute = rawQuery;
42949
+ let pwdFilePath;
42950
+ if (os2.platform() !== "win32") {
42951
+ let command = rawQuery.trim();
42952
+ const pwdFileName = `shell_pwd_${crypto.randomBytes(6).toString("hex")}.tmp`;
42953
+ pwdFilePath = path4.join(os2.tmpdir(), pwdFileName);
42954
+ const trailingBackslashes = /\\+$/.exec(command)?.[0].length ?? 0;
42955
+ if (trailingBackslashes % 2 === 1) {
42956
+ command += "\n";
42957
+ }
42958
+ if (!command.endsWith(";") && !command.endsWith("&")) {
42959
+ command += ";";
42960
+ }
42961
+ commandToExecute = `{ ${command}
42962
+ }; __code=$?; pwd > "${pwdFilePath}"; exit $__code`;
42963
+ }
42964
+ const usePty = config.getShouldUseNodePtyShell();
42965
+ const client = config.getGeminiClient();
42966
+ const chatAtStart = client.isInitialized() ? client.getChat() : void 0;
42967
+ let cumulative = "";
42968
+ let emittedText = "";
42969
+ let isBinaryStream = false;
42970
+ let lastUpdate = Date.now();
42971
+ const onOutputEvent = /* @__PURE__ */ __name((event) => {
42972
+ switch (event.type) {
42973
+ case "data":
42974
+ if (!isBinaryStream && !usePty && typeof event.chunk === "string") {
42975
+ cumulative += event.chunk;
42976
+ }
42977
+ break;
42978
+ case "binary_detected":
42979
+ case "binary_progress":
42980
+ isBinaryStream = true;
42981
+ break;
42982
+ default: {
42983
+ throw new Error("An unhandled ShellOutputEvent was found.");
42984
+ }
42985
+ }
42986
+ if (!usePty && !isBinaryStream && Date.now() - lastUpdate > OUTPUT_UPDATE_INTERVAL_MS && cumulative.length > emittedText.length) {
42987
+ const delta = cumulative.slice(emittedText.length);
42988
+ emittedText += delta;
42989
+ emit({ type: "tool-output", id: callId, delta });
42990
+ lastUpdate = Date.now();
42991
+ }
42992
+ }, "onOutputEvent");
42993
+ const cleanup = /* @__PURE__ */ __name(() => {
42994
+ if (pwdFilePath && fs2.existsSync(pwdFilePath)) {
42995
+ fs2.unlinkSync(pwdFilePath);
42996
+ }
42997
+ }, "cleanup");
42998
+ return ShellExecutionService.execute(
42999
+ commandToExecute,
43000
+ targetDir,
43001
+ onOutputEvent,
43002
+ signal,
43003
+ usePty,
43004
+ {
43005
+ ...config.getShellExecutionConfig(),
43006
+ terminalWidth: terminalSize.width,
43007
+ terminalHeight: terminalSize.height
43008
+ }
43009
+ ).then(
43010
+ ({ result }) => result.then((res) => {
43011
+ let success = true;
43012
+ let summary = "ok";
43013
+ let prefixText = "";
43014
+ if (res.error) {
43015
+ success = false;
43016
+ summary = "error";
43017
+ prefixText = `${res.error.message}
43018
+ `;
43019
+ } else if (res.aborted) {
43020
+ success = false;
43021
+ summary = "cancelled";
43022
+ prefixText = "Command was cancelled.\n";
43023
+ } else if (isSignalTermination(res.signal)) {
43024
+ success = false;
43025
+ summary = "error";
43026
+ prefixText = `Command terminated by signal: ${res.signal}.
43027
+ `;
43028
+ } else if (res.exitCode !== 0) {
43029
+ success = false;
43030
+ summary = "error";
43031
+ prefixText = `Command exited with code ${res.exitCode}.
43032
+ `;
43033
+ }
43034
+ if (pwdFilePath && fs2.existsSync(pwdFilePath)) {
43035
+ const finalPwd = fs2.readFileSync(pwdFilePath, "utf8").trim();
43036
+ if (finalPwd && finalPwd !== targetDir) {
43037
+ prefixText = `WARNING: shell mode is stateless; the directory change to '${finalPwd}' will not persist.
43038
+
43039
+ ${prefixText}`;
43040
+ }
43041
+ }
43042
+ const mainContent = isBinary(res.rawOutput) ? "[Command produced binary output, which is not shown.]" : res.output.trim() || "(Command produced no output)";
43043
+ const emittedTrimmed = emittedText.trimEnd();
43044
+ const tail = emittedTrimmed && mainContent.startsWith(emittedTrimmed) ? mainContent.slice(emittedTrimmed.length) : mainContent;
43045
+ const finalOutput = tail ? `${prefixText}${tail}` : prefixText ? `
43046
+ ${prefixText}` : "";
43047
+ emit({ type: "tool-result", id: callId, display: finalOutput });
43048
+ emit({
43049
+ type: "tool-end",
43050
+ id: callId,
43051
+ success,
43052
+ summary
43053
+ });
43054
+ if (client.isInitialized() && client.getChat() === chatAtStart) {
43055
+ addShellCommandToLlmHistory(
43056
+ config.getGeminiClient(),
43057
+ rawQuery,
43058
+ `${prefixText}${mainContent}`
43059
+ );
43060
+ }
43061
+ })
43062
+ ).catch((err) => {
43063
+ const errorMessage = err instanceof Error ? err.message : String(err);
43064
+ emit({
43065
+ type: "error",
43066
+ text: `An unexpected error occurred: ${errorMessage}`
43067
+ });
43068
+ emit({
43069
+ type: "tool-end",
43070
+ id: callId,
43071
+ success: false,
43072
+ summary: "error"
43073
+ });
43074
+ }).finally(cleanup);
43075
+ }
43076
+ __name(executeUserShell, "executeUserShell");
43077
+
43078
+ // packages/cli/src/ui/opentui/messages.tsx
43079
+ init_esbuild_shims();
43080
+
43081
+ // packages/cli/src/ui/opentui/theme.ts
43082
+ init_esbuild_shims();
43083
+ var DARK = {
43084
+ text: "#CDD6F4",
43085
+ dim: "#6C7086",
43086
+ accent: "#CBA6F7",
43087
+ green: "#A6E3A1",
43088
+ red: "#F38BA8",
43089
+ yellow: "#F9E2AF",
43090
+ purple: "#89B4FA",
43091
+ hover: "#313244",
43092
+ // No bg on dark: the default invert selection (bg=text fg, fg=black) is
43093
+ // readable on dark terminals, and leaving bg unset keeps transparency.
43094
+ selectionBg: "#264F78",
43095
+ selectionFg: "#FFFFFF"
43096
+ };
43097
+ var C2 = { ...DARK };
43098
+ function buildSyntax(mode) {
43099
+ const styles = mode === "light" ? {
43100
+ // `default` colors unstyled markdown chunks (table cells, plain
43101
+ // inline text); without it TextTable falls back to #FFFFFF.
43102
+ default: { fg: "#1f2328" },
43103
+ keyword: { fg: "#cf222e", bold: true },
43104
+ string: { fg: "#0a3069" },
43105
+ comment: { fg: "#59636e", italic: true },
43106
+ function: { fg: "#8250df" },
43107
+ type: { fg: "#953800" },
43108
+ number: { fg: "#0550ae" },
43109
+ operator: { fg: "#0550ae" },
43110
+ variable: { fg: "#1f2328" },
43111
+ heading: { fg: "#0550ae", bold: true },
43112
+ emphasis: { italic: true },
43113
+ strong: { bold: true },
43114
+ link: { fg: "#0969da" },
43115
+ code: { fg: "#0a3069" }
43116
+ } : {
43117
+ default: { fg: "#e6edf3" },
43118
+ keyword: { fg: "#bb9af7", bold: true },
43119
+ string: { fg: "#9ece6a" },
43120
+ comment: { fg: "#565f89", italic: true },
43121
+ function: { fg: "#7aa2f7" },
43122
+ type: { fg: "#e0af68" },
43123
+ number: { fg: "#ff9e64" },
43124
+ operator: { fg: "#89ddff" },
43125
+ variable: { fg: "#e6edf3" },
43126
+ heading: { fg: "#7aa2f7", bold: true },
43127
+ emphasis: { italic: true },
43128
+ strong: { bold: true },
43129
+ link: { fg: "#7aa2f7" },
43130
+ code: { fg: "#9ece6a" }
43131
+ };
43132
+ return SyntaxStyle.fromStyles({
43133
+ ...styles,
43134
+ ...markdownMarkupTokens(mode)
43135
+ });
43136
+ }
43137
+ __name(buildSyntax, "buildSyntax");
43138
+ function markdownMarkupTokens(mode) {
43139
+ const heading = mode === "light" ? "#0550ae" : "#7aa2f7";
43140
+ const inlineCode = mode === "light" ? "#0a3069" : "#9ece6a";
43141
+ const link2 = mode === "light" ? "#0969da" : "#7aa2f7";
43142
+ const headingStyle = { fg: heading, bold: true };
43143
+ return {
43144
+ "markup.heading": headingStyle,
43145
+ "markup.heading.1": headingStyle,
43146
+ "markup.heading.2": headingStyle,
43147
+ "markup.heading.3": headingStyle,
43148
+ "markup.heading.4": headingStyle,
43149
+ "markup.heading.5": headingStyle,
43150
+ "markup.heading.6": headingStyle,
43151
+ "markup.raw": { fg: inlineCode },
43152
+ "markup.italic": { italic: true },
43153
+ "markup.strong": { bold: true },
43154
+ "markup.link": { fg: link2 },
43155
+ "markup.link.label": { fg: link2 },
43156
+ "markup.link.url": { fg: link2, underline: true }
43157
+ };
43158
+ }
43159
+ __name(markdownMarkupTokens, "markdownMarkupTokens");
43160
+ var SYNTAX = buildSyntax("dark");
43161
+
43162
+ // packages/cli/node_modules/@opentui/react/jsx-runtime.js
43163
+ init_esbuild_shims();
43164
+ var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
43165
+
43166
+ // packages/cli/src/ui/opentui/messages.tsx
43167
+ var TOOL_STATUS = {
43168
+ SUCCESS: "\u2713",
43169
+ PENDING: "o",
43170
+ EXECUTING: "\u22B7",
43171
+ CONFIRMING: "?",
43172
+ CANCELED: "-",
43173
+ ERROR: "x"
43174
+ };
43175
+ var MESSAGE_ICON = {
43176
+ DIAMOND: "\u25C6",
43177
+ THEREFORE: "\u2234",
43178
+ BECAUSE: "\u2235",
43179
+ CIRCLE_FILLED: "\u25CF"
43180
+ };
43181
+ var STATUS_INDICATOR_WIDTH = 2;
43182
+ var selectionProps = /* @__PURE__ */ __name(() => ({
43183
+ selectionBg: C2.selectionBg,
43184
+ selectionFg: C2.selectionFg
43185
+ }), "selectionProps");
43186
+ var STRIKETHROUGH_ATTR = 128;
43187
+ var TODO_STATUS_ICONS = {
43188
+ pending: ICON.CIRCLE_EMPTY,
43189
+ in_progress: ICON.CIRCLE_LEFT_HALF,
43190
+ completed: ICON.CIRCLE_FILLED
43191
+ };
43192
+ var MAX_RESULT_DISPLAY_CHARACTERS = 1e6;
43193
+ function maxHistoryItemRows(terminalHeight) {
43194
+ return Math.max(Math.floor(terminalHeight) * 4, 100);
43195
+ }
43196
+ __name(maxHistoryItemRows, "maxHistoryItemRows");
43197
+ function truncateResultDisplayChars(text) {
43198
+ return text.length > MAX_RESULT_DISPLAY_CHARACTERS ? "..." + text.slice(-MAX_RESULT_DISPLAY_CHARACTERS) : text;
43199
+ }
43200
+ __name(truncateResultDisplayChars, "truncateResultDisplayChars");
43201
+ function tailWindow(lines, maxRows) {
43202
+ const target = Math.max(Math.round(maxRows), 2);
43203
+ if (lines.length <= target) return { visible: lines, hiddenCount: 0 };
43204
+ const visibleContentHeight = target - 1;
43205
+ return {
43206
+ visible: lines.slice(lines.length - visibleContentHeight),
43207
+ hiddenCount: lines.length - visibleContentHeight
43208
+ };
43209
+ }
43210
+ __name(tailWindow, "tailWindow");
43211
+ function hiddenLinesLabel(hiddenCount) {
43212
+ return `... first ${hiddenCount} line${hiddenCount === 1 ? "" : "s"} hidden ...`;
43213
+ }
43214
+ __name(hiddenLinesLabel, "hiddenLinesLabel");
43215
+ function physicalRowCount(row, cols) {
43216
+ return Math.max(1, Math.ceil(getCachedStringWidth(row) / cols));
43217
+ }
43218
+ __name(physicalRowCount, "physicalRowCount");
43219
+ function sliceRowToWidth(row, maxCols, side) {
43220
+ const points = toCodePoints(row);
43221
+ const ordered = side === "head" ? points : [...points].reverse();
43222
+ let used = 0;
43223
+ let taken = 0;
43224
+ for (const cp of ordered) {
43225
+ const cpWidth = getCachedStringWidth(cp);
43226
+ if (used + cpWidth > maxCols) break;
43227
+ used += cpWidth;
43228
+ taken += 1;
43229
+ }
43230
+ const kept = ordered.slice(0, taken);
43231
+ return (side === "tail" ? kept.reverse() : kept).join("");
43232
+ }
43233
+ __name(sliceRowToWidth, "sliceRowToWidth");
43234
+ function headWindowPhysical(rows, width, maxRows) {
43235
+ const cols = Math.max(width - 2, 10);
43236
+ const height = /* @__PURE__ */ __name((row) => physicalRowCount(row, cols), "height");
43237
+ const total = rows.reduce((sum, row) => sum + height(row), 0);
43238
+ if (total <= maxRows) return { visible: [...rows], hiddenRows: 0 };
43239
+ const budget = Math.max(maxRows - 1, 1);
43240
+ const visible = [];
43241
+ let used = 0;
43242
+ for (const row of rows) {
43243
+ const h3 = height(row);
43244
+ if (used + h3 <= budget) {
43245
+ visible.push(row);
43246
+ used += h3;
43247
+ continue;
43248
+ }
43249
+ const remaining = budget - used;
43250
+ if (remaining > 0) {
43251
+ visible.push(sliceRowToWidth(row, remaining * cols, "head"));
43252
+ used = budget;
43253
+ }
43254
+ break;
43255
+ }
43256
+ return { visible, hiddenRows: Math.max(total - used, 1) };
43257
+ }
43258
+ __name(headWindowPhysical, "headWindowPhysical");
43259
+ function hiddenTailLinesLabel(hiddenCount) {
43260
+ return `... last ${hiddenCount} line${hiddenCount === 1 ? "" : "s"} hidden ...`;
43261
+ }
43262
+ __name(hiddenTailLinesLabel, "hiddenTailLinesLabel");
43263
+ function tailWindowPhysical(rows, width, maxRows) {
43264
+ const cols = Math.max(width - 2, 10);
43265
+ const height = /* @__PURE__ */ __name((row) => physicalRowCount(row, cols), "height");
43266
+ const total = rows.reduce((sum, row) => sum + height(row), 0);
43267
+ if (total <= maxRows) return { visible: [...rows], hiddenRows: 0 };
43268
+ const budget = Math.max(maxRows, 1);
43269
+ const visible = [];
43270
+ let used = 0;
43271
+ for (let i = rows.length - 1; i >= 0; i -= 1) {
43272
+ const row = rows[i];
43273
+ const h3 = height(row);
43274
+ if (used + h3 <= budget) {
43275
+ visible.unshift(row);
43276
+ used += h3;
43277
+ continue;
43278
+ }
43279
+ const remaining = budget - used;
43280
+ if (remaining > 0) {
43281
+ visible.unshift(sliceRowToWidth(row, remaining * cols, "tail"));
43282
+ used = budget;
43283
+ }
43284
+ break;
43285
+ }
43286
+ return { visible, hiddenRows: Math.max(total - used, 1) };
43287
+ }
43288
+ __name(tailWindowPhysical, "tailWindowPhysical");
43289
+ var TOOL_CARD_DESCRIPTION_ROWS = 5;
43290
+ var PENDING_CARD_VIEWPORT_RESERVE_ROWS = 46;
43291
+ var DIALOG_EXPANDED_RESERVE_ROWS = 14;
43292
+ var CARD_DESC_WRAP_RATIO = 0.7;
43293
+ function pendingCardMaxRows(terminalHeight, descriptionWidth, width) {
43294
+ const h3 = Math.floor(terminalHeight);
43295
+ const payloadRows = Math.ceil(
43296
+ descriptionWidth / Math.max(width - STATUS_INDICATOR_WIDTH, 10)
43297
+ );
43298
+ return Math.max(
43299
+ TOOL_CARD_DESCRIPTION_ROWS,
43300
+ Math.min(
43301
+ maxHistoryItemRows(terminalHeight),
43302
+ h3 - PENDING_CARD_VIEWPORT_RESERVE_ROWS,
43303
+ Math.floor(
43304
+ (h3 - DIALOG_EXPANDED_RESERVE_ROWS - payloadRows) * CARD_DESC_WRAP_RATIO
43305
+ )
43306
+ )
43307
+ );
43308
+ }
43309
+ __name(pendingCardMaxRows, "pendingCardMaxRows");
43310
+ function capToolCardDescription(description, name, width, maxRows) {
43311
+ const cols = Math.max(width - STATUS_INDICATOR_WIDTH, 10);
43312
+ const nameCols = getCachedStringWidth(name) + 1;
43313
+ const rows = Math.ceil((nameCols + getCachedStringWidth(description)) / cols);
43314
+ if (rows <= maxRows) return { description, hiddenRows: 0 };
43315
+ const descRows = Math.max(maxRows - 1, 1);
43316
+ const visibleCols = Math.max(descRows * cols - nameCols, 0);
43317
+ return {
43318
+ description: sliceRowToWidth(description, visibleCols, "head"),
43319
+ hiddenRows: Math.max(rows - descRows, 1)
43320
+ };
43321
+ }
43322
+ __name(capToolCardDescription, "capToolCardDescription");
43323
+ function toolCardName(rawName) {
43324
+ return TOOL_DISPLAY_BY_NAME[rawName] ?? rawName;
43325
+ }
43326
+ __name(toolCardName, "toolCardName");
43327
+ var GENERIC_TOOL_SUMMARIES = /* @__PURE__ */ new Set([
43328
+ "ok",
43329
+ "error",
43330
+ "cancelled",
43331
+ "canceled",
43332
+ "interrupted",
43333
+ "skipped"
43334
+ ]);
43335
+ function toolCardSummarySuffix(done, summary) {
43336
+ if (!done || !summary || GENERIC_TOOL_SUMMARIES.has(summary)) return "";
43337
+ return ` \xB7 ${summary}`;
43338
+ }
43339
+ __name(toolCardSummarySuffix, "toolCardSummarySuffix");
43340
+ function toolCardText(v3) {
43341
+ return sanitizeMultilineForDisplay(v3.replace(/\s*\n\s*/g, " ").trim());
43342
+ }
43343
+ __name(toolCardText, "toolCardText");
43344
+ function toolCardDescription(rawName, args) {
43345
+ let parsed = {};
43346
+ try {
43347
+ parsed = JSON.parse(args ?? "{}");
43348
+ } catch {
43349
+ return "";
43350
+ }
43351
+ const str = /* @__PURE__ */ __name((v3) => typeof v3 === "string" && v3.length > 0 ? v3 : void 0, "str");
43352
+ const oneLine = toolCardText;
43353
+ switch (rawName) {
43354
+ case "run_shell_command": {
43355
+ const cmd = str(parsed["command"] ?? parsed["cmd"]);
43356
+ if (!cmd) return "";
43357
+ const desc = str(parsed["description"]);
43358
+ return desc ? `${oneLine(cmd)} (${oneLine(desc)})` : oneLine(cmd);
43359
+ }
43360
+ case "read_file":
43361
+ case "write_file":
43362
+ case "edit":
43363
+ case "notebook_edit": {
43364
+ const p2 = str(
43365
+ parsed["file_path"] ?? parsed["path"] ?? parsed["filePath"]
43366
+ );
43367
+ return p2 ? oneLine(p2) : "";
43368
+ }
43369
+ case "list_directory":
43370
+ case "glob": {
43371
+ const p2 = str(parsed["path"] ?? parsed["dir"] ?? parsed["pattern"]);
43372
+ return p2 ? oneLine(p2) : "";
43373
+ }
43374
+ case "grep_search": {
43375
+ const pat = str(parsed["pattern"]);
43376
+ return pat ? oneLine(pat) : "";
43377
+ }
43378
+ default:
43379
+ return "";
43380
+ }
43381
+ }
43382
+ __name(toolCardDescription, "toolCardDescription");
43383
+ function userMessageMeta() {
43384
+ return { glyph: ">", color: C2.purple };
43385
+ }
43386
+ __name(userMessageMeta, "userMessageMeta");
43387
+ function assistantMessageMeta() {
43388
+ return { glyph: MESSAGE_ICON.DIAMOND, color: C2.purple };
43389
+ }
43390
+ __name(assistantMessageMeta, "assistantMessageMeta");
43391
+ function thinkingMeta(done, expanded, clickable) {
43392
+ const expandHint = clickable ? "(click or ctrl+o to expand)" : "(ctrl+o to expand)";
43393
+ if (!done) {
43394
+ return {
43395
+ icon: MESSAGE_ICON.BECAUSE,
43396
+ label: "Thinking\u2026",
43397
+ hint: "",
43398
+ color: C2.dim,
43399
+ collapsed: false
43400
+ };
43401
+ }
43402
+ if (!expanded) {
43403
+ return {
43404
+ icon: MESSAGE_ICON.THEREFORE,
43405
+ label: "Thought",
43406
+ hint: expandHint,
43407
+ color: C2.dim,
43408
+ collapsed: true
43409
+ };
43410
+ }
43411
+ return {
43412
+ icon: MESSAGE_ICON.THEREFORE,
43413
+ label: "Thought",
43414
+ hint: "(ctrl+o to collapse)",
43415
+ color: C2.dim,
43416
+ collapsed: false
43417
+ };
43418
+ }
43419
+ __name(thinkingMeta, "thinkingMeta");
43420
+ function toolStatusMeta(item) {
43421
+ if (item.confirm === "pending" && !item.done) {
43422
+ return {
43423
+ glyph: TOOL_STATUS.CONFIRMING,
43424
+ color: C2.yellow,
43425
+ strikethrough: false
43426
+ };
43427
+ }
43428
+ if (!item.done) {
43429
+ return {
43430
+ glyph: TOOL_STATUS.EXECUTING,
43431
+ color: C2.text,
43432
+ strikethrough: false
43433
+ };
43434
+ }
43435
+ if (item.success) {
43436
+ return { glyph: TOOL_STATUS.SUCCESS, color: C2.green, strikethrough: false };
43437
+ }
43438
+ const canceled = item.summary === "interrupted" || item.summary === "canceled" || item.summary === "cancelled";
43439
+ if (canceled) {
43440
+ return { glyph: TOOL_STATUS.CANCELED, color: C2.text, strikethrough: true };
43441
+ }
43442
+ return { glyph: TOOL_STATUS.ERROR, color: C2.red, strikethrough: false };
43443
+ }
43444
+ __name(toolStatusMeta, "toolStatusMeta");
43445
+ function TodoRows({ todos }) {
43446
+ if (todos.length === 0) {
43447
+ return null;
43448
+ }
43449
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexDirection: "column", children: todos.map((todo) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TodoItemRow, { todo }, todo.id)) });
43450
+ }
43451
+ __name(TodoRows, "TodoRows");
43452
+ function TodoItemRow({ todo }) {
43453
+ const statusIcon = TODO_STATUS_ICONS[todo.status];
43454
+ const isCompleted = todo.status === "completed";
43455
+ const isInProgress = todo.status === "in_progress";
43456
+ const itemColor = isCompleted ? C2.text : isInProgress ? C2.green : C2.text;
43457
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", minHeight: 1, children: [
43458
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { width: 3, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: itemColor, ...selectionProps(), children: statusIcon }) }),
43459
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
43460
+ "text",
43461
+ {
43462
+ fg: itemColor,
43463
+ attributes: isCompleted ? STRIKETHROUGH_ATTR : 0,
43464
+ ...selectionProps(),
43465
+ children: todo.content
43466
+ }
43467
+ ) })
43468
+ ] });
43469
+ }
43470
+ __name(TodoItemRow, "TodoItemRow");
43471
+ var ANSI_DEFAULT_HEIGHT = 24;
43472
+ function truncateTokenLine(line, maxWidth) {
43473
+ if (maxWidth <= 0) return [];
43474
+ let width = 0;
43475
+ const kept = [];
43476
+ for (const token of line) {
43477
+ const tokenWidth = getCachedStringWidth(token.text);
43478
+ if (width + tokenWidth <= maxWidth) {
43479
+ if (tokenWidth > 0 || kept.length === 0) kept.push(token);
43480
+ width += tokenWidth;
43481
+ continue;
43482
+ }
43483
+ let partial = "";
43484
+ for (const cp of toCodePoints(token.text)) {
43485
+ const cpWidth = getCachedStringWidth(cp);
43486
+ if (width + cpWidth > maxWidth) break;
43487
+ partial += cp;
43488
+ width += cpWidth;
43489
+ }
43490
+ if (partial) kept.push({ ...token, text: partial });
43491
+ break;
43492
+ }
43493
+ return kept;
43494
+ }
43495
+ __name(truncateTokenLine, "truncateTokenLine");
43496
+ function ansiTokenProps(token) {
43497
+ const fg2 = token.inverse ? token.bg : token.fg;
43498
+ const bg2 = token.inverse ? token.fg : token.bg;
43499
+ return {
43500
+ fg: fg2 || void 0,
43501
+ bg: bg2 || void 0,
43502
+ attributes: (token.bold ? 1 : 0) | (token.dim ? 2 : 0) | (token.italic ? 4 : 0) | (token.underline ? 8 : 0)
43503
+ };
43504
+ }
43505
+ __name(ansiTokenProps, "ansiTokenProps");
43506
+ function AnsiRows({
43507
+ grid,
43508
+ maxWidth,
43509
+ totalLines,
43510
+ totalBytes
43511
+ }) {
43512
+ const windowed = tailWindow(grid, ANSI_DEFAULT_HEIGHT);
43513
+ const stats = [];
43514
+ if (totalLines && totalLines > ANSI_DEFAULT_HEIGHT) {
43515
+ stats.push(`+${totalLines - ANSI_DEFAULT_HEIGHT} lines`);
43516
+ }
43517
+ if (totalBytes && totalBytes > 0) {
43518
+ stats.push(formatMemoryUsage(totalBytes));
43519
+ }
43520
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
43521
+ windowed.hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, ...selectionProps(), children: hiddenLinesLabel(windowed.hiddenCount) }),
43522
+ windowed.visible.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexDirection: "row", children: truncateTokenLine(line, maxWidth).map((token, j3) => {
43523
+ const style = ansiTokenProps(token);
43524
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
43525
+ "text",
43526
+ {
43527
+ fg: style.fg ?? C2.text,
43528
+ bg: style.bg,
43529
+ attributes: style.attributes,
43530
+ ...selectionProps(),
43531
+ children: token.text
43532
+ },
43533
+ `${j3}`
43534
+ );
43535
+ }) }, `${i}`)),
43536
+ stats.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexDirection: "row", children: stats.map((part, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
43537
+ i > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { children: " " }),
43538
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, ...selectionProps(), children: part })
43539
+ ] }, `${i}`)) })
43540
+ ] });
43541
+ }
43542
+ __name(AnsiRows, "AnsiRows");
43543
+
42886
43544
  // packages/cli/src/ui/opentui/slash-gateway.ts
42887
43545
  init_esbuild_shims();
42888
43546
  var QUIT_TOKENS = /* @__PURE__ */ new Set([
@@ -42939,6 +43597,19 @@ var OpenTuiSlashGateway = class {
42939
43597
  await this.ready;
42940
43598
  return this.dispatcher?.mustDeferDuringStreaming(text) ?? false;
42941
43599
  }
43600
+ /**
43601
+ * Whether the dispatcher claims this input instead of the shell lane — the
43602
+ * single admission rule the shell must reuse when tagging a mid-turn
43603
+ * shell-mode submission, so routing cannot diverge between the two gates.
43604
+ */
43605
+ async takesAsSlashCommand(text) {
43606
+ await this.ready;
43607
+ if (!this.dispatcher) {
43608
+ const trimmed = text.trim();
43609
+ return trimmed.startsWith("?") || trimmed.startsWith("/") && !hasSlashCommandPathSeparator(trimmed);
43610
+ }
43611
+ return this.dispatcher.takesAsSlashCommand(text.trim());
43612
+ }
42942
43613
  /** True while a dispatched command is still running. */
42943
43614
  isBusy() {
42944
43615
  return this.busy;
@@ -43339,9 +44010,9 @@ function shouldHideSlashCommandInvocation(command, canonicalPath, args) {
43339
44010
  }
43340
44011
  return true;
43341
44012
  }
43342
- const path6 = canonicalPath.join(" ");
43343
- if (BARE_SLASH_COMMANDS_HIDE_INVOCATION.has(path6)) {
43344
- if (path6 === "model") {
44013
+ const path7 = canonicalPath.join(" ");
44014
+ if (BARE_SLASH_COMMANDS_HIDE_INVOCATION.has(path7)) {
44015
+ if (path7 === "model") {
43345
44016
  return isPickerOnlyModelInvocation(args);
43346
44017
  }
43347
44018
  return args.trim() === "";
@@ -44035,96 +44706,90 @@ async function exitSession(config, code) {
44035
44706
  }
44036
44707
  __name(exitSession, "exitSession");
44037
44708
 
44038
- // packages/cli/src/ui/opentui/opentui-error-boundary.tsx
44039
- init_esbuild_shims();
44040
- var import_react17 = __toESM(require_react(), 1);
44041
-
44042
- // packages/cli/src/ui/opentui/theme.ts
44709
+ // packages/cli/src/ui/opentui/early-input.ts
44043
44710
  init_esbuild_shims();
44044
- var DARK = {
44045
- text: "#CDD6F4",
44046
- dim: "#6C7086",
44047
- accent: "#CBA6F7",
44048
- green: "#A6E3A1",
44049
- red: "#F38BA8",
44050
- yellow: "#F9E2AF",
44051
- purple: "#89B4FA",
44052
- hover: "#313244",
44053
- // No bg on dark: the default invert selection (bg=text fg, fg=black) is
44054
- // readable on dark terminals, and leaving bg unset keeps transparency.
44055
- selectionBg: "#264F78",
44056
- selectionFg: "#FFFFFF"
44057
- };
44058
- var C2 = { ...DARK };
44059
- function buildSyntax(mode) {
44060
- const styles = mode === "light" ? {
44061
- // `default` colors unstyled markdown chunks (table cells, plain
44062
- // inline text); without it TextTable falls back to #FFFFFF.
44063
- default: { fg: "#1f2328" },
44064
- keyword: { fg: "#cf222e", bold: true },
44065
- string: { fg: "#0a3069" },
44066
- comment: { fg: "#59636e", italic: true },
44067
- function: { fg: "#8250df" },
44068
- type: { fg: "#953800" },
44069
- number: { fg: "#0550ae" },
44070
- operator: { fg: "#0550ae" },
44071
- variable: { fg: "#1f2328" },
44072
- heading: { fg: "#0550ae", bold: true },
44073
- emphasis: { italic: true },
44074
- strong: { bold: true },
44075
- link: { fg: "#0969da" },
44076
- code: { fg: "#0a3069" }
44077
- } : {
44078
- default: { fg: "#e6edf3" },
44079
- keyword: { fg: "#bb9af7", bold: true },
44080
- string: { fg: "#9ece6a" },
44081
- comment: { fg: "#565f89", italic: true },
44082
- function: { fg: "#7aa2f7" },
44083
- type: { fg: "#e0af68" },
44084
- number: { fg: "#ff9e64" },
44085
- operator: { fg: "#89ddff" },
44086
- variable: { fg: "#e6edf3" },
44087
- heading: { fg: "#7aa2f7", bold: true },
44088
- emphasis: { italic: true },
44089
- strong: { bold: true },
44090
- link: { fg: "#7aa2f7" },
44091
- code: { fg: "#9ece6a" }
44711
+ function decodeCapturedInput(buffer) {
44712
+ if (buffer.length === 0) return "";
44713
+ const text = buffer.toString("utf8");
44714
+ return text.replace(/\u001B\[[0-9:;<=>?]*[ -/]*[@-~]/g, "").replace(/\u001BO[A-Za-z]/g, "").replace(/\u001B\[[0-9:;<=>?]*[ -/]*$/, "").replace(/\u001BO$/, "").replace(/[\u0000-\u0008\u000B-\u001F\u007F]/g, "");
44715
+ }
44716
+ __name(decodeCapturedInput, "decodeCapturedInput");
44717
+ function drainCapturedInputAsText() {
44718
+ return decodeCapturedInput(stopAndGetCapturedInput());
44719
+ }
44720
+ __name(drainCapturedInputAsText, "drainCapturedInputAsText");
44721
+ function injectCapturedInput(getText, text, opts = {}) {
44722
+ if (text.length === 0) return () => {
44723
+ };
44724
+ const intervalMs = opts.intervalMs ?? 25;
44725
+ const maxAttempts = opts.maxAttempts ?? 40;
44726
+ const setTimeoutFn = opts.setTimeoutFn ?? ((fn2, ms) => setTimeout(fn2, ms));
44727
+ const clearTimeoutFn = opts.clearTimeoutFn ?? ((handle) => clearTimeout(handle));
44728
+ let attempts = 0;
44729
+ let timer = null;
44730
+ let disposed = false;
44731
+ const attempt = /* @__PURE__ */ __name(() => {
44732
+ if (disposed) return;
44733
+ const handle = getText();
44734
+ if (handle) {
44735
+ handle.setText(text);
44736
+ opts.onDelivered?.();
44737
+ return;
44738
+ }
44739
+ attempts += 1;
44740
+ if (attempts >= maxAttempts) {
44741
+ opts.onExhausted?.();
44742
+ return;
44743
+ }
44744
+ timer = setTimeoutFn(attempt, intervalMs);
44745
+ }, "attempt");
44746
+ timer = setTimeoutFn(attempt, intervalMs);
44747
+ return () => {
44748
+ disposed = true;
44749
+ if (timer !== null) clearTimeoutFn(timer);
44092
44750
  };
44093
- return SyntaxStyle.fromStyles({
44094
- ...styles,
44095
- ...markdownMarkupTokens(mode)
44096
- });
44097
44751
  }
44098
- __name(buildSyntax, "buildSyntax");
44099
- function markdownMarkupTokens(mode) {
44100
- const heading = mode === "light" ? "#0550ae" : "#7aa2f7";
44101
- const inlineCode = mode === "light" ? "#0a3069" : "#9ece6a";
44102
- const link2 = mode === "light" ? "#0969da" : "#7aa2f7";
44103
- const headingStyle = { fg: heading, bold: true };
44104
- return {
44105
- "markup.heading": headingStyle,
44106
- "markup.heading.1": headingStyle,
44107
- "markup.heading.2": headingStyle,
44108
- "markup.heading.3": headingStyle,
44109
- "markup.heading.4": headingStyle,
44110
- "markup.heading.5": headingStyle,
44111
- "markup.heading.6": headingStyle,
44112
- "markup.raw": { fg: inlineCode },
44113
- "markup.italic": { italic: true },
44114
- "markup.strong": { bold: true },
44115
- "markup.link": { fg: link2 },
44116
- "markup.link.label": { fg: link2 },
44117
- "markup.link.url": { fg: link2, underline: true }
44752
+ __name(injectCapturedInput, "injectCapturedInput");
44753
+ function armCapturedInputInjection(getText, text, opts = {}) {
44754
+ if (text.length === 0) return () => {
44755
+ };
44756
+ const retryDelayMs = opts.retryDelayMs ?? 250;
44757
+ const setTimeoutFn = opts.setTimeoutFn ?? ((fn2, ms) => setTimeout(fn2, ms));
44758
+ const clearTimeoutFn = opts.clearTimeoutFn ?? ((handle) => clearTimeout(handle));
44759
+ let pending = text;
44760
+ let disposed = false;
44761
+ let pollerDisposer = null;
44762
+ let retryTimer = null;
44763
+ const arm = /* @__PURE__ */ __name(() => {
44764
+ if (disposed) return;
44765
+ const pendingText = pending;
44766
+ if (pendingText === null) return;
44767
+ pollerDisposer = injectCapturedInput(getText, pendingText, {
44768
+ intervalMs: opts.intervalMs,
44769
+ maxAttempts: opts.maxAttempts,
44770
+ setTimeoutFn: opts.setTimeoutFn,
44771
+ clearTimeoutFn: opts.clearTimeoutFn,
44772
+ onDelivered: /* @__PURE__ */ __name(() => {
44773
+ pending = null;
44774
+ }, "onDelivered"),
44775
+ onExhausted: /* @__PURE__ */ __name(() => {
44776
+ if (disposed) return;
44777
+ retryTimer = setTimeoutFn(arm, retryDelayMs);
44778
+ }, "onExhausted")
44779
+ });
44780
+ }, "arm");
44781
+ arm();
44782
+ return () => {
44783
+ disposed = true;
44784
+ pollerDisposer?.();
44785
+ if (retryTimer !== null) clearTimeoutFn(retryTimer);
44118
44786
  };
44119
44787
  }
44120
- __name(markdownMarkupTokens, "markdownMarkupTokens");
44121
- var SYNTAX = buildSyntax("dark");
44122
-
44123
- // packages/cli/node_modules/@opentui/react/jsx-runtime.js
44124
- init_esbuild_shims();
44125
- var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
44788
+ __name(armCapturedInputInjection, "armCapturedInputInjection");
44126
44789
 
44127
44790
  // packages/cli/src/ui/opentui/opentui-error-boundary.tsx
44791
+ init_esbuild_shims();
44792
+ var import_react18 = __toESM(require_react(), 1);
44128
44793
  function normalizeError(error) {
44129
44794
  if (error instanceof Error) {
44130
44795
  return error;
@@ -44139,7 +44804,7 @@ function consumeLastRenderError() {
44139
44804
  return err;
44140
44805
  }
44141
44806
  __name(consumeLastRenderError, "consumeLastRenderError");
44142
- var OpenTuiErrorBoundary = class extends import_react17.Component {
44807
+ var OpenTuiErrorBoundary = class extends import_react18.Component {
44143
44808
  static {
44144
44809
  __name(this, "OpenTuiErrorBoundary");
44145
44810
  }
@@ -44174,7 +44839,7 @@ var OpenTuiErrorBoundary = class extends import_react17.Component {
44174
44839
 
44175
44840
  // packages/cli/src/ui/opentui/opentui-dialog-mount.tsx
44176
44841
  init_esbuild_shims();
44177
- var import_react43 = __toESM(require_react(), 1);
44842
+ var import_react44 = __toESM(require_react(), 1);
44178
44843
 
44179
44844
  // packages/cli/src/ui/opentui/key-map.ts
44180
44845
  init_esbuild_shims();
@@ -44547,11 +45212,11 @@ import { EventEmitter as EventEmitter7 } from "node:events";
44547
45212
 
44548
45213
  // packages/cli/src/ui/opentui/dialogs-model.tsx
44549
45214
  init_esbuild_shims();
44550
- var import_react20 = __toESM(require_react(), 1);
45215
+ var import_react21 = __toESM(require_react(), 1);
44551
45216
 
44552
45217
  // packages/cli/src/ui/opentui/dialogs-shared.tsx
44553
45218
  init_esbuild_shims();
44554
- var import_react18 = __toESM(require_react(), 1);
45219
+ var import_react19 = __toESM(require_react(), 1);
44555
45220
 
44556
45221
  // packages/cli/src/ui/opentui/dialogs-core.ts
44557
45222
  init_esbuild_shims();
@@ -44699,20 +45364,20 @@ function useDialogSelect(options) {
44699
45364
  onSelect,
44700
45365
  onHighlight
44701
45366
  } = options;
44702
- const [activeIndex, setActiveIndexState] = (0, import_react18.useState)(
45367
+ const [activeIndex, setActiveIndexState] = (0, import_react19.useState)(
44703
45368
  () => computeInitialActiveIndex(initialIndex, items)
44704
45369
  );
44705
- const [scrollOffset, setScrollOffset] = (0, import_react18.useState)(
45370
+ const [scrollOffset, setScrollOffset] = (0, import_react19.useState)(
44706
45371
  () => getSelectionScrollOffset(
44707
45372
  computeInitialActiveIndex(initialIndex, items),
44708
45373
  items.length,
44709
45374
  maxItemsToShow
44710
45375
  )
44711
45376
  );
44712
- const numberBuffer = (0, import_react18.useRef)("");
44713
- const numberTimer = (0, import_react18.useRef)(null);
44714
- const itemsRef = (0, import_react18.useRef)(items);
44715
- const [appliedResyncKey, setAppliedResyncKey] = (0, import_react18.useState)(resyncKey);
45377
+ const numberBuffer = (0, import_react19.useRef)("");
45378
+ const numberTimer = (0, import_react19.useRef)(null);
45379
+ const itemsRef = (0, import_react19.useRef)(items);
45380
+ const [appliedResyncKey, setAppliedResyncKey] = (0, import_react19.useState)(resyncKey);
44716
45381
  if (appliedResyncKey !== resyncKey) {
44717
45382
  setAppliedResyncKey(resyncKey);
44718
45383
  if (numberTimer.current) {
@@ -44727,7 +45392,7 @@ function useDialogSelect(options) {
44727
45392
  getSelectionScrollOffset(next, items.length, maxItemsToShow)
44728
45393
  );
44729
45394
  }
44730
- const latestRef = (0, import_react18.useRef)({ items, activeIndex, onSelect });
45395
+ const latestRef = (0, import_react19.useRef)({ items, activeIndex, onSelect });
44731
45396
  latestRef.current = { items, activeIndex, onSelect };
44732
45397
  if (itemsRef.current !== items) {
44733
45398
  const prevItems = itemsRef.current;
@@ -44742,13 +45407,13 @@ function useDialogSelect(options) {
44742
45407
  );
44743
45408
  }
44744
45409
  }
44745
- (0, import_react18.useEffect)(
45410
+ (0, import_react19.useEffect)(
44746
45411
  () => () => {
44747
45412
  if (numberTimer.current) clearTimeout(numberTimer.current);
44748
45413
  },
44749
45414
  []
44750
45415
  );
44751
- (0, import_react18.useEffect)(() => {
45416
+ (0, import_react19.useEffect)(() => {
44752
45417
  const next = followScrollOffset(
44753
45418
  activeIndex,
44754
45419
  scrollOffset,
@@ -45022,7 +45687,7 @@ function OpenTuiModelDialog(props) {
45022
45687
  availableTerminalHeight
45023
45688
  } = props;
45024
45689
  const isAuxMode = mode !== "primary";
45025
- const [highlightedKey, setHighlightedKey] = (0, import_react20.useState)(null);
45690
+ const [highlightedKey, setHighlightedKey] = (0, import_react21.useState)(null);
45026
45691
  const initialIndex = initialKey ? Math.max(
45027
45692
  0,
45028
45693
  entries.findIndex((entry) => entry.key === initialKey)
@@ -45984,7 +46649,7 @@ __name(applyExtensionUpdate, "applyExtensionUpdate");
45984
46649
 
45985
46650
  // packages/cli/src/ui/opentui/dialogs-theme.tsx
45986
46651
  init_esbuild_shims();
45987
- var import_react22 = __toESM(require_react(), 1);
46652
+ var import_react23 = __toESM(require_react(), 1);
45988
46653
  var THEME_DIALOG_MAX_ITEMS_TO_SHOW = 12;
45989
46654
  var THEME_PREVIEW_CODE = `# function
45990
46655
  def fibonacci(n):
@@ -45994,7 +46659,7 @@ def fibonacci(n):
45994
46659
  return a`;
45995
46660
  var THEME_PREVIEW_DIFF = `--- a/util.py
45996
46661
  +++ b/util.py
45997
- @@ -1,2 +1,2 @@
46662
+ @@ -1,1 +1,1 @@
45998
46663
  - print("Hello, " + name)
45999
46664
  + print(f"Hello, {name}!")
46000
46665
  `;
@@ -46053,11 +46718,11 @@ function computeThemePreviewLayout(availableTerminalHeight, themeItemCount) {
46053
46718
  __name(computeThemePreviewLayout, "computeThemePreviewLayout");
46054
46719
  function OpenTuiThemeDialog(props) {
46055
46720
  const { onSelect, onHighlight, settings, availableTerminalHeight } = props;
46056
- const [selectedScope, setSelectedScope] = (0, import_react22.useState)(
46721
+ const [selectedScope, setSelectedScope] = (0, import_react23.useState)(
46057
46722
  "User" /* User */
46058
46723
  );
46059
- const [highlightedThemeName, setHighlightedThemeName] = (0, import_react22.useState)(settings.merged.ui?.theme || AUTO_THEME_NAME);
46060
- const [mode, setMode] = (0, import_react22.useState)("theme");
46724
+ const [highlightedThemeName, setHighlightedThemeName] = (0, import_react23.useState)(settings.merged.ui?.theme || AUTO_THEME_NAME);
46725
+ const [mode, setMode] = (0, import_react23.useState)("theme");
46061
46726
  const customThemes = selectedScope === "User" /* User */ ? settings.user.settings.ui?.customThemes || {} : settings.merged.ui?.customThemes || {};
46062
46727
  const builtInThemes = themeManager.getAvailableThemes().filter((theme) => theme.type !== "custom");
46063
46728
  const themeItems = buildThemeItems(builtInThemes, Object.keys(customThemes));
@@ -46134,9 +46799,8 @@ function OpenTuiThemeDialog(props) {
46134
46799
  onWheel: (direction) => themeList.setActiveIndex(
46135
46800
  themeList.activeIndex + (direction === "down" ? 1 : -1)
46136
46801
  ),
46137
- renderLabel: (item, { titleColor }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: titleColor, children: [
46138
- item.themeNameDisplay,
46139
- " ",
46802
+ renderLabel: (item, { titleColor }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
46803
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: titleColor, children: `${item.themeNameDisplay} ` }),
46140
46804
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: item.themeTypeDisplay })
46141
46805
  ] })
46142
46806
  }
@@ -46213,14 +46877,14 @@ __name(OpenTuiThemeDialog, "OpenTuiThemeDialog");
46213
46877
 
46214
46878
  // packages/cli/src/ui/opentui/dialogs-settings.tsx
46215
46879
  init_esbuild_shims();
46216
- var import_react25 = __toESM(require_react(), 1);
46880
+ var import_react26 = __toESM(require_react(), 1);
46217
46881
 
46218
46882
  // packages/cli/src/ui/opentui/dialogs-stats-skills.tsx
46219
46883
  init_esbuild_shims();
46220
- var import_react23 = __toESM(require_react(), 1);
46884
+ var import_react24 = __toESM(require_react(), 1);
46221
46885
  function useEscToClose(onClose, enabled) {
46222
46886
  const renderer = useRenderer();
46223
- (0, import_react23.useLayoutEffect)(() => {
46887
+ (0, import_react24.useLayoutEffect)(() => {
46224
46888
  if (!enabled) return;
46225
46889
  const onRawInput = /* @__PURE__ */ __name((sequence) => {
46226
46890
  if (sequence !== "\x1B") return false;
@@ -46256,9 +46920,9 @@ var TABS = [
46256
46920
  ];
46257
46921
  function OpenTuiStatsDialog(props) {
46258
46922
  const { config, onClose, isFocused = true } = props;
46259
- const [tab, setTab] = (0, import_react23.useState)("session");
46260
- const [, forceUpdate] = (0, import_react23.useState)(0);
46261
- (0, import_react23.useEffect)(() => {
46923
+ const [tab, setTab] = (0, import_react24.useState)("session");
46924
+ const [, forceUpdate] = (0, import_react24.useState)(0);
46925
+ (0, import_react24.useEffect)(() => {
46262
46926
  const handler = /* @__PURE__ */ __name(() => forceUpdate((n) => n + 1), "handler");
46263
46927
  uiTelemetryService.on("update", handler);
46264
46928
  return () => {
@@ -46414,10 +47078,10 @@ function OpenTuiStatsDialog(props) {
46414
47078
  __name(OpenTuiStatsDialog, "OpenTuiStatsDialog");
46415
47079
  function OpenTuiSkillsDialog(props) {
46416
47080
  const { config, onClose } = props;
46417
- const [rows, setRows] = (0, import_react23.useState)([]);
46418
- const [loading, setLoading] = (0, import_react23.useState)(true);
47081
+ const [rows, setRows] = (0, import_react24.useState)([]);
47082
+ const [loading, setLoading] = (0, import_react24.useState)(true);
46419
47083
  useEscToClose(onClose, true);
46420
- (0, import_react23.useEffect)(() => {
47084
+ (0, import_react24.useEffect)(() => {
46421
47085
  let alive = true;
46422
47086
  const mgr = config?.getSkillManager?.();
46423
47087
  if (!mgr) {
@@ -46584,37 +47248,37 @@ function editMoveCursor(state, movement) {
46584
47248
  __name(editMoveCursor, "editMoveCursor");
46585
47249
  function OpenTuiSettingsDialog(props) {
46586
47250
  const { settings, onSelect, onRestartRequest, onSettingApplied, config } = props;
46587
- const [mode, setMode] = (0, import_react25.useState)("settings");
46588
- const [selectedScope, setSelectedScope] = (0, import_react25.useState)(
47251
+ const [mode, setMode] = (0, import_react26.useState)("settings");
47252
+ const [selectedScope, setSelectedScope] = (0, import_react26.useState)(
46589
47253
  "User" /* User */
46590
47254
  );
46591
- const [activeSettingIndex, setActiveSettingIndex] = (0, import_react25.useState)(0);
46592
- const [scrollOffset, setScrollOffset] = (0, import_react25.useState)(0);
46593
- const [activeTab, setActiveTab] = (0, import_react25.useState)("settings");
46594
- const [focusZone, setFocusZone] = (0, import_react25.useState)(
47255
+ const [activeSettingIndex, setActiveSettingIndex] = (0, import_react26.useState)(0);
47256
+ const [scrollOffset, setScrollOffset] = (0, import_react26.useState)(0);
47257
+ const [activeTab, setActiveTab] = (0, import_react26.useState)("settings");
47258
+ const [focusZone, setFocusZone] = (0, import_react26.useState)(
46595
47259
  "list"
46596
47260
  );
46597
- const [searchQuery, setSearchQuery] = (0, import_react25.useState)("");
46598
- const [pendingSettings, setPendingSettings] = (0, import_react25.useState)(
47261
+ const [searchQuery, setSearchQuery] = (0, import_react26.useState)("");
47262
+ const [pendingSettings, setPendingSettings] = (0, import_react26.useState)(
46599
47263
  () => structuredClone(settings.forScope("User" /* User */).settings)
46600
47264
  );
46601
- const [modifiedSettings, setModifiedSettings] = (0, import_react25.useState)(
47265
+ const [modifiedSettings, setModifiedSettings] = (0, import_react26.useState)(
46602
47266
  /* @__PURE__ */ new Set()
46603
47267
  );
46604
- const [restartRequiredSettings, setRestartRequiredSettings] = (0, import_react25.useState)(/* @__PURE__ */ new Set());
46605
- const [editingKey, setEditingKey] = (0, import_react25.useState)(null);
46606
- const [edit, setEdit] = (0, import_react25.useState)({ buffer: "", cursor: 0 });
46607
- const [systemInfo, setSystemInfo] = (0, import_react25.useState)(null);
46608
- const [statusError, setStatusError] = (0, import_react25.useState)(false);
46609
- const [statusReloadNonce, setStatusReloadNonce] = (0, import_react25.useState)(0);
47268
+ const [restartRequiredSettings, setRestartRequiredSettings] = (0, import_react26.useState)(/* @__PURE__ */ new Set());
47269
+ const [editingKey, setEditingKey] = (0, import_react26.useState)(null);
47270
+ const [edit, setEdit] = (0, import_react26.useState)({ buffer: "", cursor: 0 });
47271
+ const [systemInfo, setSystemInfo] = (0, import_react26.useState)(null);
47272
+ const [statusError, setStatusError] = (0, import_react26.useState)(false);
47273
+ const [statusReloadNonce, setStatusReloadNonce] = (0, import_react26.useState)(0);
46610
47274
  const showRestartPrompt = restartRequiredSettings.size > 0;
46611
- (0, import_react25.useEffect)(() => {
47275
+ (0, import_react26.useEffect)(() => {
46612
47276
  setPendingSettings(
46613
47277
  structuredClone(settings.forScope(selectedScope).settings)
46614
47278
  );
46615
47279
  setModifiedSettings(/* @__PURE__ */ new Set());
46616
47280
  }, [selectedScope, settings]);
46617
- (0, import_react25.useEffect)(() => {
47281
+ (0, import_react26.useEffect)(() => {
46618
47282
  if (activeTab !== "status") {
46619
47283
  setSystemInfo(null);
46620
47284
  setStatusError(false);
@@ -46632,7 +47296,7 @@ function OpenTuiSettingsDialog(props) {
46632
47296
  cancelled = true;
46633
47297
  };
46634
47298
  }, [activeTab, config, settings, statusReloadNonce]);
46635
- (0, import_react25.useEffect)(() => {
47299
+ (0, import_react26.useEffect)(() => {
46636
47300
  setActiveSettingIndex(0);
46637
47301
  setScrollOffset(0);
46638
47302
  }, [searchQuery]);
@@ -46996,8 +47660,8 @@ function OpenTuiSettingsDialog(props) {
46996
47660
  if (isEditing) {
46997
47661
  displayValue = edit.buffer;
46998
47662
  } else if (item.type === "number" || item.type === "string") {
46999
- const path6 = item.key.split(".");
47000
- const currentValue = getNestedValue(pendingSettings, path6);
47663
+ const path7 = item.key.split(".");
47664
+ const currentValue = getNestedValue(pendingSettings, path7);
47001
47665
  const defaultValue = getDefaultValue(item.key);
47002
47666
  const effectiveCurrentValue = currentValue !== void 0 && currentValue !== null ? currentValue : defaultValue;
47003
47667
  if (item.key === "general.outputLanguage" && isAutoLanguage(
@@ -47044,12 +47708,9 @@ function OpenTuiSettingsDialog(props) {
47044
47708
  },
47045
47709
  children: [
47046
47710
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { width: 2, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: isActive ? C2.green : C2.dim, children: isActive ? ICON.CIRCLE_FILLED : "" }) }),
47047
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: isActive ? C2.green : C2.text, children: [
47048
- item.label,
47049
- scopeMessage ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.dim, children: [
47050
- " ",
47051
- scopeMessage
47052
- ] }) : null
47711
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
47712
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: isActive ? C2.green : C2.text, children: item.label }),
47713
+ scopeMessage ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: ` ${scopeMessage}` }) : null
47053
47714
  ] }) }),
47054
47715
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { marginLeft: 1, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
47055
47716
  "text",
@@ -47081,7 +47742,7 @@ __name(OpenTuiSettingsDialog, "OpenTuiSettingsDialog");
47081
47742
 
47082
47743
  // packages/cli/src/ui/opentui/dialogs-extensions.tsx
47083
47744
  init_esbuild_shims();
47084
- var import_react27 = __toESM(require_react(), 1);
47745
+ var import_react28 = __toESM(require_react(), 1);
47085
47746
  var EXTENSIONS_TABS = {
47086
47747
  INSTALLED: "installed",
47087
47748
  DISCOVER: "discover",
@@ -47146,40 +47807,40 @@ function OpenTuiExtensionsDialog(props) {
47146
47807
  onDetailAction,
47147
47808
  busy = false
47148
47809
  } = props;
47149
- const [activeTab, setActiveTab] = (0, import_react27.useState)(
47810
+ const [activeTab, setActiveTab] = (0, import_react28.useState)(
47150
47811
  initialTab ?? EXTENSIONS_TABS.INSTALLED
47151
47812
  );
47152
- const [discoverFilter, setDiscoverFilter] = (0, import_react27.useState)(
47813
+ const [discoverFilter, setDiscoverFilter] = (0, import_react28.useState)(
47153
47814
  discoverFilterProp ?? null
47154
47815
  );
47155
- const [view, setView] = (0, import_react27.useState)("list");
47156
- const [selectedKey, setSelectedKey] = (0, import_react27.useState)(null);
47157
- const [checkedUpdateState, setCheckedUpdateState] = (0, import_react27.useState)(void 0);
47158
- const clearDiscoverFilter = (0, import_react27.useCallback)(() => {
47816
+ const [view, setView] = (0, import_react28.useState)("list");
47817
+ const [selectedKey, setSelectedKey] = (0, import_react28.useState)(null);
47818
+ const [checkedUpdateState, setCheckedUpdateState] = (0, import_react28.useState)(void 0);
47819
+ const clearDiscoverFilter = (0, import_react28.useCallback)(() => {
47159
47820
  setDiscoverFilter(null);
47160
47821
  onDiscoverFilterChange?.(null);
47161
47822
  }, [onDiscoverFilterChange]);
47162
- const cycle = (0, import_react27.useCallback)((direction) => {
47823
+ const cycle = (0, import_react28.useCallback)((direction) => {
47163
47824
  setDiscoverFilter(null);
47164
47825
  setActiveTab(
47165
47826
  (current) => cycleTab(EXTENSIONS_TAB_ORDER, current, direction)
47166
47827
  );
47167
47828
  }, []);
47168
- const rows = (0, import_react27.useMemo)(
47829
+ const rows = (0, import_react28.useMemo)(
47169
47830
  () => rowsByTab?.[EXTENSIONS_TABS.INSTALLED] ?? [],
47170
47831
  [rowsByTab]
47171
47832
  );
47172
- const currentRow = (0, import_react27.useMemo)(
47833
+ const currentRow = (0, import_react28.useMemo)(
47173
47834
  () => selectedKey ? rows.find((row) => row.key === selectedKey) ?? null : null,
47174
47835
  [rows, selectedKey]
47175
47836
  );
47176
- (0, import_react27.useEffect)(() => {
47837
+ (0, import_react28.useEffect)(() => {
47177
47838
  if (view !== "list" && !currentRow) {
47178
47839
  setView("list");
47179
47840
  setSelectedKey(null);
47180
47841
  }
47181
47842
  }, [view, currentRow]);
47182
- const listItems = (0, import_react27.useMemo)(
47843
+ const listItems = (0, import_react28.useMemo)(
47183
47844
  () => rows.map((row) => ({
47184
47845
  key: row.key,
47185
47846
  value: row.key,
@@ -47197,7 +47858,7 @@ function OpenTuiExtensionsDialog(props) {
47197
47858
  setView("detail");
47198
47859
  }, "onSelect")
47199
47860
  });
47200
- const detailActions = (0, import_react27.useMemo)(() => {
47861
+ const detailActions = (0, import_react28.useMemo)(() => {
47201
47862
  if (!currentRow) return [];
47202
47863
  const enabled = currentRow.enabled !== false;
47203
47864
  const items = [
@@ -47267,7 +47928,7 @@ function OpenTuiExtensionsDialog(props) {
47267
47928
  );
47268
47929
  }, "onSelect")
47269
47930
  });
47270
- const scopeItems = (0, import_react27.useMemo)(
47931
+ const scopeItems = (0, import_react28.useMemo)(
47271
47932
  () => [
47272
47933
  {
47273
47934
  key: "user",
@@ -47534,7 +48195,7 @@ __name(OpenTuiExtensionsDialog, "OpenTuiExtensionsDialog");
47534
48195
 
47535
48196
  // packages/cli/src/ui/opentui/dialogs-mcp.tsx
47536
48197
  init_esbuild_shims();
47537
- var import_react29 = __toESM(require_react(), 1);
48198
+ var import_react30 = __toESM(require_react(), 1);
47538
48199
  var MCP_MANAGEMENT_STEPS = {
47539
48200
  SERVER_LIST: "server-list",
47540
48201
  SERVER_DETAIL: "server-detail",
@@ -47712,19 +48373,19 @@ function OpenTuiMcpDialog(props) {
47712
48373
  onClose,
47713
48374
  onServerAction
47714
48375
  } = props;
47715
- const [navigationStack, setNavigationStack] = (0, import_react29.useState)([
48376
+ const [navigationStack, setNavigationStack] = (0, import_react30.useState)([
47716
48377
  MCP_MANAGEMENT_STEPS.SERVER_LIST
47717
48378
  ]);
47718
- const [selectedServerName, setSelectedServerName] = (0, import_react29.useState)(
48379
+ const [selectedServerName, setSelectedServerName] = (0, import_react30.useState)(
47719
48380
  null
47720
48381
  );
47721
48382
  const selectedServer = selectedServerName ? servers.find((server) => server.name === selectedServerName) ?? null : null;
47722
- const [selectedTool, setSelectedTool] = (0, import_react29.useState)(null);
47723
- const [selectedResource, setSelectedResource] = (0, import_react29.useState)(null);
47724
- const [serverCursor, setServerCursor] = (0, import_react29.useState)(0);
47725
- const [actionCursor, setActionCursor] = (0, import_react29.useState)(0);
47726
- const [toolCursor, setToolCursor] = (0, import_react29.useState)(0);
47727
- const [resourceCursor, setResourceCursor] = (0, import_react29.useState)(0);
48383
+ const [selectedTool, setSelectedTool] = (0, import_react30.useState)(null);
48384
+ const [selectedResource, setSelectedResource] = (0, import_react30.useState)(null);
48385
+ const [serverCursor, setServerCursor] = (0, import_react30.useState)(0);
48386
+ const [actionCursor, setActionCursor] = (0, import_react30.useState)(0);
48387
+ const [toolCursor, setToolCursor] = (0, import_react30.useState)(0);
48388
+ const [resourceCursor, setResourceCursor] = (0, import_react30.useState)(0);
47728
48389
  const currentStep = navigationStack[navigationStack.length - 1] ?? MCP_MANAGEMENT_STEPS.SERVER_LIST;
47729
48390
  const navigateToStep = /* @__PURE__ */ __name((step) => setNavigationStack((prev) => [...prev, step]), "navigateToStep");
47730
48391
  const navigateBack = /* @__PURE__ */ __name(() => setNavigationStack((prev) => prev.length <= 1 ? prev : prev.slice(0, -1)), "navigateBack");
@@ -47921,13 +48582,9 @@ function OpenTuiMcpDialog(props) {
47921
48582
  flexDirection: "column",
47922
48583
  marginBottom: groupIndex === groupedServers.length - 1 ? 0 : 1,
47923
48584
  children: [
47924
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.text, attributes: 1, children: [
47925
- ` ${group.displayName}`,
47926
- group.servers[0]?.configPath ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.dim, children: [
47927
- " (",
47928
- group.servers[0].configPath,
47929
- ")"
47930
- ] }) : null
48585
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
48586
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, attributes: 1, children: ` ${group.displayName}` }),
48587
+ group.servers[0]?.configPath ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: ` (${group.servers[0].configPath})` }) : null
47931
48588
  ] }),
47932
48589
  group.servers.map((server, itemIndex) => {
47933
48590
  const globalIndex = startIndex + itemIndex;
@@ -48136,9 +48793,9 @@ __name(OpenTuiMcpDialog, "OpenTuiMcpDialog");
48136
48793
 
48137
48794
  // packages/cli/src/ui/opentui/dialogs-permissions.tsx
48138
48795
  init_esbuild_shims();
48139
- var import_react31 = __toESM(require_react(), 1);
48140
- import * as fs2 from "node:fs";
48141
- import * as os2 from "node:os";
48796
+ var import_react32 = __toESM(require_react(), 1);
48797
+ import * as fs3 from "node:fs";
48798
+ import * as os3 from "node:os";
48142
48799
  import * as nodePath from "node:path";
48143
48800
  function getPermissionsTabs() {
48144
48801
  return [
@@ -48212,17 +48869,17 @@ __name(getPermissionScopeItems, "getPermissionScopeItems");
48212
48869
  function validateWorkspaceDirectory(input, currentDirectories) {
48213
48870
  const trimmed = input.trim();
48214
48871
  if (!trimmed) return { error: "" };
48215
- const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os2.homedir()) : trimmed;
48872
+ const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os3.homedir()) : trimmed;
48216
48873
  const absoluteExpanded = nodePath.isAbsolute(expanded) ? expanded : nodePath.resolve(expanded);
48217
- if (!fs2.existsSync(absoluteExpanded)) {
48874
+ if (!fs3.existsSync(absoluteExpanded)) {
48218
48875
  return { error: t("Directory does not exist.") };
48219
48876
  }
48220
- if (!fs2.statSync(absoluteExpanded).isDirectory()) {
48877
+ if (!fs3.statSync(absoluteExpanded).isDirectory()) {
48221
48878
  return { error: t("Path is not a directory.") };
48222
48879
  }
48223
48880
  let resolved;
48224
48881
  try {
48225
- resolved = fs2.realpathSync(absoluteExpanded);
48882
+ resolved = fs3.realpathSync(absoluteExpanded);
48226
48883
  } catch {
48227
48884
  resolved = absoluteExpanded;
48228
48885
  }
@@ -48253,19 +48910,19 @@ function OpenTuiPermissionsDialog(props) {
48253
48910
  onExit
48254
48911
  } = props;
48255
48912
  const tabs = getPermissionsTabs();
48256
- const [activeTabIndex, setActiveTabIndex] = (0, import_react31.useState)(0);
48913
+ const [activeTabIndex, setActiveTabIndex] = (0, import_react32.useState)(0);
48257
48914
  const activeTab = tabs[activeTabIndex];
48258
- const [view, setView] = (0, import_react31.useState)("rule-list");
48259
- const [searchQuery, setSearchQuery] = (0, import_react31.useState)("");
48260
- const [newRuleInput, setNewRuleInput] = (0, import_react31.useState)("");
48261
- const [ruleInputError, setRuleInputError] = (0, import_react31.useState)("");
48262
- const [pendingRuleText, setPendingRuleText] = (0, import_react31.useState)("");
48263
- const [deleteTarget, setDeleteTarget] = (0, import_react31.useState)(
48915
+ const [view, setView] = (0, import_react32.useState)("rule-list");
48916
+ const [searchQuery, setSearchQuery] = (0, import_react32.useState)("");
48917
+ const [newRuleInput, setNewRuleInput] = (0, import_react32.useState)("");
48918
+ const [ruleInputError, setRuleInputError] = (0, import_react32.useState)("");
48919
+ const [pendingRuleText, setPendingRuleText] = (0, import_react32.useState)("");
48920
+ const [deleteTarget, setDeleteTarget] = (0, import_react32.useState)(
48264
48921
  null
48265
48922
  );
48266
- const [newDirInput, setNewDirInput] = (0, import_react31.useState)("");
48267
- const [dirInputError, setDirInputError] = (0, import_react31.useState)("");
48268
- const [removeDirTarget, setRemoveDirTarget] = (0, import_react31.useState)(null);
48923
+ const [newDirInput, setNewDirInput] = (0, import_react32.useState)("");
48924
+ const [dirInputError, setDirInputError] = (0, import_react32.useState)("");
48925
+ const [removeDirTarget, setRemoveDirTarget] = (0, import_react32.useState)(null);
48269
48926
  const currentTabRules = activeTab.id === "workspace" ? [] : rules.filter((r) => r.type === activeTab.id);
48270
48927
  const filteredRules = currentTabRules.filter(
48271
48928
  (r) => matchesSearchQuery(searchQuery, [r.raw, r.toolName])
@@ -48567,13 +49224,10 @@ function OpenTuiPermissionsDialog(props) {
48567
49224
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, children: t(
48568
49225
  "Permission rules are a tool name, optionally followed by a specifier in parentheses."
48569
49226
  ) }),
48570
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.text, children: [
48571
- t("e.g.,"),
48572
- " ",
49227
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
49228
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, children: `${t("e.g.,")} ` }),
48573
49229
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { attributes: 1, children: "WebFetch" }),
48574
- " ",
48575
- t("or"),
48576
- " ",
49230
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, children: ` ${t("or")} ` }),
48577
49231
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { attributes: 1, children: "Bash(ls:*)" })
48578
49232
  ] }),
48579
49233
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { height: 1 }),
@@ -48604,11 +49258,13 @@ function OpenTuiPermissionsDialog(props) {
48604
49258
  focused: true,
48605
49259
  onHover: scopeList.setActiveIndex,
48606
49260
  onSelectIndex: scopeList.selectIndex,
48607
- renderLabel: (item, { titleColor }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: titleColor, children: [
48608
- item.label,
48609
- " ",
48610
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: item.description })
48611
- ] })
49261
+ renderLabel: (item, { titleColor }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
49262
+ "text",
49263
+ {
49264
+ fg: titleColor,
49265
+ children: `${item.label} ${item.description}`
49266
+ }
49267
+ )
48612
49268
  }
48613
49269
  )
48614
49270
  ] }),
@@ -48685,7 +49341,7 @@ __name(OpenTuiPermissionsDialog, "OpenTuiPermissionsDialog");
48685
49341
 
48686
49342
  // packages/cli/src/ui/opentui/dialogs-auth.tsx
48687
49343
  init_esbuild_shims();
48688
- var import_react35 = __toESM(require_react(), 1);
49344
+ var import_react36 = __toESM(require_react(), 1);
48689
49345
 
48690
49346
  // packages/cli/src/ui/opentui/input-prompt-key.ts
48691
49347
  init_esbuild_shims();
@@ -49382,10 +50038,10 @@ __name(historyDownDecision, "historyDownDecision");
49382
50038
 
49383
50039
  // packages/cli/src/ui/opentui/dialogs-misc.tsx
49384
50040
  init_esbuild_shims();
49385
- var import_react33 = __toESM(require_react(), 1);
50041
+ var import_react34 = __toESM(require_react(), 1);
49386
50042
  function useEsc(onClose) {
49387
50043
  const renderer = useRenderer();
49388
- (0, import_react33.useLayoutEffect)(() => {
50044
+ (0, import_react34.useLayoutEffect)(() => {
49389
50045
  const onRaw = /* @__PURE__ */ __name((seq) => {
49390
50046
  if (seq !== "\x1B") return false;
49391
50047
  onClose();
@@ -49439,20 +50095,20 @@ function nextEnabledIndex(items, current, delta) {
49439
50095
  __name(nextEnabledIndex, "nextEnabledIndex");
49440
50096
  function OpenTuiEditorDialog({ settings, onClose, notify }) {
49441
50097
  useEsc(onClose);
49442
- const editors = (0, import_react33.useMemo)(
50098
+ const editors = (0, import_react34.useMemo)(
49443
50099
  () => editorSettingsManager.getAvailableEditorDisplays(),
49444
50100
  []
49445
50101
  );
49446
- const [mode, setMode] = (0, import_react33.useState)("editor");
49447
- const [scope, setScope] = (0, import_react33.useState)("User" /* User */);
50102
+ const [mode, setMode] = (0, import_react34.useState)("editor");
50103
+ const [scope, setScope] = (0, import_react34.useState)("User" /* User */);
49448
50104
  const scopeIndexOf = /* @__PURE__ */ __name((s) => {
49449
50105
  const pref = settings.forScope(s).settings.general?.preferredEditor;
49450
50106
  const idx = pref ? editors.findIndex((e) => e.type === pref) : 0;
49451
50107
  return idx >= 0 ? idx : 0;
49452
50108
  }, "scopeIndexOf");
49453
- const [sel, setSel] = (0, import_react33.useState)(() => scopeIndexOf("User" /* User */));
49454
- const scopeItems = (0, import_react33.useMemo)(() => getScopeItems(), []);
49455
- const [scopeSel, setScopeSel] = (0, import_react33.useState)(0);
50109
+ const [sel, setSel] = (0, import_react34.useState)(() => scopeIndexOf("User" /* User */));
50110
+ const scopeItems = (0, import_react34.useMemo)(() => getScopeItems(), []);
50111
+ const [scopeSel, setScopeSel] = (0, import_react34.useState)(0);
49456
50112
  const highlightScope = /* @__PURE__ */ __name((idx) => {
49457
50113
  const item = scopeItems[idx];
49458
50114
  if (!item) return;
@@ -49566,12 +50222,12 @@ function OpenTuiTrustDialog({ config, onClose }) {
49566
50222
  __name(OpenTuiTrustDialog, "OpenTuiTrustDialog");
49567
50223
  function OpenTuiDeleteDialog({ config, onClose, notify }) {
49568
50224
  useEsc(onClose);
49569
- const [rows, setRows] = (0, import_react33.useState)([]);
49570
- const [loading, setLoading] = (0, import_react33.useState)(true);
49571
- const [cursor, setCursor] = (0, import_react33.useState)(0);
49572
- const [busy, setBusy] = (0, import_react33.useState)(false);
50225
+ const [rows, setRows] = (0, import_react34.useState)([]);
50226
+ const [loading, setLoading] = (0, import_react34.useState)(true);
50227
+ const [cursor, setCursor] = (0, import_react34.useState)(0);
50228
+ const [busy, setBusy] = (0, import_react34.useState)(false);
49573
50229
  const currentSessionId = config?.getSessionId?.() ?? "";
49574
- (0, import_react33.useEffect)(() => {
50230
+ (0, import_react34.useEffect)(() => {
49575
50231
  let alive = true;
49576
50232
  const svc = config?.getSessionService?.();
49577
50233
  if (!svc) {
@@ -49654,10 +50310,10 @@ function OpenTuiResumeDialog({
49654
50310
  onSelect
49655
50311
  }) {
49656
50312
  useEsc(onClose);
49657
- const [rows, setRows] = (0, import_react33.useState)(matchedSessions ?? []);
49658
- const [loading, setLoading] = (0, import_react33.useState)(!matchedSessions);
49659
- const [cursor, setCursor] = (0, import_react33.useState)(0);
49660
- (0, import_react33.useEffect)(() => {
50313
+ const [rows, setRows] = (0, import_react34.useState)(matchedSessions ?? []);
50314
+ const [loading, setLoading] = (0, import_react34.useState)(!matchedSessions);
50315
+ const [cursor, setCursor] = (0, import_react34.useState)(0);
50316
+ (0, import_react34.useEffect)(() => {
49661
50317
  if (matchedSessions) {
49662
50318
  setRows(matchedSessions);
49663
50319
  setLoading(false);
@@ -49733,8 +50389,8 @@ function OpenTuiRewindDialog({ onClose }) {
49733
50389
  __name(OpenTuiRewindDialog, "OpenTuiRewindDialog");
49734
50390
  function OpenTuiDiffDialog({ onClose }) {
49735
50391
  useEsc(onClose);
49736
- const [lines, setLines] = (0, import_react33.useState)([]);
49737
- (0, import_react33.useEffect)(() => {
50392
+ const [lines, setLines] = (0, import_react34.useState)([]);
50393
+ (0, import_react34.useEffect)(() => {
49738
50394
  let alive = true;
49739
50395
  import("node:child_process").then(({ execFile }) => {
49740
50396
  execFile(
@@ -49771,9 +50427,9 @@ function OpenTuiSubagentCreateDialog({ onClose }) {
49771
50427
  __name(OpenTuiSubagentCreateDialog, "OpenTuiSubagentCreateDialog");
49772
50428
  function OpenTuiSubagentListDialog({ config, onClose }) {
49773
50429
  useEsc(onClose);
49774
- const [rows, setRows] = (0, import_react33.useState)([]);
49775
- const [loading, setLoading] = (0, import_react33.useState)(true);
49776
- (0, import_react33.useEffect)(() => {
50430
+ const [rows, setRows] = (0, import_react34.useState)([]);
50431
+ const [loading, setLoading] = (0, import_react34.useState)(true);
50432
+ (0, import_react34.useEffect)(() => {
49777
50433
  let alive = true;
49778
50434
  const mgr = config?.getSubagentManager?.();
49779
50435
  if (!mgr) {
@@ -49948,13 +50604,13 @@ function useLineInputKeys(value, onChange, onSubmit) {
49948
50604
  __name(useLineInputKeys, "useLineInputKeys");
49949
50605
  function ProtocolStep({ flow }) {
49950
50606
  const provider = flow.state.provider;
49951
- const items = (0, import_react35.useMemo)(() => {
50607
+ const items = (0, import_react36.useMemo)(() => {
49952
50608
  const protocolOpts = provider.protocolOptions ?? [provider.protocol];
49953
50609
  return PROTOCOL_ITEMS.filter(
49954
50610
  (p2) => protocolOpts.includes(p2.value)
49955
50611
  );
49956
50612
  }, [provider]);
49957
- const [cursor, setCursor] = (0, import_react35.useState)(0);
50613
+ const [cursor, setCursor] = (0, import_react36.useState)(0);
49958
50614
  useKeyboard((key) => {
49959
50615
  const o = toOriginalKey(key);
49960
50616
  if (o.name === "up") {
@@ -49983,7 +50639,7 @@ function BaseUrlSelectStep({
49983
50639
  description: opt.url,
49984
50640
  value: opt.url
49985
50641
  }));
49986
- const [cursor, setCursor] = (0, import_react35.useState)(flow.state.baseUrlOptionIndex);
50642
+ const [cursor, setCursor] = (0, import_react36.useState)(flow.state.baseUrlOptionIndex);
49987
50643
  useKeyboard((key) => {
49988
50644
  const o = toOriginalKey(key);
49989
50645
  if (o.name === "up" || o.name === "down") {
@@ -50067,24 +50723,24 @@ function ModelsStep({
50067
50723
  provider,
50068
50724
  flow
50069
50725
  }) {
50070
- const modelOptions = (0, import_react35.useMemo)(
50726
+ const modelOptions = (0, import_react36.useMemo)(
50071
50727
  () => provider.models?.map((m3) => m3.id) ?? [],
50072
50728
  [provider.models]
50073
50729
  );
50074
50730
  const hasSelectableModels = modelOptions.length > 0;
50075
- const selectedModelIds = (0, import_react35.useMemo)(
50731
+ const selectedModelIds = (0, import_react36.useMemo)(
50076
50732
  () => normalizeModelIds(flow.state.modelIds),
50077
50733
  [flow.state.modelIds]
50078
50734
  );
50079
- const recommendedIds = (0, import_react35.useMemo)(() => new Set(modelOptions), [modelOptions]);
50080
- const [focus, setFocus] = (0, import_react35.useState)(MODEL_CUSTOM_INPUT_FOCUS_INDEX);
50081
- const [customText, setCustomText] = (0, import_react35.useState)(
50735
+ const recommendedIds = (0, import_react36.useMemo)(() => new Set(modelOptions), [modelOptions]);
50736
+ const [focus, setFocus] = (0, import_react36.useState)(MODEL_CUSTOM_INPUT_FOCUS_INDEX);
50737
+ const [customText, setCustomText] = (0, import_react36.useState)(
50082
50738
  () => selectedModelIds.filter((id) => !recommendedIds.has(id)).join(", ")
50083
50739
  );
50084
- const [checked, setChecked] = (0, import_react35.useState)(
50740
+ const [checked, setChecked] = (0, import_react36.useState)(
50085
50741
  () => new Set(selectedModelIds.filter((id) => recommendedIds.has(id)))
50086
50742
  );
50087
- const syncModelIds = (0, import_react35.useCallback)(
50743
+ const syncModelIds = (0, import_react36.useCallback)(
50088
50744
  (custom, keys) => {
50089
50745
  flow.changeModelIds(
50090
50746
  uniqueIds([...normalizeModelIds(custom), ...keys]).join(", ")
@@ -50092,14 +50748,14 @@ function ModelsStep({
50092
50748
  },
50093
50749
  [flow]
50094
50750
  );
50095
- const updateCustom = (0, import_react35.useCallback)(
50751
+ const updateCustom = (0, import_react36.useCallback)(
50096
50752
  (next) => {
50097
50753
  setCustomText(next);
50098
50754
  syncModelIds(next, checked);
50099
50755
  },
50100
50756
  [checked, syncModelIds]
50101
50757
  );
50102
- const toggleRecommended = (0, import_react35.useCallback)(
50758
+ const toggleRecommended = (0, import_react36.useCallback)(
50103
50759
  (id) => {
50104
50760
  const next = new Set(checked);
50105
50761
  if (next.has(id)) next.delete(id);
@@ -50109,7 +50765,7 @@ function ModelsStep({
50109
50765
  },
50110
50766
  [checked, customText, syncModelIds]
50111
50767
  );
50112
- const submit = (0, import_react35.useCallback)(() => {
50768
+ const submit = (0, import_react36.useCallback)(() => {
50113
50769
  flow.submitModelIds({
50114
50770
  modelIds: uniqueIds([...normalizeModelIds(customText), ...checked])
50115
50771
  });
@@ -50339,14 +50995,17 @@ function AuthDialogFlow({
50339
50995
  config,
50340
50996
  settings,
50341
50997
  onClose,
50342
- notify
50998
+ notify,
50999
+ initialError
50343
51000
  }) {
50344
- const [errorMessage, setErrorMessage] = (0, import_react35.useState)(null);
50345
- const [viewLevel, setViewLevel] = (0, import_react35.useState)("main");
50346
- const [_viewStack, setViewStack] = (0, import_react35.useState)([]);
50347
- const [mainIndex, setMainIndex] = (0, import_react35.useState)(null);
50348
- const [subMenuIndex, setSubMenuIndex] = (0, import_react35.useState)({});
50349
- const handleProviderSubmit = (0, import_react35.useCallback)(
51001
+ const [errorMessage, setErrorMessage] = (0, import_react36.useState)(
51002
+ initialError ?? null
51003
+ );
51004
+ const [viewLevel, setViewLevel] = (0, import_react36.useState)("main");
51005
+ const [_viewStack, setViewStack] = (0, import_react36.useState)([]);
51006
+ const [mainIndex, setMainIndex] = (0, import_react36.useState)(null);
51007
+ const [subMenuIndex, setSubMenuIndex] = (0, import_react36.useState)({});
51008
+ const handleProviderSubmit = (0, import_react36.useCallback)(
50350
51009
  async (providerConfig, inputs) => {
50351
51010
  const protocol = inputs.protocol ?? providerConfig.protocol;
50352
51011
  try {
@@ -50378,15 +51037,15 @@ function AuthDialogFlow({
50378
51037
  [settings, config, notify, onClose]
50379
51038
  );
50380
51039
  const setupFlow = useProviderSetupFlow(handleProviderSubmit);
50381
- const clearErrors = (0, import_react35.useCallback)(() => setErrorMessage(null), []);
50382
- const pushView = (0, import_react35.useCallback)(
51040
+ const clearErrors = (0, import_react36.useCallback)(() => setErrorMessage(null), []);
51041
+ const pushView = (0, import_react36.useCallback)(
50383
51042
  (view) => {
50384
51043
  setViewStack((prev) => [...prev, viewLevel]);
50385
51044
  setViewLevel(view);
50386
51045
  },
50387
51046
  [viewLevel]
50388
51047
  );
50389
- const goBack = (0, import_react35.useCallback)(() => {
51048
+ const goBack = (0, import_react36.useCallback)(() => {
50390
51049
  clearErrors();
50391
51050
  if (viewLevel === "provider-setup") {
50392
51051
  if (setupFlow.goBack()) return;
@@ -50398,8 +51057,8 @@ function AuthDialogFlow({
50398
51057
  return next;
50399
51058
  });
50400
51059
  }, [viewLevel, setupFlow, clearErrors]);
50401
- const alibabaItems = (0, import_react35.useMemo)(() => ALIBABA_PROVIDERS.map(providerToItem), []);
50402
- const thirdPartyItems = (0, import_react35.useMemo)(
51060
+ const alibabaItems = (0, import_react36.useMemo)(() => ALIBABA_PROVIDERS.map(providerToItem), []);
51061
+ const thirdPartyItems = (0, import_react36.useMemo)(
50403
51062
  () => THIRD_PARTY_PROVIDERS.map(providerToItem),
50404
51063
  []
50405
51064
  );
@@ -50413,7 +51072,7 @@ function AuthDialogFlow({
50413
51072
  const builtinIds = new Set(getDefaultModelIds(providerConfig));
50414
51073
  return saved.models.map((m3) => m3.id).filter((id) => !builtinIds.has(id));
50415
51074
  }, "getExistingModelIds");
50416
- const handleProviderSelect = (0, import_react35.useCallback)(
51075
+ const handleProviderSelect = (0, import_react36.useCallback)(
50417
51076
  (providerId) => {
50418
51077
  clearErrors();
50419
51078
  const providerConfig = findProviderById(providerId);
@@ -50439,12 +51098,12 @@ function AuthDialogFlow({
50439
51098
  contentGenConfig?.baseUrl,
50440
51099
  contentGenConfig?.apiKeyEnvKey
50441
51100
  );
50442
- const defaultMainIndex = (0, import_react35.useMemo)(() => {
51101
+ const defaultMainIndex = (0, import_react36.useMemo)(() => {
50443
51102
  if (matchedProvider?.uiGroup === "third-party") return 1;
50444
51103
  if (matchedProvider?.uiGroup === "custom") return 2;
50445
51104
  return 0;
50446
51105
  }, [matchedProvider]);
50447
- const handleMainSelect = (0, import_react35.useCallback)(
51106
+ const handleMainSelect = (0, import_react36.useCallback)(
50448
51107
  (value) => {
50449
51108
  clearErrors();
50450
51109
  switch (value) {
@@ -50504,13 +51163,17 @@ function AuthDialogFlow({
50504
51163
  }
50505
51164
  });
50506
51165
  const renderer = useRenderer();
50507
- (0, import_react35.useLayoutEffect)(() => {
51166
+ (0, import_react36.useLayoutEffect)(() => {
50508
51167
  const onRaw = /* @__PURE__ */ __name((seq) => {
50509
51168
  if (seq !== "\x1B") return false;
50510
51169
  if (viewLevel !== "main") {
50511
51170
  goBack();
50512
51171
  return true;
50513
51172
  }
51173
+ if (initialError && errorMessage === initialError) {
51174
+ onClose();
51175
+ return true;
51176
+ }
50514
51177
  if (errorMessage) return true;
50515
51178
  if (config.getAuthType() === void 0) {
50516
51179
  setErrorMessage(
@@ -50525,8 +51188,16 @@ function AuthDialogFlow({
50525
51188
  }, "onRaw");
50526
51189
  renderer.addInputHandler(onRaw);
50527
51190
  return () => renderer.removeInputHandler(onRaw);
50528
- }, [renderer, viewLevel, goBack, errorMessage, config, onClose]);
50529
- const viewTitle = (0, import_react35.useMemo)(() => {
51191
+ }, [
51192
+ renderer,
51193
+ viewLevel,
51194
+ goBack,
51195
+ errorMessage,
51196
+ initialError,
51197
+ config,
51198
+ onClose
51199
+ ]);
51200
+ const viewTitle = (0, import_react36.useMemo)(() => {
50530
51201
  if (viewLevel !== "provider-setup") {
50531
51202
  return VIEW_TITLES[viewLevel] ?? VIEW_TITLES["main"];
50532
51203
  }
@@ -50566,7 +51237,7 @@ __name(AuthDialogFlow, "AuthDialogFlow");
50566
51237
 
50567
51238
  // packages/cli/src/ui/opentui/dialogs-arena.tsx
50568
51239
  init_esbuild_shims();
50569
- var import_react37 = __toESM(require_react(), 1);
51240
+ var import_react38 = __toESM(require_react(), 1);
50570
51241
  var MODEL_PROVIDERS_DOCUMENTATION_URL = "https://qwenlm.github.io/qwen-code-docs/en/users/configuration/settings/#modelproviders";
50571
51242
  var STATUS_REFRESH_INTERVAL_MS = 2e3;
50572
51243
  var IN_PROCESS_REFRESH_INTERVAL_MS = 1e3;
@@ -50632,7 +51303,7 @@ function ArenaFrame({
50632
51303
  }
50633
51304
  __name(ArenaFrame, "ArenaFrame");
50634
51305
  function ArenaStart({ config, onClose, onFillInput }) {
50635
- const modelItems = (0, import_react37.useMemo)(() => {
51306
+ const modelItems = (0, import_react38.useMemo)(() => {
50636
51307
  const all = config?.getAllConfiguredModels?.() ?? [];
50637
51308
  return all.filter((m3) => !m3.isRuntimeModel && !m3.imageOnly).map((m3) => {
50638
51309
  const token = `${m3.authType}:${m3.id}`;
@@ -50643,9 +51314,9 @@ function ArenaStart({ config, onClose, onFillInput }) {
50643
51314
  };
50644
51315
  });
50645
51316
  }, [config]);
50646
- const [cursor, setCursor] = (0, import_react37.useState)(0);
50647
- const [checked, setChecked] = (0, import_react37.useState)(/* @__PURE__ */ new Set());
50648
- const [error, setError] = (0, import_react37.useState)(null);
51317
+ const [cursor, setCursor] = (0, import_react38.useState)(0);
51318
+ const [checked, setChecked] = (0, import_react38.useState)(/* @__PURE__ */ new Set());
51319
+ const [error, setError] = (0, import_react38.useState)(null);
50649
51320
  const hasDisabledQwenOauth = modelItems.some((m3) => m3.disabled);
50650
51321
  const selectableCount = modelItems.filter((m3) => !m3.disabled).length;
50651
51322
  const needsMoreModels = selectableCount < 2;
@@ -50719,11 +51390,11 @@ __name(agentElapsedMs, "agentElapsedMs");
50719
51390
  function ArenaStatus({ config, onClose }) {
50720
51391
  const manager = config?.getArenaManager?.() ?? null;
50721
51392
  const { width } = useTerminalDimensions();
50722
- const [, setTick] = (0, import_react37.useState)(0);
51393
+ const [, setTick] = (0, import_react38.useState)(0);
50723
51394
  const backend3 = manager?.getBackend();
50724
51395
  const isInProcess = backend3?.type === DISPLAY_MODE.IN_PROCESS;
50725
51396
  const inProcessBackend = isInProcess ? backend3 : null;
50726
- (0, import_react37.useEffect)(() => {
51397
+ (0, import_react38.useEffect)(() => {
50727
51398
  const interval = isInProcess ? IN_PROCESS_REFRESH_INTERVAL_MS : STATUS_REFRESH_INTERVAL_MS;
50728
51399
  const timer = setInterval(() => setTick((t3) => t3 + 1), interval);
50729
51400
  return () => clearInterval(timer);
@@ -50804,7 +51475,7 @@ function ArenaStatus({ config, onClose }) {
50804
51475
  }
50805
51476
  __name(ArenaStatus, "ArenaStatus");
50806
51477
  function ArenaStop({ config, onClose, notify }) {
50807
- const [processing, setProcessing] = (0, import_react37.useState)(false);
51478
+ const [processing, setProcessing] = (0, import_react38.useState)(false);
50808
51479
  const preserveDefault = config?.getAgentsSettings?.().arena?.preserveArtifacts ?? false;
50809
51480
  const items = [
50810
51481
  {
@@ -50818,7 +51489,7 @@ function ArenaStop({ config, onClose, notify }) {
50818
51489
  desc: "Keep worktrees and session files for later inspection"
50819
51490
  }
50820
51491
  ];
50821
- const [sel, setSel] = (0, import_react37.useState)(preserveDefault ? 1 : 0);
51492
+ const [sel, setSel] = (0, import_react38.useState)(preserveDefault ? 1 : 0);
50822
51493
  const runStop = /* @__PURE__ */ __name(async (action) => {
50823
51494
  if (processing) return;
50824
51495
  setProcessing(true);
@@ -50950,17 +51621,17 @@ function AgentDetailedDiff({ result }) {
50950
51621
  __name(AgentDetailedDiff, "AgentDetailedDiff");
50951
51622
  function ArenaSelect({ config, onClose, notify }) {
50952
51623
  const manager = config?.getArenaManager?.() ?? null;
50953
- const agents = (0, import_react37.useMemo)(() => manager?.getAgentStates() ?? [], [manager]);
51624
+ const agents = (0, import_react38.useMemo)(() => manager?.getAgentStates() ?? [], [manager]);
50954
51625
  const result = manager?.getResult();
50955
- const [sel, setSel] = (0, import_react37.useState)(
51626
+ const [sel, setSel] = (0, import_react38.useState)(
50956
51627
  () => Math.max(
50957
51628
  0,
50958
51629
  agents.findIndex((a) => isSuccessStatus(a.status))
50959
51630
  )
50960
51631
  );
50961
- const [showPreview, setShowPreview] = (0, import_react37.useState)(false);
50962
- const [showDetailedDiff, setShowDetailedDiff] = (0, import_react37.useState)(false);
50963
- const rows = (0, import_react37.useMemo)(
51632
+ const [showPreview, setShowPreview] = (0, import_react38.useState)(false);
51633
+ const [showDetailedDiff, setShowDetailedDiff] = (0, import_react38.useState)(false);
51634
+ const rows = (0, import_react38.useMemo)(
50964
51635
  () => agents.map((agent) => {
50965
51636
  let additions = 0;
50966
51637
  let deletions = 0;
@@ -51129,24 +51800,24 @@ __name(OpenTuiArenaDialog, "OpenTuiArenaDialog");
51129
51800
 
51130
51801
  // packages/cli/src/ui/opentui/dialogs-memory-status.tsx
51131
51802
  init_esbuild_shims();
51132
- var import_react39 = __toESM(require_react(), 1);
51133
- import fs3 from "node:fs";
51134
- import path4 from "node:path";
51803
+ var import_react40 = __toESM(require_react(), 1);
51804
+ import fs4 from "node:fs";
51805
+ import path5 from "node:path";
51135
51806
  function resolvePreferredMemoryFile(dir) {
51136
51807
  const filenames = getAllGeminiMdFilenames();
51137
51808
  for (const filename of filenames) {
51138
- const filePath = path4.join(dir, filename);
51809
+ const filePath = path5.join(dir, filename);
51139
51810
  try {
51140
- if (fs3.existsSync(filePath)) return filePath;
51811
+ if (fs4.existsSync(filePath)) return filePath;
51141
51812
  } catch {
51142
51813
  }
51143
51814
  }
51144
- return path4.join(dir, filenames[0] ?? "QWEN.md");
51815
+ return path5.join(dir, filenames[0] ?? "QWEN.md");
51145
51816
  }
51146
51817
  __name(resolvePreferredMemoryFile, "resolvePreferredMemoryFile");
51147
51818
  function useEsc2(onClose) {
51148
51819
  const renderer = useRenderer();
51149
- (0, import_react39.useLayoutEffect)(() => {
51820
+ (0, import_react40.useLayoutEffect)(() => {
51150
51821
  const onRaw = /* @__PURE__ */ __name((seq) => {
51151
51822
  if (seq !== "\x1B") return false;
51152
51823
  onClose();
@@ -51200,7 +51871,7 @@ function OpenTuiMemoryDialog(props) {
51200
51871
  const toggle = /* @__PURE__ */ __name((k3) => readMemoryToggle(mem?.[k3], modes), "toggle");
51201
51872
  const cwd = config?.getWorkingDir?.() ?? process.cwd();
51202
51873
  const filenames = getAllGeminiMdFilenames();
51203
- const userMem = path4.join(
51874
+ const userMem = path5.join(
51204
51875
  Storage.getGlobalQwenDir(),
51205
51876
  filenames[0] ?? "QWEN.md"
51206
51877
  );
@@ -51248,10 +51919,10 @@ __name(OpenTuiStatusLineDialog, "OpenTuiStatusLineDialog");
51248
51919
 
51249
51920
  // packages/cli/src/ui/opentui/dialogs-modes.tsx
51250
51921
  init_esbuild_shims();
51251
- var import_react41 = __toESM(require_react(), 1);
51922
+ var import_react42 = __toESM(require_react(), 1);
51252
51923
  function useEsc3(onClose) {
51253
51924
  const renderer = useRenderer();
51254
- (0, import_react41.useLayoutEffect)(() => {
51925
+ (0, import_react42.useLayoutEffect)(() => {
51255
51926
  const onRaw = /* @__PURE__ */ __name((seq) => {
51256
51927
  if (seq !== "\x1B") return false;
51257
51928
  onClose();
@@ -51323,7 +51994,7 @@ function OpenTuiApprovalModeDialog(props) {
51323
51994
  const { config, settings, onClose, onApprovalModeChanged } = props;
51324
51995
  const modes = APPROVAL_MODES;
51325
51996
  const current = config?.getApprovalMode?.();
51326
- const [sel, setSel] = (0, import_react41.useState)(
51997
+ const [sel, setSel] = (0, import_react42.useState)(
51327
51998
  Math.max(0, modes.indexOf(current))
51328
51999
  );
51329
52000
  useEsc3(onClose);
@@ -51363,11 +52034,10 @@ var EFFORT_DESC = {
51363
52034
  };
51364
52035
  function OpenTuiEffortDialog(props) {
51365
52036
  const { config, settings, onClose } = props;
51366
- const tiers = REASONING_EFFORT_TIERS;
52037
+ const tiers = config ? [...getReasoningEffortsForConfig(config)] : REASONING_EFFORT_TIERS;
51367
52038
  const currentEffort = config?.getReasoningEffort?.();
51368
- const [sel, setSel] = (0, import_react41.useState)(
51369
- currentEffort ? Math.max(0, tiers.indexOf(currentEffort)) : 0
51370
- );
52039
+ const configuredIndex = currentEffort ? tiers.indexOf(currentEffort) : -1;
52040
+ const [sel, setSel] = (0, import_react42.useState)(Math.max(0, configuredIndex));
51371
52041
  useEsc3(onClose);
51372
52042
  const pick = /* @__PURE__ */ __name(() => {
51373
52043
  const effort = tiers[sel];
@@ -51386,19 +52056,22 @@ function OpenTuiEffortDialog(props) {
51386
52056
  }
51387
52057
  onClose();
51388
52058
  }, "pick");
51389
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell3, { title: "Reasoning Effort", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
51390
- RadioList2,
51391
- {
51392
- items: tiers.map((t3) => ({
51393
- key: t3,
51394
- label: String(t3),
51395
- desc: EFFORT_DESC[String(t3)]
51396
- })),
51397
- selected: sel,
51398
- onMove: (d3) => setSel((s) => Math.min(tiers.length - 1, Math.max(0, s + d3))),
51399
- onPick: pick
51400
- }
51401
- ) });
52059
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Shell3, { title: "Reasoning Effort", children: [
52060
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
52061
+ RadioList2,
52062
+ {
52063
+ items: tiers.map((t3) => ({
52064
+ key: t3,
52065
+ label: String(t3),
52066
+ desc: EFFORT_DESC[String(t3)]
52067
+ })),
52068
+ selected: sel,
52069
+ onMove: (d3) => setSel((s) => Math.min(tiers.length - 1, Math.max(0, s + d3))),
52070
+ onPick: pick
52071
+ }
52072
+ ),
52073
+ currentEffort && configuredIndex === -1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: `${currentEffort} is not available for this model \u2014 using the model/provider default.` }) : null
52074
+ ] });
51402
52075
  }
51403
52076
  __name(OpenTuiEffortDialog, "OpenTuiEffortDialog");
51404
52077
  var DEFAULT_STYLE_DESC = "The standard prompt, with no extra style";
@@ -51409,12 +52082,12 @@ function containsStyle(styles, name) {
51409
52082
  __name(containsStyle, "containsStyle");
51410
52083
  function OpenTuiOutputStyleDialog(props) {
51411
52084
  const { config, settings, onClose, notify } = props;
51412
- const [styles, setStyles] = (0, import_react41.useState)();
51413
- const onCloseRef = (0, import_react41.useRef)(onClose);
52085
+ const [styles, setStyles] = (0, import_react42.useState)();
52086
+ const onCloseRef = (0, import_react42.useRef)(onClose);
51414
52087
  onCloseRef.current = onClose;
51415
- const notifyRef = (0, import_react41.useRef)(notify);
52088
+ const notifyRef = (0, import_react42.useRef)(notify);
51416
52089
  notifyRef.current = notify;
51417
- (0, import_react41.useEffect)(() => {
52090
+ (0, import_react42.useEffect)(() => {
51418
52091
  let cancelled = false;
51419
52092
  void loadSessionOutputStyles(config).then(
51420
52093
  (loaded) => {
@@ -51450,8 +52123,8 @@ function OpenTuiOutputStyleDialog(props) {
51450
52123
  style
51451
52124
  }))
51452
52125
  ] : [];
51453
- const [sel, setSel] = (0, import_react41.useState)(0);
51454
- (0, import_react41.useEffect)(() => {
52126
+ const [sel, setSel] = (0, import_react42.useState)(0);
52127
+ (0, import_react42.useEffect)(() => {
51455
52128
  if (!styles) return;
51456
52129
  const wanted = current?.toLowerCase();
51457
52130
  const index = items.findIndex((item) => item.key.toLowerCase() === wanted);
@@ -51484,12 +52157,12 @@ function OpenTuiDialogMount(props) {
51484
52157
  const { request, host, config, settings, commands, onClose, notify } = props;
51485
52158
  const isHelp = request.dialog === "help";
51486
52159
  const dimensions = useTerminalDimensions();
51487
- const [permissions, setPermissions] = (0, import_react43.useState)(
52160
+ const [permissions, setPermissions] = (0, import_react44.useState)(
51488
52161
  () => request.dialog === "permissions" ? buildPermissionsData(config) : null
51489
52162
  );
51490
52163
  const reloadPermissions = /* @__PURE__ */ __name(() => setPermissions(buildPermissionsData(config)), "reloadPermissions");
51491
- const [mcpServers, setMcpServers] = (0, import_react43.useState)([]);
51492
- (0, import_react43.useEffect)(() => {
52164
+ const [mcpServers, setMcpServers] = (0, import_react44.useState)([]);
52165
+ (0, import_react44.useEffect)(() => {
51493
52166
  if (request.dialog !== "mcp") return;
51494
52167
  let alive = true;
51495
52168
  const initial = buildMcpServers(config);
@@ -51513,14 +52186,14 @@ function OpenTuiDialogMount(props) {
51513
52186
  }
51514
52187
  );
51515
52188
  }, "runMcpAction");
51516
- const [extRows, setExtRows] = (0, import_react43.useState)(
52189
+ const [extRows, setExtRows] = (0, import_react44.useState)(
51517
52190
  () => request.dialog === "extensions_manage" ? buildExtensionRows(config) : []
51518
52191
  );
51519
- const [extBusy, setExtBusy] = (0, import_react43.useState)(false);
51520
- const [extStatus, setExtStatus] = (0, import_react43.useState)(
52192
+ const [extBusy, setExtBusy] = (0, import_react44.useState)(false);
52193
+ const [extStatus, setExtStatus] = (0, import_react44.useState)(
51521
52194
  null
51522
52195
  );
51523
- const [extDiscoverFilter, setExtDiscoverFilter] = (0, import_react43.useState)(
52196
+ const [extDiscoverFilter, setExtDiscoverFilter] = (0, import_react44.useState)(
51524
52197
  null
51525
52198
  );
51526
52199
  const reloadExtensions = /* @__PURE__ */ __name(() => setExtRows(buildExtensionRows(config)), "reloadExtensions");
@@ -51573,9 +52246,9 @@ function OpenTuiDialogMount(props) {
51573
52246
  }
51574
52247
  }
51575
52248
  }, "runExtensionAction");
51576
- const [modelError, setModelError] = (0, import_react43.useState)(null);
51577
- const [helpTab, setHelpTab] = (0, import_react43.useState)("commands");
51578
- const [helpScroll, setHelpScroll] = (0, import_react43.useState)(0);
52249
+ const [modelError, setModelError] = (0, import_react44.useState)(null);
52250
+ const [helpTab, setHelpTab] = (0, import_react44.useState)("commands");
52251
+ const [helpScroll, setHelpScroll] = (0, import_react44.useState)(0);
51579
52252
  useKeyboard((key) => {
51580
52253
  if (!isHelp) return;
51581
52254
  const { name } = toOriginalKey(key);
@@ -51639,8 +52312,11 @@ function OpenTuiDialogMount(props) {
51639
52312
  onClose();
51640
52313
  return;
51641
52314
  }
51642
- if (props.onSelectSetting) props.onSelectSetting(name, scope);
51643
- else notify(`'${name}' opens a dialog this shell does not mount.`);
52315
+ if (props.onSelectSetting) {
52316
+ props.onSelectSetting(name, scope);
52317
+ return;
52318
+ }
52319
+ notify(`'${name}' opens a dialog this shell does not mount.`);
51644
52320
  onClose();
51645
52321
  }
51646
52322
  }
@@ -51662,6 +52338,7 @@ function OpenTuiDialogMount(props) {
51662
52338
  {
51663
52339
  config,
51664
52340
  settings,
52341
+ initialError: request.initialError,
51665
52342
  onClose,
51666
52343
  notify
51667
52344
  }
@@ -51897,8 +52574,8 @@ __name(OpenTuiDialogMount, "OpenTuiDialogMount");
51897
52574
 
51898
52575
  // packages/cli/src/ui/opentui/input-prompt.tsx
51899
52576
  init_esbuild_shims();
51900
- var import_react45 = __toESM(require_react(), 1);
51901
- import path5 from "node:path";
52577
+ var import_react46 = __toESM(require_react(), 1);
52578
+ import path6 from "node:path";
51902
52579
 
51903
52580
  // packages/cli/src/ui/opentui/input-history.ts
51904
52581
  init_esbuild_shims();
@@ -52039,12 +52716,17 @@ function OpenTuiInputPrompt(props) {
52039
52716
  onEscapeArmedChange,
52040
52717
  queueLength = 0,
52041
52718
  onPopQueue,
52042
- recentSlashCommands
52719
+ recentSlashCommands,
52720
+ promptSuggestion,
52721
+ onPromptSuggestionDismiss,
52722
+ onPromptSuggestionAbort,
52723
+ shellModeActive = false,
52724
+ onToggleShellMode
52043
52725
  } = props;
52044
52726
  const { width } = useTerminalDimensions();
52045
52727
  const renderer = useRenderer();
52046
- const editorRef = (0, import_react45.useRef)(null);
52047
- (0, import_react45.useEffect)(() => {
52728
+ const editorRef = (0, import_react46.useRef)(null);
52729
+ (0, import_react46.useEffect)(() => {
52048
52730
  if (!props.composerHandle) return;
52049
52731
  props.composerHandle.current = {
52050
52732
  getText: /* @__PURE__ */ __name(() => editorRef.current?.plainText ?? "", "getText"),
@@ -52056,39 +52738,59 @@ function OpenTuiInputPrompt(props) {
52056
52738
  if (props.composerHandle) props.composerHandle.current = null;
52057
52739
  };
52058
52740
  }, [props.composerHandle]);
52059
- const userMessagesRef = (0, import_react45.useRef)(userMessages);
52741
+ const userMessagesRef = (0, import_react46.useRef)(userMessages);
52060
52742
  userMessagesRef.current = userMessages;
52061
- const recentSlashCommandsRef = (0, import_react45.useRef)(recentSlashCommands);
52743
+ const recentSlashCommandsRef = (0, import_react46.useRef)(recentSlashCommands);
52062
52744
  recentSlashCommandsRef.current = recentSlashCommands;
52063
- const historyRef = (0, import_react45.useRef)(null);
52745
+ const historyRef = (0, import_react46.useRef)(null);
52064
52746
  if (!historyRef.current) {
52065
52747
  historyRef.current = new InputHistory(() => userMessagesRef.current);
52066
52748
  }
52067
- const escapeRef = (0, import_react45.useRef)(null);
52749
+ const escapeRef = (0, import_react46.useRef)(null);
52068
52750
  if (!escapeRef.current) {
52069
52751
  escapeRef.current = new EscapeClearModel();
52070
52752
  }
52071
- const [textVersion, setTextVersion] = (0, import_react45.useState)(0);
52072
- const [suggestions, setSuggestions] = (0, import_react45.useState)([]);
52073
- const [activeIndex, setActiveIndex] = (0, import_react45.useState)(0);
52074
- const [loadingSuggestions, setLoadingSuggestions] = (0, import_react45.useState)(false);
52075
- const [escapeArmed, setEscapeArmed] = (0, import_react45.useState)(false);
52076
- const [attachments, setAttachments] = (0, import_react45.useState)([]);
52077
- const completionModeRef = (0, import_react45.useRef)("IDLE" /* IDLE */);
52078
- const historyRestoredTextRef = (0, import_react45.useRef)(null);
52079
- const dismissedUntilChangeRef = (0, import_react45.useRef)(null);
52080
- const fileSearchRef = (0, import_react45.useRef)(null);
52081
- const fileSearchReadyRef = (0, import_react45.useRef)(null);
52082
- const atSearchSeqRef = (0, import_react45.useRef)(0);
52083
- const commandsRef = (0, import_react45.useRef)([]);
52084
- const slashRangeRef = (0, import_react45.useRef)(null);
52085
- const slashSearchSeqRef = (0, import_react45.useRef)(0);
52086
- const suggestionNavigatedRef = (0, import_react45.useRef)(false);
52087
- const pendingPastesRef = (0, import_react45.useRef)(/* @__PURE__ */ new Map());
52088
- const activePlaceholderIdsRef = (0, import_react45.useRef)(/* @__PURE__ */ new Map());
52089
- const chrome = promptChrome(approvalMode);
52753
+ const [textVersion, setTextVersion] = (0, import_react46.useState)(0);
52754
+ const [suggestions, setSuggestions] = (0, import_react46.useState)([]);
52755
+ const [activeIndex, setActiveIndex] = (0, import_react46.useState)(0);
52756
+ const [loadingSuggestions, setLoadingSuggestions] = (0, import_react46.useState)(false);
52757
+ const [escapeArmed, setEscapeArmed] = (0, import_react46.useState)(false);
52758
+ const [attachments, setAttachments] = (0, import_react46.useState)([]);
52759
+ const completionModeRef = (0, import_react46.useRef)("IDLE" /* IDLE */);
52760
+ const historyRestoredTextRef = (0, import_react46.useRef)(null);
52761
+ const dismissedUntilChangeRef = (0, import_react46.useRef)(null);
52762
+ const fileSearchRef = (0, import_react46.useRef)(null);
52763
+ const fileSearchReadyRef = (0, import_react46.useRef)(null);
52764
+ const atSearchSeqRef = (0, import_react46.useRef)(0);
52765
+ const commandsRef = (0, import_react46.useRef)([]);
52766
+ const slashRangeRef = (0, import_react46.useRef)(null);
52767
+ const slashSearchSeqRef = (0, import_react46.useRef)(0);
52768
+ const suggestionNavigatedRef = (0, import_react46.useRef)(false);
52769
+ const pendingPastesRef = (0, import_react46.useRef)(/* @__PURE__ */ new Map());
52770
+ const activePlaceholderIdsRef = (0, import_react46.useRef)(/* @__PURE__ */ new Map());
52771
+ const {
52772
+ state: followupState,
52773
+ accept: acceptFollowup,
52774
+ dismiss: dismissFollowup,
52775
+ recordKeystroke: recordFollowupKeystroke,
52776
+ setSuggestion: setFollowupSuggestion
52777
+ } = useFollowupSuggestionsCLI({
52778
+ config,
52779
+ isFocused: focus,
52780
+ onAccept: /* @__PURE__ */ __name((suggestion) => {
52781
+ const el = editorRef.current;
52782
+ if (!el) return;
52783
+ el.insertText(suggestion);
52784
+ setTextVersion((v3) => v3 + 1);
52785
+ }, "onAccept")
52786
+ });
52787
+ (0, import_react46.useEffect)(() => {
52788
+ setFollowupSuggestion(promptSuggestion ?? null);
52789
+ }, [setFollowupSuggestion, promptSuggestion]);
52790
+ const availableSuggestion = followupState.isVisible || promptSuggestion ? followupState.suggestion ?? promptSuggestion ?? null : null;
52791
+ const chrome = shellModeActive ? { prefix: "!", color: C2.accent, statusText: t("Shell mode") } : promptChrome(approvalMode);
52090
52792
  const borderColor = chrome.color ?? C2.accent;
52091
- (0, import_react45.useEffect)(() => {
52793
+ (0, import_react46.useEffect)(() => {
52092
52794
  let cancelled = false;
52093
52795
  loadInteractiveCommands(config ?? null).then((commands) => {
52094
52796
  if (!cancelled) commandsRef.current = commands;
@@ -52099,7 +52801,7 @@ function OpenTuiInputPrompt(props) {
52099
52801
  };
52100
52802
  }, [config]);
52101
52803
  const projectRoot = config?.getTargetDir() ?? process.cwd();
52102
- const ensureFileSearch = (0, import_react45.useCallback)(() => {
52804
+ const ensureFileSearch = (0, import_react46.useCallback)(() => {
52103
52805
  if (fileSearchReadyRef.current) return fileSearchReadyRef.current;
52104
52806
  const searcher = FileSearchFactory.create({
52105
52807
  projectRoot,
@@ -52119,7 +52821,7 @@ function OpenTuiInputPrompt(props) {
52119
52821
  });
52120
52822
  return fileSearchReadyRef.current;
52121
52823
  }, [config, projectRoot]);
52122
- (0, import_react45.useEffect)(
52824
+ (0, import_react46.useEffect)(
52123
52825
  () => () => {
52124
52826
  void fileSearchRef.current?.dispose?.();
52125
52827
  fileSearchRef.current = null;
@@ -52127,7 +52829,7 @@ function OpenTuiInputPrompt(props) {
52127
52829
  },
52128
52830
  []
52129
52831
  );
52130
- const currentCompletionTarget = (0, import_react45.useCallback)(() => {
52832
+ const currentCompletionTarget = (0, import_react46.useCallback)(() => {
52131
52833
  const el = editorRef.current;
52132
52834
  if (!el) return null;
52133
52835
  const text = el.plainText;
@@ -52142,7 +52844,7 @@ function OpenTuiInputPrompt(props) {
52142
52844
  commandsRef.current
52143
52845
  );
52144
52846
  }, []);
52145
- const refreshCompletion = (0, import_react45.useCallback)(() => {
52847
+ const refreshCompletion = (0, import_react46.useCallback)(() => {
52146
52848
  const el = editorRef.current;
52147
52849
  if (!el) return;
52148
52850
  const text = el.plainText;
@@ -52217,7 +52919,7 @@ function OpenTuiInputPrompt(props) {
52217
52919
  }
52218
52920
  });
52219
52921
  }, [ensureFileSearch, config, currentCompletionTarget]);
52220
- (0, import_react45.useEffect)(() => {
52922
+ (0, import_react46.useEffect)(() => {
52221
52923
  const el = editorRef.current;
52222
52924
  if (!el || textVersion === 0) return;
52223
52925
  if (historyRestoredTextRef.current !== null && el.plainText !== historyRestoredTextRef.current) {
@@ -52225,10 +52927,10 @@ function OpenTuiInputPrompt(props) {
52225
52927
  }
52226
52928
  refreshCompletion();
52227
52929
  }, [textVersion, refreshCompletion]);
52228
- (0, import_react45.useEffect)(() => {
52930
+ (0, import_react46.useEffect)(() => {
52229
52931
  refreshCompletion();
52230
52932
  }, [recentSlashCommands, refreshCompletion]);
52231
- const applyTextToEditor = (0, import_react45.useCallback)((line, cursorCol) => {
52933
+ const applyTextToEditor = (0, import_react46.useCallback)((line, cursorCol) => {
52232
52934
  const el = editorRef.current;
52233
52935
  if (!el) return;
52234
52936
  const cursor = el.logicalCursor;
@@ -52242,7 +52944,7 @@ function OpenTuiInputPrompt(props) {
52242
52944
  }
52243
52945
  setTextVersion((v3) => v3 + 1);
52244
52946
  }, []);
52245
- const acceptSuggestion = (0, import_react45.useCallback)(
52947
+ const acceptSuggestion = (0, import_react46.useCallback)(
52246
52948
  (index, viaEnter) => {
52247
52949
  const el = editorRef.current;
52248
52950
  const suggestion = suggestions[index];
@@ -52277,6 +52979,8 @@ function OpenTuiInputPrompt(props) {
52277
52979
  setSuggestions([]);
52278
52980
  setAttachments([]);
52279
52981
  onSubmit(finalText, images.length > 0 ? images : void 0);
52982
+ dismissFollowup();
52983
+ onPromptSuggestionDismiss?.();
52280
52984
  return;
52281
52985
  }
52282
52986
  const apply = /* @__PURE__ */ __name(() => {
@@ -52292,10 +52996,12 @@ function OpenTuiInputPrompt(props) {
52292
52996
  applyTextToEditor,
52293
52997
  onSubmit,
52294
52998
  attachments,
52295
- currentCompletionTarget
52999
+ currentCompletionTarget,
53000
+ dismissFollowup,
53001
+ onPromptSuggestionDismiss
52296
53002
  ]
52297
53003
  );
52298
- const handleClipboardImage = (0, import_react45.useCallback)(async () => {
53004
+ const handleClipboardImage = (0, import_react46.useCallback)(async () => {
52299
53005
  try {
52300
53006
  if (!await clipboardHasImage()) return;
52301
53007
  const imagePath = await saveClipboardImage(Storage.getGlobalTempDir());
@@ -52307,13 +53013,13 @@ function OpenTuiInputPrompt(props) {
52307
53013
  {
52308
53014
  id: `${Date.now()}-${prev.length}`,
52309
53015
  path: imagePath,
52310
- filename: path5.basename(imagePath)
53016
+ filename: path6.basename(imagePath)
52311
53017
  }
52312
53018
  ]);
52313
53019
  } catch {
52314
53020
  }
52315
53021
  }, []);
52316
- (0, import_react45.useLayoutEffect)(() => {
53022
+ (0, import_react46.useLayoutEffect)(() => {
52317
53023
  const onRawInput = /* @__PURE__ */ __name((sequence) => {
52318
53024
  if (!focus) return false;
52319
53025
  if (isDeleteWordBackwardSequence(sequence)) {
@@ -52364,12 +53070,16 @@ function OpenTuiInputPrompt(props) {
52364
53070
  renderer.addInputHandler(onRawInput);
52365
53071
  return () => renderer.removeInputHandler(onRawInput);
52366
53072
  }, [renderer, focus]);
52367
- (0, import_react45.useLayoutEffect)(() => {
53073
+ (0, import_react46.useLayoutEffect)(() => {
52368
53074
  const onPaste = /* @__PURE__ */ __name((event) => {
52369
53075
  if (!focus) return;
52370
53076
  const el = editorRef.current;
52371
53077
  if (!el) return;
52372
53078
  const pasted = normalizePastedText(decodePasteBytes(event.bytes));
53079
+ if (el.plainText.length === 0 && availableSuggestion) {
53080
+ dismissFollowup();
53081
+ onPromptSuggestionDismiss?.();
53082
+ }
52373
53083
  if (!isLargePaste(pasted)) return;
52374
53084
  event.preventDefault();
52375
53085
  const charCount = [...pasted].length;
@@ -52385,7 +53095,15 @@ function OpenTuiInputPrompt(props) {
52385
53095
  return () => {
52386
53096
  renderer.keyInput.off("paste", onPaste);
52387
53097
  };
52388
- }, [renderer, focus]);
53098
+ }, [
53099
+ renderer,
53100
+ focus,
53101
+ // availableSuggestion/dismissFollowup/onPromptSuggestionDismiss are read
53102
+ // in the handler: resubscribe when they change or the closure goes stale.
53103
+ availableSuggestion,
53104
+ dismissFollowup,
53105
+ onPromptSuggestionDismiss
53106
+ ]);
52389
53107
  useKeyboard((key) => {
52390
53108
  if (!focus) return;
52391
53109
  const el = editorRef.current;
@@ -52410,6 +53128,14 @@ function OpenTuiInputPrompt(props) {
52410
53128
  acceptSuggestion(activeIndex, true);
52411
53129
  return;
52412
53130
  }
53131
+ if (el.plainText.length === 0 && availableSuggestion) {
53132
+ key.preventDefault();
53133
+ acceptFollowup("enter", {
53134
+ fallbackText: promptSuggestion ?? void 0
53135
+ });
53136
+ onPromptSuggestionDismiss?.();
53137
+ return;
53138
+ }
52413
53139
  const decision = decideSubmit(
52414
53140
  el.plainText,
52415
53141
  displayOffsetToCodePointIndex(el.plainText, el.cursorOffset)
@@ -52443,6 +53169,8 @@ function OpenTuiInputPrompt(props) {
52443
53169
  setSuggestions([]);
52444
53170
  setLoadingSuggestions(false);
52445
53171
  onSubmit(finalText, images.length > 0 ? images : void 0);
53172
+ dismissFollowup();
53173
+ onPromptSuggestionDismiss?.();
52446
53174
  key.preventDefault();
52447
53175
  return;
52448
53176
  }
@@ -52457,7 +53185,17 @@ function OpenTuiInputPrompt(props) {
52457
53185
  key.preventDefault();
52458
53186
  return;
52459
53187
  }
53188
+ if (key.sequence === "!" && key.eventType !== "release" && el.plainText.length === 0 && suggestions.length === 0 && onToggleShellMode) {
53189
+ onToggleShellMode();
53190
+ key.preventDefault();
53191
+ return;
53192
+ }
52460
53193
  if (isPrintableKeyInput(key)) {
53194
+ if (el.plainText.length === 0 && availableSuggestion) {
53195
+ recordFollowupKeystroke();
53196
+ dismissFollowup();
53197
+ onPromptSuggestionAbort?.();
53198
+ }
52461
53199
  el.insertText(key.sequence);
52462
53200
  setTextVersion((v3) => v3 + 1);
52463
53201
  key.preventDefault();
@@ -52473,6 +53211,11 @@ function OpenTuiInputPrompt(props) {
52473
53211
  }
52474
53212
  if (key.name === "escape") {
52475
53213
  key.preventDefault();
53214
+ if (shellModeActive) {
53215
+ onToggleShellMode?.();
53216
+ if (streaming) onInterrupt?.();
53217
+ return;
53218
+ }
52476
53219
  if (streaming) {
52477
53220
  onInterrupt?.();
52478
53221
  return;
@@ -52509,6 +53252,7 @@ ${current}` : popped);
52509
53252
  }
52510
53253
  const navigationUp = key.name === "up" && !key.shift && !key.ctrl || key.name === "p" && !!key.ctrl;
52511
53254
  const navigationDown = key.name === "down" && !key.shift && !key.ctrl || key.name === "n" && !!key.ctrl;
53255
+ const historyNavActive = !shellModeActive;
52512
53256
  const showing = suggestions.length > 0;
52513
53257
  if (showing && (navigationUp || navigationDown)) {
52514
53258
  key.preventDefault();
@@ -52526,7 +53270,19 @@ ${current}` : popped);
52526
53270
  acceptSuggestion(activeIndex, false);
52527
53271
  return;
52528
53272
  }
52529
- if (navigationUp && queueLength > 0) {
53273
+ if (!showing && key.name === "tab" && !key.shift && el.plainText.length === 0 && availableSuggestion) {
53274
+ key.preventDefault();
53275
+ acceptFollowup("tab", { fallbackText: promptSuggestion ?? void 0 });
53276
+ onPromptSuggestionDismiss?.();
53277
+ return;
53278
+ }
53279
+ if (key.name === "right" && !key.ctrl && !key.meta && el.plainText.length === 0 && availableSuggestion) {
53280
+ key.preventDefault();
53281
+ acceptFollowup("right", { fallbackText: promptSuggestion ?? void 0 });
53282
+ onPromptSuggestionDismiss?.();
53283
+ return;
53284
+ }
53285
+ if (historyNavActive && navigationUp && queueLength > 0) {
52530
53286
  const topCursor = el.logicalCursor;
52531
53287
  if (topCursor.row === 0 && topCursor.col === 0) {
52532
53288
  const popped = onPopQueue?.();
@@ -52540,7 +53296,7 @@ ${current}` : popped);
52540
53296
  }
52541
53297
  }
52542
53298
  }
52543
- if (navigationUp) {
53299
+ if (historyNavActive && navigationUp) {
52544
53300
  const cursor = el.logicalCursor;
52545
53301
  const decision = historyUpDecision(
52546
53302
  historyRef.current,
@@ -52564,7 +53320,7 @@ ${current}` : popped);
52564
53320
  setTextVersion((v3) => v3 + 1);
52565
53321
  return;
52566
53322
  }
52567
- if (navigationDown) {
53323
+ if (historyNavActive && navigationDown) {
52568
53324
  const cursor = el.logicalCursor;
52569
53325
  const lastLine = el.plainText.split("\n").pop() ?? "";
52570
53326
  const decision = historyDownDecision(
@@ -52589,45 +53345,11 @@ ${current}` : popped);
52589
53345
  return;
52590
53346
  }
52591
53347
  });
52592
- const handleSubmit = (0, import_react45.useCallback)(() => {
52593
- const el = editorRef.current;
52594
- if (!el) return;
52595
- const text = el.plainText;
52596
- const decision = decideSubmit(
52597
- text,
52598
- displayOffsetToCodePointIndex(text, el.cursorOffset)
52599
- );
52600
- if (decision.kind === "noop") return;
52601
- if (decision.kind === "newline-continuation") {
52602
- el.deleteCharBackward();
52603
- el.newLine();
52604
- setTextVersion((v3) => v3 + 1);
52605
- return;
52606
- }
52607
- let finalText = decision.text.trim();
52608
- if (pendingPastesRef.current.size > 0) {
52609
- finalText = expandPendingPastePlaceholders(
52610
- finalText,
52611
- pendingPastesRef.current
52612
- );
52613
- pendingPastesRef.current.clear();
52614
- activePlaceholderIdsRef.current.clear();
52615
- }
52616
- const images = attachments.map((a) => a.path);
52617
- el.clear();
52618
- setTextVersion((v3) => v3 + 1);
52619
- historyRef.current?.reset();
52620
- historyRestoredTextRef.current = null;
52621
- setSuggestions([]);
52622
- setLoadingSuggestions(false);
52623
- setAttachments([]);
52624
- onSubmit(finalText, images.length > 0 ? images : void 0);
52625
- }, [onSubmit, attachments]);
52626
- (0, import_react45.useEffect)(() => {
53348
+ (0, import_react46.useEffect)(() => {
52627
53349
  const el = editorRef.current;
52628
53350
  if (el) el.textColor = C2.text;
52629
53351
  }, []);
52630
- (0, import_react45.useEffect)(() => {
53352
+ (0, import_react46.useEffect)(() => {
52631
53353
  const el = editorRef.current;
52632
53354
  if (el) {
52633
53355
  el.keyBindings = [
@@ -52680,14 +53402,13 @@ ${current}` : popped);
52680
53402
  flexGrow: 1,
52681
53403
  minHeight: 1,
52682
53404
  maxHeight: 8,
52683
- placeholder,
53405
+ placeholder: availableSuggestion ?? placeholder,
52684
53406
  placeholderColor: C2.dim,
52685
53407
  textColor: C2.text,
52686
53408
  cursorColor: C2.accent,
52687
53409
  selectionBg: C2.selectionBg,
52688
53410
  selectionFg: C2.selectionFg,
52689
53411
  wrapMode: "char",
52690
- onSubmit: handleSubmit,
52691
53412
  onContentChange: () => setTextVersion((v3) => v3 + 1),
52692
53413
  onCursorChange: () => setTextVersion((v3) => v3 + 1),
52693
53414
  keyBindings: [
@@ -52745,7 +53466,7 @@ __name(OpenTuiInputPrompt, "OpenTuiInputPrompt");
52745
53466
 
52746
53467
  // packages/cli/src/ui/opentui/dialogs-confirm.tsx
52747
53468
  init_esbuild_shims();
52748
- var import_react47 = __toESM(require_react(), 1);
53469
+ var import_react48 = __toESM(require_react(), 1);
52749
53470
 
52750
53471
  // packages/cli/src/ui/opentui/diff-render.ts
52751
53472
  init_esbuild_shims();
@@ -52841,279 +53562,9 @@ function renderDiffBody(fileDiff) {
52841
53562
  }
52842
53563
  __name(renderDiffBody, "renderDiffBody");
52843
53564
 
52844
- // packages/cli/src/ui/opentui/messages.tsx
52845
- init_esbuild_shims();
52846
- var TOOL_STATUS = {
52847
- SUCCESS: "\u2713",
52848
- PENDING: "o",
52849
- EXECUTING: "\u22B7",
52850
- CONFIRMING: "?",
52851
- CANCELED: "-",
52852
- ERROR: "x"
52853
- };
52854
- var MESSAGE_ICON = {
52855
- DIAMOND: "\u25C6",
52856
- THEREFORE: "\u2234",
52857
- BECAUSE: "\u2235",
52858
- CIRCLE_FILLED: "\u25CF"
52859
- };
52860
- var STATUS_INDICATOR_WIDTH = 2;
52861
- var selectionProps = /* @__PURE__ */ __name(() => ({
52862
- selectionBg: C2.selectionBg,
52863
- selectionFg: C2.selectionFg
52864
- }), "selectionProps");
52865
- var STRIKETHROUGH_ATTR = 128;
52866
- var TODO_STATUS_ICONS = {
52867
- pending: ICON.CIRCLE_EMPTY,
52868
- in_progress: ICON.CIRCLE_LEFT_HALF,
52869
- completed: ICON.CIRCLE_FILLED
52870
- };
52871
- var MAX_RESULT_DISPLAY_CHARACTERS = 1e6;
52872
- function maxHistoryItemRows(terminalHeight) {
52873
- return Math.max(Math.floor(terminalHeight) * 4, 100);
52874
- }
52875
- __name(maxHistoryItemRows, "maxHistoryItemRows");
52876
- function truncateResultDisplayChars(text) {
52877
- return text.length > MAX_RESULT_DISPLAY_CHARACTERS ? "..." + text.slice(-MAX_RESULT_DISPLAY_CHARACTERS) : text;
52878
- }
52879
- __name(truncateResultDisplayChars, "truncateResultDisplayChars");
52880
- function tailWindow(lines, maxRows) {
52881
- const target = Math.max(Math.round(maxRows), 2);
52882
- if (lines.length <= target) return { visible: lines, hiddenCount: 0 };
52883
- const visibleContentHeight = target - 1;
52884
- return {
52885
- visible: lines.slice(lines.length - visibleContentHeight),
52886
- hiddenCount: lines.length - visibleContentHeight
52887
- };
52888
- }
52889
- __name(tailWindow, "tailWindow");
52890
- function hiddenLinesLabel(hiddenCount) {
52891
- return `... first ${hiddenCount} line${hiddenCount === 1 ? "" : "s"} hidden ...`;
52892
- }
52893
- __name(hiddenLinesLabel, "hiddenLinesLabel");
52894
- function toolCardName(rawName) {
52895
- return TOOL_DISPLAY_BY_NAME[rawName] ?? rawName;
52896
- }
52897
- __name(toolCardName, "toolCardName");
52898
- var GENERIC_TOOL_SUMMARIES = /* @__PURE__ */ new Set([
52899
- "ok",
52900
- "error",
52901
- "cancelled",
52902
- "canceled",
52903
- "interrupted",
52904
- "skipped"
52905
- ]);
52906
- function toolCardSummarySuffix(done, summary) {
52907
- if (!done || !summary || GENERIC_TOOL_SUMMARIES.has(summary)) return "";
52908
- return ` \xB7 ${summary}`;
52909
- }
52910
- __name(toolCardSummarySuffix, "toolCardSummarySuffix");
52911
- function toolCardText(v3) {
52912
- return sanitizeMultilineForDisplay(v3.replace(/\s*\n\s*/g, " ").trim());
52913
- }
52914
- __name(toolCardText, "toolCardText");
52915
- function toolCardDescription(rawName, args) {
52916
- let parsed = {};
52917
- try {
52918
- parsed = JSON.parse(args ?? "{}");
52919
- } catch {
52920
- return "";
52921
- }
52922
- const str = /* @__PURE__ */ __name((v3) => typeof v3 === "string" && v3.length > 0 ? v3 : void 0, "str");
52923
- const oneLine = toolCardText;
52924
- switch (rawName) {
52925
- case "run_shell_command": {
52926
- const cmd = str(parsed["command"] ?? parsed["cmd"]);
52927
- if (!cmd) return "";
52928
- const desc = str(parsed["description"]);
52929
- return desc ? `${oneLine(cmd)} (${oneLine(desc)})` : oneLine(cmd);
52930
- }
52931
- case "read_file":
52932
- case "write_file":
52933
- case "edit":
52934
- case "notebook_edit": {
52935
- const p2 = str(
52936
- parsed["file_path"] ?? parsed["path"] ?? parsed["filePath"]
52937
- );
52938
- return p2 ? oneLine(p2) : "";
52939
- }
52940
- case "list_directory":
52941
- case "glob": {
52942
- const p2 = str(parsed["path"] ?? parsed["dir"] ?? parsed["pattern"]);
52943
- return p2 ? oneLine(p2) : "";
52944
- }
52945
- case "grep_search": {
52946
- const pat = str(parsed["pattern"]);
52947
- return pat ? oneLine(pat) : "";
52948
- }
52949
- default:
52950
- return "";
52951
- }
52952
- }
52953
- __name(toolCardDescription, "toolCardDescription");
52954
- function userMessageMeta() {
52955
- return { glyph: ">", color: C2.purple };
52956
- }
52957
- __name(userMessageMeta, "userMessageMeta");
52958
- function assistantMessageMeta() {
52959
- return { glyph: MESSAGE_ICON.DIAMOND, color: C2.purple };
52960
- }
52961
- __name(assistantMessageMeta, "assistantMessageMeta");
52962
- function thinkingMeta(done, expanded, clickable) {
52963
- const expandHint = clickable ? "(click or ctrl+o to expand)" : "(ctrl+o to expand)";
52964
- if (!done) {
52965
- return {
52966
- icon: MESSAGE_ICON.BECAUSE,
52967
- label: "Thinking\u2026",
52968
- hint: "",
52969
- color: C2.dim,
52970
- collapsed: false
52971
- };
52972
- }
52973
- if (!expanded) {
52974
- return {
52975
- icon: MESSAGE_ICON.THEREFORE,
52976
- label: "Thought",
52977
- hint: expandHint,
52978
- color: C2.dim,
52979
- collapsed: true
52980
- };
52981
- }
52982
- return {
52983
- icon: MESSAGE_ICON.THEREFORE,
52984
- label: "Thought",
52985
- hint: "(ctrl+o to collapse)",
52986
- color: C2.dim,
52987
- collapsed: false
52988
- };
52989
- }
52990
- __name(thinkingMeta, "thinkingMeta");
52991
- function toolStatusMeta(item) {
52992
- if (item.confirm === "pending" && !item.done) {
52993
- return {
52994
- glyph: TOOL_STATUS.CONFIRMING,
52995
- color: C2.yellow,
52996
- strikethrough: false
52997
- };
52998
- }
52999
- if (!item.done) {
53000
- return {
53001
- glyph: TOOL_STATUS.EXECUTING,
53002
- color: C2.text,
53003
- strikethrough: false
53004
- };
53005
- }
53006
- if (item.success) {
53007
- return { glyph: TOOL_STATUS.SUCCESS, color: C2.green, strikethrough: false };
53008
- }
53009
- const canceled = item.summary === "interrupted" || item.summary === "canceled" || item.summary === "cancelled";
53010
- if (canceled) {
53011
- return { glyph: TOOL_STATUS.CANCELED, color: C2.text, strikethrough: true };
53012
- }
53013
- return { glyph: TOOL_STATUS.ERROR, color: C2.red, strikethrough: false };
53014
- }
53015
- __name(toolStatusMeta, "toolStatusMeta");
53016
- function TodoRows({ todos }) {
53017
- if (todos.length === 0) {
53018
- return null;
53019
- }
53020
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexDirection: "column", children: todos.map((todo) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TodoItemRow, { todo }, todo.id)) });
53021
- }
53022
- __name(TodoRows, "TodoRows");
53023
- function TodoItemRow({ todo }) {
53024
- const statusIcon = TODO_STATUS_ICONS[todo.status];
53025
- const isCompleted = todo.status === "completed";
53026
- const isInProgress = todo.status === "in_progress";
53027
- const itemColor = isCompleted ? C2.text : isInProgress ? C2.green : C2.text;
53028
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", minHeight: 1, children: [
53029
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { width: 3, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: itemColor, ...selectionProps(), children: statusIcon }) }),
53030
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
53031
- "text",
53032
- {
53033
- fg: itemColor,
53034
- attributes: isCompleted ? STRIKETHROUGH_ATTR : 0,
53035
- ...selectionProps(),
53036
- children: todo.content
53037
- }
53038
- ) })
53039
- ] });
53040
- }
53041
- __name(TodoItemRow, "TodoItemRow");
53042
- var ANSI_DEFAULT_HEIGHT = 24;
53043
- function truncateTokenLine(line, maxWidth) {
53044
- if (maxWidth <= 0) return [];
53045
- let width = 0;
53046
- const kept = [];
53047
- for (const token of line) {
53048
- const tokenWidth = getCachedStringWidth(token.text);
53049
- if (width + tokenWidth <= maxWidth) {
53050
- if (tokenWidth > 0 || kept.length === 0) kept.push(token);
53051
- width += tokenWidth;
53052
- continue;
53053
- }
53054
- let partial = "";
53055
- for (const cp of toCodePoints(token.text)) {
53056
- const cpWidth = getCachedStringWidth(cp);
53057
- if (width + cpWidth > maxWidth) break;
53058
- partial += cp;
53059
- width += cpWidth;
53060
- }
53061
- if (partial) kept.push({ ...token, text: partial });
53062
- break;
53063
- }
53064
- return kept;
53065
- }
53066
- __name(truncateTokenLine, "truncateTokenLine");
53067
- function ansiTokenProps(token) {
53068
- const fg2 = token.inverse ? token.bg : token.fg;
53069
- const bg2 = token.inverse ? token.fg : token.bg;
53070
- return {
53071
- fg: fg2 || void 0,
53072
- bg: bg2 || void 0,
53073
- attributes: (token.bold ? 1 : 0) | (token.dim ? 2 : 0) | (token.italic ? 4 : 0) | (token.underline ? 8 : 0)
53074
- };
53075
- }
53076
- __name(ansiTokenProps, "ansiTokenProps");
53077
- function AnsiRows({
53078
- grid,
53079
- maxWidth,
53080
- totalLines,
53081
- totalBytes
53082
- }) {
53083
- const windowed = tailWindow(grid, ANSI_DEFAULT_HEIGHT);
53084
- const stats = [];
53085
- if (totalLines && totalLines > ANSI_DEFAULT_HEIGHT) {
53086
- stats.push(`+${totalLines - ANSI_DEFAULT_HEIGHT} lines`);
53087
- }
53088
- if (totalBytes && totalBytes > 0) {
53089
- stats.push(formatMemoryUsage(totalBytes));
53090
- }
53091
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
53092
- windowed.hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, ...selectionProps(), children: hiddenLinesLabel(windowed.hiddenCount) }),
53093
- windowed.visible.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexDirection: "row", children: truncateTokenLine(line, maxWidth).map((token, j3) => {
53094
- const style = ansiTokenProps(token);
53095
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
53096
- "text",
53097
- {
53098
- fg: style.fg ?? C2.text,
53099
- bg: style.bg,
53100
- attributes: style.attributes,
53101
- ...selectionProps(),
53102
- children: token.text
53103
- },
53104
- `${j3}`
53105
- );
53106
- }) }, `${i}`)),
53107
- stats.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexDirection: "row", children: stats.map((part, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
53108
- i > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { children: " " }),
53109
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, ...selectionProps(), children: part })
53110
- ] }, `${i}`)) })
53111
- ] });
53112
- }
53113
- __name(AnsiRows, "AnsiRows");
53114
-
53115
53565
  // packages/cli/src/ui/opentui/dialogs-confirm.tsx
53116
53566
  var MAX_BODY_ROWS = 20;
53567
+ var EXPANDED_BODY_RESERVE_ROWS = 20;
53117
53568
  function buildOutcomeOptions(details) {
53118
53569
  const options = [
53119
53570
  { label: t("Yes, allow once"), value: "proceed_once" /* ProceedOnce */ }
@@ -53136,7 +53587,7 @@ function buildOutcomeOptions(details) {
53136
53587
  }
53137
53588
  __name(buildOutcomeOptions, "buildOutcomeOptions");
53138
53589
  function DiffBody({ fileDiff }) {
53139
- const lines = (0, import_react47.useMemo)(() => renderDiffBody(fileDiff), [fileDiff]);
53590
+ const lines = (0, import_react48.useMemo)(() => renderDiffBody(fileDiff), [fileDiff]);
53140
53591
  const window = tailWindow(lines, MAX_BODY_ROWS);
53141
53592
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
53142
53593
  window.hiddenCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -53151,12 +53602,45 @@ function DiffBody({ fileDiff }) {
53151
53602
  }
53152
53603
  __name(DiffBody, "DiffBody");
53153
53604
  function TextBody({ text }) {
53154
- const rows = (0, import_react47.useMemo)(() => {
53155
- const clean = sanitizeTerminalText(text);
53156
- const window = tailWindow(clean.split("\n"), MAX_BODY_ROWS);
53157
- return window.visible;
53158
- }, [text]);
53159
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexDirection: "column", children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { children: row }, `${i}`)) });
53605
+ const [expanded, setExpanded] = (0, import_react48.useState)(false);
53606
+ const { width, height } = useTerminalDimensions();
53607
+ const rows = (0, import_react48.useMemo)(() => sanitizeTerminalText(text).split("\n"), [text]);
53608
+ const window = (0, import_react48.useMemo)(
53609
+ () => headWindowPhysical(rows, width, MAX_BODY_ROWS),
53610
+ [rows, width]
53611
+ );
53612
+ const expandedWindow = (0, import_react48.useMemo)(
53613
+ () => tailWindowPhysical(
53614
+ rows,
53615
+ width,
53616
+ Math.max(height - EXPANDED_BODY_RESERVE_ROWS, 1)
53617
+ ),
53618
+ [rows, width, height]
53619
+ );
53620
+ const canExpand = window.hiddenRows > 0 && expandedWindow.hiddenRows < window.hiddenRows;
53621
+ useKeyboard((key) => {
53622
+ if (key.ctrl && toOriginalKey(key).name === "s" && canExpand) {
53623
+ setExpanded(true);
53624
+ }
53625
+ });
53626
+ if (expanded) {
53627
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
53628
+ expandedWindow.visible.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { children: row }, `${i}`)),
53629
+ expandedWindow.hiddenRows > 0 ? (
53630
+ // The tail window keeps the LAST rows, so what it drops is the
53631
+ // head — the same label the transcript's tail windows use (R5-1).
53632
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: hiddenLinesLabel(expandedWindow.hiddenRows) })
53633
+ ) : null
53634
+ ] });
53635
+ }
53636
+ if (window.hiddenRows === 0) {
53637
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexDirection: "column", children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { children: row }, `${i}`)) });
53638
+ }
53639
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
53640
+ window.visible.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { children: row }, `${i}`)),
53641
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: hiddenTailLinesLabel(window.hiddenRows) }),
53642
+ canExpand ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: "Press ctrl-s to show more lines" }) : null
53643
+ ] });
53160
53644
  }
53161
53645
  __name(TextBody, "TextBody");
53162
53646
  function ConfirmationBody({
@@ -53176,6 +53660,15 @@ function ConfirmationBody({
53176
53660
  ] });
53177
53661
  case "mcp":
53178
53662
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
53663
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { children: sanitizeTerminalText(
53664
+ t(
53665
+ 'Allow execution of MCP tool "{{tool}}" from server "{{server}}"?',
53666
+ {
53667
+ tool: details.toolName,
53668
+ server: details.serverName
53669
+ }
53670
+ )
53671
+ ) }),
53179
53672
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.accent, attributes: 1, children: sanitizeTerminalText(details.toolDisplayName) }),
53180
53673
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: sanitizeTerminalText(
53181
53674
  `${details.serverName} \xB7 ${details.toolName}`
@@ -53198,7 +53691,7 @@ function ConfirmationBody({
53198
53691
  }
53199
53692
  __name(ConfirmationBody, "ConfirmationBody");
53200
53693
  function OutcomeSelect(props) {
53201
- const items = (0, import_react47.useMemo)(
53694
+ const items = (0, import_react48.useMemo)(
53202
53695
  () => props.options.map((option, index) => ({
53203
53696
  key: `${option.value}-${index}`,
53204
53697
  value: option.value,
@@ -53231,8 +53724,8 @@ __name(OutcomeSelect, "OutcomeSelect");
53231
53724
  function OpenTuiToolConfirmation(props) {
53232
53725
  const { call, onSettled } = props;
53233
53726
  const details = call.confirmationDetails;
53234
- const settledRef = (0, import_react47.useRef)(false);
53235
- const settle = (0, import_react47.useCallback)(
53727
+ const settledRef = (0, import_react48.useRef)(false);
53728
+ const settle = (0, import_react48.useCallback)(
53236
53729
  (outcome, payload) => {
53237
53730
  if (settledRef.current) return;
53238
53731
  settledRef.current = true;
@@ -53286,12 +53779,12 @@ function OpenTuiToolConfirmation(props) {
53286
53779
  __name(OpenTuiToolConfirmation, "OpenTuiToolConfirmation");
53287
53780
  function AskUserQuestionFlow(props) {
53288
53781
  const { details, onAnswered } = props;
53289
- const [index, setIndex] = (0, import_react47.useState)(0);
53290
- const [answers, setAnswers] = (0, import_react47.useState)({});
53291
- const [selected, setSelected] = (0, import_react47.useState)(/* @__PURE__ */ new Set());
53782
+ const [index, setIndex] = (0, import_react48.useState)(0);
53783
+ const [answers, setAnswers] = (0, import_react48.useState)({});
53784
+ const [selected, setSelected] = (0, import_react48.useState)(/* @__PURE__ */ new Set());
53292
53785
  const question = details.questions[index];
53293
53786
  const isMulti = question?.multiSelect === true;
53294
- const commitQuestion = (0, import_react47.useCallback)(
53787
+ const commitQuestion = (0, import_react48.useCallback)(
53295
53788
  (value) => {
53296
53789
  if (value === void 0) return;
53297
53790
  const nextAnswers = { ...answers, [index]: value };
@@ -53309,7 +53802,7 @@ function AskUserQuestionFlow(props) {
53309
53802
  },
53310
53803
  [answers, index, details.questions.length, onAnswered]
53311
53804
  );
53312
- const items = (0, import_react47.useMemo)(
53805
+ const items = (0, import_react48.useMemo)(
53313
53806
  () => (question?.options ?? []).map((option, i) => ({
53314
53807
  key: `${option.label}-${i}`,
53315
53808
  value: option.label
@@ -53344,7 +53837,7 @@ function AskUserQuestionFlow(props) {
53344
53837
  commitQuestion([...selected].join(", "));
53345
53838
  }
53346
53839
  });
53347
- (0, import_react47.useEffect)(() => {
53840
+ (0, import_react48.useEffect)(() => {
53348
53841
  if (details.questions.length === 0 || !question?.options?.length) {
53349
53842
  onAnswered(null);
53350
53843
  }
@@ -53387,7 +53880,7 @@ function AskUserQuestionFlow(props) {
53387
53880
  __name(AskUserQuestionFlow, "AskUserQuestionFlow");
53388
53881
  function OpenTuiShellConfirmation(props) {
53389
53882
  const { commands, onResolve } = props;
53390
- const options = (0, import_react47.useMemo)(
53883
+ const options = (0, import_react48.useMemo)(
53391
53884
  () => [
53392
53885
  {
53393
53886
  label: t("Yes, allow once"),
@@ -53434,7 +53927,7 @@ function OpenTuiShellConfirmation(props) {
53434
53927
  __name(OpenTuiShellConfirmation, "OpenTuiShellConfirmation");
53435
53928
  function OpenTuiActionConfirmation(props) {
53436
53929
  const { prompt, onResolve } = props;
53437
- const options = (0, import_react47.useMemo)(
53930
+ const options = (0, import_react48.useMemo)(
53438
53931
  () => [
53439
53932
  { key: "yes", value: true },
53440
53933
  { key: "no", value: false }
@@ -53497,17 +53990,83 @@ function OpenTuiApp(props) {
53497
53990
  onPopQueue,
53498
53991
  waitingToolCalls,
53499
53992
  onToolCallSettled,
53500
- onRenderError
53993
+ onRenderError,
53994
+ promptSuggestion,
53995
+ onPromptSuggestionDismiss,
53996
+ onPromptSuggestionAbort
53501
53997
  } = props;
53502
- const [dialog, setDialog] = (0, import_react49.useState)(null);
53503
- const [noticeText, setNoticeText] = (0, import_react49.useState)(null);
53504
- const [commandList, setCommandList] = (0, import_react49.useState)(
53998
+ const [dialog, setDialog] = (0, import_react50.useState)(
53999
+ props.initialDialog ?? null
54000
+ );
54001
+ const [noticeText, setNoticeText] = (0, import_react50.useState)(null);
54002
+ const [commandList, setCommandList] = (0, import_react50.useState)(
53505
54003
  commands ?? []
53506
54004
  );
53507
- const notify = (0, import_react49.useCallback)((text) => setNoticeText(text), []);
53508
- const [modals, setModals] = (0, import_react49.useState)([]);
53509
- const modalSeq = (0, import_react49.useRef)(0);
53510
- const confirmations = (0, import_react49.useMemo)(
54005
+ const notify = (0, import_react50.useCallback)((text) => setNoticeText(text), []);
54006
+ const [shellModeActive, setShellModeActive] = (0, import_react50.useState)(false);
54007
+ const shellControllersRef = (0, import_react50.useRef)(/* @__PURE__ */ new Set());
54008
+ const { width: terminalWidth, height: terminalHeight } = useTerminalDimensions();
54009
+ const toggleShellMode = (0, import_react50.useCallback)(
54010
+ () => setShellModeActive((active) => !active),
54011
+ []
54012
+ );
54013
+ const runShellCommand = (0, import_react50.useCallback)(
54014
+ (command) => {
54015
+ const emit = props.onTranscriptEvent;
54016
+ if (!emit) return;
54017
+ const controller = new AbortController();
54018
+ shellControllersRef.current.add(controller);
54019
+ return executeUserShell(
54020
+ config,
54021
+ command,
54022
+ emit,
54023
+ controller.signal,
54024
+ // The `!` row renders behind the 2-col input indicator, and the child
54025
+ // runs over that inner width (ink parity: it also passes the raw
54026
+ // terminal width to its `!` child — no SHELL_WIDTH_FRACTION here,
54027
+ // which only reaches the model-driven tool).
54028
+ {
54029
+ width: Math.max(terminalWidth - STATUS_INDICATOR_WIDTH, 10),
54030
+ height: terminalHeight
54031
+ }
54032
+ ).catch((error) => {
54033
+ emit({
54034
+ type: "error",
54035
+ text: `An unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`
54036
+ });
54037
+ }).finally(() => {
54038
+ shellControllersRef.current.delete(controller);
54039
+ setDeferredRevision((revision) => revision + 1);
54040
+ });
54041
+ },
54042
+ [config, props.onTranscriptEvent, terminalWidth, terminalHeight]
54043
+ );
54044
+ (0, import_react50.useEffect)(
54045
+ () => () => {
54046
+ for (const controller of shellControllersRef.current) {
54047
+ controller.abort();
54048
+ }
54049
+ },
54050
+ []
54051
+ );
54052
+ const handleSelectSetting = (0, import_react50.useCallback)((name) => {
54053
+ if (name === "ui.theme") setDialog({ dialog: "theme" });
54054
+ else if (name === "general.preferredEditor")
54055
+ setDialog({ dialog: "editor" });
54056
+ else if (name === "fastModel") setDialog({ dialog: "model", mode: "fast" });
54057
+ else if (name === "visionModel")
54058
+ setDialog({ dialog: "model", mode: "vision" });
54059
+ else setDialog(null);
54060
+ }, []);
54061
+ const fillComposer = (0, import_react50.useCallback)(
54062
+ (text) => {
54063
+ injectCapturedInput(() => props.composerHandle?.current ?? null, text);
54064
+ },
54065
+ [props.composerHandle]
54066
+ );
54067
+ const [modals, setModals] = (0, import_react50.useState)([]);
54068
+ const modalSeq = (0, import_react50.useRef)(0);
54069
+ const confirmations = (0, import_react50.useMemo)(
53511
54070
  () => ({
53512
54071
  presentShell: /* @__PURE__ */ __name((commandsToRun) => new Promise((resolve4) => {
53513
54072
  modalSeq.current += 1;
@@ -53532,14 +54091,14 @@ function OpenTuiApp(props) {
53532
54091
  []
53533
54092
  );
53534
54093
  const activeModal = modals[0] ?? null;
53535
- const closeShellModal = (0, import_react49.useCallback)(
54094
+ const closeShellModal = (0, import_react50.useCallback)(
53536
54095
  (modal, resolution) => {
53537
54096
  setModals((prev) => prev.filter((m3) => m3.id !== modal.id));
53538
54097
  modal.resolve(resolution);
53539
54098
  },
53540
54099
  []
53541
54100
  );
53542
- const closeActionModal = (0, import_react49.useCallback)(
54101
+ const closeActionModal = (0, import_react50.useCallback)(
53543
54102
  (modal, confirmed) => {
53544
54103
  setModals((prev) => prev.filter((m3) => m3.id !== modal.id));
53545
54104
  modal.resolve(confirmed);
@@ -53547,7 +54106,7 @@ function OpenTuiApp(props) {
53547
54106
  []
53548
54107
  );
53549
54108
  const activeToolCall = waitingToolCalls?.[0] ?? null;
53550
- const transcript = (0, import_react49.useMemo)(
54109
+ const transcript = (0, import_react50.useMemo)(
53551
54110
  () => ({
53552
54111
  reset: /* @__PURE__ */ __name((events) => onTranscriptReset?.(events), "reset"),
53553
54112
  // /clear semantics: a fresh transcript — the live turn's reset with an
@@ -53557,7 +54116,7 @@ function OpenTuiApp(props) {
53557
54116
  }),
53558
54117
  [onTranscriptReset, onTranscriptEvent]
53559
54118
  );
53560
- const host = (0, import_react49.useMemo)(
54119
+ const host = (0, import_react50.useMemo)(
53561
54120
  () => new OpenTuiAppHost({
53562
54121
  config,
53563
54122
  settings,
@@ -53586,18 +54145,27 @@ function OpenTuiApp(props) {
53586
54145
  getSessionStats
53587
54146
  ]
53588
54147
  );
53589
- (0, import_react49.useSyncExternalStore)(
53590
- (0, import_react49.useCallback)((cb) => host.subscribe(cb), [host]),
53591
- (0, import_react49.useCallback)(() => host.getVersion(), [host])
54148
+ (0, import_react50.useSyncExternalStore)(
54149
+ (0, import_react50.useCallback)((cb) => host.subscribe(cb), [host]),
54150
+ (0, import_react50.useCallback)(() => host.getVersion(), [host])
53592
54151
  );
53593
- (0, import_react49.useEffect)(() => {
54152
+ (0, import_react50.useEffect)(() => {
53594
54153
  host.setStreaming(!!streaming);
53595
54154
  }, [host, streaming]);
53596
- const gateway = (0, import_react49.useMemo)(() => new OpenTuiSlashGateway(), []);
53597
- const reloadRef = (0, import_react49.useRef)(null);
53598
- const deferredCommandsRef = (0, import_react49.useRef)([]);
53599
- const [deferredRevision, setDeferredRevision] = (0, import_react49.useState)(0);
53600
- (0, import_react49.useEffect)(() => {
54155
+ const gateway = (0, import_react50.useMemo)(() => new OpenTuiSlashGateway(), []);
54156
+ const reloadRef = (0, import_react50.useRef)(null);
54157
+ const deferredCommandsRef = (0, import_react50.useRef)([]);
54158
+ const [deferredRevision, setDeferredRevision] = (0, import_react50.useState)(0);
54159
+ const drainingRef = (0, import_react50.useRef)(false);
54160
+ const streamingRef = (0, import_react50.useRef)(streaming);
54161
+ (0, import_react50.useEffect)(() => {
54162
+ streamingRef.current = streaming;
54163
+ }, [streaming]);
54164
+ const dialogRef = (0, import_react50.useRef)(dialog);
54165
+ (0, import_react50.useEffect)(() => {
54166
+ dialogRef.current = dialog;
54167
+ }, [dialog]);
54168
+ (0, import_react50.useEffect)(() => {
53601
54169
  const dispatcher = new OpenTuiSlashDispatcher(
53602
54170
  host,
53603
54171
  { config, settings, logger, extensionRefreshState },
@@ -53632,7 +54200,7 @@ function OpenTuiApp(props) {
53632
54200
  commands,
53633
54201
  extensionRefreshState
53634
54202
  ]);
53635
- const applyOutcome = (0, import_react49.useCallback)(
54203
+ const applyOutcome = (0, import_react50.useCallback)(
53636
54204
  (outcome) => {
53637
54205
  switch (outcome.kind) {
53638
54206
  case "handled":
@@ -53656,6 +54224,9 @@ function OpenTuiApp(props) {
53656
54224
  case "quit":
53657
54225
  deferredCommandsRef.current = [];
53658
54226
  onPopQueue?.();
54227
+ for (const controller of shellControllersRef.current) {
54228
+ controller.abort();
54229
+ }
53659
54230
  onInterrupt?.();
53660
54231
  onQuit?.(outcome.messages);
53661
54232
  return;
@@ -53667,18 +54238,31 @@ function OpenTuiApp(props) {
53667
54238
  },
53668
54239
  [onSubmitPrompt, onQuit, onInterrupt, onPopQueue, notify]
53669
54240
  );
53670
- const onSubmit = (0, import_react49.useCallback)(
54241
+ const onSubmit = (0, import_react50.useCallback)(
53671
54242
  async (text, imagePaths) => {
53672
54243
  setNoticeText(null);
53673
54244
  const submission = normalizeQuitSubmission(text);
53674
- if (streaming && await gateway.mustDeferDuringStreaming(submission)) {
53675
- const command = submission.trim();
53676
- deferredCommandsRef.current.push(command);
53677
- setDeferredRevision((revision) => revision + 1);
53678
- notify(
53679
- `Queued ${command} \u2014 it will run when the current response ends.`
53680
- );
53681
- return;
54245
+ if (streaming || shellControllersRef.current.size > 0) {
54246
+ const takesAsSlash = await gateway.takesAsSlashCommand(submission);
54247
+ const shellEntry = shellModeActive && !takesAsSlash;
54248
+ const blockedByRunningShell = !takesAsSlash && shellControllersRef.current.size > 0;
54249
+ if (shellEntry || blockedByRunningShell || await gateway.mustDeferDuringStreaming(submission)) {
54250
+ const command = submission.trim();
54251
+ deferredCommandsRef.current.push({
54252
+ text: command,
54253
+ shell: shellEntry,
54254
+ // The attachments ride the entry: the seam's contract keeps image
54255
+ // paths in the second, structured argument, so a prompt the
54256
+ // running-`!` gate held back must not lose them in the queue
54257
+ // (R5-5 fix-induced).
54258
+ ...blockedByRunningShell && !shellEntry ? { prompt: true, imagePaths } : {}
54259
+ });
54260
+ setDeferredRevision((revision) => revision + 1);
54261
+ notify(
54262
+ `Queued ${command} \u2014 it will run when the current response ends.`
54263
+ );
54264
+ return;
54265
+ }
53682
54266
  }
53683
54267
  const settlement = await gateway.dispatch(submission);
53684
54268
  if (settlement.kind === "rejected") {
@@ -53686,11 +54270,15 @@ function OpenTuiApp(props) {
53686
54270
  return;
53687
54271
  }
53688
54272
  if (settlement.outcome === false) {
54273
+ const query = text.trim();
54274
+ if (shellModeActive && query) {
54275
+ void runShellCommand(query);
54276
+ return;
54277
+ }
53689
54278
  if (!onSubmitPrompt) {
53690
54279
  notify("The live prompt turn is not wired in this shell.");
53691
54280
  return;
53692
54281
  }
53693
- const query = text.trim();
53694
54282
  onSubmitPrompt(query, imagePaths, {
53695
54283
  submittedPrompt: query || void 0
53696
54284
  });
@@ -53698,31 +54286,71 @@ function OpenTuiApp(props) {
53698
54286
  }
53699
54287
  applyOutcome(settlement.outcome);
53700
54288
  },
53701
- [gateway, onSubmitPrompt, applyOutcome, notify, streaming]
54289
+ [
54290
+ gateway,
54291
+ onSubmitPrompt,
54292
+ applyOutcome,
54293
+ notify,
54294
+ streaming,
54295
+ shellModeActive,
54296
+ runShellCommand
54297
+ ]
53702
54298
  );
53703
- (0, import_react49.useEffect)(() => {
54299
+ (0, import_react50.useEffect)(() => {
53704
54300
  if (isExitInProgress()) return;
53705
- if (streaming || dialog || deferredCommandsRef.current.length === 0) {
54301
+ if (streaming || dialog || shellControllersRef.current.size > 0 || deferredCommandsRef.current.length === 0) {
53706
54302
  return;
53707
54303
  }
54304
+ if (drainingRef.current) return;
54305
+ drainingRef.current = true;
53708
54306
  const pending = deferredCommandsRef.current;
53709
54307
  deferredCommandsRef.current = [];
53710
54308
  void (async () => {
53711
- for (const [i, command] of pending.entries()) {
53712
- if (isExitInProgress()) return;
53713
- const settlement = await gateway.dispatch(command);
53714
- if (settlement.kind === "rejected") {
53715
- notify(settlement.reason);
53716
- continue;
53717
- }
53718
- if (settlement.outcome === false) continue;
53719
- const outcome = settlement.outcome;
53720
- applyOutcome(outcome);
53721
- const holdsUi = outcome.kind === "open_dialog" || outcome.kind === "submit_prompt" && !!onSubmitPrompt;
53722
- if (holdsUi && i + 1 < pending.length) {
53723
- deferredCommandsRef.current.unshift(...pending.slice(i + 1));
53724
- return;
54309
+ let paused = false;
54310
+ try {
54311
+ for (const [i, entry] of pending.entries()) {
54312
+ if (isExitInProgress()) return;
54313
+ if (streamingRef.current || dialogRef.current || shellControllersRef.current.size > 0) {
54314
+ deferredCommandsRef.current.unshift(...pending.slice(i));
54315
+ paused = true;
54316
+ return;
54317
+ }
54318
+ if (entry.shell) {
54319
+ await runShellCommand(entry.text);
54320
+ continue;
54321
+ }
54322
+ if (entry.prompt) {
54323
+ if (!onSubmitPrompt) {
54324
+ notify("The live prompt turn is not wired in this shell.");
54325
+ continue;
54326
+ }
54327
+ onSubmitPrompt(entry.text, entry.imagePaths, {
54328
+ submittedPrompt: entry.text || void 0
54329
+ });
54330
+ if (i + 1 < pending.length) {
54331
+ deferredCommandsRef.current.unshift(...pending.slice(i + 1));
54332
+ paused = true;
54333
+ }
54334
+ return;
54335
+ }
54336
+ const settlement = await gateway.dispatch(entry.text);
54337
+ if (settlement.kind === "rejected") {
54338
+ notify(settlement.reason);
54339
+ continue;
54340
+ }
54341
+ if (settlement.outcome === false) continue;
54342
+ const outcome = settlement.outcome;
54343
+ applyOutcome(outcome);
54344
+ const holdsUi = outcome.kind === "open_dialog" || outcome.kind === "submit_prompt" && !!onSubmitPrompt;
54345
+ if (holdsUi && i + 1 < pending.length) {
54346
+ deferredCommandsRef.current.unshift(...pending.slice(i + 1));
54347
+ paused = true;
54348
+ return;
54349
+ }
53725
54350
  }
54351
+ } finally {
54352
+ drainingRef.current = false;
54353
+ if (!paused) setDeferredRevision((revision) => revision + 1);
53726
54354
  }
53727
54355
  })();
53728
54356
  }, [
@@ -53732,9 +54360,10 @@ function OpenTuiApp(props) {
53732
54360
  gateway,
53733
54361
  notify,
53734
54362
  applyOutcome,
53735
- onSubmitPrompt
54363
+ onSubmitPrompt,
54364
+ runShellCommand
53736
54365
  ]);
53737
- const userMessages = (0, import_react49.useMemo)(
54366
+ const userMessages = (0, import_react50.useMemo)(
53738
54367
  () => host.getHistory().filter((item) => item.type === "user").map((item) => item.text ?? ""),
53739
54368
  // eslint-disable-next-line react-hooks/exhaustive-deps
53740
54369
  [host, host.getVersion()]
@@ -53779,6 +54408,8 @@ function OpenTuiApp(props) {
53779
54408
  commands: commandList,
53780
54409
  onClose: () => setDialog(null),
53781
54410
  notify,
54411
+ fillInput: fillComposer,
54412
+ onSelectSetting: handleSelectSetting,
53782
54413
  onApprovalModeChanged: void 0,
53783
54414
  availableTerminalHeight: props.availableTerminalHeight
53784
54415
  },
@@ -53797,7 +54428,12 @@ function OpenTuiApp(props) {
53797
54428
  approvalMode,
53798
54429
  queueLength,
53799
54430
  onPopQueue,
53800
- composerHandle: props.composerHandle
54431
+ composerHandle: props.composerHandle,
54432
+ promptSuggestion,
54433
+ onPromptSuggestionDismiss,
54434
+ onPromptSuggestionAbort,
54435
+ shellModeActive,
54436
+ onToggleShellMode: toggleShellMode
53801
54437
  }
53802
54438
  )
53803
54439
  ] })
@@ -53806,6 +54442,82 @@ function OpenTuiApp(props) {
53806
54442
  }
53807
54443
  __name(OpenTuiApp, "OpenTuiApp");
53808
54444
 
54445
+ // packages/cli/src/ui/opentui/followup-generation.ts
54446
+ init_esbuild_shims();
54447
+ var import_react52 = __toESM(require_react(), 1);
54448
+ function useFollowupSuggestionGeneration({
54449
+ config,
54450
+ settings,
54451
+ streaming,
54452
+ items,
54453
+ waitingCalls
54454
+ }) {
54455
+ const [promptSuggestion, setPromptSuggestion] = (0, import_react52.useState)(null);
54456
+ const abortRef = (0, import_react52.useRef)(null);
54457
+ const streamingRef = (0, import_react52.useRef)(streaming);
54458
+ const followupEnabled = settings.merged.ui?.enableFollowupSuggestions !== false;
54459
+ const cacheSharingEnabled = settings.merged.ui?.enableCacheSharing !== false;
54460
+ (0, import_react52.useEffect)(() => {
54461
+ const wasStreaming = streamingRef.current;
54462
+ if (!followupEnabled || wasStreaming !== streaming) {
54463
+ abortRef.current?.abort();
54464
+ setPromptSuggestion(null);
54465
+ }
54466
+ if (followupEnabled && config.isInteractive() && !config.getSdkMode() && wasStreaming && !streaming && items[items.length - 1]?.kind !== "error" && waitingCalls.length === 0 && config.getApprovalMode() !== "plan" /* PLAN */) {
54467
+ const ac = new AbortController();
54468
+ abortRef.current = ac;
54469
+ const conversationHistory = config.getLlmClient().getHistoryTail(40, true);
54470
+ generatePromptSuggestion(config, conversationHistory, ac.signal, {
54471
+ enableCacheSharing: cacheSharingEnabled
54472
+ }).then((result) => {
54473
+ if (ac.signal.aborted) return;
54474
+ if (result.suggestion) {
54475
+ setPromptSuggestion(result.suggestion);
54476
+ } else if (result.filterReason) {
54477
+ logPromptSuggestion(
54478
+ config,
54479
+ new PromptSuggestionEvent({
54480
+ outcome: "suppressed",
54481
+ reason: result.filterReason
54482
+ })
54483
+ );
54484
+ }
54485
+ }).catch(() => {
54486
+ });
54487
+ }
54488
+ streamingRef.current = streaming;
54489
+ }, [
54490
+ config,
54491
+ followupEnabled,
54492
+ cacheSharingEnabled,
54493
+ streaming,
54494
+ items,
54495
+ waitingCalls
54496
+ ]);
54497
+ (0, import_react52.useEffect)(
54498
+ () => () => {
54499
+ abortRef.current?.abort();
54500
+ },
54501
+ []
54502
+ );
54503
+ return {
54504
+ promptSuggestion,
54505
+ // Abort-only (ink AppContainer names this "abort", not "dismiss"):
54506
+ // typing over the ghost kills the in-flight publish but leaves the
54507
+ // suggestion set, so type-then-delete restores it.
54508
+ abortPromptSuggestion: /* @__PURE__ */ __name(() => {
54509
+ abortRef.current?.abort();
54510
+ }, "abortPromptSuggestion"),
54511
+ // Accept/submit path: the persisted suggestion is cleared too, or it
54512
+ // would survive as the ghost after the buffer moved on.
54513
+ dismissPromptSuggestion: /* @__PURE__ */ __name(() => {
54514
+ abortRef.current?.abort();
54515
+ setPromptSuggestion(null);
54516
+ }, "dismissPromptSuggestion")
54517
+ };
54518
+ }
54519
+ __name(useFollowupSuggestionGeneration, "useFollowupSuggestionGeneration");
54520
+
53809
54521
  // packages/cli/src/ui/opentui/opentui-runtime.ts
53810
54522
  init_esbuild_shims();
53811
54523
  var debugLogger3 = createDebugLogger("OPEN_TUI_RUNTIME");
@@ -53934,7 +54646,7 @@ var OpenTuiRuntime = class _OpenTuiRuntime {
53934
54646
 
53935
54647
  // packages/cli/src/ui/opentui/transcript-view.tsx
53936
54648
  init_esbuild_shims();
53937
- var import_react50 = __toESM(require_react(), 1);
54649
+ var import_react53 = __toESM(require_react(), 1);
53938
54650
 
53939
54651
  // packages/cli/src/ui/opentui/live-session-model.ts
53940
54652
  init_esbuild_shims();
@@ -54089,6 +54801,16 @@ function foldLiveEvent(prev, ev) {
54089
54801
  });
54090
54802
  return items;
54091
54803
  }
54804
+ case "confirm-resolved": {
54805
+ const i = findToolIndex(items, ev.id);
54806
+ if (i >= 0) {
54807
+ const t3 = items[i];
54808
+ if (t3.confirm === "pending") {
54809
+ items[i] = { ...t3, confirm: ev.outcome };
54810
+ }
54811
+ }
54812
+ return items;
54813
+ }
54092
54814
  case "task-start":
54093
54815
  if (last?.kind === "assistant" && last.streaming)
54094
54816
  items[items.length - 1] = { ...last, streaming: false };
@@ -54244,6 +54966,48 @@ function foldLiveEvent(prev, ev) {
54244
54966
  items.push({ kind: "stop-hook", id: nid("shk"), message: ev.message });
54245
54967
  return items;
54246
54968
  }
54969
+ case "away-recap": {
54970
+ if (last?.kind === "assistant" && last.streaming)
54971
+ items[items.length - 1] = { ...last, streaming: false };
54972
+ items.push({ kind: "away-recap", id: nid("recap"), text: ev.text });
54973
+ return items;
54974
+ }
54975
+ case "user-shell": {
54976
+ if (last?.kind === "assistant" && last.streaming)
54977
+ items[items.length - 1] = { ...last, streaming: false };
54978
+ items.push({ kind: "user-shell", id: nid("ushl"), text: ev.text });
54979
+ return items;
54980
+ }
54981
+ case "advisor": {
54982
+ if (last?.kind === "assistant" && last.streaming)
54983
+ items[items.length - 1] = { ...last, streaming: false };
54984
+ items.push({
54985
+ kind: "advisor",
54986
+ id: nid("advisor"),
54987
+ text: ev.text,
54988
+ model: ev.model
54989
+ });
54990
+ return items;
54991
+ }
54992
+ case "arena-agent": {
54993
+ if (last?.kind === "assistant" && last.streaming)
54994
+ items[items.length - 1] = { ...last, streaming: false };
54995
+ items.push({ kind: "arena-agent", id: nid("arena"), agent: ev.agent });
54996
+ return items;
54997
+ }
54998
+ case "arena-session": {
54999
+ if (last?.kind === "assistant" && last.streaming)
55000
+ items[items.length - 1] = { ...last, streaming: false };
55001
+ items.push({
55002
+ kind: "arena-session",
55003
+ id: nid("arena"),
55004
+ sessionStatus: ev.sessionStatus,
55005
+ task: ev.task,
55006
+ totalDurationMs: ev.totalDurationMs,
55007
+ agents: ev.agents
55008
+ });
55009
+ return items;
55010
+ }
54247
55011
  case "segment-end": {
54248
55012
  if (last?.kind === "assistant" && last.streaming)
54249
55013
  items[items.length - 1] = { ...last, streaming: false };
@@ -54329,6 +55093,13 @@ function describeGoalCard(snapshot, cause) {
54329
55093
  const activeTimeMs = goal.activeTimeMs ?? 0;
54330
55094
  if (activeTimeMs > 0)
54331
55095
  stats.push(formatDuration(activeTimeMs, { hideTrailingZeros: true }));
55096
+ const tokensUsed = goal.tokensUsed ?? 0;
55097
+ if (tokensUsed > 0) {
55098
+ const used = formatTokenCount(tokensUsed);
55099
+ stats.push(
55100
+ goal.tokenBudget === void 0 ? `${used} tokens` : `${used}/${formatTokenCount(goal.tokenBudget)} tokens`
55101
+ );
55102
+ }
54332
55103
  const reason = (goal.status ?? "active") !== "active" || activity === "verifying" ? goal.lastReason?.trim() : void 0;
54333
55104
  return {
54334
55105
  state: "card",
@@ -54966,6 +55737,7 @@ function OpenTuiTranscriptView({
54966
55737
  {
54967
55738
  item,
54968
55739
  maxRows,
55740
+ terminalHeight: availableTerminalHeight,
54969
55741
  width: availableWidth
54970
55742
  },
54971
55743
  item.id
@@ -54975,6 +55747,7 @@ __name(OpenTuiTranscriptView, "OpenTuiTranscriptView");
54975
55747
  function TranscriptItem({
54976
55748
  item,
54977
55749
  maxRows,
55750
+ terminalHeight,
54978
55751
  width
54979
55752
  }) {
54980
55753
  switch (item.kind) {
@@ -54985,7 +55758,15 @@ function TranscriptItem({
54985
55758
  case "thinking":
54986
55759
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThinkingRow, { text: item.text, done: item.done });
54987
55760
  case "tool":
54988
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolCard, { item, maxRows, width });
55761
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
55762
+ ToolCard,
55763
+ {
55764
+ item,
55765
+ maxRows,
55766
+ terminalHeight,
55767
+ width
55768
+ }
55769
+ );
54989
55770
  case "task":
54990
55771
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskCard, { item });
54991
55772
  case "image":
@@ -55016,6 +55797,16 @@ function TranscriptItem({
55016
55797
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StopHookRow, { message: item.message });
55017
55798
  case "goal":
55018
55799
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GoalCard, { item });
55800
+ case "away-recap":
55801
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AwayRecapRow, { text: item.text });
55802
+ case "user-shell":
55803
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UserShellRow, { text: item.text });
55804
+ case "advisor":
55805
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AdvisorRow, { text: item.text, model: item.model });
55806
+ case "arena-agent":
55807
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArenaAgentRow, { agent: item.agent });
55808
+ case "arena-session":
55809
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArenaSessionRow, { item });
55019
55810
  default: {
55020
55811
  const exhaustive = item;
55021
55812
  return exhaustive;
@@ -55053,7 +55844,7 @@ function AssistantRow({
55053
55844
  }
55054
55845
  __name(AssistantRow, "AssistantRow");
55055
55846
  function ThinkingRow({ text, done }) {
55056
- const [expanded, setExpanded] = (0, import_react50.useState)(false);
55847
+ const [expanded, setExpanded] = (0, import_react53.useState)(false);
55057
55848
  const meta = thinkingMeta(done, expanded, false);
55058
55849
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
55059
55850
  "box",
@@ -55078,11 +55869,19 @@ __name(ThinkingRow, "ThinkingRow");
55078
55869
  function ToolCard({
55079
55870
  item,
55080
55871
  maxRows,
55872
+ terminalHeight,
55081
55873
  width
55082
55874
  }) {
55083
55875
  const status = toolStatusMeta(item);
55084
55876
  const name = toolCardName(item.tool);
55085
55877
  const description = item.description ?? toolCardDescription(item.tool, item.args);
55878
+ const text = toolCardText(description);
55879
+ const cap = capToolCardDescription(
55880
+ text,
55881
+ name,
55882
+ width,
55883
+ item.confirm === "pending" && !item.done ? pendingCardMaxRows(terminalHeight, getCachedStringWidth(text), width) : TOOL_CARD_DESCRIPTION_ROWS
55884
+ );
55086
55885
  const suffix2 = toolCardSummarySuffix(item.done, item.summary);
55087
55886
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
55088
55887
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
@@ -55095,9 +55894,10 @@ function ToolCard({
55095
55894
  }
55096
55895
  ) }),
55097
55896
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, attributes: status.strikethrough ? 129 : 1, children: name }),
55098
- description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, ...selectionProps(), children: ` ${sanitizeTerminalText(description)}` }) : null,
55897
+ cap.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, ...selectionProps(), children: ` ${sanitizeTerminalText(cap.description)}` }) : null,
55099
55898
  suffix2 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: sanitizeTerminalText(suffix2) }) : null
55100
55899
  ] }),
55900
+ cap.hiddenRows > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: hiddenTailLinesLabel(cap.hiddenRows) }),
55101
55901
  item.confirm === "pending" && !item.done ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.yellow, children: " (awaiting approval)" }) : null,
55102
55902
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolCardBody, { item, maxRows, width })
55103
55903
  ] });
@@ -55195,8 +55995,8 @@ function RetryRows({
55195
55995
  delayMs,
55196
55996
  startedAt
55197
55997
  }) {
55198
- const [now, setNow] = (0, import_react50.useState)(() => Date.now());
55199
- (0, import_react50.useEffect)(() => {
55998
+ const [now, setNow] = (0, import_react53.useState)(() => Date.now());
55999
+ (0, import_react53.useEffect)(() => {
55200
56000
  const timer = setInterval(() => setNow(Date.now()), 1e3);
55201
56001
  return () => clearInterval(timer);
55202
56002
  }, []);
@@ -55276,10 +56076,171 @@ function LegacyGoalCard({ legacy }) {
55276
56076
  ] });
55277
56077
  }
55278
56078
  __name(LegacyGoalCard, "LegacyGoalCard");
56079
+ function AwayRecapRow({ text }) {
56080
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
56081
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: `${ICON.REFERENCE} ` }),
56082
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, attributes: 1, children: "recap: " }),
56083
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, attributes: 4, ...selectionProps(), children: sanitizeTerminalText(text) })
56084
+ ] });
56085
+ }
56086
+ __name(AwayRecapRow, "AwayRecapRow");
56087
+ function UserShellRow({ text }) {
56088
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
56089
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.accent, children: "$ " }),
56090
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, ...selectionProps(), children: sanitizeTerminalText(text) })
56091
+ ] });
56092
+ }
56093
+ __name(UserShellRow, "UserShellRow");
56094
+ function AdvisorRow({ text, model }) {
56095
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
56096
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
56097
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.accent, attributes: 1, children: "/advisor" }),
56098
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.accent, children: ` \xB7 ${sanitizeTerminalText(model)}` })
56099
+ ] }),
56100
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
56101
+ "markdown",
56102
+ {
56103
+ content: sanitizeTerminalText(text),
56104
+ syntaxStyle: SYNTAX,
56105
+ streaming: false
56106
+ }
56107
+ ) })
56108
+ ] });
56109
+ }
56110
+ __name(AdvisorRow, "AdvisorRow");
56111
+ function arenaStatusColor(status) {
56112
+ switch (status) {
56113
+ case "idle" /* IDLE */:
56114
+ case "completed" /* COMPLETED */:
56115
+ return C2.green;
56116
+ case "cancelled" /* CANCELLED */:
56117
+ return C2.yellow;
56118
+ case "failed" /* FAILED */:
56119
+ return C2.red;
56120
+ default:
56121
+ return C2.dim;
56122
+ }
56123
+ }
56124
+ __name(arenaStatusColor, "arenaStatusColor");
56125
+ function ArenaAgentRow({ agent }) {
56126
+ const { icon, text } = getArenaStatusLabel(agent.status);
56127
+ const failed = agent.failedToolCalls > 0;
56128
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
56129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: arenaStatusColor(agent.status), children: `${icon} ${sanitizeTerminalText(agent.label)} \xB7 ${text} \xB7 ${formatDuration(agent.durationMs)}` }),
56130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: ` Tokens: ${agent.totalTokens.toLocaleString()} (in ${agent.inputTokens.toLocaleString()}, out ${agent.outputTokens.toLocaleString()})` }),
56131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.dim, children: [
56132
+ ` Tool Calls: ${agent.toolCalls}`,
56133
+ failed ? " (" : null,
56134
+ failed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.green, children: `\u2713 ${agent.successfulToolCalls}` }) : null,
56135
+ failed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.red, children: ` \u2715 ${agent.failedToolCalls}` }) : null,
56136
+ failed ? ")" : null
56137
+ ] }),
56138
+ agent.error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.red, children: ` ${sanitizeTerminalText(agent.error)}` }) : null
56139
+ ] });
56140
+ }
56141
+ __name(ArenaAgentRow, "ArenaAgentRow");
56142
+ function arenaDiffStats(agent) {
56143
+ if (agent.diffSummary) {
56144
+ return {
56145
+ additions: agent.diffSummary.additions,
56146
+ deletions: agent.diffSummary.deletions
56147
+ };
56148
+ }
56149
+ if (!agent.diff) return { additions: 0, deletions: 0 };
56150
+ let additions = 0;
56151
+ let deletions = 0;
56152
+ for (const line of agent.diff.split("\n")) {
56153
+ if (line.startsWith("+") && !line.startsWith("+++")) additions++;
56154
+ else if (line.startsWith("-") && !line.startsWith("---")) deletions++;
56155
+ }
56156
+ return { additions, deletions };
56157
+ }
56158
+ __name(arenaDiffStats, "arenaDiffStats");
56159
+ function arenaAgentFiles(agent) {
56160
+ return agent.modifiedFiles ?? agent.diffSummary?.files.map((f2) => f2.path) ?? [];
56161
+ }
56162
+ __name(arenaAgentFiles, "arenaAgentFiles");
56163
+ var ARENA_MAX_FILE_ITEMS = 4;
56164
+ function arenaFileList(files) {
56165
+ if (files.length === 0) return "none";
56166
+ const visible = files.slice(0, ARENA_MAX_FILE_ITEMS);
56167
+ const suffix2 = files.length > ARENA_MAX_FILE_ITEMS ? `, +${files.length - ARENA_MAX_FILE_ITEMS} more` : "";
56168
+ return `${visible.join(", ")}${suffix2}`;
56169
+ }
56170
+ __name(arenaFileList, "arenaFileList");
56171
+ function arenaFileGroups(agents) {
56172
+ const counts = /* @__PURE__ */ new Map();
56173
+ for (const agent of agents) {
56174
+ for (const file of new Set(arenaAgentFiles(agent))) {
56175
+ counts.set(file, (counts.get(file) ?? 0) + 1);
56176
+ }
56177
+ }
56178
+ const common = [...counts.entries()].filter(([, count]) => count > 1).map(([file]) => file).sort();
56179
+ const groups = [{ label: "common", files: common }];
56180
+ for (const agent of agents) {
56181
+ const unique = arenaAgentFiles(agent).filter((file) => counts.get(file) === 1).sort();
56182
+ if (unique.length > 0) {
56183
+ groups.push({ label: `${agent.label}-only`, files: unique });
56184
+ }
56185
+ }
56186
+ return groups;
56187
+ }
56188
+ __name(arenaFileGroups, "arenaFileGroups");
56189
+ function ArenaSessionRow({ item }) {
56190
+ const { sessionStatus, agents } = item;
56191
+ const comparing = sessionStatus === "idle" || sessionStatus === "completed";
56192
+ const title = comparing ? "Arena Comparison Summary" : sessionStatus === "cancelled" ? "Arena Cancelled" : "Arena Failed";
56193
+ const branch = /* @__PURE__ */ __name((index, total) => index === total - 1 ? "\u2514\u2500" : "\u251C\u2500", "branch");
56194
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
56195
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, attributes: 1, children: title }),
56196
+ comparing ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
56197
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, attributes: 1, children: "Status Summary:" }),
56198
+ agents.map((agent, index) => {
56199
+ const { text } = getArenaStatusLabel(agent.status);
56200
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.dim, children: [
56201
+ ` ${branch(index, agents.length)} ${sanitizeTerminalText(agent.label)}: `,
56202
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: arenaStatusColor(agent.status), children: text })
56203
+ ] }, agent.label);
56204
+ }),
56205
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, attributes: 1, children: "Files Modified:" }),
56206
+ arenaFileGroups(agents).map((group, index, groups) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.dim, children: [
56207
+ ` ${branch(index, groups.length)} ${sanitizeTerminalText(group.label)}: `,
56208
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.text, children: sanitizeTerminalText(arenaFileList(group.files)) })
56209
+ ] }, group.label)),
56210
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, attributes: 1, children: "Approach Summary:" }),
56211
+ agents.map((agent, index) => {
56212
+ const stats = arenaDiffStats(agent);
56213
+ const files = arenaAgentFiles(agent).length;
56214
+ const summary = agent.approachSummary ?? "No approach summary available.";
56215
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.text, children: [
56216
+ ` ${branch(index, agents.length)} ${sanitizeTerminalText(agent.label)}: ${sanitizeTerminalText(summary)} `,
56217
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.dim, children: `(${files} ${files === 1 ? "file" : "files"}, ` }),
56218
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.green, children: `+${stats.additions}` }),
56219
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.dim, children: " " }),
56220
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.red, children: `-${stats.deletions}` }),
56221
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.dim, children: " lines, " }),
56222
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.accent, children: agent.toolCalls }),
56223
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.dim, children: agent.toolCalls === 1 ? " tool call)" : " tool calls)" })
56224
+ ] }, agent.label);
56225
+ }),
56226
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, attributes: 1, children: "Token Efficiency:" }),
56227
+ agents.map((agent, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.dim, children: [
56228
+ ` ${branch(index, agents.length)} ${sanitizeTerminalText(agent.label)}: `,
56229
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.text, children: `${agent.outputTokens.toLocaleString()} tokens \xB7 runtime ${formatDuration(agent.durationMs)}` })
56230
+ ] }, agent.label))
56231
+ ] }) : null,
56232
+ comparing ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.dim, children: [
56233
+ "Run ",
56234
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { fg: C2.accent, children: "/arena select" }),
56235
+ sessionStatus === "idle" ? " to view detailed diff or pick a winner." : " to pick a winner."
56236
+ ] }) : null
56237
+ ] });
56238
+ }
56239
+ __name(ArenaSessionRow, "ArenaSessionRow");
55279
56240
 
55280
56241
  // packages/cli/src/ui/opentui/live-turn.ts
55281
56242
  init_esbuild_shims();
55282
- var import_react51 = __toESM(require_react(), 1);
56243
+ var import_react54 = __toESM(require_react(), 1);
55283
56244
  import { readFileSync } from "node:fs";
55284
56245
 
55285
56246
  // packages/cli/src/ui/opentui/live-session.ts
@@ -55306,10 +56267,10 @@ function nextLivePromptId(config) {
55306
56267
  return id;
55307
56268
  }
55308
56269
  __name(nextLivePromptId, "nextLivePromptId");
55309
- function formatTokenCount(n) {
56270
+ function formatTokenCount2(n) {
55310
56271
  return n >= 1e3 ? `${(n / 1e3).toFixed(1)}k` : String(n);
55311
56272
  }
55312
- __name(formatTokenCount, "formatTokenCount");
56273
+ __name(formatTokenCount2, "formatTokenCount");
55313
56274
  function createEventQueue() {
55314
56275
  const buffer = [];
55315
56276
  let wake = null;
@@ -55444,10 +56405,12 @@ async function resolveSteeredPromptParts(config, texts, signal, turnModel) {
55444
56405
  const restore = /* @__PURE__ */ __name(() => ({
55445
56406
  parts: [],
55446
56407
  events: [],
56408
+ recordings: [],
55447
56409
  restore: [...texts]
55448
56410
  }), "restore");
55449
56411
  const events = [];
55450
56412
  const segments = [];
56413
+ const recordings = [];
55451
56414
  for (const message of texts) {
55452
56415
  if (signal.aborted) return restore();
55453
56416
  let resolved = [{ text: message }];
@@ -55498,6 +56461,7 @@ async function resolveSteeredPromptParts(config, texts, signal, turnModel) {
55498
56461
  events.push(imageFormatWarningEvent());
55499
56462
  }
55500
56463
  if (messageParts.length > 0) segments.push(messageParts);
56464
+ recordings.push({ message, parts: messageParts });
55501
56465
  events.push({ type: "user", text: message, sentToModel: false });
55502
56466
  }
55503
56467
  const parts = [];
@@ -55505,16 +56469,29 @@ async function resolveSteeredPromptParts(config, texts, signal, turnModel) {
55505
56469
  if (parts.length > 0) parts.push({ text: "\n\n" });
55506
56470
  parts.push(...segment);
55507
56471
  }
55508
- return { parts, events, restore: [] };
56472
+ return { parts, events, recordings, restore: [] };
55509
56473
  }
55510
56474
  __name(resolveSteeredPromptParts, "resolveSteeredPromptParts");
56475
+ var initializationPromises = /* @__PURE__ */ new WeakMap();
56476
+ function ensureConfigInitialized(config) {
56477
+ const pending = initializationPromises.get(config);
56478
+ if (pending) return pending;
56479
+ const started = config.initialize().catch((err) => {
56480
+ if (config.getGeminiClient()?.isInitialized?.() || err instanceof Error && err.message === "Config was already initialized") {
56481
+ return;
56482
+ }
56483
+ throw err;
56484
+ });
56485
+ started.catch(() => {
56486
+ });
56487
+ initializationPromises.set(config, started);
56488
+ return started;
56489
+ }
56490
+ __name(ensureConfigInitialized, "ensureConfigInitialized");
55511
56491
  var STARTUP_CHAT_WAIT_MS = 15e3;
55512
56492
  var STARTUP_CHAT_POLL_MS = 100;
55513
56493
  async function* livePromptEvents(config, prompt, signal, options) {
55514
- try {
55515
- await config.initialize();
55516
- } catch {
55517
- }
56494
+ await ensureConfigInitialized(config);
55518
56495
  const client = config.getGeminiClient();
55519
56496
  const chatDeadline = Date.now() + STARTUP_CHAT_WAIT_MS;
55520
56497
  const chatReady = /* @__PURE__ */ __name(() => client.isInitialized() && client.getChat().getGenerationConfig().tools !== void 0, "chatReady");
@@ -55570,6 +56547,23 @@ async function* livePromptEvents(config, prompt, signal, options) {
55570
56547
  if (hasUnsupportedImageFormat(nextPrompt)) {
55571
56548
  yield imageFormatWarningEvent();
55572
56549
  }
56550
+ let stashedSteeredTexts;
56551
+ let stashedRecordings = [];
56552
+ const flushSteeredStash = /* @__PURE__ */ __name(() => {
56553
+ if (!stashedSteeredTexts) return;
56554
+ const recorder = config.getChatRecordingService?.();
56555
+ for (const recording of stashedRecordings) {
56556
+ recorder?.recordMidTurnUserMessage(recording.parts, recording.message);
56557
+ }
56558
+ stashedRecordings = [];
56559
+ stashedSteeredTexts = void 0;
56560
+ }, "flushSteeredStash");
56561
+ const restoreSteeredStash = /* @__PURE__ */ __name(() => {
56562
+ if (!stashedSteeredTexts) return;
56563
+ options?.restoreSteering?.(stashedSteeredTexts);
56564
+ stashedRecordings = [];
56565
+ stashedSteeredTexts = void 0;
56566
+ }, "restoreSteeredStash");
55573
56567
  let first = true;
55574
56568
  const waitingSeen = /* @__PURE__ */ new Set();
55575
56569
  for (; ; ) {
@@ -55589,23 +56583,33 @@ async function* livePromptEvents(config, prompt, signal, options) {
55589
56583
  promptId,
55590
56584
  sendOptions
55591
56585
  );
55592
- for await (const ev of stream) {
55593
- if (dbg) {
55594
- try {
55595
- appendFileSync2(
55596
- "/tmp/opentui-events.log",
55597
- `${ev.type}
56586
+ try {
56587
+ for await (const ev of stream) {
56588
+ flushSteeredStash();
56589
+ if (dbg) {
56590
+ try {
56591
+ appendFileSync2(
56592
+ "/tmp/opentui-events.log",
56593
+ `${ev.type}
55598
56594
  `
56595
+ );
56596
+ } catch {
56597
+ }
56598
+ }
56599
+ if (ev.type === "tool_call_request") {
56600
+ pending.push(
56601
+ ev.value
55599
56602
  );
55600
- } catch {
55601
56603
  }
56604
+ for (const neutral of map(ev)) yield neutral;
55602
56605
  }
55603
- if (ev.type === "tool_call_request") {
55604
- pending.push(
55605
- ev.value
55606
- );
55607
- }
55608
- for (const neutral of map(ev)) yield neutral;
56606
+ } catch (error) {
56607
+ restoreSteeredStash();
56608
+ throw error;
56609
+ }
56610
+ if (stashedSteeredTexts) {
56611
+ if (abort.aborted) restoreSteeredStash();
56612
+ else flushSteeredStash();
55609
56613
  }
55610
56614
  if (pending.length === 0 || abort.aborted) return;
55611
56615
  const live = createEventQueue();
@@ -55643,7 +56647,7 @@ async function* livePromptEvents(config, prompt, signal, options) {
55643
56647
  id: callId,
55644
56648
  tools: stats?.totalToolCalls ?? agent.toolCalls?.length ?? 0,
55645
56649
  seconds: Math.round((stats?.totalDurationMs ?? 0) / 100) / 10,
55646
- tokens: formatTokenCount(
56650
+ tokens: formatTokenCount2(
55647
56651
  stats?.totalTokens ?? agent.tokenCount ?? 0
55648
56652
  )
55649
56653
  });
@@ -55678,19 +56682,32 @@ async function* livePromptEvents(config, prompt, signal, options) {
55678
56682
  description: invocation.getDescription()
55679
56683
  });
55680
56684
  }
55681
- if (!options?.onWaitingCall) return;
55682
56685
  const awaiting = new Set(
55683
56686
  calls.filter((c2) => c2.status === "awaiting_approval").map((c2) => c2.request.callId)
55684
56687
  );
55685
56688
  for (const id of waitingSeen) {
55686
- if (!awaiting.has(id)) waitingSeen.delete(id);
56689
+ if (!awaiting.has(id)) {
56690
+ waitingSeen.delete(id);
56691
+ const departed = calls.find((c2) => c2.request.callId === id);
56692
+ live.push({
56693
+ type: "confirm-resolved",
56694
+ id,
56695
+ outcome: departed?.status === "cancelled" ? "rejected" : "approved"
56696
+ });
56697
+ }
55687
56698
  }
55688
56699
  for (const c2 of calls) {
55689
56700
  if (c2.status !== "awaiting_approval") continue;
55690
56701
  const callId = c2.request.callId;
55691
56702
  if (waitingSeen.has(callId)) continue;
55692
56703
  waitingSeen.add(callId);
55693
- options.onWaitingCall({
56704
+ live.push({
56705
+ type: "confirm",
56706
+ id: callId,
56707
+ tool: c2.request.name,
56708
+ title: c2.confirmationDetails.title
56709
+ });
56710
+ options?.onWaitingCall?.({
55694
56711
  callId,
55695
56712
  name: c2.request.name,
55696
56713
  confirmationDetails: c2.confirmationDetails
@@ -55733,6 +56750,12 @@ async function* livePromptEvents(config, prompt, signal, options) {
55733
56750
  };
55734
56751
  if (resp?.responseParts) responseParts.push(...resp.responseParts);
55735
56752
  }
56753
+ if (completed.every((call) => call.status === "cancelled")) {
56754
+ if (responseParts.length > 0) {
56755
+ await client.addHistory({ role: "user", parts: responseParts });
56756
+ }
56757
+ return;
56758
+ }
55736
56759
  if (!abort.aborted) {
55737
56760
  const texts = (options?.drainSteering?.() ?? []).filter((text) => text);
55738
56761
  if (texts.length > 0) {
@@ -55742,9 +56765,20 @@ async function* livePromptEvents(config, prompt, signal, options) {
55742
56765
  abort,
55743
56766
  turnModel
55744
56767
  );
56768
+ if (abort.aborted) {
56769
+ options?.restoreSteering?.(
56770
+ steered.restore.length > 0 ? steered.restore : texts
56771
+ );
56772
+ if (responseParts.length > 0) {
56773
+ await client.addHistory({ role: "user", parts: responseParts });
56774
+ }
56775
+ return;
56776
+ }
55745
56777
  if (steered.restore.length > 0) {
55746
56778
  options?.restoreSteering?.(steered.restore);
55747
56779
  }
56780
+ stashedRecordings = steered.recordings;
56781
+ stashedSteeredTexts = texts;
55748
56782
  for (const ev of steered.events) yield ev;
55749
56783
  responseParts.push(...steered.parts);
55750
56784
  }
@@ -55781,18 +56815,18 @@ var IMAGE_MIME_BY_EXTENSION = {
55781
56815
  function imagePathsToParts(imagePaths) {
55782
56816
  const parts = [];
55783
56817
  const notices = [];
55784
- for (const path6 of imagePaths) {
55785
- const ext = path6.split(".").pop()?.toLowerCase() ?? "";
56818
+ for (const path7 of imagePaths) {
56819
+ const ext = path7.split(".").pop()?.toLowerCase() ?? "";
55786
56820
  const mimeType = IMAGE_MIME_BY_EXTENSION[ext];
55787
56821
  if (!mimeType) {
55788
- notices.push(`Unsupported image type: ${path6}`);
56822
+ notices.push(`Unsupported image type: ${path7}`);
55789
56823
  continue;
55790
56824
  }
55791
56825
  try {
55792
- const data = readFileSync(path6).toString("base64");
56826
+ const data = readFileSync(path7).toString("base64");
55793
56827
  parts.push({ inlineData: { mimeType, data } });
55794
56828
  } catch {
55795
- notices.push(`Could not read image: ${path6}`);
56829
+ notices.push(`Could not read image: ${path7}`);
55796
56830
  }
55797
56831
  }
55798
56832
  return { parts, notices };
@@ -55806,43 +56840,43 @@ function foldBatch(events) {
55806
56840
  __name(foldBatch, "foldBatch");
55807
56841
  function useOpenTuiLiveTurn(options) {
55808
56842
  const { config } = options;
55809
- const [items, setItems] = (0, import_react51.useState)([]);
55810
- const [streaming, setStreaming] = (0, import_react51.useState)(false);
55811
- const [waitingCalls, setWaitingCalls] = (0, import_react51.useState)(
56843
+ const [items, setItems] = (0, import_react54.useState)([]);
56844
+ const [streaming, setStreaming] = (0, import_react54.useState)(false);
56845
+ const [waitingCalls, setWaitingCalls] = (0, import_react54.useState)(
55812
56846
  []
55813
56847
  );
55814
- const queueRef = (0, import_react51.useRef)([]);
55815
- const [queueLength, setQueueLength] = (0, import_react51.useState)(0);
55816
- const abortRef = (0, import_react51.useRef)(null);
55817
- const streamingRef = (0, import_react51.useRef)(false);
55818
- const turnSeqRef = (0, import_react51.useRef)(0);
55819
- const waitingCallsRef = (0, import_react51.useRef)([]);
56848
+ const queueRef = (0, import_react54.useRef)([]);
56849
+ const [queueLength, setQueueLength] = (0, import_react54.useState)(0);
56850
+ const abortRef = (0, import_react54.useRef)(null);
56851
+ const streamingRef = (0, import_react54.useRef)(false);
56852
+ const turnSeqRef = (0, import_react54.useRef)(0);
56853
+ const waitingCallsRef = (0, import_react54.useRef)([]);
55820
56854
  waitingCallsRef.current = waitingCalls;
55821
- const setBusy = (0, import_react51.useCallback)((busy) => {
56855
+ const setBusy = (0, import_react54.useCallback)((busy) => {
55822
56856
  if (streamingRef.current === busy) return;
55823
56857
  streamingRef.current = busy;
55824
56858
  setStreaming(busy);
55825
56859
  }, []);
55826
- const apply = (0, import_react51.useCallback)((ev) => {
56860
+ const apply = (0, import_react54.useCallback)((ev) => {
55827
56861
  setItems((prev) => foldLiveEvent(prev, ev));
55828
56862
  }, []);
55829
- const pushQueue = (0, import_react51.useCallback)((text) => {
56863
+ const pushQueue = (0, import_react54.useCallback)((text) => {
55830
56864
  queueRef.current.push(text);
55831
56865
  setQueueLength(queueRef.current.length);
55832
56866
  }, []);
55833
- const drainQueue = (0, import_react51.useCallback)(() => {
56867
+ const drainQueue = (0, import_react54.useCallback)(() => {
55834
56868
  const drained = queueRef.current;
55835
56869
  queueRef.current = [];
55836
56870
  setQueueLength(0);
55837
56871
  return drained;
55838
56872
  }, []);
55839
- const restoreQueue = (0, import_react51.useCallback)((texts) => {
56873
+ const restoreQueue = (0, import_react54.useCallback)((texts) => {
55840
56874
  const restored = texts.map((text) => text.trim()).filter(Boolean);
55841
56875
  if (restored.length === 0) return;
55842
56876
  queueRef.current = [...restored, ...queueRef.current];
55843
56877
  setQueueLength(queueRef.current.length);
55844
56878
  }, []);
55845
- const runTurn = (0, import_react51.useCallback)(
56879
+ const runTurn = (0, import_react54.useCallback)(
55846
56880
  async (prompt, promptId, turnOptions) => {
55847
56881
  const seq = ++turnSeqRef.current;
55848
56882
  const abort = new AbortController();
@@ -55866,7 +56900,7 @@ function useOpenTuiLiveTurn(options) {
55866
56900
  if (seq !== turnSeqRef.current) return;
55867
56901
  apply(ev);
55868
56902
  }
55869
- if (seq === turnSeqRef.current) {
56903
+ if (seq === turnSeqRef.current && !abort.signal.aborted) {
55870
56904
  void turnOptions?.onComplete?.().catch(() => {
55871
56905
  });
55872
56906
  }
@@ -55899,7 +56933,7 @@ function useOpenTuiLiveTurn(options) {
55899
56933
  },
55900
56934
  [config, apply, drainQueue, restoreQueue, setBusy]
55901
56935
  );
55902
- const submit = (0, import_react51.useCallback)(
56936
+ const submit = (0, import_react54.useCallback)(
55903
56937
  (content, imagePaths, options2) => {
55904
56938
  const text = typeof content === "string" ? content : collectText(normalizeParts(content));
55905
56939
  if (streamingRef.current) {
@@ -55923,10 +56957,10 @@ function useOpenTuiLiveTurn(options) {
55923
56957
  },
55924
56958
  [config, apply, pushQueue, runTurn]
55925
56959
  );
55926
- const interrupt = (0, import_react51.useCallback)(() => {
56960
+ const interrupt = (0, import_react54.useCallback)(() => {
55927
56961
  abortRef.current?.abort();
55928
56962
  }, []);
55929
- const resetTranscript = (0, import_react51.useCallback)(
56963
+ const resetTranscript = (0, import_react54.useCallback)(
55930
56964
  (events) => {
55931
56965
  turnSeqRef.current += 1;
55932
56966
  const abort = abortRef.current;
@@ -55945,14 +56979,14 @@ function useOpenTuiLiveTurn(options) {
55945
56979
  },
55946
56980
  [setBusy]
55947
56981
  );
55948
- const settleWaitingCall = (0, import_react51.useCallback)((callId) => {
56982
+ const settleWaitingCall = (0, import_react54.useCallback)((callId) => {
55949
56983
  setWaitingCalls((prev) => prev.filter((c2) => c2.callId !== callId));
55950
56984
  }, []);
55951
- const popQueue = (0, import_react51.useCallback)(() => {
56985
+ const popQueue = (0, import_react54.useCallback)(() => {
55952
56986
  if (queueRef.current.length === 0) return null;
55953
- return drainQueue().join("\n");
56987
+ return drainQueue().join("\n\n");
55954
56988
  }, [drainQueue]);
55955
- (0, import_react51.useEffect)(() => () => abortRef.current?.abort(), []);
56989
+ (0, import_react54.useEffect)(() => () => abortRef.current?.abort(), []);
55956
56990
  return {
55957
56991
  items,
55958
56992
  streaming,
@@ -56019,47 +57053,6 @@ function exitGuardHint(key) {
56019
57053
  }
56020
57054
  __name(exitGuardHint, "exitGuardHint");
56021
57055
 
56022
- // packages/cli/src/ui/opentui/early-input.ts
56023
- init_esbuild_shims();
56024
- function decodeCapturedInput(buffer) {
56025
- if (buffer.length === 0) return "";
56026
- const text = buffer.toString("utf8");
56027
- return text.replace(/\u001B\[[0-9:;<=>?]*[ -/]*[@-~]/g, "").replace(/\u001BO[A-Za-z]/g, "").replace(/\u001B\[[0-9:;<=>?]*[ -/]*$/, "").replace(/\u001BO$/, "").replace(/[\u0000-\u0008\u000B-\u001F\u007F]/g, "");
56028
- }
56029
- __name(decodeCapturedInput, "decodeCapturedInput");
56030
- function drainCapturedInputAsText() {
56031
- return decodeCapturedInput(stopAndGetCapturedInput());
56032
- }
56033
- __name(drainCapturedInputAsText, "drainCapturedInputAsText");
56034
- function injectCapturedInput(getText, text, opts = {}) {
56035
- if (text.length === 0) return () => {
56036
- };
56037
- const intervalMs = opts.intervalMs ?? 25;
56038
- const maxAttempts = opts.maxAttempts ?? 40;
56039
- const setTimeoutFn = opts.setTimeoutFn ?? ((fn2, ms) => setTimeout(fn2, ms));
56040
- const clearTimeoutFn = opts.clearTimeoutFn ?? ((handle) => clearTimeout(handle));
56041
- let attempts = 0;
56042
- let timer = null;
56043
- let disposed = false;
56044
- const attempt = /* @__PURE__ */ __name(() => {
56045
- if (disposed) return;
56046
- const handle = getText();
56047
- if (handle) {
56048
- handle.setText(text);
56049
- return;
56050
- }
56051
- attempts += 1;
56052
- if (attempts >= maxAttempts) return;
56053
- timer = setTimeoutFn(attempt, intervalMs);
56054
- }, "attempt");
56055
- timer = setTimeoutFn(attempt, intervalMs);
56056
- return () => {
56057
- disposed = true;
56058
- if (timer !== null) clearTimeoutFn(timer);
56059
- };
56060
- }
56061
- __name(injectCapturedInput, "injectCapturedInput");
56062
-
56063
57056
  // packages/cli/src/ui/opentui/start-opentui-ui.tsx
56064
57057
  var debugLogger4 = createDebugLogger("OPEN_TUI_START");
56065
57058
  function OpenTuiEntryApp({
@@ -56068,36 +57061,44 @@ function OpenTuiEntryApp({
56068
57061
  runtime,
56069
57062
  startupWarnings,
56070
57063
  extensionRefreshState,
56071
- capturedText
57064
+ capturedText,
57065
+ initialDialog
56072
57066
  }) {
56073
57067
  const { width, height } = useTerminalDimensions();
56074
57068
  const { stats, startNewSession } = useSessionStats();
56075
57069
  const logger = useLogger(config.storage, config.getSessionId());
56076
57070
  const live = useOpenTuiLiveTurn({ config });
56077
57071
  const { applyEvent, submit, interrupt, resetTranscript, settleWaitingCall } = live;
56078
- const statsRef = (0, import_react52.useRef)(stats);
56079
- (0, import_react52.useEffect)(() => {
57072
+ const { promptSuggestion, abortPromptSuggestion, dismissPromptSuggestion } = useFollowupSuggestionGeneration({
57073
+ config,
57074
+ settings,
57075
+ streaming: live.streaming,
57076
+ items: live.items,
57077
+ waitingCalls: live.waitingCalls
57078
+ });
57079
+ const statsRef = (0, import_react55.useRef)(stats);
57080
+ (0, import_react55.useEffect)(() => {
56080
57081
  statsRef.current = stats;
56081
57082
  }, [stats]);
56082
- const getSessionStats = (0, import_react52.useCallback)(() => statsRef.current, []);
56083
- const composerHandle = (0, import_react52.useRef)(null);
56084
- (0, import_react52.useEffect)(
56085
- () => injectCapturedInput(() => composerHandle.current, capturedText),
57083
+ const getSessionStats = (0, import_react55.useCallback)(() => statsRef.current, []);
57084
+ const composerHandle = (0, import_react55.useRef)(null);
57085
+ (0, import_react55.useEffect)(
57086
+ () => armCapturedInputInjection(() => composerHandle.current, capturedText),
56086
57087
  [capturedText]
56087
57088
  );
56088
- (0, import_react52.useEffect)(() => {
57089
+ (0, import_react55.useEffect)(() => {
56089
57090
  const resumeEvents = resumeEventsFromConfig(config);
56090
57091
  if (resumeEvents) resetTranscript(resumeEvents);
56091
57092
  for (const warning of startupWarnings) {
56092
57093
  applyEvent({ type: "warning", text: warning });
56093
57094
  }
56094
57095
  }, []);
56095
- const [updateNotice, setUpdateNotice] = (0, import_react52.useState)(null);
56096
- const isIdleRef = (0, import_react52.useRef)(true);
56097
- (0, import_react52.useEffect)(() => {
57096
+ const [updateNotice, setUpdateNotice] = (0, import_react55.useState)(null);
57097
+ const isIdleRef = (0, import_react55.useRef)(true);
57098
+ (0, import_react55.useEffect)(() => {
56098
57099
  isIdleRef.current = !live.streaming;
56099
57100
  }, [live.streaming]);
56100
- const addUpdateItem = (0, import_react52.useCallback)(
57101
+ const addUpdateItem = (0, import_react55.useCallback)(
56101
57102
  (item) => {
56102
57103
  if (item.type === "info" /* INFO */) {
56103
57104
  applyEvent({ type: "info", text: item.text });
@@ -56109,29 +57110,22 @@ function OpenTuiEntryApp({
56109
57110
  },
56110
57111
  [applyEvent]
56111
57112
  );
56112
- const setUpdateInfo = (0, import_react52.useCallback)((info) => {
57113
+ const setUpdateInfo = (0, import_react55.useCallback)((info) => {
56113
57114
  setUpdateNotice(info?.message ?? null);
56114
57115
  }, []);
56115
- (0, import_react52.useEffect)(() => {
56116
- const { cleanup } = setUpdateHandler(
56117
- addUpdateItem,
56118
- setUpdateInfo,
56119
- isIdleRef
56120
- );
56121
- return cleanup;
56122
- }, [addUpdateItem, setUpdateInfo]);
56123
- const [exitHint, setExitHint] = (0, import_react52.useState)(null);
56124
- const exitGuard = (0, import_react52.useMemo)(
57116
+ useUpdateNoticeFlush(addUpdateItem, setUpdateInfo, isIdleRef, live.streaming);
57117
+ const [exitHint, setExitHint] = (0, import_react55.useState)(null);
57118
+ const exitGuard = (0, import_react55.useMemo)(
56125
57119
  () => createExitGuard({ onWindowExpired: /* @__PURE__ */ __name(() => setExitHint(null), "onWindowExpired") }),
56126
57120
  []
56127
57121
  );
56128
- (0, import_react52.useEffect)(() => () => exitGuard.dispose(), [exitGuard]);
56129
- const streamingRef = (0, import_react52.useRef)(live.streaming);
56130
- (0, import_react52.useEffect)(() => {
57122
+ (0, import_react55.useEffect)(() => () => exitGuard.dispose(), [exitGuard]);
57123
+ const streamingRef = (0, import_react55.useRef)(live.streaming);
57124
+ (0, import_react55.useEffect)(() => {
56131
57125
  streamingRef.current = live.streaming;
56132
57126
  }, [live.streaming]);
56133
- const waitingCallsRef = (0, import_react52.useRef)(live.waitingCalls);
56134
- (0, import_react52.useEffect)(() => {
57127
+ const waitingCallsRef = (0, import_react55.useRef)(live.waitingCalls);
57128
+ (0, import_react55.useEffect)(() => {
56135
57129
  waitingCallsRef.current = live.waitingCalls;
56136
57130
  }, [live.waitingCalls]);
56137
57131
  useKeyboard((key) => {
@@ -56154,7 +57148,7 @@ function OpenTuiEntryApp({
56154
57148
  setExitHint(exitGuardHint(guardKey));
56155
57149
  }
56156
57150
  });
56157
- const renderMain = (0, import_react52.useCallback)(
57151
+ const renderMain = (0, import_react55.useCallback)(
56158
57152
  () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", flexGrow: 1, children: [
56159
57153
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
56160
57154
  OpenTuiTranscriptView,
@@ -56168,7 +57162,7 @@ function OpenTuiEntryApp({
56168
57162
  ] }),
56169
57163
  [live.items, width, height, exitHint]
56170
57164
  );
56171
- const handleRenderError = (0, import_react52.useCallback)(
57165
+ const handleRenderError = (0, import_react55.useCallback)(
56172
57166
  (error) => {
56173
57167
  debugLogger4.error(
56174
57168
  `[FATAL_RENDER_ERROR] ${error.message}
@@ -56180,15 +57174,15 @@ ${error.stack ?? ""}`
56180
57174
  },
56181
57175
  [config]
56182
57176
  );
56183
- const handleStartNewSession = (0, import_react52.useCallback)(
57177
+ const handleStartNewSession = (0, import_react55.useCallback)(
56184
57178
  (sessionId) => startNewSession(sessionId),
56185
57179
  [startNewSession]
56186
57180
  );
56187
- const handleSubmitPrompt = (0, import_react52.useCallback)(
57181
+ const handleSubmitPrompt = (0, import_react55.useCallback)(
56188
57182
  (content, imagePaths, options) => submit(content, imagePaths, options),
56189
57183
  [submit]
56190
57184
  );
56191
- const handleQuit = (0, import_react52.useCallback)(() => {
57185
+ const handleQuit = (0, import_react55.useCallback)(() => {
56192
57186
  void exitSession(config, 0);
56193
57187
  }, [config]);
56194
57188
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -56200,6 +57194,7 @@ ${error.stack ?? ""}`
56200
57194
  getSessionStats,
56201
57195
  runtime,
56202
57196
  extensionRefreshState,
57197
+ initialDialog,
56203
57198
  renderMain,
56204
57199
  onSubmitPrompt: handleSubmitPrompt,
56205
57200
  onQuit: handleQuit,
@@ -56216,12 +57211,15 @@ ${error.stack ?? ""}`
56216
57211
  waitingToolCalls: live.waitingCalls,
56217
57212
  onToolCallSettled: live.settleWaitingCall,
56218
57213
  onRenderError: handleRenderError,
56219
- composerHandle
57214
+ composerHandle,
57215
+ promptSuggestion,
57216
+ onPromptSuggestionDismiss: dismissPromptSuggestion,
57217
+ onPromptSuggestionAbort: abortPromptSuggestion
56220
57218
  }
56221
57219
  );
56222
57220
  }
56223
57221
  __name(OpenTuiEntryApp, "OpenTuiEntryApp");
56224
- async function startOpenTuiUI(config, settings, startupWarnings, workspaceRoot = process.cwd(), _initializationResult, options = {}) {
57222
+ async function startOpenTuiUI(config, settings, startupWarnings, workspaceRoot = process.cwd(), initializationResult, options = {}) {
56225
57223
  let renderer;
56226
57224
  try {
56227
57225
  renderer = await createCliRenderer({ exitOnCtrlC: false, useMouse: true });
@@ -56235,6 +57233,7 @@ async function startOpenTuiUI(config, settings, startupWarnings, workspaceRoot =
56235
57233
  const root = createRoot(renderer);
56236
57234
  let runtime = null;
56237
57235
  try {
57236
+ void ensureConfigInitialized(config);
56238
57237
  const version = await getCliVersion();
56239
57238
  if (!settings.merged.ui?.hideWindowTitle && settings.merged.ui?.showStatusInTitle !== false) {
56240
57239
  writeTerminalTitle(
@@ -56246,11 +57245,15 @@ async function startOpenTuiUI(config, settings, startupWarnings, workspaceRoot =
56246
57245
  await runtime.writeRuntimeSidecar();
56247
57246
  runtime.startPressureMonitor();
56248
57247
  const capturedText = drainCapturedInputAsText();
57248
+ const initialDialog = initializationResult.authError || config.getAuthType() === void 0 ? {
57249
+ dialog: "auth",
57250
+ initialError: initializationResult.authError ?? void 0
57251
+ } : null;
56249
57252
  root.render(
56250
57253
  // children must sit in the props object: the provider declares it as a
56251
57254
  // required prop, which createElement's rest-children overloads can't fill.
56252
57255
  // eslint-disable-next-line react/no-children-prop
56253
- (0, import_react52.createElement)(SessionStatsProvider, {
57256
+ (0, import_react55.createElement)(SessionStatsProvider, {
56254
57257
  sessionId: config.getSessionId(),
56255
57258
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
56256
57259
  OpenTuiEntryApp,
@@ -56260,7 +57263,8 @@ async function startOpenTuiUI(config, settings, startupWarnings, workspaceRoot =
56260
57263
  runtime,
56261
57264
  startupWarnings,
56262
57265
  extensionRefreshState: options.extensionRefreshState,
56263
- capturedText
57266
+ capturedText,
57267
+ initialDialog
56264
57268
  }
56265
57269
  )
56266
57270
  })