@oh-my-pi/pi-tui 18.4.3 → 18.4.4

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 (447) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/types/apps/cleanse-board.d.ts +17 -0
  3. package/dist/types/apps/git/help.d.ts +16 -0
  4. package/dist/types/apps/git/sidebar.d.ts +18 -0
  5. package/dist/types/apps/live-visualizer.d.ts +10 -0
  6. package/dist/types/apps/ps-top.d.ts +15 -0
  7. package/dist/types/apps/standalone-picker.d.ts +3 -0
  8. package/dist/types/autocomplete.d.ts +8 -0
  9. package/dist/types/chat/advisor-message.d.ts +12 -2
  10. package/dist/types/chat/assistant-message.d.ts +20 -0
  11. package/dist/types/chat/bash-execution.d.ts +9 -0
  12. package/dist/types/chat/chat-transcript-builder.d.ts +6 -1
  13. package/dist/types/chat/collab-prompt-message.d.ts +4 -0
  14. package/dist/types/chat/compaction-summary-message.d.ts +15 -0
  15. package/dist/types/chat/eval-execution.d.ts +8 -0
  16. package/dist/types/chat/execution-shared.d.ts +58 -0
  17. package/dist/types/chat/late-diagnostics-message.d.ts +15 -1
  18. package/dist/types/chat/read-tool-group.d.ts +15 -0
  19. package/dist/types/chat/skill-message.d.ts +9 -0
  20. package/dist/types/chat/stripped-tool-calls-placeholder.d.ts +3 -0
  21. package/dist/types/chat/todo-reminder.d.ts +4 -1
  22. package/dist/types/chat/tool-execution.d.ts +25 -1
  23. package/dist/types/chat/transcript-actions.d.ts +37 -0
  24. package/dist/types/chat/transcript-entry.d.ts +3 -1
  25. package/dist/types/chat/user-message.d.ts +25 -0
  26. package/dist/types/chrome/collab-qrcode.d.ts +7 -0
  27. package/dist/types/chrome/context-thresholds.d.ts +11 -0
  28. package/dist/types/chrome/countdown-timer.d.ts +9 -3
  29. package/dist/types/chrome/diff.d.ts +12 -0
  30. package/dist/types/chrome/dynamic-border.d.ts +3 -0
  31. package/dist/types/chrome/format.d.ts +6 -0
  32. package/dist/types/chrome/message-divider.d.ts +13 -0
  33. package/dist/types/chrome/message-frame.d.ts +10 -0
  34. package/dist/types/chrome/message-notice.d.ts +23 -0
  35. package/dist/types/chrome/overlay-box.d.ts +11 -2
  36. package/dist/types/chrome/qrcode.d.ts +7 -0
  37. package/dist/types/chrome/segment-track.d.ts +7 -0
  38. package/dist/types/chrome/selector-helpers.d.ts +0 -6
  39. package/dist/types/chrome/status-notice.d.ts +14 -0
  40. package/dist/types/chrome/streaming-panel.d.ts +3 -0
  41. package/dist/types/chrome/tool-activity.d.ts +3 -0
  42. package/dist/types/chrome/transcript-container.d.ts +13 -0
  43. package/dist/types/chrome/transcript-status.d.ts +15 -3
  44. package/dist/types/components/box.d.ts +7 -0
  45. package/dist/types/components/disclosure.d.ts +9 -0
  46. package/dist/types/components/editor.d.ts +37 -0
  47. package/dist/types/components/form.d.ts +14 -0
  48. package/dist/types/components/image.d.ts +7 -0
  49. package/dist/types/components/input.d.ts +20 -1
  50. package/dist/types/components/key-value-list.d.ts +3 -0
  51. package/dist/types/components/layout/geometry.d.ts +16 -0
  52. package/dist/types/components/layout/row.d.ts +7 -0
  53. package/dist/types/components/layout/split-pane.d.ts +8 -0
  54. package/dist/types/components/layout/stack.d.ts +6 -0
  55. package/dist/types/components/loader.d.ts +48 -0
  56. package/dist/types/components/markdown.d.ts +8 -0
  57. package/dist/types/components/metric.d.ts +7 -0
  58. package/dist/types/components/progress-bar.d.ts +3 -0
  59. package/dist/types/components/scroll-view.d.ts +6 -0
  60. package/dist/types/components/section.d.ts +3 -0
  61. package/dist/types/components/select-list.d.ts +33 -0
  62. package/dist/types/components/settings-list.d.ts +68 -0
  63. package/dist/types/components/spacer.d.ts +4 -0
  64. package/dist/types/components/tab-bar.d.ts +9 -0
  65. package/dist/types/components/table.d.ts +7 -0
  66. package/dist/types/components/text.d.ts +6 -0
  67. package/dist/types/components/tree-view.d.ts +9 -0
  68. package/dist/types/components/truncated-text.d.ts +3 -0
  69. package/dist/types/components/wizard-step.d.ts +6 -0
  70. package/dist/types/hotkeys-markdown.d.ts +24 -0
  71. package/dist/types/index.d.ts +5 -0
  72. package/dist/types/latex-block.d.ts +7 -0
  73. package/dist/types/native/apply.d.ts +39 -0
  74. package/dist/types/native/backend.d.ts +94 -0
  75. package/dist/types/native/blobs.d.ts +29 -0
  76. package/dist/types/native/describe.d.ts +56 -0
  77. package/dist/types/native/encode.d.ts +50 -0
  78. package/dist/types/native/icons.d.ts +18 -0
  79. package/dist/types/native/memo.d.ts +27 -0
  80. package/dist/types/native/node.d.ts +107 -0
  81. package/dist/types/native/overlay.d.ts +64 -0
  82. package/dist/types/native/picker.d.ts +124 -0
  83. package/dist/types/native/reconcile.d.ts +41 -0
  84. package/dist/types/native/settle.d.ts +11 -0
  85. package/dist/types/native/spans.d.ts +21 -0
  86. package/dist/types/native/state.d.ts +6 -0
  87. package/dist/types/native/tone.d.ts +24 -0
  88. package/dist/types/overlays/advisor-config.d.ts +20 -0
  89. package/dist/types/overlays/agent-hub-renderer.d.ts +27 -11
  90. package/dist/types/overlays/agent-hub.d.ts +10 -0
  91. package/dist/types/overlays/agent-transcript-viewer.d.ts +7 -0
  92. package/dist/types/overlays/agents-hub.d.ts +8 -0
  93. package/dist/types/overlays/annotation-overlay.d.ts +3 -0
  94. package/dist/types/overlays/ask-dialog.d.ts +23 -0
  95. package/dist/types/overlays/bordered-loader.d.ts +3 -0
  96. package/dist/types/overlays/btw-history-panel.d.ts +9 -0
  97. package/dist/types/overlays/btw-panel.d.ts +3 -0
  98. package/dist/types/overlays/cleanse-panel.d.ts +5 -2
  99. package/dist/types/overlays/composer-shape-preview.d.ts +7 -1
  100. package/dist/types/overlays/copy-selector.d.ts +38 -0
  101. package/dist/types/overlays/error-banner.d.ts +9 -0
  102. package/dist/types/overlays/extensions/extension-list.d.ts +1 -0
  103. package/dist/types/overlays/history-search.d.ts +18 -0
  104. package/dist/types/overlays/hook-editor.d.ts +28 -1
  105. package/dist/types/overlays/hook-input.d.ts +3 -0
  106. package/dist/types/overlays/hook-selector.d.ts +10 -0
  107. package/dist/types/overlays/hub-frame.d.ts +18 -0
  108. package/dist/types/overlays/jobs-panel.d.ts +24 -0
  109. package/dist/types/overlays/login-dialog.d.ts +10 -0
  110. package/dist/types/overlays/logout-account-selector.d.ts +4 -0
  111. package/dist/types/overlays/mcp-add-wizard.d.ts +4 -0
  112. package/dist/types/overlays/model-browser.d.ts +69 -0
  113. package/dist/types/overlays/model-hub.d.ts +7 -0
  114. package/dist/types/overlays/model-picker.d.ts +7 -0
  115. package/dist/types/overlays/move-overlay.d.ts +3 -0
  116. package/dist/types/overlays/oauth-selector.d.ts +4 -0
  117. package/dist/types/overlays/omfg-panel.d.ts +3 -0
  118. package/dist/types/overlays/pause-screen.d.ts +12 -0
  119. package/dist/types/overlays/plan-review-overlay.d.ts +5 -0
  120. package/dist/types/overlays/plan-save-overlay.d.ts +10 -0
  121. package/dist/types/overlays/plugin-selector.d.ts +4 -0
  122. package/dist/types/overlays/plugin-settings.d.ts +30 -0
  123. package/dist/types/overlays/queue-mode-selector.d.ts +4 -0
  124. package/dist/types/overlays/reset-usage-selector.d.ts +8 -0
  125. package/dist/types/overlays/rewind-selector.d.ts +5 -0
  126. package/dist/types/overlays/session-info-overlay.d.ts +19 -1
  127. package/dist/types/overlays/session-selector.d.ts +64 -1
  128. package/dist/types/overlays/settings-defs.d.ts +14 -0
  129. package/dist/types/overlays/settings-selector.d.ts +21 -0
  130. package/dist/types/overlays/show-images-selector.d.ts +4 -0
  131. package/dist/types/overlays/snapcompact-shape-preview.d.ts +2 -0
  132. package/dist/types/overlays/stats-notice.d.ts +8 -0
  133. package/dist/types/overlays/theme-selector.d.ts +11 -0
  134. package/dist/types/overlays/thinking-selector.d.ts +4 -0
  135. package/dist/types/overlays/tree-selector.d.ts +60 -2
  136. package/dist/types/overlays/usage-dashboard.d.ts +26 -3
  137. package/dist/types/overlays/usage-row.d.ts +36 -2
  138. package/dist/types/prompt/attachment-chips.d.ts +8 -0
  139. package/dist/types/prompt/composer-attachments.d.ts +15 -3
  140. package/dist/types/prompt/composer.d.ts +18 -1
  141. package/dist/types/prompt/custom-editor.d.ts +48 -2
  142. package/dist/types/prompt/editor-top-gap.d.ts +2 -0
  143. package/dist/types/prompt/macos-spelling.d.ts +6 -0
  144. package/dist/types/prompt/magic-keywords.d.ts +9 -0
  145. package/dist/types/prompt/queued-messages.d.ts +23 -0
  146. package/dist/types/prompt/skill-tokens.d.ts +4 -2
  147. package/dist/types/prompt/welcome.d.ts +16 -0
  148. package/dist/types/render/code-cell.d.ts +10 -0
  149. package/dist/types/render/file-list.d.ts +8 -0
  150. package/dist/types/render/hyperlink.d.ts +14 -0
  151. package/dist/types/render/output-block.d.ts +43 -0
  152. package/dist/types/render/output-pane.d.ts +17 -0
  153. package/dist/types/render/tool-card.d.ts +8 -0
  154. package/dist/types/render/tree-list.d.ts +8 -0
  155. package/dist/types/render/width-aware-text.d.ts +7 -0
  156. package/dist/types/setup/scenes/outro.d.ts +7 -0
  157. package/dist/types/setup/scenes/sign-in.d.ts +7 -0
  158. package/dist/types/setup/scenes/splash.d.ts +8 -0
  159. package/dist/types/setup/scenes/types.d.ts +6 -1
  160. package/dist/types/setup/wizard-overlay.d.ts +9 -0
  161. package/dist/types/status-line/component.d.ts +49 -5
  162. package/dist/types/status-line/context-usage.d.ts +20 -0
  163. package/dist/types/status-line/footer.d.ts +8 -0
  164. package/dist/types/status-line/metrics.d.ts +1 -2
  165. package/dist/types/status-line/segments.d.ts +10 -1
  166. package/dist/types/status-line/types.d.ts +40 -1
  167. package/dist/types/terminal-capabilities.d.ts +1 -1
  168. package/dist/types/terminal.d.ts +27 -0
  169. package/dist/types/theme/defaults/index.d.ts +100 -0
  170. package/dist/types/theme/schema.d.ts +2 -0
  171. package/dist/types/theme/shimmer.d.ts +8 -0
  172. package/dist/types/theme/theme-class.d.ts +2 -0
  173. package/dist/types/theme/theme.d.ts +33 -1
  174. package/dist/types/tools/ask.d.ts +3 -0
  175. package/dist/types/tools/ast-edit.d.ts +10 -1
  176. package/dist/types/tools/ast-grep.d.ts +10 -1
  177. package/dist/types/tools/autoresearch.d.ts +21 -4
  178. package/dist/types/tools/bash.d.ts +30 -1
  179. package/dist/types/tools/cfg-render.d.ts +5 -1
  180. package/dist/types/tools/debug.d.ts +3 -1
  181. package/dist/types/tools/default-renderer.d.ts +6 -1
  182. package/dist/types/tools/edit.d.ts +14 -1
  183. package/dist/types/tools/eval.d.ts +12 -1
  184. package/dist/types/tools/fetch.d.ts +16 -1
  185. package/dist/types/tools/find.d.ts +15 -1
  186. package/dist/types/tools/github.d.ts +3 -0
  187. package/dist/types/tools/glob.d.ts +14 -1
  188. package/dist/types/tools/goal.d.ts +3 -1
  189. package/dist/types/tools/grep.d.ts +14 -1
  190. package/dist/types/tools/grouped-file-output.d.ts +58 -0
  191. package/dist/types/tools/json-tree.d.ts +20 -0
  192. package/dist/types/tools/lsp.d.ts +3 -10
  193. package/dist/types/tools/mcp.d.ts +16 -1
  194. package/dist/types/tools/memory.d.ts +26 -0
  195. package/dist/types/tools/native-view.d.ts +90 -0
  196. package/dist/types/tools/proc-render.d.ts +7 -1
  197. package/dist/types/tools/read.d.ts +23 -1
  198. package/dist/types/tools/renderer.d.ts +57 -0
  199. package/dist/types/tools/report-tool-issue.d.ts +3 -0
  200. package/dist/types/tools/resolve.d.ts +14 -1
  201. package/dist/types/tools/task.d.ts +3 -0
  202. package/dist/types/tools/think.d.ts +3 -0
  203. package/dist/types/tools/todo.d.ts +12 -0
  204. package/dist/types/tools/vibe.d.ts +3 -1
  205. package/dist/types/tools/wait.d.ts +3 -0
  206. package/dist/types/tools/web-search.d.ts +8 -0
  207. package/dist/types/tools/write.d.ts +14 -1
  208. package/dist/types/tools/xdev.d.ts +13 -0
  209. package/dist/types/tui.d.ts +49 -0
  210. package/package.json +9 -9
  211. package/src/apps/autoresearch-dashboard.ts +362 -4
  212. package/src/apps/cleanse-board.ts +219 -1
  213. package/src/apps/cleanse-picker.ts +9 -1
  214. package/src/apps/debug/log-viewer.ts +15 -15
  215. package/src/apps/debug/protocol-probe.ts +2 -20
  216. package/src/apps/git/avatar.ts +2 -22
  217. package/src/apps/git/git-tui.ts +406 -59
  218. package/src/apps/git/help.ts +130 -0
  219. package/src/apps/git/sidebar.ts +491 -0
  220. package/src/apps/live-visualizer.ts +65 -0
  221. package/src/apps/ps-top.ts +448 -17
  222. package/src/apps/session-picker.ts +1 -0
  223. package/src/apps/setup-model-picker.ts +5 -1
  224. package/src/apps/standalone-picker.ts +55 -1
  225. package/src/autocomplete.ts +44 -1
  226. package/src/chat/advisor-message.ts +72 -3
  227. package/src/chat/assistant-message.ts +346 -11
  228. package/src/chat/background-tan-message.ts +4 -4
  229. package/src/chat/bash-execution.ts +81 -0
  230. package/src/chat/cache-invalidation-marker.ts +8 -0
  231. package/src/chat/chat-transcript-builder.ts +37 -6
  232. package/src/chat/collab-prompt-message.ts +15 -3
  233. package/src/chat/compaction-summary-message.ts +74 -1
  234. package/src/chat/custom-message.ts +3 -1
  235. package/src/chat/eval-execution.ts +57 -0
  236. package/src/chat/execution-shared.ts +153 -1
  237. package/src/chat/hook-message.ts +1 -0
  238. package/src/chat/late-diagnostics-message.ts +85 -2
  239. package/src/chat/read-tool-group.ts +341 -1
  240. package/src/chat/served-model-marker.ts +8 -0
  241. package/src/chat/skill-message.ts +63 -0
  242. package/src/chat/stripped-tool-calls-placeholder.ts +18 -10
  243. package/src/chat/todo-reminder.ts +34 -4
  244. package/src/chat/tool-execution.ts +385 -10
  245. package/src/chat/transcript-actions.ts +38 -0
  246. package/src/chat/transcript-browser.ts +2 -9
  247. package/src/chat/transcript-entry.ts +10 -1
  248. package/src/chat/transcript-render-helpers.ts +16 -15
  249. package/src/chat/ttsr-notification.ts +38 -1
  250. package/src/chat/user-message.ts +167 -4
  251. package/src/chrome/collab-qrcode.ts +27 -2
  252. package/src/chrome/context-thresholds.ts +34 -0
  253. package/src/chrome/countdown-timer.ts +24 -1
  254. package/src/chrome/diff.ts +60 -1
  255. package/src/chrome/dynamic-border.ts +7 -0
  256. package/src/chrome/format.ts +12 -0
  257. package/src/chrome/message-divider.ts +33 -1
  258. package/src/chrome/message-frame.ts +53 -10
  259. package/src/chrome/message-notice.ts +71 -0
  260. package/src/chrome/overlay-box.ts +45 -2
  261. package/src/chrome/qrcode.ts +28 -0
  262. package/src/chrome/segment-track.ts +26 -0
  263. package/src/chrome/selector-helpers.ts +1 -17
  264. package/src/chrome/status-notice.ts +46 -0
  265. package/src/chrome/streaming-panel.ts +25 -1
  266. package/src/chrome/tool-activity.ts +20 -0
  267. package/src/chrome/transcript-container.ts +37 -0
  268. package/src/chrome/transcript-status.ts +40 -11
  269. package/src/components/box.ts +51 -0
  270. package/src/components/disclosure.ts +33 -0
  271. package/src/components/editor.ts +216 -27
  272. package/src/components/form.ts +93 -9
  273. package/src/components/image.ts +30 -0
  274. package/src/components/input.ts +77 -26
  275. package/src/components/key-value-list.ts +18 -0
  276. package/src/components/layout/geometry.ts +44 -0
  277. package/src/components/layout/row.ts +30 -0
  278. package/src/components/layout/split-pane.ts +65 -0
  279. package/src/components/layout/stack.ts +27 -0
  280. package/src/components/loader.ts +183 -1
  281. package/src/components/markdown.ts +21 -0
  282. package/src/components/metric.ts +39 -0
  283. package/src/components/progress-bar.ts +28 -0
  284. package/src/components/scroll-view.ts +23 -0
  285. package/src/components/section.ts +16 -0
  286. package/src/components/select-list.ts +174 -25
  287. package/src/components/settings-list.ts +264 -7
  288. package/src/components/spacer.ts +17 -0
  289. package/src/components/tab-bar.ts +42 -0
  290. package/src/components/table.ts +34 -0
  291. package/src/components/text.ts +23 -0
  292. package/src/components/tree-view.ts +65 -0
  293. package/src/components/truncated-text.ts +14 -0
  294. package/src/components/wizard-step.ts +18 -9
  295. package/src/debug-server.ts +14 -7
  296. package/src/hotkeys-markdown.ts +251 -69
  297. package/src/index.ts +6 -0
  298. package/src/latex-block.ts +11 -0
  299. package/src/native/apply.ts +275 -0
  300. package/src/native/backend.ts +682 -0
  301. package/src/native/blobs.ts +70 -0
  302. package/src/native/describe.ts +124 -0
  303. package/src/native/encode.ts +233 -0
  304. package/src/native/icons.ts +184 -0
  305. package/src/native/memo.ts +64 -0
  306. package/src/native/node.ts +112 -0
  307. package/src/native/overlay.ts +131 -0
  308. package/src/native/picker.ts +333 -0
  309. package/src/native/reconcile.ts +1063 -0
  310. package/src/native/settle.ts +23 -0
  311. package/src/native/spans.ts +308 -0
  312. package/src/native/state.ts +28 -0
  313. package/src/native/tone.ts +79 -0
  314. package/src/overlays/advisor-config.ts +420 -0
  315. package/src/overlays/agent-hub-renderer.ts +155 -18
  316. package/src/overlays/agent-hub.ts +1037 -44
  317. package/src/overlays/agent-transcript-viewer.ts +129 -0
  318. package/src/overlays/agents-hub.ts +688 -53
  319. package/src/overlays/annotation-overlay.ts +391 -52
  320. package/src/overlays/ask-dialog.ts +435 -24
  321. package/src/overlays/bordered-loader.ts +17 -0
  322. package/src/overlays/btw-history-panel.ts +182 -0
  323. package/src/overlays/btw-panel.ts +68 -2
  324. package/src/overlays/cleanse-panel.ts +105 -15
  325. package/src/overlays/codex-reset-fireworks.ts +65 -5
  326. package/src/overlays/composer-shape-preview.ts +26 -1
  327. package/src/overlays/copy-selector.ts +545 -23
  328. package/src/overlays/error-banner.ts +44 -0
  329. package/src/overlays/extensions/extension-list.ts +23 -17
  330. package/src/overlays/history-search.ts +175 -33
  331. package/src/overlays/hook-editor.ts +113 -6
  332. package/src/overlays/hook-input.ts +22 -1
  333. package/src/overlays/hook-selector.ts +311 -22
  334. package/src/overlays/hub-frame.ts +80 -0
  335. package/src/overlays/jobs-panel.ts +112 -0
  336. package/src/overlays/login-dialog.ts +183 -1
  337. package/src/overlays/logout-account-selector.ts +102 -4
  338. package/src/overlays/mcp-add-wizard.ts +232 -53
  339. package/src/overlays/model-browser.ts +681 -22
  340. package/src/overlays/model-hub.ts +1402 -78
  341. package/src/overlays/model-picker.ts +175 -1
  342. package/src/overlays/move-overlay.ts +45 -0
  343. package/src/overlays/oauth-selector.ts +227 -23
  344. package/src/overlays/omfg-panel.ts +86 -2
  345. package/src/overlays/pause-screen.ts +55 -4
  346. package/src/overlays/plan-review-overlay.ts +352 -0
  347. package/src/overlays/plan-save-overlay.ts +45 -0
  348. package/src/overlays/plugin-selector.ts +21 -1
  349. package/src/overlays/plugin-settings.ts +195 -5
  350. package/src/overlays/queue-mode-selector.ts +19 -1
  351. package/src/overlays/reset-usage-selector.ts +110 -40
  352. package/src/overlays/rewind-selector.ts +458 -44
  353. package/src/overlays/session-account-selector.ts +1 -1
  354. package/src/overlays/session-info-overlay.ts +137 -1
  355. package/src/overlays/session-selector.ts +807 -46
  356. package/src/overlays/settings-defs.ts +41 -0
  357. package/src/overlays/settings-selector.ts +583 -23
  358. package/src/overlays/show-images-selector.ts +18 -1
  359. package/src/overlays/snapcompact-shape-preview.ts +48 -3
  360. package/src/overlays/stats-notice.ts +31 -0
  361. package/src/overlays/theme-selector.ts +31 -1
  362. package/src/overlays/thinking-selector.ts +22 -1
  363. package/src/overlays/tree-selector.ts +570 -110
  364. package/src/overlays/usage-dashboard.ts +587 -12
  365. package/src/overlays/usage-row.ts +161 -25
  366. package/src/prompt/attachment-chips.ts +60 -0
  367. package/src/prompt/composer-attachments.ts +31 -9
  368. package/src/prompt/composer.ts +55 -2
  369. package/src/prompt/custom-editor.ts +302 -4
  370. package/src/prompt/editor-top-gap.ts +8 -0
  371. package/src/prompt/macos-spelling.ts +24 -9
  372. package/src/prompt/magic-keywords.ts +22 -1
  373. package/src/prompt/model-mention-autocomplete.ts +1 -0
  374. package/src/prompt/queued-messages.ts +101 -0
  375. package/src/prompt/skill-tokens.ts +5 -3
  376. package/src/prompt/welcome.ts +213 -6
  377. package/src/render/code-cell.ts +103 -2
  378. package/src/render/file-list.ts +29 -0
  379. package/src/render/hyperlink.ts +32 -0
  380. package/src/render/output-block.ts +110 -0
  381. package/src/render/output-pane.ts +37 -0
  382. package/src/render/tool-card.ts +137 -0
  383. package/src/render/tree-list.ts +39 -0
  384. package/src/render/width-aware-text.ts +20 -0
  385. package/src/setup/scenes/composer.ts +29 -0
  386. package/src/setup/scenes/glyph.ts +15 -0
  387. package/src/setup/scenes/model.ts +36 -8
  388. package/src/setup/scenes/outro.ts +28 -1
  389. package/src/setup/scenes/sign-in.ts +122 -13
  390. package/src/setup/scenes/splash.ts +28 -1
  391. package/src/setup/scenes/theme.ts +88 -3
  392. package/src/setup/scenes/types.ts +7 -1
  393. package/src/setup/startup-splash.ts +46 -9
  394. package/src/setup/wizard-overlay.ts +140 -23
  395. package/src/status-line/component.ts +398 -16
  396. package/src/status-line/context-usage.ts +279 -50
  397. package/src/status-line/footer.ts +94 -1
  398. package/src/status-line/metrics.ts +3 -6
  399. package/src/status-line/segments.ts +463 -97
  400. package/src/status-line/separators.ts +3 -16
  401. package/src/status-line/types.ts +43 -1
  402. package/src/terminal-capabilities.ts +7 -0
  403. package/src/terminal.ts +130 -2
  404. package/src/theme/defaults/dark-neon-noir.json +100 -0
  405. package/src/theme/defaults/index.ts +2 -0
  406. package/src/theme/defaults/light-prism.json +5 -5
  407. package/src/theme/defaults/onyx.json +62 -62
  408. package/src/theme/schema.ts +15 -0
  409. package/src/theme/shimmer.ts +33 -0
  410. package/src/theme/theme-class.ts +24 -19
  411. package/src/theme/theme.ts +111 -9
  412. package/src/tools/ask.ts +157 -1
  413. package/src/tools/ast-edit.ts +174 -1
  414. package/src/tools/ast-grep.ts +82 -2
  415. package/src/tools/autoresearch.ts +149 -1
  416. package/src/tools/bash.ts +180 -49
  417. package/src/tools/cfg-render.ts +66 -1
  418. package/src/tools/debug.ts +78 -1
  419. package/src/tools/default-renderer.ts +35 -1
  420. package/src/tools/edit.ts +247 -2
  421. package/src/tools/eval.ts +257 -1
  422. package/src/tools/fetch.ts +102 -3
  423. package/src/tools/find.ts +127 -1
  424. package/src/tools/github.ts +119 -10
  425. package/src/tools/glob.ts +116 -1
  426. package/src/tools/goal.ts +56 -1
  427. package/src/tools/grep.ts +83 -2
  428. package/src/tools/grouped-file-output.ts +205 -0
  429. package/src/tools/json-tree.ts +116 -1
  430. package/src/tools/lsp.ts +318 -1
  431. package/src/tools/mcp.ts +80 -1
  432. package/src/tools/memory.ts +93 -11
  433. package/src/tools/native-view.ts +292 -0
  434. package/src/tools/proc-render.ts +221 -1
  435. package/src/tools/read.ts +199 -4
  436. package/src/tools/renderer.ts +61 -0
  437. package/src/tools/report-tool-issue.ts +7 -1
  438. package/src/tools/resolve.ts +63 -1
  439. package/src/tools/task.ts +406 -4
  440. package/src/tools/think.ts +19 -1
  441. package/src/tools/todo.ts +89 -0
  442. package/src/tools/vibe.ts +230 -2
  443. package/src/tools/wait.ts +181 -1
  444. package/src/tools/web-search.ts +113 -1
  445. package/src/tools/write.ts +144 -5
  446. package/src/tools/xdev.ts +64 -1
  447. package/src/tui.ts +294 -3
