@qwen-code/qwen-code 0.23.1-preview.2 → 0.23.2-preview.0

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 (297) 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 +50 -0
  6. package/bundled/qc-helper/docs/conversations-recovery.md +102 -0
  7. package/bundled/qc-helper/docs/features/channels/overview.md +1 -1
  8. package/bundled/qc-helper/docs/features/computer-use.md +9 -7
  9. package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
  10. package/bundled/qc-helper/docs/features/goals.md +15 -3
  11. package/bundled/qc-helper/docs/qwen-serve.md +19 -1
  12. package/chunks/{MaxSizedBox-IYIQ43IZ.js → MaxSizedBox-ZZJT3PJF.js} +20 -20
  13. package/chunks/{StandaloneSessionPicker-AWB2OHX6.js → StandaloneSessionPicker-DIOSZTMX.js} +38 -38
  14. package/chunks/{acp-startup-profiler-BAL4LJTN.js → acp-startup-profiler-KEU6VAYR.js} +2 -2
  15. package/chunks/{acpAgent-ZC57OLS4.js → acpAgent-62JUP5A7.js} +118 -91
  16. package/chunks/{agent-GEBPAEJS.js → agent-NLPEQQDZ.js} +13 -13
  17. package/chunks/{agent-headless-63ZEYAJK.js → agent-headless-Y2GR5F2Q.js} +13 -13
  18. package/chunks/{anthropicContentGenerator-6XDHXIII.js → anthropicContentGenerator-I7LQZH26.js} +30 -7
  19. package/chunks/{askUserQuestion-3KAYLLMM.js → askUserQuestion-I5W5S3D6.js} +1 -1
  20. package/chunks/{bridge-MHWO5I5T.js → bridge-Q66BD62H.js} +23 -23
  21. package/chunks/{channel-management-service-NFRZXQFO.js → channel-management-service-TRTLQTSV.js} +4 -4
  22. package/chunks/{channel-settings-store-T7PMIHKC.js → channel-settings-store-R5STFWUW.js} +31 -31
  23. package/chunks/{channel-worker-group-O2BWK5F7.js → channel-worker-group-PIYPVCTF.js} +6 -6
  24. package/chunks/{channel-worker-manager-4WP7VJOD.js → channel-worker-manager-FQHEDTD2.js} +6 -6
  25. package/chunks/{channel-worker-supervisor-CCUXD6J5.js → channel-worker-supervisor-XJPZZ3VK.js} +3 -3
  26. package/chunks/{chunk-ZJ2LM2SI.js → chunk-2OR32P5M.js} +104 -33
  27. package/chunks/chunk-2Z3T52OC.js +82 -0
  28. package/chunks/{chunk-5FYGZ7E3.js → chunk-33MLFMCL.js} +2 -2
  29. package/chunks/{chunk-RH344FKI.js → chunk-3BTHHXXE.js} +1 -1
  30. package/chunks/{chunk-OFB36ZBA.js → chunk-3LPJ776W.js} +1 -1
  31. package/chunks/{chunk-TSLRORQR.js → chunk-43CI6YWJ.js} +1467 -1323
  32. package/chunks/{chunk-LTCI6ZOJ.js → chunk-45ROPFQY.js} +1 -1
  33. package/chunks/{chunk-W4LL5RZO.js → chunk-4ALNJDHL.js} +52 -13
  34. package/chunks/{chunk-RRCNEW2A.js → chunk-4BLTSTF6.js} +58 -4
  35. package/chunks/{chunk-3RMVM33U.js → chunk-4JKLPTV6.js} +5 -5
  36. package/chunks/{chunk-ZRVFHLLK.js → chunk-5DQ4YTIZ.js} +1 -1
  37. package/chunks/{chunk-AWDF462I.js → chunk-5GD7LYOH.js} +2 -2
  38. package/chunks/{chunk-HZS3JRQW.js → chunk-5VZFJTL2.js} +40 -2
  39. package/chunks/{chunk-537SQ2AI.js → chunk-5WC2ECUK.js} +104 -16
  40. package/chunks/{chunk-ZT3XUGSU.js → chunk-63ACHB2H.js} +86 -9
  41. package/chunks/{chunk-3K65MUKD.js → chunk-65I7S4Z3.js} +2 -1
  42. package/chunks/{chunk-REDVV5NC.js → chunk-6GRDHIVI.js} +7 -7
  43. package/chunks/{chunk-2LD5U7Q3.js → chunk-6YEOCHSE.js} +29 -1
  44. package/chunks/{chunk-C4NXRR7T.js → chunk-743XE7N7.js} +2 -2
  45. package/chunks/{chunk-I7UNCY24.js → chunk-7GZCCHJL.js} +3 -3
  46. package/chunks/{chunk-XX4MBBFW.js → chunk-7L35FKPF.js} +3 -3
  47. package/chunks/{chunk-GEV66YGE.js → chunk-7RXOEUFF.js} +1 -1
  48. package/chunks/{chunk-TXAEXF2B.js → chunk-BL6B2QS2.js} +21 -8
  49. package/chunks/{chunk-KAZWXVI3.js → chunk-CABDNUJ4.js} +2 -2
  50. package/chunks/{chunk-R7TKFIQO.js → chunk-CALNF3Z3.js} +1 -1
  51. package/chunks/{chunk-22QOQKG4.js → chunk-CG2PDIGD.js} +1 -1
  52. package/chunks/{chunk-MFCWL4LI.js → chunk-CPJRFFPH.js} +451 -396
  53. package/chunks/{chunk-LD53HMPV.js → chunk-CRZBDVP2.js} +1 -0
  54. package/chunks/{chunk-RSU3I6UL.js → chunk-DCPRCDSR.js} +1 -1
  55. package/chunks/{chunk-PLUAIHZO.js → chunk-DTB5BXRG.js} +6 -6
  56. package/chunks/{chunk-FWH4736Q.js → chunk-EA4NFWVG.js} +3 -3
  57. package/chunks/{chunk-AX23QSX3.js → chunk-EHTKOO6W.js} +4 -4
  58. package/chunks/{chunk-37SOBIA3.js → chunk-ERXNTINK.js} +1 -1
  59. package/chunks/{chunk-EGRFCIXD.js → chunk-EUXF6URV.js} +79 -18
  60. package/chunks/{chunk-F47DITLZ.js → chunk-FAWTMDX7.js} +14 -0
  61. package/chunks/{chunk-5JLQWQK6.js → chunk-FV4DM2M4.js} +2 -2
  62. package/chunks/{chunk-C7M445SS.js → chunk-G5QLLD53.js} +1 -1
  63. package/chunks/{chunk-5V4B3EWA.js → chunk-GM44O6F7.js} +1 -1
  64. package/chunks/{chunk-Z6DDPSGJ.js → chunk-GNY7B3CA.js} +1 -1
  65. package/chunks/{chunk-7PMKXGRP.js → chunk-GXIHBIHC.js} +66 -9
  66. package/chunks/{chunk-ERMAXPXA.js → chunk-HIXUUCGY.js} +187 -12
  67. package/chunks/{chunk-EJNYBDYC.js → chunk-HNLMYDQE.js} +1 -1
  68. package/chunks/{chunk-RCUWMVN3.js → chunk-HZ2HUXX7.js} +1 -1
  69. package/chunks/{chunk-SHX2HIE7.js → chunk-ISPBBKJN.js} +1 -1
  70. package/chunks/{chunk-QQGAR64U.js → chunk-IUJLW6ZI.js} +4 -4
  71. package/chunks/{chunk-IMWCUWQT.js → chunk-J3TJH52D.js} +1 -1
  72. package/chunks/{chunk-AIMZIXZM.js → chunk-J4ECGDA3.js} +5 -7
  73. package/chunks/{chunk-HPE4LEWX.js → chunk-JDPBJIKI.js} +1 -1
  74. package/chunks/{chunk-Y3C5COGI.js → chunk-L6ZME3W7.js} +1 -1
  75. package/chunks/{chunk-EPZWBYQI.js → chunk-LBKYQ33T.js} +8 -6
  76. package/chunks/{chunk-KTLT7VCX.js → chunk-LN3WBOKU.js} +2 -2
  77. package/chunks/{chunk-FXYNIZPW.js → chunk-LUVXLLMS.js} +51 -10
  78. package/chunks/{chunk-RQNAO42A.js → chunk-M6YLOETP.js} +1 -1
  79. package/chunks/{chunk-6KYWU726.js → chunk-M73KHGNR.js} +13 -66
  80. package/chunks/{chunk-ADJD4LZF.js → chunk-MA5OUNN6.js} +1 -1
  81. package/chunks/{chunk-SI6Q52UI.js → chunk-MMMA36MN.js} +3 -3
  82. package/chunks/{chunk-QW7BUOSI.js → chunk-MWEF5MUK.js} +20 -3
  83. package/chunks/{chunk-JOV46WGX.js → chunk-NB3NDQQK.js} +1 -1
  84. package/chunks/chunk-NOO4QFXM.js +171 -0
  85. package/chunks/{chunk-UTVIIA7N.js → chunk-NVS4Z6GT.js} +1 -1
  86. package/chunks/{chunk-VMFPZXRT.js → chunk-ODBNTMZW.js} +43 -31
  87. package/chunks/{chunk-UKADFFL2.js → chunk-OFVAS4AR.js} +1 -1
  88. package/chunks/{chunk-WQBR7LN5.js → chunk-OIPUQE3S.js} +1 -1
  89. package/chunks/{chunk-2C3XDBGL.js → chunk-ORREXWOM.js} +4 -4
  90. package/chunks/{chunk-RD3VPM4E.js → chunk-PQWM4SX2.js} +2 -2
  91. package/chunks/{chunk-Z6KFLEG7.js → chunk-PSPAM24S.js} +1 -0
  92. package/chunks/{chunk-RUMSY4ES.js → chunk-Q2F43WTJ.js} +8 -7
  93. package/chunks/{chunk-VYCJITND.js → chunk-QJAFSFYA.js} +1 -1
  94. package/chunks/{chunk-L36LLVA5.js → chunk-QLM7D7W3.js} +3 -3
  95. package/chunks/{chunk-NUQFUXOG.js → chunk-QTNCGZHQ.js} +2 -0
  96. package/chunks/{chunk-XNC2TCUO.js → chunk-QXXBW2G4.js} +4 -4
  97. package/chunks/{chunk-TDHVOZ65.js → chunk-R2266LQ5.js} +2 -2
  98. package/chunks/{chunk-QJVZLILI.js → chunk-R7OO56VZ.js} +1 -1
  99. package/chunks/{chunk-LYHYXJJ3.js → chunk-RDV4NLI3.js} +3 -3
  100. package/chunks/{chunk-733KQL63.js → chunk-RN6V5HKE.js} +3 -3
  101. package/chunks/{chunk-WLZRMF3C.js → chunk-RX3FYFCN.js} +353 -11
  102. package/chunks/{chunk-NXWYCSPL.js → chunk-SOA4HKRJ.js} +1 -1
  103. package/chunks/{chunk-ZNI3V2XA.js → chunk-TK4XHPKW.js} +2 -2
  104. package/chunks/{chunk-RGAQDQ3Z.js → chunk-UHUT4IDM.js} +18 -9
  105. package/chunks/{chunk-T7TP5UQL.js → chunk-ULY4ISY2.js} +4 -4
  106. package/chunks/{chunk-PMGWY6ZP.js → chunk-UULHYZ4W.js} +13 -10
  107. package/chunks/{chunk-BNWIX6BM.js → chunk-UXDVUFKU.js} +3 -3
  108. package/chunks/{chunk-HY3DXYZK.js → chunk-UYDQYDW2.js} +1 -1
  109. package/chunks/{chunk-YLFICBYK.js → chunk-VEQBVJYH.js} +3 -3
  110. package/chunks/{chunk-3K456UJF.js → chunk-VF6D6EGV.js} +12 -4
  111. package/chunks/{chunk-KP5QK3FB.js → chunk-VH764G6B.js} +397 -54
  112. package/chunks/{chunk-IGOIYZBG.js → chunk-VHPG7BH6.js} +2 -2
  113. package/chunks/{chunk-I67KJGM6.js → chunk-W3ONSAYO.js} +3 -3
  114. package/chunks/{chunk-SHK2SIR5.js → chunk-W673V2H3.js} +4 -4
  115. package/chunks/{chunk-C55CR5I4.js → chunk-W7PXLIZJ.js} +6 -6
  116. package/chunks/{chunk-OHOO527W.js → chunk-WG7BL3FY.js} +52 -2
  117. package/chunks/{chunk-B5FF3LRF.js → chunk-WIRYFL2L.js} +22 -15
  118. package/chunks/{chunk-P5Z7VD23.js → chunk-WZ4YULVF.js} +106 -39
  119. package/chunks/{chunk-WFXD5OZH.js → chunk-WZS3X663.js} +1 -1
  120. package/chunks/{chunk-HWZOOSEB.js → chunk-XAXTQURR.js} +3 -3
  121. package/chunks/{chunk-ANVC5CSK.js → chunk-XBLG564H.js} +10 -10
  122. package/chunks/{chunk-VU7O7CGQ.js → chunk-XDNFODER.js} +1 -1
  123. package/chunks/{chunk-SD7Y2PMC.js → chunk-XI7RST4D.js} +2 -2
  124. package/chunks/{chunk-65GHQ4FX.js → chunk-XVTCSVBK.js} +514 -47
  125. package/chunks/{chunk-4OCYWXKF.js → chunk-Y6ZWXM44.js} +3 -3
  126. package/chunks/{chunk-7IKXTGZT.js → chunk-YI2YCNSP.js} +1 -1
  127. package/chunks/{chunk-E4VX6LXB.js → chunk-YZTGGCEE.js} +10 -2
  128. package/chunks/{chunk-75UQFGFE.js → chunk-ZIPYCXQP.js} +1 -1
  129. package/chunks/{chunk-AUJOWIT5.js → chunk-ZUNWKOAP.js} +3 -3
  130. package/chunks/{config-utils-F4CFJ4MW.js → config-utils-37FHWPTP.js} +24 -24
  131. package/chunks/{contextCommand-OIIGGOMU.js → contextCommand-R4JUBV5N.js} +22 -22
  132. package/chunks/{core-runtime-JEHLOGMB.js → core-runtime-6U4OXU5C.js} +20 -20
  133. package/chunks/{create-sub-session-MVFBE5RA.js → create-sub-session-LLUYAGZN.js} +21 -21
  134. package/chunks/{daemon-LCUELM6E.js → daemon-UI6SQSBV.js} +1 -1
  135. package/chunks/{daemon-git-worktree-guard-5FTKLJOU.js → daemon-git-worktree-guard-O2UTNFJC.js} +20 -20
  136. package/chunks/{daemon-status-provider-P6A5MPMW.js → daemon-status-provider-7GMAKSTX.js} +27 -27
  137. package/chunks/{daemon-trust-policy-ZJ3NFYUO.js → daemon-trust-policy-VNP76VMO.js} +27 -27
  138. package/chunks/{daemon-trust-policy-monitor-6SDLEW7S.js → daemon-trust-policy-monitor-TD5O3BZA.js} +27 -27
  139. package/chunks/{deferred-core-runtime-DWOXIU5S.js → deferred-core-runtime-NJM63YJS.js} +20 -20
  140. package/chunks/{discovery-TUM3ZQ6U.js → discovery-XP4RMDUM.js} +4 -2
  141. package/chunks/{dist-NXW4DUUX.js → dist-24TCWK5H.js} +1 -1
  142. package/chunks/{dist-I74QLLQS.js → dist-5I4HLUTO.js} +1 -1
  143. package/chunks/{dist-XINEKB5A.js → dist-FDISN4AK.js} +1 -1
  144. package/chunks/{dist-VCAS67N5.js → dist-M4CBX53H.js} +1 -1
  145. package/chunks/{dist-AI25RVRA.js → dist-NQ2636VT.js} +1 -1
  146. package/chunks/{dist-3H3WODVS.js → dist-OR2ZQTXZ.js} +1 -1
  147. package/chunks/{dist-P6YWBITG.js → dist-STAGIFNB.js} +430 -51
  148. package/chunks/{dist-YNQU4CKC.js → dist-WZTUKIDR.js} +2 -2
  149. package/chunks/{dist-T4PRA5EZ.js → dist-XJ25G6OH.js} +1 -1
  150. package/chunks/{edit-WPVXLL3T.js → edit-GL7OA6RV.js} +13 -13
  151. package/chunks/{enter-worktree-5A6VW6BN.js → enter-worktree-YFTKHXHZ.js} +2 -2
  152. package/chunks/{enterPlanMode-JSODW7E2.js → enterPlanMode-VC4BCSZE.js} +13 -13
  153. package/chunks/{environment-5LLJ3I3W.js → environment-BI6IBAZJ.js} +23 -23
  154. package/chunks/{errors-IQT3YZEP.js → errors-D6G2ZM2R.js} +22 -22
  155. package/chunks/{exit-worktree-QV7E7KP6.js → exit-worktree-NF2XEMES.js} +3 -3
  156. package/chunks/{exitPlanMode-DDVFYNW4.js → exitPlanMode-DX446CA6.js} +13 -13
  157. package/chunks/{fast-path-PAUQQEVU.js → fast-path-MAYDLJIP.js} +3 -3
  158. package/chunks/{fast-path-settings-ISEJPRYE.js → fast-path-settings-SATXY3PD.js} +3 -3
  159. package/chunks/{glob-SQ7CTZ7F.js → glob-TVKRFY36.js} +13 -13
  160. package/chunks/{goal-tools-UWZRCLQB.js → goal-tools-CA6YANRN.js} +13 -13
  161. package/chunks/{handleAutoUpdate-RUPZZTSG.js → handleAutoUpdate-AW4ZAHON.js} +23 -23
  162. package/chunks/{i18n-SF5MPWEB.js → i18n-IH5CRAY7.js} +23 -21
  163. package/chunks/{image-gen-Q3RUTVKR.js → image-gen-XP4NNIYG.js} +4 -4
  164. package/chunks/{initializer-CK4WPYZG.js → initializer-UBR37ZNM.js} +27 -27
  165. package/chunks/{installationInfo-IRPQEYRF.js → installationInfo-Y52756EC.js} +20 -20
  166. package/chunks/{list-E3PS3EBJ.js → list-7V5JDZPO.js} +30 -30
  167. package/chunks/{llm-JQKBOYAF.js → llm-QDB6JVF5.js} +62 -62
  168. package/chunks/{llm-content-generator-2QWGBW42.js → llm-content-generator-EO6MZCEO.js} +23 -8
  169. package/chunks/{loadedSettingsAdapter-DGXGVYZS.js → loadedSettingsAdapter-I3YQKMC4.js} +27 -27
  170. package/chunks/{loggingContentGenerator-ZYURLJKK.js → loggingContentGenerator-MNXYUGDG.js} +14 -14
  171. package/chunks/{managed-npm-update-HTHR63EA.js → managed-npm-update-EA3EXPTO.js} +20 -20
  172. package/chunks/{mcp-I7G2AEWS.js → mcp-QTAJ544Y.js} +27 -27
  173. package/chunks/{monitor-4R76BCRZ.js → monitor-6FQKQOTP.js} +13 -13
  174. package/chunks/{nonInteractiveCli-24OQ3VP2.js → nonInteractiveCli-MRCTZL5X.js} +64 -61
  175. package/chunks/{notebook-edit-PPSH7FEX.js → notebook-edit-BQQCKI7K.js} +13 -13
  176. package/chunks/{openaiContentGenerator-K7V5EO7F.js → openaiContentGenerator-TTSKXNVH.js} +8 -8
  177. package/chunks/{pidfile-TGIUY2GG.js → pidfile-KPIS6RIT.js} +20 -20
  178. package/chunks/{processUtils-3USXUQWX.js → processUtils-ZCASPKK4.js} +2 -2
  179. package/chunks/{prompt-terminal-ledger-XHVZRXJI.js → prompt-terminal-ledger-D6HM6TV7.js} +21 -21
  180. package/chunks/{qwenContentGenerator-MPBOQB64.js → qwenContentGenerator-GGZEFLBD.js} +16 -16
  181. package/chunks/{qwenOAuth2-BS5D2LYV.js → qwenOAuth2-KX6LVYQ3.js} +4 -4
  182. package/chunks/{read-file-R256LDWQ.js → read-file-VE5GDFLP.js} +2 -2
  183. package/chunks/{resumeHistoryUtils-S43LTFHD.js → resumeHistoryUtils-HSSGMYDC.js} +23 -23
  184. package/chunks/{ripGrep-L7HPZ75Y.js → ripGrep-SEJE7AA6.js} +3 -3
  185. package/chunks/{run-qwen-serve-CTFL5R6U.js → run-qwen-serve-OJYVH7N6.js} +58 -60
  186. package/chunks/{runtime-FS5TL6P7.js → runtime-KGMQQFJD.js} +32 -32
  187. package/chunks/{scheduled-tasks-QXPV3Q35.js → scheduled-tasks-7H5HWHYD.js} +25 -25
  188. package/chunks/{scheduler-EXU5HMVK.js → scheduler-BE42AKDG.js} +22 -22
  189. package/chunks/{send-message-GQKXGMPI.js → send-message-AWKUDJBH.js} +1 -1
  190. package/chunks/{serve-ITJC7WNN.js → serve-KZVKYMSL.js} +27 -27
  191. package/chunks/{server-6JQY3PTU.js → server-PJRALPJQ.js} +1296 -822
  192. package/chunks/{session-PJDEKXD4.js → session-IHITXU2S.js} +63 -62
  193. package/chunks/{session-attachments-root-L37ORSST.js → session-attachments-root-GQ2TUI3Y.js} +20 -20
  194. package/chunks/{session-pr-refresh-WIFD52YL.js → session-pr-refresh-H43LULTE.js} +24 -24
  195. package/chunks/{settings-LO6J5SAZ.js → settings-RKEQQDFC.js} +26 -26
  196. package/chunks/{shell-ANAFVYGR.js → shell-6PJ444U5.js} +13 -13
  197. package/chunks/{skill-SHJWKSPH.js → skill-Q3UP7B5V.js} +2 -2
  198. package/chunks/{skill-settings-GX3XHZ5Q.js → skill-settings-LZR5YRRW.js} +26 -26
  199. package/chunks/{spawnChannel-WE42VBKM.js → spawnChannel-WM3DT2BF.js} +20 -20
  200. package/chunks/{standalone-update-CWDIKJRP.js → standalone-update-E5474IBI.js} +22 -22
  201. package/chunks/{start-opentui-ui-BBHGFOTF.js → start-opentui-ui-WLWZNQ2I.js} +1991 -986
  202. package/chunks/{startInteractiveUI-FQX7LUYP.js → startInteractiveUI-FBQSGWGO.js} +1119 -1478
  203. package/chunks/{team-create-WKTPCH6D.js → team-create-VIGUFUT4.js} +13 -13
  204. package/chunks/{team-plan-approval-Y23DL7WR.js → team-plan-approval-HQVZA3MD.js} +13 -13
  205. package/chunks/{terminal-image-renderer-B646HBDW.js → terminal-image-renderer-LUKNCOVM.js} +20 -20
  206. package/chunks/{theme-manager-BNWESY26.js → theme-manager-LOENKYLY.js} +20 -20
  207. package/chunks/{tool-search-PVQ5O5Y2.js → tool-search-ZIFAQCE2.js} +2 -2
  208. package/chunks/{total-session-admission-P5Z43KNW.js → total-session-admission-FUUJH3QH.js} +24 -24
  209. package/chunks/{trustedFolders-FH2LT2MZ.js → trustedFolders-C76KYROP.js} +21 -21
  210. package/chunks/{update-relaunch-WOWTKJSN.js → update-relaunch-4G2SRXKX.js} +5 -5
  211. package/chunks/{updateCheck-3MYFMM35.js → updateCheck-EIZIO7HI.js} +22 -22
  212. package/chunks/{useAutoAcceptIndicator-Q7ZRRRKO.js → useAutoAcceptIndicator-EAA6KSY4.js} +29 -29
  213. package/chunks/{validateNonInterActiveAuth-MYEWJX3G.js → validateNonInterActiveAuth-BRX22QCN.js} +59 -58
  214. package/chunks/{version-RO2FPO76.js → version-E56RU7PR.js} +1 -1
  215. package/chunks/{web-fetch-QAKY2LUA.js → web-fetch-AAUCD7RM.js} +5 -5
  216. package/chunks/{web-search-XA5Z4ZCD.js → web-search-HFUQF44Q.js} +18 -7
  217. package/chunks/{workflow-QFIOCMDM.js → workflow-3MABM53N.js} +15 -15
  218. package/chunks/{workspace-providers-status-B2UD7RAG.js → workspace-providers-status-2FRLBZ5I.js} +29 -29
  219. package/chunks/{workspace-registration-store-VZLRTI3Q.js → workspace-registration-store-YL7HLYYI.js} +1 -1
  220. package/chunks/{workspace-registry-GYOGG6TM.js → workspace-registry-BNRP2ELW.js} +24 -24
  221. package/chunks/{workspace-runtime-coordinator-7KRXGQ4V.js → workspace-runtime-coordinator-WKGF7VHS.js} +24 -24
  222. package/chunks/{workspace-service-DJEYGJE4.js → workspace-service-4MYO72MM.js} +31 -31
  223. package/chunks/{workspace-skills-status-MOKNESUC.js → workspace-skills-status-SU66TJLZ.js} +27 -27
  224. package/chunks/{workspace-trust-reconciler-AXOSUTQW.js → workspace-trust-reconciler-D5QT7WQB.js} +31 -31
  225. package/chunks/{write-file-QOYVHAKK.js → write-file-NVPQE2AZ.js} +14 -14
  226. package/chunks/{zoom-image-UCCLGFNC.js → zoom-image-RJHC66WG.js} +2 -2
  227. package/cli.js +13 -13
  228. package/export-transcript-document.js +126 -122
  229. package/package.json +3 -3
  230. package/web-shell/assets/{abnfDiagram-VCTEODGH-CTstZpXw.js → abnfDiagram-VCTEODGH-DHc6plZn.js} +1 -1
  231. package/web-shell/assets/{arc-DKW0mbPo.js → arc-BQ9m8TDV.js} +1 -1
  232. package/web-shell/assets/{architectureDiagram-5GKGNRK7-DkMpJ42t.js → architectureDiagram-5GKGNRK7-D5ap3oVB.js} +1 -1
  233. package/web-shell/assets/{blockDiagram-NRAW4CY4-7Cp1_4i3.js → blockDiagram-NRAW4CY4-BIbnyNph.js} +1 -1
  234. package/web-shell/assets/{c4Diagram-UCG6FXSJ-BfaoSlBK.js → c4Diagram-UCG6FXSJ-BRsdx_iG.js} +1 -1
  235. package/web-shell/assets/channel-uMMdTrYk.js +1 -0
  236. package/web-shell/assets/{chunk-2Q5K7J3B-_n1qzAio.js → chunk-2Q5K7J3B-3lf1fNlx.js} +1 -1
  237. package/web-shell/assets/{chunk-5VM5RSS4-0cira5ZV.js → chunk-5VM5RSS4-DP8VNRc4.js} +1 -1
  238. package/web-shell/assets/{chunk-F27PBJKO-DseRXSHC.js → chunk-F27PBJKO-DrohDmZ6.js} +1 -1
  239. package/web-shell/assets/{chunk-G27WJ6UU-BehQWin0.js → chunk-G27WJ6UU-UZ2QhSx6.js} +1 -1
  240. package/web-shell/assets/{chunk-JWPE2WC7-B5ftg1Bb.js → chunk-JWPE2WC7-BIMHVcZK.js} +1 -1
  241. package/web-shell/assets/{chunk-LCL6LL3I-D7rnbVdk.js → chunk-LCL6LL3I-izRxdSDd.js} +1 -1
  242. package/web-shell/assets/{chunk-POPQ4Y6H-2Bp-Orju.js → chunk-POPQ4Y6H-CXADD4PP.js} +1 -1
  243. package/web-shell/assets/{chunk-SVP7TREG-CD2goGva.js → chunk-SVP7TREG-B96d8Y_1.js} +1 -1
  244. package/web-shell/assets/{chunk-XXDRQBXY-DzQt-Rji.js → chunk-XXDRQBXY-CF2sVQpv.js} +1 -1
  245. package/web-shell/assets/classDiagram-DTDB5LWJ-DcY-26Ig.js +1 -0
  246. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DcY-26Ig.js +1 -0
  247. package/web-shell/assets/{cose-bilkent-JH36ORCC-C-BZXSUn.js → cose-bilkent-JH36ORCC-CT6tXVAS.js} +1 -1
  248. package/web-shell/assets/csv-CX7rUNeC.svg +1 -0
  249. package/web-shell/assets/{cynefin-OW5HDTMX-BTcvowe1.js → cynefin-OW5HDTMX-X1NS4vtV.js} +1 -1
  250. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BoUE6K81.js → cynefinDiagram-5FMLGOSQ-DNsKNOT4.js} +1 -1
  251. package/web-shell/assets/{dagre-3AP2YEHR-BHxy9xeB.js → dagre-3AP2YEHR-9-AHKqsb.js} +1 -1
  252. package/web-shell/assets/{diagram-S7CK7UJ4-DMiJIvDT.js → diagram-S7CK7UJ4-Bjgms7j6.js} +1 -1
  253. package/web-shell/assets/{diagram-UQ7AKVKN-DXV09Aes.js → diagram-UQ7AKVKN-h6bCprbE.js} +1 -1
  254. package/web-shell/assets/{diagram-VSXAHHWV-CocpRomV.js → diagram-VSXAHHWV-4SbQXVLt.js} +1 -1
  255. package/web-shell/assets/{diagram-VX7I27RA-DL7nqtb4.js → diagram-VX7I27RA-B5gPCzzB.js} +1 -1
  256. package/web-shell/assets/{diagram-Z3DM3KII-CPZ2Jux_.js → diagram-Z3DM3KII-DFJXIA3A.js} +1 -1
  257. package/web-shell/assets/{ebnfDiagram-PWID7BFC-BX-eVNsX.js → ebnfDiagram-PWID7BFC-FwyaU7VY.js} +1 -1
  258. package/web-shell/assets/{erDiagram-SSCWMZ5O-CPy_Ir6y.js → erDiagram-SSCWMZ5O-8vJQh2te.js} +1 -1
  259. package/web-shell/assets/{flowDiagram-A5DVABFB-eknAOte9.js → flowDiagram-A5DVABFB-BzA_1gMN.js} +1 -1
  260. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-crAxw_t7.js → ganttDiagram-EL5Y4UJY-Co-ABbVX.js} +1 -1
  261. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-M29pa3Tc.js → gitGraphDiagram-WWUBYQGX-DW_FcyrX.js} +1 -1
  262. package/web-shell/assets/{index-C9R-iojE.js → index-BbMXfhNG.js} +1 -1
  263. package/web-shell/assets/{index-B4TLaxWs.js → index-Bu-rZoJ-.js} +462 -454
  264. package/web-shell/assets/index-CsPwZ1ut.css +36 -0
  265. package/web-shell/assets/{infoDiagram-RXCK75RN-XqspXdOU.js → infoDiagram-RXCK75RN-BEgfhUFN.js} +1 -1
  266. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-C5KFS-7j.js → ishikawaDiagram-5VMMS53U-DCsMxQmc.js} +1 -1
  267. package/web-shell/assets/{journeyDiagram-EYS64GPL-Cc57LVRo.js → journeyDiagram-EYS64GPL-DyIEYoHz.js} +1 -1
  268. package/web-shell/assets/{kanban-definition-3QL26DDD-C81OG-AI.js → kanban-definition-3QL26DDD-CkxjqCNr.js} +1 -1
  269. package/web-shell/assets/{layout-CFVu37BB.js → layout-BEWc0Al9.js} +1 -1
  270. package/web-shell/assets/{linear-ChBxdtWf.js → linear-CNuNxirL.js} +1 -1
  271. package/web-shell/assets/{mermaid.core-CMLfue0w.js → mermaid.core-DZBre674.js} +6 -6
  272. package/web-shell/assets/{mindmap-definition-FBJOCRG2-DFsvJThp.js → mindmap-definition-FBJOCRG2-CpafFz_F.js} +1 -1
  273. package/web-shell/assets/{pegDiagram-XKGWAZYB-BzpRzM4F.js → pegDiagram-XKGWAZYB-DfZqk_dq.js} +1 -1
  274. package/web-shell/assets/{pieDiagram-E7YTZNPT-Cv0Kankl.js → pieDiagram-E7YTZNPT-S0UWXlgC.js} +1 -1
  275. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-Bh2BJ3Ay.js → quadrantDiagram-AXDQQJYC-dd37_Ohj.js} +1 -1
  276. package/web-shell/assets/{railroadDiagram-O6MQD6OU-y8rNDdDS.js → railroadDiagram-O6MQD6OU-CH8NJZ7u.js} +1 -1
  277. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-C0m2DKJ_.js → requirementDiagram-EFPCY7ZU-CFdqWYih.js} +1 -1
  278. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-BzdGnSF4.js → sankeyDiagram-P5KCCOFB-CsddcEGD.js} +1 -1
  279. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DPzAVmzz.js → sequenceDiagram-WJ2MYXX4-BZ270mGw.js} +1 -1
  280. package/web-shell/assets/{sizeCapture-X5ZJPWSS-LcHG28Zh.js → sizeCapture-X5ZJPWSS-CGaS4DBV.js} +1 -1
  281. package/web-shell/assets/{stateDiagram-HBIQ2CUA-C1Bzy3IT.js → stateDiagram-HBIQ2CUA-COpIzMu6.js} +1 -1
  282. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-D6qEVAji.js +1 -0
  283. package/web-shell/assets/{swimlanes-XN3QIQJK-Bftk8V64.js → swimlanes-XN3QIQJK-CMF889m3.js} +1 -1
  284. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-mem5Jj4m.js +8 -0
  285. package/web-shell/assets/{timeline-definition-24CTP7MA-BfXHcN1A.js → timeline-definition-24CTP7MA-BelnxYz5.js} +1 -1
  286. package/web-shell/assets/{vennDiagram-4TSXK5OY-DRSlI9-V.js → vennDiagram-4TSXK5OY-CU-NRqIB.js} +1 -1
  287. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CaLmqGau.js → wardleyDiagram-VM6X3IG4-CDNKqWh-.js} +1 -1
  288. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-8lgUT6e8.js → xychartDiagram-S5SC5T6Z-CLqguL5D.js} +1 -1
  289. package/web-shell/index.html +2 -2
  290. package/chunks/chunk-3UMWOKJC.js +0 -78
  291. package/chunks/chunk-IQAFKVXS.js +0 -22
  292. package/web-shell/assets/channel-CQx7VSAp.js +0 -1
  293. package/web-shell/assets/classDiagram-DTDB5LWJ-C-Uz8hHk.js +0 -1
  294. package/web-shell/assets/classDiagram-v2-JRS7N3AN-C-Uz8hHk.js +0 -1
  295. package/web-shell/assets/index-CCrkEbzz.css +0 -36
  296. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-LuuL5byY.js +0 -1
  297. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-COmnNq8s.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-MFCWL4LI.js";
