@linxiraos/pi-tui 1.1.27 → 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 (373) hide show
  1. package/CHANGELOG.md +47 -463
  2. package/README.md +7 -5
  3. package/dist/types/app-keybindings.d.ts +1 -1
  4. package/dist/types/apps/cleanse-board.d.ts +1 -1
  5. package/dist/types/apps/debug/log-viewer.d.ts +4 -0
  6. package/dist/types/apps/debug/raw-sse-buffer.d.ts +2 -0
  7. package/dist/types/apps/git/git-tui.d.ts +2 -2
  8. package/dist/types/apps/git/help.d.ts +3 -1
  9. package/dist/types/apps/if-bench-board.d.ts +2 -2
  10. package/dist/types/apps/setup-model-picker.d.ts +1 -1
  11. package/dist/types/autocomplete.d.ts +5 -2
  12. package/dist/types/charts/chart-plan.d.ts +674 -0
  13. package/dist/types/charts/chart-svg.d.ts +59 -0
  14. package/dist/types/charts/table-data.d.ts +175 -0
  15. package/dist/types/chat/assistant-message.d.ts +5 -0
  16. package/dist/types/chat/chat-transcript-builder.d.ts +2 -0
  17. package/dist/types/chat/compaction-summary-message.d.ts +1 -0
  18. package/dist/types/chat/execution-shared.d.ts +6 -5
  19. package/dist/types/chat/fence-figure.d.ts +42 -0
  20. package/dist/types/chat/figure-markdown.d.ts +42 -0
  21. package/dist/types/chat/messages.d.ts +1 -1
  22. package/dist/types/chat/svg-figure.d.ts +33 -0
  23. package/dist/types/chat/svg-source.d.ts +49 -0
  24. package/dist/types/chat/table-chart.d.ts +89 -0
  25. package/dist/types/chat/tool-execution.d.ts +2 -0
  26. package/dist/types/chat/user-message.d.ts +15 -2
  27. package/dist/types/chrome/shared.d.ts +9 -0
  28. package/dist/types/chrome/transcript-container.d.ts +6 -0
  29. package/dist/types/components/box.d.ts +1 -0
  30. package/dist/types/components/disclosure.d.ts +1 -0
  31. package/dist/types/components/editor.d.ts +15 -4
  32. package/dist/types/components/form.d.ts +1 -0
  33. package/dist/types/components/image.d.ts +12 -44
  34. package/dist/types/components/key-value-list.d.ts +1 -0
  35. package/dist/types/components/layout/row.d.ts +1 -0
  36. package/dist/types/components/layout/stack.d.ts +1 -0
  37. package/dist/types/components/markdown.d.ts +36 -3
  38. package/dist/types/components/scroll-view.d.ts +1 -0
  39. package/dist/types/components/section.d.ts +1 -0
  40. package/dist/types/components/table.d.ts +1 -0
  41. package/dist/types/components/text.d.ts +1 -0
  42. package/dist/types/components/tree-view.d.ts +7 -0
  43. package/dist/types/components/truncated-text.d.ts +1 -0
  44. package/dist/types/fuzzy.d.ts +29 -1
  45. package/dist/types/key-hint-format.d.ts +1 -1
  46. package/dist/types/keybinding-matchers.d.ts +3 -0
  47. package/dist/types/keybindings.d.ts +1 -1
  48. package/dist/types/kitty-graphics.d.ts +2 -2
  49. package/dist/types/loop-watchdog.d.ts +8 -7
  50. package/dist/types/multiplexers/cmux.d.ts +16 -0
  51. package/dist/types/multiplexers/herdr.d.ts +26 -0
  52. package/dist/types/multiplexers/notify.d.ts +13 -0
  53. package/dist/types/multiplexers/orca.d.ts +12 -0
  54. package/dist/types/multiplexers/screen.d.ts +9 -0
  55. package/dist/types/multiplexers/tmux.d.ts +29 -0
  56. package/dist/types/multiplexers/types.d.ts +100 -0
  57. package/dist/types/multiplexers/wmux.d.ts +12 -0
  58. package/dist/types/multiplexers/zellij.d.ts +12 -0
  59. package/dist/types/native/backend.d.ts +3 -2
  60. package/dist/types/native/blobs.d.ts +7 -3
  61. package/dist/types/native/encode.d.ts +3 -4
  62. package/dist/types/native/overlay.d.ts +5 -0
  63. package/dist/types/overlays/agent-hub-projection.d.ts +6 -5
  64. package/dist/types/overlays/agent-hub-types.d.ts +9 -0
  65. package/dist/types/overlays/agent-hub.d.ts +2 -0
  66. package/dist/types/overlays/agent-transcript-viewer.d.ts +11 -2
  67. package/dist/types/overlays/agents-hub.d.ts +9 -0
  68. package/dist/types/overlays/annotation-overlay.d.ts +19 -2
  69. package/dist/types/overlays/annotation-types.d.ts +2 -0
  70. package/dist/types/overlays/ask-dialog.d.ts +5 -2
  71. package/dist/types/overlays/history-search.d.ts +10 -0
  72. package/dist/types/overlays/hook-selector.d.ts +9 -4
  73. package/dist/types/overlays/jobs-panel.d.ts +1 -7
  74. package/dist/types/overlays/model-browser.d.ts +54 -7
  75. package/dist/types/overlays/model-hub.d.ts +23 -0
  76. package/dist/types/overlays/oauth-selector.d.ts +0 -1
  77. package/dist/types/overlays/plan-review-overlay.d.ts +3 -2
  78. package/dist/types/overlays/session-observer-registry.d.ts +2 -0
  79. package/dist/types/overlays/session-selector.d.ts +6 -2
  80. package/dist/types/overlays/settings-defs.d.ts +1 -0
  81. package/dist/types/overlays/usage-dashboard.d.ts +8 -4
  82. package/dist/types/overlays/usage-display.d.ts +3 -1
  83. package/dist/types/prompt/composer.d.ts +1 -1
  84. package/dist/types/prompt/custom-editor.d.ts +11 -8
  85. package/dist/types/prompt/image-source.d.ts +2 -1
  86. package/dist/types/prompt/interactive-context-helpers.d.ts +4 -1
  87. package/dist/types/prompt/model-mention-autocomplete.d.ts +1 -1
  88. package/dist/types/prompt/welcome.d.ts +6 -1
  89. package/dist/types/render/composite.d.ts +2 -0
  90. package/dist/types/render/output-pane.d.ts +1 -0
  91. package/dist/types/render/render-utils.d.ts +1 -0
  92. package/dist/types/render/tool-card.d.ts +6 -0
  93. package/dist/types/render/width-aware-text.d.ts +2 -0
  94. package/dist/types/setup/scenes/types.d.ts +1 -0
  95. package/dist/types/status-line/component.d.ts +3 -0
  96. package/dist/types/status-line/host.d.ts +4 -1
  97. package/dist/types/status-line/segments.d.ts +2 -0
  98. package/dist/types/status-line/types.d.ts +14 -3
  99. package/dist/types/terminal-capabilities.d.ts +27 -35
  100. package/dist/types/terminal-multiplexer.d.ts +127 -14
  101. package/dist/types/terminal.d.ts +22 -6
  102. package/dist/types/theme/active-symbols.d.ts +1 -1
  103. package/dist/types/theme/schema.d.ts +11 -2
  104. package/dist/types/theme/symbols.d.ts +1 -1
  105. package/dist/types/theme/theme-class.d.ts +7 -0
  106. package/dist/types/theme/theme.d.ts +1 -1
  107. package/dist/types/theme/tui-adapters.d.ts +3 -0
  108. package/dist/types/tmux.d.ts +11 -4
  109. package/dist/types/tools/daemon.d.ts +1 -1
  110. package/dist/types/tools/eval.d.ts +22 -3
  111. package/dist/types/tools/glob.d.ts +4 -0
  112. package/dist/types/tools/native-view.d.ts +47 -0
  113. package/dist/types/tools/output-meta.d.ts +11 -1
  114. package/dist/types/tools/renderer.d.ts +37 -2
  115. package/dist/types/tools/streaming-output.d.ts +20 -1
  116. package/dist/types/tools/task.d.ts +0 -4
  117. package/dist/types/tools/write.d.ts +9 -2
  118. package/dist/types/tools/yield.d.ts +22 -0
  119. package/dist/types/tui.d.ts +31 -0
  120. package/dist/types/utils.d.ts +6 -0
  121. package/dist/types/vim.d.ts +19 -5
  122. package/package.json +13 -9
  123. package/src/app-keybindings.d.ts +1 -1
  124. package/src/app-keybindings.ts +1 -1
  125. package/src/apps/autoresearch-dashboard.ts +7 -3
  126. package/src/apps/cleanse-board.ts +2 -2
  127. package/src/apps/cleanse-picker.ts +1 -1
  128. package/src/apps/debug/log-viewer.ts +188 -72
  129. package/src/apps/debug/raw-sse-buffer.ts +8 -0
  130. package/src/apps/debug/raw-sse.ts +39 -5
  131. package/src/apps/git/diff-pane.ts +26 -5
  132. package/src/apps/git/git-tui.ts +2 -2
  133. package/src/apps/git/help.ts +29 -20
  134. package/src/apps/if-bench-board.ts +2 -2
  135. package/src/apps/ps-top.ts +2 -2
  136. package/src/apps/setup-model-picker.ts +1 -1
  137. package/src/autocomplete.d.ts +5 -2
  138. package/src/autocomplete.ts +67 -43
  139. package/src/charts/chart-plan.d.ts +674 -0
  140. package/src/charts/chart-plan.ts +5081 -0
  141. package/src/charts/chart-svg.d.ts +59 -0
  142. package/src/charts/chart-svg.ts +4657 -0
  143. package/src/charts/table-data.d.ts +175 -0
  144. package/src/charts/table-data.ts +1478 -0
  145. package/src/chat/advisor-message.ts +11 -0
  146. package/src/chat/assistant-message.d.ts +5 -0
  147. package/src/chat/assistant-message.ts +219 -50
  148. package/src/chat/chat-transcript-builder.d.ts +2 -0
  149. package/src/chat/chat-transcript-builder.ts +5 -3
  150. package/src/chat/compaction-summary-message.d.ts +1 -0
  151. package/src/chat/compaction-summary-message.ts +8 -0
  152. package/src/chat/execution-shared.d.ts +6 -5
  153. package/src/chat/execution-shared.ts +42 -25
  154. package/src/chat/fence-figure.d.ts +42 -0
  155. package/src/chat/fence-figure.ts +80 -0
  156. package/src/chat/figure-markdown.d.ts +42 -0
  157. package/src/chat/figure-markdown.ts +174 -0
  158. package/src/chat/messages.d.ts +1 -1
  159. package/src/chat/messages.ts +1 -1
  160. package/src/chat/read-tool-group.ts +6 -4
  161. package/src/chat/skill-message.ts +6 -0
  162. package/src/chat/svg-figure.d.ts +33 -0
  163. package/src/chat/svg-figure.ts +399 -0
  164. package/src/chat/svg-source.d.ts +49 -0
  165. package/src/chat/svg-source.ts +188 -0
  166. package/src/chat/table-chart.d.ts +89 -0
  167. package/src/chat/table-chart.ts +294 -0
  168. package/src/chat/tool-execution.d.ts +2 -0
  169. package/src/chat/tool-execution.ts +80 -6
  170. package/src/chat/user-message.d.ts +15 -2
  171. package/src/chat/user-message.ts +55 -3
  172. package/src/chrome/shared.ts +53 -0
  173. package/src/chrome/transcript-container.d.ts +6 -0
  174. package/src/chrome/transcript-container.ts +93 -13
  175. package/src/components/box.d.ts +1 -0
  176. package/src/components/box.ts +5 -0
  177. package/src/components/disclosure.d.ts +1 -0
  178. package/src/components/disclosure.ts +8 -0
  179. package/src/components/editor.d.ts +15 -4
  180. package/src/components/editor.ts +294 -46
  181. package/src/components/form.d.ts +1 -0
  182. package/src/components/form.ts +8 -0
  183. package/src/components/image.d.ts +12 -44
  184. package/src/components/image.ts +47 -151
  185. package/src/components/key-value-list.d.ts +1 -0
  186. package/src/components/key-value-list.ts +4 -0
  187. package/src/components/layout/row.d.ts +1 -0
  188. package/src/components/layout/row.ts +7 -0
  189. package/src/components/layout/stack.d.ts +1 -0
  190. package/src/components/layout/stack.ts +7 -0
  191. package/src/components/markdown.d.ts +36 -3
  192. package/src/components/markdown.ts +433 -318
  193. package/src/components/scroll-view.d.ts +1 -0
  194. package/src/components/scroll-view.ts +5 -0
  195. package/src/components/section.d.ts +1 -0
  196. package/src/components/section.ts +5 -0
  197. package/src/components/settings-list.ts +2 -0
  198. package/src/components/table.d.ts +1 -0
  199. package/src/components/table.ts +4 -0
  200. package/src/components/text.d.ts +1 -0
  201. package/src/components/text.ts +7 -0
  202. package/src/components/tree-view.d.ts +7 -0
  203. package/src/components/tree-view.ts +38 -8
  204. package/src/components/truncated-text.d.ts +1 -0
  205. package/src/components/truncated-text.ts +5 -0
  206. package/src/desktop-notify.ts +1 -1
  207. package/src/fuzzy.d.ts +29 -1
  208. package/src/fuzzy.ts +115 -30
  209. package/src/key-hint-format.d.ts +1 -1
  210. package/src/key-hint-format.ts +1 -1
  211. package/src/keybinding-matchers.d.ts +3 -0
  212. package/src/keybinding-matchers.ts +6 -2
  213. package/src/keybindings.d.ts +1 -1
  214. package/src/keybindings.ts +1 -1
  215. package/src/kitty-graphics.d.ts +2 -2
  216. package/src/kitty-graphics.ts +4 -4
  217. package/src/loop-watchdog.d.ts +8 -7
  218. package/src/loop-watchdog.ts +18 -13
  219. package/src/multiplexers/cmux.d.ts +16 -0
  220. package/src/multiplexers/cmux.ts +29 -0
  221. package/src/multiplexers/herdr.d.ts +26 -0
  222. package/src/multiplexers/herdr.ts +64 -0
  223. package/src/multiplexers/notify.d.ts +13 -0
  224. package/src/multiplexers/notify.ts +24 -0
  225. package/src/multiplexers/orca.d.ts +12 -0
  226. package/src/multiplexers/orca.ts +16 -0
  227. package/src/multiplexers/screen.d.ts +9 -0
  228. package/src/multiplexers/screen.ts +15 -0
  229. package/src/multiplexers/tmux.d.ts +29 -0
  230. package/src/multiplexers/tmux.ts +40 -0
  231. package/src/multiplexers/types.d.ts +100 -0
  232. package/src/multiplexers/types.ts +110 -0
  233. package/src/multiplexers/wmux.d.ts +12 -0
  234. package/src/multiplexers/wmux.ts +16 -0
  235. package/src/multiplexers/zellij.d.ts +12 -0
  236. package/src/multiplexers/zellij.ts +24 -0
  237. package/src/native/backend.d.ts +3 -2
  238. package/src/native/backend.ts +174 -18
  239. package/src/native/blobs.d.ts +7 -3
  240. package/src/native/blobs.ts +47 -12
  241. package/src/native/encode.d.ts +3 -4
  242. package/src/native/encode.ts +58 -31
  243. package/src/native/overlay.d.ts +5 -0
  244. package/src/native/overlay.ts +13 -0
  245. package/src/native/reconcile.ts +4 -0
  246. package/src/overlays/agent-hub-projection.d.ts +6 -5
  247. package/src/overlays/agent-hub-projection.ts +124 -13
  248. package/src/overlays/agent-hub-types.d.ts +9 -0
  249. package/src/overlays/agent-hub-types.ts +6 -0
  250. package/src/overlays/agent-hub.ts +44 -29
  251. package/src/overlays/agent-transcript-viewer.ts +91 -23
  252. package/src/overlays/agents-hub.ts +28 -8
  253. package/src/overlays/annotation-overlay.ts +293 -90
  254. package/src/overlays/annotation-types.ts +2 -0
  255. package/src/overlays/ask-dialog.ts +7 -10
  256. package/src/overlays/btw-history-panel.ts +12 -1
  257. package/src/overlays/copy-selector.ts +30 -8
  258. package/src/overlays/extensions/state-manager.ts +52 -12
  259. package/src/overlays/history-search.ts +100 -7
  260. package/src/overlays/hook-selector.ts +12 -5
  261. package/src/overlays/jobs-panel.ts +28 -46
  262. package/src/overlays/model-browser.ts +341 -110
  263. package/src/overlays/model-hub.ts +300 -49
  264. package/src/overlays/move-overlay.ts +28 -14
  265. package/src/overlays/oauth-selector.ts +54 -70
  266. package/src/overlays/plan-review-overlay.ts +194 -70
  267. package/src/overlays/plugin-settings.ts +3 -3
  268. package/src/overlays/report-panel.ts +2 -2
  269. package/src/overlays/rewind-selector.ts +86 -17
  270. package/src/overlays/session-observer-registry.d.ts +2 -0
  271. package/src/overlays/session-observer-registry.ts +10 -2
  272. package/src/overlays/session-selector.ts +64 -26
  273. package/src/overlays/settings-defs.ts +4 -3
  274. package/src/overlays/settings-selector.ts +33 -8
  275. package/src/overlays/snapcompact-shape-preview.ts +2 -3
  276. package/src/overlays/stats-notice.ts +1 -1
  277. package/src/overlays/tree-selector.ts +41 -20
  278. package/src/overlays/usage-dashboard.ts +100 -50
  279. package/src/overlays/usage-display.ts +10 -4
  280. package/src/prompt/attachment-chips.ts +15 -11
  281. package/src/prompt/composer-attachments.ts +6 -4
  282. package/src/prompt/composer.ts +4 -15
  283. package/src/prompt/custom-editor.ts +54 -26
  284. package/src/prompt/image-source.ts +2 -1
  285. package/src/prompt/interactive-context-helpers.ts +30 -18
  286. package/src/prompt/macos-spelling.ts +7 -0
  287. package/src/prompt/magic-keywords.ts +11 -2
  288. package/src/prompt/model-mention-autocomplete.ts +14 -14
  289. package/src/prompt/tips.txt +6 -5
  290. package/src/prompt/welcome.ts +55 -12
  291. package/src/prompt/word-completion.ts +38 -5
  292. package/src/render/composite.d.ts +2 -0
  293. package/src/render/composite.ts +64 -0
  294. package/src/render/output-pane.d.ts +1 -0
  295. package/src/render/output-pane.ts +6 -0
  296. package/src/render/render-utils.d.ts +1 -0
  297. package/src/render/render-utils.ts +11 -0
  298. package/src/render/tool-card.d.ts +6 -0
  299. package/src/render/tool-card.ts +15 -0
  300. package/src/render/width-aware-text.d.ts +2 -0
  301. package/src/render/width-aware-text.ts +5 -0
  302. package/src/setup/scenes/model.ts +2 -1
  303. package/src/setup/scenes/types.ts +1 -0
  304. package/src/status-line/component.ts +292 -78
  305. package/src/status-line/host.ts +4 -1
  306. package/src/status-line/segments.ts +40 -22
  307. package/src/status-line/types.ts +15 -3
  308. package/src/terminal-capabilities.d.ts +27 -35
  309. package/src/terminal-capabilities.ts +75 -189
  310. package/src/terminal-multiplexer.d.ts +127 -14
  311. package/src/terminal-multiplexer.ts +112 -33
  312. package/src/terminal.d.ts +22 -6
  313. package/src/terminal.ts +139 -37
  314. package/src/theme/active-symbols.d.ts +1 -1
  315. package/src/theme/active-symbols.ts +1 -1
  316. package/src/theme/schema-validation.ts +1 -0
  317. package/src/theme/schema.d.ts +11 -2
  318. package/src/theme/schema.ts +14 -1
  319. package/src/theme/session-color.ts +1 -7
  320. package/src/theme/symbols.d.ts +1 -1
  321. package/src/theme/symbols.ts +6 -1
  322. package/src/theme/theme-class.d.ts +7 -0
  323. package/src/theme/theme-class.ts +26 -1
  324. package/src/theme/theme-schema.json +5 -1
  325. package/src/theme/theme.d.ts +1 -1
  326. package/src/theme/theme.ts +8 -4
  327. package/src/theme/tui-adapters.d.ts +3 -0
  328. package/src/theme/tui-adapters.ts +68 -0
  329. package/src/tmux.d.ts +11 -4
  330. package/src/tmux.ts +47 -11
  331. package/src/tools/ast-edit.ts +59 -35
  332. package/src/tools/ast-grep.ts +35 -16
  333. package/src/tools/bash.ts +92 -42
  334. package/src/tools/daemon.d.ts +1 -1
  335. package/src/tools/daemon.ts +1 -1
  336. package/src/tools/default-renderer.ts +35 -19
  337. package/src/tools/edit.ts +142 -120
  338. package/src/tools/eval-format/index.ts +28 -2
  339. package/src/tools/eval-format/javascript.ts +7 -5
  340. package/src/tools/eval.d.ts +22 -3
  341. package/src/tools/eval.ts +364 -208
  342. package/src/tools/fetch.ts +5 -6
  343. package/src/tools/glob.d.ts +4 -0
  344. package/src/tools/glob.ts +33 -65
  345. package/src/tools/grep.ts +81 -48
  346. package/src/tools/index.ts +2 -0
  347. package/src/tools/lsp.ts +81 -59
  348. package/src/tools/mcp.ts +111 -68
  349. package/src/tools/native-view.d.ts +47 -0
  350. package/src/tools/native-view.ts +102 -1
  351. package/src/tools/output-meta.d.ts +11 -1
  352. package/src/tools/output-meta.ts +23 -3
  353. package/src/tools/read.ts +7 -5
  354. package/src/tools/renderer.d.ts +37 -2
  355. package/src/tools/renderer.ts +42 -2
  356. package/src/tools/streaming-output.d.ts +20 -1
  357. package/src/tools/streaming-output.ts +149 -50
  358. package/src/tools/task.d.ts +0 -4
  359. package/src/tools/task.ts +112 -59
  360. package/src/tools/todo.ts +119 -30
  361. package/src/tools/wait.ts +34 -24
  362. package/src/tools/web-search.ts +1 -1
  363. package/src/tools/write.d.ts +9 -2
  364. package/src/tools/write.ts +147 -95
  365. package/src/tools/yield.d.ts +22 -0
  366. package/src/tools/yield.ts +225 -0
  367. package/src/tui.d.ts +31 -0
  368. package/src/tui.ts +309 -160
  369. package/src/utils.d.ts +6 -0
  370. package/src/utils.ts +19 -0
  371. package/src/vim.d.ts +19 -5
  372. package/src/vim.ts +333 -18
  373. package/src/windows-input-mode.ts +8 -0