@@ -10,11 +10,16 @@ import { shortenPath } from "../render/render-utils";
10
10
  import { getSelectListTheme, theme } from "../theme/theme";
11
11
  import { matchesAppInterrupt, matchesSelectDown, matchesSelectUp } from "../keybinding-matchers";
12
12
  import { formatKeyHint } from "../app-keybindings";
13
- import { editorKey, editorKeys, interruptKey } from "../chrome/keybinding-hints";
13
+ import { boundKeys, editorKey, editorKeys, interruptKey } from "../chrome/keybinding-hints";
14
14
  import { OverlayPanel } from "../chrome/overlay-box";
15
15
  import { TextFormField, type FormFieldTheme } from "../components/form";
16
16
  import { SelectList } from "../components/select-list";
17
17
  import { WizardStep, type WizardStepKind } from "../components/wizard-step";
18
+ import { col, node, span, text } from "../native/describe";
19
+ import { type DescribeContext, leafKey, type NativeChild, type NativeNode, type NativeUiEvent } from "../native/node";
20
+ import { actionHint, hintsRow, type NativeHint } from "../native/overlay";
21
+ import { plainText } from "../native/spans";
22
+ import { isNativeRendering } from "../native/state";
18
23
 
19
24
  type TransportType = "stdio" | "http" | "sse";
