@ashx-j/lunr 0.2.22 → 0.2.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/README.md +15 -13
  3. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  4. package/dist/builtin-extensions/ashxj-tui.js +2 -2
  5. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  6. package/dist/builtin-extensions/lunr-browser.d.ts +7 -1
  7. package/dist/builtin-extensions/lunr-browser.d.ts.map +1 -1
  8. package/dist/builtin-extensions/lunr-browser.js +116 -3
  9. package/dist/builtin-extensions/lunr-browser.js.map +1 -1
  10. package/dist/builtin-extensions/lunr-plan-tools.d.ts +7 -7
  11. package/dist/builtin-extensions/lunr-plan-tools.d.ts.map +1 -1
  12. package/dist/builtin-extensions/lunr-plan-tools.js +12 -12
  13. package/dist/builtin-extensions/lunr-plan-tools.js.map +1 -1
  14. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  15. package/dist/builtin-extensions/pi-intercom/index.js +2 -0
  16. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  17. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts.map +1 -1
  18. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js +1 -0
  19. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js.map +1 -1
  20. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  21. package/dist/builtin-extensions/pi-mcp-adapter/index.js +1 -1
  22. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  23. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  24. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +1 -1
  25. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  26. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  27. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +1 -1
  28. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  29. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -4
  30. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  31. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +6 -4
  32. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  33. package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.d.ts +2 -0
  34. package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.js +6 -3
  36. package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.js.map +1 -1
  37. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
  38. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +7 -2
  39. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
  40. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts +2 -0
  41. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
  42. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +4 -0
  43. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
  44. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  45. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +1 -1
  46. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  47. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +2 -0
  48. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
  49. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +9 -0
  50. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
  51. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +41 -3
  53. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
  54. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts +1 -0
  55. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  56. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +5 -1
  57. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  58. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  59. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +3 -2
  60. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  61. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  62. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +23 -0
  63. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  64. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
  65. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
  66. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +1 -1
  67. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
  68. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts +2 -0
  69. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
  70. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +17 -15
  71. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
  72. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
  73. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +3 -1
  74. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
  75. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
  76. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +2 -2
  77. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
  78. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +1 -0
  79. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  80. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  81. package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts +1 -1
  82. package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -1
  83. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +3 -2
  84. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -1
  85. package/dist/core/agent-session.d.ts +20 -1
  86. package/dist/core/agent-session.d.ts.map +1 -1
  87. package/dist/core/agent-session.js +235 -107
  88. package/dist/core/agent-session.js.map +1 -1
  89. package/dist/core/browser/schema.d.ts +1 -1
  90. package/dist/core/browser/schema.d.ts.map +1 -1
  91. package/dist/core/browser/schema.js +1 -1
  92. package/dist/core/browser/schema.js.map +1 -1
  93. package/dist/core/catalog-cache-scope.d.ts.map +1 -1
  94. package/dist/core/catalog-cache-scope.js +3 -1
  95. package/dist/core/catalog-cache-scope.js.map +1 -1
  96. package/dist/core/model-runtime.d.ts.map +1 -1
  97. package/dist/core/model-runtime.js +3 -2
  98. package/dist/core/model-runtime.js.map +1 -1
  99. package/dist/core/permissions.d.ts +16 -23
  100. package/dist/core/permissions.d.ts.map +1 -1
  101. package/dist/core/permissions.js +66 -141
  102. package/dist/core/permissions.js.map +1 -1
  103. package/dist/core/plan-mode.d.ts +10 -12
  104. package/dist/core/plan-mode.d.ts.map +1 -1
  105. package/dist/core/plan-mode.js +16 -18
  106. package/dist/core/plan-mode.js.map +1 -1
  107. package/dist/core/runtime-bridges.d.ts.map +1 -1
  108. package/dist/core/runtime-bridges.js +2 -0
  109. package/dist/core/runtime-bridges.js.map +1 -1
  110. package/dist/core/sdk.d.ts.map +1 -1
  111. package/dist/core/sdk.js +13 -6
  112. package/dist/core/sdk.js.map +1 -1
  113. package/dist/core/session-manager.d.ts.map +1 -1
  114. package/dist/core/session-manager.js +9 -2
  115. package/dist/core/session-manager.js.map +1 -1
  116. package/dist/core/settings-manager.d.ts +13 -1
  117. package/dist/core/settings-manager.d.ts.map +1 -1
  118. package/dist/core/settings-manager.js +49 -1
  119. package/dist/core/settings-manager.js.map +1 -1
  120. package/dist/core/slash-commands.d.ts.map +1 -1
  121. package/dist/core/slash-commands.js +4 -4
  122. package/dist/core/slash-commands.js.map +1 -1
  123. package/dist/core/subagent-permission-inherit.d.ts +6 -10
  124. package/dist/core/subagent-permission-inherit.d.ts.map +1 -1
  125. package/dist/core/subagent-permission-inherit.js +14 -14
  126. package/dist/core/subagent-permission-inherit.js.map +1 -1
  127. package/dist/core/subagent-wait-interruption.d.ts +11 -0
  128. package/dist/core/subagent-wait-interruption.d.ts.map +1 -0
  129. package/dist/core/subagent-wait-interruption.js +19 -0
  130. package/dist/core/subagent-wait-interruption.js.map +1 -0
  131. package/dist/core/system-prompt.d.ts +2 -0
  132. package/dist/core/system-prompt.d.ts.map +1 -1
  133. package/dist/core/system-prompt.js +11 -4
  134. package/dist/core/system-prompt.js.map +1 -1
  135. package/dist/core/tools/render-utils.d.ts +3 -3
  136. package/dist/core/tools/render-utils.d.ts.map +1 -1
  137. package/dist/core/tools/render-utils.js +3 -3
  138. package/dist/core/tools/render-utils.js.map +1 -1
  139. package/dist/gateway/adapters/discord.d.ts.map +1 -1
  140. package/dist/gateway/adapters/discord.js +1 -1
  141. package/dist/gateway/adapters/discord.js.map +1 -1
  142. package/dist/gateway/approval.d.ts +2 -6
  143. package/dist/gateway/approval.d.ts.map +1 -1
  144. package/dist/gateway/approval.js +3 -7
  145. package/dist/gateway/approval.js.map +1 -1
  146. package/dist/gateway/mobile-commands.d.ts.map +1 -1
  147. package/dist/gateway/mobile-commands.js +12 -11
  148. package/dist/gateway/mobile-commands.js.map +1 -1
  149. package/dist/gateway/router.d.ts.map +1 -1
  150. package/dist/gateway/router.js +1 -1
  151. package/dist/gateway/router.js.map +1 -1
  152. package/dist/main.d.ts.map +1 -1
  153. package/dist/main.js +1 -2
  154. package/dist/main.js.map +1 -1
  155. package/dist/modes/interactive/components/assistant-message.d.ts +10 -2
  156. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  157. package/dist/modes/interactive/components/assistant-message.js +29 -5
  158. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  159. package/dist/modes/interactive/components/copyable-text.d.ts +2 -6
  160. package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
  161. package/dist/modes/interactive/components/copyable-text.js +26 -35
  162. package/dist/modes/interactive/components/copyable-text.js.map +1 -1
  163. package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
  164. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  165. package/dist/modes/interactive/components/settings-selector.js +36 -3
  166. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  167. package/dist/modes/interactive/components/thinking-tail.d.ts +9 -2
  168. package/dist/modes/interactive/components/thinking-tail.d.ts.map +1 -1
  169. package/dist/modes/interactive/components/thinking-tail.js +43 -1
  170. package/dist/modes/interactive/components/thinking-tail.js.map +1 -1
  171. package/dist/modes/interactive/components/tool-execution.d.ts +5 -3
  172. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  173. package/dist/modes/interactive/components/tool-execution.js +44 -45
  174. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  175. package/dist/modes/interactive/interactive-mode.d.ts +7 -2
  176. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  177. package/dist/modes/interactive/interactive-mode.js +194 -129
  178. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  179. package/dist/modes/interactive/theme/theme.d.ts +1 -0
  180. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  181. package/dist/modes/interactive/theme/theme.js +23 -0
  182. package/dist/modes/interactive/theme/theme.js.map +1 -1
  183. package/dist/node-runtime/{agent-session-services-NQ6GKOIK.js → agent-session-services-IEF7LQWD.js} +12 -13
  184. package/dist/node-runtime/{builtin-extensions-GVC6IFDU.js → builtin-extensions-EBAWTH4M.js} +5 -5
  185. package/dist/node-runtime/{chunk-XLTL257W.js → chunk-2KIPT4HJ.js} +5 -1
  186. package/dist/node-runtime/{chunk-IWOWXRWU.js → chunk-5Q3EHOHI.js} +21 -21
  187. package/dist/node-runtime/{chunk-6B2POMK7.js → chunk-6VYZ5UFP.js} +1 -1
  188. package/dist/node-runtime/{chunk-TQGPP4SC.js → chunk-CDVHZOOK.js} +1 -1
  189. package/dist/node-runtime/{chunk-TDL7UWJ7.js → chunk-DE2JB6J5.js} +189 -70
  190. package/dist/node-runtime/{chunk-YJMMG7C6.js → chunk-DSIKTUPW.js} +1 -1
  191. package/dist/node-runtime/{chunk-IQIEU7SB.js → chunk-F4FLTQKV.js} +2 -2
  192. package/dist/node-runtime/{chunk-GMHJCCEN.js → chunk-FU6OODRZ.js} +4 -1
  193. package/dist/node-runtime/{chunk-5BNJ4JUH.js → chunk-GJ2RDBRL.js} +1 -1
  194. package/dist/node-runtime/{chunk-GNN7H3B7.js → chunk-GS42T6MX.js} +1 -1
  195. package/dist/node-runtime/{chunk-OFKSVRV7.js → chunk-GYIXXQAO.js} +1 -1
  196. package/dist/node-runtime/{chunk-BX2RB477.js → chunk-HFVZUPFJ.js} +1 -1
  197. package/dist/node-runtime/{chunk-PC2Z5TKZ.js → chunk-HMBGROQK.js} +3 -3
  198. package/dist/node-runtime/{chunk-AZJHNQKQ.js → chunk-I54LGHWM.js} +1 -1
  199. package/dist/node-runtime/{chunk-IVXYUAJE.js → chunk-IF24A3FH.js} +1 -1
  200. package/dist/node-runtime/{chunk-VJPTNWAP.js → chunk-IGV54Q5V.js} +3 -3
  201. package/dist/node-runtime/{chunk-QDGKKKUM.js → chunk-K5AGHH57.js} +18 -13
  202. package/dist/node-runtime/{chunk-GS66LV4M.js → chunk-KJ6DWS3K.js} +4 -4
  203. package/dist/node-runtime/{chunk-EQ63ANHL.js → chunk-L3LX4SNR.js} +310 -192
  204. package/dist/node-runtime/{chunk-VSELYKWU.js → chunk-LWYIVUGV.js} +2 -1
  205. package/dist/node-runtime/{chunk-JHYKXIMM.js → chunk-MPKSOJBT.js} +1 -1
  206. package/dist/node-runtime/{chunk-UAFLNHSH.js → chunk-OF7PWMG4.js} +8 -8
  207. package/dist/node-runtime/{chunk-CSUZVNYE.js → chunk-OVX6X377.js} +10 -6
  208. package/dist/node-runtime/{chunk-ORH324EP.js → chunk-PCEW76PM.js} +3 -3
  209. package/dist/node-runtime/{chunk-6427XAWG.js → chunk-QH6YL7VK.js} +3 -3
  210. package/dist/node-runtime/{chunk-LMBNLFXQ.js → chunk-QM43FEAE.js} +15 -15
  211. package/dist/node-runtime/{chunk-7QWNYZDI.js → chunk-RDDAZOMU.js} +16 -0
  212. package/dist/node-runtime/{chunk-WADV2VDS.js → chunk-RORY2HMJ.js} +46 -5
  213. package/dist/node-runtime/{chunk-H3XF4UVQ.js → chunk-RWTKOC3B.js} +1 -1
  214. package/dist/node-runtime/{chunk-V2A7CEXK.js → chunk-WHLRAGUQ.js} +13 -12
  215. package/dist/node-runtime/{chunk-GJSAD4AB.js → chunk-Y73WPE6S.js} +17 -17
  216. package/dist/node-runtime/{chunk-VSSXXL36.js → chunk-YDO2F2IA.js} +2 -2
  217. package/dist/node-runtime/{chunk-BFNXONG3.js → chunk-YVI6L6LU.js} +5 -5
  218. package/dist/node-runtime/{chunk-5D7LC2ZQ.js → chunk-ZXSGTGJ6.js} +54 -85
  219. package/dist/node-runtime/cli-runtime.js +1 -1
  220. package/dist/node-runtime/{command-3JHHXOPX.js → command-7BG7VVTS.js} +3 -3
  221. package/dist/node-runtime/{commands-KAMO2T6P.js → commands-NZLSOHPE.js} +2 -2
  222. package/dist/node-runtime/{commands-2JVNFGMQ.js → commands-QFDKNQTL.js} +9 -9
  223. package/dist/node-runtime/{direct-tool-executor-YAVOLDFY.js → direct-tool-executor-77GW4F5P.js} +3 -3
  224. package/dist/node-runtime/{export-html-KBFVV63J.js → export-html-VM4J2MNR.js} +2 -2
  225. package/dist/node-runtime/{extension-input-K24TVKVW.js → extension-input-E7BJZ35H.js} +4 -4
  226. package/dist/node-runtime/{extension-selector-SPNF7EDR.js → extension-selector-WU42XDTU.js} +4 -4
  227. package/dist/node-runtime/{gateway-VFO6SFKK.js → gateway-TWR3N65G.js} +14 -14
  228. package/dist/node-runtime/index.js +26 -27
  229. package/dist/node-runtime/{init-X2LIUB2H.js → init-HS6NQXSK.js} +2 -2
  230. package/dist/node-runtime/{install-cli-C3CF7O7N.js → install-cli-VAP6KBFN.js} +1 -1
  231. package/dist/node-runtime/{interactive-mode-LOM6AIF6.js → interactive-mode-6J5VZ2TT.js} +19 -20
  232. package/dist/node-runtime/{interactive-view-IDSCPPK7.js → interactive-view-NGFAMHPW.js} +7 -7
  233. package/dist/node-runtime/lunr-browser-J5ZZYVGM.js +174 -0
  234. package/dist/node-runtime/{lunr-cron-BKHGNBKT.js → lunr-cron-CXOL37AL.js} +7 -7
  235. package/dist/node-runtime/main.js +22 -23
  236. package/dist/node-runtime/{mobile-commands-HMP25WBC.js → mobile-commands-VTBM5DSZ.js} +6 -6
  237. package/dist/node-runtime/{model-runtime-PLQKAG4B.js → model-runtime-OO5HFLWE.js} +1 -1
  238. package/dist/node-runtime/{package-manager-cli-VCK4E2RC.js → package-manager-cli-ZLW5DZXF.js} +9 -10
  239. package/dist/node-runtime/{pi-intercom-HBPK5HSJ.js → pi-intercom-QM53RLTS.js} +2 -0
  240. package/dist/node-runtime/{pi-mcp-adapter-E6WULBKF.js → pi-mcp-adapter-5UKBZP44.js} +7 -6
  241. package/dist/node-runtime/{pi-subagents-FEUDLJOE.js → pi-subagents-XPCLLKIM.js} +65 -21
  242. package/dist/node-runtime/{proxy-modes-OSQCWRBI.js → proxy-modes-LGEUYD7R.js} +3 -3
  243. package/dist/node-runtime/rpc-entry.js +22 -23
  244. package/dist/node-runtime/{rpc-mode-P5ODXPEG.js → rpc-mode-O3XV4SID.js} +2 -2
  245. package/dist/node-runtime/{runtime-bridges-3XUQ46XW.js → runtime-bridges-QYXUX2TG.js} +8 -1
  246. package/dist/node-runtime/{session-handoff-HC7R5E24.js → session-handoff-GWARVEWT.js} +2 -2
  247. package/dist/node-runtime/{session-manager-CFN4UFM2.js → session-manager-JB5J6XBN.js} +1 -1
  248. package/dist/node-runtime/{session-selector-LHRMJOKT.js → session-selector-GIM4DHQ2.js} +4 -4
  249. package/dist/node-runtime/{settings-manager-UUZ6NUXI.js → settings-manager-WCQDUVQB.js} +7 -4
  250. package/dist/node-runtime/{setup-NRXVZBLJ.js → setup-YRBKH2LD.js} +2 -2
  251. package/dist/node-runtime/{subagent-executor-MLUMBWCP.js → subagent-executor-OTNISDQU.js} +47 -10
  252. package/dist/node-runtime/{theme-U7IGOA7O.js → theme-UOO5RVFN.js} +1 -1
  253. package/dist/node-runtime/{update-cli-4TP25CNW.js → update-cli-VBR2777K.js} +1 -2
  254. package/dist/startup/interactive-view.d.ts.map +1 -1
  255. package/dist/startup/interactive-view.js +5 -1
  256. package/dist/startup/interactive-view.js.map +1 -1
  257. package/docs/browser.md +1 -1
  258. package/docs/features.md +17 -14
  259. package/docs/index.md +1 -1
  260. package/docs/keybindings.md +1 -1
  261. package/docs/providers.md +6 -2
  262. package/docs/quickstart.md +2 -2
  263. package/docs/settings.md +2 -1
  264. package/docs/usage.md +6 -6
  265. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  266. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  267. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  268. package/examples/extensions/gondolin/package-lock.json +2 -2
  269. package/examples/extensions/gondolin/package.json +1 -1
  270. package/examples/extensions/plan-mode/README.md +1 -1
  271. package/examples/extensions/sandbox/package-lock.json +2 -2
  272. package/examples/extensions/sandbox/package.json +1 -1
  273. package/examples/extensions/with-deps/package-lock.json +2 -2
  274. package/examples/extensions/with-deps/package.json +1 -1
  275. package/package.json +4 -4
  276. package/dist/node-runtime/chunk-LISUTZS3.js +0 -19
  277. package/dist/node-runtime/lunr-browser-YNW7FTYX.js +0 -87
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-US544NN6.js";
9
9
  import {
10
10
  computeContextBreakdown
11
- } from "./chunk-TQGPP4SC.js";
11
+ } from "./chunk-CDVHZOOK.js";
12
12
  import {
13
13
  copyToClipboard,
14
14
  readClipboardText
@@ -20,7 +20,7 @@ import {
20
20
  import {
21
21
  BootScreenComponent,
22
22
  registerPermissionModeBridge
23
- } from "./chunk-H3XF4UVQ.js";
23
+ } from "./chunk-RWTKOC3B.js";
24
24
  import {
25
25
  nextModeForGoal,
26
26
  registerPermissionModeControlBridge
@@ -45,19 +45,19 @@ import {
45
45
  peekRollbackTurnsConsumed,
46
46
  rollbackLastTurn,
47
47
  setRollbackWarningHandler
48
- } from "./chunk-TDL7UWJ7.js";
48
+ } from "./chunk-DE2JB6J5.js";
49
49
  import {
50
50
  notifyTodosEnabledChanged
51
51
  } from "./chunk-CCCN2UCX.js";
52
52
  import {
53
53
  parseGitUrl
54
- } from "./chunk-IQIEU7SB.js";
54
+ } from "./chunk-F4FLTQKV.js";
55
55
  import {
56
56
  createAllToolDefinitions,
57
57
  ensureTool,
58
58
  getToolPath,
59
59
  truncateToVisualLines
60
- } from "./chunk-VSSXXL36.js";
60
+ } from "./chunk-YDO2F2IA.js";
61
61
  import {
62
62
  DEFAULT_MAX_BYTES,
63
63
  DEFAULT_MAX_LINES,
@@ -80,17 +80,15 @@ import {
80
80
  hasGrokCliXaiAuth,
81
81
  refreshModelCandidatesForInit,
82
82
  stripJsonComments
83
- } from "./chunk-GS66LV4M.js";
83
+ } from "./chunk-KJ6DWS3K.js";
84
84
  import {
85
85
  HTTP_IDLE_TIMEOUT_CHOICES,
86
86
  SKILL_TAG_CHARACTERS,
87
+ SUBAGENT_SPINNER_LABELS,
88
+ SUBAGENT_SPINNER_NAMES,
87
89
  configureHttpDispatcher,
88
90
  formatHttpIdleTimeoutMs
89
- } from "./chunk-WADV2VDS.js";
90
- import {
91
- SUBAGENT_SPINNER_LABELS,
92
- SUBAGENT_SPINNER_NAMES
93
- } from "./chunk-LISUTZS3.js";
91
+ } from "./chunk-RORY2HMJ.js";
94
92
  import {
95
93
  ProjectTrustStore,
96
94
  getProjectTrustOptions,
@@ -103,21 +101,21 @@ import {
103
101
  extractFileOpsFromMessage,
104
102
  findExactModelReferenceMatch,
105
103
  resolveModelScope
106
- } from "./chunk-OFKSVRV7.js";
104
+ } from "./chunk-GYIXXQAO.js";
107
105
  import {
108
106
  SubagentEscapeSequence,
109
107
  getSubagentCancellation
110
108
  } from "./chunk-BBUVIEZB.js";
