@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
@@ -19,7 +19,7 @@ import { centerLine, sliceWithWidth, truncateToWidth, visibleWidth } from "../..
19
19
  import { formatBytes } from "@linxiraos/pi-utils";
20
20
  import { sanitizeDisplayText } from "../../overlays/extensions/display-text";
21
21
  import { getLanguageFromPath } from "../../lang-from-path";
22
- import { createHighlightStream, theme } from "../../theme/theme";
22
+ import { createHighlightStream, getThemeEpoch, theme } from "../../theme/theme";
23
23
  import { bgAnsiHex, canvasHex, fgAnsiHex, mixHex, pill, selectionBgAnsi, textHex, withBg } from "./colors";
24
24
  import { DIFF_CONTEXT_LINES, type FileAssetSide, type FileStreamUpdate } from "./state";
25
25
  import { tuiText } from "../../i18n";
@@ -184,6 +184,10 @@ export interface DiffBuildOptions {
184
184
  streamResult?: DiffStreamResult;
185
185
  }
186
186
 
187
+ function filePatchHeader(filePath: string): string {
188
+ return `diff --git a/${filePath} b/${filePath}\n--- a/${filePath}\n+++ b/${filePath}\n`;
189
+ }
190
+
187
191
  /** Build the aligned document for one file from its raw old/new texts. */