20
25
  type AuthMethod = "none" | "oauth" | "manual";
@@ -165,6 +170,11 @@ function sanitize(text: string): string {
165
170
  return truncateToWidth(replaceTabs(text), MAX_DISPLAY_WIDTH);
166
171
  }
167
172
 
173
+ /** An error message for a native text node: whole (the terminal wraps it), tabs expanded, no escapes. */
174
+ function nativeErrorText(error: unknown): string {
175
+ return plainText(error instanceof Error ? error.message : String(error));
176
+ }
177
+
168
178
  /** Footer for text steps; the field submits on `tui.input.submit` and cancels on `tui.select.cancel`. */
169
179
  function inputHint(escapeAction: string): string {
170
180
  return `[${editorKey("tui.input.submit")} to continue, ${editorKey("tui.select.cancel")} to ${escapeAction}]`;
@@ -175,6 +185,31 @@ function choiceHint(escapeAction: string): string {
175
185
  return `[${editorKeys("tui.select.up", "tui.select.down")} to navigate, ${formatKeyHint("enter")} to select, ${interruptKey()} to ${escapeAction}]`;
176
186
  }
177
187
 
188
+ /** The `app.interrupt` key (raw Escape when unbound) as a footer hint. */
189
+ function interruptHint(label: string): NativeHint {
190
+ return { keys: boundKeys("app.interrupt", ["escape"]).slice(0, 1), label };
191
+ }
192
+
193
+ /** Native form of {@link choiceHint}. */
194
+ function choiceHints(escapeAction: string): readonly (NativeHint | undefined)[] {
195
+ return [
196
+ actionHint(["tui.select.up", "tui.select.down"], "navigate"),
197
+ { keys: ["enter"], label: "select" },
198
+ interruptHint(escapeAction),
199
+ ];
200
+ }
201
+
202
+ /** What the native description shows for the mounted step (the ANSI view mounts a {@link WizardStep}). */
203
+ interface NativeWizardStep {
204
+ readonly heading: string;
205
+ /** Heading colour token. */
206
+ readonly tone: string;
207
+ /** Nodes, and a text step's `Input`, between the heading and the choices. */
208
+ readonly body: readonly NativeChild[];
209
+ readonly choices?: readonly WizardChoiceOption[];
210
+ readonly hints: readonly (NativeHint | undefined)[];
211
+ }
212
+
178
213
  const mcpFormTheme: FormFieldTheme = {
179
214
  label: text => text,
180
215
  description: text => theme.fg("muted", text),
@@ -223,6 +258,11 @@ export class MCPAddWizard extends OverlayPanel {
223
258
  #validationError: string | null = null;
224
259
  #oauthErrorLines: readonly string[] | null = null;
225
260
  #oauthErrorHeading: { text: string; tone: "error" | "muted" } | null = null;
261
+ /** Native form of {@link #oauthErrorLines}: the full error and its tip. */
262
+ #oauthErrorNative: readonly NativeNode[] = [];
263
+ #nativeStep: NativeWizardStep = { heading: "", tone: "accent", body: [], hints: [] };
264
+ /** Memoized native description; dropped whenever a step mounts or its body changes. */
265
+ #native: NativeNode | undefined;
226
266
  #onCompleteCallback: (name: string, config: MCPAddWizardConfig, scope: Scope) => void;
227
267
  #onCancelCallback: () => void;
228
268
  #onOAuthCallback:
@@ -260,7 +300,7 @@ export class MCPAddWizard extends OverlayPanel {
260
300
  onRender?: () => void,
261
301
  initialName?: string,
262
302
  ) {
263
- super("Add MCP Server");
303
+ super("Add MCP Server", "omp.overlay.mcpAdd");
264
304
  this.#deps = deps;
265
305
  this.#onCompleteCallback = onComplete;
266
306
  this.#onCancelCallback = onCancel;
@@ -289,23 +329,40 @@ export class MCPAddWizard extends OverlayPanel {
289
329
  }
290
330
 
291
331
  /** Mount a step as the wizard body. Overlay chrome is unbounded, so no height budget applies. */
292
- #show(step: WizardStep): void {
332
+ #show(step: WizardStep, native: NativeWizardStep): void {
293
333
  step.setMaxHeight(undefined);
294
334
  this.#step = step;
295
335
  this.#contentContainer.clear();
296
336
  this.#contentContainer.addChild(step);
337
+ this.#nativeStep = native;
338
+ this.#native = undefined;
297
339
  }
298
340
 
341
+ /** Replace the mounted step's native body (async steps update in place). */
342
+ #setNativeBody(body: readonly NativeChild[]): void {
343
+ this.#nativeStep = { ...this.#nativeStep, body };
344
+ this.#native = undefined;
345
+ }
346
+
347
+ /**
348
+ * `note` is a constraint shown above the key hint; `escape` names what
349
+ * Escape does (`undefined`: an optional step whose only hint is skipping).
350
+ */
299
351
  #inputStep(options: {
300
352
  heading: string;
301
353
  prompt: string;
302
354
  initial: string;
303
- hint: string;
355
+ note?: string;
356
+ escape?: string;
304
357
  details?: readonly string[];
305
358
  optional: boolean;
306
359
  error?: string | null;
307
360
  }): void {
308
361
  this.#stepKind = "input";
362
+ const keyHint =
363
+ options.escape === undefined
364
+ ? `[Press ${editorKey("tui.input.submit")} to skip or continue]`
365
+ : inputHint(options.escape);
309
366
  const field = new TextFormField({
310
367
  theme: mcpFormTheme,
311
368
  label: options.prompt,
@@ -313,7 +370,7 @@ export class MCPAddWizard extends OverlayPanel {
313
370
  summary: options.error
314
371
  ? [new Text(theme.fg("error", `✗ ${sanitize(options.error)}`), 0, 0), new Spacer(1)]
315
372
  : undefined,
316
- hint: options.hint,
373
+ hint: options.note ? `[${options.note}]\n${keyHint}` : keyHint,
317
374
  initialValue: options.initial,
318
375
  empty: options.optional ? "submit" : "reject",
319
376
  emptyError: " ",
@@ -321,21 +378,39 @@ export class MCPAddWizard extends OverlayPanel {
321
378
  onCancel: () => this.#cancelInputStep(),
322
379
  });
323
380
  this.#inputField = field;
381
+ const body: NativeChild[] = [text(options.prompt, { wrap: "word" })];
382
+ for (const detail of options.details ?? []) body.push(text([span(detail, "muted")], { wrap: "word" }));
383
+ body.push(field.input);
384
+ if (options.error) {
385
+ body.push(text([span(`✗ ${plainText(options.error)}`, "error")], { wrap: "word" }));
386
+ }
387
+ if (options.note) body.push(text([span(options.note, "muted")], { wrap: "word" }));
324
388
  this.#show(
325
389
  new WizardStep({
326
390
  kind: "input",
327
391
  heading: new Text(theme.fg("accent", options.heading), 0, 0),
328
392
  content: field,
329
393
  }),
394
+ {
395
+ heading: options.heading,
396
+ tone: "accent",
397
+ body,
398
+ hints:
399
+ options.escape === undefined
400
+ ? [actionHint("tui.input.submit", "skip or continue")]
401
+ : [actionHint("tui.input.submit", "continue"), actionHint("tui.select.cancel", options.escape)],
402
+ },
330
403
  );
331
404
  }
332
405
 
406
+ /** `escape` names what Escape does; `nativeIntro` is `intro`'s native description. */
333
407
  #choiceStep(options: {
334
408
  heading: string;
335
409
  headingTone?: "accent" | "error" | "muted";
336
410
  intro?: Component;
411
+ nativeIntro?: readonly NativeChild[];
337
412
  choices: readonly WizardChoiceOption[];
338
- hint: string;
413
+ escape: string;
339
414
  kind?: WizardStepKind;
340
415
  }): void {
341
416
  const tone = options.headingTone ?? "accent";
@@ -364,16 +439,26 @@ export class MCPAddWizard extends OverlayPanel {
364
439
  heading: new Text(theme.fg(tone, options.heading), 0, 0),
365
440
  intro: options.intro,
366
441
  content: list,
367
- footer: new Text(theme.fg("muted", options.hint), 0, 0),
442
+ footer: new Text(theme.fg("muted", choiceHint(options.escape)), 0, 0),
368
443
  }),