111
109
  import {
112
110
  AUTO_MODE_ADDENDUM,
113
- PLAN_MODE_ADDENDUM,
111
+ READ_ONLY_MODE_ADDENDUM,
114
112
  getPermissionMode,
115
113
  nextPermissionMode,
116
114
  registerApprovalHandler,
117
115
  resetPermissions,
118
116
  restorePermissionModeAfterPlan,
119
117
  setPermissionMode
120
- } from "./chunk-5D7LC2ZQ.js";
118
+ } from "./chunk-ZXSGTGJ6.js";
121
119
  import {
122
120
  getGlobalInstructionsPath,
123
121
  getModelInstructionsPath
@@ -141,11 +139,11 @@ import {
141
139
  recordTuiActivity,
142
140
  registerTransferHandler,
143
141
  requestSessionTransfer
144
- } from "./chunk-AZJHNQKQ.js";
142
+ } from "./chunk-I54LGHWM.js";
145
143
  import {
146
144
  SessionManager,
147
145
  sessionEntryToContextMessages
148
- } from "./chunk-XLTL257W.js";
146
+ } from "./chunk-2KIPT4HJ.js";
149
147
  import {
150
148
  createCompactionSummaryMessage
151
149
  } from "./chunk-FVDOXRUD.js";
@@ -166,7 +164,7 @@ import {
166
164
  } from "./chunk-2MI5OPMN.js";
167
165
  import {
168
166
  SessionSelectorComponent
169
- } from "./chunk-ORH324EP.js";
167
+ } from "./chunk-PCEW76PM.js";
170
168
  import {
171
169
  CustomEditor
172
170
  } from "./chunk-H2EOZYMP.js";
@@ -181,23 +179,23 @@ import {
181
179
  } from "./chunk-CCZJ3PYY.js";
182
180
  import {
183
181
  ExtensionSelectorComponent
184
- } from "./chunk-6427XAWG.js";
182
+ } from "./chunk-QH6YL7VK.js";
185
183
  import {
186
184
  ExtensionInputComponent
187
- } from "./chunk-PC2Z5TKZ.js";
185
+ } from "./chunk-HMBGROQK.js";
188
186
  import {
189
187
  CountdownTimer
190
188
  } from "./chunk-I6R76AG7.js";