22
- import "./chunk-R7TKFIQO.js";
23
- import "./chunk-RRCNEW2A.js";
22
+ } from "./chunk-CPJRFFPH.js";
23
+ import "./chunk-CALNF3Z3.js";
24
+ import "./chunk-4BLTSTF6.js";
24
25
  import {
25
26
  startPostRenderPrefetches
26
- } from "./chunk-ANVC5CSK.js";
27
+ } from "./chunk-XBLG564H.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-KP5QK3FB.js";
40
+ } from "./chunk-VH764G6B.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-T7TP5UQL.js";
49
+ } from "./chunk-ULY4ISY2.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-XNC2TCUO.js";
60
+ } from "./chunk-QXXBW2G4.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-VMFPZXRT.js";
92
+ } from "./chunk-ODBNTMZW.js";
90
93
  import {
91
94
  EXTENSION_RELOAD_FAILED_REASON,
92
95
  ExtensionRefreshState
93
- } from "./chunk-P5Z7VD23.js";
96
+ } from "./chunk-WZ4YULVF.js";
94
97
  import {
95
98
  formatSupportedModes,
96
99
  getCommandDisplayName,
97
100
  getCommandSourceBadge,
98
101
  getCommandSourceGroup,
99
102
  getCommandSubcommandNames
100
- } from "./chunk-VYCJITND.js";
103
+ } from "./chunk-QJAFSFYA.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-I67KJGM6.js";
111
+ } from "./chunk-W3ONSAYO.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-XX4MBBFW.js";
121
+ } from "./chunk-UYDQYDW2.js";
122
+ import "./chunk-7L35FKPF.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-SHK2SIR5.js";
139
+ import "./chunk-W673V2H3.js";
137
140
  import {
138
141
  getErrorMessage as getErrorMessage2
139
- } from "./chunk-YLFICBYK.js";
140
- import "./chunk-22QOQKG4.js";
142
+ } from "./chunk-VEQBVJYH.js";
143
+ import "./chunk-CG2PDIGD.js";
141
144
  import "./chunk-XQ4RDO5B.js";
142
145
  import {
143
146
  setUpdateHandler
144
- } from "./chunk-IGOIYZBG.js";
147
+ } from "./chunk-VHPG7BH6.js";
145
148
  import "./chunk-EKTCKZV5.js";
146
- import "./chunk-FXYNIZPW.js";
149
+ import "./chunk-LUVXLLMS.js";
147
150
  import "./chunk-YAF2MQZ6.js";
148
151
  import "./chunk-24FVUD5P.js";
149
- import "./chunk-L36LLVA5.js";
152
+ import "./chunk-QLM7D7W3.js";
150
153
  import "./chunk-6H67XLET.js";
151
- import "./chunk-PMGWY6ZP.js";
154
+ import "./chunk-UULHYZ4W.js";
152
155
  import "./chunk-M3JGHRMQ.js";
153
156
  import "./chunk-VFFQAOPR.js";
154
- import "./chunk-37SOBIA3.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-JOV46WGX.js";
180
+ } from "./chunk-NB3NDQQK.js";
178
181
  import "./chunk-Y53DG2HA.js";
179
182
  import {
180
183
  getExtendedSystemInfo
181
- } from "./chunk-FWH4736Q.js";
182
- import "./chunk-TDHVOZ65.js";
184
+ } from "./chunk-EA4NFWVG.js";
185
+ import "./chunk-R2266LQ5.js";
183
186
  import "./chunk-7U5G6JXI.js";
184
187
  import "./chunk-WCCLLK7X.js";
185
- import "./chunk-I7UNCY24.js";
188
+ import {
189
+ getReasoningEffortsForConfig
190
+ } from "./chunk-2OR32P5M.js";
191
+ import "./chunk-7GZCCHJL.js";
186
192
  import "./chunk-HWVUSYSN.js";
187
- import "./chunk-537SQ2AI.js";
188
- import "./chunk-3RMVM33U.js";
189
- import "./chunk-2C3XDBGL.js";
193
+ import "./chunk-5WC2ECUK.js";
194
+ import "./chunk-4JKLPTV6.js";
195
+ import "./chunk-ORREXWOM.js";
190
196
  import "./chunk-57OAHC2Y.js";
191
- import "./chunk-BNWIX6BM.js";
192
- import "./chunk-RGAQDQ3Z.js";
193
- import "./chunk-RH344FKI.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-UTVIIA7N.js";
198
- import "./chunk-LTCI6ZOJ.js";
203
+ } from "./chunk-NVS4Z6GT.js";
204
+ import "./chunk-45ROPFQY.js";
199
205
  import "./chunk-2AUM35J5.js";
200
206
  import "./chunk-N6VQ37ZZ.js";
201
- import "./chunk-Z6KFLEG7.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-5V4B3EWA.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-65GHQ4FX.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-C55CR5I4.js";
224
+ } from "./chunk-W7PXLIZJ.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-RUMSY4ES.js";
240
+ } from "./chunk-Q2F43WTJ.js";
235
241
  import {
236
242
  TOGGLE_TYPES
237
- } from "./chunk-QW7BUOSI.js";
243
+ } from "./chunk-MWEF5MUK.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-LD53HMPV.js";
249
+ } from "./chunk-CRZBDVP2.js";
244
250
  import "./chunk-5EJZE3FP.js";
245
- import "./chunk-4OCYWXKF.js";
246
- import "./chunk-NUQFUXOG.js";
251
+ import "./chunk-Y6ZWXM44.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-SHX2HIE7.js";
257
+ } from "./chunk-ISPBBKJN.js";
252
258
  import "./chunk-W3N5XAZ6.js";
253
- import "./chunk-GEV66YGE.js";
259
+ import "./chunk-7RXOEUFF.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-TXAEXF2B.js";
277
+ } from "./chunk-BL6B2QS2.js";
271
278
  import "./chunk-GELRJXE2.js";
272
279
  import "./chunk-32CM56LO.js";
273
- import "./chunk-C7M445SS.js";
280
+ import "./chunk-G5QLLD53.js";
274
281
  import "./chunk-XFSFZCM5.js";
275
282
  import "./chunk-2EKVPSIJ.js";
276
283
  import "./chunk-LJZSMWOH.js";
277
- import "./chunk-E4VX6LXB.js";
278
- import "./chunk-RSU3I6UL.js";
284
+ import "./chunk-YZTGGCEE.js";
285
+ import "./chunk-DCPRCDSR.js";
279
286
  import "./chunk-DJXSOEFB.js";
280
- import "./chunk-KTLT7VCX.js";
287
+ import "./chunk-LN3WBOKU.js";
281
288
  import "./chunk-J3VZF2AL.js";
282
289
  import "./chunk-OWCFKIFQ.js";
283
290
  import "./chunk-ZPJWUGCS.js";
284
291
  import "./chunk-5Z4FCEPY.js";
285
292
  import "./chunk-BUQN5LTI.js";
286
- import "./chunk-VU7O7CGQ.js";
287
- import "./chunk-SD7Y2PMC.js";
293
+ import "./chunk-XDNFODER.js";
294
+ import "./chunk-XI7RST4D.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,9 +322,9 @@ import {
313
322
  parseRule,
314
323
  parseVisionModelSetting,
315
324
  refreshMemoryInstruction
316
- } from "./chunk-TSLRORQR.js";
325
+ } from "./chunk-43CI6YWJ.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";
@@ -324,7 +333,7 @@ import "./chunk-LYT2OU7D.js";
324
333
  import "./chunk-B54PFQS5.js";
325
334
  import {
326
335
  writeRuntimeStatus
327
- } from "./chunk-ERMAXPXA.js";
336
+ } from "./chunk-HIXUUCGY.js";
328
337
  import "./chunk-6PVPNMXU.js";
329
338
  import {
330
339
  resolveModelId
@@ -352,31 +361,32 @@ import {
352
361
  } from "./chunk-JX6XHPTX.js";
353
362
  import "./chunk-CLKE4IY3.js";
354
363
  import "./chunk-ZSTCM3MX.js";
355
- import "./chunk-NXWYCSPL.js";
364
+ import "./chunk-SOA4HKRJ.js";
356
365
  import "./chunk-MLXTMF7H.js";
357
- import "./chunk-OFB36ZBA.js";
366
+ import "./chunk-3LPJ776W.js";
358
367
  import "./chunk-3CZ2BQV6.js";
359
368
  import "./chunk-PQEISIKS.js";
360
- import "./chunk-3K456UJF.js";
369
+ import "./chunk-VF6D6EGV.js";
361
370
  import "./chunk-H3Q3RSKZ.js";
362
371
  import "./chunk-S6LOFUVP.js";
363
372
  import "./chunk-NAVJD2PQ.js";
364
- import "./chunk-UKADFFL2.js";
365
- import "./chunk-EJNYBDYC.js";
373
+ import "./chunk-OFVAS4AR.js";
374
+ import "./chunk-HNLMYDQE.js";
366
375
  import "./chunk-QHMLYMMS.js";
367
376
  import "./chunk-CFKIH3D3.js";
368
377
  import {
369
378
  REASONING_EFFORT_TIERS,
370
379
  applyReasoningEffort
371
- } from "./chunk-2LD5U7Q3.js";
380
+ } from "./chunk-6YEOCHSE.js";
372
381
  import "./chunk-DJ2GSRLV.js";
373
- import "./chunk-W4LL5RZO.js";
374
- import "./chunk-3UMWOKJC.js";
382
+ import "./chunk-4ALNJDHL.js";
383
+ import "./chunk-NOO4QFXM.js";
375
384
  import "./chunk-KFFCDLKV.js";
376
385
  import "./chunk-7OCIQNKX.js";
377
386
  import {
378
387
  AuthEvent,
379
388
  ModelSlashCommandEvent,
389
+ PromptSuggestionEvent,
380
390
  collectText,
381
391
  formatFullTurnVisionNotice,
382
392
  formatVisionBridgeNotice,
@@ -386,6 +396,7 @@ import {
386
396
  isImageCapable,
387
397
  logAuth,
388
398
  logModelSlashCommand,
399
+ logPromptSuggestion,
389
400
  logSlashCommand,
390
401
  makeSlashCommandEvent,
391
402
  normalizeParts,
@@ -395,7 +406,7 @@ import {
395
406
  shouldRunVisionBridge,
396
407
  splitImageParts,
397
408
  uiTelemetryService
398
- } from "./chunk-WQBR7LN5.js";
409
+ } from "./chunk-OIPUQE3S.js";
399
410
  import "./chunk-5ETULJLP.js";
400
411
  import "./chunk-XBVNNDPK.js";
401
412
  import "./chunk-VGC4I5JJ.js";
@@ -409,11 +420,12 @@ import "./chunk-HD7O6WLV.js";
409
420
  import "./chunk-WZAD4ZNJ.js";
410
421
  import "./chunk-FPGTNKCP.js";
411
422
  import "./chunk-TIGXX4PA.js";
412
- import "./chunk-PLUAIHZO.js";
423
+ import "./chunk-DTB5BXRG.js";
413
424
  import "./chunk-XFFRI3WM.js";
414
425
  import "./chunk-4HOEU2OR.js";
415
426
  import "./chunk-HHJLM3WQ.js";
416
427
  import {
428
+ isBinary,
417
429
  redactUrlCredentials
418
430
  } from "./chunk-7VEYUF3N.js";
419
431
  import "./chunk-74TONY4F.js";
@@ -435,12 +447,12 @@ import {
435
447
  getErrorMessage,
436
448
  isDebugLogFileEnabled
437
449
  } from "./chunk-ZAFYHRVY.js";
438
- import "./chunk-Y3C5COGI.js";
450
+ import "./chunk-L6ZME3W7.js";
439
451
  import "./chunk-HRPFBHW7.js";
440
452
  import {
441
453
  registerCleanup,
442
454
  runExitCleanup
443
- } from "./chunk-HPE4LEWX.js";
455
+ } from "./chunk-JDPBJIKI.js";
444
456
  import {
445
457
  profileCheckpoint
446
458
  } from "./chunk-QILD6R27.js";