444
+ {
445
+ heading: options.heading,
446
+ tone,
447
+ body: options.nativeIntro ?? [],
448
+ choices: options.choices,
449
+ hints: choiceHints(options.escape),
450
+ },
369
451
  );
370
452
  }
371
453
 
454
+ /** `nativeBody` describes `body`; `escapeHint` is the native form of `footer`. */
372
455
  #asyncStep(
373
456
  heading: string,
374
457
  headingTone: "accent" | "success" | "warning" | "error" | "muted",
375
458
  body: Component,
459
+ nativeBody: readonly NativeChild[],
376
460
  footer?: Component,
461
+ escapeHint?: NativeHint,
377
462
  ): void {
378
463
  this.#stepKind = "async";
379
464
  this.#inputField = null;
@@ -384,9 +469,53 @@ export class MCPAddWizard extends OverlayPanel {
384
469
  content: body,
385
470
  footer,
386
471
  }),
472
+ { heading, tone: headingTone, body: nativeBody, hints: escapeHint ? [escapeHint] : [] },
387
473
  );
388
474
  }
389
475
 
476
+ override describe(_cx: DescribeContext): NativeNode {
477
+ if (this.#native) return this.#native;
478
+ const step = this.#nativeStep;
479
+ const children: NativeChild[] = [
480
+ text([span(step.heading, `${step.tone} strong`)], { wrap: "word" }),
481
+ ...step.body,
482
+ ];
483
+ if (step.choices) {
484
+ const items = step.choices.map((choice, index) =>
485
+ node(
486
+ "item",
487
+ { label: choice.label, ...(choice.description ? { detail: choice.description } : {}) },
488
+ undefined,
489
+ String(index),
490
+ ),
491
+ );
492
+ // Keyed per step: a double-click's trailing event never lands on the next step's list.
493
+ children.push(node("list", { selected: String(this.#selectedIndex) }, items, `choices-${this.#currentStep}`));
494
+ }
495
+ children.push(hintsRow(step.hints));
496
+ // The wizard replaces the editor in the dock; its sheet hoists into the terminal's layer.
497
+ const sheet = node(
498
+ "overlay",
499
+ { role: this.nativeRole, head: "Add MCP server", anchor: "center", size: "md", modal: true },
500
+ [col(children, { gap: "md" })],
501
+ "sheet",
502
+ );
503
+ this.#native = col([sheet]);
504
+ return this.#native;
505
+ }
506
+
507
+ /** A click on a choice is Enter on it, exactly as highlighting it with the arrows and pressing Enter. */
508
+ handleNativeEvent(event: NativeUiEvent): void {
509
+ if (event.type !== "select" && event.type !== "activate") return;
510
+ if (leafKey(event.key) !== `choices-${this.#currentStep}`) return;
511
+ if (this.#inputField || this.#stepKind === "async" || this.#oauthAbort) return;
512
+ const index = Number(event.item);
513
+ if (!Number.isInteger(index) || index < 0 || index > this.#getMaxIndexForCurrentStep()) return;
514
+ this.#selectedIndex = index;
515
+ this.#selectCurrentOption();
516
+ this.#requestRender();
517
+ }
518
+
390
519
  #cancelInputStep(): void {
391
520
  if (this.#currentStep === "name") {
392
521
  this.#onCancelCallback();
@@ -463,7 +592,8 @@ export class MCPAddWizard extends OverlayPanel {
463
592
  heading: "Step 1: Server Name",
464
593
  prompt: "Enter a unique name for this server:",
465
594
  initial: this.#state.name,
466
- hint: `[Only letters, numbers, dash, underscore, dot, colon]\n${inputHint("cancel")}`,
595
+ note: "Only letters, numbers, dash, underscore, dot, colon",
596
+ escape: "cancel",
467
597
  optional: false,
468
598
  error: this.#validationError,
469
599
  });
@@ -473,12 +603,13 @@ export class MCPAddWizard extends OverlayPanel {
473
603
  this.#choiceStep({
474
604
  heading: "Step 2: Transport Type",
475
605
  intro: new Text("Select the transport type:", 0, 0),
606
+ nativeIntro: [text("Select the transport type:")],
476
607
  choices: [
477
608
  { label: "stdio (Local process)" },
478
609
  { label: "http (HTTP server)" },
479
610
  { label: "sse (Server-Sent Events)" },
480
611
  ],
481
- hint: choiceHint("cancel"),
612
+ escape: "cancel",
482
613
  });
483
614
  }
484
615
 
@@ -487,7 +618,7 @@ export class MCPAddWizard extends OverlayPanel {
487
618
  heading: "Step 3: Command",
488
619
  prompt: "Enter the command to run:",
489
620
  initial: this.#state.command,
490
- hint: inputHint("go back"),
621
+ escape: "go back",
491
622
  optional: false,
492
623
  });
493
624
  }
@@ -497,7 +628,6 @@ export class MCPAddWizard extends OverlayPanel {
497
628
  heading: "Step 4: Arguments (Optional)",
498
629
  prompt: "Enter command arguments (space-separated):",
499
630
  initial: this.#state.args,
500
- hint: `[Press ${editorKey("tui.input.submit")} to skip or continue]`,
501
631
  optional: true,
502
632
  });
503
633
  }
@@ -507,7 +637,8 @@ export class MCPAddWizard extends OverlayPanel {
507
637
  heading: "Step 3: Server URL",
508
638
  prompt: "Enter the server URL:",
509
639
  initial: this.#state.url,
510
- hint: `[Must start with http:// or https://]\n${inputHint("go back")}`,
640
+ note: "Must start with http:// or https://",
641
+ escape: "go back",
511
642
  optional: false,
512
643
  error: this.#validationError,
513
644
  });
