@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
@@ -72,6 +72,53 @@ export declare function truncationNotice(meta: OutputMeta | undefined): NativeNo
72
72
  * truncation / artifact-capture notice from `meta`; undefined when empty.
73
73
  */
74
74
  export declare function footnoteText(parts: readonly string[], meta?: OutputMeta): NativeNode | undefined;
75
+ /** Drawn lines of a run's input (command, cell code) before its "N more lines" button. */
76
+ export declare const RUN_INPUT_PREVIEW_LINES = 6;
77
+ /**
78
+ * What a run's foot names: `running` (live clock), `background` (an async job
79
+ * outlives the call), and the settled outcomes. A failure with an exit code
80
+ * reads `exit N`; without one, `Failed`.
81
+ */
82
+ export type RunState = "running" | "background" | "done" | "failed" | "cancelled" | "timed-out";
83
+ /** Inputs of {@link runFoot}. */
84
+ export interface RunFootInput {
85
+ readonly state: RunState;
86
+ /** Exit code of a `failed` run; a non-zero code names the state `exit N`. */
87
+ readonly exitCode?: number;
88
+ /** Milliseconds run so far (`running`) or in total; the time is omitted when undefined. */
89
+ readonly elapsedMs?: number;
90
+ /** Quiet facts (job id, service state, artifact), muted and ` · `-joined. */
91
+ readonly facts?: readonly string[];
92
+ /** Truncation / artifact-capture notices, appended to the facts in `warning`. */
93
+ readonly meta?: OutputMeta;
94
+ }
95
+ /**
96
+ * The foot line of a run box (`zeta.run.foot`): the state word in its tone,
97
+ * the run time (a live clock while running, frozen once settled) and the
98
+ * quiet facts. Glyphs are the terminal's styling, never text.
99
+ */
100
+ export declare function runFoot(input: RunFootInput): NativeNode;
101
+ /** A run's input section: the command or cell source, clamped to {@link RUN_INPUT_PREVIEW_LINES}. */
102
+ export declare function runInput(source: string, p: {
103
+ role: string;
104
+ lang: string;
105
+ wrap: boolean;
106
+ }): NativeNode;
107
+ /** A run's terminal output: follows its tail, clamped to the last `previewLines` lines while folded. */
108
+ export declare function runOutput(output: string, p: {
109
+ role: string;
110
+ previewLines: number;
111
+ key?: string;
112
+ }): NativeNode;
113
+ /**
114
+ * One run as one box (`zeta.run`): input, output, status lines and foot in
115
+ * order. `tone` tints the box: `error` for a failed run, `warning` for a
116
+ * timed-out one.
117
+ */
118
+ export declare function runBox(children: readonly (NativeChild | undefined | false)[], p: {
119
+ key: string;
120
+ tone?: TspTone;
121
+ }): NativeNode;
75
122
  /** A diagnostic's severity glyph: `x-circle` error, `warn` warning, `info`, `lightbulb` hint, in the severity tone. */
76
123
  export declare function diagnosticGlyph(severity: ParsedDiagnostic["severity"]): NativeNode;
77
124
  /**
@@ -84,12 +84,22 @@ export interface LimitsMeta {
84
84
  reached: number;
85
85
  suggestion: number;
86
86
  };
87
- /** `unit` may be absent in sessions persisted before it was recorded. */
87
+ /**
88
+ * `unit` may be absent in sessions persisted before it was recorded. `lines` is
89
+ * the first-to-last range of cut lines, and `selectorBase` the target a
90
+ * `:raw:<line>-<line>` selector reads one of them whole from (an artifact's
91
+ * `artifact://<id>` stands in when absent).
92
+ */
88
93
  columnTruncated?: {
89
94
  maxColumn: number;
90
95
  unit?: "bytes" | "chars";
91
96
  artifactId?: string;
92
97
  artifactElidedBytes?: number;
98
+ lines?: {
99
+ first: number;
100
+ last: number;
101
+ };
102
+ selectorBase?: string;
93
103
  };
94
104
  }
95
105
  /**
@@ -25,6 +25,14 @@ export interface RenderResultOptions {
25
25
  * Streamed `xd://` previews stay queued until this is set.
26
26
  */
27
27
  executionStarted?: boolean;