191
189
  import {
192
190
  DynamicBorder
193
- } from "./chunk-6B2POMK7.js";
191
+ } from "./chunk-6VYZ5UFP.js";
194
192
  import {
195
193
  formatKeyText,
196
194
  keyDisplayText,
197
195
  keyHint,
198
196
  keyText,
199
197
  rawKeyHint
200
- } from "./chunk-GNN7H3B7.js";
198
+ } from "./chunk-GS42T6MX.js";
201
199
  import {
202
200
  FS_WATCH_RETRY_DELAY_MS,
203
201
  Theme,
@@ -223,7 +221,7 @@ import {
223
221
  stopThemeWatcher,
224
222
  theme,
225
223
  watchWithErrorHandler
226
- } from "./chunk-7QWNYZDI.js";
224
+ } from "./chunk-RDDAZOMU.js";
227
225
  import {
228
226
  APP_NAME,
229
227
  APP_TITLE,
@@ -245,7 +243,7 @@ import * as fs2 from "node:fs";
245
243
  import * as os2 from "node:os";
246
244
  import * as path2 from "node:path";
247
245
  import { getSupportedThinkingLevels } from "@ashx-j/lunr-ai/compat";
248
- import { CombinedAutocompleteProvider, Container as Container19, collectImageMarkerIds, formatImageMarker, fuzzyFilter as fuzzyFilter5, isFocusable, Markdown as Markdown10, matchesKey as matchesKey2, ProcessTerminal, Spacer as Spacer19, setKeybindings, Text as Text21, TruncatedText as TruncatedText2, TUI, visibleWidth as visibleWidth4 } from "@ashx-j/lunr-tui";
246
+ import { CombinedAutocompleteProvider, Container as Container19, collectImageMarkerIds, formatImageMarker, fuzzyFilter as fuzzyFilter5, isFocusable, Markdown as Markdown10, matchesKey as matchesKey2, ProcessTerminal, Spacer as Spacer19, setKeybindings, Text as Text21, TruncatedText as TruncatedText2, TUI, visibleWidth as visibleWidth6 } from "@ashx-j/lunr-tui";
249
247
  import chalk from "chalk";
250
248
  import { spawn as spawn3, spawnSync } from "child_process";
251
249
 
@@ -709,15 +707,15 @@ var BUILTIN_SLASH_COMMANDS = [
709
707
  { name: "context", description: "Show estimated context window breakdown" },
710
708
  {
711
709
  name: "plan",
712
- description: "Switch to plan permission mode, or /plan <task> to plan a task",
710
+ description: "Use read-only mode to plan a task, or /plan <task> to start planning",
713
711
  argumentHint: "[on|off|status|<task>]"
714
712
  },
715
713
  {
716
714
  name: "mode",
717
- description: "Set permission mode: manual, yolo, plan, or auto",
718
- argumentHint: "[manual|yolo|plan|auto]"
715
+ description: "Set permission mode: yolo, auto, or read",
716
+ argumentHint: "[yolo|auto|read]"
719
717
  },
720
- { name: "manual", description: "Activate manual permission mode (approve every action)" },
718
+ { name: "read", description: "Activate read-only permission mode" },
721
719
  { name: "yolo", description: "Activate YOLO permission mode (auto-approve tools)" },
722
720
  { name: "auto", description: "Activate auto permission mode (fully autonomous, no questions)" },
723
721
  { name: "processes", description: "View and manage background processes started this session" },
@@ -1118,7 +1116,7 @@ var ArminComponent = class {
1118
1116
  import { Container, Markdown as Markdown2, Spacer, Text } from "@ashx-j/lunr-tui";
1119
1117
 
1120
1118
  // packages/coding-agent/dist/modes/interactive/components/copyable-text.js
1121
- import { truncateToWidth, wrapTextWithAnsi } from "@ashx-j/lunr-tui";
1119
+ import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@ashx-j/lunr-tui";
1122
1120
  function sourceLines(source) {
1123
1121
  let lines = [], pattern = /([^\r\n]*)(\r\n|\r|\n|$)/g;
1124
1122
  for (let match of source.matchAll(pattern)) {
@@ -1192,35 +1190,36 @@ function parseCopyableTextSegments(source) {
1192
1190
  return emittedThrough < source.length && segments.push({ type: "markdown", text: source.slice(emittedThrough) }), segments;
1193
1191
  }
1194
1192
  var CopyableTextBlockComponent = class {
1195
- buttonRow = -1;
1196
- buttonStart = -1;
1197
- buttonEnd = -1;
1193
+ renderedRows = 0;
1198
1194
  payload;
1199
1195
  complete;
1200
1196
  outputPad;
1201
- markdownTheme;
1202
1197
  status;
1203
1198
  onCopy;
1204
- constructor(payload, complete, outputPad, markdownTheme, status, onCopy) {
1205
- this.payload = payload, this.complete = complete, this.outputPad = outputPad, this.markdownTheme = markdownTheme, this.status = status, this.onCopy = onCopy;
1199
+ constructor(payload, complete, outputPad, status, onCopy) {
1200
+ this.payload = payload, this.complete = complete, this.outputPad = outputPad, this.status = status, this.onCopy = onCopy;
1206
1201
  }
1207
1202
  invalidate() {
1208
- this.buttonRow = -1, this.buttonStart = -1, this.buttonEnd = -1;
1203
+ this.renderedRows = 0;
1209
1204
  }
1210
1205
  render(width) {
1211
- let pad = " ".repeat(this.outputPad), contentWidth = Math.max(1, width - this.outputPad - 2), lines = [truncateToWidth(`${pad}${this.markdownTheme.codeBlockBorder("\u256D\u2500 lunr-copy")}`, width, "")], payloadLines = this.payload.replace(/\t/g, " ").split(`
1206
+ if (width <= 0)
1207
+ return this.renderedRows = 0, [];
1208
+ let horizontalPad = Math.min(this.outputPad, Math.max(0, width - 1)), pad = " ".repeat(horizontalPad), contentWidth = Math.max(1, width - horizontalPad * 2), paint = (content) => {
1209
+ let line = truncateToWidth(`${pad}${content}`, width, "");
1210
+ return theme.bg("userMessageBg", `${line}${" ".repeat(Math.max(0, width - visibleWidth(line)))}`);
1211
+ }, lines = [paint("")], payloadLines = this.payload.replace(/\t/g, " ").split(`
1212
1212
  `);
1213
1213
  for (let payloadLine of payloadLines)
1214
1214
  for (let wrappedLine of wrapTextWithAnsi(payloadLine, contentWidth))
1215
- lines.push(truncateToWidth(`${pad}${this.markdownTheme.codeBlockBorder("\u2502 ")}${this.markdownTheme.codeBlock(wrappedLine)}`, width, ""));
1216
- if (lines.push(truncateToWidth(`${pad}${this.markdownTheme.codeBlockBorder(this.complete ? "\u2570\u2500" : "\u2570\u2500 receiving")}`, width, "")), this.buttonRow = -1, this.buttonStart = -1, this.buttonEnd = -1, this.complete) {
1217
- let button = "[ Copy ]", feedback = "";
1218
- this.status === "copying" ? feedback = theme.fg("dim", " Copying...") : this.status === "copied" ? feedback = theme.fg("success", " Copied") : typeof this.status == "object" && (feedback = theme.fg("error", ` Copy failed: ${this.status.error}`)), this.buttonRow = lines.length, this.buttonStart = this.outputPad, this.buttonEnd = Math.min(width, this.buttonStart + button.length), lines.push(truncateToWidth(`${pad}${theme.fg("accent", button)}${feedback}`, width, ""));
1219
- }
1220
- return lines;
1215
+ lines.push(paint(theme.fg("userMessageText", wrappedLine)));
1216
+ if (typeof this.status == "object")
1217
+ for (let wrappedLine of wrapTextWithAnsi(`Copy failed: ${this.status.error}`, contentWidth))
1218
+ lines.push(paint(theme.fg("error", wrappedLine)));
1219
+ return lines.push(paint("")), this.renderedRows = lines.length, lines;
1221
1220
  }
1222
1221
  handleClick(localY, width, localX) {
1223
- return this.render(width), !this.complete || this.status === "copying" || localX === void 0 || localY !== this.buttonRow || localX < this.buttonStart || localX >= this.buttonEnd ? !1 : (this.onCopy(), !0);
1222
+ return this.render(width), !this.complete || this.status === "copying" || localY < 0 || localY >= this.renderedRows || localX !== void 0 && (localX < 0 || localX >= width) ? !1 : (this.onCopy(), !0);
1224
1223
  }
1225
1224
  };
1226
1225
 
@@ -1270,7 +1269,7 @@ function isThinkingRunComplete(_hasFollowingBlock, timing, timingsAttached) {
1270
1269
  }
1271
1270
 
1272
1271
  // packages/coding-agent/dist/modes/interactive/components/thinking-tail.js
1273
- import { Markdown } from "@ashx-j/lunr-tui";
1272
+ import { Markdown, truncateToWidth as truncateToWidth2, visibleWidth as visibleWidth2 } from "@ashx-j/lunr-tui";
1274
1273
  var THINKING_TAIL_LINES = 4, ThinkingTailComponent = class {
1275
1274
  markdown;
1276
1275
  maxLines;
@@ -1284,6 +1283,28 @@ var THINKING_TAIL_LINES = 4, ThinkingTailComponent = class {
1284
1283
  let lines = this.markdown.render(width);
1285
1284
  return lines.length <= this.maxLines ? lines : lines.slice(-this.maxLines);
1286
1285
  }
1286
+ }, shimmerSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" }), SHIMMER_PERIOD_MS = 2800, ThinkingLineComponent = class extends ThinkingTailComponent {
1287
+ startedAt;
1288
+ palette = theme.getFgGradient("thinkingText", "white", 32);
1289
+ constructor(text, paddingX, markdownTheme, startedAt) {
1290
+ super(text, paddingX, 0, markdownTheme), this.startedAt = startedAt;
1291
+ }
1292
+ invalidate() {
1293
+ super.invalidate(), this.palette = theme.getFgGradient("thinkingText", "white", 32);
1294
+ }
1295
+ render(width) {
1296
+ if (width <= 0)
1297
+ return ["", ""];
1298
+ let lines = this.markdown.render(width), latest = "";
1299
+ for (let index = lines.length - 1; index >= 0 && (latest = stripAnsi(lines[index]).trimEnd(), !latest.trim()); index--)
1300
+ ;
1301
+ let text = stripAnsi(truncateToWidth2(latest, width, "")), length = visibleWidth2(text), band = Math.max(6, Math.min(18, length * 0.3)), progress = (performance.now() - this.startedAt) % SHIMMER_PERIOD_MS / SHIMMER_PERIOD_MS, center = -band + progress * (length + band * 2), column = 0, highlighted = "";
1302
+ for (let { segment } of shimmerSegmenter.segment(text)) {
1303
+ let cells = visibleWidth2(segment), distance = Math.abs(column + cells / 2 - center) / band, intensity = distance >= 1 ? 0 : (1 + Math.cos(Math.PI * distance)) / 2;
1304
+ highlighted += this.palette[Math.round(intensity * (this.palette.length - 1))] + segment, column += cells;
1305
+ }
1306
+ return ["", `\x1B[3m${highlighted}\x1B[23m\x1B[39m`];
1307
+ }
1287
1308
  };
1288
1309
 
1289
1310
  // packages/coding-agent/dist/modes/interactive/components/assistant-message.js
@@ -1311,13 +1332,20 @@ var OSC133_ZONE_START = "\x1B]133;A\x07", OSC133_ZONE_END = "\x1B]133;B\x07", OS
1311
1332
  copyText;
1312
1333
  requestRender;
1313
1334
  copyStates = /* @__PURE__ */ new Map();
1314
- constructor(message, hideThinkingBlock = !1, markdownTheme = getMarkdownTheme(), hiddenThinkingLabel = "Thinking...", outputPad = 1, thinkingCollapse = !1, copyOptions = {}) {
1315
- super(), this.hideThinkingBlock = hideThinkingBlock, this.thinkingCollapse = thinkingCollapse, this.markdownTheme = markdownTheme, this.hiddenThinkingLabel = hiddenThinkingLabel, this.outputPad = outputPad, this.copyText = copyOptions.copyText ?? copyToClipboard, this.requestRender = copyOptions.requestRender ?? (() => {
1316
- }), this.contentContainer = new Container(), this.addChild(this.contentContainer), message && this.updateContent(message);
1335
+ reasoningDisplay;
1336
+ onThinkingAnimationChange;
1337
+ thinkingAnimationStart = performance.now();
1338
+ thinkingAnimationActive = !1;
1339
+ constructor(message, hideThinkingBlock = !1, markdownTheme = getMarkdownTheme(), hiddenThinkingLabel = "Thinking...", outputPad = 1, thinkingCollapse = !1, options = {}) {
1340
+ super(), this.hideThinkingBlock = hideThinkingBlock, this.thinkingCollapse = thinkingCollapse, this.markdownTheme = markdownTheme, this.hiddenThinkingLabel = hiddenThinkingLabel, this.outputPad = outputPad, this.copyText = options.copyText ?? copyToClipboard, this.requestRender = options.requestRender ?? (() => {
1341
+ }), this.reasoningDisplay = options.reasoningDisplay ?? "auto", this.onThinkingAnimationChange = options.onThinkingAnimationChange, this.contentContainer = new Container(), this.addChild(this.contentContainer), message && this.updateContent(message);
1317
1342
  }
1318
1343
  invalidate() {
1319
1344
  super.invalidate(), this.lastMessage && this.updateContent(this.lastMessage, this.thinkingSourceOptions());
1320
1345
  }
1346
+ setReasoningDisplay(display) {
1347
+ this.reasoningDisplay = display, this.lastMessage && this.updateContent(this.lastMessage, this.thinkingSourceOptions());
1348
+ }
1321
1349
  setHideThinkingBlock(hide) {
1322
1350
  this.hideThinkingBlock = hide, this.lastMessage && this.updateContent(this.lastMessage, this.thinkingSourceOptions());
1323
1351
  }
@@ -1368,7 +1396,7 @@ var OSC133_ZONE_START = "\x1B]133;A\x07", OSC133_ZONE_END = "\x1B]133;B\x07", OS
1368
1396
  return this.thinkingSource ? { thinkingSource: this.thinkingSource } : void 0;
1369
1397
  }
1370
1398
  updateContent(message, options) {
1371
- this.lastMessage = message, this.thinkingSource = options?.thinkingSource, this.contentContainer.clear();
1399
+ this.lastMessage = message, this.thinkingSource = options?.thinkingSource, this.thinkingAnimationActive = !1, this.contentContainer.clear();
1372
1400
  let sourceMessage = this.thinkingSource ?? message, sourceThinkingRuns = collectThinkingRuns(sourceMessage.content);
1373
1401
  message.content.some((c) => c.type === "text" && c.text.trim() || !this.hideThinkingBlock && c.type === "thinking" && c.thinking.trim()) && this.contentContainer.addChild(new Spacer(1));
1374
1402
  let isFirstTextBlock = !0, thinkingRunIndex = -1;
@@ -1387,7 +1415,7 @@ var OSC133_ZONE_START = "\x1B]133;A\x07", OSC133_ZONE_END = "\x1B]133;B\x07", OS
1387
1415
  continue;
1388
1416
  }
1389
1417
  let key = `${i}:${segment.start}`, copyState = this.copyStates.get(key), status = copyState?.payload === segment.payload ? copyState.status : "idle";
1390
- copyState && copyState.payload !== segment.payload && this.copyStates.delete(key), this.contentContainer.addChild(new CopyableTextBlockComponent(segment.payload, segment.complete, this.outputPad, this.markdownTheme, status, () => this.copyPayload(key, segment.payload)));
1418
+ copyState && copyState.payload !== segment.payload && this.copyStates.delete(key), this.contentContainer.addChild(new CopyableTextBlockComponent(segment.payload, segment.complete, this.outputPad, status, () => this.copyPayload(key, segment.payload)));
1391
1419
  }
1392
1420
  else if (content.type === "thinking") {
1393
1421
  thinkingRunIndex++;
@@ -1417,6 +1445,7 @@ var OSC133_ZONE_START = "\x1B]133;A\x07", OSC133_ZONE_END = "\x1B]133;B\x07", OS
1417
1445
  this.contentContainer.addChild(new Spacer(1)), this.contentContainer.addChild(new Text(theme.fg("error", `Error: ${errorMsg}`), this.outputPad, 0));
1418
1446
  }
1419
1447
  }
1448
+ this.onThinkingAnimationChange?.(this.thinkingAnimationActive);
1420
1449
  }
1421
1450
  copyPayload(key, payload) {
1422
1451
  this.copyStates.get(key)?.status !== "copying" && (this.copyStates.set(key, { payload, status: "copying" }), this.refreshCopyStatus(), Promise.resolve().then(() => this.copyText(payload)).then(() => {
@@ -1443,6 +1472,12 @@ var OSC133_ZONE_START = "\x1B]133;A\x07", OSC133_ZONE_END = "\x1B]133;B\x07", OS
1443
1472
  return;
1444
1473
  }
1445
1474
  if (!runComplete && !this.isRunExpanded(thinkingRunIndex)) {
1475
+ if (this.reasoningDisplay === "one-line" || this.reasoningDisplay === "auto" && displayMessage.provider === "openai-codex") {
1476
+ this.thinkingAnimationActive = !0, this.contentContainer.children.length === 1 && this.contentContainer.children[0] instanceof Spacer && this.contentContainer.clear(), wrap(new ThinkingLineComponent(thinkingBlocks.join(`
1477
+
1478
+ `), this.outputPad, this.markdownTheme, this.thinkingAnimationStart));
1479
+ return;
1480
+ }
1446
1481
  wrap(new ThinkingTailComponent(thinkingBlocks.join(`
1447
1482
 
1448
1483
  `), this.outputPad, 0, this.markdownTheme, {
@@ -1661,7 +1696,7 @@ var CompactionSummaryMessageComponent = class extends Box2 {
1661
1696
 
1662
1697
  // packages/coding-agent/dist/modes/interactive/components/footer.js
1663
1698
  import { isAbsolute, relative, resolve as resolve2, sep } from "node:path";
1664
- import { truncateToWidth as truncateToWidth2, visibleWidth } from "@ashx-j/lunr-tui";
1699
+ import { truncateToWidth as truncateToWidth3, visibleWidth as visibleWidth3 } from "@ashx-j/lunr-tui";
1665
1700
  function sanitizeStatusText(text) {
1666
1701
  return text.replace(/[\r\n\t]/g, " ").replace(/ +/g, " ").trim();
1667
1702
  }
@@ -1720,38 +1755,38 @@ var FooterComponent = class {
1720
1755
  }
1721
1756
  let contextPercentStr, autoIndicator = this.autoCompactEnabled ? " (auto)" : "", contextPercentDisplay = contextPercent === "?" ? `?/${formatTokens(contextWindow)}${autoIndicator}` : `${contextPercent}%/${formatTokens(contextWindow)}${autoIndicator}`;
1722
1757
  contextPercentValue > 90 ? contextPercentStr = theme.fg("error", contextPercentDisplay) : contextPercentValue > 70 ? contextPercentStr = theme.fg("warning", contextPercentDisplay) : contextPercentStr = contextPercentDisplay, statsParts.push(contextPercentStr), areExperimentalFeaturesEnabled() && statsParts.push(`${theme.fg("dim", "\u2022")} ${theme.bold(theme.fg("warning", "xp"))}`);
1723
- let statsLeft = statsParts.join(" "), modelName = state.model?.id || "no-model", statsLeftWidth = visibleWidth(statsLeft);
1724
- statsLeftWidth > width && (statsLeft = truncateToWidth2(statsLeft, width, "..."), statsLeftWidth = visibleWidth(statsLeft));
1758
+ let statsLeft = statsParts.join(" "), modelName = state.model?.id || "no-model", statsLeftWidth = visibleWidth3(statsLeft);
1759
+ statsLeftWidth > width && (statsLeft = truncateToWidth3(statsLeft, width, "..."), statsLeftWidth = visibleWidth3(statsLeft));
1725
1760
  let minPadding = 2, rightSideWithoutProvider = modelName;
1726
1761
  if (state.model?.reasoning) {
1727
1762
  let thinkingLevel = state.thinkingLevel || "off";
1728
1763
  rightSideWithoutProvider = thinkingLevel === "off" ? `${modelName} \u2022 thinking off` : `${modelName} \u2022 ${thinkingLevel}`;
1729
1764
  }
1730
1765
  let rightSide = rightSideWithoutProvider;
1731
- this.footerData.getAvailableProviderCount() > 1 && state.model && (rightSide = `(${state.model.provider}) ${rightSideWithoutProvider}`, statsLeftWidth + minPadding + visibleWidth(rightSide) > width && (rightSide = rightSideWithoutProvider));
1732
- let rightSideWidth = visibleWidth(rightSide), totalNeeded = statsLeftWidth + minPadding + rightSideWidth, statsLine;
1766
+ this.footerData.getAvailableProviderCount() > 1 && state.model && (rightSide = `(${state.model.provider}) ${rightSideWithoutProvider}`, statsLeftWidth + minPadding + visibleWidth3(rightSide) > width && (rightSide = rightSideWithoutProvider));
1767
+ let rightSideWidth = visibleWidth3(rightSide), totalNeeded = statsLeftWidth + minPadding + rightSideWidth, statsLine;
1733
1768
  if (totalNeeded <= width) {
1734
1769
  let padding = " ".repeat(width - statsLeftWidth - rightSideWidth);
1735
1770
  statsLine = statsLeft + padding + rightSide;
1736
1771
  } else {
1737
1772
  let availableForRight = width - statsLeftWidth - minPadding;
1738
1773
  if (availableForRight > 0) {
1739
- let truncatedRight = truncateToWidth2(rightSide, availableForRight, ""), truncatedRightWidth = visibleWidth(truncatedRight), padding = " ".repeat(Math.max(0, width - statsLeftWidth - truncatedRightWidth));
1774
+ let truncatedRight = truncateToWidth3(rightSide, availableForRight, ""), truncatedRightWidth = visibleWidth3(truncatedRight), padding = " ".repeat(Math.max(0, width - statsLeftWidth - truncatedRightWidth));
1740
1775
  statsLine = statsLeft + padding + truncatedRight;
1741
1776
  } else
1742
1777
  statsLine = statsLeft;
1743
1778
  }
1744
- let dimStatsLeft = theme.fg("dim", statsLeft), remainder = statsLine.slice(statsLeft.length), dimRemainder = theme.fg("dim", remainder), lines = [truncateToWidth2(theme.fg("dim", pwd), width, theme.fg("dim", "...")), dimStatsLeft + dimRemainder], extensionStatuses = this.footerData.getExtensionStatuses();
1779
+ let dimStatsLeft = theme.fg("dim", statsLeft), remainder = statsLine.slice(statsLeft.length), dimRemainder = theme.fg("dim", remainder), lines = [truncateToWidth3(theme.fg("dim", pwd), width, theme.fg("dim", "...")), dimStatsLeft + dimRemainder], extensionStatuses = this.footerData.getExtensionStatuses();
1745
1780
  if (extensionStatuses.size > 0) {
1746
1781
  let statusLine = Array.from(extensionStatuses.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, text]) => sanitizeStatusText(text)).join(" ");
1747
- lines.push(truncateToWidth2(statusLine, width, theme.fg("dim", "...")));
1782
+ lines.push(truncateToWidth3(statusLine, width, theme.fg("dim", "...")));
1748
1783
  }
1749
1784
  return lines;
1750
1785
  }
1751
1786
  };
1752
1787
 
1753
1788
  // packages/coding-agent/dist/modes/interactive/components/usage-view.js
1754
- import { truncateToWidth as truncateToWidth3, visibleWidth as visibleWidth2 } from "@ashx-j/lunr-tui";
1789
+ import { truncateToWidth as truncateToWidth4, visibleWidth as visibleWidth4 } from "@ashx-j/lunr-tui";
1755
1790
  var BAR_CELLS = 20;
1756
1791
  function usageLevelColor(percent) {
1757
1792
  return percent > 90 ? "error" : percent > 70 ? "warning" : "success";
@@ -1789,9 +1824,9 @@ function planWindowLine(window, labelWidth) {
1789
1824
  return ` ${window.label.padEnd(labelWidth)} ${usageBar(window.usedPercent)} ${pct}${reset}`;
1790
1825
  }
1791
1826
  function renderThemedBox(headerText, content, maxWidth) {
1792
- let contentWidth = Math.max(...content.map((line) => visibleWidth2(line))), totalWidth = Math.max(24, Math.min(contentWidth + 4, Math.max(24, maxWidth))), innerWidth = totalWidth - 4, border = (text) => theme.fg("border", text), top = border(`\u256D${headerText}${"\u2500".repeat(Math.max(0, totalWidth - 2 - headerText.length))}\u256E`), bottom = border(`\u2570${"\u2500".repeat(totalWidth - 2)}\u256F`), lines = [top];
1827
+ let contentWidth = Math.max(...content.map((line) => visibleWidth4(line))), totalWidth = Math.max(24, Math.min(contentWidth + 4, Math.max(24, maxWidth))), innerWidth = totalWidth - 4, border = (text) => theme.fg("border", text), top = border(`\u256D${headerText}${"\u2500".repeat(Math.max(0, totalWidth - 2 - headerText.length))}\u256E`), bottom = border(`\u2570${"\u2500".repeat(totalWidth - 2)}\u256F`), lines = [top];
1793
1828
  for (let rawLine of content) {
1794
- let line = rawLine.length > 0 ? truncateToWidth3(rawLine, innerWidth, "") : "", padding = " ".repeat(Math.max(0, innerWidth - visibleWidth2(line)));
1829
+ let line = rawLine.length > 0 ? truncateToWidth4(rawLine, innerWidth, "") : "", padding = " ".repeat(Math.max(0, innerWidth - visibleWidth4(line)));
1795
1830
  lines.push(`${border("\u2502 ")}${line}${padding}${border(" \u2502")}`);
1796
1831
  }
1797
1832
  return lines.push(bottom), lines;
@@ -2568,7 +2603,7 @@ var PlanMessageComponent = class extends Container10 {
2568
2603
  };
2569
2604
 
2570
2605
  // packages/coding-agent/dist/modes/interactive/components/processes-selector.js
2571
- import { Container as Container11, getKeybindings as getKeybindings5, Spacer as Spacer12, Text as Text13, truncateToWidth as truncateToWidth4 } from "@ashx-j/lunr-tui";
2606
+ import { Container as Container11, getKeybindings as getKeybindings5, Spacer as Spacer12, Text as Text13, truncateToWidth as truncateToWidth5 } from "@ashx-j/lunr-tui";
2572
2607
  function formatElapsed(startedAt) {
2573
2608
  let ms = Date.now() - startedAt, s = Math.floor(ms / 1e3);
2574
2609
  if (s < 60)
@@ -2605,7 +2640,7 @@ var ProcessesSelectorComponent = class extends Container11 {
2605
2640
  continue;
2606
2641
  let elapsed = formatElapsed(p.startedAt), status;
2607
2642
  p.status === "exited" ? status = `exited(${p.exitCode ?? "?"})` : p.status === "paused" ? status = "paused" : status = "running";
2608
- let line = `${i === this.selected ? "\u25B8 " : " "}${p.pid} \xB7 ${status} \xB7 ${elapsed} \xB7 ${truncateToWidth4(p.command, 60)}`, colored = i === this.selected ? theme.fg("accent", line) : theme.fg("dim", line);
2643
+ let line = `${i === this.selected ? "\u25B8 " : " "}${p.pid} \xB7 ${status} \xB7 ${elapsed} \xB7 ${truncateToWidth5(p.command, 60)}`, colored = i === this.selected ? theme.fg("accent", line) : theme.fg("dim", line);
2609
2644
  this.addChild(new Text13(colored, 0, 0));
2610
2645
  }
2611
2646
  this.addChild(new Spacer12(1));
@@ -3580,6 +3615,14 @@ var ThemeSubmenu = class extends Container13 {
3580
3615
  values: ["true", "false"],
3581
3616
  disabled: () => config.hideThinkingBlock
3582
3617
  },
3618
+ {
3619
+ id: "reasoning-display",
3620
+ label: "Reasoning display",
3621
+ description: "Auto uses one line for OpenAI Codex, four lines for other models. One line has a soft moving highlight.",
3622
+ currentValue: config.reasoningDisplay ?? "auto",
3623
+ values: ["auto", "one-line", "four-lines"],
3624
+ disabled: () => config.hideThinkingBlock
3625
+ },
3583
3626
  {
3584
3627
  id: "cache-miss-notices",
3585
3628
  label: "Cache miss notices",
@@ -3680,8 +3723,8 @@ var ThemeSubmenu = class extends Container13 {
3680
3723
  id: "default-permission-mode",
3681
3724
  label: "Default permission mode",
3682
3725
  description: "Starting permission mode for new sessions",
3683
- currentValue: config.defaultPermissionMode,
3684
- values: ["manual", "yolo", "plan", "auto"]
3726
+ currentValue: config.defaultPermissionMode === "read-only" ? "read" : config.defaultPermissionMode,
3727
+ values: ["yolo", "auto", "read"]
3685
3728
  },
3686
3729
  {
3687
3730
  id: "double-escape-action",
@@ -3731,6 +3774,20 @@ var ThemeSubmenu = class extends Container13 {
3731
3774
  currentValue: config.modelInstructions.enabled ? "on" : "off",
3732
3775
  submenu: (_currentValue, done) => new ModelInstructionsSubmenu(config, callbacks, done)
3733
3776
  },
3777
+ {
3778
+ id: "subagent-communication",
3779
+ label: "Subagent communication",
3780
+ description: "Allow parent and child to exchange messages during a task",
3781
+ currentValue: config.subagentCommunicationEnabled ? "on" : "off",
3782
+ values: ["on", "off"]
3783
+ },
3784
+ {
3785
+ id: "automatic-subagent-delegation",
3786
+ label: "Automatic subagent delegation",
3787
+ description: "Let the agent decide when to delegate work",
3788
+ currentValue: config.automaticSubagentDelegation ? "on" : "off",
3789
+ values: ["on", "off"]
3790
+ },
3734
3791
  {
3735
3792
  id: "confirm-large-subagent-launches",
3736
3793
  label: "Confirm large subagent launches",
@@ -3909,6 +3966,9 @@ var ThemeSubmenu = class extends Container13 {
3909
3966
  case "thinking-collapse":
3910
3967
  callbacks.onThinkingCollapseChange(newValue === "true");
3911
3968
  break;
3969
+ case "reasoning-display":
3970
+ (newValue === "auto" || newValue === "one-line" || newValue === "four-lines") && callbacks.onReasoningDisplayChange(newValue);
3971
+ break;
3912
3972
  case "cache-miss-notices":
3913
3973
  callbacks.onShowCacheMissNoticesChange(newValue === "true");
3914
3974
  break;
@@ -3921,6 +3981,12 @@ var ThemeSubmenu = class extends Container13 {
3921
3981
  case "smooth-streaming":
3922
3982
  callbacks.onSmoothStreamingChange(newValue === "true");
3923
3983
  break;
3984
+ case "subagent-communication":
3985
+ callbacks.onSubagentCommunicationChange(newValue === "on");
3986
+ break;
3987
+ case "automatic-subagent-delegation":
3988
+ callbacks.onAutomaticSubagentDelegationChange(newValue === "on");
3989
+ break;
3924
3990
  case "plan-usage-window":
3925
3991
  callbacks.onPlanUsageWindowChange(newValue === "5h" ? "5h" : "weekly");
3926
3992
  break;
@@ -3948,7 +4014,7 @@ var ThemeSubmenu = class extends Container13 {
3948
4014
  break;
3949
4015
  }
3950
4016
  case "default-permission-mode":
3951
- callbacks.onDefaultPermissionModeChange(newValue);
4017
+ callbacks.onDefaultPermissionModeChange(newValue === "read" ? "read-only" : newValue);
3952
4018
  break;
3953
4019
  case "double-escape-action":
3954
4020
  callbacks.onDoubleEscapeActionChange(newValue);
@@ -4100,7 +4166,6 @@ var ToolExecutionComponent = class extends Container14 {
4100
4166
  hideComponent = !1;
4101
4167
  groupContinuation = !1;
4102
4168
  groupFollowed = !1;
4103
- groupPrev;
4104
4169
  groupNext;
4105
4170
  constructor(toolName, toolCallId, args, options = {}, toolDefinition, ui, cwd) {
4106
4171
  super(), this.toolName = toolName, this.toolCallId = toolCallId, this.args = args, this.toolDefinition = toolDefinition, this.builtInToolDefinition = createAllToolDefinitions(cwd)[toolName], this.showImages = options.showImages ?? !0, this.imageWidthCells = options.imageWidthCells ?? 60, this.ui = ui, this.cwd = cwd, this.topSpacer = new Spacer15(1), this.addChild(this.topSpacer), this.contentBox = new Box7(1, 1, (text) => theme.bg("toolPendingBg", text)), this.contentText = new Text17("", 1, 1, (text) => theme.bg("toolPendingBg", text)), this.selfRenderContainer = new Container14(), this.hasRendererDefinition() ? this.addChild(this.getRenderShell() === "self" ? this.selfRenderContainer : this.contentBox) : this.addChild(this.contentText), this.updateDisplay();
@@ -4144,13 +4209,18 @@ var ToolExecutionComponent = class extends Container14 {
4144
4209
  let state = this.isPartial ? "pending" : this.result?.isError ? "error" : "success";
4145
4210
  return toolStatusDot(state, theme);
4146
4211
  }
4212
+ getWaitDuration() {
4213
+ return this.toolName !== "subagent_wait" || this.isPartial || this.expanded ? void 0 : /^(?:Waited |Wait (?:timed out|aborted) after )(\d+(?:ms|[smhd])(?:\d+[smhd])*)\b/.exec(this.getTextOutput())?.[1];
4214
+ }
4147
4215
  createCallFallback() {
4216
+ let waitDuration = this.getWaitDuration();
4148
4217
  return new Text17(formatGroupedCall({
4149
4218
  role: toolGroupRole(this.groupContinuation, this.groupFollowed),
4150
4219
  compact: !this.isPartial && !this.expanded && !this.result?.isError,
4151
4220
  tree: toolGroupTree({ expanded: this.expanded, isError: this.result?.isError }),
4152
4221
  dot: this.getStatusDot(),
4153
- title: theme.fg("toolTitle", theme.bold(this.toolName))
4222
+ title: theme.fg("toolTitle", theme.bold(this.toolName)),
4223
+ detail: waitDuration && theme.fg("toolOutput", waitDuration)
4154
4224
  }), 0, 0);
4155
4225
  }
4156
4226
  createResultFallback() {
@@ -4185,16 +4255,30 @@ var ToolExecutionComponent = class extends Container14 {
4185
4255
  }
4186
4256
  }
4187
4257
  setExpanded(expanded) {
4188
- this.expanded = expanded, this.updateDisplay(), this.refreshGroupTail();
4258
+ this.toolName !== "browser" && (this.expanded = expanded, this.updateDisplay(), this.refreshGroupTail());
4189
4259
  }
4190
4260
  handleClick(_localY, _width) {
4191
- return this.isPartial || this.toolName === "subagent" || this.toolName === "subagent_wait" ? !1 : (this.setExpanded(!this.expanded), this.ui.requestRender(), !0);
4261
+ return this.isPartial || this.toolName === "browser" || this.toolName === "subagent" ? !1 : (this.setExpanded(!this.expanded), this.ui.requestRender(), !0);
4262
+ }
4263
+ beginNextExecution(toolCallId, args) {
4264
+ this.toolCallId = toolCallId, this.args = args, this.result = void 0, this.isPartial = !0, this.executionStarted = !1, this.argsComplete = !1, this.expanded = !1, this.disposeComponent(this.resultRendererComponent), this.resultRendererComponent = void 0, this.updateDisplay();
4265
+ }
4266
+ dispose() {
4267
+ let components = /* @__PURE__ */ new Set([this.callRendererComponent, this.resultRendererComponent]);
4268
+ for (let component of components)
4269
+ this.disposeComponent(component);
4270
+ }
4271
+ disposeComponent(component) {
4272
+ component?.dispose?.();
4192
4273
  }
4193
4274
  // lunr: consecutive same-tool grouping — exposes the tool name so the caller
4194
4275
  // can detect adjacency.
4195
4276
  getToolName() {
4196
4277
  return this.toolName;
4197
4278
  }
4279
+ matchesToolCall(toolCallId) {
4280
+ return this.toolCallId === toolCallId;
4281
+ }
4198
4282
  // lunr: consecutive same-tool grouping — continuation calls hide the top
4199
4283
  // spacer and top box pad so adjacent same-bg boxes read as one continuous
4200
4284
  // background; the last card in a run keeps its bottom pad.
@@ -4206,41 +4290,22 @@ var ToolExecutionComponent = class extends Container14 {
4206
4290
  setGroupFollowed(on) {
4207
4291
  this.groupFollowed = on, this.applyGroupPadding(), this.invalidate();
4208
4292
  }
4209
- // lunr: same-name run link so a later card can hoist earlier error bodies
4210
- // under the last leaf instead of splitting the tree.
4293
+ // lunr: same-name run link keeps the final card refreshed as earlier calls settle.
4211
4294
  linkGroupNext(next) {
4212
- this.groupNext = next, next.groupPrev = this;
4295
+ this.groupNext = next;
4213
4296
  }
4214
4297
  applyGroupPadding() {
4215
4298
  let top = this.groupContinuation ? 0 : 1, bottom = this.groupFollowed ? 0 : 1;
4216
4299
  this.contentBox.setPaddingTop(top), this.contentBox.setPaddingBottom(bottom), this.contentText.setPaddingTop(top), this.contentText.setPaddingBottom(bottom), this.getRenderShell() === "self" && this.callRendererComponent instanceof Box7 && (this.callRendererComponent.setPaddingTop(top), this.callRendererComponent.setPaddingBottom(bottom));
4217
4300
  }
4218
- shouldHideGroupedErrorBody() {
4219
- return !!this.result?.isError && this.groupFollowed && !this.expanded && !this.isPartial && this.getRenderShell() === "default" && this.toolName !== "subagent" && this.toolName !== "subagent_wait";
4220
- }
4221
4301
  shouldSkipCompactResult() {
4222
4302
  if (this.result === void 0 || this.isPartial || this.expanded)
4223
4303
  return !1;
4224
4304
  if (this.toolName === "subagent") {
4225
4305
  let details = this.result.details;
4226
- return !(this.result.isError || Array.isArray(details?.results) && details.results.length > 0 || details?.mode === "management");
4306
+ return !this.result.isError && this.args?.action === "steer" ? !0 : !(this.result.isError || Array.isArray(details?.results) && details.results.length > 0 || details?.mode === "management");
4227
4307
  }
4228
- return this.result.isError ? this.shouldHideGroupedErrorBody() : this.getRenderShell() === "default";
4229
- }
4230
- formatHoistedGroupErrors() {
4231
- if (this.groupFollowed || this.expanded)
4232
- return;
4233
- let texts = [], prev = this.groupPrev;
4234
- for (; prev; ) {
4235
- if (prev.shouldHideGroupedErrorBody()) {
4236
- let output = prev.getTextOutput().trim();
4237
- output && texts.unshift(output);
4238
- }
4239
- prev = prev.groupPrev;
4240
- }
4241
- return texts.length > 0 ? `
4242
- ${texts.join(`
4243
- `)}` : void 0;
4308
+ return this.toolName === "subagent_wait" || this.result.isError ? !0 : this.getRenderShell() === "default";
4244
4309
  }
4245
4310
  refreshGroupTail() {
4246
4311
  let next = this.groupNext;
@@ -4308,8 +4373,6 @@ ${texts.join(`
4308
4373
  let component = this.createResultFallback();
4309
4374
  component && (renderContainer.addChild(component), hasContent = !0);
4310
4375
  }
4311
- let hoisted = this.formatHoistedGroupErrors();
4312
- hoisted && (renderContainer.addChild(new Text17(theme.fg("toolOutput", hoisted), 0, 0)), hasContent = !0);
4313
4376
  }
4314
4377
  } else
4315
4378
  this.contentText.setCustomBgFn(bgFn), this.contentText.setText(this.formatToolExecution()), hasContent = !0;
@@ -4339,12 +4402,13 @@ ${texts.join(`
4339
4402
  return getTextOutput(this.result, this.showImages);
4340
4403
  }
4341
4404
  formatToolExecution() {
4342
- let hideGroupedErrorBody = !!(this.result?.isError && this.groupFollowed && !this.expanded), compact = !this.isPartial && !this.expanded && (!this.result?.isError || hideGroupedErrorBody), text = formatGroupedCall({
4405
+ let compact = !this.isPartial && !this.expanded, waitDuration = this.getWaitDuration(), text = formatGroupedCall({
4343
4406
  role: toolGroupRole(this.groupContinuation, this.groupFollowed),
4344
4407
  compact,
4345
4408
  tree: toolGroupTree({ expanded: this.expanded, isError: this.result?.isError }),
4346
4409
  dot: this.getStatusDot(),
4347
- title: theme.fg("toolTitle", theme.bold(this.toolName))
4410
+ title: theme.fg("toolTitle", theme.bold(this.toolName)),
4411
+ detail: waitDuration && theme.fg("toolOutput", waitDuration)
4348
4412
  });
4349
4413
  if (!compact) {
4350
4414
  let content = JSON.stringify(this.args, null, 2);
@@ -4355,8 +4419,7 @@ ${content}`);
4355
4419
  output && (text += `
4356
4420
  ${output}`);
4357
4421
  }
4358
- let hoisted = this.formatHoistedGroupErrors();
4359
- return hoisted && (text += hoisted), text;
4422
+ return text;
4360
4423
  }
4361
4424
  };
4362
4425
  function applySameToolGrouping(previous, next) {
@@ -4364,7 +4427,7 @@ function applySameToolGrouping(previous, next) {
4364
4427
  }
4365
4428
 
4366
4429
  // packages/coding-agent/dist/modes/interactive/components/tree-selector.js
4367
- import { Container as Container15, getKeybindings as getKeybindings8, Input as Input6, Spacer as Spacer16, sliceByColumn, Text as Text18, truncateToWidth as truncateToWidth5, visibleWidth as visibleWidth3, wrapTextWithAnsi as wrapTextWithAnsi2 } from "@ashx-j/lunr-tui";
4430
+ import { Container as Container15, getKeybindings as getKeybindings8, Input as Input6, Spacer as Spacer16, sliceByColumn, Text as Text18, truncateToWidth as truncateToWidth6, visibleWidth as visibleWidth5, wrapTextWithAnsi as wrapTextWithAnsi2 } from "@ashx-j/lunr-tui";
4368
4431
  var TREE_GUTTER_WIDTH = 2, MIN_VISIBLE_ANCHOR_CONTENT_WIDTH = 4, MAX_VISIBLE_ANCHOR_CONTENT_WIDTH = 20, MIN_ANCHOR_CONTEXT_WIDTH = 2, MAX_ANCHOR_CONTEXT_WIDTH = 12;
4369
4432
  function renderHorizontalViewport(rows, width) {
4370
4433
  let viewportWidth = Math.max(0, width - TREE_GUTTER_WIDTH), maxBodyWidth = rows.reduce((max, row) => Math.max(max, row.bodyWidth), 0), maxHorizontalScroll = Math.max(0, maxBodyWidth - viewportWidth), selectedRow = rows.find((row) => row.isSelected), horizontalScroll = 0;
@@ -4377,7 +4440,7 @@ function renderHorizontalViewport(rows, width) {
4377
4440
  }
4378
4441
  return rows.map((row) => {
4379
4442
  let line = horizontalScroll > 0 ? `${row.gutter}${sliceByColumn(row.body, horizontalScroll, viewportWidth, !0)}\x1B[0m` : row.gutter + row.body;
4380
- return truncateToWidth5(line, width, "");
4443
+ return truncateToWidth6(line, width, "");
4381
4444
  });
4382
4445
  }
4383
4446
  var TreeList = class {
@@ -4695,7 +4758,7 @@ var TreeList = class {
4695
4758
  render(width) {
4696
4759
  let lines = [];
4697
4760
  if (this.filteredNodes.length === 0)
4698
- return lines.push(truncateToWidth5(theme.fg("muted", " No entries found"), width)), lines.push(truncateToWidth5(theme.fg("muted", ` (0/0)${this.getStatusLabels()}`), width)), lines;
4761
+ return lines.push(truncateToWidth6(theme.fg("muted", " No entries found"), width)), lines.push(truncateToWidth6(theme.fg("muted", ` (0/0)${this.getStatusLabels()}`), width)), lines;
4699
4762
  let startIndex = Math.max(0, Math.min(this.selectedIndex - Math.floor(this.maxVisibleLines / 2), this.filteredNodes.length - this.maxVisibleLines)), endIndex = Math.min(startIndex + this.maxVisibleLines, this.filteredNodes.length), renderedRows = [];
4700
4763
  for (let i = startIndex; i < endIndex; i++) {
4701
4764
  let flatNode = this.filteredNodes[i], entry = flatNode.node.entry, isSelected = i === this.selectedIndex, cursor = isSelected ? theme.fg("accent", "\u203A ") : " ", displayIndent = this.multipleRoots ? Math.max(0, flatNode.indent - 1) : flatNode.indent, connector = flatNode.showConnector && !flatNode.isVirtualRootChild ? flatNode.isLast ? "\u2514\u2500 " : "\u251C\u2500 " : "", connectorPosition = connector ? displayIndent - 1 : -1, totalChars = displayIndent * 3, prefixChars = [], isFolded = this.foldedNodes.has(entry.id);
@@ -4714,10 +4777,10 @@ var TreeList = class {
4714
4777
  else
4715
4778
  prefixChars.push(" ");
4716
4779
  }
4717
- let prefix = prefixChars.join(""), showsFoldInConnector = flatNode.showConnector && !flatNode.isVirtualRootChild, foldMarker = isFolded && !showsFoldInConnector ? theme.fg("accent", "\u229E ") : "", pathMarker = this.activePathIds.has(entry.id) ? theme.fg("accent", "\u2022 ") : "", label = flatNode.node.label ? theme.fg("warning", `[${flatNode.node.label}] `) : "", labelTimestamp = this.showLabelTimestamps && flatNode.node.label && flatNode.node.labelTimestamp ? theme.fg("muted", `${this.formatLabelTimestamp(flatNode.node.labelTimestamp)} `) : "", content = this.getEntryDisplayText(flatNode.node, isSelected), prefixPart = theme.fg("dim", prefix) + foldMarker + pathMarker, anchorCol = visibleWidth3(prefixPart), gutter = cursor, body = prefixPart + label + labelTimestamp + content;
4718
- isSelected && (gutter = theme.bg("selectedBg", gutter), body = theme.bg("selectedBg", body)), renderedRows.push({ gutter, body, anchorCol, bodyWidth: visibleWidth3(body), isSelected });
4780
+ let prefix = prefixChars.join(""), showsFoldInConnector = flatNode.showConnector && !flatNode.isVirtualRootChild, foldMarker = isFolded && !showsFoldInConnector ? theme.fg("accent", "\u229E ") : "", pathMarker = this.activePathIds.has(entry.id) ? theme.fg("accent", "\u2022 ") : "", label = flatNode.node.label ? theme.fg("warning", `[${flatNode.node.label}] `) : "", labelTimestamp = this.showLabelTimestamps && flatNode.node.label && flatNode.node.labelTimestamp ? theme.fg("muted", `${this.formatLabelTimestamp(flatNode.node.labelTimestamp)} `) : "", content = this.getEntryDisplayText(flatNode.node, isSelected), prefixPart = theme.fg("dim", prefix) + foldMarker + pathMarker, anchorCol = visibleWidth5(prefixPart), gutter = cursor, body = prefixPart + label + labelTimestamp + content;
4781
+ isSelected && (gutter = theme.bg("selectedBg", gutter), body = theme.bg("selectedBg", body)), renderedRows.push({ gutter, body, anchorCol, bodyWidth: visibleWidth5(body), isSelected });
4719
4782
  }
4720
- return lines.push(...renderHorizontalViewport(renderedRows, width)), lines.push(truncateToWidth5(theme.fg("muted", ` (${this.selectedIndex + 1}/${this.filteredNodes.length})${this.getStatusLabels()}`), width)), lines;
4783
+ return lines.push(...renderHorizontalViewport(renderedRows, width)), lines.push(truncateToWidth6(theme.fg("muted", ` (${this.selectedIndex + 1}/${this.filteredNodes.length})${this.getStatusLabels()}`), width)), lines;
4721
4784
  }
4722
4785
  getEntryDisplayText(node, isSelected) {
4723
4786
  let entry = node.entry, result, normalize = (s) => s.replace(/[\n\t]/g, " ").trim();
@@ -4976,7 +5039,7 @@ var TreeList = class {
4976
5039
  }
4977
5040
  render(width) {
4978
5041
  let query = this.treeList.getSearchQuery();
4979
- return query ? [truncateToWidth5(` ${theme.fg("muted", "Type to search:")} ${theme.fg("accent", query)}`, width)] : [truncateToWidth5(` ${theme.fg("muted", "Type to search:")}`, width)];
5042
+ return query ? [truncateToWidth6(` ${theme.fg("muted", "Type to search:")} ${theme.fg("accent", query)}`, width)] : [truncateToWidth6(` ${theme.fg("muted", "Type to search:")}`, width)];
4980
5043
  }
4981
5044
  handleInput(_keyData) {
4982
5045
  }
@@ -4989,12 +5052,12 @@ var TreeList = class {
4989
5052
  return text ? labelFirst ? `${label} ${text}` : `${text} ${label}` : label;
4990
5053
  }), availableWidth = Math.max(1, width), indent = " ", separator = " \xB7 ", lines = [], currentLine = "";
4991
5054
  for (let item of items) {
4992
- let candidate = currentLine ? `${currentLine}${separator}${item}` : visibleWidth3(`${indent}${item}`) <= availableWidth ? `${indent}${item}` : item;
4993
- if (!currentLine || visibleWidth3(candidate) <= availableWidth) {
5055
+ let candidate = currentLine ? `${currentLine}${separator}${item}` : visibleWidth5(`${indent}${item}`) <= availableWidth ? `${indent}${item}` : item;
5056
+ if (!currentLine || visibleWidth5(candidate) <= availableWidth) {
4994
5057
  currentLine = candidate;
4995
5058
  continue;
4996
5059
  }
4997
- lines.push(...wrapTextWithAnsi2(currentLine.trimEnd(), availableWidth)), currentLine = visibleWidth3(`${indent}${item}`) <= availableWidth ? `${indent}${item}` : item;
5060
+ lines.push(...wrapTextWithAnsi2(currentLine.trimEnd(), availableWidth)), currentLine = visibleWidth5(`${indent}${item}`) <= availableWidth ? `${indent}${item}` : item;
4998
5061
  }
4999
5062
  return currentLine && lines.push(...wrapTextWithAnsi2(currentLine.trimEnd(), availableWidth)), lines.map((line) => theme.fg("muted", line));
5000
5063
  }
@@ -5055,7 +5118,7 @@ var LabelInput = class {
5055
5118
  }
5056
5119
  render(width) {
5057
5120
  let lines = [], availableWidth = width - 2;
5058
- return lines.push(truncateToWidth5(` ${theme.fg("muted", "Label (empty to remove):")}`, width)), lines.push(...this.input.render(availableWidth).map((line) => truncateToWidth5(` ${line}`, width))), lines.push(truncateToWidth5(` ${keyHint("tui.select.confirm", "save")} ${keyHint("tui.select.cancel", "cancel")}`, width)), lines;
5121
+ return lines.push(truncateToWidth6(` ${theme.fg("muted", "Label (empty to remove):")}`, width)), lines.push(...this.input.render(availableWidth).map((line) => truncateToWidth6(` ${line}`, width))), lines.push(truncateToWidth6(` ${keyHint("tui.select.confirm", "save")} ${keyHint("tui.select.cancel", "cancel")}`, width)), lines;
5059
5122
  }
5060
5123
  handleInput(keyData) {
5061
5124
  let kb = getKeybindings8();
@@ -5172,7 +5235,7 @@ var OSC133_ZONE_START2 = "\x1B]133;A\x07", OSC133_ZONE_END2 = "\x1B]133;B\x07",
5172
5235
  };
5173
5236
 
5174
5237
  // packages/coding-agent/dist/modes/interactive/components/user-message-selector.js
5175
- import { Container as Container18, getKeybindings as getKeybindings10, Spacer as Spacer18, Text as Text20, truncateToWidth as truncateToWidth6 } from "@ashx-j/lunr-tui";
5238
+ import { Container as Container18, getKeybindings as getKeybindings10, Spacer as Spacer18, Text as Text20, truncateToWidth as truncateToWidth7 } from "@ashx-j/lunr-tui";
5176
5239
  var UserMessageList = class {
5177
5240
  messages = [];
5178
5241
  selectedIndex = 0;
@@ -5193,7 +5256,7 @@ var UserMessageList = class {
5193
5256
  return lines.push(theme.fg("muted", " No user messages found")), lines;
5194
5257
  let startIndex = Math.max(0, Math.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.messages.length - this.maxVisible)), endIndex = Math.min(startIndex + this.maxVisible, this.messages.length);
5195
5258
  for (let i = startIndex; i < endIndex; i++) {
5196
- let message = this.messages[i], isSelected = i === this.selectedIndex, normalizedMessage = message.text.replace(/\n/g, " ").trim(), cursor = isSelected ? theme.fg("accent", "\u203A ") : " ", maxMsgWidth = width - 2, truncatedMsg = truncateToWidth6(normalizedMessage, maxMsgWidth), messageLine = cursor + (isSelected ? theme.bold(truncatedMsg) : truncatedMsg);
5259
+ let message = this.messages[i], isSelected = i === this.selectedIndex, normalizedMessage = message.text.replace(/\n/g, " ").trim(), cursor = isSelected ? theme.fg("accent", "\u203A ") : " ", maxMsgWidth = width - 2, truncatedMsg = truncateToWidth7(normalizedMessage, maxMsgWidth), messageLine = cursor + (isSelected ? theme.bold(truncatedMsg) : truncatedMsg);
5197
5260
  lines.push(messageLine);
5198
5261
  let metadata = ` Message ${i + 1} of ${this.messages.length}`, metadataLine = theme.fg("muted", metadata);
5199
5262
  lines.push(metadataLine), lines.push("");
@@ -5502,7 +5565,7 @@ function isDeadTerminalError(error) {
5502
5565
  let code = error.code;
5503
5566
  return code !== void 0 && DEAD_TERMINAL_ERROR_CODES.has(code);
5504
5567
  }
5505
- var ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage.", ANTHROPIC_TOS_DISCLAIMER = "Connecting an Anthropic subscription (Claude Pro/Max) account to lunR may violate Anthropic's Terms of Service (https://www.anthropic.com/legal/consumer-terms). Third-party harness usage also draws from paid extra usage, not your plan limits. Continue?", INIT_PROMPT = `Analyze this codebase and write a starter AGENTS.md in the project root.
5568
+ var ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Claude Code handles Anthropic subscription authentication. lunR retains tool execution and conversation state. Check your Claude account for usage and any extra charges.", ANTHROPIC_TOS_DISCLAIMER = "Connecting an Anthropic subscription through Claude Code may be subject to Anthropic's Terms of Service (https://www.anthropic.com/legal/consumer-terms). Claude Code authenticates each lunR generation; lunR keeps its own tools and history. Continue?", INIT_PROMPT = `Analyze this codebase and write a starter AGENTS.md in the project root.
5506
5569
  Scan: package manifests, directory layout, build/test/lint scripts, CI config,
5507
5570
  existing README/docs. Include only: project purpose (one paragraph), build &
5508
5571
  test commands, code style/conventions found, directory map, and agent rules
@@ -5615,8 +5678,10 @@ var InteractiveMode = class _InteractiveMode {
5615
5678
  streamingTargetMessage = void 0;
5616
5679
  streamingDisplayedLength = 0;
5617
5680
  smoothStreamingTimer = void 0;
5681
+ thinkingAnimationTimer;
5618
5682
  // Tool execution tracking: toolCallId -> component
5619
5683
  pendingTools = /* @__PURE__ */ new Map();
5684
+ browserActivityComponent;
5620
5685
  // Tool output expansion state
5621
5686
  toolOutputExpanded = !1;
5622
5687
  // Thinking block visibility state
@@ -5635,8 +5700,7 @@ var InteractiveMode = class _InteractiveMode {
5635
5700
  signalCleanupHandlers = [];
5636
5701
  // Track if editor is in bash mode (text starts with !)
5637
5702
  isBashMode = !1;
5638
- // lunr: mode in effect before the current plan stretch. Used by approve / `/plan off`
5639
- // / `/plan <text>` to leave plan. Shift+Tab and `/mode` pick the destination themselves.
5703
+ // Restore the previous mode after approving a plan or leaving read-only via /plan.
5640
5704
  previousPermissionMode;
5641
5705
  // lunr: mode in effect before `/goal` forced session auto. Dedicated so it cannot
5642
5706
  // collide with plan restore.
@@ -5823,9 +5887,13 @@ var InteractiveMode = class _InteractiveMode {
5823
5887
  return this.showLargeSubagentLaunchApprovalDialog(req);
5824
5888
  if (req.kind === "plan") {
5825
5889
  let resp = await this.showPlanApprovalDialog(req.detail);
5826
- return (typeof resp == "string" ? resp : resp.decision) !== "reject" && this.applyPermissionMode(this.restoreTargetAfterPlan()), resp;
5890
+ if ((typeof resp == "string" ? resp : resp.decision) !== "reject") {
5891
+ let target = this.restoreTargetAfterPlan();
5892
+ this.applyPermissionMode(target === "read-only" ? "yolo" : target);
5893
+ }
5894
+ return resp;
5827
5895
  }
5828
- return this.showApprovalDialog(req);
5896
+ return "reject";
5829
5897
  }), initRollback(this.settingsManager, this.sessionManager.getSessionId()), setRollbackWarningHandler((msg) => this.showStatus(msg)), this.syncPermissionModeEffects(this.sessionManager.getPermissionMode() ?? this.settingsManager.getDefaultPermissionMode()), await this.themeController.applyFromSettings(), this.headerContainer.clear(), this.options.verbose || !this.settingsManager.getQuietStartup()) {
5830
5898
  let header = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
5831
5899
  this.builtInHeader = new BootScreenComponent(header, this.buildBootRows()), this.headerContainer.addChild(new Spacer19(1)), this.headerContainer.addChild(this.builtInHeader);
@@ -6313,7 +6381,7 @@ ${warningLines}`, 0, 0)), this.loadedResourcesContainer.addChild(new Spacer19(1)
6313
6381
  replaceInstructions: options?.replaceInstructions,
6314
6382
  label: options?.label
6315
6383
  });
6316
- return result.cancelled ? { cancelled: !0 } : (this.chatContainer.clear(), this.renderInitialMessages(), result.editorText && !this.editor.getText().trim() && this.restoreEditorFromTreeResult(result), this.showStatus("Navigated to selected point"), this.flushCompactionQueue({ willRetry: !1 }), { cancelled: !1 });
6384
+ return result.cancelled ? { cancelled: !0 } : (this.clearChatContainer(), this.renderInitialMessages(), result.editorText && !this.editor.getText().trim() && this.restoreEditorFromTreeResult(result), this.showStatus("Navigated to selected point"), this.flushCompactionQueue({ willRetry: !1 }), { cancelled: !1 });
6317
6385
  },
6318
6386
  switchSession: async (sessionPath, options) => this.handleResumeSession(sessionPath, options),
6319
6387
  reload: async () => {
@@ -6364,7 +6432,7 @@ ${warningLines}`, 0, 0)), this.loadedResourcesContainer.addChild(new Spacer19(1)
6364
6432
  this.showError(`${prefix}: ${message}`), stopThemeWatcher(), this.stop(), process.exit(1);
6365
6433
  }
6366
6434
  renderCurrentSessionState() {
6367
- this.ui.setChatScroll(0), this.loadedResourcesContainer.clear(), this.chatContainer.clear(), this.pendingMessagesContainer.clear(), this.compactionQueuedMessages = [], this.pendingCompactionRender = void 0, this.stopSmoothStreaming(), this.streamingComponent = void 0, this.streamingMessage = void 0, this.pendingTools.clear(), this.renderInitialMessages();
6435
+ this.ui.setChatScroll(0), this.loadedResourcesContainer.clear(), this.clearChatContainer(), this.pendingMessagesContainer.clear(), this.compactionQueuedMessages = [], this.pendingCompactionRender = void 0, this.stopSmoothStreaming(), this.streamingComponent = void 0, this.streamingMessage = void 0, this.pendingTools.clear(), this.renderInitialMessages();
6368
6436
  }
6369
6437
  /**
6370
6438
  * Get a registered tool definition by name (for custom rendering).
@@ -6907,7 +6975,7 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
6907
6975
  }
6908
6976
  return;
6909
6977
  }
6910
- if (text && !this.runtimeHost.isDetached && (!text.startsWith("/") || /^\/(?:model|thinking|effort|reasoning|off|minimal|low|medium|high|xhigh|max|mode|plan|manual|yolo|auto|name|title|undo|edit|redo|tree|compact)(?:\s|$)/.test(text)) && recordTuiActivity(this.sessionManager, this.runtimeHost.services.agentDir), !text) {
6978
+ if (text && !this.runtimeHost.isDetached && (!text.startsWith("/") || /^\/(?:model|thinking|effort|reasoning|off|minimal|low|medium|high|xhigh|max|mode|plan|read|yolo|auto|name|title|undo|edit|redo|tree|compact)(?:\s|$)/.test(text)) && recordTuiActivity(this.sessionManager, this.runtimeHost.services.agentDir), !text) {
6911
6979
  this.takeSubmittedImages(text);
6912
6980
  return;
6913
6981
  }
@@ -7005,8 +7073,8 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7005
7073
  this.editor.setText(""), this.handleModeCommand(text === "/mode" ? "" : text.slice(6).trim());
7006
7074
  return;
7007
7075
  }
7008
- if (text === "/manual" || text === "/yolo" || text === "/auto") {
7009
- this.editor.setText(""), this.applyPermissionMode(text.slice(1));
7076
+ if (text === "/read" || text === "/yolo" || text === "/auto") {
7077
+ this.editor.setText(""), this.applyPermissionMode(text === "/read" ? "read-only" : text.slice(1));
7010
7078
  return;
7011
7079
  }
7012
7080
  if (text === "/processes") {
@@ -7078,9 +7146,21 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7078
7146
  this.isExtensionCommand(text) ? (this.editor.addToHistory?.(text), this.editor.setText(""), await this.promptAfterDeferredBuiltins(text)) : this.queueCompactionMessage(text, "steer", images);
7079
7147
  return;
7080
7148
  }
7081
- if (this.session.isStreaming) {
7082
- this.editor.addToHistory?.(text), this.editor.setText(""), await this.promptAfterDeferredBuiltins(text, { streamingBehavior: "steer", images }), this.updatePendingMessagesDisplay(), this.ui.requestRender();
7083
- return;
7149
+ if (this.session.isStreaming || this.session.isWaitPromptHandoffActive) {
7150
+ if (!this.isExtensionCommand(text)) {
7151
+ await this.awaitDeferredBuiltinsForPrompt();
7152
+ let handoff = await this.session.interruptSubagentWaitWithPrompt(text, { images });
7153
+ if (handoff) {
7154
+ this.editor.addToHistory?.(text), this.editor.setText(""), handoff.completion.catch((error) => {
7155
+ this.showError(error instanceof Error ? error.message : String(error));
7156
+ }), this.ui.requestRender();
7157
+ return;
7158
+ }
7159
+ }
7160
+ if (this.session.isStreaming) {
7161
+ this.editor.addToHistory?.(text), this.editor.setText(""), await this.promptAfterDeferredBuiltins(text, { streamingBehavior: "steer", images }), this.updatePendingMessagesDisplay(), this.ui.requestRender();
7162
+ return;
7163
+ }
7084
7164
  }
7085
7165
  this.flushPendingBashComponents(), this.onInputCallback ? this.onInputCallback({ text, images }) : this.pendingUserInputs.push({ text, images }), this.editor.addToHistory?.(text);
7086
7166
  };
@@ -7090,6 +7170,13 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7090
7170
  getSmoothStreamingOptions() {
7091
7171
  return { hideThinking: this.hideThinkingBlock };
7092
7172
  }
7173
+ setThinkingAnimation(active) {
7174
+ if (!active) {
7175
+ this.thinkingAnimationTimer && clearInterval(this.thinkingAnimationTimer), this.thinkingAnimationTimer = void 0;
7176
+ return;
7177
+ }
7178
+ this.thinkingAnimationTimer || (this.thinkingAnimationTimer = setInterval(() => this.ui.requestRender(), 33), this.thinkingAnimationTimer.unref?.());
7179
+ }
7093
7180
  clearSmoothStreamingTimer() {
7094
7181
  this.smoothStreamingTimer && (clearInterval(this.smoothStreamingTimer), this.smoothStreamingTimer = void 0);
7095
7182
  }
@@ -7120,11 +7207,8 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7120
7207
  let component = this.pendingTools.get(content.id);
7121
7208
  component && component.updateArgs(content.arguments);
7122
7209
  } else {
7123
- let component = new ToolExecutionComponent(content.name, content.id, content.arguments, {
7124
- showImages: this.settingsManager.getShowImages(),
7125
- imageWidthCells: this.settingsManager.getImageWidthCells()
7126
- }, this.getRegisteredToolDefinition(content.name), this.ui, this.sessionManager.getCwd());
7127
- component.setExpanded(this.toolOutputExpanded), this.addToolComponentToChat(component), this.pendingTools.set(content.id, component);
7210
+ let component = content.name === "browser" && this.browserActivityComponent ? this.browserActivityComponent : this.createToolExecutionComponent(content.name, content.id, content.arguments);
7211
+ this.pendingTools.set(content.id, component);
7128
7212
  }
7129
7213
  }
7130
7214
  advanceSmoothStreaming() {
@@ -7142,7 +7226,7 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7142
7226
  this.streamingDisplayedLength += computeSmoothRevealStep(backlog), this.streamingDisplayedLength > total && (this.streamingDisplayedLength = total), this.paintSmoothStreamingFrame(), this.streamingDisplayedLength >= total && this.clearSmoothStreamingTimer();
7143
7227
  }
7144
7228
  stopSmoothStreaming() {
7145
- this.clearSmoothStreamingTimer(), this.streamingTargetMessage = void 0, this.streamingDisplayedLength = 0;
7229
+ this.setThinkingAnimation(!1), this.clearSmoothStreamingTimer(), this.streamingTargetMessage = void 0, this.streamingDisplayedLength = 0;
7146
7230
  }
7147
7231
  /** Apply a mid-stream smoothStreaming setting change without rewinding. */
7148
7232
  applySmoothStreamingSettingChange(enabled) {
@@ -7164,7 +7248,7 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7164
7248
  async handleEvent(event) {
7165
7249
  switch (this.isInitialized || await this.init(), this.footer.invalidate(), event.type) {
7166
7250
  case "agent_start":
7167
- this.pendingTools.clear(), this.settingsManager.getShowTerminalProgress() && this.ui.terminal.setProgress(!0), this.retryEscapeHandler && (this.defaultEditor.onEscape = this.retryEscapeHandler, this.retryEscapeHandler = void 0), this.workingVisible ? this.showStatusIndicator(new WorkingStatusIndicator(this.ui, this.workingMessage ?? this.defaultWorkingMessage, this.workingIndicatorOptions)) : this.clearStatusIndicator(), this.ui.requestRender();
7251
+ this.pendingTools.clear(), this.browserActivityComponent = void 0, this.settingsManager.getShowTerminalProgress() && this.ui.terminal.setProgress(!0), this.retryEscapeHandler && (this.defaultEditor.onEscape = this.retryEscapeHandler, this.retryEscapeHandler = void 0), this.workingVisible ? this.showStatusIndicator(new WorkingStatusIndicator(this.ui, this.workingMessage ?? this.defaultWorkingMessage, this.workingIndicatorOptions)) : this.clearStatusIndicator(), this.ui.requestRender();
7168
7252
  break;
7169
7253
  case "queue_update":
7170
7254
  this.updatePendingMessagesDisplay(), this.ui.requestRender();
@@ -7179,7 +7263,11 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7179
7263
  this.footer.invalidate(), this.updateEditorBorderColor();
7180
7264
  break;
7181
7265
  case "message_start":
7182
- event.message.role === "custom" ? (this.addMessageToChat(event.message), this.ui.requestRender()) : event.message.role === "user" ? (this.redoStack.length = 0, beginTurn(this.sessionManager.getCwd(), this.sessionManager.getSessionId()), this.stopSmoothStreaming(), this.addMessageToChat(event.message), this.updatePendingMessagesDisplay(), this.ui.requestRender()) : event.message.role === "assistant" && (this.streamingComponent = new AssistantMessageComponent(void 0, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.thinkingCollapse, { requestRender: () => this.ui.requestRender() }), this.thinkingRunTimings = [], this.streamingComponent.setThinkingTimings(this.thinkingRunTimings), this.streamingComponent.setExpanded(this.toolOutputExpanded), this.streamingMessage = event.message, this.streamingTargetMessage = event.message, this.streamingDisplayedLength = 0, this.chatContainer.addChild(this.streamingComponent), this.settingsManager.getSmoothStreaming() ? this.streamingComponent.updateContent(sliceMessageContent(this.streamingMessage, 0, this.getSmoothStreamingOptions()), { thinkingSource: this.streamingMessage }) : this.streamingComponent.updateContent(this.streamingMessage), this.ui.requestRender());
7266
+ event.message.role === "custom" ? (this.addMessageToChat(event.message), this.ui.requestRender()) : event.message.role === "user" ? (this.redoStack.length = 0, beginTurn(this.sessionManager.getCwd(), this.sessionManager.getSessionId()), this.stopSmoothStreaming(), this.addMessageToChat(event.message), this.updatePendingMessagesDisplay(), this.ui.requestRender()) : event.message.role === "assistant" && (this.streamingComponent = new AssistantMessageComponent(void 0, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.thinkingCollapse, {
7267
+ requestRender: () => this.ui.requestRender(),
7268
+ reasoningDisplay: this.settingsManager.getReasoningDisplay(),
7269
+ onThinkingAnimationChange: (active) => this.setThinkingAnimation(active)
7270
+ }), this.thinkingRunTimings = [], this.streamingComponent.setThinkingTimings(this.thinkingRunTimings), this.streamingComponent.setExpanded(this.toolOutputExpanded), this.streamingMessage = event.message, this.streamingTargetMessage = event.message, this.streamingDisplayedLength = 0, this.chatContainer.addChild(this.streamingComponent), this.settingsManager.getSmoothStreaming() ? this.streamingComponent.updateContent(sliceMessageContent(this.streamingMessage, 0, this.getSmoothStreamingOptions()), { thinkingSource: this.streamingMessage }) : this.streamingComponent.updateContent(this.streamingMessage), this.ui.requestRender());
7183
7271
  break;
7184
7272
  case "message_update":
7185
7273
  if (this.streamingComponent && event.message.role === "assistant")
@@ -7222,10 +7310,7 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7222
7310
  this.streamingDisplayedLength < needed && (this.streamingDisplayedLength = needed), this.paintSmoothStreamingFrame();
7223
7311
  }
7224
7312
  let component = this.pendingTools.get(event.toolCallId);
7225
- component || (component = new ToolExecutionComponent(event.toolName, event.toolCallId, event.args, {
7226
- showImages: this.settingsManager.getShowImages(),
7227
- imageWidthCells: this.settingsManager.getImageWidthCells()
7228
- }, this.getRegisteredToolDefinition(event.toolName), this.ui, this.sessionManager.getCwd()), component.setExpanded(this.toolOutputExpanded), this.addToolComponentToChat(component), this.pendingTools.set(event.toolCallId, component)), component.markExecutionStarted(), this.ui.requestRender();
7313
+ component ? event.toolName === "browser" && !component.matchesToolCall(event.toolCallId) && component.beginNextExecution(event.toolCallId, event.args) : (component = this.createToolExecutionComponent(event.toolName, event.toolCallId, event.args), this.pendingTools.set(event.toolCallId, component)), component.markExecutionStarted(), this.ui.requestRender();
7229
7314
  break;
7230
7315
  }
7231
7316
  case "tool_execution_update": {
@@ -7239,7 +7324,7 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7239
7324
  break;
7240
7325
  }
7241
7326
  case "agent_end":
7242
- this.session.refreshModelFromRegistry(), this.settingsManager.getShowTerminalProgress() && this.ui.terminal.setProgress(!1), this.clearStatusIndicator("working"), this.stopSmoothStreaming(), this.streamingComponent && (this.chatContainer.removeChild(this.streamingComponent), this.streamingComponent = void 0, this.streamingMessage = void 0), this.pendingTools.clear(), this.maybeAutoNameSession(), captureTreeChanges(this.sessionManager.getCwd(), this.sessionManager.getSessionId()), this.ui.requestRender();
7327
+ this.session.refreshModelFromRegistry(), this.settingsManager.getShowTerminalProgress() && this.ui.terminal.setProgress(!1), this.clearStatusIndicator("working"), this.stopSmoothStreaming(), this.streamingComponent && (this.chatContainer.removeChild(this.streamingComponent), this.streamingComponent = void 0, this.streamingMessage = void 0), this.pendingTools.clear(), this.browserActivityComponent = void 0, this.maybeAutoNameSession(), captureTreeChanges(this.sessionManager.getCwd(), this.sessionManager.getSessionId()), this.ui.requestRender();
7243
7328
  break;
7244
7329
  case "agent_settled":
7245
7330
  if (this.pendingCompactionRender) {
@@ -7360,7 +7445,10 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7360
7445
  break;
7361
7446
  }
7362
7447
  case "assistant": {
7363
- let assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.thinkingCollapse, { requestRender: () => this.ui.requestRender() });
7448
+ let assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.thinkingCollapse, {
7449
+ requestRender: () => this.ui.requestRender(),
7450
+ reasoningDisplay: this.settingsManager.getReasoningDisplay()
7451
+ });
7364
7452
  assistantComponent.setThinkingTimings(this.thinkingTimingsByMessage.get(message)), assistantComponent.setExpanded(this.toolOutputExpanded), this.chatContainer.addChild(assistantComponent);
7365
7453
  break;
7366
7454
  }
@@ -7373,7 +7461,7 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7373
7461
  }
7374
7462
  renderSessionItems(items, options = {}) {
7375
7463
  this.pendingTools.clear();
7376
- let renderedPendingTools = /* @__PURE__ */ new Map(), cacheMisses = this.settingsManager.getShowCacheMissNotices() ? collectCacheMisses(this.sessionManager.getEntries(), this.session.modelRuntime) : /* @__PURE__ */ new Map();
7464
+ let browserActivityComponent, renderedPendingTools = /* @__PURE__ */ new Map(), cacheMisses = this.settingsManager.getShowCacheMissNotices() ? collectCacheMisses(this.sessionManager.getEntries(), this.session.modelRuntime) : /* @__PURE__ */ new Map();
7377
7465
  options.updateFooter && (this.footer.invalidate(), this.updateEditorBorderColor());
7378
7466
  for (let item of items) {
7379
7467
  if (isCustomSessionEntry(item)) {
@@ -7385,11 +7473,11 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7385
7473
  this.addMessageToChat(message);
7386
7474
  for (let content of message.content)
7387
7475
  if (content.type === "toolCall") {
7388
- let component = new ToolExecutionComponent(content.name, content.id, content.arguments, {
7476
+ let component = content.name === "browser" ? browserActivityComponent : void 0;
7477
+ if (component ? component.beginNextExecution(content.id, content.arguments) : (component = new ToolExecutionComponent(content.name, content.id, content.arguments, {
7389
7478
  showImages: this.settingsManager.getShowImages(),
7390
7479
  imageWidthCells: this.settingsManager.getImageWidthCells()
7391
- }, this.getRegisteredToolDefinition(content.name), this.ui, this.sessionManager.getCwd());
7392
- if (component.setExpanded(this.toolOutputExpanded), this.addToolComponentToChat(component), message.stopReason === "aborted" || message.stopReason === "error") {
7480
+ }, this.getRegisteredToolDefinition(content.name), this.ui, this.sessionManager.getCwd()), component.setExpanded(this.toolOutputExpanded), this.addToolComponentToChat(component), content.name === "browser" && (browserActivityComponent = component)), message.stopReason === "aborted" || message.stopReason === "error") {
7393
7481
  let errorMessage;
7394
7482
  if (message.stopReason === "aborted") {
7395
7483
  let retryAttempt = this.session.retryAttempt;
@@ -7408,7 +7496,7 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7408
7496
  let component = renderedPendingTools.get(message.toolCallId);
7409
7497
  component && (component.updateResult(message), renderedPendingTools.delete(message.toolCallId));
7410
7498
  } else
7411
- this.addMessageToChat(message, options);
7499
+ message.role === "user" && (browserActivityComponent = void 0), this.addMessageToChat(message, options);
7412
7500
  }
7413
7501
  for (let [toolCallId, component] of renderedPendingTools)
7414
7502
  this.pendingTools.set(toolCallId, component);
@@ -7467,7 +7555,7 @@ ${message}`, ["Yes", "No"], opts) === "Yes";
7467
7555
  });
7468
7556
  }
7469
7557
  rebuildChatFromMessages() {
7470
- this.chatContainer.clear(), this.renderSessionEntries(this.sessionManager.buildContextEntries());
7558
+ this.clearChatContainer(), this.renderSessionEntries(this.sessionManager.buildContextEntries());
7471
7559
  }
7472
7560
  // =========================================================================
7473
7561
  // Key handlers
@@ -7661,6 +7749,23 @@ Kill them before exit?`) && killAll(), this.stop(), await this.runtimeHost.dispo
7661
7749
  isExpandable(child) && child.setExpanded(expanded);
7662
7750
  globalThis[/* @__PURE__ */ Symbol.for("@lunr/tools-expanded-changed")]?.(expanded), this.ui.requestRender();
7663
7751
  }
7752
+ createToolExecutionComponent(toolName, toolCallId, args) {
7753
+ if (toolName === "browser" && this.browserActivityComponent)
7754
+ return this.browserActivityComponent.beginNextExecution(toolCallId, args), this.browserActivityComponent;
7755
+ let component = new ToolExecutionComponent(toolName, toolCallId, args, {
7756
+ showImages: this.settingsManager.getShowImages(),
7757
+ imageWidthCells: this.settingsManager.getImageWidthCells()
7758
+ }, this.getRegisteredToolDefinition(toolName), this.ui, this.sessionManager.getCwd());
7759
+ return component.setExpanded(this.toolOutputExpanded), this.addToolComponentToChat(component), toolName === "browser" && (this.browserActivityComponent = component), component;
7760
+ }
7761
+ disposeChatToolComponents() {
7762
+ for (let child of this.chatContainer.children)
7763
+ child instanceof ToolExecutionComponent && child.dispose();
7764
+ this.browserActivityComponent = void 0;
7765
+ }
7766
+ clearChatContainer() {
7767
+ this.disposeChatToolComponents(), this.chatContainer.clear();
7768
+ }
7664
7769
  // lunr: consecutive same-tool grouping — a tool component appended right after
7665
7770
  // another component for the SAME tool becomes a group continuation (no top
7666
7771
  // spacer / top pad); the previous card drops its bottom pad. Mixed neighbors
@@ -7670,7 +7775,7 @@ Kill them before exit?`) && killAll(), this.stop(), await this.runtimeHost.dispo
7670
7775
  applySameToolGrouping(last instanceof ToolExecutionComponent ? last : void 0, component), this.chatContainer.addChild(component);
7671
7776
  }
7672
7777
  toggleThinkingBlockVisibility() {
7673
- if (this.hideThinkingBlock = !this.hideThinkingBlock, this.settingsManager.setHideThinkingBlock(this.hideThinkingBlock), this.chatContainer.clear(), this.rebuildChatFromMessages(), this.streamingComponent && this.streamingMessage) {
7778
+ if (this.hideThinkingBlock = !this.hideThinkingBlock, this.settingsManager.setHideThinkingBlock(this.hideThinkingBlock), this.rebuildChatFromMessages(), this.streamingComponent && this.streamingMessage) {
7674
7779
  if (this.streamingComponent.setHideThinkingBlock(this.hideThinkingBlock), this.settingsManager.getSmoothStreaming() && this.streamingTargetMessage) {
7675
7780
  let opts = this.getSmoothStreamingOptions(), total = countMessageGraphemes(this.streamingTargetMessage, opts);
7676
7781
  this.streamingDisplayedLength > total && (this.streamingDisplayedLength = total), this.paintSmoothStreamingFrame(), this.streamingDisplayedLength < total && this.startSmoothStreaming();
@@ -7787,7 +7892,7 @@ Pi will resume when the editor exits.
7787
7892
  return !!extensionRunner.getCommand(commandName);
7788
7893
  }
7789
7894
  renderCompactionResult(result) {
7790
- this.chatContainer.clear(), this.rebuildChatFromMessages(), this.addMessageToChat(createCompactionSummaryMessage(result.summary, result.tokensBefore, (/* @__PURE__ */ new Date()).toISOString())), this.footer.invalidate();
7895
+ this.rebuildChatFromMessages(), this.addMessageToChat(createCompactionSummaryMessage(result.summary, result.tokensBefore, (/* @__PURE__ */ new Date()).toISOString())), this.footer.invalidate();
7791
7896
  }
7792
7897
  async flushCompactionQueue(options) {
7793
7898
  if (this.compactionQueuedMessages.length === 0)
@@ -7866,6 +7971,7 @@ Pi will resume when the editor exits.
7866
7971
  availableThemes: getAvailableThemes(),
7867
7972
  hideThinkingBlock: this.hideThinkingBlock,
7868
7973
  thinkingCollapse: this.thinkingCollapse,
7974
+ reasoningDisplay: this.settingsManager.getReasoningDisplay(),
7869
7975
  cacheRetention: this.settingsManager.getCacheRetention() ?? "short",
7870
7976
  doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
7871
7977
  treeFilterMode: this.settingsManager.getTreeFilterMode(),
@@ -7886,6 +7992,8 @@ Pi will resume when the editor exits.
7886
7992
  globalInstructionsPath: getGlobalInstructionsPath(getAgentDir()),
7887
7993
  modelInstructionsPath: getModelInstructionsPath(getAgentDir(), this.session.model?.id ?? "no-model-selected"),
7888
7994
  confirmLargeSubagentLaunches: this.settingsManager.getConfirmLargeSubagentLaunches(),
7995
+ subagentCommunicationEnabled: this.settingsManager.getSubagentCommunicationEnabled(),
7996
+ automaticSubagentDelegation: this.settingsManager.getAutomaticSubagentDelegation(),
7889
7997
  browserEnabled: this.settingsManager.getBrowserEnabled(),
7890
7998
  memoryEnabled: this.settingsManager.getMemoryEnabled(),
7891
7999
  memoryCharCap: this.settingsManager.getMemoryCharCap(),
@@ -7960,13 +8068,19 @@ Pi will resume when the editor exits.
7960
8068
  this.hideThinkingBlock = hidden, this.settingsManager.setHideThinkingBlock(hidden);
7961
8069
  for (let child of this.chatContainer.children)
7962
8070
  child instanceof AssistantMessageComponent && child.setHideThinkingBlock(hidden);
7963
- this.chatContainer.clear(), this.rebuildChatFromMessages();
8071
+ this.rebuildChatFromMessages();
7964
8072
  },
7965
8073
  onThinkingCollapseChange: (collapse) => {
7966
8074
  this.thinkingCollapse = collapse, this.settingsManager.setThinkingCollapse(collapse);
7967
8075
  for (let child of this.chatContainer.children)
7968
8076
  child instanceof AssistantMessageComponent && child.setThinkingCollapse(collapse);
7969
- this.chatContainer.clear(), this.rebuildChatFromMessages();
8077
+ this.rebuildChatFromMessages();
8078
+ },
8079
+ onReasoningDisplayChange: (display) => {
8080
+ this.settingsManager.setReasoningDisplay(display);
8081
+ for (let child of this.chatContainer.children)
8082
+ child instanceof AssistantMessageComponent && child.setReasoningDisplay(this.settingsManager.getReasoningDisplay());
8083
+ this.ui.requestRender();
7970
8084
  },
7971
8085
  onShowCacheMissNoticesChange: (shown) => {
7972
8086
  this.settingsManager.setShowCacheMissNotices(shown), this.rebuildChatFromMessages();
@@ -8037,6 +8151,12 @@ Pi will resume when the editor exits.
8037
8151
  onConfirmLargeSubagentLaunchesChange: (enabled) => {
8038
8152
  this.settingsManager.setConfirmLargeSubagentLaunches(enabled);
8039
8153
  },
8154
+ onSubagentCommunicationChange: (enabled) => {
8155
+ this.settingsManager.setSubagentCommunicationEnabled(enabled);
8156
+ },
8157
+ onAutomaticSubagentDelegationChange: (enabled) => {
8158
+ this.settingsManager.setAutomaticSubagentDelegation(enabled), this.session.refreshToolRegistry();
8159
+ },
8040
8160
  getTierThinkingLevels: (tier) => {
8041
8161
  let model = this.resolveModelReference(this.settingsManager.getTierModel(tier));
8042
8162
  return model ? getSupportedThinkingLevels(model) : this.session.getAvailableThinkingLevels();
@@ -8514,7 +8634,7 @@ Pi will resume when the editor exits.
8514
8634
  this.showStatus("Navigation cancelled");
8515
8635
  return;
8516
8636
  }
8517
- this.chatContainer.clear(), this.renderInitialMessages(), result.editorText && !this.editor.getText().trim() && this.restoreEditorFromTreeResult(result), this.showStatus("Navigated to selected point"), this.flushCompactionQueue({ willRetry: !1 });
8637
+ this.clearChatContainer(), this.renderInitialMessages(), result.editorText && !this.editor.getText().trim() && this.restoreEditorFromTreeResult(result), this.showStatus("Navigated to selected point"), this.flushCompactionQueue({ willRetry: !1 });
8518
8638
  } catch (error) {
8519
8639
  this.showError(error instanceof Error ? error.message : String(error));
8520
8640
  } finally {
@@ -8616,8 +8736,8 @@ Pi will resume when the editor exits.
8616
8736
  }
8617
8737
  async getLogoutProviderOptions() {
8618
8738
  let options = [];
8619
- for (let { providerId, type } of await this.session.modelRuntime.listCredentials()) {
8620
- let name = this.session.modelRuntime.getProvider(providerId)?.name ?? providerId, status = { type, source: "stored credential" };
8739
+ for (let { providerId, type: credentialType } of await this.session.modelRuntime.listCredentials()) {
8740
+ let type = credentialType === "external_claude_code" ? "oauth" : credentialType, name = this.session.modelRuntime.getProvider(providerId)?.name ?? providerId, status = { type, source: "stored credential" };
8621
8741
  if (type === "api_key") {
8622
8742
  let subs = await this.session.modelRuntime.subscriptionManager.list(providerId);
8623
8743
  if (subs.length > 1) {
@@ -9021,7 +9141,22 @@ Pi will resume when the editor exits.
9021
9141
  return this.session.modelRuntime.login(providerId, method, {
9022
9142
  signal: dialog.signal,
9023
9143
  prompt: (prompt) => this.showAuthPrompt(dialog, prompt),
9024
- notify: (event) => this.notifyAuthDialog(dialog, event)
9144
+ notify: (event) => this.notifyAuthDialog(dialog, event),
9145
+ handoff: async (command, args, env) => {
9146
+ this.ui.stop();
9147
+ try {
9148
+ await new Promise((resolve4, reject) => {
9149
+ let child = spawn3(command, [...args], { stdio: "inherit", env, windowsHide: !1 }), abort = () => child.kill();
9150
+ dialog.signal.addEventListener("abort", abort, { once: !0 }), dialog.signal.aborted && abort(), child.once("error", (error) => {
9151
+ dialog.signal.removeEventListener("abort", abort), reject(error);
9152
+ }), child.once("close", (code) => {
9153
+ dialog.signal.removeEventListener("abort", abort), code === 0 ? resolve4() : reject(new Error("Claude Code login did not complete"));
9154
+ });
9155
+ });
9156
+ } finally {
9157
+ this.ui.start();
9158
+ }
9159
+ }
9025
9160
  });
9026
9161
  }
9027
9162
  async showLoginDialog(providerId, providerName) {
@@ -9102,7 +9237,7 @@ ${INIT_EXISTING_FILE_INSTRUCTIONS.append}`;
9102
9237
  this.showStatus(command === "undo" ? "Undo cancelled" : "Edit cancelled");
9103
9238
  return;
9104
9239
  }
9105
- return leafId && this.redoStack.push(leafId), this.chatContainer.clear(), this.renderInitialMessages(), this.flushCompactionQueue({ willRetry: !1 }), { editorText: result.editorText, editorImages: result.editorImages };
9240
+ return leafId && this.redoStack.push(leafId), this.clearChatContainer(), this.renderInitialMessages(), this.flushCompactionQueue({ willRetry: !1 }), { editorText: result.editorText, editorImages: result.editorImages };
9106
9241
  } catch (error) {
9107
9242
  this.showError(error instanceof Error ? error.message : String(error));
9108
9243
  return;
@@ -9134,7 +9269,7 @@ ${INIT_EXISTING_FILE_INSTRUCTIONS.append}`;
9134
9269
  this.redoStack.push(targetId), this.showStatus("Navigation cancelled");
9135
9270
  return;
9136
9271
  }
9137
- this.chatContainer.clear(), this.renderInitialMessages(), result.editorText && !this.editor.getText().trim() && this.restoreEditorFromTreeResult(result), this.showStatus("Redone"), this.flushCompactionQueue({ willRetry: !1 });
9272
+ this.clearChatContainer(), this.renderInitialMessages(), result.editorText && !this.editor.getText().trim() && this.restoreEditorFromTreeResult(result), this.showStatus("Redone"), this.flushCompactionQueue({ willRetry: !1 });
9138
9273
  } catch (error) {
9139
9274
  this.showError(error instanceof Error ? error.message : String(error));
9140
9275
  }
@@ -9479,56 +9614,54 @@ ${theme.fg("dim", "Cache Re-billed:")} ${detail}`;
9479
9614
  this.chatContainer.addChild(new Spacer19(1)), this.chatContainer.addChild(new Text21(lines.join(`
9480
9615
  `), 1, 0)), this.ui.requestRender();
9481
9616
  }
9482
- // lunr: /plan — shortcut onto the plan permission mode (not a second state machine).
9617
+ // /plan is a shortcut into read-only mode for planning.
9483
9618
  async handlePlanCommand(args) {
9484
- let sub = args.toLowerCase(), inPlan = getPermissionMode() === "plan";
9619
+ let sub = args.toLowerCase(), inReadOnly = getPermissionMode() === "read-only";
9485
9620
  if (sub === "status") {
9486
- this.showStatus(inPlan ? "Plan mode is active \u2014 edit/write and mutating bash are blocked. /plan off to implement." : `Permission mode: ${getPermissionMode()}.`);
9621
+ this.showStatus(inReadOnly ? "Read mode is active. /plan off to leave it." : `Permission mode: ${getPermissionMode()}.`);
9487
9622
  return;
9488
9623
  }
9489
9624
  if (sub !== "" && sub !== "on" && sub !== "off") {
9490
- inPlan ? this.applyPermissionMode(this.restoreTargetAfterPlan()) : this.applyPermissionMode("plan"), await this.sendUserMessageAfterDeferredBuiltins(args);
9625
+ inReadOnly || this.applyPermissionMode("read-only"), await this.sendUserMessageAfterDeferredBuiltins(`Create a plan for: ${args}`);
9491
9626
  return;
9492
9627
  }
9493
- let next = sub === "" ? !inPlan : sub === "on";
9494
- if (next === inPlan) {
9495
- this.showStatus(next ? "Plan mode is already active." : "Plan mode is already off.");
9628
+ let next = sub !== "off";
9629
+ if (next === inReadOnly) {
9630
+ this.showStatus(next ? "Read mode is already active." : "Read mode is already off.");
9496
9631
  return;
9497
9632
  }
9498
- next ? this.applyPermissionMode("plan") : this.applyPermissionMode(this.restoreTargetAfterPlan());
9633
+ this.applyPermissionMode(next ? "read-only" : this.restoreTargetAfterPlan());
9499
9634
  }
9500
- // lunr: /mode — permission mode selector (manual / yolo / plan / auto). Per-session only.
9501
9635
  handleModeCommand(args) {
9502
9636
  let sub = args.toLowerCase();
9503
9637
  if (sub === "status") {
9504
- this.showStatus(`Permission mode: ${getPermissionMode()}`);
9638
+ this.showStatus(`Permission mode: ${getPermissionMode() === "read-only" ? "read" : getPermissionMode()}`);
9505
9639
  return;
9506
9640
  }
9507
- if (sub === "manual" || sub === "yolo" || sub === "plan" || sub === "auto") {
9508
- this.applyPermissionMode(sub);
9641
+ if (sub === "yolo" || sub === "auto" || sub === "read-only" || sub === "read") {
9642
+ this.applyPermissionMode(sub === "read" ? "read-only" : sub);
9509
9643
  return;
9510
9644
  }
9511
9645
  if (sub !== "") {
9512
- this.showStatus("Usage: /mode [manual|yolo|plan|auto] \u2014 bare /mode opens the selector.");
9646
+ this.showStatus("Usage: /mode [yolo|auto|read] \u2014 bare /mode opens the selector.");
9513
9647
  return;
9514
9648
  }
9515
9649
  let options = [
9516
- "Manual \u2014 approve every action",
9517
9650
  "YOLO \u2014 auto-approve tools, agent may still ask",
9518
- "Plan \u2014 read-only; present a plan for approval",
9519
- "Auto \u2014 fully autonomous, no questions"
9651
+ "Auto \u2014 fully autonomous, no questions",
9652
+ "Read \u2014 inspect without making changes"
9520
9653
  ];
9521
9654
  this.showExtensionSelector("Permission mode", options).then((choice) => {
9522
- choice && (choice.startsWith("Manual") ? this.applyPermissionMode("manual") : choice.startsWith("YOLO") ? this.applyPermissionMode("yolo") : choice.startsWith("Plan") ? this.applyPermissionMode("plan") : choice.startsWith("Auto") && this.applyPermissionMode("auto"));
9655
+ choice && (choice.startsWith("YOLO") ? this.applyPermissionMode("yolo") : choice.startsWith("Auto") ? this.applyPermissionMode("auto") : choice.startsWith("Read") && this.applyPermissionMode("read-only"));
9523
9656
  });
9524
9657
  }
9525
- /** Destination when leaving plan via approve / `/plan off` / `/plan <text>`. */
9658
+ /** Destination after plan approval or /plan off. */
9526
9659
  restoreTargetAfterPlan() {
9527
9660
  return restorePermissionModeAfterPlan(this.previousPermissionMode, this.settingsManager.getDefaultPermissionMode());
9528
9661
  }
9529
9662
  /** Apply addendum + auto-rollback for a mode without a status toast. */
9530
9663
  syncPermissionModeEffects(mode) {
9531
- this.runtimeHost.isDetached || this.transferInProgress || (this.sessionManager.setPermissionMode(mode), mode === "plan" ? this.session.setSystemPromptAppend(PLAN_MODE_ADDENDUM) : mode === "auto" ? (this.session.setSystemPromptAppend(AUTO_MODE_ADDENDUM), enableRollbackForSession(this.sessionManager.getSessionId())) : this.session.setSystemPromptAppend(void 0));
9664
+ this.runtimeHost.isDetached || this.transferInProgress || (this.sessionManager.setPermissionMode(mode), mode === "read-only" ? this.session.setSystemPromptAppend(READ_ONLY_MODE_ADDENDUM) : mode === "auto" ? (this.session.setSystemPromptAppend(AUTO_MODE_ADDENDUM), enableRollbackForSession(this.sessionManager.getSessionId())) : this.session.setSystemPromptAppend(void 0));
9532
9665
  }
9533
9666
  // lunr: `/goal` forces session auto without writing settings.
9534
9667
  enterGoalAuto() {
@@ -9544,22 +9677,7 @@ ${theme.fg("dim", "Cache Re-billed:")} ${detail}`;
9544
9677
  return;
9545
9678
  this.sessionManager.setPermissionMode(mode), recordTuiActivity(this.sessionManager, this.runtimeHost.services.agentDir);
9546
9679
  let prev = getPermissionMode();
9547
- mode === "plan" && prev !== "plan" && (this.previousPermissionMode = prev), setPermissionMode(mode), this.ui.requestRender(), mode === "plan" ? this.session.setSystemPromptAppend(PLAN_MODE_ADDENDUM) : mode === "auto" ? this.session.setSystemPromptAppend(AUTO_MODE_ADDENDUM) : this.session.setSystemPromptAppend(void 0), mode === "auto" && prev !== "auto" ? enableRollbackForSession(this.sessionManager.getSessionId()) : mode !== "auto" && prev === "auto" && disableRollbackForSession(this.sessionManager.getSessionId()), !opts?.silent && (mode === "auto" && prev !== "auto" ? this.showStatus("Auto mode active \u2014 fully autonomous. Rollback enabled for this session.") : mode === "plan" ? this.showStatus("Plan mode active \u2014 edit/write and mutating bash are blocked. /plan off to implement.") : this.showStatus(`Permission mode: ${mode}`));
9548
- }
9549
- // lunr: approval dialog for manual permission mode.
9550
- // lunr: adds "Switch to auto" / "Switch to yolo" at the bottom so users can
9551
- // escape manual approval mid-turn without a separate /mode round-trip.
9552
- async showApprovalDialog(req) {
9553
- return new Promise((resolve4) => {
9554
- this.showSelector((done) => {
9555
- let selector = new ExtensionSelectorComponent(`Approve ${req.action}?`, ["Approve once", "Approve for session", "Reject", "Switch to auto", "Switch to yolo"], (option) => {
9556
- done(), option === "Approve once" ? resolve4("once") : option === "Approve for session" ? resolve4("session") : option === "Switch to auto" ? (this.applyPermissionMode("auto"), resolve4("once")) : option === "Switch to yolo" ? (this.applyPermissionMode("yolo"), resolve4("once")) : resolve4("reject");
9557
- }, () => {
9558
- done(), resolve4("reject");
9559
- }, { message: req.detail.slice(0, 500) });
9560
- return { component: selector, focus: selector };
9561
- });
9562
- });
9680
+ mode === "read-only" && prev !== "read-only" && (this.previousPermissionMode = prev), setPermissionMode(mode), this.ui.requestRender(), mode === "read-only" ? this.session.setSystemPromptAppend(READ_ONLY_MODE_ADDENDUM) : mode === "auto" ? this.session.setSystemPromptAppend(AUTO_MODE_ADDENDUM) : this.session.setSystemPromptAppend(void 0), mode === "auto" && prev !== "auto" ? enableRollbackForSession(this.sessionManager.getSessionId()) : mode !== "auto" && prev === "auto" && disableRollbackForSession(this.sessionManager.getSessionId()), !opts?.silent && (mode === "auto" && prev !== "auto" ? this.showStatus("Auto mode active \u2014 fully autonomous. Rollback enabled for this session.") : mode === "read-only" ? this.showStatus("Read mode active. Changes are blocked.") : this.showStatus(`Permission mode: ${mode}`));
9563
9681
  }
9564
9682
  // Approval dialog for one subagent call launching more than two children.
9565
9683
  // "Reject with feedback" collects a one-line
@@ -9579,7 +9697,7 @@ ${theme.fg("dim", "Cache Re-billed:")} ${detail}`;
9579
9697
  });
9580
9698
  });
9581
9699
  }
9582
- // lunr: approval dialog for present_plan (plan mode). The "with feedback"
9700
+ // Approval dialog for present_plan (read-only mode). The "with feedback"
9583
9701
  // options collect a one-line note via showExtensionInput that becomes part of
9584
9702
  // the result text the model sees. Esc/close counts as Decline.
9585
9703
  showPlanInChat(summary) {
@@ -9750,7 +9868,7 @@ ${toggleThinking ? `| \`${toggleThinking}\` | Toggle thinking block visibility |
9750
9868
  "",
9751
9869
  "=== All rendered lines with visible widths ===",
9752
9870
  ...allLines.map((line, idx) => {
9753
- let vw = visibleWidth4(line), escaped = JSON.stringify(line);
9871
+ let vw = visibleWidth6(line), escaped = JSON.stringify(line);
9754
9872
  return `[${idx}] (w=${vw}) ${escaped}`;
9755
9873
  }),
9756
9874
  "",
@@ -9803,7 +9921,7 @@ ${theme.fg("muted", debugLogPath)}`, 1, 1)), this.ui.requestRender();
9803
9921
  }
9804
9922
  }
9805
9923
  stop() {
9806
- this.stopCatalogRefresh?.(), this.stopCatalogRefresh = void 0, this.settingsManager.getShowTerminalProgress() && this.ui.terminal.setProgress(!1), this.clearStatusIndicator(), this.themeController.disableAutoSync(), this.clearExtensionTerminalInputListeners(), this.footer.dispose(), this.footerDataProvider.dispose(), this.unsubscribe && this.unsubscribe(), this.isInitialized && (this.ui.stop(), this.isInitialized = !1), this.unregisterSignalHandlers();
9924
+ this.setThinkingAnimation(!1), this.stopCatalogRefresh?.(), this.stopCatalogRefresh = void 0, this.settingsManager.getShowTerminalProgress() && this.ui.terminal.setProgress(!1), this.clearStatusIndicator(), this.themeController.disableAutoSync(), this.clearExtensionTerminalInputListeners(), this.footer.dispose(), this.footerDataProvider.dispose(), this.disposeChatToolComponents(), this.unsubscribe && this.unsubscribe(), this.isInitialized && (this.ui.stop(), this.isInitialized = !1), this.unregisterSignalHandlers();
9807
9925
  }
9808
9926
  };
9809
9927