@@ -517,7 +648,7 @@ export class MCPAddWizard extends OverlayPanel {
517
648
  this.#choiceStep({
518
649
  heading: "Step: How to provide the key?",
519
650
  choices: [{ label: "Environment variable" }, { label: "HTTP header" }],
520
- hint: choiceHint("go back"),
651
+ escape: "go back",
521
652
  });
522
653
  }
523
654
 
@@ -526,7 +657,7 @@ export class MCPAddWizard extends OverlayPanel {
526
657
  heading: "Step: Environment Variable Name",
527
658
  prompt: "Enter the environment variable name:",
528
659
  initial: this.#state.envVarName,
529
- hint: inputHint("go back"),
660
+ escape: "go back",
530
661
  optional: false,
531
662
  });
532
663
  }
@@ -536,7 +667,7 @@ export class MCPAddWizard extends OverlayPanel {
536
667
  heading: "Step: HTTP Header Name",
537
668
  prompt: "Enter the HTTP header name:",
538
669
  initial: this.#state.headerName,
539
- hint: inputHint("go back"),
670
+ escape: "go back",
540
671
  optional: false,
541
672
  });
542
673
  }
@@ -548,47 +679,54 @@ export class MCPAddWizard extends OverlayPanel {
548
679
  this.#choiceStep({
549
680
  heading: "Step: Configuration Scope",
550
681
  choices: [{ label: `User level (${userPathLabel})` }, { label: `Project level (${projectPathLabel})` }],
551
- hint: choiceHint("go back"),
682
+ escape: "go back",
552
683
  });