28
+ /**
29
+ * Milliseconds since this call began executing (`tool_execution_start`),
30
+ * or its total once settled; undefined before it starts. Native describe
31
+ * hooks only.
32
+ */
33
+ elapsedMs?: number;
34
+ /** The call was abandoned without a final result (turn aborted, sealed). Native describe hooks only. */
35
+ cancelled?: boolean;
28
36
  }
29
37
  /** Render options for a result, plus the tool-specific context the transcript threads through. */
30
38
  export type RenderResultContextOptions = RenderResultOptions & {
@@ -39,6 +47,18 @@ export interface ToolRenderResult<TDetails = unknown> {
39
47
  details?: TDetails;
40
48
  isError?: boolean;
41
49
  }
50
+ /**
51
+ * A fence a tool call draws under its card, as assistant Markdown draws that
52
+ * fence. Any fence language may be named (`svg`, `mermaid`, `obj`); the
53
+ * transcript draws only those it draws as figures in assistant text.
54
+ */
55
+ export interface ToolFigure {
56
+ readonly lang: string;
57
+ /** The body so far. */
58
+ readonly source: string;
59
+ /** No more of the body arrives. */
60
+ readonly closed: boolean;
61
+ }
42
62
  /**
43
63
  * Per-renderer opt-in for a full viewport replay when the first result
44
64
  * replaces a painted pending-call render. A predicate receives the painted
@@ -73,6 +93,8 @@ export interface NativeToolHead {
73
93
  readonly targetKind?: TspToolProps["targetKind"];
74
94
  /** Language for `command` targets. */
75
95
  readonly lang?: string;
96
+ /** The raw command line the head's Copy command button copies (set implicitly by a `command` target). */
97
+ readonly command?: string;
76
98
  /** `file://` link for path targets. */
77
99
  readonly href?: string;
78
100
  /** Short facts after the target (`+8 −1`, `5 matches · 2 files`). */
@@ -99,10 +121,15 @@ export interface NativeToolView {
99
121
  readonly body?: readonly NativeChild[];
100
122
  /** Tone override; the frame otherwise derives it from the call status. */
101
123
  readonly tone?: TspTone;
102
- /** Body clamp while collapsed; `{tail}` keeps the end (terminal output). Defaults to the transcript's preview size. */
124
+ /**
125
+ * Body clamp while collapsed; `{tail}` keeps the end (terminal output). Defaults to the transcript's preview size.
126
+ * `children`: the body stays whole while collapsed and its own `ansi`/`code` previews clamp instead.
127
+ */
103
128
  readonly preview?: TspPreview | {
104
129
  readonly tail: number;
105
- } | "none";
130
+ } | "none" | "children";
131
+ /** Starts expanded whatever the transcript's expand state (the todo checklist); the user can still fold it. */
132
+ readonly open?: boolean;
106
133
  /** Render frameless (`frame:"inline"`): a head line plus a disclosed body. */
107
134
  readonly inline?: boolean;
108
135
  /** Head actions offered on hover (`copy`, `retry`). */
@@ -125,6 +152,14 @@ export interface ToolRenderer<TArgs = unknown, TDetails = unknown> {
125
152
  /** Semantic result view for TSP terminals; merged with the call view when {@link mergeCallAndResult}. */
126
153
  describeResult?(result: ToolRenderResult<TDetails>, options: RenderResultContextOptions, args?: TArgs): NativeToolView | undefined;
127
154
  mergeCallAndResult?: boolean;
155
+ /**
156
+ * The fence a call draws under its card (a `.svg` being written, as its
157
+ * image): growing while the args stream, closed once they are final; none
158
+ * after an error. `result` is undefined until the call has one. Rendered
159
+ * TUI only, and only fences the terminal draws as figures; native views put
160
+ * their drawing in their describe hooks.
161
+ */
162
+ figure?(args: TArgs, result: ToolRenderResult<TDetails> | undefined, options: RenderResultOptions): ToolFigure | undefined;
128
163
  /** Describes current activity without coupling a renderer to terminal layout. */
129
164
  activitySummary?(args: TArgs, context: ToolActivityContext): ToolActivitySummary;
130
165
  /** Render without background box, inline in the response flow */
@@ -31,6 +31,15 @@ export interface OutputSummary {
31
31
  columnDroppedBytes?: number;
32
32
  /** Number of distinct lines that hit the per-line column cap. */
33
33
  columnTruncatedLines?: number;
34
+ /**
35
+ * 1-indexed first and last lines the column cap cut, numbered as in the
36
+ * artifact. Absent when the numbering cannot match the artifact (an inline
37
+ * substitute was capped, or `replace()` rewrote the buffer).
38
+ */
39
+ columnTruncatedRange?: {
40
+ first: number;
41
+ last: number;
42
+ };
34
43
  /** Configured per-line column cap in effect (UTF-8 bytes), when > 0. */
35
44
  columnMax?: number;
36
45
  /** Artifact ID for internal URL access (artifact://<id>) when truncated */
@@ -236,7 +245,8 @@ export declare class OutputSink {
236
245
  constructor(options?: OutputSinkOptions);
237
246
  /**
238
247
  * Push a chunk of output. The buffer management and onChunk callback run
239
- * synchronously. File sink writes are deferred and serialized internally.
248
+ * synchronously; onChunk fires after the chunk is stored, so {@link preview}
249
+ * already includes it. File sink writes are deferred and serialized internally.
240
250
  *
241
251
  * `inline` substitutes a bounded representation for the in-memory buffer and
242
252
  * live preview while the complete chunk is mirrored to the artifact.
@@ -260,6 +270,15 @@ export declare class OutputSink {
260
270
  * branch in `dump()` against stale totals.
261
271
  */
262
272
  replace(text: string): void;
273
+ /**
274
+ * Current inline view without finalizing: the body {@link dump} would
275
+ * return right now (head + elision marker + rolling tail), minus any notice
276
+ * and minus the newline `dump()` appends after output that ends in a bare
277
+ * carriage return. Each call trims the rolling tail to its budget (a copy
278
+ * of the tail window once it overflowed), so call it from a throttled
279
+ * onChunk (`chunkThrottleMs`), not once per raw chunk.
280
+ */
281
+ preview(): string;
263
282
  dump(notice?: string): Promise<OutputSummary>;
264
283
  /**
265
284
  * Release the artifact spill descriptor on an exit path that skips
@@ -1,10 +1,9 @@
1
1
  import type { Usage } from "@linxiraos/pi-ai";
2
2
  import type { ThemeColor } from "../theme/theme.js";
3
3
  import type { ConfiguredThinkingLevel } from "../render/render-utils.js";
4
+ import type { RenderResultOptions, NativeToolView, ToolRenderResult } from "./renderer.js";
4
5
  import { type Component } from "../tui.js";
5
- import type { RenderResultOptions } from "./renderer.js";
6
6
  import { type Theme } from "../theme/theme.js";
7
- import type { NativeToolView, ToolRenderResult } from "./renderer.js";
8
7
  /** Render context threaded in from `ToolExecutionComponent.#buildRenderContext`. */
9
8
  interface TaskRenderContext {
10
9
  hasResult?: boolean;
@@ -255,7 +254,7 @@ export interface AgentProgress {
255
254
  resolvedModelRoute?: string;
256
255
  /** True when a live advisor was attached to this run's session, not merely enabled in settings. */
257
256
  advisor?: boolean;
258
- /** The agent's latest self-estimate of task completion (0–100), from the periodic `task.completionProbeMs` side request. */
257
+ /** The agent's latest self-estimate of task completion (0–100), from the periodic `task.completionProbe` side request. */
259
258
  completionPercent?: number;
260
259
  /** Data extracted by registered subprocess tool handlers (keyed by tool name) */
261
260
  extractedToolData?: Record<string, unknown[]>;
@@ -6,7 +6,7 @@ import { type ProcWriteDetails } from "./proc-render.js";
6
6
  import { type CfgWriteDetails } from "./cfg-render.js";
7
7
  import type { FileDiagnosticsResult } from "./lsp.js";
8
8
  import type { OutputMeta } from "./output-meta.js";
9
- import type { NativeToolView, RenderResultOptions, ToolActivityContext, ToolActivitySummary } from "./renderer.js";
9
+ import type { NativeToolView, RenderResultOptions, ToolActivityContext, ToolActivitySummary, ToolFigure } from "./renderer.js";
10
10
  import { type XdevRenderDispatch, type XdevMountedRenderer } from "./xdev.js";
11
11
  /** Details returned by the write tool for transcript rendering. */
12
12
  export interface WriteToolDetails {
@@ -37,6 +37,12 @@ interface WriteResult {
37
37
  details?: WriteToolDetails;
38
38
  isError?: boolean;
39
39
  }
40
+ /**
41
+ * The fence a file write draws as while its content streams and after: its
42
+ * extension names a figure language and it has content, closed once the args
43
+ * are final. None for URL-card writes, or after an error.
44
+ */
45
+ declare function writeFigure(args: WriteRenderArgs | undefined, result: WriteResult | undefined, options: RenderResultOptions): ToolFigure | undefined;
40
46
  declare const writeStreamingPreviewStateKey: unique symbol;
41
47
  /**
42
48
  * Per-component state for incrementally rendering a streamed write.
@@ -75,7 +81,7 @@ export declare const writeToolRenderer: {
75
81
  renderCall(args: WriteRenderArgs, options: RenderResultOptions & WriteStreamingPreviewStateCarrier & {
76
82
  renderContext?: WriteRenderContext;
77
83
  }, uiTheme: Theme): Component | undefined;
78
- renderResult(result: WriteResult, options: RenderResultOptions & {
84
+ renderResult(result: WriteResult, options: RenderResultOptions & WriteStreamingPreviewStateCarrier & {
79
85
  renderContext?: WriteRenderContext;
80
86
  }, uiTheme: Theme, args?: WriteRenderArgs): Component;
81
87
  describeCall(args: WriteRenderArgs, options: RenderResultOptions & {
@@ -84,6 +90,7 @@ export declare const writeToolRenderer: {
84
90
  describeResult(result: WriteResult, options: RenderResultOptions & {
85
91
  renderContext?: WriteRenderContext;
86
92
  }, args?: WriteRenderArgs): NativeToolView | undefined;
93
+ figure: typeof writeFigure;
87
94
  mergeCallAndResult: true;
88
95
  forceFirstResultViewportRepaint: (args: unknown, options: RenderResultOptions) => boolean;
89
96
  };
@@ -0,0 +1,22 @@
1
+ import type { Theme } from "../theme/theme.js";
2
+ import type { Component } from "../tui.js";
3
+ import type { NativeToolView, RenderResultContextOptions, RenderResultOptions, ToolRenderResult } from "./renderer.js";
4
+ import type { YieldItem } from "./task.js";
5
+ /** `yield` arguments as sent; strict-mode providers send omitted optionals as `null`. */
6
+ interface YieldRenderArgs {
7
+ type?: string | string[] | null;
8
+ data?: unknown;
9
+ error?: string | null;
10
+ /** 1-based workpool item number. */
11
+ key?: number;
12
+ }
13
+ /** Shows a `yield` call's submitted data instead of its model-facing acknowledgement. */
14
+ export declare const yieldToolRenderer: {
15
+ renderCall(args: YieldRenderArgs, options: RenderResultOptions, theme: Theme): Component;
16
+ renderResult(result: ToolRenderResult<YieldItem>, options: RenderResultContextOptions, theme: Theme, args?: YieldRenderArgs): Component;
17
+ describeCall(args: YieldRenderArgs, options: RenderResultOptions): NativeToolView;
18
+ describeResult(result: ToolRenderResult<YieldItem>, _options: RenderResultContextOptions, args?: YieldRenderArgs): NativeToolView;
19
+ mergeCallAndResult: true;
20
+ animatedPendingPreview: true;
21
+ };
22
+ export {};
@@ -78,6 +78,10 @@ export interface TUIStartOptions {
78
78
  * Paint without owning stdin: the terminal stays in cooked mode (kernel
79
79
  * echo + line editing at the hardware cursor) until {@link TUI.enableInput}
80
80
  * switches to raw input and replays the kernel-buffered keystrokes.
81
+ *
82
+ * A terminal expected to speak TSP needs raw input from the start, so it
83
+ * gets it; its keystrokes are held instead (TSP events and the cell-size
84
+ * reply still apply) until {@link TUI.releaseHeldInput} replays them.
81
85
  */
82
86
  deferInput?: boolean;
83
87
  }
@@ -150,6 +154,11 @@ export interface Component {
150
154
  describeScreen?(cx: DescribeContext): NativeScreen;
151
155
  /** User actions on nodes this component described (toggle, select, activate, custom). */
152
156
  handleNativeEvent?(event: NativeUiEvent): void;
157
+ /**
158
+ * Pure preflight for focused input that must precede TUI-wide input listeners
159
+ * and debug shortcuts. A true result routes the event to this component first.
160
+ */
161
+ capturesInput?(data: string): boolean;
153
162
  /**
154
163
  * Optional handler for keyboard input when component has focus
155
164
  */
@@ -164,6 +173,16 @@ export interface Component {
164
173
  * Called when theme changes or when component needs to re-render from scratch.
165
174
  */
166
175
  invalidate?(): void;
176
+ /**
177
+ * Optional hook to drop memoized render output (rows, parse and wrap state)
178
+ * that the next `render()` can rebuild from state the component keeps.
179
+ * Unlike {@link invalidate}, it must not rebuild anything eagerly: no
180
+ * renderer or extension callbacks, no image conversions, and no child
181
+ * replacement or disposal. The next render must return the same rows it
182
+ * would have returned without the release. Components without it are
183
+ * simply not released.
184
+ */
185
+ releaseRenderCaches?(): void;
167
186
  /**
168
187
  * Optional hook to set whether this component ignores tight layout mode.
169
188
  */
@@ -303,6 +322,7 @@ export declare class Container implements Component {
303
322
  /** Dispose every child, then detach it from this container. */
304
323
  disposeChildren(): void;
305
324
  invalidate(): void;
325
+ releaseRenderCaches(): void;
306
326
  /**
307
327
  * Propagate teardown to children. Call when the container's children are
308
328
  * being permanently discarded (not when they are detached for reuse — use
@@ -471,6 +491,22 @@ export declare class TUI extends Container {
471
491
  * path. Idempotent; no-op when input was never deferred.
472
492
  */
473
493
  enableInput(): void;
494
+ /**
495
+ * Replay the keystrokes held since a TSP `deferInput` start through the
496
+ * normal input path, then deliver input live. Call once the app's key
497
+ * handlers are installed so a hotkey pressed during startup still fires.
498
+ * Only keys typed while the start-time focus owner had focus are held. The
499
+ * hold survives a stop/start until released. Idempotent; no-op when nothing
500
+ * is held.
501
+ */
502
+ releaseHeldInput(): void;
503
+ /**
504
+ * Hand held-key ownership from `previous` to `next` when the app replaces
505
+ * the component focused at start (a swapped-in custom editor), so keys
506
+ * typed into the replacement stay queued behind the held ones instead of
507
+ * overtaking them. No-op unless `previous` owns the held keys.
508
+ */
509
+ replaceHeldFocus(previous: Component, next: Component): void;
474
510
  addStartListener(listener: StartListener): () => void;
475
511
  addInputListener(listener: InputListener): () => void;
476
512
  removeInputListener(listener: InputListener): void;
@@ -26,6 +26,12 @@ export interface TextSizingOptions {
26
26
  */
27
27
  export declare function encodeTextSized(text: string, options?: TextSizingOptions): string;
28
28
  export declare function sliceWithWidth(line: string, startCol: number, length: number, strict?: boolean | null): SliceResult;
29
+ /**
30
+ * Hard-wrap one literal terminal row without trimming spaces or splitting graphemes.
31
+ * An oversized grapheme is emitted intact even when it exceeds the requested width.
32
+ * Zero-cell rows remain one empty row, matching restored-terminal reflow.
33
+ */
34
+ export declare function wrapLiteralLine(line: string, width: number): string[];
29
35
  export declare function truncateToWidth(text: string, maxWidth: number, ellipsisKind?: Ellipsis | null | "", pad?: boolean | null): string;
30
36
  export declare function wrapTextWithAnsi(text: string, width: number): string[];
31
37
  export declare function extractSegments(line: string, beforeEnd: number, afterStart: number, afterLen: number, strictAfter: boolean): ExtractSegmentsResult;
@@ -8,8 +8,8 @@
8
8
  * This is a usable subset of Vim, not a reimplementation of it (see issue #3299): Normal and Visual
9
9
  * modes, the common motions, and operators built from those motions.
10
10
  */
11
- export type VimMode = "insert" | "normal" | "visual" | "visual-line";
12
- export type VimOperator = "d" | "y" | "c";
11
+ export type VimMode = "insert" | "normal" | "visual" | "visual-line" | "replace";
12
+ export type VimOperator = "d" | "y" | "c" | ">" | "<";
13
13
  export interface VimPosition {
14
14
  line: number;
15
15
  col: number;
@@ -50,6 +50,20 @@ export type VimCommand = {
50
50
  count: number;
51
51
  } | {
52
52
  kind: "undo";
53
+ } | {
54
+ kind: "replace";
55
+ from: VimPosition;
56
+ to: VimPosition;
57
+ text: string;
58
+ } | {
59
+ kind: "join";
60
+ fromLine: number;
61
+ lines: number;
62
+ } | {
63
+ kind: "indent";
64
+ fromLine: number;
65
+ toLine: number;
66
+ out: boolean;
53
67
  };
54
68
  /** Start offset of the grapheme after `col`, clamped to `text.length`. */
55
69
  export declare function nextGraphemeStart(text: string, col: number): number;
@@ -62,11 +76,11 @@ export declare class VimState {
62
76
  mode: VimMode;
63
77
  /** Fixed end of a Visual selection; the cursor is the moving end. */
64
78
  anchor: VimPosition | null;
65
- /** True while a count, operator, `g`, or text-object prefix is half-typed — Escape cancels it. */
79
+ /** True while a count, operator, `g`, text-object, find, or `r` prefix is half-typed — Escape cancels it. */
66
80
  get pending(): boolean;
67
81
  /**
68
- * The half-typed command as Vim would echo it (`"2"`, `"d"`, `"2d"`, `"di"`) — empty when
69
- * nothing is pending. Hosts render this next to the mode so a partially entered operator is
82
+ * The half-typed command as Vim would echo it (`"2"`, `"d"`, `"2d"`, `"di"`, `"df"`, `"r"`) — empty
83
+ * when nothing is pending. Hosts render this next to the mode so a partially entered operator is
70
84
  * visible instead of silently swallowing the next keystroke.
71
85
  */
72
86
  get pendingText(): string;
@@ -16,10 +16,26 @@
16
16
  * terminal sends; chords legacy encoding loses (modified Enter/Tab/Escape,
17
17
  * Ctrl+Shift+letter, …) translate to kitty CSI-u, which key matching already
18
18
  * parses.
19
+ *
20
+ * A host terminal that writes VT instead of key records (any ConPTY host
21
+ * besides Windows Terminal's native path) reaches us as one `Vk = 0` text
22
+ * record per byte: Alt+Up arrives as `ESC`, `[`, `1`, `;`, `3`, `A`. Those
23
+ * bytes are reassembled into the escape sequence they spell; delivering them
24
+ * one at a time turns every such key into a bare Escape plus typed garbage.
25
+ */
26
+ /**
27
+ * Stateful decoder: joins UTF-16 surrogate halves that arrive as separate
28
+ * records, and reassembles VT escape sequences relayed as text records.
19
29
  */
20
- /** Stateful decoder: joins UTF-16 surrogate halves that arrive as separate records. */
21
30
  export declare class Win32InputModeDecoder {
22
31
  #private;
32
+ /** Whether relayed VT text is held waiting for the rest of its sequence. */
33
+ get hasPendingSequence(): boolean;
34
+ /**
35
+ * Release held VT text as-is. The caller invokes this once no further bytes
36
+ * arrived in time, so a lone relayed ESC still acts as the Escape key.
37
+ */
38
+ flushPendingSequence(): string[];
23
39
  /**
24
40
  * Translate one stdin sequence. Returns `undefined` when `data` is not a
25
41
  * win32-input-mode record (pass it through unchanged), otherwise the key
@@ -35,3 +51,19 @@ export declare class Win32InputModeDecoder {
35
51
  */
36
52
  decodePaste(content: string): string;
37
53
  }
54
+ /**
55
+ * Restores paste delimiters that a Windows console host emitted as individual
56
+ * win32-input-mode key records before StdinBuffer searches for the delimiters.
57
+ * Non-matching records remain untouched for normal key and paste decoding.
58
+ */
59
+ export declare class Win32PasteMarkerNormalizer {
60
+ #private;
61
+ /**
62
+ * `onExpired` runs after held records are released because their wait timed
63
+ * out, so a downstream holder can treat the same wait as already elapsed.
64
+ */
65
+ constructor(onInput: (data: string) => void, onExpired?: () => void);
66
+ process(data: string): void;
67
+ /** Release an incomplete marker as its original key records. */
68
+ flush(): void;
69
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@linxiraos/pi-tui",
4
- "version": "1.1.26",
4
+ "version": "1.2.0",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://linxira-os.github.io/zeta/",
7
7
  "author": "Linxira-OS",
@@ -38,14 +38,14 @@
38
38
  "gen:glyphs": "bun scripts/gen-glyphs.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@linxiraos/pi-omptype": "1.1.26",
42
- "@linxiraos/pi-agent-core": "1.1.26",
43
- "@linxiraos/pi-ai": "1.1.26",
44
- "@linxiraos/pi-catalog": "1.1.26",
45
- "@linxiraos/pi-natives": "1.1.26",
46
- "@linxiraos/pi-utils": "1.1.26",
47
- "@linxiraos/pi-wire": "1.1.26",
48
- "@linxiraos/pi-snapcompact": "1.1.26"
41
+ "@linxiraos/pi-omptype": "1.2.0",
42
+ "@linxiraos/pi-agent-core": "1.2.0",
43
+ "@linxiraos/pi-ai": "1.2.0",
44
+ "@linxiraos/pi-catalog": "1.2.0",
45
+ "@linxiraos/pi-natives": "1.2.0",
46
+ "@linxiraos/pi-utils": "1.2.0",
47
+ "@linxiraos/pi-wire": "1.2.0",
48
+ "@linxiraos/pi-snapcompact": "1.2.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "kitty-vt-wasm": "^0.2.0"
@@ -102,6 +102,10 @@
102
102
  "types": "./dist/types/components/*.d.ts",
103
103
  "import": "./src/components/*.ts"
104
104
  },
105
+ "./native/*": {
106
+ "types": "./dist/types/native/*.d.ts",
107
+ "import": "./src/native/*.ts"
108
+ },
105
109
  "./*.js": "./src/*.ts"
106
110
  }
107
111
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Ownership of stdout by a started {@link ProcessTerminal}, kept in a leaf
3
+ * module so writers that `terminal.ts` itself imports (terminal capabilities,
4
+ * notifications) can route through the active terminal without an import cycle.
5
+ */
6
+ import type { ProcessTerminal } from "./terminal";
7
+ /** The started terminal that owns stdout in this thread, if any. */
8
+ export declare function getActiveTerminal(): ProcessTerminal | null;
9
+ /** Record the terminal that owns stdout (`ProcessTerminal.start`), or release it with `null` (`stop`). */
10
+ export declare function setActiveTerminal(terminal: ProcessTerminal | null): void;
11
+ /** Observe stdout errors through the shared listener. Returns the unregister callback. */
12
+ export declare function registerStdoutErrorHandler(handler: (err: Error) => void): () => void;
13
+ /**
14
+ * Hand `data` to the active terminal's ordered output path. Returns false when
15
+ * no terminal in this thread has started. On the main thread that means the
16
+ * caller owns stdout; a worker thread never sees the main thread's terminal, so
17
+ * there `false` is not permission to write. Prefer {@link writeTerminalSequence}.
18
+ */
19
+ export declare function writeThroughActiveTerminal(data: string): boolean;
20
+ /**
21
+ * Write an out-of-band escape sequence (window title, OSC 52 clipboard,
22
+ * notification). While a TUI owns stdout, its frames go through an off-thread
23
+ * pump in chunks that ignore escape boundaries; a direct `process.stdout.write`
24
+ * can land between two chunks and split a frame's escape sequence, and the host
25
+ * terminal then prints its tail as text. So the sequence takes the active
26
+ * terminal's ordered output path, and goes straight to stdout, best-effort, only
27
+ * when no terminal owns it. A worker thread cannot reach the main thread's
28
+ * terminal and would write around its pump, so it writes nothing.
29
+ */
30
+ export declare function writeTerminalSequence(data: string): void;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Ownership of stdout by a started {@link ProcessTerminal}, kept in a leaf
3
+ * module so writers that `terminal.ts` itself imports (terminal capabilities,
4
+ * notifications) can route through the active terminal without an import cycle.
5
+ */
6
+ import type { ProcessTerminal } from "./terminal";
7
+
8
+ // The started terminal that owns stdout in this thread; also consulted by the
9
+ // emergency restore on crash.
10
+ let activeTerminal: ProcessTerminal | null = null;
11
+
12
+ /** The started terminal that owns stdout in this thread, if any. */
13
+ export function getActiveTerminal(): ProcessTerminal | null {
14
+ return activeTerminal;
15
+ }
16
+
17
+ /** Record the terminal that owns stdout (`ProcessTerminal.start`), or release it with `null` (`stop`). */
18
+ export function setActiveTerminal(terminal: ProcessTerminal | null): void {
19
+ activeTerminal = terminal;
20
+ }
21
+
22
+ const stdoutErrorHandlers = new Set<(err: Error) => void>();
23
+ let stdoutErrorListenerInstalled = false;
24
+
25
+ function onStdoutError(err: Error): void {
26
+ for (const handler of stdoutErrorHandlers) handler(err);
27
+ }
28
+
29
+ /**
30
+ * Install the one shared `process.stdout` `error` listener. Its presence alone
31
+ * keeps a stdout error (EPIPE on a closed pipe, EIO on a revoked PTY) from
32
+ * crashing the process as an unhandled `error` event.
33
+ */
34
+ function installStdoutErrorListener(): void {
35
+ if (stdoutErrorListenerInstalled) return;
36
+ process.stdout.on("error", onStdoutError);
37
+ stdoutErrorListenerInstalled = true;
38
+ }
39
+
40
+ /** Observe stdout errors through the shared listener. Returns the unregister callback. */
41
+ export function registerStdoutErrorHandler(handler: (err: Error) => void): () => void {
42
+ stdoutErrorHandlers.add(handler);
43
+ installStdoutErrorListener();
44
+ return () => {
45
+ stdoutErrorHandlers.delete(handler);
46
+ };
47
+ }
48
+
49
+ /**
50
+ * Hand `data` to the active terminal's ordered output path. Returns false when
51
+ * no terminal in this thread has started. On the main thread that means the
52
+ * caller owns stdout; a worker thread never sees the main thread's terminal, so
53
+ * there `false` is not permission to write. Prefer {@link writeTerminalSequence}.
54
+ */
55
+ export function writeThroughActiveTerminal(data: string): boolean {
56
+ if (!activeTerminal) return false;
57
+ activeTerminal.write(data);
58
+ return true;
59
+ }
60
+
61
+ /**
62
+ * Write an out-of-band escape sequence (window title, OSC 52 clipboard,
63
+ * notification). While a TUI owns stdout, its frames go through an off-thread
64
+ * pump in chunks that ignore escape boundaries; a direct `process.stdout.write`
65
+ * can land between two chunks and split a frame's escape sequence, and the host
66
+ * terminal then prints its tail as text. So the sequence takes the active
67
+ * terminal's ordered output path, and goes straight to stdout, best-effort, only
68
+ * when no terminal owns it. A worker thread cannot reach the main thread's
69
+ * terminal and would write around its pump, so it writes nothing.
70
+ */
71
+ export function writeTerminalSequence(data: string): void {
72
+ if (!Bun.isMainThread) return;
73
+ if (writeThroughActiveTerminal(data)) return;
74
+ installStdoutErrorListener();
75
+ try {
76
+ process.stdout.write(data);
77
+ } catch {
78
+ // Best-effort: a closed stdout must not fail the caller.
79
+ }
80
+ }
@@ -40,6 +40,7 @@ interface AppKeybindings {
40
40
  "app.tree.unfoldOrDown": true;
41
41
  "app.plan.toggle": true;
42
42
  "app.history.search": true;
43
+ "app.stt.pushToTalk": true;
43
44
  "app.stt.toggle": true;
44
45
  "app.live.toggle": true;
45
46
  }
@@ -118,7 +119,7 @@ export declare const KEYBINDINGS: {
118
119
  readonly description: "Delete word backward";
119
120
  };
120
121
  readonly "tui.editor.deleteWordForward": {
121
- readonly defaultKeys: ["alt+delete", "alt+d", "super+alt+delete", "super+alt+d"];
122
+ readonly defaultKeys: ["alt+delete", "alt+d", "ctrl+delete", "super+alt+delete", "super+alt+d"];
122
123
  readonly description: "Delete word forward";
123
124
  };
124
125
  readonly "tui.editor.deleteToLineStart": {
@@ -329,9 +330,13 @@ export declare const KEYBINDINGS: {
329
330
  readonly defaultKeys: "ctrl+r";
330
331
  readonly description: "Search history";
331
332
  };
333
+ readonly "app.stt.pushToTalk": {
334
+ readonly defaultKeys: "space";
335
+ readonly description: "Hold to record speech-to-text";
336
+ };
332
337
  readonly "app.stt.toggle": {
333
338
  readonly defaultKeys: [];
334
- readonly description: "Toggle speech-to-text (default gesture: hold Space)";
339
+ readonly description: "Toggle speech-to-text recording";
335
340
  };
336
341
  readonly "app.live.toggle": {
337
342
  readonly defaultKeys: "ctrl+l";