@linxiraos/pi-tui 1.1.26 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (423) hide show
  1. package/CHANGELOG.md +51 -491
  2. package/README.md +13 -7
  3. package/dist/types/active-terminal.d.ts +30 -0
  4. package/dist/types/app-keybindings.d.ts +7 -2
  5. package/dist/types/apps/cleanse-board.d.ts +1 -1
  6. package/dist/types/apps/debug/log-viewer.d.ts +4 -0
  7. package/dist/types/apps/debug/raw-sse-buffer.d.ts +2 -0
  8. package/dist/types/apps/git/git-tui.d.ts +5 -4
  9. package/dist/types/apps/git/help.d.ts +3 -1
  10. package/dist/types/apps/if-bench-board.d.ts +2 -2
  11. package/dist/types/apps/setup-model-picker.d.ts +1 -1
  12. package/dist/types/autocomplete.d.ts +5 -2
  13. package/dist/types/charts/chart-plan.d.ts +674 -0
  14. package/dist/types/charts/chart-svg.d.ts +59 -0
  15. package/dist/types/charts/table-data.d.ts +175 -0
  16. package/dist/types/chat/assistant-message.d.ts +11 -1
  17. package/dist/types/chat/chat-transcript-builder.d.ts +3 -0
  18. package/dist/types/chat/compaction-summary-message.d.ts +1 -0
  19. package/dist/types/chat/execution-shared.d.ts +6 -5
  20. package/dist/types/chat/fence-figure.d.ts +42 -0
  21. package/dist/types/chat/figure-markdown.d.ts +42 -0
  22. package/dist/types/chat/messages.d.ts +1 -1
  23. package/dist/types/chat/svg-figure.d.ts +33 -0
  24. package/dist/types/chat/svg-source.d.ts +49 -0
  25. package/dist/types/chat/table-chart.d.ts +89 -0
  26. package/dist/types/chat/tool-execution.d.ts +2 -0
  27. package/dist/types/chat/user-message.d.ts +17 -4
  28. package/dist/types/chrome/shared.d.ts +9 -0
  29. package/dist/types/chrome/status-notice.d.ts +15 -3
  30. package/dist/types/chrome/transcript-container.d.ts +6 -0
  31. package/dist/types/components/box.d.ts +1 -0
  32. package/dist/types/components/disclosure.d.ts +1 -0
  33. package/dist/types/components/editor.d.ts +23 -5
  34. package/dist/types/components/form.d.ts +1 -0
  35. package/dist/types/components/image.d.ts +26 -44
  36. package/dist/types/components/input.d.ts +2 -1
  37. package/dist/types/components/key-value-list.d.ts +1 -0
  38. package/dist/types/components/layout/row.d.ts +1 -0
  39. package/dist/types/components/layout/stack.d.ts +1 -0
  40. package/dist/types/components/loader.d.ts +5 -6
  41. package/dist/types/components/markdown.d.ts +47 -5
  42. package/dist/types/components/scroll-view.d.ts +1 -0
  43. package/dist/types/components/section.d.ts +1 -0
  44. package/dist/types/components/table.d.ts +1 -0
  45. package/dist/types/components/text.d.ts +1 -0
  46. package/dist/types/components/tree-view.d.ts +7 -0
  47. package/dist/types/components/truncated-text.d.ts +1 -0
  48. package/dist/types/fuzzy.d.ts +29 -1
  49. package/dist/types/key-hint-format.d.ts +9 -1
  50. package/dist/types/keybinding-matchers.d.ts +3 -0
  51. package/dist/types/keybindings.d.ts +1 -1
  52. package/dist/types/kitty-graphics.d.ts +2 -2
  53. package/dist/types/loop-watchdog.d.ts +8 -7
  54. package/dist/types/multiplexers/cmux.d.ts +16 -0
  55. package/dist/types/multiplexers/herdr.d.ts +26 -0
  56. package/dist/types/multiplexers/notify.d.ts +13 -0
  57. package/dist/types/multiplexers/orca.d.ts +12 -0
  58. package/dist/types/multiplexers/screen.d.ts +9 -0
  59. package/dist/types/multiplexers/tmux.d.ts +29 -0
  60. package/dist/types/multiplexers/types.d.ts +100 -0
  61. package/dist/types/multiplexers/wmux.d.ts +12 -0
  62. package/dist/types/multiplexers/zellij.d.ts +12 -0
  63. package/dist/types/native/apply.d.ts +4 -3
  64. package/dist/types/native/backend.d.ts +5 -4
  65. package/dist/types/native/blobs.d.ts +7 -3
  66. package/dist/types/native/encode.d.ts +8 -6
  67. package/dist/types/native/node.d.ts +36 -5
  68. package/dist/types/native/overlay.d.ts +8 -3
  69. package/dist/types/native/settle.d.ts +4 -3
  70. package/dist/types/overlays/agent-hub-projection.d.ts +6 -5
  71. package/dist/types/overlays/agent-hub-types.d.ts +9 -0
  72. package/dist/types/overlays/agent-hub.d.ts +3 -0
  73. package/dist/types/overlays/agent-transcript-viewer.d.ts +12 -2
  74. package/dist/types/overlays/agents-hub.d.ts +9 -0
  75. package/dist/types/overlays/annotation-overlay.d.ts +19 -2
  76. package/dist/types/overlays/annotation-types.d.ts +2 -0
  77. package/dist/types/overlays/ask-dialog.d.ts +5 -2
  78. package/dist/types/overlays/btw-history-panel.d.ts +13 -1
  79. package/dist/types/overlays/copy-selector.d.ts +1 -0
  80. package/dist/types/overlays/history-search.d.ts +10 -0
  81. package/dist/types/overlays/hook-selector.d.ts +9 -4
  82. package/dist/types/overlays/hub-frame.d.ts +4 -1
  83. package/dist/types/overlays/jobs-panel.d.ts +1 -7
  84. package/dist/types/overlays/model-browser.d.ts +54 -7
  85. package/dist/types/overlays/model-hub.d.ts +37 -0
  86. package/dist/types/overlays/oauth-selector.d.ts +0 -1
  87. package/dist/types/overlays/plan-review-overlay.d.ts +3 -2
  88. package/dist/types/overlays/report-panel.d.ts +68 -0
  89. package/dist/types/overlays/rewind-selector.d.ts +1 -0
  90. package/dist/types/overlays/session-observer-registry.d.ts +2 -0
  91. package/dist/types/overlays/session-selector.d.ts +6 -2
  92. package/dist/types/overlays/settings-defs.d.ts +1 -0
  93. package/dist/types/overlays/thinking-selector.d.ts +2 -2
  94. package/dist/types/overlays/usage-dashboard.d.ts +12 -8
  95. package/dist/types/overlays/usage-display.d.ts +3 -1
  96. package/dist/types/prompt/composer-cache.d.ts +0 -16
  97. package/dist/types/prompt/composer.d.ts +18 -3
  98. package/dist/types/prompt/custom-editor.d.ts +25 -13
  99. package/dist/types/prompt/image-source.d.ts +2 -1
  100. package/dist/types/prompt/interactive-context-helpers.d.ts +5 -1
  101. package/dist/types/prompt/model-mention-autocomplete.d.ts +1 -1
  102. package/dist/types/prompt/welcome.d.ts +7 -2
  103. package/dist/types/render/composite.d.ts +2 -0
  104. package/dist/types/render/output-pane.d.ts +1 -0
  105. package/dist/types/render/render-utils.d.ts +1 -0
  106. package/dist/types/render/tool-card.d.ts +6 -0
  107. package/dist/types/render/width-aware-text.d.ts +2 -0
  108. package/dist/types/setup/scenes/types.d.ts +1 -0
  109. package/dist/types/space-hold.d.ts +40 -25
  110. package/dist/types/status-line/component.d.ts +3 -0
  111. package/dist/types/status-line/context-usage.d.ts +7 -5
  112. package/dist/types/status-line/host.d.ts +4 -1
  113. package/dist/types/status-line/segments.d.ts +2 -0
  114. package/dist/types/status-line/types.d.ts +14 -3
  115. package/dist/types/terminal-capabilities.d.ts +41 -36
  116. package/dist/types/terminal-multiplexer.d.ts +127 -14
  117. package/dist/types/terminal.d.ts +23 -16
  118. package/dist/types/theme/active-symbols.d.ts +1 -1
  119. package/dist/types/theme/schema.d.ts +11 -2
  120. package/dist/types/theme/symbols.d.ts +1 -1
  121. package/dist/types/theme/theme-class.d.ts +7 -0
  122. package/dist/types/theme/theme.d.ts +1 -1
  123. package/dist/types/theme/tui-adapters.d.ts +3 -0
  124. package/dist/types/thinking.d.ts +1 -1
  125. package/dist/types/tmux.d.ts +11 -4
  126. package/dist/types/tools/bash.d.ts +7 -2
  127. package/dist/types/tools/daemon.d.ts +1 -1
  128. package/dist/types/tools/eval.d.ts +22 -3
  129. package/dist/types/tools/glob.d.ts +4 -0
  130. package/dist/types/tools/native-view.d.ts +47 -0
  131. package/dist/types/tools/output-meta.d.ts +11 -1
  132. package/dist/types/tools/renderer.d.ts +37 -2
  133. package/dist/types/tools/streaming-output.d.ts +20 -1
  134. package/dist/types/tools/task.d.ts +2 -3
  135. package/dist/types/tools/write.d.ts +9 -2
  136. package/dist/types/tools/yield.d.ts +22 -0
  137. package/dist/types/tui.d.ts +36 -0
  138. package/dist/types/utils.d.ts +6 -0
  139. package/dist/types/vim.d.ts +19 -5
  140. package/dist/types/windows-input-mode.d.ts +33 -1
  141. package/package.json +13 -9
  142. package/src/active-terminal.d.ts +30 -0
  143. package/src/active-terminal.ts +80 -0
  144. package/src/app-keybindings.d.ts +7 -2
  145. package/src/app-keybindings.ts +7 -2
  146. package/src/apps/autoresearch-dashboard.ts +7 -3
  147. package/src/apps/cleanse-board.ts +2 -2
  148. package/src/apps/cleanse-picker.ts +1 -1
  149. package/src/apps/debug/log-viewer.ts +188 -72
  150. package/src/apps/debug/raw-sse-buffer.ts +8 -0
  151. package/src/apps/debug/raw-sse.ts +39 -5
  152. package/src/apps/git/diff-pane.ts +96 -23
  153. package/src/apps/git/git-tui.ts +23 -16
  154. package/src/apps/git/help.ts +29 -20
  155. package/src/apps/git/sidebar.ts +8 -3
  156. package/src/apps/if-bench-board.ts +2 -2
  157. package/src/apps/ps-top.ts +2 -2
  158. package/src/apps/setup-model-picker.ts +1 -1
  159. package/src/autocomplete.d.ts +5 -2
  160. package/src/autocomplete.ts +67 -43
  161. package/src/bracketed-paste.ts +10 -3
  162. package/src/charts/chart-plan.d.ts +674 -0
  163. package/src/charts/chart-plan.ts +5081 -0
  164. package/src/charts/chart-svg.d.ts +59 -0
  165. package/src/charts/chart-svg.ts +4657 -0
  166. package/src/charts/table-data.d.ts +175 -0
  167. package/src/charts/table-data.ts +1478 -0
  168. package/src/chat/advisor-message.ts +11 -0
  169. package/src/chat/assistant-message.d.ts +11 -1
  170. package/src/chat/assistant-message.ts +245 -54
  171. package/src/chat/chat-transcript-builder.d.ts +3 -0
  172. package/src/chat/chat-transcript-builder.ts +9 -3
  173. package/src/chat/compaction-summary-message.d.ts +1 -0
  174. package/src/chat/compaction-summary-message.ts +8 -0
  175. package/src/chat/execution-shared.d.ts +6 -5
  176. package/src/chat/execution-shared.ts +42 -25
  177. package/src/chat/fence-figure.d.ts +42 -0
  178. package/src/chat/fence-figure.ts +80 -0
  179. package/src/chat/figure-markdown.d.ts +42 -0
  180. package/src/chat/figure-markdown.ts +174 -0
  181. package/src/chat/messages.d.ts +1 -1
  182. package/src/chat/messages.ts +1 -1
  183. package/src/chat/read-tool-group.ts +6 -4
  184. package/src/chat/skill-message.ts +6 -0
  185. package/src/chat/svg-figure.d.ts +33 -0
  186. package/src/chat/svg-figure.ts +399 -0
  187. package/src/chat/svg-source.d.ts +49 -0
  188. package/src/chat/svg-source.ts +188 -0
  189. package/src/chat/table-chart.d.ts +89 -0
  190. package/src/chat/table-chart.ts +294 -0
  191. package/src/chat/tool-execution.d.ts +2 -0
  192. package/src/chat/tool-execution.ts +86 -7
  193. package/src/chat/user-message.d.ts +17 -4
  194. package/src/chat/user-message.ts +71 -8
  195. package/src/chrome/shared.ts +53 -0
  196. package/src/chrome/status-notice.ts +25 -7
  197. package/src/chrome/transcript-container.d.ts +6 -0
  198. package/src/chrome/transcript-container.ts +162 -19
  199. package/src/components/box.d.ts +1 -0
  200. package/src/components/box.ts +5 -0
  201. package/src/components/disclosure.d.ts +1 -0
  202. package/src/components/disclosure.ts +8 -0
  203. package/src/components/editor.d.ts +23 -5
  204. package/src/components/editor.ts +316 -47
  205. package/src/components/form.d.ts +1 -0
  206. package/src/components/form.ts +8 -0
  207. package/src/components/image.d.ts +26 -44
  208. package/src/components/image.ts +115 -152
  209. package/src/components/input.d.ts +2 -1
  210. package/src/components/input.ts +17 -7
  211. package/src/components/key-value-list.d.ts +1 -0
  212. package/src/components/key-value-list.ts +4 -0
  213. package/src/components/layout/row.d.ts +1 -0
  214. package/src/components/layout/row.ts +7 -0
  215. package/src/components/layout/stack.d.ts +1 -0
  216. package/src/components/layout/stack.ts +7 -0
  217. package/src/components/loader.d.ts +5 -6
  218. package/src/components/loader.ts +10 -17
  219. package/src/components/markdown.d.ts +47 -5
  220. package/src/components/markdown.ts +786 -303
  221. package/src/components/scroll-view.d.ts +1 -0
  222. package/src/components/scroll-view.ts +5 -0
  223. package/src/components/section.d.ts +1 -0
  224. package/src/components/section.ts +5 -0
  225. package/src/components/settings-list.ts +2 -0
  226. package/src/components/table.d.ts +1 -0
  227. package/src/components/table.ts +4 -0
  228. package/src/components/text.d.ts +1 -0
  229. package/src/components/text.ts +7 -0
  230. package/src/components/tree-view.d.ts +7 -0
  231. package/src/components/tree-view.ts +38 -8
  232. package/src/components/truncated-text.d.ts +1 -0
  233. package/src/components/truncated-text.ts +5 -0
  234. package/src/desktop-notify.ts +3 -2
  235. package/src/fuzzy.d.ts +29 -1
  236. package/src/fuzzy.ts +115 -30
  237. package/src/hotkeys-markdown.ts +9 -2
  238. package/src/key-hint-format.d.ts +9 -1
  239. package/src/key-hint-format.ts +26 -11
  240. package/src/keybinding-matchers.d.ts +3 -0
  241. package/src/keybinding-matchers.ts +6 -2
  242. package/src/keybindings.d.ts +1 -1
  243. package/src/keybindings.ts +1 -1
  244. package/src/kitty-graphics.d.ts +2 -2
  245. package/src/kitty-graphics.ts +11 -5
  246. package/src/loop-watchdog.d.ts +8 -7
  247. package/src/loop-watchdog.ts +18 -13
  248. package/src/multiplexers/cmux.d.ts +16 -0
  249. package/src/multiplexers/cmux.ts +29 -0
  250. package/src/multiplexers/herdr.d.ts +26 -0
  251. package/src/multiplexers/herdr.ts +64 -0
  252. package/src/multiplexers/notify.d.ts +13 -0
  253. package/src/multiplexers/notify.ts +24 -0
  254. package/src/multiplexers/orca.d.ts +12 -0
  255. package/src/multiplexers/orca.ts +16 -0
  256. package/src/multiplexers/screen.d.ts +9 -0
  257. package/src/multiplexers/screen.ts +15 -0
  258. package/src/multiplexers/tmux.d.ts +29 -0
  259. package/src/multiplexers/tmux.ts +40 -0
  260. package/src/multiplexers/types.d.ts +100 -0
  261. package/src/multiplexers/types.ts +110 -0
  262. package/src/multiplexers/wmux.d.ts +12 -0
  263. package/src/multiplexers/wmux.ts +16 -0
  264. package/src/multiplexers/zellij.d.ts +12 -0
  265. package/src/multiplexers/zellij.ts +24 -0
  266. package/src/native/apply.d.ts +4 -3
  267. package/src/native/apply.ts +4 -3
  268. package/src/native/backend.d.ts +5 -4
  269. package/src/native/backend.ts +199 -22
  270. package/src/native/blobs.d.ts +7 -3
  271. package/src/native/blobs.ts +47 -12
  272. package/src/native/encode.d.ts +8 -6
  273. package/src/native/encode.ts +76 -34
  274. package/src/native/node.d.ts +36 -5
  275. package/src/native/node.ts +31 -5
  276. package/src/native/overlay.d.ts +8 -3
  277. package/src/native/overlay.ts +17 -4
  278. package/src/native/reconcile.ts +16 -4
  279. package/src/native/settle.d.ts +4 -3
  280. package/src/native/settle.ts +4 -3
  281. package/src/overlays/agent-hub-projection.d.ts +6 -5
  282. package/src/overlays/agent-hub-projection.ts +124 -13
  283. package/src/overlays/agent-hub-types.d.ts +9 -0
  284. package/src/overlays/agent-hub-types.ts +6 -0
  285. package/src/overlays/agent-hub.ts +48 -29
  286. package/src/overlays/agent-transcript-viewer.ts +93 -23
  287. package/src/overlays/agents-hub.ts +28 -8
  288. package/src/overlays/annotation-overlay.ts +293 -90
  289. package/src/overlays/annotation-types.ts +2 -0
  290. package/src/overlays/ask-dialog.ts +10 -17
  291. package/src/overlays/btw-history-panel.ts +136 -39
  292. package/src/overlays/copy-selector.d.ts +1 -0
  293. package/src/overlays/copy-selector.ts +32 -8
  294. package/src/overlays/extensions/extension-dashboard.ts +4 -4
  295. package/src/overlays/extensions/state-manager.ts +52 -12
  296. package/src/overlays/history-search.ts +100 -7
  297. package/src/overlays/hook-selector.ts +12 -5
  298. package/src/overlays/hub-frame.ts +19 -1
  299. package/src/overlays/jobs-panel.ts +33 -52
  300. package/src/overlays/model-browser.ts +367 -122
  301. package/src/overlays/model-hub.ts +435 -59
  302. package/src/overlays/move-overlay.ts +28 -14
  303. package/src/overlays/oauth-selector.ts +54 -70
  304. package/src/overlays/pause-screen.ts +2 -2
  305. package/src/overlays/plan-review-overlay.ts +208 -70
  306. package/src/overlays/plugin-settings.ts +3 -3
  307. package/src/overlays/report-panel.ts +191 -0
  308. package/src/overlays/rewind-selector.ts +88 -17
  309. package/src/overlays/session-observer-registry.d.ts +2 -0
  310. package/src/overlays/session-observer-registry.ts +10 -2
  311. package/src/overlays/session-selector.ts +64 -26
  312. package/src/overlays/settings-defs.ts +5 -4
  313. package/src/overlays/settings-selector.ts +33 -8
  314. package/src/overlays/snapcompact-shape-preview.ts +2 -3
  315. package/src/overlays/stats-notice.ts +1 -1
  316. package/src/overlays/thinking-selector.ts +11 -10
  317. package/src/overlays/tree-selector.ts +41 -20
  318. package/src/overlays/usage-dashboard.ts +117 -58
  319. package/src/overlays/usage-display.ts +10 -4
  320. package/src/overlays/usage-row.ts +22 -8
  321. package/src/prompt/attachment-chips.ts +15 -11
  322. package/src/prompt/composer-attachments.ts +6 -4
  323. package/src/prompt/composer-cache.ts +7 -86
  324. package/src/prompt/composer.ts +37 -26
  325. package/src/prompt/custom-editor.ts +282 -105
  326. package/src/prompt/image-source.ts +2 -1
  327. package/src/prompt/interactive-context-helpers.ts +32 -18
  328. package/src/prompt/macos-spelling.ts +7 -0
  329. package/src/prompt/magic-keywords.ts +11 -2
  330. package/src/prompt/model-mention-autocomplete.ts +14 -14
  331. package/src/prompt/queued-messages.ts +6 -4
  332. package/src/prompt/tips.txt +13 -9
  333. package/src/prompt/welcome.ts +64 -46
  334. package/src/prompt/word-completion.ts +38 -5
  335. package/src/render/composite.d.ts +2 -0
  336. package/src/render/composite.ts +64 -0
  337. package/src/render/output-pane.d.ts +1 -0
  338. package/src/render/output-pane.ts +6 -0
  339. package/src/render/render-utils.d.ts +1 -0
  340. package/src/render/render-utils.ts +16 -1
  341. package/src/render/tool-card.d.ts +6 -0
  342. package/src/render/tool-card.ts +15 -0
  343. package/src/render/width-aware-text.d.ts +2 -0
  344. package/src/render/width-aware-text.ts +5 -0
  345. package/src/setup/scenes/model.ts +2 -1
  346. package/src/setup/scenes/types.ts +1 -0
  347. package/src/space-hold.d.ts +40 -25
  348. package/src/space-hold.ts +156 -52
  349. package/src/status-line/component.ts +292 -78
  350. package/src/status-line/context-usage.ts +21 -46
  351. package/src/status-line/host.ts +4 -1
  352. package/src/status-line/segments.ts +40 -22
  353. package/src/status-line/types.ts +15 -3
  354. package/src/terminal-capabilities.d.ts +41 -36
  355. package/src/terminal-capabilities.ts +137 -213
  356. package/src/terminal-multiplexer.d.ts +127 -14
  357. package/src/terminal-multiplexer.ts +112 -33
  358. package/src/terminal.d.ts +23 -16
  359. package/src/terminal.ts +203 -99
  360. package/src/theme/active-symbols.d.ts +1 -1
  361. package/src/theme/active-symbols.ts +1 -1
  362. package/src/theme/schema-validation.ts +1 -0
  363. package/src/theme/schema.d.ts +11 -2
  364. package/src/theme/schema.ts +14 -1
  365. package/src/theme/session-color.ts +1 -7
  366. package/src/theme/symbols.d.ts +1 -1
  367. package/src/theme/symbols.ts +11 -4
  368. package/src/theme/theme-class.d.ts +7 -0
  369. package/src/theme/theme-class.ts +26 -1
  370. package/src/theme/theme-schema.json +5 -1
  371. package/src/theme/theme.d.ts +1 -1
  372. package/src/theme/theme.ts +8 -4
  373. package/src/theme/tui-adapters.d.ts +3 -0
  374. package/src/theme/tui-adapters.ts +68 -0
  375. package/src/thinking.d.ts +1 -1
  376. package/src/thinking.ts +1 -1
  377. package/src/tmux.d.ts +11 -4
  378. package/src/tmux.ts +47 -11
  379. package/src/tools/ast-edit.ts +59 -35
  380. package/src/tools/ast-grep.ts +35 -16
  381. package/src/tools/bash.d.ts +7 -2
  382. package/src/tools/bash.ts +116 -47
  383. package/src/tools/daemon.d.ts +1 -1
  384. package/src/tools/daemon.ts +1 -1
  385. package/src/tools/default-renderer.ts +35 -19
  386. package/src/tools/edit.ts +142 -120
  387. package/src/tools/eval-format/index.ts +28 -2
  388. package/src/tools/eval-format/javascript.ts +7 -5
  389. package/src/tools/eval.d.ts +22 -3
  390. package/src/tools/eval.ts +364 -208
  391. package/src/tools/fetch.ts +5 -6
  392. package/src/tools/glob.d.ts +4 -0
  393. package/src/tools/glob.ts +33 -65
  394. package/src/tools/grep.ts +81 -48
  395. package/src/tools/index.ts +2 -0
  396. package/src/tools/lsp.ts +81 -59
  397. package/src/tools/mcp.ts +111 -68
  398. package/src/tools/native-view.d.ts +47 -0
  399. package/src/tools/native-view.ts +102 -1
  400. package/src/tools/output-meta.d.ts +11 -1
  401. package/src/tools/output-meta.ts +23 -3
  402. package/src/tools/read.ts +7 -5
  403. package/src/tools/renderer.d.ts +37 -2
  404. package/src/tools/renderer.ts +42 -2
  405. package/src/tools/streaming-output.d.ts +20 -1
  406. package/src/tools/streaming-output.ts +154 -50
  407. package/src/tools/task.d.ts +2 -3
  408. package/src/tools/task.ts +115 -62
  409. package/src/tools/todo.ts +119 -30
  410. package/src/tools/wait.ts +34 -24
  411. package/src/tools/web-search.ts +1 -1
  412. package/src/tools/write.d.ts +9 -2
  413. package/src/tools/write.ts +147 -95
  414. package/src/tools/yield.d.ts +22 -0
  415. package/src/tools/yield.ts +225 -0
  416. package/src/tui.d.ts +36 -0
  417. package/src/tui.ts +666 -217
  418. package/src/utils.d.ts +6 -0
  419. package/src/utils.ts +19 -0
  420. package/src/vim.d.ts +19 -5
  421. package/src/vim.ts +333 -18
  422. package/src/windows-input-mode.d.ts +33 -1
  423. package/src/windows-input-mode.ts +212 -6
