@oh-my-pi/pi-tui 18.4.2 → 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 (463) hide show
  1. package/CHANGELOG.md +56 -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/thinking-display.d.ts +2 -0
  22. package/dist/types/chat/todo-reminder.d.ts +4 -1
  23. package/dist/types/chat/tool-execution.d.ts +25 -1
  24. package/dist/types/chat/transcript-actions.d.ts +37 -0
  25. package/dist/types/chat/transcript-entry.d.ts +3 -1
  26. package/dist/types/chat/user-message.d.ts +25 -0
  27. package/dist/types/chrome/collab-qrcode.d.ts +7 -0
  28. package/dist/types/chrome/context-thresholds.d.ts +11 -0
  29. package/dist/types/chrome/countdown-timer.d.ts +9 -3
  30. package/dist/types/chrome/diff.d.ts +12 -0
  31. package/dist/types/chrome/dynamic-border.d.ts +3 -0
  32. package/dist/types/chrome/format.d.ts +6 -0
  33. package/dist/types/chrome/message-divider.d.ts +13 -0
  34. package/dist/types/chrome/message-frame.d.ts +10 -0
  35. package/dist/types/chrome/message-notice.d.ts +23 -0
  36. package/dist/types/chrome/overlay-box.d.ts +11 -2
  37. package/dist/types/chrome/qrcode.d.ts +7 -0
  38. package/dist/types/chrome/segment-track.d.ts +7 -0
  39. package/dist/types/chrome/selector-helpers.d.ts +0 -6
  40. package/dist/types/chrome/status-notice.d.ts +14 -0
  41. package/dist/types/chrome/streaming-panel.d.ts +3 -0
  42. package/dist/types/chrome/tool-activity.d.ts +3 -0
  43. package/dist/types/chrome/transcript-container.d.ts +13 -0
  44. package/dist/types/chrome/transcript-status.d.ts +15 -3
  45. package/dist/types/components/box.d.ts +7 -0
  46. package/dist/types/components/disclosure.d.ts +9 -0
  47. package/dist/types/components/editor.d.ts +42 -0
  48. package/dist/types/components/form.d.ts +14 -0
  49. package/dist/types/components/image.d.ts +7 -0
  50. package/dist/types/components/input.d.ts +20 -1
  51. package/dist/types/components/key-value-list.d.ts +3 -0
  52. package/dist/types/components/layout/geometry.d.ts +16 -0
  53. package/dist/types/components/layout/row.d.ts +7 -0
  54. package/dist/types/components/layout/split-pane.d.ts +8 -0
  55. package/dist/types/components/layout/stack.d.ts +6 -0
  56. package/dist/types/components/loader.d.ts +48 -0
  57. package/dist/types/components/markdown.d.ts +8 -0
  58. package/dist/types/components/metric.d.ts +7 -0
  59. package/dist/types/components/progress-bar.d.ts +3 -0
  60. package/dist/types/components/scroll-view.d.ts +6 -0
  61. package/dist/types/components/section.d.ts +3 -0
  62. package/dist/types/components/select-list.d.ts +33 -0
  63. package/dist/types/components/settings-list.d.ts +68 -0
  64. package/dist/types/components/spacer.d.ts +4 -0
  65. package/dist/types/components/tab-bar.d.ts +9 -0
  66. package/dist/types/components/table.d.ts +7 -0
  67. package/dist/types/components/text.d.ts +6 -0
  68. package/dist/types/components/tree-view.d.ts +9 -0
  69. package/dist/types/components/truncated-text.d.ts +3 -0
  70. package/dist/types/components/wizard-step.d.ts +6 -0
  71. package/dist/types/hotkeys-markdown.d.ts +24 -0
  72. package/dist/types/index.d.ts +5 -0
  73. package/dist/types/latex-block.d.ts +7 -0
  74. package/dist/types/loop-watchdog.d.ts +9 -0
  75. package/dist/types/native/apply.d.ts +39 -0
  76. package/dist/types/native/backend.d.ts +94 -0
  77. package/dist/types/native/blobs.d.ts +29 -0
  78. package/dist/types/native/describe.d.ts +56 -0
  79. package/dist/types/native/encode.d.ts +50 -0
  80. package/dist/types/native/icons.d.ts +18 -0
  81. package/dist/types/native/memo.d.ts +27 -0
  82. package/dist/types/native/node.d.ts +107 -0
  83. package/dist/types/native/overlay.d.ts +64 -0
  84. package/dist/types/native/picker.d.ts +124 -0
  85. package/dist/types/native/reconcile.d.ts +41 -0
  86. package/dist/types/native/settle.d.ts +11 -0
  87. package/dist/types/native/spans.d.ts +21 -0
  88. package/dist/types/native/state.d.ts +6 -0
  89. package/dist/types/native/tone.d.ts +24 -0
  90. package/dist/types/overlays/advisor-config.d.ts +20 -0
  91. package/dist/types/overlays/agent-hub-renderer.d.ts +27 -11
  92. package/dist/types/overlays/agent-hub.d.ts +10 -0
  93. package/dist/types/overlays/agent-transcript-viewer.d.ts +7 -0
  94. package/dist/types/overlays/agents-hub.d.ts +8 -0
  95. package/dist/types/overlays/annotation-overlay.d.ts +3 -0
  96. package/dist/types/overlays/ask-dialog.d.ts +23 -0
  97. package/dist/types/overlays/bordered-loader.d.ts +3 -0
  98. package/dist/types/overlays/btw-history-panel.d.ts +9 -0
  99. package/dist/types/overlays/btw-panel.d.ts +3 -0
  100. package/dist/types/overlays/cleanse-panel.d.ts +5 -2
  101. package/dist/types/overlays/composer-shape-preview.d.ts +7 -1
  102. package/dist/types/overlays/copy-selector.d.ts +38 -0
  103. package/dist/types/overlays/error-banner.d.ts +9 -0
  104. package/dist/types/overlays/extensions/extension-list.d.ts +1 -0
  105. package/dist/types/overlays/history-search.d.ts +18 -0
  106. package/dist/types/overlays/hook-editor.d.ts +28 -1
  107. package/dist/types/overlays/hook-input.d.ts +3 -0
  108. package/dist/types/overlays/hook-selector.d.ts +10 -0
  109. package/dist/types/overlays/hub-frame.d.ts +18 -0
  110. package/dist/types/overlays/jobs-panel.d.ts +24 -0
  111. package/dist/types/overlays/login-dialog.d.ts +10 -0
  112. package/dist/types/overlays/logout-account-selector.d.ts +4 -0
  113. package/dist/types/overlays/mcp-add-wizard.d.ts +4 -0
  114. package/dist/types/overlays/model-browser.d.ts +69 -0
  115. package/dist/types/overlays/model-hub.d.ts +7 -0
  116. package/dist/types/overlays/model-picker.d.ts +9 -1
  117. package/dist/types/overlays/move-overlay.d.ts +3 -0
  118. package/dist/types/overlays/oauth-selector.d.ts +4 -0
  119. package/dist/types/overlays/omfg-panel.d.ts +3 -0
  120. package/dist/types/overlays/pause-screen.d.ts +12 -0
  121. package/dist/types/overlays/plan-review-overlay.d.ts +5 -0
  122. package/dist/types/overlays/plan-save-overlay.d.ts +10 -0
  123. package/dist/types/overlays/plugin-selector.d.ts +4 -0
  124. package/dist/types/overlays/plugin-settings.d.ts +30 -0
  125. package/dist/types/overlays/queue-mode-selector.d.ts +4 -0
  126. package/dist/types/overlays/reset-usage-selector.d.ts +8 -0
  127. package/dist/types/overlays/rewind-selector.d.ts +5 -0
  128. package/dist/types/overlays/session-info-overlay.d.ts +19 -1
  129. package/dist/types/overlays/session-selector.d.ts +64 -1
  130. package/dist/types/overlays/settings-defs.d.ts +14 -0
  131. package/dist/types/overlays/settings-selector.d.ts +21 -0
  132. package/dist/types/overlays/show-images-selector.d.ts +4 -0
  133. package/dist/types/overlays/snapcompact-shape-preview.d.ts +2 -0
  134. package/dist/types/overlays/stats-notice.d.ts +8 -0
  135. package/dist/types/overlays/theme-selector.d.ts +11 -0
  136. package/dist/types/overlays/thinking-selector.d.ts +4 -0
  137. package/dist/types/overlays/tree-selector.d.ts +60 -2
  138. package/dist/types/overlays/usage-dashboard.d.ts +26 -3
  139. package/dist/types/overlays/usage-row.d.ts +36 -2
  140. package/dist/types/prompt/attachment-chips.d.ts +8 -0
  141. package/dist/types/prompt/composer-attachments.d.ts +15 -3
  142. package/dist/types/prompt/composer.d.ts +18 -1
  143. package/dist/types/prompt/custom-editor.d.ts +48 -2
  144. package/dist/types/prompt/editor-top-gap.d.ts +2 -0
  145. package/dist/types/prompt/macos-spelling.d.ts +6 -0
  146. package/dist/types/prompt/magic-keywords.d.ts +9 -0
  147. package/dist/types/prompt/queued-messages.d.ts +23 -0
  148. package/dist/types/prompt/skill-tokens.d.ts +4 -2
  149. package/dist/types/prompt/welcome.d.ts +16 -0
  150. package/dist/types/render/code-cell.d.ts +10 -0
  151. package/dist/types/render/file-list.d.ts +8 -0
  152. package/dist/types/render/hyperlink.d.ts +14 -0
  153. package/dist/types/render/output-block.d.ts +43 -0
  154. package/dist/types/render/output-pane.d.ts +17 -0
  155. package/dist/types/render/tool-card.d.ts +8 -0
  156. package/dist/types/render/tree-list.d.ts +8 -0
  157. package/dist/types/render/width-aware-text.d.ts +7 -0
  158. package/dist/types/setup/scenes/outro.d.ts +7 -0
  159. package/dist/types/setup/scenes/sign-in.d.ts +16 -9
  160. package/dist/types/setup/scenes/splash.d.ts +8 -0
  161. package/dist/types/setup/scenes/types.d.ts +6 -27
  162. package/dist/types/setup/wizard-overlay.d.ts +9 -0
  163. package/dist/types/status-line/component.d.ts +49 -5
  164. package/dist/types/status-line/context-usage.d.ts +20 -0
  165. package/dist/types/status-line/footer.d.ts +8 -0
  166. package/dist/types/status-line/metrics.d.ts +1 -2
  167. package/dist/types/status-line/segments.d.ts +10 -1
  168. package/dist/types/status-line/types.d.ts +40 -1
  169. package/dist/types/stdin-buffer.d.ts +10 -7
  170. package/dist/types/terminal-capabilities.d.ts +1 -1
  171. package/dist/types/terminal.d.ts +36 -0
  172. package/dist/types/theme/defaults/index.d.ts +100 -0
  173. package/dist/types/theme/schema.d.ts +2 -0
  174. package/dist/types/theme/shimmer.d.ts +8 -0
  175. package/dist/types/theme/theme-class.d.ts +2 -0
  176. package/dist/types/theme/theme.d.ts +33 -1
  177. package/dist/types/tools/ask.d.ts +3 -0
  178. package/dist/types/tools/ast-edit.d.ts +10 -1
  179. package/dist/types/tools/ast-grep.d.ts +10 -1
  180. package/dist/types/tools/autoresearch.d.ts +21 -4
  181. package/dist/types/tools/bash.d.ts +30 -1
  182. package/dist/types/tools/cfg-render.d.ts +5 -1
  183. package/dist/types/tools/debug.d.ts +3 -1
  184. package/dist/types/tools/default-renderer.d.ts +6 -1
  185. package/dist/types/tools/edit.d.ts +14 -1
  186. package/dist/types/tools/eval.d.ts +12 -1
  187. package/dist/types/tools/fetch.d.ts +16 -1
  188. package/dist/types/tools/find.d.ts +15 -1
  189. package/dist/types/tools/github.d.ts +3 -0
  190. package/dist/types/tools/glob.d.ts +14 -1
  191. package/dist/types/tools/goal.d.ts +3 -1
  192. package/dist/types/tools/grep.d.ts +14 -1
  193. package/dist/types/tools/grouped-file-output.d.ts +58 -0
  194. package/dist/types/tools/json-tree.d.ts +20 -0
  195. package/dist/types/tools/lsp.d.ts +3 -10
  196. package/dist/types/tools/mcp.d.ts +16 -1
  197. package/dist/types/tools/memory.d.ts +26 -0
  198. package/dist/types/tools/native-view.d.ts +90 -0
  199. package/dist/types/tools/proc-render.d.ts +7 -1
  200. package/dist/types/tools/read.d.ts +23 -1
  201. package/dist/types/tools/renderer.d.ts +57 -0
  202. package/dist/types/tools/report-tool-issue.d.ts +3 -0
  203. package/dist/types/tools/resolve.d.ts +14 -1
  204. package/dist/types/tools/task.d.ts +3 -0
  205. package/dist/types/tools/think.d.ts +3 -0
  206. package/dist/types/tools/todo.d.ts +12 -0
  207. package/dist/types/tools/vibe.d.ts +3 -1
  208. package/dist/types/tools/wait.d.ts +3 -0
  209. package/dist/types/tools/web-search-types.d.ts +90 -0
  210. package/dist/types/tools/web-search.d.ts +9 -168
  211. package/dist/types/tools/write.d.ts +14 -1
  212. package/dist/types/tools/xdev.d.ts +13 -0
  213. package/dist/types/tui.d.ts +49 -0
  214. package/package.json +9 -9
  215. package/src/apps/autoresearch-dashboard.ts +362 -4
  216. package/src/apps/cleanse-board.ts +219 -1
  217. package/src/apps/cleanse-picker.ts +9 -1
  218. package/src/apps/debug/log-viewer.ts +15 -15
  219. package/src/apps/debug/protocol-probe.ts +2 -20
  220. package/src/apps/git/avatar.ts +2 -22
  221. package/src/apps/git/git-tui.ts +406 -59
  222. package/src/apps/git/help.ts +130 -0
  223. package/src/apps/git/sidebar.ts +491 -0
  224. package/src/apps/live-visualizer.ts +65 -0
  225. package/src/apps/ps-top.ts +448 -17
  226. package/src/apps/session-picker.ts +1 -0
  227. package/src/apps/setup-model-picker.ts +5 -1
  228. package/src/apps/standalone-picker.ts +55 -1
  229. package/src/autocomplete.ts +44 -1
  230. package/src/chat/advisor-message.ts +72 -3
  231. package/src/chat/assistant-message.ts +538 -51
  232. package/src/chat/background-tan-message.ts +4 -4
  233. package/src/chat/bash-execution.ts +81 -0
  234. package/src/chat/cache-invalidation-marker.ts +8 -0
  235. package/src/chat/chat-transcript-builder.ts +37 -6
  236. package/src/chat/collab-prompt-message.ts +15 -3
  237. package/src/chat/compaction-summary-message.ts +74 -1
  238. package/src/chat/custom-message.ts +3 -1
  239. package/src/chat/eval-execution.ts +57 -0
  240. package/src/chat/execution-shared.ts +153 -1
  241. package/src/chat/hook-message.ts +1 -0
  242. package/src/chat/late-diagnostics-message.ts +85 -2
  243. package/src/chat/read-tool-group.ts +341 -1
  244. package/src/chat/served-model-marker.ts +8 -0
  245. package/src/chat/skill-message.ts +63 -0
  246. package/src/chat/stripped-tool-calls-placeholder.ts +18 -10
  247. package/src/chat/thinking-display.ts +73 -11
  248. package/src/chat/todo-reminder.ts +34 -4
  249. package/src/chat/tool-execution.ts +385 -10
  250. package/src/chat/transcript-actions.ts +38 -0
  251. package/src/chat/transcript-browser.ts +2 -9
  252. package/src/chat/transcript-entry.ts +10 -1
  253. package/src/chat/transcript-render-helpers.ts +16 -15
  254. package/src/chat/ttsr-notification.ts +38 -1
  255. package/src/chat/user-message.ts +167 -4
  256. package/src/chrome/collab-qrcode.ts +27 -2
  257. package/src/chrome/context-thresholds.ts +34 -0
  258. package/src/chrome/countdown-timer.ts +24 -1
  259. package/src/chrome/diff.ts +60 -1
  260. package/src/chrome/dynamic-border.ts +7 -0
  261. package/src/chrome/format.ts +12 -0
  262. package/src/chrome/message-divider.ts +33 -1
  263. package/src/chrome/message-frame.ts +53 -10
  264. package/src/chrome/message-notice.ts +71 -0
  265. package/src/chrome/overlay-box.ts +45 -2
  266. package/src/chrome/qrcode.ts +28 -0
  267. package/src/chrome/segment-track.ts +26 -0
  268. package/src/chrome/selector-helpers.ts +1 -17
  269. package/src/chrome/status-notice.ts +46 -0
  270. package/src/chrome/streaming-panel.ts +25 -1
  271. package/src/chrome/tool-activity.ts +20 -0
  272. package/src/chrome/transcript-container.ts +139 -17
  273. package/src/chrome/transcript-status.ts +40 -11
  274. package/src/components/box.ts +51 -0
  275. package/src/components/disclosure.ts +33 -0
  276. package/src/components/editor.ts +239 -36
  277. package/src/components/form.ts +93 -9
  278. package/src/components/image.ts +30 -0
  279. package/src/components/input.ts +77 -26
  280. package/src/components/key-value-list.ts +18 -0
  281. package/src/components/layout/geometry.ts +44 -0
  282. package/src/components/layout/row.ts +30 -0
  283. package/src/components/layout/split-pane.ts +65 -0
  284. package/src/components/layout/stack.ts +27 -0
  285. package/src/components/loader.ts +183 -1
  286. package/src/components/markdown.ts +131 -56
  287. package/src/components/metric.ts +39 -0
  288. package/src/components/progress-bar.ts +28 -0
  289. package/src/components/scroll-view.ts +23 -0
  290. package/src/components/section.ts +16 -0
  291. package/src/components/select-list.ts +174 -25
  292. package/src/components/settings-list.ts +264 -7
  293. package/src/components/spacer.ts +17 -0
  294. package/src/components/tab-bar.ts +42 -0
  295. package/src/components/table.ts +34 -0
  296. package/src/components/text.ts +23 -0
  297. package/src/components/tree-view.ts +65 -0
  298. package/src/components/truncated-text.ts +14 -0
  299. package/src/components/wizard-step.ts +18 -9
  300. package/src/debug-server.ts +14 -7
  301. package/src/hotkeys-markdown.ts +251 -69
  302. package/src/index.ts +6 -0
  303. package/src/latex-block.ts +11 -0
  304. package/src/loop-watchdog.ts +38 -10
  305. package/src/native/apply.ts +275 -0
  306. package/src/native/backend.ts +682 -0
  307. package/src/native/blobs.ts +70 -0
  308. package/src/native/describe.ts +124 -0
  309. package/src/native/encode.ts +233 -0
  310. package/src/native/icons.ts +184 -0
  311. package/src/native/memo.ts +64 -0
  312. package/src/native/node.ts +112 -0
  313. package/src/native/overlay.ts +131 -0
  314. package/src/native/picker.ts +333 -0
  315. package/src/native/reconcile.ts +1063 -0
  316. package/src/native/settle.ts +23 -0
  317. package/src/native/spans.ts +308 -0
  318. package/src/native/state.ts +28 -0
  319. package/src/native/tone.ts +79 -0
  320. package/src/overlays/advisor-config.ts +420 -0
  321. package/src/overlays/agent-hub-renderer.ts +155 -18
  322. package/src/overlays/agent-hub.ts +1037 -44
  323. package/src/overlays/agent-transcript-viewer.ts +129 -0
  324. package/src/overlays/agents-hub.ts +688 -53
  325. package/src/overlays/annotation-overlay.ts +391 -52
  326. package/src/overlays/ask-dialog.ts +435 -24
  327. package/src/overlays/bordered-loader.ts +17 -0
  328. package/src/overlays/btw-history-panel.ts +182 -0
  329. package/src/overlays/btw-panel.ts +68 -2
  330. package/src/overlays/cleanse-panel.ts +105 -15
  331. package/src/overlays/codex-reset-fireworks.ts +65 -5
  332. package/src/overlays/composer-shape-preview.ts +26 -1
  333. package/src/overlays/copy-selector.ts +545 -23
  334. package/src/overlays/error-banner.ts +44 -0
  335. package/src/overlays/extensions/extension-list.ts +23 -17
  336. package/src/overlays/history-search.ts +175 -33
  337. package/src/overlays/hook-editor.ts +113 -6
  338. package/src/overlays/hook-input.ts +22 -1
  339. package/src/overlays/hook-selector.ts +311 -22
  340. package/src/overlays/hub-frame.ts +80 -0
  341. package/src/overlays/jobs-panel.ts +112 -0
  342. package/src/overlays/login-dialog.ts +183 -1
  343. package/src/overlays/logout-account-selector.ts +102 -4
  344. package/src/overlays/mcp-add-wizard.ts +232 -53
  345. package/src/overlays/model-browser.ts +681 -22
  346. package/src/overlays/model-hub.ts +1402 -78
  347. package/src/overlays/model-picker.ts +184 -7
  348. package/src/overlays/move-overlay.ts +45 -0
  349. package/src/overlays/oauth-selector.ts +227 -23
  350. package/src/overlays/omfg-panel.ts +86 -2
  351. package/src/overlays/pause-screen.ts +55 -4
  352. package/src/overlays/plan-review-overlay.ts +352 -0
  353. package/src/overlays/plan-save-overlay.ts +45 -0
  354. package/src/overlays/plugin-selector.ts +21 -1
  355. package/src/overlays/plugin-settings.ts +195 -5
  356. package/src/overlays/queue-mode-selector.ts +19 -1
  357. package/src/overlays/reset-usage-selector.ts +110 -40
  358. package/src/overlays/rewind-selector.ts +458 -44
  359. package/src/overlays/session-account-selector.ts +1 -1
  360. package/src/overlays/session-info-overlay.ts +137 -1
  361. package/src/overlays/session-selector.ts +807 -46
  362. package/src/overlays/settings-defs.ts +41 -0
  363. package/src/overlays/settings-selector.ts +585 -33
  364. package/src/overlays/show-images-selector.ts +18 -1
  365. package/src/overlays/snapcompact-shape-preview.ts +48 -3
  366. package/src/overlays/stats-notice.ts +31 -0
  367. package/src/overlays/theme-selector.ts +31 -1
  368. package/src/overlays/thinking-selector.ts +22 -1
  369. package/src/overlays/tree-selector.ts +570 -110
  370. package/src/overlays/usage-dashboard.ts +587 -12
  371. package/src/overlays/usage-row.ts +161 -25
  372. package/src/prompt/attachment-chips.ts +60 -0
  373. package/src/prompt/composer-attachments.ts +31 -9
  374. package/src/prompt/composer.ts +55 -2
  375. package/src/prompt/custom-editor.ts +302 -4
  376. package/src/prompt/editor-top-gap.ts +8 -0
  377. package/src/prompt/macos-spelling.ts +24 -9
  378. package/src/prompt/magic-keywords.ts +22 -1
  379. package/src/prompt/model-mention-autocomplete.ts +1 -0
  380. package/src/prompt/queued-messages.ts +101 -0
  381. package/src/prompt/skill-tokens.ts +5 -3
  382. package/src/prompt/welcome.ts +213 -6
  383. package/src/render/code-cell.ts +103 -2
  384. package/src/render/file-list.ts +29 -0
  385. package/src/render/hyperlink.ts +32 -0
  386. package/src/render/output-block.ts +110 -0
  387. package/src/render/output-pane.ts +37 -0
  388. package/src/render/tool-card.ts +137 -0
  389. package/src/render/tree-list.ts +39 -0
  390. package/src/render/width-aware-text.ts +20 -0
  391. package/src/setup/scenes/composer.ts +29 -0
  392. package/src/setup/scenes/glyph.ts +15 -0
  393. package/src/setup/scenes/model.ts +36 -8
  394. package/src/setup/scenes/outro.ts +28 -1
  395. package/src/setup/scenes/sign-in.ts +138 -24
  396. package/src/setup/scenes/splash.ts +28 -1
  397. package/src/setup/scenes/theme.ts +88 -3
  398. package/src/setup/scenes/types.ts +7 -28
  399. package/src/setup/startup-splash.ts +46 -9
  400. package/src/setup/wizard-overlay.ts +140 -23
  401. package/src/setup/wizard.ts +1 -1
  402. package/src/status-line/component.ts +414 -18
  403. package/src/status-line/context-usage.ts +279 -50
  404. package/src/status-line/footer.ts +94 -1
  405. package/src/status-line/metrics.ts +3 -6
  406. package/src/status-line/segments.ts +463 -97
  407. package/src/status-line/separators.ts +3 -16
  408. package/src/status-line/types.ts +43 -1
  409. package/src/stdin-buffer.ts +27 -21
  410. package/src/terminal-capabilities.ts +7 -0
  411. package/src/terminal.ts +153 -11
  412. package/src/theme/defaults/dark-neon-noir.json +100 -0
  413. package/src/theme/defaults/index.ts +2 -0
  414. package/src/theme/defaults/light-prism.json +5 -5
  415. package/src/theme/defaults/onyx.json +62 -62
  416. package/src/theme/mermaid-cache.ts +10 -1
  417. package/src/theme/schema.ts +15 -0
  418. package/src/theme/shimmer.ts +33 -0
  419. package/src/theme/theme-class.ts +24 -19
  420. package/src/theme/theme.ts +111 -9
  421. package/src/theme/tui-adapters.ts +14 -1
  422. package/src/tools/ask.ts +157 -1
  423. package/src/tools/ast-edit.ts +174 -1
  424. package/src/tools/ast-grep.ts +82 -2
  425. package/src/tools/autoresearch.ts +149 -1
  426. package/src/tools/bash.ts +233 -62
  427. package/src/tools/cfg-render.ts +66 -1
  428. package/src/tools/debug.ts +78 -1
  429. package/src/tools/default-renderer.ts +35 -1
  430. package/src/tools/edit.ts +357 -31
  431. package/src/tools/eval.ts +257 -1
  432. package/src/tools/fetch.ts +102 -3
  433. package/src/tools/find.ts +127 -1
  434. package/src/tools/github.ts +119 -10
  435. package/src/tools/glob.ts +116 -1
  436. package/src/tools/goal.ts +56 -1
  437. package/src/tools/grep.ts +83 -2
  438. package/src/tools/grouped-file-output.ts +205 -0
  439. package/src/tools/json-tree.ts +116 -1
  440. package/src/tools/lsp.ts +318 -1
  441. package/src/tools/mcp.ts +80 -1
  442. package/src/tools/memory.ts +93 -11
  443. package/src/tools/native-view.ts +292 -0
  444. package/src/tools/proc-render.ts +221 -1
  445. package/src/tools/read.ts +199 -4
  446. package/src/tools/renderer.ts +61 -0
  447. package/src/tools/report-tool-issue.ts +7 -1
  448. package/src/tools/resolve.ts +63 -1
  449. package/src/tools/streaming-output.ts +79 -16
  450. package/src/tools/task.ts +406 -4
  451. package/src/tools/think.ts +19 -1
  452. package/src/tools/todo.ts +89 -0
  453. package/src/tools/vibe.ts +230 -2
  454. package/src/tools/wait.ts +181 -1
  455. package/src/tools/web-search-types.ts +99 -0
  456. package/src/tools/web-search.ts +111 -170
  457. package/src/tools/write.ts +144 -5
  458. package/src/tools/xdev.ts +64 -1
  459. package/src/tui.ts +295 -4
  460. package/dist/types/setup/scenes/providers.d.ts +0 -3
  461. package/dist/types/setup/scenes/web-search.d.ts +0 -22
  462. package/src/setup/scenes/providers.ts +0 -110
  463. package/src/setup/scenes/web-search.ts +0 -165