188
192
  export function buildDiffDocument(
189
193
  oldRaw: string,
@@ -376,10 +380,11 @@ export function buildDiffDocument(
376
380
  // cannot use the raw streamed result because its equality basis differs.
377
381
  const canPatch = !ignoreWs;
378
382
  const tightHunks = streamed?.hunks ?? structuredPatchHunks(oldBasis, newBasis, DIFF_CONTEXT_LINES);
383
+ const patchHeader = canPatch && tightHunks.length > 0 ? filePatchHeader(filePath) : "";
379
384
  const allHunks: HunkBlock[] = tightHunks.map(hunk => ({
380
385
  header: `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`,
381
386
  patch: canPatch
382
- ? `--- a/${filePath}\n+++ b/${filePath}\n@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@\n${hunk.lines.join("\n")}\n`
387
+ ? `${patchHeader}@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@\n${hunk.lines.join("\n")}\n`
383
388
  : "",
384
389
  rows: walkHunk(hunk, false),
385
390
  }));
@@ -476,7 +481,7 @@ export function buildLineSelectionPatch(
476
481
  `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@\n${hunk.lines.join("\n")}`,
477
482
  )
478
483
  .join("\n");
479
- return `--- a/${doc.filePath}\n+++ b/${doc.filePath}\n${body}\n`;
484
+ return `${filePatchHeader(doc.filePath)}${body}\n`;
480
485
  }
481
486
 
482
487
  // ── palette ──────────────────────────────────────────────────────────────────
@@ -497,9 +502,12 @@ interface DiffPalette {
497
502
  gutterDel: string;
498
503
  }
499
504
 
500
- let paletteCache: { key: string; palette: DiffPalette } | undefined;
505
+ let paletteCache: { epoch: number; theme: object; palette: DiffPalette } | undefined;
501
506
 
507
+ /** Diff colors for the active theme, rebuilt only when the theme instance or epoch changes. */
502
508
  function palette(): DiffPalette {
509
+ const epoch = getThemeEpoch();
510
+ if (paletteCache?.epoch === epoch && paletteCache.theme === theme) return paletteCache.palette;
503
511
  const added = theme.getColorHex("toolDiffAdded");
504
512
  const removed = theme.getColorHex("toolDiffRemoved");
505
513
  const accent = theme.getColorHex("accent");
@@ -507,8 +515,6 @@ function palette(): DiffPalette {
507
515
  const dark = luminance === undefined || luminance <= 0.5;
508
516
  const canvas = canvasHex();
509
517
  const text = textHex();
510
- const key = `${added}\u0000${removed}\u0000${accent}\u0000${dark}\u0000${canvas}\u0000${text}`;
511
- if (paletteCache?.key === key) return paletteCache.palette;
512
518
  const built: DiffPalette = {
513
519
  addSoft: bgAnsiHex(mixHex(canvas, added, dark ? 0.18 : 0.24)),
514
520
  addStrong: bgAnsiHex(mixHex(canvas, added, dark ? 0.42 : 0.48)),
@@ -524,7 +530,7 @@ function palette(): DiffPalette {
524
530
  gutterAdd: added,
525
531
  gutterDel: removed,
526
532
  };
527
- paletteCache = { key, palette: built };
533
+ paletteCache = { epoch, theme, palette: built };
528
534
  return built;
529
535
  }
530
536
 
@@ -594,8 +600,18 @@ export class DiffPane {
594
600
  #lastHeight = 1;
595
601
  #lastWidth = 0;
596
602
  #layoutCache: { key: string; visuals: Visual[] } | undefined;
603
+ /** Minimap column for (layout, height, scroll offset, palette). */
604
+ #minimapCache:
605
+ | { visuals: Visual[]; height: number; scrollTop: number; colors: DiffPalette; lines: string[] }
606
+ | undefined;
597
607
  /** Per visible row: clickable hunk-button ranges recorded during render. */
598
608
  #hits: ({ hunk: number; primary?: [number, number]; discard?: [number, number] } | undefined)[] = [];
609
+ /**
610
+ * Asset images from the last render, by placement and size. Reusing them
611
+ * lets a SIXEL image show the sequence its off-thread encode delivers on a
612
+ * later render; a fresh `Image` per render would restart the encode forever.
613
+ */
614
+ #assetImages = new Map<string, Image>();
599
615
  constructor(imageBudget?: ImageBudget) {
600
616
  this.#imageBudget = imageBudget;
601
617
  }
@@ -721,6 +737,7 @@ export class DiffPane {
721
737
  this.scrollLeft = 0;
722
738
  this.cursor = 0;
723
739
  this.anchor = null;
740
+ if (mode === "hunk") this.selectedHunk = 0;
724
741
  }
725
742
 
726
743
  cycleMode(): void {
@@ -771,6 +788,7 @@ export class DiffPane {
771
788
  this.anchor = null;
772
789
  }
773
790
  this.cursor = Math.max(0, Math.min(total - 1, this.cursor + delta));
791
+ this.#syncHunkToCursor();
774
792
  this.scrollTop = scrollOffsetForRow(this.scrollTop, this.cursor, total, this.#lastHeight);
775
793
  this.#clampScroll();
776
794
  }
@@ -854,6 +872,7 @@ export class DiffPane {
854
872
  if (total === 0) return;
855
873
  this.anchor = null;
856
874
  this.cursor = edge === "start" ? 0 : total - 1;
875
+ this.#syncHunkToCursor();
857
876
  this.scrollTop = scrollOffsetForRow(this.scrollTop, this.cursor, total, this.#lastHeight);
858
877
  this.#clampScroll();
859
878
  }
@@ -870,6 +889,19 @@ export class DiffPane {
870
889
  }
871
890
  }
872
891
 
892
+ /** Keep the hunk action and highlighted header on the cursor's hunk, including blank separators. */
893
+ #syncHunkToCursor(): void {
894
+ if (this.mode !== "hunk") return;
895
+ const visuals = this.#layout(this.#lastWidth || 80);
896
+ for (let row = this.cursor; row >= 0; row--) {
897
+ const visual = visuals[row];
898
+ if (visual?.t === "header") {
899
+ this.selectedHunk = visual.hunk;
900
+ return;
901
+ }
902
+ }
903
+ }
904
+
873
905
  /** First visual row of every change block, in document order. */
874
906
  #changeStarts(visuals: Visual[]): number[] {
875
907
  const starts: number[] = [];
@@ -917,6 +949,10 @@ export class DiffPane {
917
949
  const hit = this.#hits[row];
918
950
  if (hit && this.#doc) {
919
951
  this.selectedHunk = hit.hunk;
952
+ if (this.mode === "hunk") {
953
+ this.cursor = this.scrollTop + row;
954
+ this.anchor = null;
955
+ }
920
956
  if (hit.primary && col >= hit.primary[0] && col < hit.primary[1] && this.patchTarget) {
921
957
  return { type: "hunk-action", hunk: this.#doc.hunks[hit.hunk], action: this.patchTarget };
922
958
  }
@@ -933,6 +969,7 @@ export class DiffPane {
933
969
  this.anchor = null;
934
970
  }
935
971
  this.cursor = visual;
972
+ this.#syncHunkToCursor();
936
973
  return { type: "handled" };
937
974
  }
938
975
  return null;
@@ -1077,8 +1114,16 @@ export class DiffPane {
1077
1114
  const leftWidth = Math.max(1, Math.floor((width - 1) / 2));
1078
1115
  const rightWidth = Math.max(1, width - leftWidth - 1);
1079
1116
  const bodyHeight = Math.max(0, height - 1);
1080
- const oldLines = this.#renderAssetSide(asset.old, leftWidth, bodyHeight, `old:${asset.filePath}`);
1081
- const newLines = this.#renderAssetSide(asset.new, rightWidth, bodyHeight, `new:${asset.filePath}`);
1117
+ const previousImages = this.#assetImages;
1118
+ this.#assetImages = new Map();
1119
+ const oldLines = this.#renderAssetSide(asset.old, leftWidth, bodyHeight, `old:${asset.filePath}`, previousImages);
1120
+ const newLines = this.#renderAssetSide(
1121
+ asset.new,
1122
+ rightWidth,
1123
+ bodyHeight,
1124
+ `new:${asset.filePath}`,
1125
+ previousImages,
1126
+ );
1082
1127
  const border = theme.fg("borderMuted", "│");
1083
1128
  const lines: string[] = [];
1084
1129
  for (let index = 0; index < height; index++) {
@@ -1105,24 +1150,36 @@ export class DiffPane {
1105
1150
  return lines;
1106
1151
  }
1107
1152
 
1108
- #renderAssetSide(side: FileAssetSide, width: number, height: number, placementKey: string): readonly string[] {
1153
+ #renderAssetSide(
1154
+ side: FileAssetSide,
1155
+ width: number,
1156
+ height: number,
1157
+ placementKey: string,
1158
+ previousImages: ReadonlyMap<string, Image>,
1159
+ ): readonly string[] {
1109
1160
  if (height <= 0) return [];
1110
1161
  let content: readonly string[];
1111
1162
  if (side.kind === "image") {
1112
1163
  const image = side.image;
1113
- content = new Image(
1114
- image.data,
1115
- image.mimeType,
1116
- { fallbackColor: text => theme.fg("dim", text) },
1117
- {
1118
- maxWidthCells: Math.max(1, width - 2),
1119
- maxHeightCells: height,
1120
- filename: this.#asset?.filePath,
1121
- budget: this.#imageBudget,
1122
- imageKey: `git-review:${placementKey}:${image.key}`,
1123
- },
1124
- { widthPx: image.widthPx, heightPx: image.heightPx },
1125
- ).render(width);
1164
+ const imageKey = `git-review:${placementKey}:${image.key}`;
1165
+ const cacheKey = `${imageKey}:${width}x${height}`;
1166
+ const component =
1167
+ previousImages.get(cacheKey) ??
1168
+ new Image(
1169
+ image.data,
1170
+ image.mimeType,
1171
+ { fallbackColor: text => theme.fg("dim", text) },
1172
+ {
1173
+ maxWidthCells: Math.max(1, width - 2),
1174
+ maxHeightCells: height,
1175
+ filename: this.#asset?.filePath,
1176
+ budget: this.#imageBudget,
1177
+ imageKey,
1178
+ },
1179
+ { widthPx: image.widthPx, heightPx: image.heightPx },
1180
+ );
1181
+ this.#assetImages.set(cacheKey, component);
1182
+ content = component.render(width);
1126
1183
  } else {
1127
1184
  let details: string[];
1128
1185
  switch (side.kind) {
@@ -1448,6 +1505,22 @@ export class DiffPane {
1448
1505
  }
1449
1506
 
1450
1507
  #renderMinimap(visuals: Visual[], height: number, colors: DiffPalette): string[] {
1508
+ const cached = this.#minimapCache;
1509
+ if (
1510
+ cached &&
1511
+ cached.visuals === visuals &&
1512
+ cached.height === height &&
1513
+ cached.scrollTop === this.scrollTop &&
1514
+ cached.colors === colors
1515
+ ) {
1516
+ return cached.lines;
1517
+ }
1518
+ const lines = this.#buildMinimap(visuals, height, colors);
1519
+ this.#minimapCache = { visuals, height, scrollTop: this.scrollTop, colors, lines };
1520
+ return lines;
1521
+ }
1522
+
1523
+ #buildMinimap(visuals: Visual[], height: number, colors: DiffPalette): string[] {
1451
1524
  const total = visuals.length;
1452
1525
  const lines: string[] = [];
1453
1526
  const bandKind = (band: number): RowKind | "hunk" | null => {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `omp git` — fullscreen repository TUI.
2
+ * `zetacode git` — fullscreen repository TUI.
3
3
  *
4
4
  * Layout: header (file path, encoding, stage-file button, close), toolbar
5
5
  * (scope chip, file/diff toggle, hunk navigation, hunk/inline/split view
@@ -13,8 +13,9 @@
13
13
  * arrows/PgUp/PgDn, vim motions (`j`/`k`/`h`/`l`/`g`/`G`), and mouse
14
14
  * clicks/wheel. All toolbar buttons are clickable and mirrored by keys:
15
15
  * `v` cycles the view (`1`–`4` pick one), `alt+↓`/`alt+↑` jump hunks and roll
16
- * into the adjacent file at the edges, `]`/`[` switch files, `s`/`u`
17
- * stage/unstage (hunk-aware), `x` discards a hunk, `delete` discards the
16
+ * into the adjacent file at the edges, `space` stages/unstages the focused
17
+ * diff row (the focused hunk in hunk view), `s`/`u` stage/unstage
18
+ * (hunk-aware), `x` discards a hunk, `delete` discards the
18
19
  * whole file (press twice to confirm), `w` wraps, `b` cycles
19
20
  * whitespace handling (exact → ignore whitespace → ignore
20
21
  * formatting/import-only changes), `c` jumps to the commit form, `r`
@@ -25,7 +26,7 @@
25
26
  */
26
27
 
27
28
  import type { TspSpan } from "@linxiraos/pi-wire";
28
- import { formatKeyHint, formatKeyHints } from "../../app-keybindings";
29
+ import { formatKeyHint, formatKeyHints, formatTooltipKey } from "../../app-keybindings";
29
30
  import { SplitPane } from "../../components/layout/split-pane";
30
31
  import { Stack } from "../../components/layout/stack";
31
32
  import { matchesKey } from "../../keys";
@@ -669,14 +670,20 @@ class GitTuiComponent implements Component {
669
670
  else if (matchesKey(data, "up") || data === "k") this.#pane.moveCursor(-1, false);
670
671
  else if (matchesKey(data, "down") || data === "j") this.#pane.moveCursor(1, false);
671
672
  else if (matchesKey(data, "pageUp")) this.#pane.moveCursor(-Math.max(1, this.#contentHeight - 2), false);
672
- else if (matchesKey(data, "pageDown") || data === " ")
673
- this.#pane.moveCursor(Math.max(1, this.#contentHeight - 2), false);
673
+ else if (matchesKey(data, "pageDown")) this.#pane.moveCursor(Math.max(1, this.#contentHeight - 2), false);
674
674
  else if (matchesKey(data, "left") || data === "h") this.#pane.scrollLeftBy(-8);
675
675
  else if (matchesKey(data, "right") || data === "l") this.#pane.scrollLeftBy(8);
676
676
  else if (matchesKey(data, "home") || data === "g") this.#pane.cursorToEdge("start");
677
677
  else if (matchesKey(data, "end") || data === "G") this.#pane.cursorToEdge("end");
678
678
  else if (matchesKey(data, "enter")) return this.#jumpHunkOrFile(1);
679
- else if (data === "s" || data === "u") {
679
+ else if (matchesKey(data, "space")) {
680
+ // Hunk-view rows do not map back to document rows, so Space acts on the focused hunk there.
681
+ const target = this.#pane.patchTarget;
682
+ const hunk = this.#pane.mode === "hunk" ? this.#pane.currentHunk : null;
683
+ if (target && hunk) void this.#hunkAction(hunk, target);
684
+ else if (target && this.#pane.selection) void this.#lineAction(target);
685
+ return;
686
+ } else if (data === "s" || data === "u") {
680
687
  if (this.#pane.selection?.explicit && this.#pane.patchTarget) {
681
688
  void this.#lineAction(this.#pane.patchTarget);
682
689
  return;
@@ -1023,8 +1030,8 @@ class GitTuiComponent implements Component {
1023
1030
  const right: NativeNode[] = [
1024
1031
  row(
1025
1032
  [
1026
- iconButton("chev-up", "prev-hunk", `Previous change (${formatKeyHint("alt+up")})`),
1027
- iconButton("chev", "next-hunk", `Next change (${formatKeyHint("alt+down")})`),
1033
+ iconButton("chev-up", "prev-hunk", `Previous change (${formatTooltipKey("alt+up")})`),
1034
+ iconButton("chev", "next-hunk", `Next change (${formatTooltipKey("alt+down")})`),
1028
1035
  ],
1029
1036
  { gap: "none", align: "center" },
1030
1037
  ),
@@ -1045,13 +1052,13 @@ class GitTuiComponent implements Component {
1045
1052
  "type",
1046
1053
  "whitespace",
1047
1054
  this.#whitespace === "off"
1048
- ? `Ignore whitespace (${formatKeyHint("b")})`
1055
+ ? `Ignore whitespace (${formatTooltipKey("b")})`
1049
1056
  : this.#whitespace === "whitespace"
1050
- ? `Ignoring whitespace; also ignore formatting (${formatKeyHint("b")})`
1051
- : `Ignoring formatting and imports; show all (${formatKeyHint("b")})`,
1057
+ ? `Ignoring whitespace; also ignore formatting (${formatTooltipKey("b")})`
1058
+ : `Ignoring formatting and imports; show all (${formatTooltipKey("b")})`,
1052
1059
  this.#whitespace !== "off",
1053
1060
  ),
1054
- iconButton("corner-down-right", "wrap", `Wrap lines (${formatKeyHint("w")})`, this.#pane.wrap),
1061
+ iconButton("corner-down-right", "wrap", `Wrap lines (${formatTooltipKey("w")})`, this.#pane.wrap),
1055
1062
  );
1056
1063
  }
1057
1064
  if (file?.area === "unstaged" || file?.area === "staged") {
@@ -1063,8 +1070,8 @@ class GitTuiComponent implements Component {
1063
1070
  );
1064
1071
  }
1065
1072
  right.push(
1066
- iconButton("keyboard", "help", `Keyboard shortcuts (${formatKeyHint("?")})`),
1067
- iconButton("x", "close", `Close (${formatKeyHint("q")})`),
1073
+ iconButton("keyboard", "help", `Keyboard shortcuts (${formatTooltipKey("?")})`),
1074
+ iconButton("x", "close", `Close (${formatTooltipKey("q")})`),
1068
1075
  );
1069
1076
  return keyed(
1070
1077
  row(
@@ -1228,7 +1235,7 @@ export async function showGitOverlay(ui: TUI, host: GitTuiHost): Promise<void> {
1228
1235
  }
1229
1236
  }
1230
1237
 
1231
- /** Run the fullscreen git TUI standalone (`omp git`) until the user quits. */
1238
+ /** Run the fullscreen git TUI standalone (`zetacode git`) until the user quits. */
1232
1239
  export async function runGitTui(host: GitTuiHost): Promise<void> {
1233
1240
  const ui = new TUI(new ProcessTerminal());
1234
1241
  ui.start();
@@ -11,7 +11,8 @@ import { formatKeyHint } from "../../app-keybindings";
11
11
  import type { KeyName } from "../../key-hint-format";
12
12
  import { matchesKey } from "../../keys";
13
13
  import { col, node, span } from "../../native/describe";
14
- import type { NativeNode } from "../../native/node";
14
+ import type { NativeNode, NativeUiEvent } from "../../native/node";
15
+ import { actionBar, actionButton } from "../../native/overlay";
15
16
  import { theme } from "../../theme/theme";
16
17
  import type { Component } from "../../tui";
17
18
  import { truncateToWidth, visibleWidth } from "../../utils";
@@ -79,28 +80,36 @@ export class GitHelpSheet implements Component {
79
80
  if (data === "?" || data === "q" || matchesKey(data, "escape") || matchesKey(data, "ctrl+c")) this.#close();
80
81
  }
81
82
 
83
+ /** Close runs what Esc runs. */
84
+ handleNativeEvent(event: NativeUiEvent): void {
85
+ if (event.type === "action" && event.act === "close") this.#close();
86
+ }
87
+
82
88
  describe(): NativeNode {
83
89
  this.#native ??= col(
84
- GROUPS.map(group =>
85
- node(
86
- "section",
87
- { head: group.title, role: "zeta.hotkeys.group" },
88
- [
89
- node("table", {
90
- role: "zeta.hotkeys.table",
91
- cols: [
92
- { id: "keys", head: "Keys" },
93
- { id: "does", head: "Action", grow: 1 },
94
- ],
95
- rows: group.rows.map((row, index) => ({
96
- id: String(index),
97
- cells: { keys: row.keys.map(key => span(formatKeyHint(key), "key")), does: row.label },
98
- })),
99
- }),
100
- ],
101
- group.title,
90
+ [
91
+ ...GROUPS.map(group =>
92
+ node(
93
+ "section",
94
+ { head: group.title, role: "zeta.hotkeys.group" },
95
+ [
96
+ node("table", {
97
+ role: "zeta.hotkeys.table",
98
+ cols: [
99
+ { id: "keys", head: "Keys" },
100
+ { id: "does", head: "Action", grow: 1 },
101
+ ],
102
+ rows: group.rows.map((row, index) => ({
103
+ id: String(index),
104
+ cells: { keys: row.keys.map(key => span(formatKeyHint(key), "key")), does: row.label },
105
+ })),
106
+ }),
107
+ ],
108
+ group.title,
109
+ ),
102
110
  ),
103
- ),
111
+ actionBar([null, actionButton("Close", "close", { keys: "escape" })]),
112
+ ],
104
113
  { gap: "lg", role: "zeta.app.git.help" },
105
114
  );
106
115
  return this.#native;
@@ -1008,7 +1008,7 @@ export class Sidebar {
1008
1008
  * text field being edited. False when not the sidebar's event.
1009
1009
  */
1010
1010
  handleNativeEvent(event: NativeUiEvent): boolean {
1011
- if (event.type === "edit") {
1011
+ if (event.type === "edit" || event.type === "undo") {
1012
1012
  const editing = this.editing ? this.selected?.kind : undefined;
1013
1013
  const field =
1014
1014
  editing === "summary"
@@ -1018,7 +1018,7 @@ export class Sidebar {
1018
1018
  : editing === "description"
1019
1019
  ? this.description
1020
1020
  : undefined;
1021
- field?.applyHostEdit(event);
1021
+ field?.handleNativeEvent(event);
1022
1022
  return field !== undefined;
1023
1023
  }
1024
1024
  if (event.type === "select" || event.type === "activate") {
@@ -1713,7 +1713,12 @@ export class Sidebar {
1713
1713
  png,
1714
1714
  "image/png",
1715
1715
  { fallbackColor: text => theme.fg("dim", text) },
1716
- { maxHeightCells: 3, budget: this.#imageBudget, imageKey: `git-avatar:${email}` },
1716
+ {
1717
+ maxHeightCells: 3,
1718
+ budget: this.#imageBudget,
1719
+ imageKey: `git-avatar:${email}`,
1720
+ requestRender: this.#requestRender,
1721
+ },
1717
1722
  ),
1718
1723
  };
1719
1724
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Live board and scoreboard for `omp if-bench`.
2
+ * Live board and scoreboard for `zetacode if-bench`.
3
3
  *
4
4
  * Interactive terminals get one repainted row per model — a turn ladder that
5
5
  * fills as turns pass, the in-flight turn as a spinner cell, and the live
@@ -71,7 +71,7 @@ const FAILURE_TEXT: Record<IfBenchFailure, string> = {
71
71
  provider: "provider error",
72
72
  };
73
73
 
74
- /** Rendering surface for one `omp if-bench` run. */
74
+ /** Rendering surface for one `zetacode if-bench` run. */
75
75
  export interface IfBenchBoard extends IfBenchObserver {
76
76
  readonly interactive: boolean;
77
77
  /** Print a permanent line above the live rows (plain write when non-TTY). */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Interactive alt-screen monitor for `omp ps` (btop idiom): a live process
2
+ * Interactive alt-screen monitor for `zetacode ps` (btop idiom): a live process
3
3
  * table over every selected broker scope with in-place actions.
4
4
  *
5
5
  * Keys — table: `↑/↓`/`j/k` select, `enter`/`i` info, `l` logs, `s` stop,
@@ -631,7 +631,7 @@ export class PsTopComponent implements Component {
631
631
 
632
632
  #header(width: number, title: string): string {
633
633
  const age = this.#lastRefresh ? `updated ${formatDuration(Date.now() - this.#lastRefresh)} ago` : "updating…";
634
- const left = ` ${chalk.bold("omp ps")} ${chalk.dim("·")} ${title}`;
634
+ const left = ` ${chalk.bold("zetacode ps")} ${chalk.dim("·")} ${title}`;
635
635
  const right = chalk.dim(age);
636
636
  const pad = Math.max(1, width - Bun.stringWidth(left) - Bun.stringWidth(right) - 1);
637
637
  return truncateToWidth(`${left}${" ".repeat(pad)}${right}`, width);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Standalone TUI model picker used by `omp setup speech`.
2
+ * Standalone TUI model picker used by `zetacode setup speech`.
3
3
  *
4
4
  * One-shot {@link selectStandaloneItem} prompt: resolve on select/cancel and
5
5
  * let the adapter tear the UI down. The standalone TUI auto-renders on input,
@@ -77,8 +77,11 @@ export interface AutocompleteProvider {
77
77
  };
78
78
  /** Get inline hint text to show as dim ghost text after the cursor */
79
79
  getInlineHint?(lines: string[], cursorLine: number, cursorCol: number): string | null;
80
- /** Synchronously try to complete a slash command at the start of a line (no async I/O). */
81
- /** Returns matched items and the full prefix, or null if not applicable. */
80
+ /**
81
+ * Synchronously list slash command-name completions for a leading slash token (no async I/O).
82
+ * Mirrors the command-name branch of {@link getSuggestions}, including the bare `/` listing and
83
+ * the collapsed `/skill:` namespace row. Returns null outside a command-name token or with no match.
84
+ */
82
85
  trySyncSlashCompletion?(textBeforeCursor: string): {
83
86
  items: AutocompleteItem[];
84
87
  prefix: string;