@@ -41,15 +41,22 @@ import { sanitizeErrorLine } from "../chrome/error-block";
41
41
  import type { ScrollRangeAnchor } from "../components/scroll-view";
42
42
  import { formatContextUsage } from "../chrome/context-thresholds";
43
43
  import { node, span, text } from "../native/describe";
44
- import type { DescribeContext, NativeChild, NativeNode } from "../native/node";
45
- import { actionHint, hintsRow, overlayCard } from "../native/overlay";
44
+ import type { DescribeContext, NativeChild, NativeNode, NativeUiEvent } from "../native/node";
45
+ import { actionHint, escCloseButton, hintsRow, overlayCard } from "../native/overlay";
46
46
 
47
47
  /** Parsed message and model metadata relevant to a transcript viewer. */
48
48
  export type AgentTranscriptEntry = SessionMessageEntryLike | { type: "model_change"; model: string };
49
49
 
50
50
  /** Local filesystem and session parsing capabilities supplied by the host. */
51
51
  export interface AgentTranscriptSource {
52
- fs: Pick<typeof fs, "openSync" | "closeSync" | "readSync" | "readFileSync" | "statSync">;
52
+ /**
53
+ * Sync primitives drive the first paint and the incremental tail. When the
54
+ * host also supplies `promises.readFile` (e.g. passes `node:fs` itself), full
55
+ * reloads after rotation/rewrite read the file off the UI thread.
56
+ */
57
+ fs: Pick<typeof fs, "openSync" | "closeSync" | "readSync" | "readFileSync" | "statSync"> & {
58
+ promises?: Pick<typeof fs.promises, "readFile">;
59
+ };
53
60
  parseEntries(text: string): AgentTranscriptEntry[];
54
61
  }