553
684
  }
554
685
 
555
686
  #renderConfirmStep(): void {
556
- const summary = new Container();
557
- summary.addChild(new Text(`Name: ${theme.fg("accent", this.#state.name)}`, 0, 0));
558
- summary.addChild(new Text(`Type: ${this.#state.transport}`, 0, 0));
687
+ // `ansi` overrides the value in the ANSI summary (the native `kv` styles and fits values itself).
688
+ const entries: { k: string; v: string; ansi?: string }[] = [
689
+ { k: "Name", v: this.#state.name, ansi: theme.fg("accent", this.#state.name) },
690
+ { k: "Type", v: `${this.#state.transport}` },
691
+ ];
559
692
 
560
693
  if (this.#state.transport === "stdio") {
561
- summary.addChild(new Text(`Command: ${this.#state.command}`, 0, 0));
694
+ entries.push({ k: "Command", v: this.#state.command });
562
695
  if (this.#state.args) {
563
- summary.addChild(new Text(`Args: ${this.#state.args}`, 0, 0));
696
+ entries.push({ k: "Args", v: this.#state.args });
564
697
  }
565
698
  } else {
566
- summary.addChild(new Text(`URL: ${sanitize(this.#state.url)}`, 0, 0));
699
+ entries.push({ k: "URL", v: replaceTabs(this.#state.url), ansi: sanitize(this.#state.url) });
567
700
  }
568
701
 
569
702
  // Auth info
570
703
  if (this.#state.authMethod === "none") {
571
- summary.addChild(new Text("Auth: None", 0, 0));
704
+ entries.push({ k: "Auth", v: "None" });
572
705
  } else if (this.#state.authMethod === "oauth") {
573
- summary.addChild(new Text("Auth: OAuth (authenticated)", 0, 0));
706
+ entries.push({ k: "Auth", v: "OAuth (authenticated)" });
574
707
  } else if (this.#state.authMethod === "manual") {
575
708
  if (this.#state.authLocation === "env") {
576
- summary.addChild(new Text(`Auth: API key via env (${this.#state.envVarName})`, 0, 0));
709
+ entries.push({ k: "Auth", v: `API key via env (${this.#state.envVarName})` });
577
710
  } else {
578
- summary.addChild(new Text(`Auth: API key via header (${this.#state.headerName})`, 0, 0));
711
+ entries.push({ k: "Auth", v: `API key via header (${this.#state.headerName})` });
579
712
  }
580
713
  }
581
714
 
582
715
  const scopeLabel = this.#state.scope === "user" ? "User level" : "Project level";
583
- summary.addChild(new Text(`Scope: ${scopeLabel}`, 0, 0));
716
+ entries.push({ k: "Scope", v: scopeLabel });
717
+
718
+ const summary = new Container();
719
+ for (const entry of entries) summary.addChild(new Text(`${entry.k}: ${entry.ansi ?? entry.v}`, 0, 0));
584
720
  summary.addChild(new Spacer(1));
585
721
  summary.addChild(new Text("Save this configuration?", 0, 0));
722
+ const items = entries.map(entry => ({ k: entry.k, v: entry.k === "Name" ? [span(entry.v, "accent")] : entry.v }));
586
723
 
587
724
  this.#choiceStep({
588
725
  heading: "Review Configuration",
589
726
  intro: summary,
727
+ nativeIntro: [node("kv", { items }, undefined, "summary"), text("Save this configuration?")],
590
728
  choices: [{ label: "Yes" }, { label: "No" }],
591
- hint: choiceHint("go back"),
729
+ escape: "go back",
592
730
  kind: "confirm",
593
731
  });
594
732
  }
@@ -943,7 +1081,7 @@ export class MCPAddWizard extends OverlayPanel {
943
1081
  { label: "OAuth flow (web-based)", description: "(opens browser)" },
944
1082
  { label: "Manual API key/token", description: "(paste or use shell command)" },
945
1083
  ],
946
- hint: choiceHint("go back"),
1084
+ escape: "go back",
947
1085
  });
948
1086
  }
949
1087
 
@@ -953,7 +1091,7 @@ export class MCPAddWizard extends OverlayPanel {
953
1091
  prompt: "Enter the OAuth authorization endpoint:",
954
1092
  initial: this.#state.oauthAuthUrl,
955
1093
  details: ["e.g., https://auth.example.com/oauth/authorize"],
956
- hint: inputHint("go back"),
1094
+ escape: "go back",
957
1095
  optional: false,
958
1096
  });
959
1097
  }
