@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
package/src/tools/edit.ts CHANGED
@@ -36,6 +36,7 @@ import {
36
36
  invalidateRenderedStringCache,
37
37
  PREVIEW_LIMITS,
38
38
  previewWindowRows,
39
+ releaseRenderedStringCache,
39
40
  type RenderedStringCache,
40
41
  replaceTabs,
41
42
  shortenPath,
@@ -1110,41 +1111,49 @@ export const editToolRenderer = {
1110
1111
  return renderInlineEditRow(uiTheme, { op, rename, rawPath, pending: true });
1111
1112
  }
1112
1113
  const callPreviewCaches: RenderedStringCache[] = [];
1113
- return framedToolCard(uiTheme, ({ width }) => {
1114
- // No status icon on the head row: it's the head of the framed block,
1115
- // and native-scrollback commits are prefix-only — an animated glyph
1116
- // would pin the commit boundary at the top, and the pending hourglass
1117
- // just adds noise. The liveness cue rides the trailing "(preview)" /
1118
- // "(streaming)" line instead.
1119
- const header = renderEditHeader(width, uiTheme, {
1120
- op,
1121
- rawPath,
1122
- rename,
1123
- extraSuffix: fileCount > 1 ? uiTheme.fg("dim", ` (+${fileCount - 1} more)`) : undefined,
1124
- });
1125
- let body = getCallPreview(
1126
- editArgs,
1127
- rawPath,
1128
- width,
1129
- uiTheme,
1130
- renderContext,
1131
- options.expanded,
1132
- options?.spinnerFrame,
1133
- callPreviewCaches,
1134
- );
1135
- if (applyPatchError) {
1136
- body += `\n${uiTheme.fg("error", truncateToWidth(replaceTabs(applyPatchError), Math.max(1, width - 2)))}`;
1137
- }
1138
- const bodyLines = body ? body.split("\n") : [];
1139
- while (bodyLines.length > 0 && bodyLines[0].trim() === "") bodyLines.shift();
1140
- return {
1141
- header,
1142
- sections: bodyLines.length > 0 ? [{ content: bodyLines }] : [],
1143
- phase: applyPatchError ? "error" : "pending",
1144
- borderColor: applyPatchError ? "error" : "borderMuted",
1145
- contentPaddingLeft: 0,
1146
- };
1147
- });
1114
+ return framedToolCard(
1115
+ uiTheme,
1116
+ ({ width }) => {
1117
+ // No status icon on the head row: it's the head of the framed block,
1118
+ // and native-scrollback commits are prefix-only — an animated glyph
1119
+ // would pin the commit boundary at the top, and the pending hourglass
1120
+ // just adds noise. The liveness cue rides the trailing "(preview)" /
1121
+ // "(streaming)" line instead.
1122
+ const header = renderEditHeader(width, uiTheme, {
1123
+ op,
1124
+ rawPath,
1125
+ rename,
1126
+ extraSuffix: fileCount > 1 ? uiTheme.fg("dim", ` (+${fileCount - 1} more)`) : undefined,
1127
+ });
1128
+ let body = getCallPreview(
1129
+ editArgs,
1130
+ rawPath,
1131
+ width,
1132
+ uiTheme,
1133
+ renderContext,
1134
+ options.expanded,
1135
+ options?.spinnerFrame,
1136
+ callPreviewCaches,
1137
+ );
1138
+ if (applyPatchError) {
1139
+ body += `\n${uiTheme.fg("error", truncateToWidth(replaceTabs(applyPatchError), Math.max(1, width - 2)))}`;
1140
+ }
1141
+ const bodyLines = body ? body.split("\n") : [];
1142
+ while (bodyLines.length > 0 && bodyLines[0].trim() === "") bodyLines.shift();
1143
+ return {
1144
+ header,
1145
+ sections: bodyLines.length > 0 ? [{ content: bodyLines }] : [],
1146
+ phase: applyPatchError ? "error" : "pending",
1147
+ borderColor: applyPatchError ? "error" : "borderMuted",
1148
+ contentPaddingLeft: 0,
1149
+ };
1150
+ },
1151
+ {
1152
+ onReleaseRenderCaches: () => {
1153
+ for (const cache of callPreviewCaches) releaseRenderedStringCache(cache);
1154
+ },
1155
+ },
1156
+ );
1148
1157
  },