55
62
 
@@ -73,6 +80,7 @@ export interface AgentTranscriptViewerDeps {
73
80
  cwd: string;
74
81
  hideThinkingBlock?: () => boolean;
75
82
  proseOnlyThinking?: () => boolean;
83
+ expandThinkingBlocks?: () => boolean;
76
84
  expandKeys: KeyId[];
77
85
  /** Keys that toggle the whole hub closed (app.agents.hub + app.session.observe). */
78
86
  hubKeys: KeyId[];
@@ -85,6 +93,8 @@ export interface AgentTranscriptViewerDeps {
85
93
 
86
94
  /** How often to re-stat a file-backed transcript for growth (advisor/live tail). */
87
95
  const POLL_MS = 250;
96
+ /** Every Nth idle poll re-verifies sentinels, catching same-size/mtime rewrites. */
97
+ const IDLE_SENTINEL_CHECK_EVERY = 5;
88
98
 
89
99
  const SENTINEL_BYTES = 4096;
90
100
 
@@ -182,6 +192,10 @@ export class AgentTranscriptViewer implements Component {
182
192
  #model: string | undefined;
183
193
  #pollTimer: NodeJS.Timeout | undefined;
184
194
  #disposed = false;
195
+ /** Async full reload in flight; polls are skipped until it lands. */
196
+ #localLoadInFlight = false;
197
+ /** Idle polls since the sentinels were last verified. */
198
+ #idlePolls = 0;
185
199
  #initialEntryId: string | undefined;
186
200
  /** Last described node and the visible inputs it was built from. */
187
201
  #nativeCache: { signature: string; node: NativeNode } | undefined;
@@ -199,6 +213,9 @@ export class AgentTranscriptViewer implements Component {
199
213
  cwd: deps.cwd,
200
214
  hideThinkingBlock: deps.hideThinkingBlock,
201
215
  proseOnlyThinking: deps.proseOnlyThinking,
216
+ expandThinkingBlocks: deps.expandThinkingBlocks,
217
+ // Charts are for the main session's answers, not parked subagent, advisor, or guest transcripts.
218
+ tableCharts: false,
202
219
  requestRender: deps.requestRender,
203
220
  });
204
221
  this.#browser = new TranscriptBrowser({
@@ -211,8 +228,10 @@ export class AgentTranscriptViewer implements Component {
211
228
  this.#editor.setMaxHeight(4);
212
229
  this.#editor.onSubmit = text => this.#submit(text);
213
230
  }
214
- this.#refresh();
215
- this.#pollTimer = setInterval(() => this.#refresh(), POLL_MS);
231
+ // First paint loads synchronously so the initial entry can be revealed
232
+ // immediately; later full reloads from the poll may go async.
233
+ this.#refresh(false);
234
+ this.#pollTimer = setInterval(() => this.#refresh(true), POLL_MS);
216
235
  this.#pollTimer.unref?.();
217
236
  }
218
237
 
@@ -241,12 +260,13 @@ export class AgentTranscriptViewer implements Component {
241
260
  // ========================================================================
242
261
 
243
262
  /** Refresh the transcript from a local file or remote host. */
244
- #refresh(): void {
263
+ #refresh(allowAsync: boolean): void {
245
264
  if (this.#disposed) return;
246
265
  if (this.#deps.remote) {
247
266
  this.#fetchRemote();
248
267
  return;
249
268
  }
269
+ if (this.#localLoadInFlight) return;
250
270
  const sessionFile = this.#deps.registry.get(this.#deps.agentId)?.sessionFile;
251
271
  if (!sessionFile) {
252
272
  this.#clearLocal("none");
@@ -260,14 +280,29 @@ export class AgentTranscriptViewer implements Component {
260
280
  return;
261
281
  }
262
282
  const state = this.#localState;
263
- if (state && this.#canAppendLocal(sessionFile, stat, state)) {
264
- if (stat.size === state.size && stat.mtimeMs === state.mtimeMs) return;
265
- if (stat.size > state.size) {
266
- this.#appendLocal(sessionFile, stat, state);
283
+ if (state) {
284
+ // Idle fast path: an unchanged identity/size/mtime costs one stat;
285
+ // sentinels are re-read only every Nth idle poll so a rewrite that
286
+ // keeps size and mtime is still noticed.
287
+ if (
288
+ state.path === sessionFile &&
289
+ state.dev === stat.dev &&
290
+ state.ino === stat.ino &&
291
+ stat.size === state.size &&
292
+ stat.mtimeMs === state.mtimeMs
293
+ ) {
294
+ if (++this.#idlePolls < IDLE_SENTINEL_CHECK_EVERY) return;
295
+ this.#idlePolls = 0;
296
+ if (this.#canAppendLocal(sessionFile, stat, state)) return;
297
+ this.#loadLocalFull(sessionFile, stat, allowAsync);
298
+ return;
299
+ }
300
+ if (stat.size > state.size && this.#canAppendLocal(sessionFile, stat, state)) {
301
+ this.#appendLocal(sessionFile, stat, state, allowAsync);
267
302
  return;
268
303
  }
269
304
  }
270
- this.#loadLocalFull(sessionFile, stat);
305
+ this.#loadLocalFull(sessionFile, stat, allowAsync);
271
306
  }
272
307
 
273
308
  #clearLocal(reason: string): void {
@@ -301,7 +336,23 @@ export class AgentTranscriptViewer implements Component {
301
336
  return true;
302
337
  }
303
338
 
304
- #loadLocalFull(sessionFile: string, stat: fs.Stats): void {
339
+ #loadLocalFull(sessionFile: string, stat: fs.Stats, allowAsync: boolean): void {
340
+ const promises = allowAsync ? this.#deps.transcript.fs.promises : undefined;
341
+ if (promises) {
342
+ this.#localLoadInFlight = true;
343
+ void promises
344
+ .readFile(sessionFile)
345
+ .then(data => {
346
+ this.#localLoadInFlight = false;
347
+ if (!this.#disposed) this.#applyLocalFull(sessionFile, stat, data);
348
+ })
349
+ .catch((err: unknown) => {
350
+ // Leave #localState unchanged so a transient read error retries next poll.
351
+ this.#localLoadInFlight = false;
352
+ logger.debug("transcript viewer: read failed", { err: String(err) });
353
+ });
354
+ return;
355
+ }
305
356
  let data: Buffer;
306
357
  try {
307
358
  data = this.#deps.transcript.fs.readFileSync(sessionFile);
@@ -310,6 +361,10 @@ export class AgentTranscriptViewer implements Component {
310
361
  logger.debug("transcript viewer: read failed", { err: String(err) });
311
362
  return;
312
363
  }
364
+ this.#applyLocalFull(sessionFile, stat, data);
365
+ }
366
+
367
+ #applyLocalFull(sessionFile: string, stat: fs.Stats, data: Buffer): void {
313
368
  // The file may have grown between the earlier `statSync` and this read.
314
369
  // Anchor the tail cursor to what we actually consumed so the next poll's
315
370
  // `#appendLocal` never re-renders bytes already in the rebuilt transcript;
@@ -343,7 +398,7 @@ export class AgentTranscriptViewer implements Component {
343
398
  this.#rebuild(this.#extractMessages(this.#deps.transcript.parseEntries(complete)));
344
399
  }
345
400
 
346
- #appendLocal(sessionFile: string, stat: fs.Stats, state: LocalTranscriptState): void {
401
+ #appendLocal(sessionFile: string, stat: fs.Stats, state: LocalTranscriptState, allowAsync: boolean): void {
347
402
  let chunk: string;
348
403
  try {
349
404
  chunk = readFileRangeSync(
@@ -354,7 +409,7 @@ export class AgentTranscriptViewer implements Component {
354
409
  ).toString("utf-8");
355
410
  } catch (err) {
356
411
  logger.debug("transcript viewer: tail read failed", { err: String(err) });
357
- this.#loadLocalFull(sessionFile, stat);
412
+ this.#loadLocalFull(sessionFile, stat, allowAsync);
358
413
  return;
359
414
  }
360
415
  const combined = state.pending + chunk;
@@ -369,7 +424,7 @@ export class AgentTranscriptViewer implements Component {
369
424
  // File unlinked/rotated mid-poll: fall back to a guarded full reload
370
425
  // instead of letting the open escape the poll timer.
371
426
  logger.debug("transcript viewer: sentinel recompute failed", { err: String(err) });
372
- this.#loadLocalFull(sessionFile, stat);
427
+ this.#loadLocalFull(sessionFile, stat, allowAsync);
373
428
  return;
374
429
  }
375
430
  this.#localState = {
@@ -504,12 +559,7 @@ export class AgentTranscriptViewer implements Component {
504
559
  }
505
560
 
506
561
  if (matchesKey(data, "escape")) {
507
- if (this.#editor && this.#editor.getText().trim() !== "") {
508
- this.#editor.setText("");
509
- this.#deps.requestRender();
510
- return;
511
- }
512
- this.#deps.onClose();
562
+ this.#escape();
513
563
  return;
514
564
  }
515
565
 
@@ -592,6 +642,21 @@ export class AgentTranscriptViewer implements Component {
592
642
  return lines;
593
643
  }
594
644
 
645
+ /** The top-right `esc` runs Esc. */
646
+ handleNativeEvent(event: NativeUiEvent): void {
647
+ if (event.type === "action" && event.act === "close") this.#escape();
648
+ }
649
+
650
+ /** Esc: clear a non-empty draft first, else close the viewer. */
651
+ #escape(): void {
652
+ if (this.#editor && this.#editor.getText().trim() !== "") {
653
+ this.#editor.setText("");
654
+ this.#deps.requestRender();
655
+ return;
656
+ }
657
+ this.#deps.onClose();
658
+ }
659
+
595
660
  /**
596
661
  * Header, transcript body (the builder's container, which describes its own
597
662
  * blocks), notice, message editor, stats and key hints. Scrolling is the
@@ -620,6 +685,8 @@ export class AgentTranscriptViewer implements Component {
620
685
 
621
686
  const id = this.#deps.agentId;
622
687
  const children: NativeChild[] = [];
688
+ // Top row: the agent's meta on the left, a clickable `esc` (close) on the right.
689
+ const top: NativeChild[] = [];
623
690
  if (ref) {
624
691
  const kindTag = ref.parentId ? `${ref.kind} ${theme.sep.dot} of ${ref.parentId}` : ref.kind;
625
692
  const meta: NativeChild[] = [
@@ -628,8 +695,12 @@ export class AgentTranscriptViewer implements Component {
628
695
  text([span(kindTag, "dim")], { truncate: "end" }),
629
696
  ];
630
697
  if (this.#model) meta.push(text([span(this.#model, "muted")], { truncate: "end" }));
631
- children.push(node("row", { gap: "sm", align: "center" }, meta, "meta"));
698
+ top.push(node("row", { gap: "sm", align: "center", grow: 1, min: { w: 0 } }, meta, "meta"));
699
+ } else {
700
+ top.push(node("spacer", { grow: 1 }));
632
701
  }
702
+ top.push(escCloseButton());
703
+ children.push(node("row", { gap: "md", align: "center" }, top, "top"));
633
704
  children.push(
634
705
  placeholder === undefined
635
706
  ? node("col", { grow: 1 }, [this.#builder.container], "transcript")
@@ -692,7 +763,6 @@ export class AgentTranscriptViewer implements Component {
692
763
  children.push(
693
764
  hintsRow([
694
765
  this.#editor ? actionHint("tui.input.submit", "send") : undefined,
695
- { keys: ["escape"], label: "close" },
696
766
  { keys: [this.#deps.expandKeys[0] ?? "ctrl+o"], label: "expand" },
697
767
  ]),
698
768
  );
@@ -15,7 +15,7 @@ import type { TspPickerAction, TspPickerColumn, TspPickerItem, TspPickerScope, T
15
15
  import {
16
16
  type Component,
17
17
  Editor,
18
- fuzzyMatch,
18
+ FuzzyQuery,
19
19
  Input,
20
20
  matchesKey,
21
21
  replaceTabs,
@@ -141,6 +141,11 @@ export interface AgentsHubCallbacks {
141
141
  const IDENTIFIER_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+){1,5}$/;
142
142
 
143
143
  function extractJsonObject(raw: string): string {
144
+ // A bare JSON object may legitimately contain code fences inside string values; keep it intact.
145
+ try {
146
+ JSON.parse(raw);
147
+ return raw;
148
+ } catch {}
144
149
  const fenceMatch = raw.match(/```(?:json)?\s*([\s\S]*?)```/i);
145
150
  if (fenceMatch?.[1]) return fenceMatch[1].trim();
146
151
  const start = raw.indexOf("{");
@@ -149,7 +154,15 @@ function extractJsonObject(raw: string): string {
149
154
  return raw.trim();
150
155
  }
151
156
 
152
- function parseGeneratedAgentSpec(raw: string): GeneratedAgentSpec {
157
+ /**
158
+ * Parse model output into a {@link GeneratedAgentSpec}. Accepts a bare JSON object
159
+ * (tried first) or one wrapped in a code fence. Returns the spec with trimmed fields.
160
+ * Throws if the output is not valid JSON or not an object, if `identifier`, `whenToUse`
161
+ * or `systemPrompt` is missing or not a string, if the identifier is not lowercase
162
+ * kebab-case with 2+ words, if `whenToUse` does not start with "Use this agent when",
163
+ * or if `systemPrompt` is empty.
164
+ */
165
+ export function parseGeneratedAgentSpec(raw: string): GeneratedAgentSpec {
153
166
  const parsed = JSON.parse(extractJsonObject(raw)) as Partial<GeneratedAgentSpec>;
154
167
  if (!parsed || typeof parsed !== "object") {
155
168
  throw new Error("Model output is not a JSON object");
@@ -181,12 +194,12 @@ function listRowId(rowDef: ListRow): string {
181
194
  return rowDef.kind === "new" ? "new" : `agent:${rowDef.agent.source}:${rowDef.agent.name}`;
182
195
  }
183
196
 
184
- function matchAgent(agent: HubAgent, query: string): boolean {
197
+ /** All `tokens` (prepared once per query) fuzzy-match the agent's searchable text. */
198
+ function matchAgent(agent: HubAgent, tokens: readonly FuzzyQuery[]): boolean {
199
+ // Not memoized: `overrideModel` is edited in place, and the module index
200
+ // cache already reuses the per-text index for unchanged agents.
185
201
  const text = `${agent.name} ${agent.description} ${SOURCE_LABEL[agent.source]} ${agent.overrideModel ?? ""}`;
186
- return query
187
- .trim()
188
- .split(/\s+/)
189
- .every(token => fuzzyMatch(token, text).matches);
202
+ return tokens.every(token => token.match(text).matches);
190
203
  }
191
204
 
192
205
  /**
@@ -360,7 +373,14 @@ export class AgentsHubComponent implements Component {
360
373
  const scoped =
361
374
  entry.kind === "source" ? this.#allAgents.filter(agent => agent.source === entry.source) : this.#allAgents;
362
375
  const query = this.#search.getValue();
363
- const filtered = query ? scoped.filter(agent => matchAgent(agent, query)) : scoped;
376
+ let filtered = scoped;
377
+ if (query) {
378
+ const tokens = query
379
+ .trim()
380
+ .split(/\s+/)
381
+ .map(token => new FuzzyQuery(token));
382
+ filtered = scoped.filter(agent => matchAgent(agent, tokens));
383
+ }
364
384
  this.#rows = [...filtered.map(agent => ({ kind: "agent", agent }) as ListRow), { kind: "new" }];
365
385
  }
366
386