@@ -1,10 +1,6 @@
1
1
  import type { Theme } from "../theme";
2
2
  import type { SeparatorDef, StatusLineSeparatorStyle } from "./types";
3
3
 
4
- function trimSep(value: string): string {
5
- return value.trim();
6
- }
7
-
8
4
  export function getSeparator(style: StatusLineSeparatorStyle, theme: Theme): SeparatorDef {
9
5
  switch (style) {
10
6
  case "powerline":
@@ -17,22 +13,12 @@ export function getSeparator(style: StatusLineSeparatorStyle, theme: Theme): Sep
17
13
  useBgAsFg: true,
18
14
  },
19
15
  };
20
- case "powerline-thin":
21
- return {
22
- left: theme.sep.powerlineThinLeft,
23
- right: theme.sep.powerlineThinRight,
24
- endCaps: {
25
- left: theme.sep.powerlineRight,
26
- right: theme.sep.powerlineLeft,
27
- useBgAsFg: true,
28
- },
29
- };
30
16
  case "slash": {
31
- const slash = trimSep(theme.sep.slash);
17
+ const slash = theme.sep.slash.trim();
32
18
  return { left: slash, right: slash };
33
19
  }
34
20
  case "pipe": {
35
- const pipe = trimSep(theme.sep.pipe);
21
+ const pipe = theme.sep.pipe.trim();
36
22
  return { left: pipe, right: pipe };
37
23
  }