@@ -964,7 +1102,7 @@ export class MCPAddWizard extends OverlayPanel {
964
1102
  prompt: "Enter the OAuth token endpoint:",
965
1103
  initial: this.#state.oauthTokenUrl,
966
1104
  details: ["e.g., https://auth.example.com/oauth/token"],
967
- hint: inputHint("go back"),
1105
+ escape: "go back",
968
1106
  optional: false,
969
1107
  });
970
1108
  }
@@ -974,7 +1112,7 @@ export class MCPAddWizard extends OverlayPanel {
974
1112
  heading: "OAuth: Client ID",
975
1113
  prompt: "Enter your OAuth client ID:",
976
1114
  initial: this.#state.oauthClientId,
977
- hint: inputHint("go back"),
1115
+ escape: "go back",
978
1116
  optional: false,
979
1117
  });
980
1118
  }
@@ -985,7 +1123,7 @@ export class MCPAddWizard extends OverlayPanel {
985
1123
  prompt: "Enter your OAuth client secret:",
986
1124
  initial: this.#state.oauthClientSecret,
987
1125
  details: ["(Leave empty for PKCE-only flows)"],
988
- hint: inputHint("go back"),
1126
+ escape: "go back",
989
1127
  optional: true,
990
1128
  });
991
1129
  }
@@ -996,7 +1134,7 @@ export class MCPAddWizard extends OverlayPanel {
996
1134
  prompt: "Enter OAuth scopes (space-separated):",
997
1135
  initial: this.#state.oauthScopes,
998
1136
  details: ["e.g., read write"],
999
- hint: inputHint("go back"),
1137
+ escape: "go back",
1000
1138
  optional: true,
1001
1139
  });
1002
1140
  }
@@ -1013,8 +1151,9 @@ export class MCPAddWizard extends OverlayPanel {
1013
1151
  heading: this.#oauthErrorHeading?.text ?? "OAuth authentication failed",
1014
1152
  headingTone: this.#oauthErrorHeading?.tone ?? "error",
1015
1153
  intro,
1154
+ nativeIntro: [...this.#oauthErrorNative, text("Choose next action:")],
1016
1155
  choices: [{ label: "Retry OAuth authentication" }, { label: "Edit OAuth settings" }],
1017
- hint: choiceHint("go back"),
1156
+ escape: "go back",
1018
1157
  });
1019
1158
  }
1020
1159
 
@@ -1024,7 +1163,7 @@ export class MCPAddWizard extends OverlayPanel {
1024
1163
  prompt: "Enter your API key or token:",
1025
1164
  initial: this.#state.apiKey,
1026
1165
  details: ["(Supports !command for password manager)"],
1027
- hint: inputHint("go back"),
1166
+ escape: "go back",
1028
1167
  optional: false,
1029
1168
  });
1030
1169
  }