@@ -452,7 +464,10 @@ import {
452
464
  import "./chunk-75DOP5OR.js";
453
465
  import "./chunk-DMTGGOSA.js";
454
466
  import "./chunk-YQ3U5MUC.js";
467
+ import "./chunk-EFT7OMDN.js";
455
468
  import "./chunk-MATEIJZF.js";
469
+ import "./chunk-J5TTWBZK.js";
470
+ import "./chunk-RVIGZBIT.js";
456
471
  import "./chunk-TBWQLLFO.js";
457
472
  import {
458
473
  init_esbuild_shims
@@ -489,7 +504,7 @@ var require_jsx_dev_runtime = __commonJS({
489
504
 
490
505
  // packages/cli/src/ui/opentui/start-opentui-ui.tsx
491
506
  init_esbuild_shims();
492
- var import_react52 = __toESM(require_react(), 1);
507
+ var import_react55 = __toESM(require_react(), 1);
493
508
  import { stat as stat2 } from "node:fs/promises";
494
509
  import { basename as basename3 } from "node:path";
495
510
 
@@ -538,9 +553,9 @@ function requiredOpenTuiAssetKeys(platform = process.platform, arch = process.ar
538
553
  ];
539
554
  }
540
555
  __name(requiredOpenTuiAssetKeys, "requiredOpenTuiAssetKeys");
541
- function isFile(path6) {
556
+ function isFile(path7) {
542
557
  try {
543
- return statSync(path6).isFile();
558
+ return statSync(path7).isFile();
544
559
  } catch {
545
560
  return false;
546
561
  }
@@ -925,11 +940,11 @@ function toBunPointer(pointer) {
925
940
  __name(toBunPointer, "toBunPointer");
926
941
  function createBunBackend(bun2) {
927
942
  return {
928
- dlopen(path6, symbols) {
929
- if (path6 === null) {
943
+ dlopen(path7, symbols) {
944
+ if (path7 === null) {
930
945
  throw new Error(BUN_DLOPEN_NULL);
931
946
  }
932
- const library = bun2.dlopen(path6, normalizeBunDefinitions(symbols));
947
+ const library = bun2.dlopen(path7, normalizeBunDefinitions(symbols));
933
948
  const callbacks = /* @__PURE__ */ new Set();
934
949
  let closed = false;
935
950
  return {
@@ -966,8 +981,8 @@ function createBunBackend(bun2) {
966
981
  __name(createBunBackend, "createBunBackend");
967
982
  function createNodeBackend(nodeFfi) {
968
983
  return {
969
- dlopen(path6, symbols) {
970
- 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));
971
986
  const callbacks = /* @__PURE__ */ new Set();
972
987
  let closed = false;
973
988
  let libraryClosed = false;
@@ -1018,8 +1033,8 @@ function createNodeBackend(nodeFfi) {
1018
1033
  };
1019
1034
  }
1020
1035
  __name(createNodeBackend, "createNodeBackend");
1021
- function toNodeLibraryPath(path6) {
1022
- return path6 instanceof URL ? fileURLToPath(path6) : path6;
1036
+ function toNodeLibraryPath(path7) {
1037
+ return path7 instanceof URL ? fileURLToPath(path7) : path7;
1023
1038
  }
1024
1039
  __name(toNodeLibraryPath, "toNodeLibraryPath");
1025
1040
  function normalizeNodeDefinitions(definitions) {
@@ -8339,8 +8354,8 @@ function resolveParserAsset(relativePath) {
8339
8354
  return resolveDefaultParserAsset(relativePath, new URL(`./${relativePath}`, import.meta.url));
8340
8355
  }
8341
8356
  __name(resolveParserAsset, "resolveParserAsset");
8342
- function isBunfsPath(path6) {
8343
- return path6.includes("$bunfs") || /^B:[\\/]~BUN/i.test(path6);
8357
+ function isBunfsPath(path7) {
8358
+ return path7.includes("$bunfs") || /^B:[\\/]~BUN/i.test(path7);
8344
8359
  }
8345
8360
  __name(isBunfsPath, "isBunfsPath");
8346
8361
  function getBunfsRootPath() {
@@ -8625,7 +8640,7 @@ registerEnvVar({
8625
8640
  default: ""
8626
8641
  });
8627
8642
  var DEFAULT_PARSER_OVERRIDES = [];
8628
- 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");
8629
8644
  var TreeSitterClient = class extends EventEmitter2 {
8630
8645
  static {
8631
8646
  __name(this, "TreeSitterClient");
@@ -8856,17 +8871,17 @@ var TreeSitterClient = class extends EventEmitter2 {
8856
8871
  worker.postMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser: this.resolveFiletypeParser(parser) });
8857
8872
  }
8858
8873
  }
8859
- resolvePath(path6) {
8860
- if (isUrl(path6)) {
8861
- return path6;
8874
+ resolvePath(path7) {
8875
+ if (isUrl(path7)) {
8876
+ return path7;
8862
8877
  }
8863
- if (isBunfsPath(path6)) {
8864
- return normalizeBunfsPath(parse(path6).base);
8878
+ if (isBunfsPath(path7)) {
8879
+ return normalizeBunfsPath(parse(path7).base);
8865
8880
  }
8866
- if (!isAbsolute3(path6)) {
8867
- return resolve2(path6);
8881
+ if (!isAbsolute3(path7)) {
8882
+ return resolve2(path7);
8868
8883
  }
8869
- return path6;
8884
+ return path7;
8870
8885
  }
8871
8886
  addFiletypeParser(filetypeParser) {
8872
8887
  this.sendWorkerMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser: this.resolveFiletypeParser(filetypeParser) });
@@ -8877,8 +8892,8 @@ var TreeSitterClient = class extends EventEmitter2 {
8877
8892
  aliases: filetypeParser.aliases ? [...new Set(filetypeParser.aliases.filter((alias) => alias !== filetypeParser.filetype))] : void 0,
8878
8893
  wasm: this.resolvePath(filetypeParser.wasm),
8879
8894
  queries: {
8880
- highlights: filetypeParser.queries.highlights.map((path6) => this.resolvePath(path6)),
8881
- 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))
8882
8897
  }
8883
8898
  };
8884
8899
  }
@@ -31201,11 +31216,11 @@ async function readResponseBytes(response, signal) {
31201
31216
  return data.byteLength === total ? data : data.slice(0, total);
31202
31217
  }
31203
31218
  __name(readResponseBytes, "readResponseBytes");
31204
- async function readFileBytes(path6, signal) {
31219
+ async function readFileBytes(path7, signal) {
31205
31220
  signal?.throwIfAborted();
31206
- if ((await stat(path6)).size > MAX_ENCODED_BYTES)
31221
+ if ((await stat(path7)).size > MAX_ENCODED_BYTES)
31207
31222
  throw imageError(6);
31208
- const file = await open(path6, "r");
31223
+ const file = await open(path7, "r");
31209
31224
  const chunks = [];
31210
31225
  let total = 0;
31211
31226
  try {
@@ -31297,10 +31312,10 @@ var NativeImage = class _NativeImage {
31297
31312
  }
31298
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;
31299
31314
  if (!url || url.protocol === "file:") {
31300
- const path6 = url ?? source;
31315
+ const path7 = url ?? source;
31301
31316
  let data;
31302
31317
  try {
31303
- data = await readFileBytes(path6, options.signal);
31318
+ data = await readFileBytes(path7, options.signal);
31304
31319
  } catch (error) {
31305
31320
  if (options.signal?.aborted)
31306
31321
  throw options.signal.reason;
@@ -40989,9 +41004,27 @@ var PluginErrorBoundary = class extends import_react14.default.Component {
40989
41004
  };
40990
41005
  extend({ "time-to-first-draw": TimeToFirstDrawRenderable });
40991
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
+
40992
41025
  // packages/cli/src/ui/opentui/opentui-app-shell.tsx
40993
41026
  init_esbuild_shims();
40994
- var import_react49 = __toESM(require_react(), 1);
41027
+ var import_react50 = __toESM(require_react(), 1);
40995
41028
 
40996
41029
  // packages/cli/src/ui/opentui/opentui-host.ts
40997
41030
  init_esbuild_shims();
@@ -42231,6 +42264,22 @@ function projectItemToStreamEvent(item, ctx) {
42231
42264
  type: "warning",
42232
42265
  text: formatUserPromptSubmitBlocked(item.reason, item.originalPrompt)
42233
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
+ };
42234
42283
  case "about":
42235
42284
  case "tools_list":
42236
42285
  case "model_stats":
@@ -42257,11 +42306,10 @@ function projectItemToStreamEvent(item, ctx) {
42257
42306
  // - `help`: `/help` resolves to a dialog and the overlay renders from
42258
42307
  // help-content.ts; no command returns a HELP message, so nothing writes
42259
42308
  // this item in either renderer.
42260
- // - the rest: ink renders these through dedicated components and this
42261
- // renderer has no row shape for them yet. `/advisor`, `/arena` and
42262
- // `/recap` are registered here and do write four of these kinds, so
42263
- // their output stays invisible a registered gap (U-34), not an
42264
- // 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).
42265
42313
  case "tool_group":
42266
42314
  case "retry_countdown":
42267
42315
  case "vision_notice":
@@ -42271,11 +42319,6 @@ function projectItemToStreamEvent(item, ctx) {
42271
42319
  case "gemini_thought_content":
42272
42320
  case "help":
42273
42321
  case "notification":
42274
- case "user_shell":
42275
- case "advisor":
42276
- case "arena_agent_complete":
42277
- case "arena_session_complete":
42278
- case "away_recap":
42279
42322
  case "tool_use_summary":
42280
42323
  case "diff_stats":
42281
42324
  return null;
@@ -42312,8 +42355,10 @@ function transcribeSession(jsonl, opts = {}) {
42312
42355
  }
42313
42356
  const parts = o.message?.parts ?? [];
42314
42357
  if (o.type === "user") {
42315
- if (o.subtype) continue;
42316
- 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);
42317
42362
  if (text) {
42318
42363
  events.push({ type: "user", text });
42319
42364
  prompts.push(text);
@@ -42882,6 +42927,620 @@ var OpenTuiAppHost = class {
42882
42927
  }
42883
42928
  };
42884
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
+
42885
43544
  // packages/cli/src/ui/opentui/slash-gateway.ts
42886
43545
  init_esbuild_shims();
42887
43546
  var QUIT_TOKENS = /* @__PURE__ */ new Set([
@@ -42938,6 +43597,19 @@ var OpenTuiSlashGateway = class {
42938
43597
  await this.ready;
42939
43598
  return this.dispatcher?.mustDeferDuringStreaming(text) ?? false;
42940
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
+ }
42941
43613
  /** True while a dispatched command is still running. */
42942
43614
  isBusy() {
42943
43615
  return this.busy;
@@ -43338,9 +44010,9 @@ function shouldHideSlashCommandInvocation(command, canonicalPath, args) {
43338
44010
  }
43339
44011
  return true;
43340
44012
  }
43341
- const path6 = canonicalPath.join(" ");
43342
- if (BARE_SLASH_COMMANDS_HIDE_INVOCATION.has(path6)) {
43343
- if (path6 === "model") {
44013
+ const path7 = canonicalPath.join(" ");
44014
+ if (BARE_SLASH_COMMANDS_HIDE_INVOCATION.has(path7)) {
44015
+ if (path7 === "model") {
43344
44016
  return isPickerOnlyModelInvocation(args);
43345
44017
  }
43346
44018
  return args.trim() === "";
@@ -44034,96 +44706,90 @@ async function exitSession(config, code) {
44034
44706
  }
44035
44707
  __name(exitSession, "exitSession");
44036
44708
 
44037
- // packages/cli/src/ui/opentui/opentui-error-boundary.tsx
44038
- init_esbuild_shims();
44039
- var import_react17 = __toESM(require_react(), 1);
44040
-
44041
- // packages/cli/src/ui/opentui/theme.ts
44709
+ // packages/cli/src/ui/opentui/early-input.ts
44042
44710
  init_esbuild_shims();
44043
- var DARK = {
44044
- text: "#CDD6F4",
44045
- dim: "#6C7086",
44046
- accent: "#CBA6F7",
44047
- green: "#A6E3A1",
44048
- red: "#F38BA8",
44049
- yellow: "#F9E2AF",
44050
- purple: "#89B4FA",
44051
- hover: "#313244",
44052
- // No bg on dark: the default invert selection (bg=text fg, fg=black) is
44053
- // readable on dark terminals, and leaving bg unset keeps transparency.
44054
- selectionBg: "#264F78",
44055
- selectionFg: "#FFFFFF"
44056
- };
44057
- var C2 = { ...DARK };
44058
- function buildSyntax(mode) {
44059
- const styles = mode === "light" ? {
44060
- // `default` colors unstyled markdown chunks (table cells, plain
44061
- // inline text); without it TextTable falls back to #FFFFFF.
44062
- default: { fg: "#1f2328" },
44063
- keyword: { fg: "#cf222e", bold: true },
44064
- string: { fg: "#0a3069" },
44065
- comment: { fg: "#59636e", italic: true },
44066
- function: { fg: "#8250df" },
44067
- type: { fg: "#953800" },
44068
- number: { fg: "#0550ae" },
44069
- operator: { fg: "#0550ae" },
44070
- variable: { fg: "#1f2328" },
44071
- heading: { fg: "#0550ae", bold: true },
44072
- emphasis: { italic: true },
44073
- strong: { bold: true },
44074
- link: { fg: "#0969da" },
44075
- code: { fg: "#0a3069" }
44076
- } : {
44077
- default: { fg: "#e6edf3" },
44078
- keyword: { fg: "#bb9af7", bold: true },
44079
- string: { fg: "#9ece6a" },
44080
- comment: { fg: "#565f89", italic: true },
44081
- function: { fg: "#7aa2f7" },
44082
- type: { fg: "#e0af68" },
44083
- number: { fg: "#ff9e64" },
44084
- operator: { fg: "#89ddff" },
44085
- variable: { fg: "#e6edf3" },
44086
- heading: { fg: "#7aa2f7", bold: true },
44087
- emphasis: { italic: true },
44088
- strong: { bold: true },
44089
- link: { fg: "#7aa2f7" },
44090
- 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);
44091
44750
  };
44092
- return SyntaxStyle.fromStyles({
44093
- ...styles,
44094
- ...markdownMarkupTokens(mode)
44095
- });
44096
44751
  }
44097
- __name(buildSyntax, "buildSyntax");
44098
- function markdownMarkupTokens(mode) {
44099
- const heading = mode === "light" ? "#0550ae" : "#7aa2f7";
44100
- const inlineCode = mode === "light" ? "#0a3069" : "#9ece6a";
44101
- const link2 = mode === "light" ? "#0969da" : "#7aa2f7";
44102
- const headingStyle = { fg: heading, bold: true };
44103
- return {
44104
- "markup.heading": headingStyle,
44105
- "markup.heading.1": headingStyle,
44106
- "markup.heading.2": headingStyle,
44107
- "markup.heading.3": headingStyle,
44108
- "markup.heading.4": headingStyle,
44109
- "markup.heading.5": headingStyle,
44110
- "markup.heading.6": headingStyle,
44111
- "markup.raw": { fg: inlineCode },
44112
- "markup.italic": { italic: true },
44113
- "markup.strong": { bold: true },
44114
- "markup.link": { fg: link2 },
44115
- "markup.link.label": { fg: link2 },
44116
- "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);
44117
44786
  };
44118
44787
  }
44119
- __name(markdownMarkupTokens, "markdownMarkupTokens");
44120
- var SYNTAX = buildSyntax("dark");
44121
-
44122
- // packages/cli/node_modules/@opentui/react/jsx-runtime.js
44123
- init_esbuild_shims();
44124
- var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
44788
+ __name(armCapturedInputInjection, "armCapturedInputInjection");
44125
44789
 
44126
44790
  // packages/cli/src/ui/opentui/opentui-error-boundary.tsx
44791
+ init_esbuild_shims();
44792
+ var import_react18 = __toESM(require_react(), 1);
44127
44793
  function normalizeError(error) {
44128
44794
  if (error instanceof Error) {
44129
44795
  return error;
@@ -44138,7 +44804,7 @@ function consumeLastRenderError() {
44138
44804
  return err;
44139
44805
  }
44140
44806
  __name(consumeLastRenderError, "consumeLastRenderError");
44141
- var OpenTuiErrorBoundary = class extends import_react17.Component {
44807
+ var OpenTuiErrorBoundary = class extends import_react18.Component {
44142
44808
  static {
44143
44809
  __name(this, "OpenTuiErrorBoundary");
44144
44810
  }
@@ -44173,7 +44839,7 @@ var OpenTuiErrorBoundary = class extends import_react17.Component {
44173
44839
 
44174
44840
  // packages/cli/src/ui/opentui/opentui-dialog-mount.tsx
44175
44841
  init_esbuild_shims();
44176
- var import_react43 = __toESM(require_react(), 1);
44842
+ var import_react44 = __toESM(require_react(), 1);
44177
44843
 
44178
44844
  // packages/cli/src/ui/opentui/key-map.ts
44179
44845
  init_esbuild_shims();
@@ -44546,11 +45212,11 @@ import { EventEmitter as EventEmitter7 } from "node:events";
44546
45212
 
44547
45213
  // packages/cli/src/ui/opentui/dialogs-model.tsx
44548
45214
  init_esbuild_shims();
44549
- var import_react20 = __toESM(require_react(), 1);
45215
+ var import_react21 = __toESM(require_react(), 1);
44550
45216
 
44551
45217
  // packages/cli/src/ui/opentui/dialogs-shared.tsx
44552
45218
  init_esbuild_shims();
44553
- var import_react18 = __toESM(require_react(), 1);
45219
+ var import_react19 = __toESM(require_react(), 1);
44554
45220
 
44555
45221
  // packages/cli/src/ui/opentui/dialogs-core.ts
44556
45222
  init_esbuild_shims();
@@ -44698,20 +45364,20 @@ function useDialogSelect(options) {
44698
45364
  onSelect,
44699
45365
  onHighlight
44700
45366
  } = options;
44701
- const [activeIndex, setActiveIndexState] = (0, import_react18.useState)(
45367
+ const [activeIndex, setActiveIndexState] = (0, import_react19.useState)(
44702
45368
  () => computeInitialActiveIndex(initialIndex, items)
44703
45369
  );
44704
- const [scrollOffset, setScrollOffset] = (0, import_react18.useState)(
45370
+ const [scrollOffset, setScrollOffset] = (0, import_react19.useState)(
44705
45371
  () => getSelectionScrollOffset(
44706
45372
  computeInitialActiveIndex(initialIndex, items),
44707
45373
  items.length,
44708
45374
  maxItemsToShow
44709
45375
  )
44710
45376
  );
44711
- const numberBuffer = (0, import_react18.useRef)("");
44712
- const numberTimer = (0, import_react18.useRef)(null);
44713
- const itemsRef = (0, import_react18.useRef)(items);
44714
- 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);
44715
45381
  if (appliedResyncKey !== resyncKey) {
44716
45382
  setAppliedResyncKey(resyncKey);
44717
45383
  if (numberTimer.current) {
@@ -44726,7 +45392,7 @@ function useDialogSelect(options) {
44726
45392
  getSelectionScrollOffset(next, items.length, maxItemsToShow)
44727
45393
  );
44728
45394
  }
44729
- const latestRef = (0, import_react18.useRef)({ items, activeIndex, onSelect });
45395
+ const latestRef = (0, import_react19.useRef)({ items, activeIndex, onSelect });
44730
45396
  latestRef.current = { items, activeIndex, onSelect };
44731
45397
  if (itemsRef.current !== items) {
44732
45398
  const prevItems = itemsRef.current;
@@ -44741,13 +45407,13 @@ function useDialogSelect(options) {
44741
45407
  );
44742
45408
  }
44743
45409
  }
44744
- (0, import_react18.useEffect)(
45410
+ (0, import_react19.useEffect)(
44745
45411
  () => () => {
44746
45412
  if (numberTimer.current) clearTimeout(numberTimer.current);
44747
45413
  },
44748
45414
  []
44749
45415
  );
44750
- (0, import_react18.useEffect)(() => {
45416
+ (0, import_react19.useEffect)(() => {
44751
45417
  const next = followScrollOffset(
44752
45418
  activeIndex,
44753
45419
  scrollOffset,
@@ -45021,7 +45687,7 @@ function OpenTuiModelDialog(props) {
45021
45687
  availableTerminalHeight
45022
45688
  } = props;
45023
45689
  const isAuxMode = mode !== "primary";
45024
- const [highlightedKey, setHighlightedKey] = (0, import_react20.useState)(null);
45690
+ const [highlightedKey, setHighlightedKey] = (0, import_react21.useState)(null);
45025
45691
  const initialIndex = initialKey ? Math.max(
45026
45692
  0,
45027
45693
  entries.findIndex((entry) => entry.key === initialKey)
@@ -45983,7 +46649,7 @@ __name(applyExtensionUpdate, "applyExtensionUpdate");
45983
46649
 
45984
46650
  // packages/cli/src/ui/opentui/dialogs-theme.tsx
45985
46651
  init_esbuild_shims();
45986
- var import_react22 = __toESM(require_react(), 1);
46652
+ var import_react23 = __toESM(require_react(), 1);
45987
46653
  var THEME_DIALOG_MAX_ITEMS_TO_SHOW = 12;
45988
46654
  var THEME_PREVIEW_CODE = `# function
45989
46655
  def fibonacci(n):
@@ -45993,7 +46659,7 @@ def fibonacci(n):
45993
46659
  return a`;
45994
46660
  var THEME_PREVIEW_DIFF = `--- a/util.py
45995
46661
  +++ b/util.py
45996
- @@ -1,2 +1,2 @@
46662
+ @@ -1,1 +1,1 @@
45997
46663
  - print("Hello, " + name)
45998
46664
  + print(f"Hello, {name}!")
45999
46665
  `;
@@ -46052,11 +46718,11 @@ function computeThemePreviewLayout(availableTerminalHeight, themeItemCount) {
46052
46718
  __name(computeThemePreviewLayout, "computeThemePreviewLayout");
46053
46719
  function OpenTuiThemeDialog(props) {
46054
46720
  const { onSelect, onHighlight, settings, availableTerminalHeight } = props;
46055
- const [selectedScope, setSelectedScope] = (0, import_react22.useState)(
46721
+ const [selectedScope, setSelectedScope] = (0, import_react23.useState)(
46056
46722
  "User" /* User */
46057
46723
  );
46058
- const [highlightedThemeName, setHighlightedThemeName] = (0, import_react22.useState)(settings.merged.ui?.theme || AUTO_THEME_NAME);
46059
- 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");
46060
46726
  const customThemes = selectedScope === "User" /* User */ ? settings.user.settings.ui?.customThemes || {} : settings.merged.ui?.customThemes || {};
46061
46727
  const builtInThemes = themeManager.getAvailableThemes().filter((theme) => theme.type !== "custom");
46062
46728
  const themeItems = buildThemeItems(builtInThemes, Object.keys(customThemes));
@@ -46133,9 +46799,8 @@ function OpenTuiThemeDialog(props) {
46133
46799
  onWheel: (direction) => themeList.setActiveIndex(
46134
46800
  themeList.activeIndex + (direction === "down" ? 1 : -1)
46135
46801
  ),
46136
- renderLabel: (item, { titleColor }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: titleColor, children: [
46137
- item.themeNameDisplay,
46138
- " ",
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} ` }),
46139
46804
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: item.themeTypeDisplay })
46140
46805
  ] })
46141
46806
  }
@@ -46212,14 +46877,14 @@ __name(OpenTuiThemeDialog, "OpenTuiThemeDialog");
46212
46877
 
46213
46878
  // packages/cli/src/ui/opentui/dialogs-settings.tsx
46214
46879
  init_esbuild_shims();
46215
- var import_react25 = __toESM(require_react(), 1);
46880
+ var import_react26 = __toESM(require_react(), 1);
46216
46881
 
46217
46882
  // packages/cli/src/ui/opentui/dialogs-stats-skills.tsx
46218
46883
  init_esbuild_shims();
46219
- var import_react23 = __toESM(require_react(), 1);
46884
+ var import_react24 = __toESM(require_react(), 1);
46220
46885
  function useEscToClose(onClose, enabled) {
46221
46886
  const renderer = useRenderer();
46222
- (0, import_react23.useLayoutEffect)(() => {
46887
+ (0, import_react24.useLayoutEffect)(() => {
46223
46888
  if (!enabled) return;
46224
46889
  const onRawInput = /* @__PURE__ */ __name((sequence) => {
46225
46890
  if (sequence !== "\x1B") return false;
@@ -46255,9 +46920,9 @@ var TABS = [
46255
46920
  ];
46256
46921
  function OpenTuiStatsDialog(props) {
46257
46922
  const { config, onClose, isFocused = true } = props;
46258
- const [tab, setTab] = (0, import_react23.useState)("session");
46259
- const [, forceUpdate] = (0, import_react23.useState)(0);
46260
- (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)(() => {
46261
46926
  const handler = /* @__PURE__ */ __name(() => forceUpdate((n) => n + 1), "handler");
46262
46927
  uiTelemetryService.on("update", handler);
46263
46928
  return () => {
@@ -46413,10 +47078,10 @@ function OpenTuiStatsDialog(props) {
46413
47078
  __name(OpenTuiStatsDialog, "OpenTuiStatsDialog");
46414
47079
  function OpenTuiSkillsDialog(props) {
46415
47080
  const { config, onClose } = props;
46416
- const [rows, setRows] = (0, import_react23.useState)([]);
46417
- 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);
46418
47083
  useEscToClose(onClose, true);
46419
- (0, import_react23.useEffect)(() => {
47084
+ (0, import_react24.useEffect)(() => {
46420
47085
  let alive = true;
46421
47086
  const mgr = config?.getSkillManager?.();
46422
47087
  if (!mgr) {
@@ -46583,37 +47248,37 @@ function editMoveCursor(state, movement) {
46583
47248
  __name(editMoveCursor, "editMoveCursor");
46584
47249
  function OpenTuiSettingsDialog(props) {
46585
47250
  const { settings, onSelect, onRestartRequest, onSettingApplied, config } = props;
46586
- const [mode, setMode] = (0, import_react25.useState)("settings");
46587
- const [selectedScope, setSelectedScope] = (0, import_react25.useState)(
47251
+ const [mode, setMode] = (0, import_react26.useState)("settings");
47252
+ const [selectedScope, setSelectedScope] = (0, import_react26.useState)(
46588
47253
  "User" /* User */
46589
47254
  );
46590
- const [activeSettingIndex, setActiveSettingIndex] = (0, import_react25.useState)(0);
46591
- const [scrollOffset, setScrollOffset] = (0, import_react25.useState)(0);
46592
- const [activeTab, setActiveTab] = (0, import_react25.useState)("settings");
46593
- 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)(
46594
47259
  "list"
46595
47260
  );
46596
- const [searchQuery, setSearchQuery] = (0, import_react25.useState)("");
46597
- const [pendingSettings, setPendingSettings] = (0, import_react25.useState)(
47261
+ const [searchQuery, setSearchQuery] = (0, import_react26.useState)("");
47262
+ const [pendingSettings, setPendingSettings] = (0, import_react26.useState)(
46598
47263
  () => structuredClone(settings.forScope("User" /* User */).settings)
46599
47264
  );
46600
- const [modifiedSettings, setModifiedSettings] = (0, import_react25.useState)(
47265
+ const [modifiedSettings, setModifiedSettings] = (0, import_react26.useState)(
46601
47266
  /* @__PURE__ */ new Set()
46602
47267
  );
46603
- const [restartRequiredSettings, setRestartRequiredSettings] = (0, import_react25.useState)(/* @__PURE__ */ new Set());
46604
- const [editingKey, setEditingKey] = (0, import_react25.useState)(null);
46605
- const [edit, setEdit] = (0, import_react25.useState)({ buffer: "", cursor: 0 });
46606
- const [systemInfo, setSystemInfo] = (0, import_react25.useState)(null);
46607
- const [statusError, setStatusError] = (0, import_react25.useState)(false);
46608
- 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);
46609
47274
  const showRestartPrompt = restartRequiredSettings.size > 0;
46610
- (0, import_react25.useEffect)(() => {
47275
+ (0, import_react26.useEffect)(() => {
46611
47276
  setPendingSettings(
46612
47277
  structuredClone(settings.forScope(selectedScope).settings)
46613
47278
  );
46614
47279
  setModifiedSettings(/* @__PURE__ */ new Set());
46615
47280
  }, [selectedScope, settings]);
46616
- (0, import_react25.useEffect)(() => {
47281
+ (0, import_react26.useEffect)(() => {
46617
47282
  if (activeTab !== "status") {
46618
47283
  setSystemInfo(null);
46619
47284
  setStatusError(false);
@@ -46631,7 +47296,7 @@ function OpenTuiSettingsDialog(props) {
46631
47296
  cancelled = true;
46632
47297
  };
46633
47298
  }, [activeTab, config, settings, statusReloadNonce]);
46634
- (0, import_react25.useEffect)(() => {
47299
+ (0, import_react26.useEffect)(() => {
46635
47300
  setActiveSettingIndex(0);
46636
47301
  setScrollOffset(0);
46637
47302
  }, [searchQuery]);
@@ -46995,8 +47660,8 @@ function OpenTuiSettingsDialog(props) {
46995
47660
  if (isEditing) {
46996
47661
  displayValue = edit.buffer;
46997
47662
  } else if (item.type === "number" || item.type === "string") {
46998
- const path6 = item.key.split(".");
46999
- const currentValue = getNestedValue(pendingSettings, path6);
47663
+ const path7 = item.key.split(".");
47664
+ const currentValue = getNestedValue(pendingSettings, path7);
47000
47665
  const defaultValue = getDefaultValue(item.key);
47001
47666
  const effectiveCurrentValue = currentValue !== void 0 && currentValue !== null ? currentValue : defaultValue;
47002
47667
  if (item.key === "general.outputLanguage" && isAutoLanguage(
@@ -47043,12 +47708,9 @@ function OpenTuiSettingsDialog(props) {
47043
47708
  },
47044
47709
  children: [
47045
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 : "" }) }),
47046
- /* @__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: [
47047
- item.label,
47048
- scopeMessage ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.dim, children: [
47049
- " ",
47050
- scopeMessage
47051
- ] }) : 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
47052
47714
  ] }) }),
47053
47715
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { marginLeft: 1, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
47054
47716
  "text",
@@ -47080,7 +47742,7 @@ __name(OpenTuiSettingsDialog, "OpenTuiSettingsDialog");
47080
47742
 
47081
47743
  // packages/cli/src/ui/opentui/dialogs-extensions.tsx
47082
47744
  init_esbuild_shims();
47083
- var import_react27 = __toESM(require_react(), 1);
47745
+ var import_react28 = __toESM(require_react(), 1);
47084
47746
  var EXTENSIONS_TABS = {
47085
47747
  INSTALLED: "installed",
47086
47748
  DISCOVER: "discover",
@@ -47145,40 +47807,40 @@ function OpenTuiExtensionsDialog(props) {
47145
47807
  onDetailAction,
47146
47808
  busy = false
47147
47809
  } = props;
47148
- const [activeTab, setActiveTab] = (0, import_react27.useState)(
47810
+ const [activeTab, setActiveTab] = (0, import_react28.useState)(
47149
47811
  initialTab ?? EXTENSIONS_TABS.INSTALLED
47150
47812
  );
47151
- const [discoverFilter, setDiscoverFilter] = (0, import_react27.useState)(
47813
+ const [discoverFilter, setDiscoverFilter] = (0, import_react28.useState)(
47152
47814
  discoverFilterProp ?? null
47153
47815
  );
47154
- const [view, setView] = (0, import_react27.useState)("list");
47155
- const [selectedKey, setSelectedKey] = (0, import_react27.useState)(null);
47156
- const [checkedUpdateState, setCheckedUpdateState] = (0, import_react27.useState)(void 0);
47157
- 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)(() => {
47158
47820
  setDiscoverFilter(null);
47159
47821
  onDiscoverFilterChange?.(null);
47160
47822
  }, [onDiscoverFilterChange]);
47161
- const cycle = (0, import_react27.useCallback)((direction) => {
47823
+ const cycle = (0, import_react28.useCallback)((direction) => {
47162
47824
  setDiscoverFilter(null);
47163
47825
  setActiveTab(
47164
47826
  (current) => cycleTab(EXTENSIONS_TAB_ORDER, current, direction)
47165
47827
  );
47166
47828
  }, []);
47167
- const rows = (0, import_react27.useMemo)(
47829
+ const rows = (0, import_react28.useMemo)(
47168
47830
  () => rowsByTab?.[EXTENSIONS_TABS.INSTALLED] ?? [],
47169
47831
  [rowsByTab]
47170
47832
  );
47171
- const currentRow = (0, import_react27.useMemo)(
47833
+ const currentRow = (0, import_react28.useMemo)(
47172
47834
  () => selectedKey ? rows.find((row) => row.key === selectedKey) ?? null : null,
47173
47835
  [rows, selectedKey]
47174
47836
  );
47175
- (0, import_react27.useEffect)(() => {
47837
+ (0, import_react28.useEffect)(() => {
47176
47838
  if (view !== "list" && !currentRow) {
47177
47839
  setView("list");
47178
47840
  setSelectedKey(null);
47179
47841
  }
47180
47842
  }, [view, currentRow]);
47181
- const listItems = (0, import_react27.useMemo)(
47843
+ const listItems = (0, import_react28.useMemo)(
47182
47844
  () => rows.map((row) => ({
47183
47845
  key: row.key,
47184
47846
  value: row.key,
@@ -47196,7 +47858,7 @@ function OpenTuiExtensionsDialog(props) {
47196
47858
  setView("detail");
47197
47859
  }, "onSelect")
47198
47860
  });
47199
- const detailActions = (0, import_react27.useMemo)(() => {
47861
+ const detailActions = (0, import_react28.useMemo)(() => {
47200
47862
  if (!currentRow) return [];
47201
47863
  const enabled = currentRow.enabled !== false;
47202
47864
  const items = [
@@ -47266,7 +47928,7 @@ function OpenTuiExtensionsDialog(props) {
47266
47928
  );
47267
47929
  }, "onSelect")
47268
47930
  });
47269
- const scopeItems = (0, import_react27.useMemo)(
47931
+ const scopeItems = (0, import_react28.useMemo)(
47270
47932
  () => [
47271
47933
  {
47272
47934
  key: "user",
@@ -47533,7 +48195,7 @@ __name(OpenTuiExtensionsDialog, "OpenTuiExtensionsDialog");
47533
48195
 
47534
48196
  // packages/cli/src/ui/opentui/dialogs-mcp.tsx
47535
48197
  init_esbuild_shims();
47536
- var import_react29 = __toESM(require_react(), 1);
48198
+ var import_react30 = __toESM(require_react(), 1);
47537
48199
  var MCP_MANAGEMENT_STEPS = {
47538
48200
  SERVER_LIST: "server-list",
47539
48201
  SERVER_DETAIL: "server-detail",
@@ -47711,19 +48373,19 @@ function OpenTuiMcpDialog(props) {
47711
48373
  onClose,
47712
48374
  onServerAction
47713
48375
  } = props;
47714
- const [navigationStack, setNavigationStack] = (0, import_react29.useState)([
48376
+ const [navigationStack, setNavigationStack] = (0, import_react30.useState)([
47715
48377
  MCP_MANAGEMENT_STEPS.SERVER_LIST
47716
48378
  ]);
47717
- const [selectedServerName, setSelectedServerName] = (0, import_react29.useState)(
48379
+ const [selectedServerName, setSelectedServerName] = (0, import_react30.useState)(
47718
48380
  null
47719
48381
  );
47720
48382
  const selectedServer = selectedServerName ? servers.find((server) => server.name === selectedServerName) ?? null : null;
47721
- const [selectedTool, setSelectedTool] = (0, import_react29.useState)(null);
47722
- const [selectedResource, setSelectedResource] = (0, import_react29.useState)(null);
47723
- const [serverCursor, setServerCursor] = (0, import_react29.useState)(0);
47724
- const [actionCursor, setActionCursor] = (0, import_react29.useState)(0);
47725
- const [toolCursor, setToolCursor] = (0, import_react29.useState)(0);
47726
- 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);
47727
48389
  const currentStep = navigationStack[navigationStack.length - 1] ?? MCP_MANAGEMENT_STEPS.SERVER_LIST;
47728
48390
  const navigateToStep = /* @__PURE__ */ __name((step) => setNavigationStack((prev) => [...prev, step]), "navigateToStep");
47729
48391
  const navigateBack = /* @__PURE__ */ __name(() => setNavigationStack((prev) => prev.length <= 1 ? prev : prev.slice(0, -1)), "navigateBack");
@@ -47920,13 +48582,9 @@ function OpenTuiMcpDialog(props) {
47920
48582
  flexDirection: "column",
47921
48583
  marginBottom: groupIndex === groupedServers.length - 1 ? 0 : 1,
47922
48584
  children: [
47923
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.text, attributes: 1, children: [
47924
- ` ${group.displayName}`,
47925
- group.servers[0]?.configPath ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.dim, children: [
47926
- " (",
47927
- group.servers[0].configPath,
47928
- ")"
47929
- ] }) : 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
47930
48588
  ] }),
47931
48589
  group.servers.map((server, itemIndex) => {
47932
48590
  const globalIndex = startIndex + itemIndex;
@@ -48135,9 +48793,9 @@ __name(OpenTuiMcpDialog, "OpenTuiMcpDialog");
48135
48793
 
48136
48794
  // packages/cli/src/ui/opentui/dialogs-permissions.tsx
48137
48795
  init_esbuild_shims();
48138
- var import_react31 = __toESM(require_react(), 1);
48139
- import * as fs2 from "node:fs";
48140
- 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";
48141
48799
  import * as nodePath from "node:path";
48142
48800
  function getPermissionsTabs() {
48143
48801
  return [
@@ -48211,17 +48869,17 @@ __name(getPermissionScopeItems, "getPermissionScopeItems");
48211
48869
  function validateWorkspaceDirectory(input, currentDirectories) {
48212
48870
  const trimmed = input.trim();
48213
48871
  if (!trimmed) return { error: "" };
48214
- const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os2.homedir()) : trimmed;
48872
+ const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os3.homedir()) : trimmed;
48215
48873
  const absoluteExpanded = nodePath.isAbsolute(expanded) ? expanded : nodePath.resolve(expanded);
48216
- if (!fs2.existsSync(absoluteExpanded)) {
48874
+ if (!fs3.existsSync(absoluteExpanded)) {
48217
48875
  return { error: t("Directory does not exist.") };
48218
48876
  }
48219
- if (!fs2.statSync(absoluteExpanded).isDirectory()) {
48877
+ if (!fs3.statSync(absoluteExpanded).isDirectory()) {
48220
48878
  return { error: t("Path is not a directory.") };
48221
48879
  }
48222
48880
  let resolved;
48223
48881
  try {
48224
- resolved = fs2.realpathSync(absoluteExpanded);
48882
+ resolved = fs3.realpathSync(absoluteExpanded);
48225
48883
  } catch {
48226
48884
  resolved = absoluteExpanded;
48227
48885
  }
@@ -48252,19 +48910,19 @@ function OpenTuiPermissionsDialog(props) {
48252
48910
  onExit
48253
48911
  } = props;
48254
48912
  const tabs = getPermissionsTabs();
48255
- const [activeTabIndex, setActiveTabIndex] = (0, import_react31.useState)(0);
48913
+ const [activeTabIndex, setActiveTabIndex] = (0, import_react32.useState)(0);
48256
48914
  const activeTab = tabs[activeTabIndex];
48257
- const [view, setView] = (0, import_react31.useState)("rule-list");
48258
- const [searchQuery, setSearchQuery] = (0, import_react31.useState)("");
48259
- const [newRuleInput, setNewRuleInput] = (0, import_react31.useState)("");
48260
- const [ruleInputError, setRuleInputError] = (0, import_react31.useState)("");
48261
- const [pendingRuleText, setPendingRuleText] = (0, import_react31.useState)("");
48262
- 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)(
48263
48921
  null
48264
48922
  );
48265
- const [newDirInput, setNewDirInput] = (0, import_react31.useState)("");
48266
- const [dirInputError, setDirInputError] = (0, import_react31.useState)("");
48267
- 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);
48268
48926
  const currentTabRules = activeTab.id === "workspace" ? [] : rules.filter((r) => r.type === activeTab.id);
48269
48927
  const filteredRules = currentTabRules.filter(
48270
48928
  (r) => matchesSearchQuery(searchQuery, [r.raw, r.toolName])
@@ -48566,13 +49224,10 @@ function OpenTuiPermissionsDialog(props) {
48566
49224
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, children: t(
48567
49225
  "Permission rules are a tool name, optionally followed by a specifier in parentheses."
48568
49226
  ) }),
48569
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: C2.text, children: [
48570
- t("e.g.,"),
48571
- " ",
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.,")} ` }),
48572
49229
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { attributes: 1, children: "WebFetch" }),
48573
- " ",
48574
- t("or"),
48575
- " ",
49230
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, children: ` ${t("or")} ` }),
48576
49231
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { attributes: 1, children: "Bash(ls:*)" })
48577
49232
  ] }),
48578
49233
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { height: 1 }),
@@ -48603,11 +49258,13 @@ function OpenTuiPermissionsDialog(props) {
48603
49258
  focused: true,
48604
49259
  onHover: scopeList.setActiveIndex,
48605
49260
  onSelectIndex: scopeList.selectIndex,
48606
- renderLabel: (item, { titleColor }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("text", { fg: titleColor, children: [
48607
- item.label,
48608
- " ",
48609
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: item.description })
48610
- ] })
49261
+ renderLabel: (item, { titleColor }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
49262
+ "text",
49263
+ {
49264
+ fg: titleColor,
49265
+ children: `${item.label} ${item.description}`
49266
+ }
49267
+ )
48611
49268
  }
48612
49269
  )
48613
49270
  ] }),
@@ -48684,7 +49341,7 @@ __name(OpenTuiPermissionsDialog, "OpenTuiPermissionsDialog");
48684
49341
 
48685
49342
  // packages/cli/src/ui/opentui/dialogs-auth.tsx
48686
49343
  init_esbuild_shims();
48687
- var import_react35 = __toESM(require_react(), 1);
49344
+ var import_react36 = __toESM(require_react(), 1);
48688
49345
 
48689
49346
  // packages/cli/src/ui/opentui/input-prompt-key.ts
48690
49347
  init_esbuild_shims();
@@ -49381,10 +50038,10 @@ __name(historyDownDecision, "historyDownDecision");
49381
50038
 
49382
50039
  // packages/cli/src/ui/opentui/dialogs-misc.tsx
49383
50040
  init_esbuild_shims();
49384
- var import_react33 = __toESM(require_react(), 1);
50041
+ var import_react34 = __toESM(require_react(), 1);
49385
50042
  function useEsc(onClose) {
49386
50043
  const renderer = useRenderer();
49387
- (0, import_react33.useLayoutEffect)(() => {
50044
+ (0, import_react34.useLayoutEffect)(() => {
49388
50045
  const onRaw = /* @__PURE__ */ __name((seq) => {
49389
50046
  if (seq !== "\x1B") return false;
49390
50047
  onClose();
@@ -49438,20 +50095,20 @@ function nextEnabledIndex(items, current, delta) {
49438
50095
  __name(nextEnabledIndex, "nextEnabledIndex");
49439
50096
  function OpenTuiEditorDialog({ settings, onClose, notify }) {
49440
50097
  useEsc(onClose);
49441
- const editors = (0, import_react33.useMemo)(
50098
+ const editors = (0, import_react34.useMemo)(
49442
50099
  () => editorSettingsManager.getAvailableEditorDisplays(),
49443
50100
  []
49444
50101
  );
49445
- const [mode, setMode] = (0, import_react33.useState)("editor");
49446
- 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 */);
49447
50104
  const scopeIndexOf = /* @__PURE__ */ __name((s) => {
49448
50105
  const pref = settings.forScope(s).settings.general?.preferredEditor;
49449
50106
  const idx = pref ? editors.findIndex((e) => e.type === pref) : 0;
49450
50107
  return idx >= 0 ? idx : 0;
49451
50108
  }, "scopeIndexOf");
49452
- const [sel, setSel] = (0, import_react33.useState)(() => scopeIndexOf("User" /* User */));
49453
- const scopeItems = (0, import_react33.useMemo)(() => getScopeItems(), []);
49454
- 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);
49455
50112
  const highlightScope = /* @__PURE__ */ __name((idx) => {
49456
50113
  const item = scopeItems[idx];
49457
50114
  if (!item) return;
@@ -49565,12 +50222,12 @@ function OpenTuiTrustDialog({ config, onClose }) {
49565
50222
  __name(OpenTuiTrustDialog, "OpenTuiTrustDialog");
49566
50223
  function OpenTuiDeleteDialog({ config, onClose, notify }) {
49567
50224
  useEsc(onClose);
49568
- const [rows, setRows] = (0, import_react33.useState)([]);
49569
- const [loading, setLoading] = (0, import_react33.useState)(true);
49570
- const [cursor, setCursor] = (0, import_react33.useState)(0);
49571
- 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);
49572
50229
  const currentSessionId = config?.getSessionId?.() ?? "";
49573
- (0, import_react33.useEffect)(() => {
50230
+ (0, import_react34.useEffect)(() => {
49574
50231
  let alive = true;
49575
50232
  const svc = config?.getSessionService?.();
49576
50233
  if (!svc) {
@@ -49653,10 +50310,10 @@ function OpenTuiResumeDialog({
49653
50310
  onSelect
49654
50311
  }) {
49655
50312
  useEsc(onClose);
49656
- const [rows, setRows] = (0, import_react33.useState)(matchedSessions ?? []);
49657
- const [loading, setLoading] = (0, import_react33.useState)(!matchedSessions);
49658
- const [cursor, setCursor] = (0, import_react33.useState)(0);
49659
- (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)(() => {
49660
50317
  if (matchedSessions) {
49661
50318
  setRows(matchedSessions);
49662
50319
  setLoading(false);
@@ -49732,8 +50389,8 @@ function OpenTuiRewindDialog({ onClose }) {
49732
50389
  __name(OpenTuiRewindDialog, "OpenTuiRewindDialog");
49733
50390
  function OpenTuiDiffDialog({ onClose }) {
49734
50391
  useEsc(onClose);
49735
- const [lines, setLines] = (0, import_react33.useState)([]);
49736
- (0, import_react33.useEffect)(() => {
50392
+ const [lines, setLines] = (0, import_react34.useState)([]);
50393
+ (0, import_react34.useEffect)(() => {
49737
50394
  let alive = true;
49738
50395
  import("node:child_process").then(({ execFile }) => {
49739
50396
  execFile(
@@ -49770,9 +50427,9 @@ function OpenTuiSubagentCreateDialog({ onClose }) {
49770
50427
  __name(OpenTuiSubagentCreateDialog, "OpenTuiSubagentCreateDialog");
49771
50428
  function OpenTuiSubagentListDialog({ config, onClose }) {
49772
50429
  useEsc(onClose);
49773
- const [rows, setRows] = (0, import_react33.useState)([]);
49774
- const [loading, setLoading] = (0, import_react33.useState)(true);
49775
- (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)(() => {
49776
50433
  let alive = true;
49777
50434
  const mgr = config?.getSubagentManager?.();
49778
50435
  if (!mgr) {
@@ -49947,13 +50604,13 @@ function useLineInputKeys(value, onChange, onSubmit) {
49947
50604
  __name(useLineInputKeys, "useLineInputKeys");
49948
50605
  function ProtocolStep({ flow }) {
49949
50606
  const provider = flow.state.provider;
49950
- const items = (0, import_react35.useMemo)(() => {
50607
+ const items = (0, import_react36.useMemo)(() => {
49951
50608
  const protocolOpts = provider.protocolOptions ?? [provider.protocol];
49952
50609
  return PROTOCOL_ITEMS.filter(
49953
50610
  (p2) => protocolOpts.includes(p2.value)
49954
50611
  );
49955
50612
  }, [provider]);
49956
- const [cursor, setCursor] = (0, import_react35.useState)(0);
50613
+ const [cursor, setCursor] = (0, import_react36.useState)(0);
49957
50614
  useKeyboard((key) => {
49958
50615
  const o = toOriginalKey(key);
49959
50616
  if (o.name === "up") {
@@ -49982,7 +50639,7 @@ function BaseUrlSelectStep({
49982
50639
  description: opt.url,
49983
50640
  value: opt.url
49984
50641
  }));
49985
- const [cursor, setCursor] = (0, import_react35.useState)(flow.state.baseUrlOptionIndex);
50642
+ const [cursor, setCursor] = (0, import_react36.useState)(flow.state.baseUrlOptionIndex);
49986
50643
  useKeyboard((key) => {
49987
50644
  const o = toOriginalKey(key);
49988
50645
  if (o.name === "up" || o.name === "down") {
@@ -50066,24 +50723,24 @@ function ModelsStep({
50066
50723
  provider,
50067
50724
  flow
50068
50725
  }) {
50069
- const modelOptions = (0, import_react35.useMemo)(
50726
+ const modelOptions = (0, import_react36.useMemo)(
50070
50727
  () => provider.models?.map((m3) => m3.id) ?? [],
50071
50728
  [provider.models]
50072
50729
  );
50073
50730
  const hasSelectableModels = modelOptions.length > 0;
50074
- const selectedModelIds = (0, import_react35.useMemo)(
50731
+ const selectedModelIds = (0, import_react36.useMemo)(
50075
50732
  () => normalizeModelIds(flow.state.modelIds),
50076
50733
  [flow.state.modelIds]
50077
50734
  );
50078
- const recommendedIds = (0, import_react35.useMemo)(() => new Set(modelOptions), [modelOptions]);
50079
- const [focus, setFocus] = (0, import_react35.useState)(MODEL_CUSTOM_INPUT_FOCUS_INDEX);
50080
- 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)(
50081
50738
  () => selectedModelIds.filter((id) => !recommendedIds.has(id)).join(", ")
50082
50739
  );
50083
- const [checked, setChecked] = (0, import_react35.useState)(
50740
+ const [checked, setChecked] = (0, import_react36.useState)(
50084
50741
  () => new Set(selectedModelIds.filter((id) => recommendedIds.has(id)))
50085
50742
  );
50086
- const syncModelIds = (0, import_react35.useCallback)(
50743
+ const syncModelIds = (0, import_react36.useCallback)(
50087
50744
  (custom, keys) => {
50088
50745
  flow.changeModelIds(
50089
50746
  uniqueIds([...normalizeModelIds(custom), ...keys]).join(", ")
@@ -50091,14 +50748,14 @@ function ModelsStep({
50091
50748
  },
50092
50749
  [flow]
50093
50750
  );
50094
- const updateCustom = (0, import_react35.useCallback)(
50751
+ const updateCustom = (0, import_react36.useCallback)(
50095
50752
  (next) => {
50096
50753
  setCustomText(next);
50097
50754
  syncModelIds(next, checked);
50098
50755
  },
50099
50756
  [checked, syncModelIds]
50100
50757
  );
50101
- const toggleRecommended = (0, import_react35.useCallback)(
50758
+ const toggleRecommended = (0, import_react36.useCallback)(
50102
50759
  (id) => {
50103
50760
  const next = new Set(checked);
50104
50761
  if (next.has(id)) next.delete(id);
@@ -50108,7 +50765,7 @@ function ModelsStep({
50108
50765
  },
50109
50766
  [checked, customText, syncModelIds]
50110
50767
  );
50111
- const submit = (0, import_react35.useCallback)(() => {
50768
+ const submit = (0, import_react36.useCallback)(() => {
50112
50769
  flow.submitModelIds({
50113
50770
  modelIds: uniqueIds([...normalizeModelIds(customText), ...checked])
50114
50771
  });
@@ -50338,14 +50995,17 @@ function AuthDialogFlow({
50338
50995
  config,
50339
50996
  settings,
50340
50997
  onClose,
50341
- notify
50998
+ notify,
50999
+ initialError
50342
51000
  }) {
50343
- const [errorMessage, setErrorMessage] = (0, import_react35.useState)(null);
50344
- const [viewLevel, setViewLevel] = (0, import_react35.useState)("main");
50345
- const [_viewStack, setViewStack] = (0, import_react35.useState)([]);
50346
- const [mainIndex, setMainIndex] = (0, import_react35.useState)(null);
50347
- const [subMenuIndex, setSubMenuIndex] = (0, import_react35.useState)({});
50348
- 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)(
50349
51009
  async (providerConfig, inputs) => {
50350
51010
  const protocol = inputs.protocol ?? providerConfig.protocol;
50351
51011
  try {
@@ -50377,15 +51037,15 @@ function AuthDialogFlow({
50377
51037
  [settings, config, notify, onClose]
50378
51038
  );
50379
51039
  const setupFlow = useProviderSetupFlow(handleProviderSubmit);
50380
- const clearErrors = (0, import_react35.useCallback)(() => setErrorMessage(null), []);
50381
- const pushView = (0, import_react35.useCallback)(
51040
+ const clearErrors = (0, import_react36.useCallback)(() => setErrorMessage(null), []);
51041
+ const pushView = (0, import_react36.useCallback)(
50382
51042
  (view) => {
50383
51043
  setViewStack((prev) => [...prev, viewLevel]);
50384
51044
  setViewLevel(view);
50385
51045
  },
50386
51046
  [viewLevel]
50387
51047
  );
50388
- const goBack = (0, import_react35.useCallback)(() => {
51048
+ const goBack = (0, import_react36.useCallback)(() => {
50389
51049
  clearErrors();
50390
51050
  if (viewLevel === "provider-setup") {
50391
51051
  if (setupFlow.goBack()) return;
@@ -50397,8 +51057,8 @@ function AuthDialogFlow({
50397
51057
  return next;
50398
51058
  });
50399
51059
  }, [viewLevel, setupFlow, clearErrors]);
50400
- const alibabaItems = (0, import_react35.useMemo)(() => ALIBABA_PROVIDERS.map(providerToItem), []);
50401
- const thirdPartyItems = (0, import_react35.useMemo)(
51060
+ const alibabaItems = (0, import_react36.useMemo)(() => ALIBABA_PROVIDERS.map(providerToItem), []);
51061
+ const thirdPartyItems = (0, import_react36.useMemo)(
50402
51062
  () => THIRD_PARTY_PROVIDERS.map(providerToItem),
50403
51063
  []
50404
51064
  );
@@ -50412,7 +51072,7 @@ function AuthDialogFlow({
50412
51072
  const builtinIds = new Set(getDefaultModelIds(providerConfig));
50413
51073
  return saved.models.map((m3) => m3.id).filter((id) => !builtinIds.has(id));
50414
51074
  }, "getExistingModelIds");
50415
- const handleProviderSelect = (0, import_react35.useCallback)(
51075
+ const handleProviderSelect = (0, import_react36.useCallback)(
50416
51076
  (providerId) => {
50417
51077
  clearErrors();
50418
51078
  const providerConfig = findProviderById(providerId);
@@ -50438,12 +51098,12 @@ function AuthDialogFlow({
50438
51098
  contentGenConfig?.baseUrl,
50439
51099
  contentGenConfig?.apiKeyEnvKey
50440
51100
  );
50441
- const defaultMainIndex = (0, import_react35.useMemo)(() => {
51101
+ const defaultMainIndex = (0, import_react36.useMemo)(() => {
50442
51102
  if (matchedProvider?.uiGroup === "third-party") return 1;
50443
51103
  if (matchedProvider?.uiGroup === "custom") return 2;
50444
51104
  return 0;
50445
51105
  }, [matchedProvider]);
50446
- const handleMainSelect = (0, import_react35.useCallback)(
51106
+ const handleMainSelect = (0, import_react36.useCallback)(
50447
51107
  (value) => {
50448
51108
  clearErrors();
50449
51109
  switch (value) {
@@ -50503,13 +51163,17 @@ function AuthDialogFlow({
50503
51163
  }
50504
51164
  });
50505
51165
  const renderer = useRenderer();
50506
- (0, import_react35.useLayoutEffect)(() => {
51166
+ (0, import_react36.useLayoutEffect)(() => {
50507
51167
  const onRaw = /* @__PURE__ */ __name((seq) => {
50508
51168
  if (seq !== "\x1B") return false;
50509
51169
  if (viewLevel !== "main") {
50510
51170
  goBack();
50511
51171
  return true;
50512
51172
  }
51173
+ if (initialError && errorMessage === initialError) {
51174
+ onClose();
51175
+ return true;
51176
+ }
50513
51177
  if (errorMessage) return true;
50514
51178
  if (config.getAuthType() === void 0) {
50515
51179
  setErrorMessage(
@@ -50524,8 +51188,16 @@ function AuthDialogFlow({
50524
51188
  }, "onRaw");
50525
51189
  renderer.addInputHandler(onRaw);
50526
51190
  return () => renderer.removeInputHandler(onRaw);
50527
- }, [renderer, viewLevel, goBack, errorMessage, config, onClose]);
50528
- 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)(() => {
50529
51201
  if (viewLevel !== "provider-setup") {
50530
51202
  return VIEW_TITLES[viewLevel] ?? VIEW_TITLES["main"];
50531
51203
  }
@@ -50565,7 +51237,7 @@ __name(AuthDialogFlow, "AuthDialogFlow");
50565
51237
 
50566
51238
  // packages/cli/src/ui/opentui/dialogs-arena.tsx
50567
51239
  init_esbuild_shims();
50568
- var import_react37 = __toESM(require_react(), 1);
51240
+ var import_react38 = __toESM(require_react(), 1);
50569
51241
  var MODEL_PROVIDERS_DOCUMENTATION_URL = "https://qwenlm.github.io/qwen-code-docs/en/users/configuration/settings/#modelproviders";
50570
51242
  var STATUS_REFRESH_INTERVAL_MS = 2e3;
50571
51243
  var IN_PROCESS_REFRESH_INTERVAL_MS = 1e3;
@@ -50631,7 +51303,7 @@ function ArenaFrame({
50631
51303
  }
50632
51304
  __name(ArenaFrame, "ArenaFrame");
50633
51305
  function ArenaStart({ config, onClose, onFillInput }) {
50634
- const modelItems = (0, import_react37.useMemo)(() => {
51306
+ const modelItems = (0, import_react38.useMemo)(() => {
50635
51307
  const all = config?.getAllConfiguredModels?.() ?? [];
50636
51308
  return all.filter((m3) => !m3.isRuntimeModel && !m3.imageOnly).map((m3) => {
50637
51309
  const token = `${m3.authType}:${m3.id}`;
@@ -50642,9 +51314,9 @@ function ArenaStart({ config, onClose, onFillInput }) {
50642
51314
  };
50643
51315
  });
50644
51316
  }, [config]);
50645
- const [cursor, setCursor] = (0, import_react37.useState)(0);
50646
- const [checked, setChecked] = (0, import_react37.useState)(/* @__PURE__ */ new Set());
50647
- 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);
50648
51320
  const hasDisabledQwenOauth = modelItems.some((m3) => m3.disabled);
50649
51321
  const selectableCount = modelItems.filter((m3) => !m3.disabled).length;
50650
51322
  const needsMoreModels = selectableCount < 2;
@@ -50718,11 +51390,11 @@ __name(agentElapsedMs, "agentElapsedMs");
50718
51390
  function ArenaStatus({ config, onClose }) {
50719
51391
  const manager = config?.getArenaManager?.() ?? null;
50720
51392
  const { width } = useTerminalDimensions();
50721
- const [, setTick] = (0, import_react37.useState)(0);
51393
+ const [, setTick] = (0, import_react38.useState)(0);
50722
51394
  const backend3 = manager?.getBackend();
50723
51395
  const isInProcess = backend3?.type === DISPLAY_MODE.IN_PROCESS;
50724
51396
  const inProcessBackend = isInProcess ? backend3 : null;
50725
- (0, import_react37.useEffect)(() => {
51397
+ (0, import_react38.useEffect)(() => {
50726
51398
  const interval = isInProcess ? IN_PROCESS_REFRESH_INTERVAL_MS : STATUS_REFRESH_INTERVAL_MS;
50727
51399
  const timer = setInterval(() => setTick((t3) => t3 + 1), interval);
50728
51400
  return () => clearInterval(timer);
@@ -50803,7 +51475,7 @@ function ArenaStatus({ config, onClose }) {
50803
51475
  }
50804
51476
  __name(ArenaStatus, "ArenaStatus");
50805
51477
  function ArenaStop({ config, onClose, notify }) {
50806
- const [processing, setProcessing] = (0, import_react37.useState)(false);
51478
+ const [processing, setProcessing] = (0, import_react38.useState)(false);
50807
51479
  const preserveDefault = config?.getAgentsSettings?.().arena?.preserveArtifacts ?? false;
50808
51480
  const items = [
50809
51481
  {
@@ -50817,7 +51489,7 @@ function ArenaStop({ config, onClose, notify }) {
50817
51489
  desc: "Keep worktrees and session files for later inspection"
50818
51490
  }
50819
51491
  ];
50820
- const [sel, setSel] = (0, import_react37.useState)(preserveDefault ? 1 : 0);
51492
+ const [sel, setSel] = (0, import_react38.useState)(preserveDefault ? 1 : 0);
50821
51493
  const runStop = /* @__PURE__ */ __name(async (action) => {
50822
51494
  if (processing) return;
50823
51495
  setProcessing(true);
@@ -50949,17 +51621,17 @@ function AgentDetailedDiff({ result }) {
50949
51621
  __name(AgentDetailedDiff, "AgentDetailedDiff");
50950
51622
  function ArenaSelect({ config, onClose, notify }) {
50951
51623
  const manager = config?.getArenaManager?.() ?? null;
50952
- const agents = (0, import_react37.useMemo)(() => manager?.getAgentStates() ?? [], [manager]);
51624
+ const agents = (0, import_react38.useMemo)(() => manager?.getAgentStates() ?? [], [manager]);
50953
51625
  const result = manager?.getResult();
50954
- const [sel, setSel] = (0, import_react37.useState)(
51626
+ const [sel, setSel] = (0, import_react38.useState)(
50955
51627
  () => Math.max(
50956
51628
  0,
50957
51629
  agents.findIndex((a) => isSuccessStatus(a.status))
50958
51630
  )
50959
51631
  );
50960
- const [showPreview, setShowPreview] = (0, import_react37.useState)(false);
50961
- const [showDetailedDiff, setShowDetailedDiff] = (0, import_react37.useState)(false);
50962
- 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)(
50963
51635
  () => agents.map((agent) => {
50964
51636
  let additions = 0;
50965
51637
  let deletions = 0;
@@ -51128,24 +51800,24 @@ __name(OpenTuiArenaDialog, "OpenTuiArenaDialog");
51128
51800
 
51129
51801
  // packages/cli/src/ui/opentui/dialogs-memory-status.tsx
51130
51802
  init_esbuild_shims();
51131
- var import_react39 = __toESM(require_react(), 1);
51132
- import fs3 from "node:fs";
51133
- 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";
51134
51806
  function resolvePreferredMemoryFile(dir) {
51135
51807
  const filenames = getAllGeminiMdFilenames();
51136
51808
  for (const filename of filenames) {
51137
- const filePath = path4.join(dir, filename);
51809
+ const filePath = path5.join(dir, filename);
51138
51810
  try {
51139
- if (fs3.existsSync(filePath)) return filePath;
51811
+ if (fs4.existsSync(filePath)) return filePath;
51140
51812
  } catch {
51141
51813
  }
51142
51814
  }
51143
- return path4.join(dir, filenames[0] ?? "QWEN.md");
51815
+ return path5.join(dir, filenames[0] ?? "QWEN.md");
51144
51816
  }
51145
51817
  __name(resolvePreferredMemoryFile, "resolvePreferredMemoryFile");
51146
51818
  function useEsc2(onClose) {
51147
51819
  const renderer = useRenderer();
51148
- (0, import_react39.useLayoutEffect)(() => {
51820
+ (0, import_react40.useLayoutEffect)(() => {
51149
51821
  const onRaw = /* @__PURE__ */ __name((seq) => {
51150
51822
  if (seq !== "\x1B") return false;
51151
51823
  onClose();
@@ -51199,7 +51871,7 @@ function OpenTuiMemoryDialog(props) {
51199
51871
  const toggle = /* @__PURE__ */ __name((k3) => readMemoryToggle(mem?.[k3], modes), "toggle");
51200
51872
  const cwd = config?.getWorkingDir?.() ?? process.cwd();
51201
51873
  const filenames = getAllGeminiMdFilenames();
51202
- const userMem = path4.join(
51874
+ const userMem = path5.join(
51203
51875
  Storage.getGlobalQwenDir(),
51204
51876
  filenames[0] ?? "QWEN.md"
51205
51877
  );
@@ -51247,10 +51919,10 @@ __name(OpenTuiStatusLineDialog, "OpenTuiStatusLineDialog");
51247
51919
 
51248
51920
  // packages/cli/src/ui/opentui/dialogs-modes.tsx
51249
51921
  init_esbuild_shims();
51250
- var import_react41 = __toESM(require_react(), 1);
51922
+ var import_react42 = __toESM(require_react(), 1);
51251
51923
  function useEsc3(onClose) {
51252
51924
  const renderer = useRenderer();
51253
- (0, import_react41.useLayoutEffect)(() => {
51925
+ (0, import_react42.useLayoutEffect)(() => {
51254
51926
  const onRaw = /* @__PURE__ */ __name((seq) => {
51255
51927
  if (seq !== "\x1B") return false;
51256
51928
  onClose();
@@ -51322,7 +51994,7 @@ function OpenTuiApprovalModeDialog(props) {
51322
51994
  const { config, settings, onClose, onApprovalModeChanged } = props;
51323
51995
  const modes = APPROVAL_MODES;
51324
51996
  const current = config?.getApprovalMode?.();
51325
- const [sel, setSel] = (0, import_react41.useState)(
51997
+ const [sel, setSel] = (0, import_react42.useState)(
51326
51998
  Math.max(0, modes.indexOf(current))
51327
51999
  );
51328
52000
  useEsc3(onClose);
@@ -51362,11 +52034,10 @@ var EFFORT_DESC = {
51362
52034
  };
51363
52035
  function OpenTuiEffortDialog(props) {
51364
52036
  const { config, settings, onClose } = props;
51365
- const tiers = REASONING_EFFORT_TIERS;
52037
+ const tiers = config ? [...getReasoningEffortsForConfig(config)] : REASONING_EFFORT_TIERS;
51366
52038
  const currentEffort = config?.getReasoningEffort?.();
51367
- const [sel, setSel] = (0, import_react41.useState)(
51368
- currentEffort ? Math.max(0, tiers.indexOf(currentEffort)) : 0
51369
- );
52039
+ const configuredIndex = currentEffort ? tiers.indexOf(currentEffort) : -1;
52040
+ const [sel, setSel] = (0, import_react42.useState)(Math.max(0, configuredIndex));
51370
52041
  useEsc3(onClose);
51371
52042
  const pick = /* @__PURE__ */ __name(() => {
51372
52043
  const effort = tiers[sel];
@@ -51385,19 +52056,22 @@ function OpenTuiEffortDialog(props) {
51385
52056
  }
51386
52057
  onClose();
51387
52058
  }, "pick");
51388
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell3, { title: "Reasoning Effort", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
51389
- RadioList2,
51390
- {
51391
- items: tiers.map((t3) => ({
51392
- key: t3,
51393
- label: String(t3),
51394
- desc: EFFORT_DESC[String(t3)]
51395
- })),
51396
- selected: sel,
51397
- onMove: (d3) => setSel((s) => Math.min(tiers.length - 1, Math.max(0, s + d3))),
51398
- onPick: pick
51399
- }
51400
- ) });
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
+ ] });
51401
52075
  }
51402
52076
  __name(OpenTuiEffortDialog, "OpenTuiEffortDialog");
51403
52077
  var DEFAULT_STYLE_DESC = "The standard prompt, with no extra style";
@@ -51408,12 +52082,12 @@ function containsStyle(styles, name) {
51408
52082
  __name(containsStyle, "containsStyle");
51409
52083
  function OpenTuiOutputStyleDialog(props) {
51410
52084
  const { config, settings, onClose, notify } = props;
51411
- const [styles, setStyles] = (0, import_react41.useState)();
51412
- const onCloseRef = (0, import_react41.useRef)(onClose);
52085
+ const [styles, setStyles] = (0, import_react42.useState)();
52086
+ const onCloseRef = (0, import_react42.useRef)(onClose);
51413
52087
  onCloseRef.current = onClose;
51414
- const notifyRef = (0, import_react41.useRef)(notify);
52088
+ const notifyRef = (0, import_react42.useRef)(notify);
51415
52089
  notifyRef.current = notify;
51416
- (0, import_react41.useEffect)(() => {
52090
+ (0, import_react42.useEffect)(() => {
51417
52091
  let cancelled = false;
51418
52092
  void loadSessionOutputStyles(config).then(
51419
52093
  (loaded) => {
@@ -51449,8 +52123,8 @@ function OpenTuiOutputStyleDialog(props) {
51449
52123
  style
51450
52124
  }))
51451
52125
  ] : [];
51452
- const [sel, setSel] = (0, import_react41.useState)(0);
51453
- (0, import_react41.useEffect)(() => {
52126
+ const [sel, setSel] = (0, import_react42.useState)(0);
52127
+ (0, import_react42.useEffect)(() => {
51454
52128
  if (!styles) return;
51455
52129
  const wanted = current?.toLowerCase();
51456
52130
  const index = items.findIndex((item) => item.key.toLowerCase() === wanted);
@@ -51483,12 +52157,12 @@ function OpenTuiDialogMount(props) {
51483
52157
  const { request, host, config, settings, commands, onClose, notify } = props;
51484
52158
  const isHelp = request.dialog === "help";
51485
52159
  const dimensions = useTerminalDimensions();
51486
- const [permissions, setPermissions] = (0, import_react43.useState)(
52160
+ const [permissions, setPermissions] = (0, import_react44.useState)(
51487
52161
  () => request.dialog === "permissions" ? buildPermissionsData(config) : null
51488
52162
  );
51489
52163
  const reloadPermissions = /* @__PURE__ */ __name(() => setPermissions(buildPermissionsData(config)), "reloadPermissions");
51490
- const [mcpServers, setMcpServers] = (0, import_react43.useState)([]);
51491
- (0, import_react43.useEffect)(() => {
52164
+ const [mcpServers, setMcpServers] = (0, import_react44.useState)([]);
52165
+ (0, import_react44.useEffect)(() => {
51492
52166
  if (request.dialog !== "mcp") return;
51493
52167
  let alive = true;
51494
52168
  const initial = buildMcpServers(config);
@@ -51512,14 +52186,14 @@ function OpenTuiDialogMount(props) {
51512
52186
  }
51513
52187
  );
51514
52188
  }, "runMcpAction");
51515
- const [extRows, setExtRows] = (0, import_react43.useState)(
52189
+ const [extRows, setExtRows] = (0, import_react44.useState)(
51516
52190
  () => request.dialog === "extensions_manage" ? buildExtensionRows(config) : []
51517
52191
  );
51518
- const [extBusy, setExtBusy] = (0, import_react43.useState)(false);
51519
- const [extStatus, setExtStatus] = (0, import_react43.useState)(
52192
+ const [extBusy, setExtBusy] = (0, import_react44.useState)(false);
52193
+ const [extStatus, setExtStatus] = (0, import_react44.useState)(
51520
52194
  null
51521
52195
  );
51522
- const [extDiscoverFilter, setExtDiscoverFilter] = (0, import_react43.useState)(
52196
+ const [extDiscoverFilter, setExtDiscoverFilter] = (0, import_react44.useState)(
51523
52197
  null
51524
52198
  );
51525
52199
  const reloadExtensions = /* @__PURE__ */ __name(() => setExtRows(buildExtensionRows(config)), "reloadExtensions");
@@ -51572,9 +52246,9 @@ function OpenTuiDialogMount(props) {
51572
52246
  }
51573
52247
  }
51574
52248
  }, "runExtensionAction");
51575
- const [modelError, setModelError] = (0, import_react43.useState)(null);
51576
- const [helpTab, setHelpTab] = (0, import_react43.useState)("commands");
51577
- 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);
51578
52252
  useKeyboard((key) => {
51579
52253
  if (!isHelp) return;
51580
52254
  const { name } = toOriginalKey(key);
@@ -51638,8 +52312,11 @@ function OpenTuiDialogMount(props) {
51638
52312
  onClose();
51639
52313
  return;
51640
52314
  }
51641
- if (props.onSelectSetting) props.onSelectSetting(name, scope);
51642
- 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.`);
51643
52320
  onClose();
51644
52321
  }
51645
52322
  }
@@ -51661,6 +52338,7 @@ function OpenTuiDialogMount(props) {
51661
52338
  {
51662
52339
  config,
51663
52340
  settings,
52341
+ initialError: request.initialError,
51664
52342
  onClose,
51665
52343
  notify
51666
52344
  }
@@ -51896,8 +52574,8 @@ __name(OpenTuiDialogMount, "OpenTuiDialogMount");
51896
52574
 
51897
52575
  // packages/cli/src/ui/opentui/input-prompt.tsx
51898
52576
  init_esbuild_shims();
51899
- var import_react45 = __toESM(require_react(), 1);
51900
- import path5 from "node:path";
52577
+ var import_react46 = __toESM(require_react(), 1);
52578
+ import path6 from "node:path";
51901
52579
 
51902
52580
  // packages/cli/src/ui/opentui/input-history.ts
51903
52581
  init_esbuild_shims();
@@ -52038,12 +52716,17 @@ function OpenTuiInputPrompt(props) {
52038
52716
  onEscapeArmedChange,
52039
52717
  queueLength = 0,
52040
52718
  onPopQueue,
52041
- recentSlashCommands
52719
+ recentSlashCommands,
52720
+ promptSuggestion,
52721
+ onPromptSuggestionDismiss,
52722
+ onPromptSuggestionAbort,
52723
+ shellModeActive = false,
52724
+ onToggleShellMode
52042
52725
  } = props;
52043
52726
  const { width } = useTerminalDimensions();
52044
52727
  const renderer = useRenderer();
52045
- const editorRef = (0, import_react45.useRef)(null);
52046
- (0, import_react45.useEffect)(() => {
52728
+ const editorRef = (0, import_react46.useRef)(null);
52729
+ (0, import_react46.useEffect)(() => {
52047
52730
  if (!props.composerHandle) return;
52048
52731
  props.composerHandle.current = {
52049
52732
  getText: /* @__PURE__ */ __name(() => editorRef.current?.plainText ?? "", "getText"),
@@ -52055,39 +52738,59 @@ function OpenTuiInputPrompt(props) {
52055
52738
  if (props.composerHandle) props.composerHandle.current = null;
52056
52739
  };
52057
52740
  }, [props.composerHandle]);
52058
- const userMessagesRef = (0, import_react45.useRef)(userMessages);
52741
+ const userMessagesRef = (0, import_react46.useRef)(userMessages);
52059
52742
  userMessagesRef.current = userMessages;
52060
- const recentSlashCommandsRef = (0, import_react45.useRef)(recentSlashCommands);
52743
+ const recentSlashCommandsRef = (0, import_react46.useRef)(recentSlashCommands);
52061
52744
  recentSlashCommandsRef.current = recentSlashCommands;
52062
- const historyRef = (0, import_react45.useRef)(null);
52745
+ const historyRef = (0, import_react46.useRef)(null);
52063
52746
  if (!historyRef.current) {
52064
52747
  historyRef.current = new InputHistory(() => userMessagesRef.current);
52065
52748
  }
52066
- const escapeRef = (0, import_react45.useRef)(null);
52749
+ const escapeRef = (0, import_react46.useRef)(null);
52067
52750
  if (!escapeRef.current) {
52068
52751
  escapeRef.current = new EscapeClearModel();
52069
52752
  }
52070
- const [textVersion, setTextVersion] = (0, import_react45.useState)(0);
52071
- const [suggestions, setSuggestions] = (0, import_react45.useState)([]);
52072
- const [activeIndex, setActiveIndex] = (0, import_react45.useState)(0);
52073
- const [loadingSuggestions, setLoadingSuggestions] = (0, import_react45.useState)(false);
52074
- const [escapeArmed, setEscapeArmed] = (0, import_react45.useState)(false);
52075
- const [attachments, setAttachments] = (0, import_react45.useState)([]);
52076
- const completionModeRef = (0, import_react45.useRef)("IDLE" /* IDLE */);
52077
- const historyRestoredTextRef = (0, import_react45.useRef)(null);
52078
- const dismissedUntilChangeRef = (0, import_react45.useRef)(null);
52079
- const fileSearchRef = (0, import_react45.useRef)(null);
52080
- const fileSearchReadyRef = (0, import_react45.useRef)(null);
52081
- const atSearchSeqRef = (0, import_react45.useRef)(0);
52082
- const commandsRef = (0, import_react45.useRef)([]);
52083
- const slashRangeRef = (0, import_react45.useRef)(null);
52084
- const slashSearchSeqRef = (0, import_react45.useRef)(0);
52085
- const suggestionNavigatedRef = (0, import_react45.useRef)(false);
52086
- const pendingPastesRef = (0, import_react45.useRef)(/* @__PURE__ */ new Map());
52087
- const activePlaceholderIdsRef = (0, import_react45.useRef)(/* @__PURE__ */ new Map());
52088
- 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);
52089
52792
  const borderColor = chrome.color ?? C2.accent;
52090
- (0, import_react45.useEffect)(() => {
52793
+ (0, import_react46.useEffect)(() => {
52091
52794
  let cancelled = false;
52092
52795
  loadInteractiveCommands(config ?? null).then((commands) => {
52093
52796
  if (!cancelled) commandsRef.current = commands;
@@ -52098,7 +52801,7 @@ function OpenTuiInputPrompt(props) {
52098
52801
  };
52099
52802
  }, [config]);
52100
52803
  const projectRoot = config?.getTargetDir() ?? process.cwd();
52101
- const ensureFileSearch = (0, import_react45.useCallback)(() => {
52804
+ const ensureFileSearch = (0, import_react46.useCallback)(() => {
52102
52805
  if (fileSearchReadyRef.current) return fileSearchReadyRef.current;
52103
52806
  const searcher = FileSearchFactory.create({
52104
52807
  projectRoot,
@@ -52118,7 +52821,7 @@ function OpenTuiInputPrompt(props) {
52118
52821
  });
52119
52822
  return fileSearchReadyRef.current;
52120
52823
  }, [config, projectRoot]);
52121
- (0, import_react45.useEffect)(
52824
+ (0, import_react46.useEffect)(
52122
52825
  () => () => {
52123
52826
  void fileSearchRef.current?.dispose?.();
52124
52827
  fileSearchRef.current = null;
@@ -52126,7 +52829,7 @@ function OpenTuiInputPrompt(props) {
52126
52829
  },
52127
52830
  []
52128
52831
  );
52129
- const currentCompletionTarget = (0, import_react45.useCallback)(() => {
52832
+ const currentCompletionTarget = (0, import_react46.useCallback)(() => {
52130
52833
  const el = editorRef.current;
52131
52834
  if (!el) return null;
52132
52835
  const text = el.plainText;
@@ -52141,7 +52844,7 @@ function OpenTuiInputPrompt(props) {
52141
52844
  commandsRef.current
52142
52845
  );
52143
52846
  }, []);
52144
- const refreshCompletion = (0, import_react45.useCallback)(() => {
52847
+ const refreshCompletion = (0, import_react46.useCallback)(() => {
52145
52848
  const el = editorRef.current;
52146
52849
  if (!el) return;
52147
52850
  const text = el.plainText;
@@ -52216,7 +52919,7 @@ function OpenTuiInputPrompt(props) {
52216
52919
  }
52217
52920
  });
52218
52921
  }, [ensureFileSearch, config, currentCompletionTarget]);
52219
- (0, import_react45.useEffect)(() => {
52922
+ (0, import_react46.useEffect)(() => {
52220
52923
  const el = editorRef.current;
52221
52924
  if (!el || textVersion === 0) return;
52222
52925
  if (historyRestoredTextRef.current !== null && el.plainText !== historyRestoredTextRef.current) {
@@ -52224,10 +52927,10 @@ function OpenTuiInputPrompt(props) {
52224
52927
  }
52225
52928
  refreshCompletion();
52226
52929
  }, [textVersion, refreshCompletion]);
52227
- (0, import_react45.useEffect)(() => {
52930
+ (0, import_react46.useEffect)(() => {
52228
52931
  refreshCompletion();
52229
52932
  }, [recentSlashCommands, refreshCompletion]);
52230
- const applyTextToEditor = (0, import_react45.useCallback)((line, cursorCol) => {
52933
+ const applyTextToEditor = (0, import_react46.useCallback)((line, cursorCol) => {
52231
52934
  const el = editorRef.current;
52232
52935
  if (!el) return;
52233
52936
  const cursor = el.logicalCursor;
@@ -52241,7 +52944,7 @@ function OpenTuiInputPrompt(props) {
52241
52944
  }
52242
52945
  setTextVersion((v3) => v3 + 1);
52243
52946
  }, []);
52244
- const acceptSuggestion = (0, import_react45.useCallback)(
52947
+ const acceptSuggestion = (0, import_react46.useCallback)(
52245
52948
  (index, viaEnter) => {
52246
52949
  const el = editorRef.current;
52247
52950
  const suggestion = suggestions[index];
@@ -52276,6 +52979,8 @@ function OpenTuiInputPrompt(props) {
52276
52979
  setSuggestions([]);
52277
52980
  setAttachments([]);
52278
52981
  onSubmit(finalText, images.length > 0 ? images : void 0);
52982
+ dismissFollowup();
52983
+ onPromptSuggestionDismiss?.();
52279
52984
  return;
52280
52985
  }
52281
52986
  const apply = /* @__PURE__ */ __name(() => {
@@ -52291,10 +52996,12 @@ function OpenTuiInputPrompt(props) {
52291
52996
  applyTextToEditor,
52292
52997
  onSubmit,
52293
52998
  attachments,
52294
- currentCompletionTarget
52999
+ currentCompletionTarget,
53000
+ dismissFollowup,
53001
+ onPromptSuggestionDismiss
52295
53002
  ]
52296
53003
  );
52297
- const handleClipboardImage = (0, import_react45.useCallback)(async () => {
53004
+ const handleClipboardImage = (0, import_react46.useCallback)(async () => {
52298
53005
  try {
52299
53006
  if (!await clipboardHasImage()) return;
52300
53007
  const imagePath = await saveClipboardImage(Storage.getGlobalTempDir());
@@ -52306,13 +53013,13 @@ function OpenTuiInputPrompt(props) {
52306
53013
  {
52307
53014
  id: `${Date.now()}-${prev.length}`,
52308
53015
  path: imagePath,
52309
- filename: path5.basename(imagePath)
53016
+ filename: path6.basename(imagePath)
52310
53017
  }
52311
53018
  ]);
52312
53019
  } catch {
52313
53020
  }
52314
53021
  }, []);
52315
- (0, import_react45.useLayoutEffect)(() => {
53022
+ (0, import_react46.useLayoutEffect)(() => {
52316
53023
  const onRawInput = /* @__PURE__ */ __name((sequence) => {
52317
53024
  if (!focus) return false;
52318
53025
  if (isDeleteWordBackwardSequence(sequence)) {
@@ -52363,12 +53070,16 @@ function OpenTuiInputPrompt(props) {
52363
53070
  renderer.addInputHandler(onRawInput);
52364
53071
  return () => renderer.removeInputHandler(onRawInput);
52365
53072
  }, [renderer, focus]);
52366
- (0, import_react45.useLayoutEffect)(() => {
53073
+ (0, import_react46.useLayoutEffect)(() => {
52367
53074
  const onPaste = /* @__PURE__ */ __name((event) => {
52368
53075
  if (!focus) return;
52369
53076
  const el = editorRef.current;
52370
53077
  if (!el) return;
52371
53078
  const pasted = normalizePastedText(decodePasteBytes(event.bytes));
53079
+ if (el.plainText.length === 0 && availableSuggestion) {
53080
+ dismissFollowup();
53081
+ onPromptSuggestionDismiss?.();
53082
+ }
52372
53083
  if (!isLargePaste(pasted)) return;
52373
53084
  event.preventDefault();
52374
53085
  const charCount = [...pasted].length;
@@ -52384,7 +53095,15 @@ function OpenTuiInputPrompt(props) {
52384
53095
  return () => {
52385
53096
  renderer.keyInput.off("paste", onPaste);
52386
53097
  };
52387
- }, [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
+ ]);
52388
53107
  useKeyboard((key) => {
52389
53108
  if (!focus) return;
52390
53109
  const el = editorRef.current;
@@ -52409,6 +53128,14 @@ function OpenTuiInputPrompt(props) {
52409
53128
  acceptSuggestion(activeIndex, true);
52410
53129
  return;
52411
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
+ }
52412
53139
  const decision = decideSubmit(
52413
53140
  el.plainText,
52414
53141
  displayOffsetToCodePointIndex(el.plainText, el.cursorOffset)
@@ -52442,6 +53169,8 @@ function OpenTuiInputPrompt(props) {
52442
53169
  setSuggestions([]);
52443
53170
  setLoadingSuggestions(false);
52444
53171
  onSubmit(finalText, images.length > 0 ? images : void 0);
53172
+ dismissFollowup();
53173
+ onPromptSuggestionDismiss?.();
52445
53174
  key.preventDefault();
52446
53175
  return;
52447
53176
  }
@@ -52456,7 +53185,17 @@ function OpenTuiInputPrompt(props) {
52456
53185
  key.preventDefault();
52457
53186
  return;
52458
53187
  }
53188
+ if (key.sequence === "!" && key.eventType !== "release" && el.plainText.length === 0 && suggestions.length === 0 && onToggleShellMode) {
53189
+ onToggleShellMode();
53190
+ key.preventDefault();
53191
+ return;
53192
+ }
52459
53193
  if (isPrintableKeyInput(key)) {
53194
+ if (el.plainText.length === 0 && availableSuggestion) {
53195
+ recordFollowupKeystroke();
53196
+ dismissFollowup();
53197
+ onPromptSuggestionAbort?.();
53198
+ }
52460
53199
  el.insertText(key.sequence);
52461
53200
  setTextVersion((v3) => v3 + 1);
52462
53201
  key.preventDefault();
@@ -52472,6 +53211,11 @@ function OpenTuiInputPrompt(props) {
52472
53211
  }
52473
53212
  if (key.name === "escape") {
52474
53213
  key.preventDefault();
53214
+ if (shellModeActive) {
53215
+ onToggleShellMode?.();
53216
+ if (streaming) onInterrupt?.();
53217
+ return;
53218
+ }
52475
53219
  if (streaming) {
52476
53220
  onInterrupt?.();
52477
53221
  return;
@@ -52508,6 +53252,7 @@ ${current}` : popped);
52508
53252
  }
52509
53253
  const navigationUp = key.name === "up" && !key.shift && !key.ctrl || key.name === "p" && !!key.ctrl;
52510
53254
  const navigationDown = key.name === "down" && !key.shift && !key.ctrl || key.name === "n" && !!key.ctrl;
53255
+ const historyNavActive = !shellModeActive;
52511
53256
  const showing = suggestions.length > 0;
52512
53257
  if (showing && (navigationUp || navigationDown)) {
52513
53258
  key.preventDefault();
@@ -52525,7 +53270,19 @@ ${current}` : popped);
52525
53270
  acceptSuggestion(activeIndex, false);
52526
53271
  return;
52527
53272
  }
52528
- 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) {
52529
53286
  const topCursor = el.logicalCursor;
52530
53287
  if (topCursor.row === 0 && topCursor.col === 0) {
52531
53288
  const popped = onPopQueue?.();
@@ -52539,7 +53296,7 @@ ${current}` : popped);
52539
53296
  }
52540
53297
  }
52541
53298
  }
52542
- if (navigationUp) {
53299
+ if (historyNavActive && navigationUp) {
52543
53300
  const cursor = el.logicalCursor;
52544
53301
  const decision = historyUpDecision(
52545
53302
  historyRef.current,
@@ -52563,7 +53320,7 @@ ${current}` : popped);
52563
53320
  setTextVersion((v3) => v3 + 1);
52564
53321
  return;
52565
53322
  }
52566
- if (navigationDown) {
53323
+ if (historyNavActive && navigationDown) {
52567
53324
  const cursor = el.logicalCursor;
52568
53325
  const lastLine = el.plainText.split("\n").pop() ?? "";
52569
53326
  const decision = historyDownDecision(
@@ -52588,45 +53345,11 @@ ${current}` : popped);
52588
53345
  return;
52589
53346
  }
52590
53347
  });
52591
- const handleSubmit = (0, import_react45.useCallback)(() => {
52592
- const el = editorRef.current;
52593
- if (!el) return;
52594
- const text = el.plainText;
52595
- const decision = decideSubmit(
52596
- text,
52597
- displayOffsetToCodePointIndex(text, el.cursorOffset)
52598
- );
52599
- if (decision.kind === "noop") return;
52600
- if (decision.kind === "newline-continuation") {
52601
- el.deleteCharBackward();
52602
- el.newLine();
52603
- setTextVersion((v3) => v3 + 1);
52604
- return;
52605
- }
52606
- let finalText = decision.text.trim();
52607
- if (pendingPastesRef.current.size > 0) {
52608
- finalText = expandPendingPastePlaceholders(
52609
- finalText,
52610
- pendingPastesRef.current
52611
- );
52612
- pendingPastesRef.current.clear();
52613
- activePlaceholderIdsRef.current.clear();
52614
- }
52615
- const images = attachments.map((a) => a.path);
52616
- el.clear();
52617
- setTextVersion((v3) => v3 + 1);
52618
- historyRef.current?.reset();
52619
- historyRestoredTextRef.current = null;
52620
- setSuggestions([]);
52621
- setLoadingSuggestions(false);
52622
- setAttachments([]);
52623
- onSubmit(finalText, images.length > 0 ? images : void 0);
52624
- }, [onSubmit, attachments]);
52625
- (0, import_react45.useEffect)(() => {
53348
+ (0, import_react46.useEffect)(() => {
52626
53349
  const el = editorRef.current;
52627
53350
  if (el) el.textColor = C2.text;
52628
53351
  }, []);
52629
- (0, import_react45.useEffect)(() => {
53352
+ (0, import_react46.useEffect)(() => {
52630
53353
  const el = editorRef.current;
52631
53354
  if (el) {
52632
53355
  el.keyBindings = [
@@ -52679,14 +53402,13 @@ ${current}` : popped);
52679
53402
  flexGrow: 1,
52680
53403
  minHeight: 1,
52681
53404
  maxHeight: 8,
52682
- placeholder,
53405
+ placeholder: availableSuggestion ?? placeholder,
52683
53406
  placeholderColor: C2.dim,
52684
53407
  textColor: C2.text,
52685
53408
  cursorColor: C2.accent,
52686
53409
  selectionBg: C2.selectionBg,
52687
53410
  selectionFg: C2.selectionFg,
52688
53411
  wrapMode: "char",
52689
- onSubmit: handleSubmit,
52690
53412
  onContentChange: () => setTextVersion((v3) => v3 + 1),
52691
53413
  onCursorChange: () => setTextVersion((v3) => v3 + 1),
52692
53414
  keyBindings: [
@@ -52744,7 +53466,7 @@ __name(OpenTuiInputPrompt, "OpenTuiInputPrompt");
52744
53466
 
52745
53467
  // packages/cli/src/ui/opentui/dialogs-confirm.tsx
52746
53468
  init_esbuild_shims();
52747
- var import_react47 = __toESM(require_react(), 1);
53469
+ var import_react48 = __toESM(require_react(), 1);
52748
53470
 
52749
53471
  // packages/cli/src/ui/opentui/diff-render.ts
52750
53472
  init_esbuild_shims();
@@ -52840,279 +53562,9 @@ function renderDiffBody(fileDiff) {
52840
53562
  }
52841
53563
  __name(renderDiffBody, "renderDiffBody");
52842
53564
 
52843
- // packages/cli/src/ui/opentui/messages.tsx
52844
- init_esbuild_shims();
52845
- var TOOL_STATUS = {
52846
- SUCCESS: "\u2713",
52847
- PENDING: "o",
52848
- EXECUTING: "\u22B7",
52849
- CONFIRMING: "?",
52850
- CANCELED: "-",
52851
- ERROR: "x"
52852
- };
52853
- var MESSAGE_ICON = {
52854
- DIAMOND: "\u25C6",
52855
- THEREFORE: "\u2234",
52856
- BECAUSE: "\u2235",
52857
- CIRCLE_FILLED: "\u25CF"
52858
- };
52859
- var STATUS_INDICATOR_WIDTH = 2;
52860
- var selectionProps = /* @__PURE__ */ __name(() => ({
52861
- selectionBg: C2.selectionBg,
52862
- selectionFg: C2.selectionFg
52863
- }), "selectionProps");
52864
- var STRIKETHROUGH_ATTR = 128;
52865
- var TODO_STATUS_ICONS = {
52866
- pending: ICON.CIRCLE_EMPTY,
52867
- in_progress: ICON.CIRCLE_LEFT_HALF,
52868
- completed: ICON.CIRCLE_FILLED
52869
- };
52870
- var MAX_RESULT_DISPLAY_CHARACTERS = 1e6;
52871
- function maxHistoryItemRows(terminalHeight) {
52872
- return Math.max(Math.floor(terminalHeight) * 4, 100);
52873
- }
52874
- __name(maxHistoryItemRows, "maxHistoryItemRows");
52875
- function truncateResultDisplayChars(text) {
52876
- return text.length > MAX_RESULT_DISPLAY_CHARACTERS ? "..." + text.slice(-MAX_RESULT_DISPLAY_CHARACTERS) : text;
52877
- }
52878
- __name(truncateResultDisplayChars, "truncateResultDisplayChars");
52879
- function tailWindow(lines, maxRows) {
52880
- const target = Math.max(Math.round(maxRows), 2);
52881
- if (lines.length <= target) return { visible: lines, hiddenCount: 0 };
52882
- const visibleContentHeight = target - 1;
52883
- return {
52884
- visible: lines.slice(lines.length - visibleContentHeight),
52885
- hiddenCount: lines.length - visibleContentHeight
52886
- };
52887
- }
52888
- __name(tailWindow, "tailWindow");
52889
- function hiddenLinesLabel(hiddenCount) {
52890
- return `... first ${hiddenCount} line${hiddenCount === 1 ? "" : "s"} hidden ...`;
52891
- }
52892
- __name(hiddenLinesLabel, "hiddenLinesLabel");
52893
- function toolCardName(rawName) {
52894
- return TOOL_DISPLAY_BY_NAME[rawName] ?? rawName;
52895
- }
52896
- __name(toolCardName, "toolCardName");
52897
- var GENERIC_TOOL_SUMMARIES = /* @__PURE__ */ new Set([
52898
- "ok",
52899
- "error",
52900
- "cancelled",
52901
- "canceled",
52902
- "interrupted",
52903
- "skipped"
52904
- ]);
52905
- function toolCardSummarySuffix(done, summary) {
52906
- if (!done || !summary || GENERIC_TOOL_SUMMARIES.has(summary)) return "";
52907
- return ` \xB7 ${summary}`;
52908
- }
52909
- __name(toolCardSummarySuffix, "toolCardSummarySuffix");
52910
- function toolCardText(v3) {
52911
- return sanitizeMultilineForDisplay(v3.replace(/\s*\n\s*/g, " ").trim());
52912
- }
52913
- __name(toolCardText, "toolCardText");
52914
- function toolCardDescription(rawName, args) {
52915
- let parsed = {};
52916
- try {
52917
- parsed = JSON.parse(args ?? "{}");
52918
- } catch {
52919
- return "";
52920
- }
52921
- const str = /* @__PURE__ */ __name((v3) => typeof v3 === "string" && v3.length > 0 ? v3 : void 0, "str");
52922
- const oneLine = toolCardText;
52923
- switch (rawName) {
52924
- case "run_shell_command": {
52925
- const cmd = str(parsed["command"] ?? parsed["cmd"]);
52926
- if (!cmd) return "";
52927
- const desc = str(parsed["description"]);
52928
- return desc ? `${oneLine(cmd)} (${oneLine(desc)})` : oneLine(cmd);
52929
- }
52930
- case "read_file":
52931
- case "write_file":
52932
- case "edit":
52933
- case "notebook_edit": {
52934
- const p2 = str(
52935
- parsed["file_path"] ?? parsed["path"] ?? parsed["filePath"]
52936
- );
52937
- return p2 ? oneLine(p2) : "";
52938
- }
52939
- case "list_directory":
52940
- case "glob": {
52941
- const p2 = str(parsed["path"] ?? parsed["dir"] ?? parsed["pattern"]);
52942
- return p2 ? oneLine(p2) : "";
52943
- }
52944
- case "grep_search": {
52945
- const pat = str(parsed["pattern"]);
52946
- return pat ? oneLine(pat) : "";
52947
- }
52948
- default:
52949
- return "";
52950
- }
52951
- }
52952
- __name(toolCardDescription, "toolCardDescription");
52953
- function userMessageMeta() {
52954
- return { glyph: ">", color: C2.purple };
52955
- }
52956
- __name(userMessageMeta, "userMessageMeta");
52957
- function assistantMessageMeta() {
52958
- return { glyph: MESSAGE_ICON.DIAMOND, color: C2.purple };
52959
- }
52960
- __name(assistantMessageMeta, "assistantMessageMeta");
52961
- function thinkingMeta(done, expanded, clickable) {
52962
- const expandHint = clickable ? "(click or ctrl+o to expand)" : "(ctrl+o to expand)";
52963
- if (!done) {
52964
- return {
52965
- icon: MESSAGE_ICON.BECAUSE,
52966
- label: "Thinking\u2026",
52967
- hint: "",
52968
- color: C2.dim,
52969
- collapsed: false
52970
- };
52971
- }
52972
- if (!expanded) {
52973
- return {
52974
- icon: MESSAGE_ICON.THEREFORE,
52975
- label: "Thought",
52976
- hint: expandHint,
52977
- color: C2.dim,
52978
- collapsed: true
52979
- };
52980
- }
52981
- return {
52982
- icon: MESSAGE_ICON.THEREFORE,
52983
- label: "Thought",
52984
- hint: "(ctrl+o to collapse)",
52985
- color: C2.dim,
52986
- collapsed: false
52987
- };
52988
- }
52989
- __name(thinkingMeta, "thinkingMeta");
52990
- function toolStatusMeta(item) {
52991
- if (item.confirm === "pending" && !item.done) {
52992
- return {
52993
- glyph: TOOL_STATUS.CONFIRMING,
52994
- color: C2.yellow,
52995
- strikethrough: false
52996
- };
52997
- }
52998
- if (!item.done) {
52999
- return {
53000
- glyph: TOOL_STATUS.EXECUTING,
53001
- color: C2.text,
53002
- strikethrough: false
53003
- };
53004
- }
53005
- if (item.success) {
53006
- return { glyph: TOOL_STATUS.SUCCESS, color: C2.green, strikethrough: false };
53007
- }
53008
- const canceled = item.summary === "interrupted" || item.summary === "canceled" || item.summary === "cancelled";
53009
- if (canceled) {
53010
- return { glyph: TOOL_STATUS.CANCELED, color: C2.text, strikethrough: true };
53011
- }
53012
- return { glyph: TOOL_STATUS.ERROR, color: C2.red, strikethrough: false };
53013
- }
53014
- __name(toolStatusMeta, "toolStatusMeta");
53015
- function TodoRows({ todos }) {
53016
- if (todos.length === 0) {
53017
- return null;
53018
- }
53019
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexDirection: "column", children: todos.map((todo) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TodoItemRow, { todo }, todo.id)) });
53020
- }
53021
- __name(TodoRows, "TodoRows");
53022
- function TodoItemRow({ todo }) {
53023
- const statusIcon = TODO_STATUS_ICONS[todo.status];
53024
- const isCompleted = todo.status === "completed";
53025
- const isInProgress = todo.status === "in_progress";
53026
- const itemColor = isCompleted ? C2.text : isInProgress ? C2.green : C2.text;
53027
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", minHeight: 1, children: [
53028
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { width: 3, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: itemColor, ...selectionProps(), children: statusIcon }) }),
53029
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
53030
- "text",
53031
- {
53032
- fg: itemColor,
53033
- attributes: isCompleted ? STRIKETHROUGH_ATTR : 0,
53034
- ...selectionProps(),
53035
- children: todo.content
53036
- }
53037
- ) })
53038
- ] });
53039
- }
53040
- __name(TodoItemRow, "TodoItemRow");
53041
- var ANSI_DEFAULT_HEIGHT = 24;
53042
- function truncateTokenLine(line, maxWidth) {
53043
- if (maxWidth <= 0) return [];
53044
- let width = 0;
53045
- const kept = [];
53046
- for (const token of line) {
53047
- const tokenWidth = getCachedStringWidth(token.text);
53048
- if (width + tokenWidth <= maxWidth) {
53049
- if (tokenWidth > 0 || kept.length === 0) kept.push(token);
53050
- width += tokenWidth;
53051
- continue;
53052
- }
53053
- let partial = "";
53054
- for (const cp of toCodePoints(token.text)) {
53055
- const cpWidth = getCachedStringWidth(cp);
53056
- if (width + cpWidth > maxWidth) break;
53057
- partial += cp;
53058
- width += cpWidth;
53059
- }
53060
- if (partial) kept.push({ ...token, text: partial });
53061
- break;
53062
- }
53063
- return kept;
53064
- }
53065
- __name(truncateTokenLine, "truncateTokenLine");
53066
- function ansiTokenProps(token) {
53067
- const fg2 = token.inverse ? token.bg : token.fg;
53068
- const bg2 = token.inverse ? token.fg : token.bg;
53069
- return {
53070
- fg: fg2 || void 0,
53071
- bg: bg2 || void 0,
53072
- attributes: (token.bold ? 1 : 0) | (token.dim ? 2 : 0) | (token.italic ? 4 : 0) | (token.underline ? 8 : 0)
53073
- };
53074
- }
53075
- __name(ansiTokenProps, "ansiTokenProps");
53076
- function AnsiRows({
53077
- grid,
53078
- maxWidth,
53079
- totalLines,
53080
- totalBytes
53081
- }) {
53082
- const windowed = tailWindow(grid, ANSI_DEFAULT_HEIGHT);
53083
- const stats = [];
53084
- if (totalLines && totalLines > ANSI_DEFAULT_HEIGHT) {
53085
- stats.push(`+${totalLines - ANSI_DEFAULT_HEIGHT} lines`);
53086
- }
53087
- if (totalBytes && totalBytes > 0) {
53088
- stats.push(formatMemoryUsage(totalBytes));
53089
- }
53090
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
53091
- windowed.hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, ...selectionProps(), children: hiddenLinesLabel(windowed.hiddenCount) }),
53092
- windowed.visible.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("box", { flexDirection: "row", children: truncateTokenLine(line, maxWidth).map((token, j3) => {
53093
- const style = ansiTokenProps(token);
53094
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
53095
- "text",
53096
- {
53097
- fg: style.fg ?? C2.text,
53098
- bg: style.bg,
53099
- attributes: style.attributes,
53100
- ...selectionProps(),
53101
- children: token.text
53102
- },
53103
- `${j3}`
53104
- );
53105
- }) }, `${i}`)),
53106
- 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: [
53107
- i > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { children: " " }),
53108
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, ...selectionProps(), children: part })
53109
- ] }, `${i}`)) })
53110
- ] });
53111
- }
53112
- __name(AnsiRows, "AnsiRows");
53113
-
53114
53565
  // packages/cli/src/ui/opentui/dialogs-confirm.tsx
53115
53566
  var MAX_BODY_ROWS = 20;
53567
+ var EXPANDED_BODY_RESERVE_ROWS = 20;
53116
53568
  function buildOutcomeOptions(details) {
53117
53569
  const options = [
53118
53570
  { label: t("Yes, allow once"), value: "proceed_once" /* ProceedOnce */ }
@@ -53135,7 +53587,7 @@ function buildOutcomeOptions(details) {
53135
53587
  }
53136
53588
  __name(buildOutcomeOptions, "buildOutcomeOptions");
53137
53589
  function DiffBody({ fileDiff }) {
53138
- const lines = (0, import_react47.useMemo)(() => renderDiffBody(fileDiff), [fileDiff]);
53590
+ const lines = (0, import_react48.useMemo)(() => renderDiffBody(fileDiff), [fileDiff]);
53139
53591
  const window = tailWindow(lines, MAX_BODY_ROWS);
53140
53592
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
53141
53593
  window.hiddenCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -53150,12 +53602,45 @@ function DiffBody({ fileDiff }) {
53150
53602
  }
53151
53603
  __name(DiffBody, "DiffBody");
53152
53604
  function TextBody({ text }) {
53153
- const rows = (0, import_react47.useMemo)(() => {
53154
- const clean = sanitizeTerminalText(text);
53155
- const window = tailWindow(clean.split("\n"), MAX_BODY_ROWS);
53156
- return window.visible;
53157
- }, [text]);
53158
- 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
+ ] });
53159
53644
  }
53160
53645
  __name(TextBody, "TextBody");
53161
53646
  function ConfirmationBody({
@@ -53175,6 +53660,15 @@ function ConfirmationBody({
53175
53660
  ] });
53176
53661
  case "mcp":
53177
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
+ ) }),
53178
53672
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.accent, attributes: 1, children: sanitizeTerminalText(details.toolDisplayName) }),
53179
53673
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: sanitizeTerminalText(
53180
53674
  `${details.serverName} \xB7 ${details.toolName}`
@@ -53197,7 +53691,7 @@ function ConfirmationBody({
53197
53691
  }
53198
53692
  __name(ConfirmationBody, "ConfirmationBody");
53199
53693
  function OutcomeSelect(props) {
53200
- const items = (0, import_react47.useMemo)(
53694
+ const items = (0, import_react48.useMemo)(
53201
53695
  () => props.options.map((option, index) => ({
53202
53696
  key: `${option.value}-${index}`,
53203
53697
  value: option.value,
@@ -53230,8 +53724,8 @@ __name(OutcomeSelect, "OutcomeSelect");
53230
53724
  function OpenTuiToolConfirmation(props) {
53231
53725
  const { call, onSettled } = props;
53232
53726
  const details = call.confirmationDetails;
53233
- const settledRef = (0, import_react47.useRef)(false);
53234
- const settle = (0, import_react47.useCallback)(
53727
+ const settledRef = (0, import_react48.useRef)(false);
53728
+ const settle = (0, import_react48.useCallback)(
53235
53729
  (outcome, payload) => {
53236
53730
  if (settledRef.current) return;
53237
53731
  settledRef.current = true;
@@ -53285,12 +53779,12 @@ function OpenTuiToolConfirmation(props) {
53285
53779
  __name(OpenTuiToolConfirmation, "OpenTuiToolConfirmation");
53286
53780
  function AskUserQuestionFlow(props) {
53287
53781
  const { details, onAnswered } = props;
53288
- const [index, setIndex] = (0, import_react47.useState)(0);
53289
- const [answers, setAnswers] = (0, import_react47.useState)({});
53290
- 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());
53291
53785
  const question = details.questions[index];
53292
53786
  const isMulti = question?.multiSelect === true;
53293
- const commitQuestion = (0, import_react47.useCallback)(
53787
+ const commitQuestion = (0, import_react48.useCallback)(
53294
53788
  (value) => {
53295
53789
  if (value === void 0) return;
53296
53790
  const nextAnswers = { ...answers, [index]: value };
@@ -53308,7 +53802,7 @@ function AskUserQuestionFlow(props) {
53308
53802
  },
53309
53803
  [answers, index, details.questions.length, onAnswered]
53310
53804
  );
53311
- const items = (0, import_react47.useMemo)(
53805
+ const items = (0, import_react48.useMemo)(
53312
53806
  () => (question?.options ?? []).map((option, i) => ({
53313
53807
  key: `${option.label}-${i}`,
53314
53808
  value: option.label
@@ -53343,7 +53837,7 @@ function AskUserQuestionFlow(props) {
53343
53837
  commitQuestion([...selected].join(", "));
53344
53838
  }
53345
53839
  });
53346
- (0, import_react47.useEffect)(() => {
53840
+ (0, import_react48.useEffect)(() => {
53347
53841
  if (details.questions.length === 0 || !question?.options?.length) {
53348
53842
  onAnswered(null);
53349
53843
  }
@@ -53386,7 +53880,7 @@ function AskUserQuestionFlow(props) {
53386
53880
  __name(AskUserQuestionFlow, "AskUserQuestionFlow");
53387
53881
  function OpenTuiShellConfirmation(props) {
53388
53882
  const { commands, onResolve } = props;
53389
- const options = (0, import_react47.useMemo)(
53883
+ const options = (0, import_react48.useMemo)(
53390
53884
  () => [
53391
53885
  {
53392
53886
  label: t("Yes, allow once"),
@@ -53433,7 +53927,7 @@ function OpenTuiShellConfirmation(props) {
53433
53927
  __name(OpenTuiShellConfirmation, "OpenTuiShellConfirmation");
53434
53928
  function OpenTuiActionConfirmation(props) {
53435
53929
  const { prompt, onResolve } = props;
53436
- const options = (0, import_react47.useMemo)(
53930
+ const options = (0, import_react48.useMemo)(
53437
53931
  () => [
53438
53932
  { key: "yes", value: true },
53439
53933
  { key: "no", value: false }
@@ -53496,17 +53990,83 @@ function OpenTuiApp(props) {
53496
53990
  onPopQueue,
53497
53991
  waitingToolCalls,
53498
53992
  onToolCallSettled,
53499
- onRenderError
53993
+ onRenderError,
53994
+ promptSuggestion,
53995
+ onPromptSuggestionDismiss,
53996
+ onPromptSuggestionAbort
53500
53997
  } = props;
53501
- const [dialog, setDialog] = (0, import_react49.useState)(null);
53502
- const [noticeText, setNoticeText] = (0, import_react49.useState)(null);
53503
- 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)(
53504
54003
  commands ?? []
53505
54004
  );
53506
- const notify = (0, import_react49.useCallback)((text) => setNoticeText(text), []);
53507
- const [modals, setModals] = (0, import_react49.useState)([]);
53508
- const modalSeq = (0, import_react49.useRef)(0);
53509
- 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)(
53510
54070
  () => ({
53511
54071
  presentShell: /* @__PURE__ */ __name((commandsToRun) => new Promise((resolve4) => {
53512
54072
  modalSeq.current += 1;
@@ -53531,14 +54091,14 @@ function OpenTuiApp(props) {
53531
54091
  []
53532
54092
  );
53533
54093
  const activeModal = modals[0] ?? null;
53534
- const closeShellModal = (0, import_react49.useCallback)(
54094
+ const closeShellModal = (0, import_react50.useCallback)(
53535
54095
  (modal, resolution) => {
53536
54096
  setModals((prev) => prev.filter((m3) => m3.id !== modal.id));
53537
54097
  modal.resolve(resolution);
53538
54098
  },
53539
54099
  []
53540
54100
  );
53541
- const closeActionModal = (0, import_react49.useCallback)(
54101
+ const closeActionModal = (0, import_react50.useCallback)(
53542
54102
  (modal, confirmed) => {
53543
54103
  setModals((prev) => prev.filter((m3) => m3.id !== modal.id));
53544
54104
  modal.resolve(confirmed);
@@ -53546,7 +54106,7 @@ function OpenTuiApp(props) {
53546
54106
  []
53547
54107
  );
53548
54108
  const activeToolCall = waitingToolCalls?.[0] ?? null;
53549
- const transcript = (0, import_react49.useMemo)(
54109
+ const transcript = (0, import_react50.useMemo)(
53550
54110
  () => ({
53551
54111
  reset: /* @__PURE__ */ __name((events) => onTranscriptReset?.(events), "reset"),
53552
54112
  // /clear semantics: a fresh transcript — the live turn's reset with an
@@ -53556,7 +54116,7 @@ function OpenTuiApp(props) {
53556
54116
  }),
53557
54117
  [onTranscriptReset, onTranscriptEvent]
53558
54118
  );
53559
- const host = (0, import_react49.useMemo)(
54119
+ const host = (0, import_react50.useMemo)(
53560
54120
  () => new OpenTuiAppHost({
53561
54121
  config,
53562
54122
  settings,
@@ -53585,18 +54145,27 @@ function OpenTuiApp(props) {
53585
54145
  getSessionStats
53586
54146
  ]
53587
54147
  );
53588
- (0, import_react49.useSyncExternalStore)(
53589
- (0, import_react49.useCallback)((cb) => host.subscribe(cb), [host]),
53590
- (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])
53591
54151
  );
53592
- (0, import_react49.useEffect)(() => {
54152
+ (0, import_react50.useEffect)(() => {
53593
54153
  host.setStreaming(!!streaming);
53594
54154
  }, [host, streaming]);
53595
- const gateway = (0, import_react49.useMemo)(() => new OpenTuiSlashGateway(), []);
53596
- const reloadRef = (0, import_react49.useRef)(null);
53597
- const deferredCommandsRef = (0, import_react49.useRef)([]);
53598
- const [deferredRevision, setDeferredRevision] = (0, import_react49.useState)(0);
53599
- (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)(() => {
53600
54169
  const dispatcher = new OpenTuiSlashDispatcher(
53601
54170
  host,
53602
54171
  { config, settings, logger, extensionRefreshState },
@@ -53631,7 +54200,7 @@ function OpenTuiApp(props) {
53631
54200
  commands,
53632
54201
  extensionRefreshState
53633
54202
  ]);
53634
- const applyOutcome = (0, import_react49.useCallback)(
54203
+ const applyOutcome = (0, import_react50.useCallback)(
53635
54204
  (outcome) => {
53636
54205
  switch (outcome.kind) {
53637
54206
  case "handled":
@@ -53655,6 +54224,9 @@ function OpenTuiApp(props) {
53655
54224
  case "quit":
53656
54225
  deferredCommandsRef.current = [];
53657
54226
  onPopQueue?.();
54227
+ for (const controller of shellControllersRef.current) {
54228
+ controller.abort();
54229
+ }
53658
54230
  onInterrupt?.();
53659
54231
  onQuit?.(outcome.messages);
53660
54232
  return;
@@ -53666,18 +54238,31 @@ function OpenTuiApp(props) {
53666
54238
  },
53667
54239
  [onSubmitPrompt, onQuit, onInterrupt, onPopQueue, notify]
53668
54240
  );
53669
- const onSubmit = (0, import_react49.useCallback)(
54241
+ const onSubmit = (0, import_react50.useCallback)(
53670
54242
  async (text, imagePaths) => {
53671
54243
  setNoticeText(null);
53672
54244
  const submission = normalizeQuitSubmission(text);
53673
- if (streaming && await gateway.mustDeferDuringStreaming(submission)) {
53674
- const command = submission.trim();
53675
- deferredCommandsRef.current.push(command);
53676
- setDeferredRevision((revision) => revision + 1);
53677
- notify(
53678
- `Queued ${command} \u2014 it will run when the current response ends.`
53679
- );
53680
- 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
+ }
53681
54266
  }
53682
54267
  const settlement = await gateway.dispatch(submission);
53683
54268
  if (settlement.kind === "rejected") {
@@ -53685,11 +54270,15 @@ function OpenTuiApp(props) {
53685
54270
  return;
53686
54271
  }
53687
54272
  if (settlement.outcome === false) {
54273
+ const query = text.trim();
54274
+ if (shellModeActive && query) {
54275
+ void runShellCommand(query);
54276
+ return;
54277
+ }
53688
54278
  if (!onSubmitPrompt) {
53689
54279
  notify("The live prompt turn is not wired in this shell.");
53690
54280
  return;
53691
54281
  }
53692
- const query = text.trim();
53693
54282
  onSubmitPrompt(query, imagePaths, {
53694
54283
  submittedPrompt: query || void 0
53695
54284
  });
@@ -53697,31 +54286,71 @@ function OpenTuiApp(props) {
53697
54286
  }
53698
54287
  applyOutcome(settlement.outcome);
53699
54288
  },
53700
- [gateway, onSubmitPrompt, applyOutcome, notify, streaming]
54289
+ [
54290
+ gateway,
54291
+ onSubmitPrompt,
54292
+ applyOutcome,
54293
+ notify,
54294
+ streaming,
54295
+ shellModeActive,
54296
+ runShellCommand
54297
+ ]
53701
54298
  );
53702
- (0, import_react49.useEffect)(() => {
54299
+ (0, import_react50.useEffect)(() => {
53703
54300
  if (isExitInProgress()) return;
53704
- if (streaming || dialog || deferredCommandsRef.current.length === 0) {
54301
+ if (streaming || dialog || shellControllersRef.current.size > 0 || deferredCommandsRef.current.length === 0) {
53705
54302
  return;
53706
54303
  }
54304
+ if (drainingRef.current) return;
54305
+ drainingRef.current = true;
53707
54306
  const pending = deferredCommandsRef.current;
53708
54307
  deferredCommandsRef.current = [];
53709
54308
  void (async () => {
53710
- for (const [i, command] of pending.entries()) {
53711
- if (isExitInProgress()) return;
53712
- const settlement = await gateway.dispatch(command);
53713
- if (settlement.kind === "rejected") {
53714
- notify(settlement.reason);
53715
- continue;
53716
- }
53717
- if (settlement.outcome === false) continue;
53718
- const outcome = settlement.outcome;
53719
- applyOutcome(outcome);
53720
- const holdsUi = outcome.kind === "open_dialog" || outcome.kind === "submit_prompt" && !!onSubmitPrompt;
53721
- if (holdsUi && i + 1 < pending.length) {
53722
- deferredCommandsRef.current.unshift(...pending.slice(i + 1));
53723
- 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
+ }
53724
54350
  }
54351
+ } finally {
54352
+ drainingRef.current = false;
54353
+ if (!paused) setDeferredRevision((revision) => revision + 1);
53725
54354
  }
53726
54355
  })();
53727
54356
  }, [
@@ -53731,9 +54360,10 @@ function OpenTuiApp(props) {
53731
54360
  gateway,
53732
54361
  notify,
53733
54362
  applyOutcome,
53734
- onSubmitPrompt
54363
+ onSubmitPrompt,
54364
+ runShellCommand
53735
54365
  ]);
53736
- const userMessages = (0, import_react49.useMemo)(
54366
+ const userMessages = (0, import_react50.useMemo)(
53737
54367
  () => host.getHistory().filter((item) => item.type === "user").map((item) => item.text ?? ""),
53738
54368
  // eslint-disable-next-line react-hooks/exhaustive-deps
53739
54369
  [host, host.getVersion()]
@@ -53778,6 +54408,8 @@ function OpenTuiApp(props) {
53778
54408
  commands: commandList,
53779
54409
  onClose: () => setDialog(null),
53780
54410
  notify,
54411
+ fillInput: fillComposer,
54412
+ onSelectSetting: handleSelectSetting,
53781
54413
  onApprovalModeChanged: void 0,
53782
54414
  availableTerminalHeight: props.availableTerminalHeight
53783
54415
  },
@@ -53796,7 +54428,12 @@ function OpenTuiApp(props) {
53796
54428
  approvalMode,
53797
54429
  queueLength,
53798
54430
  onPopQueue,
53799
- composerHandle: props.composerHandle
54431
+ composerHandle: props.composerHandle,
54432
+ promptSuggestion,
54433
+ onPromptSuggestionDismiss,
54434
+ onPromptSuggestionAbort,
54435
+ shellModeActive,
54436
+ onToggleShellMode: toggleShellMode
53800
54437
  }
53801
54438
  )
53802
54439
  ] })
@@ -53805,6 +54442,82 @@ function OpenTuiApp(props) {
53805
54442
  }
53806
54443
  __name(OpenTuiApp, "OpenTuiApp");
53807
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
+
53808
54521
  // packages/cli/src/ui/opentui/opentui-runtime.ts
53809
54522
  init_esbuild_shims();
53810
54523
  var debugLogger3 = createDebugLogger("OPEN_TUI_RUNTIME");
@@ -53933,7 +54646,7 @@ var OpenTuiRuntime = class _OpenTuiRuntime {
53933
54646
 
53934
54647
  // packages/cli/src/ui/opentui/transcript-view.tsx
53935
54648
  init_esbuild_shims();
53936
- var import_react50 = __toESM(require_react(), 1);
54649
+ var import_react53 = __toESM(require_react(), 1);
53937
54650
 
53938
54651
  // packages/cli/src/ui/opentui/live-session-model.ts
53939
54652
  init_esbuild_shims();
@@ -54088,6 +54801,16 @@ function foldLiveEvent(prev, ev) {
54088
54801
  });
54089
54802
  return items;
54090
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
+ }
54091
54814
  case "task-start":
54092
54815
  if (last?.kind === "assistant" && last.streaming)
54093
54816
  items[items.length - 1] = { ...last, streaming: false };
@@ -54243,6 +54966,48 @@ function foldLiveEvent(prev, ev) {
54243
54966
  items.push({ kind: "stop-hook", id: nid("shk"), message: ev.message });
54244
54967
  return items;
54245
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
+ }
54246
55011
  case "segment-end": {
54247
55012
  if (last?.kind === "assistant" && last.streaming)
54248
55013
  items[items.length - 1] = { ...last, streaming: false };
@@ -54328,6 +55093,13 @@ function describeGoalCard(snapshot, cause) {
54328
55093
  const activeTimeMs = goal.activeTimeMs ?? 0;
54329
55094
  if (activeTimeMs > 0)
54330
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
+ }
54331
55103
  const reason = (goal.status ?? "active") !== "active" || activity === "verifying" ? goal.lastReason?.trim() : void 0;
54332
55104
  return {
54333
55105
  state: "card",
@@ -54965,6 +55737,7 @@ function OpenTuiTranscriptView({
54965
55737
  {
54966
55738
  item,
54967
55739
  maxRows,
55740
+ terminalHeight: availableTerminalHeight,
54968
55741
  width: availableWidth
54969
55742
  },
54970
55743
  item.id
@@ -54974,6 +55747,7 @@ __name(OpenTuiTranscriptView, "OpenTuiTranscriptView");
54974
55747
  function TranscriptItem({
54975
55748
  item,
54976
55749
  maxRows,
55750
+ terminalHeight,
54977
55751
  width
54978
55752
  }) {
54979
55753
  switch (item.kind) {
@@ -54984,7 +55758,15 @@ function TranscriptItem({
54984
55758
  case "thinking":
54985
55759
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThinkingRow, { text: item.text, done: item.done });
54986
55760
  case "tool":
54987
- 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
+ );
54988
55770
  case "task":
54989
55771
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskCard, { item });
54990
55772
  case "image":
@@ -55015,6 +55797,16 @@ function TranscriptItem({
55015
55797
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StopHookRow, { message: item.message });
55016
55798
  case "goal":
55017
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 });
55018
55810
  default: {
55019
55811
  const exhaustive = item;
55020
55812
  return exhaustive;
@@ -55052,7 +55844,7 @@ function AssistantRow({
55052
55844
  }
55053
55845
  __name(AssistantRow, "AssistantRow");
55054
55846
  function ThinkingRow({ text, done }) {
55055
- const [expanded, setExpanded] = (0, import_react50.useState)(false);
55847
+ const [expanded, setExpanded] = (0, import_react53.useState)(false);
55056
55848
  const meta = thinkingMeta(done, expanded, false);
55057
55849
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
55058
55850
  "box",
@@ -55077,11 +55869,19 @@ __name(ThinkingRow, "ThinkingRow");
55077
55869
  function ToolCard({
55078
55870
  item,
55079
55871
  maxRows,
55872
+ terminalHeight,
55080
55873
  width
55081
55874
  }) {
55082
55875
  const status = toolStatusMeta(item);
55083
55876
  const name = toolCardName(item.tool);
55084
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
+ );
55085
55885
  const suffix2 = toolCardSummarySuffix(item.done, item.summary);
55086
55886
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", children: [
55087
55887
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "row", children: [
@@ -55094,9 +55894,10 @@ function ToolCard({
55094
55894
  }
55095
55895
  ) }),
55096
55896
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.text, attributes: status.strikethrough ? 129 : 1, children: name }),
55097
- 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,
55098
55898
  suffix2 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: sanitizeTerminalText(suffix2) }) : null
55099
55899
  ] }),
55900
+ cap.hiddenRows > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.dim, children: hiddenTailLinesLabel(cap.hiddenRows) }),
55100
55901
  item.confirm === "pending" && !item.done ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { fg: C2.yellow, children: " (awaiting approval)" }) : null,
55101
55902
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolCardBody, { item, maxRows, width })
55102
55903
  ] });
@@ -55194,8 +55995,8 @@ function RetryRows({
55194
55995
  delayMs,
55195
55996
  startedAt
55196
55997
  }) {
55197
- const [now, setNow] = (0, import_react50.useState)(() => Date.now());
55198
- (0, import_react50.useEffect)(() => {
55998
+ const [now, setNow] = (0, import_react53.useState)(() => Date.now());
55999
+ (0, import_react53.useEffect)(() => {
55199
56000
  const timer = setInterval(() => setNow(Date.now()), 1e3);
55200
56001
  return () => clearInterval(timer);
55201
56002
  }, []);
@@ -55275,10 +56076,171 @@ function LegacyGoalCard({ legacy }) {
55275
56076
  ] });
55276
56077
  }
55277
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");
55278
56240
 
55279
56241
  // packages/cli/src/ui/opentui/live-turn.ts
55280
56242
  init_esbuild_shims();
55281
- var import_react51 = __toESM(require_react(), 1);
56243
+ var import_react54 = __toESM(require_react(), 1);
55282
56244
  import { readFileSync } from "node:fs";
55283
56245
 
55284
56246
  // packages/cli/src/ui/opentui/live-session.ts
@@ -55305,10 +56267,10 @@ function nextLivePromptId(config) {
55305
56267
  return id;
55306
56268
  }
55307
56269
  __name(nextLivePromptId, "nextLivePromptId");
55308
- function formatTokenCount(n) {
56270
+ function formatTokenCount2(n) {
55309
56271
  return n >= 1e3 ? `${(n / 1e3).toFixed(1)}k` : String(n);
55310
56272
  }
55311
- __name(formatTokenCount, "formatTokenCount");
56273
+ __name(formatTokenCount2, "formatTokenCount");
55312
56274
  function createEventQueue() {
55313
56275
  const buffer = [];
55314
56276
  let wake = null;
@@ -55443,10 +56405,12 @@ async function resolveSteeredPromptParts(config, texts, signal, turnModel) {
55443
56405
  const restore = /* @__PURE__ */ __name(() => ({
55444
56406
  parts: [],
55445
56407
  events: [],
56408
+ recordings: [],
55446
56409
  restore: [...texts]
55447
56410
  }), "restore");
55448
56411
  const events = [];
55449
56412
  const segments = [];
56413
+ const recordings = [];
55450
56414
  for (const message of texts) {
55451
56415
  if (signal.aborted) return restore();
55452
56416
  let resolved = [{ text: message }];
@@ -55497,6 +56461,7 @@ async function resolveSteeredPromptParts(config, texts, signal, turnModel) {
55497
56461
  events.push(imageFormatWarningEvent());
55498
56462
  }
55499
56463
  if (messageParts.length > 0) segments.push(messageParts);
56464
+ recordings.push({ message, parts: messageParts });
55500
56465
  events.push({ type: "user", text: message, sentToModel: false });
55501
56466
  }
55502
56467
  const parts = [];
@@ -55504,16 +56469,29 @@ async function resolveSteeredPromptParts(config, texts, signal, turnModel) {
55504
56469
  if (parts.length > 0) parts.push({ text: "\n\n" });
55505
56470
  parts.push(...segment);
55506
56471
  }
55507
- return { parts, events, restore: [] };
56472
+ return { parts, events, recordings, restore: [] };
55508
56473
  }
55509
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");
55510
56491
  var STARTUP_CHAT_WAIT_MS = 15e3;
55511
56492
  var STARTUP_CHAT_POLL_MS = 100;
55512
56493
  async function* livePromptEvents(config, prompt, signal, options) {
55513
- try {
55514
- await config.initialize();
55515
- } catch {
55516
- }
56494
+ await ensureConfigInitialized(config);
55517
56495
  const client = config.getGeminiClient();
55518
56496
  const chatDeadline = Date.now() + STARTUP_CHAT_WAIT_MS;
55519
56497
  const chatReady = /* @__PURE__ */ __name(() => client.isInitialized() && client.getChat().getGenerationConfig().tools !== void 0, "chatReady");
@@ -55569,6 +56547,23 @@ async function* livePromptEvents(config, prompt, signal, options) {
55569
56547
  if (hasUnsupportedImageFormat(nextPrompt)) {
55570
56548
  yield imageFormatWarningEvent();
55571
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");
55572
56567
  let first = true;
55573
56568
  const waitingSeen = /* @__PURE__ */ new Set();
55574
56569
  for (; ; ) {
@@ -55588,23 +56583,33 @@ async function* livePromptEvents(config, prompt, signal, options) {
55588
56583
  promptId,
55589
56584
  sendOptions
55590
56585
  );
55591
- for await (const ev of stream) {
55592
- if (dbg) {
55593
- try {
55594
- appendFileSync2(
55595
- "/tmp/opentui-events.log",
55596
- `${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}
55597
56594
  `
56595
+ );
56596
+ } catch {
56597
+ }
56598
+ }
56599
+ if (ev.type === "tool_call_request") {
56600
+ pending.push(
56601
+ ev.value
55598
56602
  );
55599
- } catch {
55600
56603
  }
56604
+ for (const neutral of map(ev)) yield neutral;
55601
56605
  }
55602
- if (ev.type === "tool_call_request") {
55603
- pending.push(
55604
- ev.value
55605
- );
55606
- }
55607
- 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();
55608
56613
  }
55609
56614
  if (pending.length === 0 || abort.aborted) return;
55610
56615
  const live = createEventQueue();
@@ -55642,7 +56647,7 @@ async function* livePromptEvents(config, prompt, signal, options) {
55642
56647
  id: callId,
55643
56648
  tools: stats?.totalToolCalls ?? agent.toolCalls?.length ?? 0,
55644
56649
  seconds: Math.round((stats?.totalDurationMs ?? 0) / 100) / 10,
55645
- tokens: formatTokenCount(
56650
+ tokens: formatTokenCount2(
55646
56651
  stats?.totalTokens ?? agent.tokenCount ?? 0
55647
56652
  )
55648
56653
  });
@@ -55677,19 +56682,32 @@ async function* livePromptEvents(config, prompt, signal, options) {
55677
56682
  description: invocation.getDescription()
55678
56683
  });
55679
56684
  }
55680
- if (!options?.onWaitingCall) return;
55681
56685
  const awaiting = new Set(
55682
56686
  calls.filter((c2) => c2.status === "awaiting_approval").map((c2) => c2.request.callId)
55683
56687
  );
55684
56688
  for (const id of waitingSeen) {
55685
- 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
+ }
55686
56698
  }
55687
56699
  for (const c2 of calls) {
55688
56700
  if (c2.status !== "awaiting_approval") continue;
55689
56701
  const callId = c2.request.callId;
55690
56702
  if (waitingSeen.has(callId)) continue;
55691
56703
  waitingSeen.add(callId);
55692
- 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?.({
55693
56711
  callId,
55694
56712
  name: c2.request.name,
55695
56713
  confirmationDetails: c2.confirmationDetails
@@ -55732,6 +56750,12 @@ async function* livePromptEvents(config, prompt, signal, options) {
55732
56750
  };
55733
56751
  if (resp?.responseParts) responseParts.push(...resp.responseParts);
55734
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
+ }
55735
56759
  if (!abort.aborted) {
55736
56760
  const texts = (options?.drainSteering?.() ?? []).filter((text) => text);
55737
56761
  if (texts.length > 0) {
@@ -55741,9 +56765,20 @@ async function* livePromptEvents(config, prompt, signal, options) {
55741
56765
  abort,
55742
56766
  turnModel
55743
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
+ }
55744
56777
  if (steered.restore.length > 0) {
55745
56778
  options?.restoreSteering?.(steered.restore);
55746
56779
  }
56780
+ stashedRecordings = steered.recordings;
56781
+ stashedSteeredTexts = texts;
55747
56782
  for (const ev of steered.events) yield ev;
55748
56783
  responseParts.push(...steered.parts);
55749
56784
  }
@@ -55780,18 +56815,18 @@ var IMAGE_MIME_BY_EXTENSION = {
55780
56815
  function imagePathsToParts(imagePaths) {
55781
56816
  const parts = [];
55782
56817
  const notices = [];
55783
- for (const path6 of imagePaths) {
55784
- const ext = path6.split(".").pop()?.toLowerCase() ?? "";
56818
+ for (const path7 of imagePaths) {
56819
+ const ext = path7.split(".").pop()?.toLowerCase() ?? "";
55785
56820
  const mimeType = IMAGE_MIME_BY_EXTENSION[ext];
55786
56821
  if (!mimeType) {
55787
- notices.push(`Unsupported image type: ${path6}`);
56822
+ notices.push(`Unsupported image type: ${path7}`);
55788
56823
  continue;
55789
56824
  }
55790
56825
  try {
55791
- const data = readFileSync(path6).toString("base64");
56826
+ const data = readFileSync(path7).toString("base64");
55792
56827
  parts.push({ inlineData: { mimeType, data } });
55793
56828
  } catch {
55794
- notices.push(`Could not read image: ${path6}`);
56829
+ notices.push(`Could not read image: ${path7}`);
55795
56830
  }
55796
56831
  }
55797
56832
  return { parts, notices };
@@ -55805,43 +56840,43 @@ function foldBatch(events) {
55805
56840
  __name(foldBatch, "foldBatch");
55806
56841
  function useOpenTuiLiveTurn(options) {
55807
56842
  const { config } = options;
55808
- const [items, setItems] = (0, import_react51.useState)([]);
55809
- const [streaming, setStreaming] = (0, import_react51.useState)(false);
55810
- 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)(
55811
56846
  []
55812
56847
  );
55813
- const queueRef = (0, import_react51.useRef)([]);
55814
- const [queueLength, setQueueLength] = (0, import_react51.useState)(0);
55815
- const abortRef = (0, import_react51.useRef)(null);
55816
- const streamingRef = (0, import_react51.useRef)(false);
55817
- const turnSeqRef = (0, import_react51.useRef)(0);
55818
- 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)([]);
55819
56854
  waitingCallsRef.current = waitingCalls;
55820
- const setBusy = (0, import_react51.useCallback)((busy) => {
56855
+ const setBusy = (0, import_react54.useCallback)((busy) => {
55821
56856
  if (streamingRef.current === busy) return;
55822
56857
  streamingRef.current = busy;
55823
56858
  setStreaming(busy);
55824
56859
  }, []);
55825
- const apply = (0, import_react51.useCallback)((ev) => {
56860
+ const apply = (0, import_react54.useCallback)((ev) => {
55826
56861
  setItems((prev) => foldLiveEvent(prev, ev));
55827
56862
  }, []);
55828
- const pushQueue = (0, import_react51.useCallback)((text) => {
56863
+ const pushQueue = (0, import_react54.useCallback)((text) => {
55829
56864
  queueRef.current.push(text);
55830
56865
  setQueueLength(queueRef.current.length);
55831
56866
  }, []);
55832
- const drainQueue = (0, import_react51.useCallback)(() => {
56867
+ const drainQueue = (0, import_react54.useCallback)(() => {
55833
56868
  const drained = queueRef.current;
55834
56869
  queueRef.current = [];
55835
56870
  setQueueLength(0);
55836
56871
  return drained;
55837
56872
  }, []);
55838
- const restoreQueue = (0, import_react51.useCallback)((texts) => {
56873
+ const restoreQueue = (0, import_react54.useCallback)((texts) => {
55839
56874
  const restored = texts.map((text) => text.trim()).filter(Boolean);
55840
56875
  if (restored.length === 0) return;
55841
56876
  queueRef.current = [...restored, ...queueRef.current];
55842
56877
  setQueueLength(queueRef.current.length);
55843
56878
  }, []);
55844
- const runTurn = (0, import_react51.useCallback)(
56879
+ const runTurn = (0, import_react54.useCallback)(
55845
56880
  async (prompt, promptId, turnOptions) => {
55846
56881
  const seq = ++turnSeqRef.current;
55847
56882
  const abort = new AbortController();
@@ -55865,7 +56900,7 @@ function useOpenTuiLiveTurn(options) {
55865
56900
  if (seq !== turnSeqRef.current) return;
55866
56901
  apply(ev);
55867
56902
  }
55868
- if (seq === turnSeqRef.current) {
56903
+ if (seq === turnSeqRef.current && !abort.signal.aborted) {
55869
56904
  void turnOptions?.onComplete?.().catch(() => {
55870
56905
  });
55871
56906
  }
@@ -55898,7 +56933,7 @@ function useOpenTuiLiveTurn(options) {
55898
56933
  },
55899
56934
  [config, apply, drainQueue, restoreQueue, setBusy]
55900
56935
  );
55901
- const submit = (0, import_react51.useCallback)(
56936
+ const submit = (0, import_react54.useCallback)(
55902
56937
  (content, imagePaths, options2) => {
55903
56938
  const text = typeof content === "string" ? content : collectText(normalizeParts(content));
55904
56939
  if (streamingRef.current) {
@@ -55922,10 +56957,10 @@ function useOpenTuiLiveTurn(options) {
55922
56957
  },
55923
56958
  [config, apply, pushQueue, runTurn]
55924
56959
  );
55925
- const interrupt = (0, import_react51.useCallback)(() => {
56960
+ const interrupt = (0, import_react54.useCallback)(() => {
55926
56961
  abortRef.current?.abort();
55927
56962
  }, []);
55928
- const resetTranscript = (0, import_react51.useCallback)(
56963
+ const resetTranscript = (0, import_react54.useCallback)(
55929
56964
  (events) => {
55930
56965
  turnSeqRef.current += 1;
55931
56966
  const abort = abortRef.current;
@@ -55944,14 +56979,14 @@ function useOpenTuiLiveTurn(options) {
55944
56979
  },
55945
56980
  [setBusy]
55946
56981
  );
55947
- const settleWaitingCall = (0, import_react51.useCallback)((callId) => {
56982
+ const settleWaitingCall = (0, import_react54.useCallback)((callId) => {
55948
56983
  setWaitingCalls((prev) => prev.filter((c2) => c2.callId !== callId));
55949
56984
  }, []);
55950
- const popQueue = (0, import_react51.useCallback)(() => {
56985
+ const popQueue = (0, import_react54.useCallback)(() => {
55951
56986
  if (queueRef.current.length === 0) return null;
55952
- return drainQueue().join("\n");
56987
+ return drainQueue().join("\n\n");
55953
56988
  }, [drainQueue]);
55954
- (0, import_react51.useEffect)(() => () => abortRef.current?.abort(), []);
56989
+ (0, import_react54.useEffect)(() => () => abortRef.current?.abort(), []);
55955
56990
  return {
55956
56991
  items,
55957
56992
  streaming,
@@ -56018,47 +57053,6 @@ function exitGuardHint(key) {
56018
57053
  }
56019
57054
  __name(exitGuardHint, "exitGuardHint");
56020
57055
 
56021
- // packages/cli/src/ui/opentui/early-input.ts
56022
- init_esbuild_shims();
56023
- function decodeCapturedInput(buffer) {
56024
- if (buffer.length === 0) return "";
56025
- const text = buffer.toString("utf8");
56026
- 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, "");
56027
- }
56028
- __name(decodeCapturedInput, "decodeCapturedInput");
56029
- function drainCapturedInputAsText() {
56030
- return decodeCapturedInput(stopAndGetCapturedInput());
56031
- }
56032
- __name(drainCapturedInputAsText, "drainCapturedInputAsText");
56033
- function injectCapturedInput(getText, text, opts = {}) {
56034
- if (text.length === 0) return () => {
56035
- };
56036
- const intervalMs = opts.intervalMs ?? 25;
56037
- const maxAttempts = opts.maxAttempts ?? 40;
56038
- const setTimeoutFn = opts.setTimeoutFn ?? ((fn2, ms) => setTimeout(fn2, ms));
56039
- const clearTimeoutFn = opts.clearTimeoutFn ?? ((handle) => clearTimeout(handle));
56040
- let attempts = 0;
56041
- let timer = null;
56042
- let disposed = false;
56043
- const attempt = /* @__PURE__ */ __name(() => {
56044
- if (disposed) return;
56045
- const handle = getText();
56046
- if (handle) {
56047
- handle.setText(text);
56048
- return;
56049
- }
56050
- attempts += 1;
56051
- if (attempts >= maxAttempts) return;
56052
- timer = setTimeoutFn(attempt, intervalMs);
56053
- }, "attempt");
56054
- timer = setTimeoutFn(attempt, intervalMs);
56055
- return () => {
56056
- disposed = true;
56057
- if (timer !== null) clearTimeoutFn(timer);
56058
- };
56059
- }
56060
- __name(injectCapturedInput, "injectCapturedInput");
56061
-
56062
57056
  // packages/cli/src/ui/opentui/start-opentui-ui.tsx
56063
57057
  var debugLogger4 = createDebugLogger("OPEN_TUI_START");
56064
57058
  function OpenTuiEntryApp({
@@ -56067,36 +57061,44 @@ function OpenTuiEntryApp({
56067
57061
  runtime,
56068
57062
  startupWarnings,
56069
57063
  extensionRefreshState,
56070
- capturedText
57064
+ capturedText,
57065
+ initialDialog
56071
57066
  }) {
56072
57067
  const { width, height } = useTerminalDimensions();
56073
57068
  const { stats, startNewSession } = useSessionStats();
56074
57069
  const logger = useLogger(config.storage, config.getSessionId());
56075
57070
  const live = useOpenTuiLiveTurn({ config });
56076
57071
  const { applyEvent, submit, interrupt, resetTranscript, settleWaitingCall } = live;
56077
- const statsRef = (0, import_react52.useRef)(stats);
56078
- (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)(() => {
56079
57081
  statsRef.current = stats;
56080
57082
  }, [stats]);
56081
- const getSessionStats = (0, import_react52.useCallback)(() => statsRef.current, []);
56082
- const composerHandle = (0, import_react52.useRef)(null);
56083
- (0, import_react52.useEffect)(
56084
- () => 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),
56085
57087
  [capturedText]
56086
57088
  );
56087
- (0, import_react52.useEffect)(() => {
57089
+ (0, import_react55.useEffect)(() => {
56088
57090
  const resumeEvents = resumeEventsFromConfig(config);
56089
57091
  if (resumeEvents) resetTranscript(resumeEvents);
56090
57092
  for (const warning of startupWarnings) {
56091
57093
  applyEvent({ type: "warning", text: warning });
56092
57094
  }
56093
57095
  }, []);
56094
- const [updateNotice, setUpdateNotice] = (0, import_react52.useState)(null);
56095
- const isIdleRef = (0, import_react52.useRef)(true);
56096
- (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)(() => {
56097
57099
  isIdleRef.current = !live.streaming;
56098
57100
  }, [live.streaming]);
56099
- const addUpdateItem = (0, import_react52.useCallback)(
57101
+ const addUpdateItem = (0, import_react55.useCallback)(
56100
57102
  (item) => {
56101
57103
  if (item.type === "info" /* INFO */) {
56102
57104
  applyEvent({ type: "info", text: item.text });
@@ -56108,29 +57110,22 @@ function OpenTuiEntryApp({
56108
57110
  },
56109
57111
  [applyEvent]
56110
57112
  );
56111
- const setUpdateInfo = (0, import_react52.useCallback)((info) => {
57113
+ const setUpdateInfo = (0, import_react55.useCallback)((info) => {
56112
57114
  setUpdateNotice(info?.message ?? null);
56113
57115
  }, []);
56114
- (0, import_react52.useEffect)(() => {
56115
- const { cleanup } = setUpdateHandler(
56116
- addUpdateItem,
56117
- setUpdateInfo,
56118
- isIdleRef
56119
- );
56120
- return cleanup;
56121
- }, [addUpdateItem, setUpdateInfo]);
56122
- const [exitHint, setExitHint] = (0, import_react52.useState)(null);
56123
- 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)(
56124
57119
  () => createExitGuard({ onWindowExpired: /* @__PURE__ */ __name(() => setExitHint(null), "onWindowExpired") }),
56125
57120
  []
56126
57121
  );
56127
- (0, import_react52.useEffect)(() => () => exitGuard.dispose(), [exitGuard]);
56128
- const streamingRef = (0, import_react52.useRef)(live.streaming);
56129
- (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)(() => {
56130
57125
  streamingRef.current = live.streaming;
56131
57126
  }, [live.streaming]);
56132
- const waitingCallsRef = (0, import_react52.useRef)(live.waitingCalls);
56133
- (0, import_react52.useEffect)(() => {
57127
+ const waitingCallsRef = (0, import_react55.useRef)(live.waitingCalls);
57128
+ (0, import_react55.useEffect)(() => {
56134
57129
  waitingCallsRef.current = live.waitingCalls;
56135
57130
  }, [live.waitingCalls]);
56136
57131
  useKeyboard((key) => {
@@ -56153,7 +57148,7 @@ function OpenTuiEntryApp({
56153
57148
  setExitHint(exitGuardHint(guardKey));
56154
57149
  }
56155
57150
  });
56156
- const renderMain = (0, import_react52.useCallback)(
57151
+ const renderMain = (0, import_react55.useCallback)(
56157
57152
  () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("box", { flexDirection: "column", flexGrow: 1, children: [
56158
57153
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
56159
57154
  OpenTuiTranscriptView,
@@ -56167,7 +57162,7 @@ function OpenTuiEntryApp({
56167
57162
  ] }),
56168
57163
  [live.items, width, height, exitHint]
56169
57164
  );
56170
- const handleRenderError = (0, import_react52.useCallback)(
57165
+ const handleRenderError = (0, import_react55.useCallback)(
56171
57166
  (error) => {
56172
57167
  debugLogger4.error(
56173
57168
  `[FATAL_RENDER_ERROR] ${error.message}
@@ -56179,15 +57174,15 @@ ${error.stack ?? ""}`
56179
57174
  },
56180
57175
  [config]
56181
57176
  );
56182
- const handleStartNewSession = (0, import_react52.useCallback)(
57177
+ const handleStartNewSession = (0, import_react55.useCallback)(
56183
57178
  (sessionId) => startNewSession(sessionId),
56184
57179
  [startNewSession]
56185
57180
  );
56186
- const handleSubmitPrompt = (0, import_react52.useCallback)(
57181
+ const handleSubmitPrompt = (0, import_react55.useCallback)(
56187
57182
  (content, imagePaths, options) => submit(content, imagePaths, options),
56188
57183
  [submit]
56189
57184
  );
56190
- const handleQuit = (0, import_react52.useCallback)(() => {
57185
+ const handleQuit = (0, import_react55.useCallback)(() => {
56191
57186
  void exitSession(config, 0);
56192
57187
  }, [config]);
56193
57188
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -56199,6 +57194,7 @@ ${error.stack ?? ""}`
56199
57194
  getSessionStats,
56200
57195
  runtime,
56201
57196
  extensionRefreshState,
57197
+ initialDialog,
56202
57198
  renderMain,
56203
57199
  onSubmitPrompt: handleSubmitPrompt,
56204
57200
  onQuit: handleQuit,
@@ -56215,12 +57211,15 @@ ${error.stack ?? ""}`
56215
57211
  waitingToolCalls: live.waitingCalls,
56216
57212
  onToolCallSettled: live.settleWaitingCall,
56217
57213
  onRenderError: handleRenderError,
56218
- composerHandle
57214
+ composerHandle,
57215
+ promptSuggestion,
57216
+ onPromptSuggestionDismiss: dismissPromptSuggestion,
57217
+ onPromptSuggestionAbort: abortPromptSuggestion
56219
57218
  }
56220
57219
  );
56221
57220
  }
56222
57221
  __name(OpenTuiEntryApp, "OpenTuiEntryApp");
56223
- async function startOpenTuiUI(config, settings, startupWarnings, workspaceRoot = process.cwd(), _initializationResult, options = {}) {
57222
+ async function startOpenTuiUI(config, settings, startupWarnings, workspaceRoot = process.cwd(), initializationResult, options = {}) {
56224
57223
  let renderer;
56225
57224
  try {
56226
57225
  renderer = await createCliRenderer({ exitOnCtrlC: false, useMouse: true });
@@ -56234,6 +57233,7 @@ async function startOpenTuiUI(config, settings, startupWarnings, workspaceRoot =
56234
57233
  const root = createRoot(renderer);
56235
57234
  let runtime = null;
56236
57235
  try {
57236
+ void ensureConfigInitialized(config);
56237
57237
  const version = await getCliVersion();
56238
57238
  if (!settings.merged.ui?.hideWindowTitle && settings.merged.ui?.showStatusInTitle !== false) {
56239
57239
  writeTerminalTitle(
@@ -56245,11 +57245,15 @@ async function startOpenTuiUI(config, settings, startupWarnings, workspaceRoot =
56245
57245
  await runtime.writeRuntimeSidecar();
56246
57246
  runtime.startPressureMonitor();
56247
57247
  const capturedText = drainCapturedInputAsText();
57248
+ const initialDialog = initializationResult.authError || config.getAuthType() === void 0 ? {
57249
+ dialog: "auth",
57250
+ initialError: initializationResult.authError ?? void 0
57251
+ } : null;
56248
57252
  root.render(
56249
57253
  // children must sit in the props object: the provider declares it as a
56250
57254
  // required prop, which createElement's rest-children overloads can't fill.
56251
57255
  // eslint-disable-next-line react/no-children-prop
56252
- (0, import_react52.createElement)(SessionStatsProvider, {
57256
+ (0, import_react55.createElement)(SessionStatsProvider, {
56253
57257
  sessionId: config.getSessionId(),
56254
57258
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
56255
57259
  OpenTuiEntryApp,
@@ -56259,7 +57263,8 @@ async function startOpenTuiUI(config, settings, startupWarnings, workspaceRoot =
56259
57263
  runtime,
56260
57264
  startupWarnings,
56261
57265
  extensionRefreshState: options.extensionRefreshState,
56262
- capturedText
57266
+ capturedText,
57267
+ initialDialog
56263
57268
  }
56264
57269
  )
56265
57270
  })