1149
1158
 
1150
1159
  describeCall(
@@ -1452,74 +1461,54 @@ function renderSingleFileResult(
1452
1461
  const renderedDiffCache = createRenderedStringCache();
1453
1462
  const statsSuffixCache = createRenderedStringCache();
1454
1463
 
1455
- return framedToolCard(uiTheme, ({ width }) => {
1456
- const { expanded, renderContext } = options;
1457
- // A finalized result is authoritative: its `details` describe exactly
1458
- // what happened. The shared streaming `editDiffPreview` is a call-phase
1459
- // artifact (in a batch it reflects only the first file), so consulting it
1460
- // for an empty-diff delete/move/no-op result mislabels the card. Fall
1461
- // back to the preview only when no details exist yet.
1462
- const editDiffPreview = details ? undefined : renderContext?.editDiffPreview;
1463
- const renderDiffFn = renderContext?.renderDiff ?? renderFallbackDiff;
1464
-
1465
- if (diffSectionRenderDiffFn !== renderDiffFn) {
1466
- diffSectionRenderDiffFn = renderDiffFn;
1467
- invalidateRenderedStringCache(diffSectionCache);
1468
- invalidateRenderedStringCache(renderedDiffCache);
1469
- }
1470
- const firstChangedLine =
1471
- (editDiffPreview && "firstChangedLine" in editDiffPreview ? editDiffPreview.firstChangedLine : undefined) ||
1472
- (details && !isError ? details.firstChangedLine : undefined);
1473
- const linkPath = details && "path" in details ? details.path : undefined;
1474
-
1475
- // Change stats ride inline on the header bar next to the path.
1476
- const previewDiff = editDiffPreview && !("error" in editDiffPreview) ? editDiffPreview.diff : undefined;
1477
- const headerDiff = isError ? undefined : details?.diff || previewDiff;
1478
- const statsSuffix = headerDiff
1479
- ? cachedRenderedString(statsSuffixCache, uiTheme, false, "", headerDiff, () =>
1480
- formatDiffStatsSuffix(headerDiff, uiTheme),
1481
- )
1482
- : "";
1483
- const header = renderEditHeader(width, uiTheme, {
1484
- icon: isError ? "error" : "success",
1485
- iconOverride: !isError && !options.isPartial ? uiTheme.styledSymbol("tool.edit", "accent") : undefined,
1486
- op,
1487
- rawPath,
1488
- rename,
1489
- firstChangedLine,
1490
- linkPath,
1491
- statsSuffix,
1492
- });
1493
- const innerWidth = Math.max(1, width - 2);
1494
-
1495
- let body = "";
1496
- if (isError) {
1497
- if (errorText) body = uiTheme.fg("error", replaceTabs(errorText));
1498
- } else if (details?.diff) {
1499
- body = renderDiffSection(
1500
- details.diff,
1501
- rawPath,
1502
- expanded,
1503
- innerWidth,
1504
- uiTheme,
1505
- renderDiffFn,
1506
- renderedDiffCache,
1507
- diffSectionCache,
1508
- );
1509
- } else if (details) {
1510
- // Authoritative result with no textual diff: a delete, a move-only
1511
- // rename, or a genuine no-op. The header already names the op
1512
- // (Delete / `src → dst`); only a true no-op needs an explanatory
1513
- // body so an empty card isn't mistaken for a stalled edit.
1514
- if (op !== "delete" && op !== "create" && !rename) {
1515
- const noChangePath = linkPath ? shortenPath(linkPath) : rawPath ? shortenPath(rawPath) : "";
1516
- body = uiTheme.fg("dim", `No changes were made${noChangePath ? ` to ${noChangePath}` : ""}.`);
1464
+ return framedToolCard(
1465
+ uiTheme,
1466
+ ({ width }) => {
1467
+ const { expanded, renderContext } = options;
1468
+ // A finalized result is authoritative: its `details` describe exactly
1469
+ // what happened. The shared streaming `editDiffPreview` is a call-phase
1470
+ // artifact (in a batch it reflects only the first file), so consulting it
1471
+ // for an empty-diff delete/move/no-op result mislabels the card. Fall
1472
+ // back to the preview only when no details exist yet.
1473
+ const editDiffPreview = details ? undefined : renderContext?.editDiffPreview;
1474
+ const renderDiffFn = renderContext?.renderDiff ?? renderFallbackDiff;
1475
+
1476
+ if (diffSectionRenderDiffFn !== renderDiffFn) {
1477
+ diffSectionRenderDiffFn = renderDiffFn;
1478
+ invalidateRenderedStringCache(diffSectionCache);
1479
+ invalidateRenderedStringCache(renderedDiffCache);
1517
1480
  }
1518
- } else if (editDiffPreview) {
1519
- if ("error" in editDiffPreview) body = uiTheme.fg("error", replaceTabs(editDiffPreview.error));
1520
- else if (editDiffPreview.diff)
1481
+ const firstChangedLine =
1482
+ (editDiffPreview && "firstChangedLine" in editDiffPreview ? editDiffPreview.firstChangedLine : undefined) ||
1483
+ (details && !isError ? details.firstChangedLine : undefined);
1484
+ const linkPath = details && "path" in details ? details.path : undefined;
1485
+
1486
+ // Change stats ride inline on the header bar next to the path.
1487
+ const previewDiff = editDiffPreview && !("error" in editDiffPreview) ? editDiffPreview.diff : undefined;
1488
+ const headerDiff = isError ? undefined : details?.diff || previewDiff;
1489
+ const statsSuffix = headerDiff
1490
+ ? cachedRenderedString(statsSuffixCache, uiTheme, false, "", headerDiff, () =>
1491
+ formatDiffStatsSuffix(headerDiff, uiTheme),
1492
+ )
1493
+ : "";
1494
+ const header = renderEditHeader(width, uiTheme, {
1495
+ icon: isError ? "error" : "success",
1496
+ iconOverride: !isError && !options.isPartial ? uiTheme.styledSymbol("tool.edit", "accent") : undefined,
1497
+ op,
1498
+ rawPath,
1499
+ rename,
1500
+ firstChangedLine,
1501
+ linkPath,
1502
+ statsSuffix,
1503
+ });
1504
+ const innerWidth = Math.max(1, width - 2);
1505
+
1506
+ let body = "";
1507
+ if (isError) {
1508
+ if (errorText) body = uiTheme.fg("error", replaceTabs(errorText));
1509
+ } else if (details?.diff) {
1521
1510
  body = renderDiffSection(
1522
- editDiffPreview.diff,
1511
+ details.diff,
1523
1512
  rawPath,
1524
1513
  expanded,
1525
1514
  innerWidth,
@@ -1528,27 +1517,56 @@ function renderSingleFileResult(
1528
1517
  renderedDiffCache,
1529
1518
  diffSectionCache,
1530
1519
  );
1531
- }
1532
- if (details?.diagnostics) {
1533
- body += formatDiagnostics(details.diagnostics, expanded, uiTheme, (fp: string) =>
1534
- uiTheme.getLangIcon(getLanguageFromPath(fp)),
1535
- );
1536
- }
1520
+ } else if (details) {
1521
+ // Authoritative result with no textual diff: a delete, a move-only
1522
+ // rename, or a genuine no-op. The header already names the op
1523
+ // (Delete / `src → dst`); only a true no-op needs an explanatory
1524
+ // body so an empty card isn't mistaken for a stalled edit.
1525
+ if (op !== "delete" && op !== "create" && !rename) {
1526
+ const noChangePath = linkPath ? shortenPath(linkPath) : rawPath ? shortenPath(rawPath) : "";
1527
+ body = uiTheme.fg("dim", `No changes were made${noChangePath ? ` to ${noChangePath}` : ""}.`);
1528
+ }
1529
+ } else if (editDiffPreview) {
1530
+ if ("error" in editDiffPreview) body = uiTheme.fg("error", replaceTabs(editDiffPreview.error));
1531
+ else if (editDiffPreview.diff)
1532
+ body = renderDiffSection(
1533
+ editDiffPreview.diff,
1534
+ rawPath,
1535
+ expanded,
1536
+ innerWidth,
1537
+ uiTheme,
1538
+ renderDiffFn,
1539
+ renderedDiffCache,
1540
+ diffSectionCache,
1541
+ );
1542
+ }
1543
+ if (details?.diagnostics) {
1544
+ body += formatDiagnostics(details.diagnostics, expanded, uiTheme, (fp: string) =>
1545
+ uiTheme.getLangIcon(getLanguageFromPath(fp)),
1546
+ );
1547
+ }
1537
1548
 
1538
- // Diff lines self-wrap with a continuation gutter; pre-wrap to the frame's
1539
- // inner width so renderOutputBlock's generic wrap is a no-op. Edit frames
1540
- // use a flush left border because code-frame gutters already provide padding.
1541
- const bodyLines = body.length > 0 ? body.split("\n").flatMap(line => wrapEditRendererLine(line, innerWidth)) : [];
1542
- while (bodyLines.length > 0 && bodyLines[0].trim() === "") bodyLines.shift();
1549
+ // Diff lines self-wrap with a continuation gutter; pre-wrap to the frame's
1550
+ // inner width so renderOutputBlock's generic wrap is a no-op. Edit frames
1551
+ // use a flush left border because code-frame gutters already provide padding.
1552
+ const bodyLines =
1553
+ body.length > 0 ? body.split("\n").flatMap(line => wrapEditRendererLine(line, innerWidth)) : [];
1554
+ while (bodyLines.length > 0 && bodyLines[0].trim() === "") bodyLines.shift();
1543
1555
 
1544
- return {
1545
- header,
1546
- sections: bodyLines.length > 0 ? [{ content: bodyLines }] : [],
1547
- phase: isError ? "error" : options.isPartial ? "partial" : "success",
1548
- borderColor: isError ? "error" : "borderMuted",
1549
- contentPaddingLeft: 0,
1550
- };
1551
- });
1556
+ return {
1557
+ header,
1558
+ sections: bodyLines.length > 0 ? [{ content: bodyLines }] : [],
1559
+ phase: isError ? "error" : options.isPartial ? "partial" : "success",
1560
+ borderColor: isError ? "error" : "borderMuted",
1561
+ contentPaddingLeft: 0,
1562
+ };
1563
+ },
1564
+ {
1565
+ // Only the width-keyed diff section goes; the highlighted diff and stats suffix do not depend on width, and
1566
+ // re-highlighting every committed card on each resize replay costs seconds.
1567
+ onReleaseRenderCaches: () => releaseRenderedStringCache(diffSectionCache),
1568
+ },
1569
+ );
1552
1570
  }
1553
1571
 
1554
1572
  function renderMultiFileResult(
@@ -1603,5 +1621,9 @@ function renderMultiFileResult(
1603
1621
  cached = undefined;
1604
1622
  for (const c of fileComponents) c.invalidate?.();
1605
1623
  },
1624
+ releaseRenderCaches() {
1625
+ cached = undefined;
1626
+ for (const c of fileComponents) c.releaseRenderCaches?.();
1627
+ },
1606
1628
  };
1607
1629
  }
@@ -1,3 +1,4 @@
1
+ import { LRUCache } from "@linxiraos/pi-utils/lru";
1
2
  import type { EvalLanguage } from "../eval";
2
3
  import { formatJavaScriptForDisplay } from "./javascript";
3
4
  import { formatPythonForDisplay } from "./python";
@@ -5,13 +6,38 @@ import { formatPythonForDisplay } from "./python";
5
6
  export * from "./javascript";
6
7
  export * from "./python";
7
8
 
9
+ function createDisplayFormatMemo(): LRUCache<string, string> {
10
+ return new LRUCache<string, string>({
11
+ max: 64,
12
+ maxSize: 4_000_000,
13
+ // LRUCache rejects sizes <= 0; empty sources (cells not yet streamed) still cost one.
14
+ sizeCalculation: (formatted, source) => formatted.length + source.length + 1,
15
+ });
16
+ }
17
+
18
+ /**
19
+ * Formatted display text keyed by source, one memo per formatter. Renderers
20
+ * reformat every cell on each streamed argument delta and result update; the
21
+ * memo keeps that linear in the changed cell instead of the whole call.
22
+ */
23
+ const jsDisplayMemo = createDisplayFormatMemo();
24
+ const pythonDisplayMemo = createDisplayFormatMemo();
25
+
8
26
  /** Formats an arbitrary eval-code prefix for display without changing the executed source. */
9
27
  export function formatEvalCodeForDisplay(source: string, language: EvalLanguage): string {
10
28
  if (/^\s*%/.test(source)) return source;
11
29
  switch (language) {
12
30
  case "js":
13
- return formatJavaScriptForDisplay(source);
31
+ return memoizedFormat(jsDisplayMemo, source, formatJavaScriptForDisplay);
14
32
  case "python":
15
- return formatPythonForDisplay(source);
33
+ return memoizedFormat(pythonDisplayMemo, source, formatPythonForDisplay);
16
34
  }
17
35
  }
36
+
37
+ function memoizedFormat(memo: LRUCache<string, string>, source: string, format: (source: string) => string): string {
38
+ const cached = memo.get(source);
39
+ if (cached !== undefined) return cached;
40
+ const formatted = format(source);
41
+ memo.set(source, formatted);
42
+ return formatted;
43
+ }
@@ -249,7 +249,9 @@ interface DisplayBraceNode {
249
249
 
250
250
  function classifySourceBraces(source: string): boolean[] {
251
251
  const objects: boolean[] = [];
252
- const statementWords: string[] = [];
252
+ // Whether the current statement has seen `class`/`function`/`switch`, whose
253
+ // next `{` opens a block. A flag instead of a word list keeps each brace O(1).
254
+ let statementDeclaresBlock = false;
253
255
  let previousToken = "";
254
256
  let previousWord = "";
255
257
  let regexAllowed = true;
@@ -287,7 +289,7 @@ function classifySourceBraces(source: string): boolean[] {
287
289
  if (isIdentifierStart(char)) {
288
290
  const end = scanIdentifier(source, index);
289
291
  const word = source.slice(index, end);
290
- statementWords.push(word);
292
+ if (word === "class" || word === "function" || word === "switch") statementDeclaresBlock = true;
291
293
  previousWord = word;
292
294
  previousToken = word;
293
295
  regexAllowed = REGEX_PREFIX_WORDS[word] === true;
@@ -307,7 +309,7 @@ function classifySourceBraces(source: string): boolean[] {
307
309
  previousToken === ")" ||
308
310
  previousToken === "}" ||
309
311
  BLOCK_BRACE_WORDS[previousWord] === true ||
310
- statementWords.some(word => word === "class" || word === "function" || word === "switch");
312
+ statementDeclaresBlock;
311
313
  const isObject =
312
314
  !isBlock &&
313
315
  (previousToken === "=" ||
@@ -319,7 +321,7 @@ function classifySourceBraces(source: string): boolean[] {
319
321
  previousToken === "" ||
320
322
  OBJECT_PREFIX_WORDS[previousWord] === true);
321
323
  objects.push(isObject);
322
- if (isBlock) statementWords.length = 0;
324
+ if (isBlock) statementDeclaresBlock = false;
323
325
  previousToken = "{";
324
326
  previousWord = "";
325
327
  regexAllowed = true;
@@ -334,7 +336,7 @@ function classifySourceBraces(source: string): boolean[] {
334
336
  continue;
335
337
  }
336
338
  if (char === ";") {
337
- statementWords.length = 0;
339
+ statementDeclaresBlock = false;
338
340
  previousToken = ";";
339
341
  previousWord = "";
340
342
  regexAllowed = true;
@@ -24,6 +24,8 @@ export interface EvalCellResult {
24
24
  durationMs?: number;
25
25
  exitCode?: number;
26
26
  statusEvents?: EvalStatusEvent[];
27
+ /** Discrete events dropped from the front of `statusEvents` (see {@link recordStatusEvent}). */
28
+ statusEventsElided?: number;
27
29
  hasMarkdown?: boolean;
28
30
  }
29
31
  /** Tool result detail object surfaced to the UI/transcript. */
@@ -32,6 +34,8 @@ export interface EvalToolDetails {
32
34
  jsonOutputs?: unknown[];
33
35
  images?: ImageContent[];
34
36
  statusEvents?: EvalStatusEvent[];
37
+ /** Discrete events dropped from the front of `statusEvents` (see {@link recordStatusEvent}). */
38
+ statusEventsElided?: number;
35
39
  isError?: boolean;
36
40
  meta?: OutputMeta;
37
41
  /** First backend that produced cells. Kept for transcript compatibility. */
@@ -74,13 +78,28 @@ export declare function statusEventKey(event: {
74
78
  op: string;
75
79
  [key: string]: unknown;
76
80
  }): string | undefined;
81
+ /**
82
+ * Discrete status events a log keeps. A cell polling a helper in a loop emits
83
+ * one event per call (hundreds of thousands), and every live update and the
84
+ * persisted tool result would otherwise carry them all.
85
+ */
86
+ export declare const MAX_STATUS_EVENTS = 200;
87
+ /** A status event list plus the count of discrete events dropped from its front. */
88
+ export type StatusEventLog = Pick<EvalCellResult, "statusEvents" | "statusEventsElided">;
77
89
  /**
78
90
  * Append or replace a status event. Progress snapshots (see
79
91
  * {@link statusEventKey}) coalesce in place, preserving first-seen order; every
80
- * other op is a discrete action and simply appends. Keeps the persisted event
81
- * list bounded even when a subagent or batch emits hundreds of progress ticks.
92
+ * other op is a discrete action and simply appends.
82
93
  */
83
94
  export declare function upsertStatusEvent(events: EvalStatusEvent[], event: EvalStatusEvent): void;
95
+ /**
96
+ * {@link upsertStatusEvent} into a bounded log. Past {@link MAX_STATUS_EVENTS},
97
+ * the oldest discrete event is dropped and counted. Snapshots stay, since agent
98
+ * cards read them, and so does the newest committed `todo` result, which the
99
+ * session todo panel refreshes from. Renderers already show only the newest
100
+ * events behind an "… N earlier" row.
101
+ */
102
+ export declare function recordStatusEvent(log: StatusEventLog, event: EvalStatusEvent): void;
84
103
  /** Render eval code cells, structured display output, and progress events. */
85
104
  export declare const evalToolRenderer: {
86
105
  animatedPendingPreview: true;
@@ -95,7 +114,7 @@ export declare const evalToolRenderer: {
95
114
  }, options: RenderResultOptions & {
96
115
  renderContext?: EvalRenderContext;
97
116
  }, uiTheme: Theme, _args?: EvalRenderArgs): Component;
98
- describeCall(args: EvalRenderArgs, _options: RenderResultOptions): NativeToolView;
117
+ describeCall(args: EvalRenderArgs, options: RenderResultOptions): NativeToolView;
99
118
  describeResult(result: {
100
119
  content: Array<{
101
120
  type: string;