38
24
  case "block":
@@ -41,6 +27,7 @@ export function getSeparator(style: StatusLineSeparatorStyle, theme: Theme): Sep
41
27
  return { left: theme.sep.space, right: theme.sep.space };
42
28
  case "ascii":
43
29
  return { left: theme.sep.asciiLeft, right: theme.sep.asciiRight };
30
+ // "powerline-thin" is also the fallback for unknown styles.
44
31
  default:
45
32
  return {
46
33
  left: theme.sep.powerlineThinLeft,
@@ -1,5 +1,6 @@
1
1
  import type { Model } from "@oh-my-pi/pi-ai";
2
- import type { SessionState } from "@oh-my-pi/pi-wire";
2
+ import type { SessionState, TspSpan, TspTone } from "@oh-my-pi/pi-wire";
3
+ import type { NativeNode, NativeUiEvent } from "../native/node";
3
4
  import type { ContextLineMode, StatusLinePreset, StatusLineSegmentId, StatusLineSeparatorStyle } from "./schema";
4
5
  import type { ActiveRepoContext, StatusLineSession } from "./host";
5
6
  import type { LoopConditionConfig, LoopLimitRuntime } from "./loop";
@@ -203,9 +204,50 @@ export interface RenderedSegment {
203
204
  visible: boolean; // Whether to render (e.g., git hidden when not in repo)
204
205
  }
205
206
 
207
+ /**
208
+ * A segment described for a TSP terminal: styled spans (theme/semantic
209
+ * tokens, no ANSI), a named icon, a tone, and terminal-clocked nodes
210
+ * (`spinner`, `elapsed`, `rate`) laid out after the spans.
211
+ */
212
+ export interface SegmentView {
213
+ readonly spans: readonly TspSpan[];
214
+ readonly icon?: string;
215
+ readonly tone?: TspTone;
216
+ readonly motion?: readonly NativeNode[];
217
+ /** Tooltip on the segment. */
218
+ readonly title?: string;
219
+ }
220
+
221
+ /**
222
+ * The status line's facts for the native composer. A TSP terminal shows no
223
+ * status strip: the tab title carries the session, the pane header the path
224
+ * and branch, and the composer the rest.
225
+ */
226
+ export interface ComposerFacts {
227
+ /** `meter` (role `omp.composer.context`): context usage along the composer's top edge. */
228
+ readonly context: NativeNode;
229
+ /** The model chip's label: name plus the advisor, fast-mode and slow-mode marks. */
230
+ readonly model: SegmentView;
231
+ /**
232
+ * `status` (role `omp.composer.extras`, `grow: 1`) of the other configured
233
+ * segments as `seg`s; the bar's flexible space, so present even when empty.
234
+ */
235
+ readonly extras: NativeNode;
236
+ /** `text` (role `omp.composer.usage`): the context share of the window and the session cost. */
237
+ readonly usage: NativeNode;
238
+ }
239
+
240
+ /** Supplies {@link ComposerFacts} and takes the clicks on them (`status.*` actions). */
241
+ export interface ComposerFactsSource {
242
+ describeComposerFacts(): ComposerFacts;
243
+ handleNativeEvent(event: NativeUiEvent): void;
244
+ }
245
+
206
246
  export interface StatusLineSegment {
207
247
  id: StatusLineSegmentId;
208
248
  render(ctx: SegmentContext): RenderedSegment;
249
+ /** Native description; null when the segment is hidden. */
250
+ describe(ctx: SegmentContext): SegmentView | null;
209
251
  }
210
252
 
211
253
  // ═══════════════════════════════════════════════════════════════════════════
@@ -424,11 +424,11 @@ export class StdinBuffer extends EventEmitter<StdinBufferEventMap> {
424
424
  #rawPasteCandidate = "";
425
425
  #rawPasteTimer?: NodeJS.Timeout;
426
426
  // Unbracketed raw-paste classification is a fallback for terminals that do
427
- // not wrap pastes in DECSET 2004 markers. When the terminal confirms mode
428
- // 2004 support, a genuine paste always arrives bracketed, so the heuristic
429
- // can only misfire on keystrokes an event-loop stall batched into one read
430
- // (issue #12540) — Terminal disables it via `setRawPasteClassification`.
431
- #rawPasteClassificationEnabled = true;
427
+ // not wrap pastes in DECSET 2004 markers. Once the terminal confirms mode
428
+ // 2004, Terminal installs this probe: an unmarked multiline burst is then
429
+ // an input-method commit (#13344) unless an event-loop stall batched the
430
+ // keystrokes into one read (#12540). See `setRawPasteStallProbe`.
431
+ #rawPasteStallProbe?: () => boolean;
432
432
  #stringDiscardActive = false;
433
433
  #stringDiscardBytes = 0;
434
434
  #stringDiscardEscHeld = false;
@@ -491,14 +491,13 @@ export class StdinBuffer extends EventEmitter<StdinBufferEventMap> {
491
491
  } else {
492
492
  this.#rawPasteCandidate += str;
493
493
  if (isRawMultilineBurst(this.#rawPasteCandidate)) {
494
- this.#emitRawPasteCandidate();
494
+ this.#classifyRawPasteCandidate();
495
495
  }
496
496
  return;
497
497
  }
498
498
  }
499
499
 
500
500
  if (
501
- this.#rawPasteClassificationEnabled &&
502
501
  this.#buffer.length === 0 &&
503
502
  str.indexOf(ESC) === -1 &&
504
503
  (str.indexOf("\r") !== -1 || str.indexOf("\n") !== -1)
@@ -508,7 +507,7 @@ export class StdinBuffer extends EventEmitter<StdinBufferEventMap> {
508
507
  // Enter is replayed unchanged when the fixed window expires.
509
508
  this.#rawPasteCandidate = str;
510
509
  if (isRawMultilineBurst(str)) {
511
- this.#emitRawPasteCandidate();
510
+ this.#classifyRawPasteCandidate();
512
511
  } else {
513
512
  this.#armRawPasteTimer();
514
513
  }
@@ -649,18 +648,18 @@ export class StdinBuffer extends EventEmitter<StdinBufferEventMap> {
649
648
  }
650
649
 
651
650
  /**
652
- * Enable or disable unbracketed raw-paste classification. Terminal disables
653
- * it once DECRQM confirms bracketed-paste (mode 2004) support: a genuine
654
- * paste then always arrives wrapped, so the heuristic can only misfire on
655
- * keystrokes an event-loop stall batched into one read (issue #12540).
656
- * Disabling flushes any candidate already held by the classification window
657
- * as ordinary key events so no buffered input is lost.
651
+ * Gate unbracketed raw-paste classification on event-loop responsiveness.
652
+ * Terminal installs a probe once DECRQM confirms bracketed-paste (mode
653
+ * 2004) support: a genuine paste then always arrives wrapped, so an
654
+ * unmarked multiline burst is either an input-method commit — IME,
655
+ * dictation, and emoji commits are typed input, never bracketed (#13344) —
656
+ * or keystrokes an event-loop stall batched into one read (#12540). A burst
657
+ * classified while `stalled()` reports a stall is replayed as the original
658
+ * keys so every Enter submits; otherwise it is delivered as one paste.
659
+ * `undefined` restores unconditional classification.
658
660
  */
659
- setRawPasteClassification(enabled: boolean): void {
660
- this.#rawPasteClassificationEnabled = enabled;
661
- if (!enabled && this.#rawPasteCandidate.length > 0) {
662
- this.#flushRawPasteCandidate();
663
- }
661
+ setRawPasteStallProbe(stalled: (() => boolean) | undefined): void {
662
+ this.#rawPasteStallProbe = stalled;
664
663
  }
665
664
 
666
665
  /** Start one fixed window from the first break-bearing raw read. */
@@ -686,8 +685,15 @@ export class StdinBuffer extends EventEmitter<StdinBufferEventMap> {
686
685
  return content;
687
686
  }
688
687
 
689
- /** Emit a classified raw multiline burst through the paste channel. */
690
- #emitRawPasteCandidate(): void {
688
+ /**
689
+ * Deliver a classified raw multiline burst: one paste, or the original
690
+ * keys when the stall probe says a blocked loop batched typed input.
691
+ */
692
+ #classifyRawPasteCandidate(): void {
693
+ if (this.#rawPasteStallProbe?.()) {
694
+ this.#flushRawPasteCandidate();
695
+ return;
696
+ }
691
697
  const content = this.#takeRawPasteCandidate();
692
698
  this.#pendingKittyPrintableCodepoint = undefined;
693
699
  this.emit("paste", content);
@@ -39,6 +39,7 @@ export type TerminalId =
39
39
  | "orca"
40
40
  | "otty"
41
41
  | "rio"
42
+ | "tern"
42
43
  | "base"
43
44
  | "trueColor";
44
45
 
@@ -698,6 +699,11 @@ const KNOWN_TERMINALS = Object.freeze({
698
699
  // OSC 99, and OSC 66 text sizing are outside rio's supported set and keep
699
700
  // the conservative defaults.
700
701
  rio: new TerminalInfo("rio", ImageProtocol.Kitty, true, true),
702
+ // Tern (Stencil's terminal, `stencil-term`) sets TERM_PROGRAM=tern and
703
+ // implements Kitty graphics, OSC 8 and OSC 9/99 notifications. Whether omp
704
+ // renders natively (Tern Surface Protocol) is decided by the `hello`
705
+ // handshake alone, never by this identity.
706
+ tern: new TerminalInfo("tern", ImageProtocol.Kitty, true, true, NotifyProtocol.Osc99),
701
707
  });
702
708
 
703
709
  /** Resolve terminal identity from environment markers used by common emulators. */
@@ -718,6 +724,7 @@ export function detectTerminalId(env: NodeJS.ProcessEnv = Bun.env): TerminalId {
718
724
  if (caseEq(program, "orca")) return "orca";
719
725
  if (caseEq(program, "otty")) return "otty";
720
726
  if (caseEq(program, "rio")) return "rio";
727
+ if (caseEq(program, "tern")) return "tern";
721
728
  return null;
722
729
  }
723
730
 
package/src/terminal.ts CHANGED
@@ -5,6 +5,7 @@ import { $env, isBunTestRuntime, isTerminalHeadless, isWsl } from "@oh-my-pi/pi-
5
5
  import * as logger from "@oh-my-pi/pi-utils/logger";
6
6
  import * as postmortem from "@oh-my-pi/pi-utils/postmortem";
7
7
  import { restoreTerminalStderr, suppressTerminalStderr } from "@oh-my-pi/pi-utils/stderr-guard";
8
+ import { TSP_VERSION } from "@oh-my-pi/pi-wire";
8
9
  import {
9
10
  encodeBundledGlyphRegistrations,
10
11
  encodeGlyphCoverageQuery,
@@ -14,6 +15,7 @@ import {
14
15
  parseGlyphProtocolReply,
15
16
  } from "./glyph-protocol";
16
17
  import { setKittyProtocolActive } from "./keys";
18
+ import { encodeTspHelloQuery, parseTspMessage, TSP_PREFIX, type TspHello } from "./native/encode";
17
19
  import { StdinBuffer } from "./stdin-buffer";
18
20
  import {
19
21
  isInsideTerminalMultiplexer,
@@ -460,6 +462,15 @@ export interface TerminalStartOptions {
460
462
  * echoes even while module loading blocks the event loop.
461
463
  */
462
464
  deferInput?: boolean;
465
+ /**
466
+ * Reports whether the event loop is stalled or just recovered from a
467
+ * stall. Once the terminal confirms bracketed paste, an unmarked multiline
468
+ * burst is an input-method commit (IME, dictation) delivered as one paste
469
+ * on a responsive loop, but keystrokes a stall batched into one read —
470
+ * replayed as keys so Enter submits — while this returns true. Without a
471
+ * probe every such burst is treated as an input-method commit.
472
+ */
473
+ isLoopStalled?: () => boolean;
463
474
  }
464
475
  /** Identity of an accepted explicit terminal appearance refresh request. */
465
476
  export type TerminalAppearanceRequestToken = number;
@@ -477,6 +488,12 @@ export type PrivateModeReportHandler = (mode: number, supported: boolean, confir
477
488
  * glossary, so a host can safely repaint — or switch to the nerd preset.
478
489
  */
479
490
  export type GlyphProtocolReportHandler = (supported: boolean) => void;
491
+ /**
492
+ * Outcome of the Tern Surface Protocol `hello` probe: the terminal's reply,
493
+ * or null when it answered the DA1 sentinel first (no TSP) or the probe was
494
+ * skipped (`PI_TUI_NATIVE=0`, multiplexers).
495
+ */
496
+ export type TspHelloHandler = (hello: TspHello | null) => void;
480
497
 
481
498
  /**
482
499
  * Cursor shapes addressable via DECSCUSR (`CSI <n> SP q`). `"default"` (0) hands the shape back to
@@ -645,6 +662,23 @@ export interface Terminal {
645
662
  * pi-tui versions keep working.
646
663
  */
647
664
  onGlyphProtocolReport?(callback: GlyphProtocolReportHandler): void;
665
+ /**
666
+ * Register a callback fired once the Tern Surface Protocol `hello` probe
667
+ * resolves (see {@link TspHelloHandler}); a resolved outcome is replayed to
668
+ * late subscribers. TSP events arriving afterwards are delivered through
669
+ * `onInput` as complete `ESC _ tsp;e;… ESC \` strings. Optional so custom
670
+ * Terminals built against older pi-tui versions keep working.
671
+ */
672
+ onTspHello?(callback: TspHelloHandler): void;
673
+ /** True while the `hello` probe awaits its reply or DA1 sentinel. */
674
+ readonly tspProbePending?: boolean;
675
+ /**
676
+ * The environment names a Tern Surface Protocol terminal
677
+ * (`TERM_PROGRAM=tern`) and the `hello` probe will run: the TUI takes input
678
+ * at start and opens its surface before the reply, which then confirms or
679
+ * revokes it.
680
+ */
681
+ readonly tspExpected?: boolean;
648
682
  }
649
683
 
650
684
  /**
@@ -667,7 +701,8 @@ type Da1SentinelOwner =
667
701
  | { kind: "osc11" }
668
702
  | { kind: "privateMode"; mode: number }
669
703
  | { kind: "osc99Probe"; id: string }
670
- | { kind: "glyphProtocol"; phase: "support" | "confirm" };
704
+ | { kind: "glyphProtocol"; phase: "support" | "confirm" }
705
+ | { kind: "tsp" };
671
706
 
672
707
  let nextOsc99ProbeId = 1;
673
708
 
@@ -717,6 +752,7 @@ export class ProcessTerminal implements Terminal {
717
752
  #resizeHandler?: () => void;
718
753
  /** True between a `deferInput` start() and enableInput(). */
719
754
  #inputDeferred = false;
755
+ #isLoopStalled?: () => boolean;
720
756
  #stdoutResizeListener?: () => void;
721
757
  #kittyProtocolActive = false;
722
758
  #kittyEnableSeq: string | null = null;
@@ -803,6 +839,10 @@ export class ProcessTerminal implements Terminal {
803
839
  #glyphProtocolReplyBuffer = "";
804
840
  #glyphProtocolResult: boolean | undefined;
805
841
  #glyphProtocolCallbacks: GlyphProtocolReportHandler[] = [];
842
+ #tspPending = false;
843
+ #tspResult: TspHello | null | undefined;
844
+ #tspCallbacks: TspHelloHandler[] = [];
845
+ #tspReplyBuffer = "";
806
846
  #privateCsiResponseBuffer = "";
807
847
  #da1SentinelOwners: Da1SentinelOwner[] = [];
808
848
  /** Resolved DECRQM support per private mode (mode → supported). */
@@ -914,6 +954,26 @@ export class ProcessTerminal implements Terminal {
914
954
  if (this.#glyphProtocolResult !== undefined) callback(this.#glyphProtocolResult);
915
955
  }
916
956
 
957
+ onTspHello(callback: TspHelloHandler): void {
958
+ this.#tspCallbacks.push(callback);
959
+ if (this.#tspResult !== undefined) callback(this.#tspResult);
960
+ }
961
+
962
+ get tspProbePending(): boolean {
963
+ return this.#tspPending;
964
+ }
965
+
966
+ get tspExpected(): boolean {
967
+ // A multiplexer started from Tern can leave `TERM_PROGRAM=tern` behind
968
+ // while swallowing APC, even when `PI_TUI_NATIVE=1` forces the probe.
969
+ return (
970
+ $env.TERM_PROGRAM?.toLowerCase() === "tern" &&
971
+ !isInsideTerminalMultiplexer($env) &&
972
+ !isTerminalHeadless() &&
973
+ this.#shouldQueryTspSupport()
974
+ );
975
+ }
976
+
917
977
  start(
918
978
  onInput: (data: string) => void,
919
979
  onResize: () => void,
@@ -923,6 +983,7 @@ export class ProcessTerminal implements Terminal {
923
983
  this.#inputHandler = onInput;
924
984
  this.#resizeHandler = onResize;
925
985
  this.#disconnectHandler = onDisconnect;
986
+ this.#isLoopStalled = options?.isLoopStalled;
926
987
  // The host terminal's cursor visibility is unknown until we write it.
927
988
  this.#cursorVisible = undefined;
928
989
 
@@ -1055,6 +1116,10 @@ export class ProcessTerminal implements Terminal {
1055
1116
  // without a patched font installed.
1056
1117
  this.#queryGlyphProtocolSupport();
1057
1118
 
1119
+ // Tern Surface Protocol `hello`, same DA1 sentinel FIFO. A reply switches
1120
+ // the TUI to describing its UI instead of painting rows.
1121
+ this.#queryTspSupport();
1122
+
1058
1123
  // Subscribe to Mode 2031 appearance change notifications.
1059
1124
  // When the terminal reports a change, we re-query OSC 11 to get the
1060
1125
  // actual background color (following Neovim convention) with 100ms debounce.
@@ -1081,9 +1146,10 @@ export class ProcessTerminal implements Terminal {
1081
1146
  this.#queryPrivateMode(2048);
1082
1147
  this.#queryPrivateMode(2031);
1083
1148
  // 2004 (bracketed paste) is queried only to confirm the terminal brackets
1084
- // pastes; once confirmed, the unbracketed raw-paste heuristic in
1085
- // StdinBuffer is disabled so keystrokes an event-loop stall batches into
1086
- // one read are never misclassified as a paste (#12540).
1149
+ // pastes; once confirmed, StdinBuffer's unbracketed raw-paste heuristic
1150
+ // consults the host's stall probe so keystrokes an event-loop stall
1151
+ // batches into one read stay keys (#12540) while input-method commits
1152
+ // still land as one paste (#13344).
1087
1153
  this.#queryPrivateMode(2004);
1088
1154
  for (const mode of XTERM_SCROLL_TO_BOTTOM_MODES) {
1089
1155
  this.#queryPrivateMode(mode);
@@ -1198,7 +1264,8 @@ export class ProcessTerminal implements Terminal {
1198
1264
  this.#inBandResizeBuffer.length === 0 &&
1199
1265
  this.#osc11ResponseBuffer.length === 0 &&
1200
1266
  this.#osc99ResponseBuffer.length === 0 &&
1201
- this.#glyphProtocolReplyBuffer.length === 0
1267
+ this.#glyphProtocolReplyBuffer.length === 0 &&
1268
+ this.#tspReplyBuffer.length === 0
1202
1269
  ) {
1203
1270
  if (this.#inputHandler) {
1204
1271
  this.#inputHandler(sequence);
@@ -1364,6 +1431,11 @@ export class ProcessTerminal implements Terminal {
1364
1431
  if (owner.phase === this.#glyphProtocolPhase) this.#resolveGlyphProtocolSupport(false);
1365
1432
  break;
1366
1433
  }
1434
+ case "tsp": {
1435
+ // DA1 before any `tsp;r` reply: the terminal doesn't speak TSP.
1436
+ this.#resolveTspSupport(null);
1437
+ break;
1438
+ }
1367
1439
  }
1368
1440
  return;
1369
1441
  }
@@ -1448,6 +1520,22 @@ export class ProcessTerminal implements Terminal {
1448
1520
  }
1449
1521
  }
1450
1522
 
1523
+ // Tern Surface Protocol APC (`ESC _ tsp ; … ESC \`): the hello reply
1524
+ // resolves the probe; events go to the input handler whole, where the
1525
+ // TUI routes them to the native backend before key matching.
1526
+ if (this.#tspReplyBuffer || sequence.startsWith(TSP_PREFIX)) {
1527
+ if (this.#tspReplyBuffer && sequence.startsWith("\x1b") && sequence !== "\x1b\\") {
1528
+ this.#tspReplyBuffer = "";
1529
+ } else {
1530
+ this.#tspReplyBuffer += sequence;
1531
+ if (!this.#tspReplyBuffer.endsWith("\x1b\\")) return;
1532
+ const message = this.#tspReplyBuffer;
1533
+ this.#tspReplyBuffer = "";
1534
+ this.#handleTspMessage(message);
1535
+ return;
1536
+ }
1537
+ }
1538
+
1451
1539
  // Glyph Protocol APC replies (`ESC _ 25a1 ; … ESC \`). Swallowed for
1452
1540
  // the whole session, not just while the probe is outstanding: an APC is
1453
1541
  // exclusively terminal->host data, and registrations use `reply=0`, so
@@ -1657,6 +1745,54 @@ export class ProcessTerminal implements Terminal {
1657
1745
  }
1658
1746
  }
1659
1747
 
1748
+ #shouldQueryTspSupport(): boolean {
1749
+ const override = $env.PI_TUI_NATIVE;
1750
+ if (override === "0") return false;
1751
+ if (override === "1") return true;
1752
+ // Multiplexers swallow APC, so the reply could never arrive.
1753
+ if (isInsideTerminalMultiplexer($env)) return false;
1754
+ return !isBunTestRuntime();
1755
+ }
1756
+
1757
+ #queryTspSupport(): void {
1758
+ this.#tspPending = false;
1759
+ this.#tspResult = undefined;
1760
+ this.#tspReplyBuffer = "";
1761
+ if (this.#dead) return;
1762
+ if (!this.#shouldQueryTspSupport()) {
1763
+ this.#tspResult = null;
1764
+ for (const cb of this.#tspCallbacks) cb(null);
1765
+ return;
1766
+ }
1767
+ this.#tspPending = true;
1768
+ this.#da1SentinelOwners.push({ kind: "tsp" });
1769
+ this.#safeWrite(`${encodeTspHelloQuery()}\x1b[c`);
1770
+ }
1771
+
1772
+ #handleTspMessage(sequence: string): void {
1773
+ const message = parseTspMessage(sequence);
1774
+ if (message?.verb === "r") {
1775
+ if (message.reply.r === "hello") this.#resolveTspSupport(message.reply);
1776
+ return;
1777
+ }
1778
+ this.#inputHandler?.(sequence);
1779
+ }
1780
+
1781
+ #resolveTspSupport(hello: TspHello | null): void {
1782
+ if (!this.#tspPending) return;
1783
+ this.#tspPending = false;
1784
+ const result = hello !== null && hello.v === TSP_VERSION ? hello : null;
1785
+ if (hello !== null && result === null) logger.warn("TSP: unsupported protocol version", { v: hello.v });
1786
+ this.#tspResult = result;
1787
+ for (const cb of this.#tspCallbacks) {
1788
+ try {
1789
+ cb(result);
1790
+ } catch (error) {
1791
+ logger.warn("TSP: hello subscriber failed", { error: String(error) });
1792
+ }
1793
+ }
1794
+ }
1795
+
1660
1796
  /** Finish the handshake in either phase and notify subscribers once. */
1661
1797
  #resolveGlyphProtocolSupport(supported: boolean): void {
1662
1798
  if (this.#glyphProtocolPhase === "idle") return;
@@ -1774,15 +1910,17 @@ export class ProcessTerminal implements Terminal {
1774
1910
  }
1775
1911
  if (mode === 2048 && supported) this.#enableInBandResize();
1776
1912
  if (mode === 2031) this.#syncWindowsTerminalAppearancePolling(supported);
1777
- // Confirmed bracketed-paste support makes the unbracketed raw-paste
1778
- // heuristic pure downside — turn it off so stall-batched keystrokes are
1779
- // not misread as a paste (#12540). `supported` is only true here after an
1780
- // explicit DECRPM reply (the DA1-sentinel fallback resolves unsupported).
1913
+ // Confirmed bracketed-paste support means a genuine paste arrives
1914
+ // wrapped, so an unmarked multiline burst is an input-method commit
1915
+ // (#13344) unless an event-loop stall batched typed keys into one read
1916
+ // (#12540). Let the host's stall probe decide per burst. `supported` is
1917
+ // only true here after an explicit DECRPM reply (the DA1-sentinel
1918
+ // fallback resolves unsupported).
1781
1919
  if (mode === 2004 && supported) {
1782
- this.#stdinBuffer?.setRawPasteClassification(false);
1920
+ this.#stdinBuffer?.setRawPasteStallProbe(this.#isLoopStalled);
1783
1921
  // A terminal can reset this mode after the initial probe (for example,
1784
1922
  // iTerm2's Terminal State toggle). Keep the mode asserted while we own
1785
- // the TTY, since the raw fallback is disabled after confirmation.
1923
+ // the TTY, since a stalled loop now replays unmarked bursts as keys.
1786
1924
  this.#bracketedPasteRefreshTimer ??= setInterval(() => {
1787
1925
  if (this.#active && !this.#dead) this.#safeWrite("\x1b[?2004h");
1788
1926
  }, 1000);
@@ -2003,6 +2141,10 @@ export class ProcessTerminal implements Terminal {
2003
2141
  this.#glyphProtocolReplyBuffer = "";
2004
2142
  this.#glyphProtocolCallbacks = [];
2005
2143
  setTerminalGlyphProtocol(false);
2144
+ this.#tspPending = false;
2145
+ this.#tspResult = undefined;
2146
+ this.#tspReplyBuffer = "";
2147
+ this.#tspCallbacks = [];
2006
2148
  this.#privateCsiResponseBuffer = "";
2007
2149
  this.#inBandResizeBuffer = "";
2008
2150
  this.#da1SentinelOwners.length = 0;
@@ -0,0 +1,100 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/theme-schema.json",
3
+ "name": "dark-neon-noir",
4
+ "vars": {
5
+ "magenta": "#ff2bd6",
6
+ "hotMagenta": "#ff4f9a",
7
+ "deepMagenta": "#8f1a78",
8
+ "cyan": "#00e5ff",
9
+ "paleCyan": "#8ff4ff",
10
+ "deepCyan": "#0a6f80",
11
+ "violet": "#a35cff",
12
+ "amber": "#ffc857",
13
+ "ash": "#d8d8e0",
14
+ "smoke": "#8a8a96",
15
+ "soot": "#4a4a55",
16
+ "black": "#050507",
17
+ "panelBg": "#0d0d12",
18
+ "selectedBg": "#1c0b1c",
19
+ "userMsgBg": "#0b1418",
20
+ "toolPendingBg": "#0d0d12",
21
+ "toolSuccessBg": "#06141a",
22
+ "toolErrorBg": "#1f0612",
23
+ "customMsgBg": "#140a18"
24
+ },
25
+ "colors": {
26
+ "accent": "magenta",
27
+ "border": "deepMagenta",
28
+ "borderAccent": "cyan",
29
+ "borderMuted": "soot",
30
+ "success": "cyan",
31
+ "error": "hotMagenta",
32
+ "warning": "amber",
33
+ "muted": "smoke",
34
+ "dim": "soot",
35
+ "text": "",
36
+ "thinkingText": "smoke",
37
+ "selectedBg": "selectedBg",
38
+ "userMessageBg": "userMsgBg",
39
+ "userMessageText": "",
40
+ "customMessageBg": "customMsgBg",
41
+ "customMessageText": "",
42
+ "customMessageLabel": "magenta",
43
+ "toolPendingBg": "toolPendingBg",
44
+ "toolSuccessBg": "toolSuccessBg",
45
+ "toolErrorBg": "toolErrorBg",
46
+ "toolText": "",
47
+ "toolTitle": "",
48
+ "toolOutput": "smoke",
49
+ "mdHeading": "magenta",
50
+ "mdLink": "cyan",
51
+ "mdLinkUrl": "deepCyan",
52
+ "mdCode": "paleCyan",
53
+ "mdCodeBlock": "ash",
54
+ "mdCodeBlockBorder": "deepMagenta",
55
+ "mdQuote": "smoke",
56
+ "mdQuoteBorder": "deepMagenta",
57
+ "mdHr": "soot",
58
+ "mdListBullet": "magenta",
59
+ "toolDiffAdded": "cyan",
60
+ "toolDiffRemoved": "hotMagenta",
61
+ "toolDiffContext": "smoke",
62
+ "link": "cyan",
63
+ "syntaxComment": "soot",
64
+ "syntaxKeyword": "magenta",
65
+ "syntaxFunction": "cyan",
66
+ "syntaxVariable": "ash",
67
+ "syntaxString": "paleCyan",
68
+ "syntaxNumber": "amber",
69
+ "syntaxType": "violet",
70
+ "syntaxOperator": "hotMagenta",
71
+ "syntaxPunctuation": "smoke",
72
+ "thinkingOff": "soot",
73
+ "thinkingMinimal": "smoke",
74
+ "thinkingLow": "deepCyan",
75
+ "thinkingMedium": "cyan",
76
+ "thinkingHigh": "magenta",
77
+ "thinkingXhigh": "hotMagenta",
78
+ "bashMode": "cyan",
79
+ "statusLineBg": "black",
80
+ "statusLineSep": 238,
81
+ "statusLineModel": "magenta",
82
+ "statusLinePath": "cyan",
83
+ "statusLineGitClean": "cyan",
84
+ "statusLineGitDirty": "amber",
85
+ "statusLineContext": "violet",
86
+ "statusLineSpend": "ash",
87
+ "statusLineStaged": "cyan",
88
+ "statusLineDirty": "amber",
89
+ "statusLineUntracked": "hotMagenta",
90
+ "statusLineOutput": "magenta",
91
+ "statusLineCost": "paleCyan",
92
+ "statusLineSubagents": "magenta",
93
+ "pythonMode": "amber"
94
+ },
95
+ "export": {
96
+ "pageBg": "#050507",
97
+ "cardBg": "#0d0d12",
98
+ "infoBg": "#1c0b1c"
99
+ }
100
+ }
@@ -25,6 +25,7 @@ import dark_midnight from "./dark-midnight.json" with { type: "json" };
25
25
  import dark_monochrome from "./dark-monochrome.json" with { type: "json" };
26
26
  import dark_monokai from "./dark-monokai.json" with { type: "json" };
27
27
  import dark_nebula from "./dark-nebula.json" with { type: "json" };
28
+ import dark_neon_noir from "./dark-neon-noir.json" with { type: "json" };
28
29
  import dark_nord from "./dark-nord.json" with { type: "json" };
29
30
  import dark_ocean from "./dark-ocean.json" with { type: "json" };
30
31
  import dark_one from "./dark-one.json" with { type: "json" };
@@ -126,6 +127,7 @@ export const defaultThemes = {
126
127
  "dark-monochrome": dark_monochrome,
127
128
  "dark-monokai": dark_monokai,
128
129
  "dark-nebula": dark_nebula,
130
+ "dark-neon-noir": dark_neon_noir,
129
131
  "dark-nord": dark_nord,
130
132
  "dark-ocean": dark_ocean,
131
133
  "dark-one": dark_one,
@@ -25,7 +25,7 @@
25
25
  "muted": "slate",
26
26
  "dim": "dim",
27
27
  "text": "",
28
- "thinkingText": "muted",
28
+ "thinkingText": "slate",
29
29
  "selectedBg": "#f2f5fb",
30
30
  "userMessageBg": "#ffffff",
31
31
  "userMessageText": "",
@@ -36,20 +36,20 @@
36
36
  "toolSuccessBg": "#effaf2",
37
37
  "toolErrorBg": "#fceeee",
38
38
  "toolTitle": "",
39
- "toolOutput": "muted",
39
+ "toolOutput": "slate",
40
40
  "mdHeading": "indigo",
41
41
  "mdLink": "blue",
42
42
  "mdLinkUrl": "dim",
43
43
  "mdCode": "violet",
44
44
  "mdCodeBlock": "slate",
45
45
  "mdCodeBlockBorder": "#e1e4ea",
46
- "mdQuote": "muted",
46
+ "mdQuote": "slate",
47
47
  "mdQuoteBorder": "#e1e4ea",
48
48
  "mdHr": "#e1e4ea",
49
49
  "mdListBullet": "cyan",
50
50
  "toolDiffAdded": "green",
51
51
  "toolDiffRemoved": "red",
52
- "toolDiffContext": "muted",
52
+ "toolDiffContext": "slate",
53
53
  "syntaxComment": "dim",
54
54
  "syntaxKeyword": "indigo",
55
55
  "syntaxFunction": "blue",
@@ -72,7 +72,7 @@
72
72
  "statusLinePath": "blue",
73
73
  "statusLineGitClean": "green",
74
74
  "statusLineGitDirty": "orange",
75
- "statusLineContext": "muted",
75
+ "statusLineContext": "slate",
76
76
  "statusLineSpend": "cyan",
77
77
  "statusLineStaged": "green",
78
78
  "statusLineDirty": "orange",