@@ -1050,7 +1189,7 @@ export class MCPAddWizard extends OverlayPanel {
1050
1189
  // Success! No auth required
1051
1190
  const successBody = new Container();
1052
1191
  successBody.addChild(new Text("No authentication required", 0, 0));
1053
- this.#asyncStep("✓ Connection successful!", "success", successBody);
1192
+ this.#asyncStep("✓ Connection successful!", "success", successBody, [text("No authentication required")]);
1054
1193
 
1055
1194
  setTimeout(() => {
1056
1195
  this.#state.authMethod = "none";
@@ -1098,7 +1237,9 @@ export class MCPAddWizard extends OverlayPanel {
1098
1237
 
1099
1238
  const oauthBody = new Container();
1100
1239
  oauthBody.addChild(new Text("Launching browser for authorization...", 0, 0));
1101
- this.#asyncStep("✓ OAuth detected", "success", oauthBody);
1240
+ this.#asyncStep("✓ OAuth detected", "success", oauthBody, [
1241
+ text("Launching browser for authorization..."),
1242
+ ]);
1102
1243
 
1103
1244
  void this.#launchOAuthFlow();
1104
1245
  return;
@@ -1114,7 +1255,10 @@ export class MCPAddWizard extends OverlayPanel {
1114
1255
  failureBody.addChild(new Text(errorMsg, 0, 0));
1115
1256
  failureBody.addChild(new Spacer(1));
1116
1257
  failureBody.addChild(new Text(theme.fg("muted", "Adding server anyway..."), 0, 0));
1117
- this.#asyncStep("✗ Connection failed", "error", failureBody);
1258
+ this.#asyncStep("✗ Connection failed", "error", failureBody, [
1259
+ text(nativeErrorText(error), { wrap: "word" }),
1260
+ text([span("Adding server anyway...", "muted")]),
1261
+ ]);
1118
1262
 
1119
1263
  setTimeout(() => {
1120
1264
  this.#state.authMethod = "none";
@@ -1209,7 +1353,9 @@ export class MCPAddWizard extends OverlayPanel {
1209
1353
  if (!this.#onOAuthCallback) {
1210
1354
  const unavailableBody = new Container();
1211
1355
  unavailableBody.addChild(new Text("OAuth login cannot start without a host OAuth handler.", 0, 0));
1212
- this.#asyncStep("OAuth flow not available", "error", unavailableBody);
1356
+ this.#asyncStep("OAuth flow not available", "error", unavailableBody, [
1357
+ text("OAuth login cannot start without a host OAuth handler.", { wrap: "word" }),
1358
+ ]);
1213
1359
  this.#requestRender();
1214
1360
  return;
1215
1361
  }
@@ -1222,7 +1368,9 @@ export class MCPAddWizard extends OverlayPanel {
1222
1368
  "OAuth configuration incomplete",
1223
1369
  "error",
1224
1370
  incompleteBody,
1371
+ [text("Authorization and Token URLs are required.")],
1225
1372
  new Text(theme.fg("muted", `[Press ${interruptKey()} to go back]`), 0, 0),
1373
+ interruptHint("go back"),
1226
1374
  );
1227
1375
  this.#requestRender();
1228
1376
  return;
@@ -1238,7 +1386,13 @@ export class MCPAddWizard extends OverlayPanel {
1238
1386
  "OAuth Authentication",
1239
1387
  "accent",
1240
1388
  authBody,
1389
+ [
1390
+ text("Launching OAuth flow..."),
1391
+ text([span("Browser will open automatically.", "muted")]),
1392
+ text([span("If browser doesn't open, copy the URL from chat.", "warning")], { wrap: "word" }),
1393
+ ],
1241
1394
  new Text(theme.fg("muted", `(Press ${interruptKey()} to cancel)`), 0, 0),
1395
+ interruptHint("cancel"),
1242
1396
  );
1243
1397
  this.#requestRender();
1244
1398
 
@@ -1278,19 +1432,30 @@ export class MCPAddWizard extends OverlayPanel {
1278
1432
  const initialFrame = spinnerFrames[0] ?? "|";
1279
1433
  const healthText = new Text(theme.fg("muted", `${initialFrame} Checking server connection...`), 0, 0);
1280
1434
  healthBody.addChild(healthText);
1281
- this.#asyncStep("✓ Authentication successful!", "success", healthBody);
1435
+ const healthIntro = text([span("Running connection health check...", "muted")]);
1436
+ this.#asyncStep("✓ Authentication successful!", "success", healthBody, [
1437
+ healthIntro,
1438
+ node("spinner", { label: [span("Checking server connection...", "muted")] }, undefined, "health"),
1439
+ ]);
1282
1440
 
1441
+ // The frame ticker only repaints; a native terminal animates the described spinner itself.
1283
1442
  let spinnerIndex = 0;
1284
- const spinner = setInterval(() => {
1285
- healthText.setText(
1286
- theme.fg("muted", `${spinnerFrames[spinnerIndex % spinnerFrames.length]} Checking server connection...`),
1287
- );
1288
- spinnerIndex++;
1289
- this.#requestRender();
1290
- }, 80);
1443
+ const spinner = isNativeRendering()
1444
+ ? undefined
1445
+ : setInterval(() => {
1446
+ healthText.setText(
1447
+ theme.fg(
1448
+ "muted",
1449
+ `${spinnerFrames[spinnerIndex % spinnerFrames.length]} Checking server connection...`,
1450
+ ),
1451
+ );
1452
+ spinnerIndex++;
1453
+ this.#requestRender();
1454
+ }, 80);
1291
1455
 
1292
1456
  let healthPassed = true;
1293
1457
  let healthError = "";
1458
+ let nativeHealthError = "";
1294
1459
  if (this.#onTestConnectionCallback) {
1295
1460
  try {
1296
1461
  const { promise: timeoutPromise, reject: timeoutReject } = Promise.withResolvers<never>();
@@ -1309,16 +1474,23 @@ export class MCPAddWizard extends OverlayPanel {
1309
1474
  } catch (error) {
1310
1475
  healthPassed = false;
1311
1476
  healthError = sanitize(error instanceof Error ? error.message : String(error));
1477
+ nativeHealthError = nativeErrorText(error);
1312
1478
  }
1313
1479
  }
1314
1480
 
1315
1481
  clearInterval(spinner);
1316
1482
  if (healthPassed) {
1317
1483
  healthText.setText(theme.fg("success", "✓ Health check passed"));
1484
+ this.#setNativeBody([healthIntro, text([span("✓ Health check passed", "success")])]);
1318
1485
  } else {
1319
1486
  healthText.setText(theme.fg("warning", "⚠ Health check failed (will still save config)"));
1320
1487
  healthBody.addChild(new Spacer(1));
1321
1488
  healthBody.addChild(new Text(theme.fg("muted", healthError), 0, 0));
1489
+ this.#setNativeBody([
1490
+ healthIntro,
1491
+ text([span("⚠ Health check failed (will still save config)", "warning")]),
1492
+ text([span(nativeHealthError, "muted")], { wrap: "word" }),
1493
+ ]);
1322
1494
  }
1323
1495
  this.#requestRender();
1324
1496
 
@@ -1338,16 +1510,23 @@ export class MCPAddWizard extends OverlayPanel {
1338
1510
  // stay meaningful. Name-matching avoids importing controller types.
1339
1511
  const cancelled = error instanceof Error && error.name === "MCPOAuthCancelledError";
1340
1512
  const errorMsg = sanitize(error instanceof Error ? error.message : String(error));
1341
- const tipLines: string[] = [errorMsg];
1513
+ let tip: string | undefined;
1342
1514
  if (cancelled) {
1343
- tipLines.push(theme.fg("muted", "Tip: Choose Retry to launch the browser again."));
1515
+ tip = "Tip: Choose Retry to launch the browser again.";
1344
1516
  } else if (errorMsg.includes("timeout") || errorMsg.includes("timed out")) {
1345
- tipLines.push(theme.fg("muted", "Tip: Complete authorization faster next time"));
1517
+ tip = "Tip: Complete authorization faster next time";
1346
1518
  } else if (errorMsg.includes("Invalid OAuth URLs")) {
1347
- tipLines.push(theme.fg("muted", "Tip: Check that the OAuth URLs are correct"));
1519
+ tip = "Tip: Check that the OAuth URLs are correct";
1348
1520
  } else if (errorMsg.includes("ECONNREFUSED")) {
1349
- tipLines.push(theme.fg("muted", "Tip: Verify the OAuth server is accessible"));
1521
+ tip = "Tip: Verify the OAuth server is accessible";
1522
+ }
1523
+ const tipLines: string[] = [errorMsg];
1524
+ const nativeLines = [text(nativeErrorText(error), { wrap: "word" })];
1525
+ if (tip) {
1526
+ tipLines.push(theme.fg("muted", tip));
1527
+ nativeLines.push(text([span(tip, "muted")], { wrap: "word" }));
1350
1528
  }
1529
+ this.#oauthErrorNative = nativeLines;
1351
1530
 
1352
1531
  // Set up as a selector step
1353
1532
  this.#selectedIndex = 0;