@@ -15,7 +15,8 @@ import { formatKeyHint } from "../app-keybindings";
15
15
  import { editorKey, editorKeys } from "../chrome/keybinding-hints";
16
16
  import type { NativeNode, NativeUiEvent } from "../native/node";
17
17
  import { node, span } from "../native/describe";
18
- import { actionHint, overlayCard, statusHintsRow } from "../native/overlay";
18
+ import { actionBar, actionButton, actionHint, overlayCard, statusHintsRow } from "../native/overlay";
19
+ import { getKeybindings } from "../keybindings";
19
20
 
20
21
  export interface MoveOverlayResult {
21
22
  directory: string;
@@ -122,12 +123,7 @@ export class MoveOverlay implements Component, Focusable {
122
123
  return;
123
124
  }
124
125
  if (matchesKey(data, Key.tab)) {
125
- const selected = this.#results[this.#selectedIndex];
126
- if (selected) {
127
- this.#field.setValue(selected.value);
128
- this.#selectedIndex = 0;
129
- this.#updateResults();
130
- }
126
+ this.#accept();
131
127
  return;
132
128
  }
133
129
  const before = this.#field.getValue();
@@ -192,19 +188,28 @@ export class MoveOverlay implements Component, Focusable {
192
188
  );
193
189
  const hints = statusHintsRow(
194
190
  [span("Type to filter", "dim")],
195
- [
196
- actionHint(["tui.select.up", "tui.select.down"], "navigate"),
197
- { keys: ["tab"], label: "accept" },
198
- { keys: ["enter"], label: "confirm" },
199
- actionHint("tui.select.cancel", "cancel"),
200
- ],
191
+ [actionHint(["tui.select.up", "tui.select.down"], "navigate")],
201
192
  );
202
- const described = overlayCard("zeta.dialog.move", "Move to directory", [this.#field, list, hints]);
193
+ // Accept, Confirm and Cancel run what Tab, Enter and Esc run.
194
+ const actions = actionBar([
195
+ actionButton("Accept", "accept", { keys: "tab" }),
196
+ null,
197
+ // The bound cancel key; Esc also cancels when it is unbound.
198
+ actionButton("Cancel", "cancel", { keys: getKeybindings().getKeys("tui.select.cancel")[0] ?? "escape" }),
199
+ actionButton("Confirm", "confirm", { keys: "enter", tone: "accent" }),
200
+ ]);
201
+ const described = overlayCard("zeta.dialog.move", "Move to directory", [this.#field, list, hints, actions]);
203
202
  this.#native = { revision: this.#revision, node: described };
204
203
  return described;
205
204
  }
206
205
 
207
206
  handleNativeEvent(event: NativeUiEvent): void {
207
+ if (event.type === "action") {
208
+ if (event.act === "accept") this.#accept();
209
+ else if (event.act === "confirm") this.#field.submit();
210
+ else if (event.act === "cancel") this.#done(undefined);
211
+ return;
212
+ }
208
213
  if (event.type !== "select" && event.type !== "activate") return;
209
214
  const index = this.#results.findIndex(result => result.value === event.item);
210
215
  if (index === -1) return;
@@ -216,6 +221,15 @@ export class MoveOverlay implements Component, Focusable {
216
221
  if (event.type === "activate") this.#field.submit();
217
222
  }
218
223
 
224
+ /** Tab: fill the field with the highlighted suggestion. */
225
+ #accept(): void {
226
+ const selected = this.#results[this.#selectedIndex];
227
+ if (!selected) return;
228
+ this.#field.setValue(selected.value);
229
+ this.#selectedIndex = 0;
230
+ this.#updateResults();
231
+ }
232
+
219
233
  invalidate(): void {
220
234
  this.#field.input.prompt = theme.fg("dim", "Path: ");
221
235
  this.#field.invalidate();
@@ -11,7 +11,6 @@ import {
11
11
  TruncatedText,
12
12
  visibleWidth,
13
13
  } from "../index";
14
- import { tuiText, tuiTextFmt } from "../i18n";
15
14
  import { theme } from "../theme/theme";
16
15
  import { matchesSelectCancel, matchesSelectDown, matchesSelectUp } from "../keybinding-matchers";
17
16
  import { OverlayPanel } from "../chrome/overlay-box";
@@ -52,6 +51,8 @@ const ORIGIN_LABELS = {
52
51
  */
53
52
  export class OAuthSelectorComponent extends OverlayPanel {
54
53
  #listContainer: Container;
54
+ /** Provider rows viewport of the last {@link #updateList}; spinner ticks repaint only its rows. */
55
+ #listView: ScrollView | undefined;
55
56
  #menu: MenuSelection<OAuthProviderInfo>;
56
57
  /** The provider search field; its value drives `#menu`'s query. */
57
58
  #search = Object.assign(new Input(), { prompt: "" });
@@ -90,12 +91,7 @@ export class OAuthSelectorComponent extends OverlayPanel {
90
91
  requestRender?: () => void;
91
92
  },
92
93
  ) {
93
- super(
94
- mode === "login"
95
- ? tuiText("oauthSelectLoginTitle", "Select provider to login")
96
- : tuiText("oauthSelectLogoutTitle", "Select provider to logout"),
97
- "zeta.overlay.oauth",
98
- );
94
+ super(mode === "login" ? "Select provider to login" : "Select provider to logout", "zeta.overlay.oauth");
99
95
  this.#mode = mode;
100
96
  this.#authStorage = authStorage;
101
97
  this.#onSelectCallback = onSelect;
@@ -219,7 +215,13 @@ export class OAuthSelectorComponent extends OverlayPanel {
219
215
  if (frameCount > 0) {
220
216
  this.#spinnerFrame = (this.#spinnerFrame + 1) % frameCount;
221
217
  }
222
- this.#updateList();
218
+ // Only the provider rows carry the spinner glyph; the window is unchanged.
219
+ if (this.#listView) {
220
+ const start = this.#scrollStart;
221
+ this.#listView.setLines(this.#providerRows(start, start + this.#visibleCount));
222
+ } else {
223
+ this.#updateList();
224
+ }
223
225
  this.#requestRenderCallback?.();
224
226
  }, 80);
225
227
  }
@@ -238,45 +240,26 @@ export class OAuthSelectorComponent extends OverlayPanel {
238
240
  #getSourceLabel(providerId: string): string {
239
241
  const origin = this.#authStorage.keys.source(providerId);
240
242
  if (!origin) return "";
241
- const detail =
242
- origin.kind === "env" && origin.envVar
243
- ? `${tuiText("oauthOriginEnv", "env")}: ${origin.envVar}`
244
- : this.#originDisplayLabel(origin.kind);
243
+ const detail = origin.kind === "env" && origin.envVar ? `env: ${origin.envVar}` : ORIGIN_LABELS[origin.kind];
245
244
  return theme.fg("muted", ` (${detail})`);
246
245
  }
247
246
 
248
- /** Localized display tag for a credential-origin leg; `--api-key` stays a verbatim CLI flag. */
249
- #originDisplayLabel(kind: keyof typeof ORIGIN_LABELS): string {
250
- switch (kind) {
251
- case "runtime":
252
- return ORIGIN_LABELS.runtime;
253
- case "config":
254
- return tuiText("oauthOriginConfig", ORIGIN_LABELS.config);
255
- case "oauth":
256
- return tuiText("oauthOriginLogin", ORIGIN_LABELS.oauth);
257
- case "api_key":
258
- return tuiText("oauthOriginApiKey", ORIGIN_LABELS.api_key);
259
- case "env":
260
- return tuiText("oauthOriginEnv", ORIGIN_LABELS.env);
261
- }
262
- }
263
-
264
247
  #getStatusIndicator(providerId: string): string {
265
248
  const state = this.#authState.get(providerId);
266
249
  const source = this.#getSourceLabel(providerId);
267
250
  if (state === "checking") {
268
251
  const frameCount = theme.spinnerFrames.length;
269
252
  const spinner = frameCount > 0 ? theme.spinnerFrames[this.#spinnerFrame % frameCount] : theme.status.pending;
270
- return theme.fg("warning", ` ${spinner} ${tuiText("oauthStatusChecking", "checking")}`) + source;
253
+ return theme.fg("warning", ` ${spinner} checking`) + source;
271
254
  }
272
255
  if (state === "invalid") {
273
- return theme.fg("error", ` ${theme.status.error} ${tuiText("oauthStatusInvalid", "invalid")}`) + source;
256
+ return theme.fg("error", ` ${theme.status.error} invalid`) + source;
274
257
  }
275
258
  if (state === "valid") {
276
- return theme.fg("success", ` ${theme.status.enabled} ${tuiText("oauthStatusLoggedIn", "logged in")}`) + source;
259
+ return theme.fg("success", ` ${theme.status.enabled} logged in`) + source;
277
260
  }
278
261
  return this.#hasSelectableAuth(providerId)
279
- ? theme.fg("success", ` ${theme.status.enabled} ${tuiText("oauthStatusLoggedIn", "logged in")}`) + source
262
+ ? theme.fg("success", ` ${theme.status.enabled} logged in`) + source
280
263
  : "";
281
264
  }
282
265
 
@@ -290,9 +273,9 @@ export class OAuthSelectorComponent extends OverlayPanel {
290
273
 
291
274
  #renderStatusLine(_total: number): string {
292
275
  const query = this.#menu.query.trim();
293
- if (!query) return theme.fg("muted", tuiText("oauthTypeToSearch", "Type to search"));
276
+ if (!query) return theme.fg("muted", "Type to search");
294
277
  const width = visibleWidth(this.#search.getValue()) + 1;
295
- return theme.fg("muted", tuiText("oauthSearchLabel", "Search: ")) + (this.#search.render(width)[0] ?? "");
278
+ return theme.fg("muted", "Search: ") + (this.#search.render(width)[0] ?? "");
296
279
  }
297
280
 
298
281
  #getProviderSearchText(provider: OAuthProviderInfo): string {
@@ -335,37 +318,15 @@ export class OAuthSelectorComponent extends OverlayPanel {
335
318
  this.#nativeRoot = undefined;
336
319
  this.#pickerRoot = undefined;
337
320
  this.#listContainer.clear();
321
+ this.#listView = undefined;
338
322
 
339
- const items = this.#menu.visibleItems;
340
- const total = items.length;
323
+ const total = this.#menu.visibleItems.length;
341
324
  const maxVisible = this.#maxVisible;
342
325
  const { start: startIndex, end: endIndex } = centeredViewportRange(this.#menu.selectedIndex, total, maxVisible);
343
326
  this.#scrollStart = startIndex;
344
327
  this.#visibleCount = endIndex - startIndex;
345
328
 
346
- const rows: string[] = [];
347
- for (let i = startIndex; i < endIndex; i++) {
348
- const provider = items[i];
349
- if (!provider) continue;
350
- const isSelected = i === this.#menu.selectedIndex;
351
- const isAvailable = provider.available;
352
- const statusIndicator = this.#getStatusIndicator(provider.id);
353
-
354
- let line = "";
355
- if (isSelected) {
356
- const prefix = theme.fg("accent", `${theme.nav.cursor} `);
357
- const text = isAvailable ? theme.fg("accent", provider.name) : theme.fg("dim", provider.name);
358
- line = prefix + text + statusIndicator;
359
- } else {
360
- const text = isAvailable ? ` ${provider.name}` : theme.fg("dim", ` ${provider.name}`);
361
- line = text + statusIndicator;
362
- }
363
- if (!isSelected && i === this.#hoveredIndex) {
364
- line = theme.bg("selectedBg", line);
365
- }
366
- rows.push(line);
367
- }
368
-
329
+ const rows = this.#providerRows(startIndex, endIndex);
369
330
  if (rows.length > 0) {
370
331
  const sv = new ScrollView(rows, {
371
332
  height: rows.length,
@@ -374,6 +335,7 @@ export class OAuthSelectorComponent extends OverlayPanel {
374
335
  theme: { track: t => theme.fg("muted", t), thumb: t => theme.fg("accent", t) },
375
336
  });
376
337
  sv.setScrollOffset(startIndex);
338
+ this.#listView = sv;
377
339
  this.#listContainer.addChild(sv);
378
340
  }
379
341
 
@@ -386,9 +348,9 @@ export class OAuthSelectorComponent extends OverlayPanel {
386
348
  const message =
387
349
  this.#menu.items.length === 0
388
350
  ? this.#mode === "login"
389
- ? tuiText("oauthNoProvidersAvailable", "No OAuth providers available")
390
- : tuiText("oauthNoStoredCredentials", "No stored provider credentials to log out")
391
- : tuiText("oauthNoMatchingProviders", "No matching providers");
351
+ ? "No OAuth providers available"
352
+ : "No stored provider credentials to log out"
353
+ : "No matching providers";
392
354
  this.#listContainer.addChild(new TruncatedText(theme.fg("muted", message), 0, 0));
393
355
  }
394
356
  if (this.#statusMessage) {
@@ -396,6 +358,34 @@ export class OAuthSelectorComponent extends OverlayPanel {
396
358
  this.#listContainer.addChild(new TruncatedText(theme.fg("warning", this.#statusMessage), 0, 0));
397
359
  }
398
360
  }
361
+
362
+ /** Styled rows for visible providers `[startIndex, endIndex)`: cursor, name, auth status and provenance. */
363
+ #providerRows(startIndex: number, endIndex: number): string[] {
364
+ const items = this.#menu.visibleItems;
365
+ const rows: string[] = [];
366
+ for (let i = startIndex; i < endIndex; i++) {
367
+ const provider = items[i];
368
+ if (!provider) continue;
369
+ const isSelected = i === this.#menu.selectedIndex;
370
+ const isAvailable = provider.available;
371
+ const statusIndicator = this.#getStatusIndicator(provider.id);
372
+
373
+ let line = "";
374
+ if (isSelected) {
375
+ const prefix = theme.fg("accent", `${theme.nav.cursor} `);
376
+ const text = isAvailable ? theme.fg("accent", provider.name) : theme.fg("dim", provider.name);
377
+ line = prefix + text + statusIndicator;
378
+ } else {
379
+ const text = isAvailable ? ` ${provider.name}` : theme.fg("dim", ` ${provider.name}`);
380
+ line = text + statusIndicator;
381
+ }
382
+ if (!isSelected && i === this.#hoveredIndex) {
383
+ line = theme.bg("selectedBg", line);
384
+ }
385
+ rows.push(line);
386
+ }
387
+ return rows;
388
+ }
399
389
  handleInput(keyData: string): void {
400
390
  // Escape or Ctrl+C
401
391
  if (matchesSelectCancel(keyData)) {
@@ -444,7 +434,8 @@ export class OAuthSelectorComponent extends OverlayPanel {
444
434
  this.stopValidation();
445
435
  this.#onSelectCallback(selectedProvider.id);
446
436
  } else if (selectedProvider) {
447
- this.#statusMessage = tuiText("oauthProviderUnavailable", "Provider unavailable in this environment.");
437
+ this.#statusMessage = "Provider unavailable in this environment.";
438
+ this.#updateList();
448
439
  }
449
440
  }
450
441
 
@@ -667,11 +658,4 @@ export class OAuthSelectorComponent extends OverlayPanel {
667
658
  }
668
659
  this.#confirmSelection();
669
660
  }
670
- override render(width: number): readonly string[] {
671
- this.title =
672
- this.#mode === "login"
673
- ? tuiText("oauthSelectLoginTitle", "Select provider to login")
674
- : tuiText("oauthSelectLogoutTitle", "Select provider to logout");
675
- return super.render(width);
676
- }
677
661
  }