@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
@@ -0,0 +1,292 @@
1
+ /**
2
+ * Shared pieces of the tool renderers' TSP describe hooks: result text,
3
+ * card heads, error views, notes and notices. No layout: every helper returns
4
+ * semantic nodes/spans only, with ANSI-free, sanitized text.
5
+ */
6
+ import * as path from "node:path";
7
+ import { pathToFileURL } from "node:url";
8
+ import type { TspSpan, TspText, TspTone } from "@oh-my-pi/pi-wire";
9
+ import { code, keyed, node, row, span, text } from "../native/describe";
10
+ import type { NativeChild, NativeNode } from "../native/node";
11
+ import { type ParsedDiagnostic, parseDiagnosticMessage, shortenPath } from "../render/render-utils";
12
+ import { plainText } from "../native/spans";
13
+ import type { FileDiagnosticsResult } from "./lsp";
14
+ import { formatArtifactErrorNotice, formatTruncationMetaNotice, type OutputMeta } from "./output-meta";
15
+ import type { NativeToolHead, NativeToolView, ToolRenderResult } from "./renderer";
16
+
17
+ /** A path for native heads: relative to the working directory when inside it, else `~`-shortened. */
18
+ export function displayPath(filePath: string): string {
19
+ if (path.isAbsolute(filePath)) {
20
+ const rel = path.relative(process.cwd(), filePath);
21
+ if (rel && !rel.startsWith("..") && !path.isAbsolute(rel)) return rel;
22
+ }
23
+ return shortenPath(filePath);
24
+ }
25
+
26
+ /** `file://` link for a head's path target, when the path is absolute. */
27
+ export function fileHref(filePath: string | undefined): string | undefined {
28
+ return filePath && path.isAbsolute(filePath) ? pathToFileURL(filePath).href : undefined;
29
+ }
30
+
31
+ /** Diff stats as one head `meta` string, `+8 −1` (U+2212 minus), or undefined when nothing changed. */
32
+ export function diffStatsMeta(added: number, removed: number): string | undefined {
33
+ const parts: string[] = [];
34
+ if (added > 0) parts.push(`+${added}`);
35
+ if (removed > 0) parts.push(`\u2212${removed}`);
36
+ return parts.length > 0 ? parts.join(" ") : undefined;
37
+ }
38
+
39
+ /**
40
+ * One file of a multi-file edit: a borderless `section` headed by the path
41
+ * (→ rename) and its `+a −d`, over the file's body (its diff, diagnostics).
42
+ */
43
+ export function fileDiffSection(
44
+ file: { path: string; rename?: string; added?: number; removed?: number },
45
+ body: readonly NativeChild[],
46
+ p: { role: string; tone?: TspTone },
47
+ ): NativeNode {
48
+ const head: TspSpan[] = [span(displayPath(file.path), "path")];
49
+ if (file.rename) head.push(span(" → ", "muted"), span(displayPath(file.rename), "path"));
50
+ if (file.added) head.push(span(` +${file.added}`, "ins"));
51
+ if (file.removed) head.push(span(` \u2212${file.removed}`, "del"));
52
+ return node("section", { head, role: p.role, tone: p.tone }, body, file.path);
53
+ }
54
+
55
+ /**
56
+ * One 22px file row (role `omp.tool.file`) for read groups, grep files, glob
57
+ * lists and find hits: a leading glyph (the file icon unless `lead` replaces
58
+ * it), the path with a dim directory and a strong name (cut in the middle),
59
+ * a quiet `range` suffix (`:13-36`), then an optional count `chip` and a
60
+ * muted `detail`.
61
+ */
62
+ export function fileRow(
63
+ filePath: string,
64
+ p: {
65
+ range?: string;
66
+ chip?: { text: string; title?: string };
67
+ detail?: TspText;
68
+ href?: string;
69
+ lead?: NativeNode;
70
+ icon?: string;
71
+ tone?: TspTone;
72
+ title?: string;
73
+ key?: string;
74
+ } = {},
75
+ ): NativeNode {
76
+ const isDir = filePath.endsWith("/");
77
+ const bare = isDir ? filePath.slice(0, -1) : filePath;
78
+ const cut = bare.lastIndexOf("/") + 1;
79
+ const spans: TspSpan[] = [];
80
+ if (cut > 0) spans.push(span(bare.slice(0, cut), "dim"));
81
+ spans.push(span(`${bare.slice(cut) || "…"}${isDir ? "/" : ""}`, "strong", p.href ? { href: p.href } : undefined));
82
+ if (p.range) spans.push(span(p.range, "muted"));
83
+ const children: NativeChild[] = [
84
+ p.lead ?? node("icon", { name: p.icon ?? (isDir ? "folder" : "file"), tone: p.tone }),
85
+ text(spans, { lines: 1, truncate: "middle", shrink: 1, title: p.title ?? filePath }),
86
+ ];
87
+ if (p.chip) children.push(node("badge", { text: p.chip.text, title: p.chip.title }));
88
+ if (p.detail !== undefined) {
89
+ const detail = typeof p.detail === "string" ? [span(plainText(p.detail), "muted")] : p.detail;
90
+ children.push(text(detail, { lines: 1, truncate: "end", shrink: 1 }));
91
+ }
92
+ return keyed(row(children, { role: "omp.tool.file", tone: p.tone }), p.key ?? filePath);
93
+ }
94
+
95
+ /** Longest error excerpt an inline head carries before the body takes the full message. */
96
+ const ERROR_GIST_CHARS = 120;
97
+
98
+ /**
99
+ * Inline error view (§7.3 read error): error tone, the message's first line
100
+ * after `—` in the head's meta, so a collapsed inline call never hides it,
101
+ * and the full message as the body only when the head had to cut it short.
102
+ */
103
+ export function inlineErrorView(head: NativeToolHead, message: string): NativeToolView {
104
+ const full = plainText(message).trim() || "failed";
105
+ const first = full.split("\n", 1)[0]!.trim();
106
+ const gist = first.length > ERROR_GIST_CHARS ? `${first.slice(0, ERROR_GIST_CHARS - 1)}…` : first;
107
+ return {
108
+ tool: { ...head, meta: [...(head.meta ?? []), [span(`— ${gist}`, "muted")]] },
109
+ tone: "error",
110
+ inline: true,
111
+ body: gist === full ? undefined : [errorText(full)],
112
+ };
113
+ }
114
+
115
+ /** Text blocks of a tool result joined by newlines, or `""`. */
116
+ export function resultText(result: ToolRenderResult<unknown>): string {
117
+ let out = "";
118
+ for (const block of result.content ?? []) {
119
+ if (block.type === "text" && typeof block.text === "string") out += out ? `\n${block.text}` : block.text;
120
+ }
121
+ return out;
122
+ }
123
+
124
+ /**
125
+ * Card head: the bold `toolTitle` title, then detail spans; string details
126
+ * become muted plain text, empty details are skipped.
127
+ */
128
+ export function toolHead(title: string, ...details: readonly (TspSpan | string | undefined)[]): TspSpan[] {
129
+ const spans: TspSpan[] = [span(title, "toolTitle strong")];
130
+ for (const detail of details) {
131
+ if (detail === undefined) continue;
132
+ const value = typeof detail === "string" ? span(plainText(detail), "muted") : detail;
133
+ if (!value.t) continue;
134
+ spans.push(span(" "), value);
135
+ }
136
+ return spans;
137
+ }
138
+
139
+ /** Error body: wrapped error text, or a JSON `code` block when the message is structured. */
140
+ export function errorText(message: string): NativeNode {
141
+ const body = plainText(message).trim();
142
+ return body.includes("\n") && /^[{[]/.test(body)
143
+ ? code(body, { lang: "json", tone: "error", role: "omp.tool.error" })
144
+ : text([span(body, "error")], { wrap: "word", role: "omp.tool.error" });
145
+ }
146
+
147
+ /** Error card view: error tone, the tool head and the error body (`<title> failed` when empty). */
148
+ export function errorView(title: string, message: string, ...meta: readonly (string | undefined)[]): NativeToolView {
149
+ return {
150
+ head: toolHead(title, ...meta),
151
+ tone: "error",
152
+ body: [errorText(plainText(message).trim() || `${title} failed`)],
153
+ };
154
+ }
155
+
156
+ /** Wrapped placeholder or secondary line (`(no output)`, `No matches`, …); `lines` clamps it. */
157
+ export function noteText(message: string, token = "muted", lines?: number): NativeNode {
158
+ return text([span(plainText(message), token)], lines === undefined ? { wrap: "word" } : { wrap: "word", lines });
159
+ }
160
+
161
+ /** Muted `a · b · c` metadata line, or undefined when there are no parts. */
162
+ export function statsText(parts: readonly string[]): NativeNode | undefined {
163
+ if (parts.length === 0) return undefined;
164
+ return text([span(parts.join(" · "), "muted")], { wrap: "word", role: "omp.tool.stats" });
165
+ }
166
+
167
+ /** Warning line for truncation / artifact capture failures, or undefined. */
168
+ export function truncationNotice(meta: OutputMeta | undefined): NativeNode | undefined {
169
+ if (!meta?.truncation && !meta?.artifactError) return undefined;
170
+ const parts: string[] = [];
171
+ if (meta.truncation) parts.push(formatTruncationMetaNotice(meta.truncation, meta.source));
172
+ if (meta.artifactError) parts.push(formatArtifactErrorNotice(meta.artifactError));
173
+ return text([span(parts.join(". "), "warning")], { wrap: "word", role: "omp.tool.notice" });
174
+ }
175
+
176
+ /**
177
+ * The one final quiet line of a tool body (§7.2): `a · b` facts, then any
178
+ * truncation / artifact-capture notice from `meta`; undefined when empty.
179
+ */
180
+ export function footnoteText(parts: readonly string[], meta?: OutputMeta): NativeNode | undefined {
181
+ const all = parts.map(part => plainText(part)).filter(part => part.length > 0);
182
+ if (meta?.truncation) all.push(formatTruncationMetaNotice(meta.truncation, meta.source));
183
+ if (meta?.artifactError) all.push(formatArtifactErrorNotice(meta.artifactError));
184
+ if (all.length === 0) return undefined;
185
+ const notice = meta?.truncation !== undefined || meta?.artifactError !== undefined;
186
+ return {
187
+ ...text([span(all.join(" · "), "muted")], { wrap: "word", role: notice ? "omp.tool.notice" : "omp.tool.stats" }),
188
+ key: "foot",
189
+ };
190
+ }
191
+
192
+ /** Diagnostic rows shown before `+N more`. */
193
+ const DIAGNOSTIC_ROWS = 5;
194
+
195
+ const SEVERITY_RANK: Record<ParsedDiagnostic["severity"], number> = { error: 0, warning: 1, info: 2, hint: 3 };
196
+ const SEVERITY_ICON: Record<ParsedDiagnostic["severity"], string> = {
197
+ error: "x-circle",
198
+ warning: "warn",
199
+ info: "info",
200
+ hint: "lightbulb",
201
+ };
202
+ const SEVERITY_TONE: Record<ParsedDiagnostic["severity"], TspTone> = {
203
+ error: "error",
204
+ warning: "warning",
205
+ info: "info",
206
+ hint: "muted",
207
+ };
208
+
209
+ /** A diagnostic's severity glyph: `x-circle` error, `warn` warning, `info`, `lightbulb` hint, in the severity tone. */
210
+ export function diagnosticGlyph(severity: ParsedDiagnostic["severity"]): NativeNode {
211
+ return node("icon", { name: SEVERITY_ICON[severity] ?? "warn", tone: SEVERITY_TONE[severity], aria: severity });
212
+ }
213
+
214
+ /** One diagnostic row: severity icon · `line:col` (with the file when `withPath`) · message and source. */
215
+ function diagnosticRow(diagnostic: ParsedDiagnostic, withPath: boolean, key: string): NativeNode {
216
+ const where = `${withPath ? `${displayPath(diagnostic.filePath)}:` : ""}${diagnostic.line}:${diagnostic.col}`;
217
+ const message: TspSpan[] = [span(diagnostic.message)];
218
+ const source = [diagnostic.source, diagnostic.code].filter(Boolean).join(" ");
219
+ if (source) message.push(span(` ${source}`, "muted"));
220
+ return row(
221
+ [
222
+ node("icon", {
223
+ name: SEVERITY_ICON[diagnostic.severity] ?? "warn",
224
+ tone: SEVERITY_TONE[diagnostic.severity],
225
+ aria: diagnostic.severity,
226
+ }),
227
+ text([span(where, "muted")], { wrap: "none" }),
228
+ text(message, { wrap: "word" }),
229
+ ],
230
+ { role: "omp.tool.diagnostic", key },
231
+ );
232
+ }
233
+
234
+ /**
235
+ * LSP diagnostics section for write/edit results: rows of severity icon ·
236
+ * `line:col` · message, most severe first, capped at five with `+N more`.
237
+ * Rows name the file too when the messages span several files (or `withPath`).
238
+ * Undefined when there is nothing to show.
239
+ */
240
+ export function diagnosticsSection(
241
+ diagnostics: FileDiagnosticsResult | undefined,
242
+ opts?: { withPath?: boolean },
243
+ ): NativeNode | undefined {
244
+ if (!diagnostics || diagnostics.messages.length === 0) return undefined;
245
+ const parsed: ParsedDiagnostic[] = [];
246
+ const unparsed: string[] = [];
247
+ for (const message of diagnostics.messages) {
248
+ const diagnostic = parseDiagnosticMessage(plainText(message).trim());
249
+ if (diagnostic) parsed.push(diagnostic);
250
+ else if (message.trim()) unparsed.push(plainText(message).trim());
251
+ }
252
+ parsed.sort(
253
+ (a, b) => (SEVERITY_RANK[a.severity] ?? 4) - (SEVERITY_RANK[b.severity] ?? 4) || a.line - b.line || a.col - b.col,
254
+ );
255
+ const withPath = opts?.withPath === true || new Set(parsed.map(d => d.filePath)).size > 1;
256
+ const rows: NativeNode[] = [
257
+ ...parsed.map((d, i) => diagnosticRow(d, withPath, `d${i}`)),
258
+ ...unparsed.map((message, i) =>
259
+ text([span(message)], { wrap: "word", role: "omp.tool.diagnostic", key: `u${i}` }),
260
+ ),
261
+ ];
262
+ const shown = rows.slice(0, DIAGNOSTIC_ROWS);
263
+ const hidden = rows.length - shown.length;
264
+ if (hidden > 0) {
265
+ shown.push(text([span(`+${hidden} more`, "muted")], { role: "omp.tool.stats", key: "more" }));
266
+ }
267
+ return node(
268
+ "section",
269
+ {
270
+ head: [span("Diagnostics")],
271
+ tone: diagnostics.errored ? "error" : "warning",
272
+ role: "omp.tool.diagnostics",
273
+ },
274
+ shown,
275
+ "diagnostics",
276
+ );
277
+ }
278
+
279
+ /** Head chip counting LSP diagnostics across files (`2 diagnostics`), or undefined when there are none. */
280
+ export function diagnosticsBadge(
281
+ files: readonly (FileDiagnosticsResult | undefined)[],
282
+ ): { text: string; tone: TspTone } | undefined {
283
+ let count = 0;
284
+ let errored = false;
285
+ for (const file of files) {
286
+ if (!file) continue;
287
+ count += file.messages.length;
288
+ errored ||= file.errored;
289
+ }
290
+ if (count === 0) return undefined;
291
+ return { text: count === 1 ? "1 diagnostic" : `${count} diagnostics`, tone: errored ? "error" : "warning" };
292
+ }
@@ -11,7 +11,11 @@ import {
11
11
  type ToolUIColor,
12
12
  } from "../render/render-utils";
13
13
  import type { Theme } from "../theme/theme";
14
- import type { RenderResultOptions } from "./renderer";
14
+ import type { NativeToolView, RenderResultOptions } from "./renderer";
15
+ import type { TspSpan, TspTone } from "@oh-my-pi/pi-wire";
16
+ import { ansi, compact, node, span, text } from "../native/describe";
17
+ import type { NativeChild, NativeNode } from "../native/node";
18
+ import { errorText, noteText, toolHead } from "./native-view";
15
19
  import type { AgentActivitySnapshot, CoordinationDetails, JobSnapshot } from "./wait";
16
20
  import type { IrcDeliveryReceipt } from "./irc";
17
21
  import type { DaemonSnapshot } from "./daemon";
@@ -268,3 +272,219 @@ export function renderProcRead(
268
272
  ];
269
273
  }, options);
270
274
  }
275
+
276
+ // =============================================================================
277
+ // Native (TSP) views
278
+ // =============================================================================
279
+
280
+ function daemonMetaText(daemon: DaemonSnapshot): string {
281
+ const meta: string[] = [daemon.state];
282
+ if (daemon.pid !== undefined) meta.push(`pid ${daemon.pid}`);
283
+ meta.push(
284
+ `${daemon.exitedAt === undefined ? "up" : "ran"} ${formatDuration(Math.max(0, (daemon.exitedAt ?? Date.now()) - daemon.startedAt))}`,
285
+ );
286
+ if (daemon.detached) meta.push("detached");
287
+ else if (daemon.persist) meta.push("persistent");
288
+ return meta.join(" · ");
289
+ }
290
+
291
+ function jobTone(status: JobSnapshot["status"]): TspTone {
292
+ return status === "failed"
293
+ ? "error"
294
+ : status === "cancelled"
295
+ ? "warning"
296
+ : status === "running"
297
+ ? "info"
298
+ : "success";
299
+ }
300
+
301
+ function jobItem(job: JobSnapshot, badge?: { text: string; tone: TspTone }): NativeNode {
302
+ return node(
303
+ "item",
304
+ {
305
+ label: [span(job.type, "accent"), span(" "), span(safe(job.id), "toolOutput")],
306
+ detail: [span(safe(job.label), "muted")],
307
+ value: badge ? [span(badge.text, badge.tone)] : [span(formatDuration(job.durationMs), "muted")],
308
+ tone: badge?.tone ?? jobTone(job.status),
309
+ },
310
+ undefined,
311
+ job.id,
312
+ );
313
+ }
314
+
315
+ function quotedPreview(body: string, tone = "muted"): NativeNode | undefined {
316
+ if (!body.trim()) return undefined;
317
+ return text([span(body, tone)], { wrap: "word", role: "omp.tool.proc.preview" });
318
+ }
319
+
320
+ const RECEIPT_TONE: Record<IrcDeliveryReceipt["outcome"], TspTone> = {
321
+ injected: "success",
322
+ woken: "success",
323
+ revived: "warning",
324
+ failed: "error",
325
+ };
326
+
327
+ /** TSP view of an `agent://` write (IRC message). */
328
+ export function describeAgentWrite(
329
+ to: string,
330
+ body: string,
331
+ result: ToolResult | undefined,
332
+ details: CoordinationDetails | undefined,
333
+ ): NativeToolView {
334
+ const recipient = safe(details?.to || to || "…");
335
+ const receipts = details?.receipts ?? [];
336
+ const delivered = receipts.filter(receipt => receipt.outcome !== "failed").length;
337
+ const failed = receipts.length - delivered;
338
+ const meta: TspSpan[] = [];
339
+ if (recipient === "all") meta.push(span("broadcast", "muted"));
340
+ if (receipts.length === 1) meta.push(span(receipts[0]!.outcome, RECEIPT_TONE[receipts[0]!.outcome]));
341
+ else if (receipts.length > 1) {
342
+ if (delivered) meta.push(span(`${delivered} delivered`, "success"));
343
+ if (failed) meta.push(span(`${failed} failed`, "error"));
344
+ }
345
+ const head = toolHead("IRC", span(recipient, "accent"), ...meta);
346
+ const error = result?.isError === true || (failed > 0 && delivered === 0);
347
+ if (result?.isError && receipts.length === 0) {
348
+ return { head, tone: "error", body: [errorText(firstText(result) || "Message delivery failed.")] };
349
+ }
350
+ const children = compact<NativeChild>([
351
+ quotedPreview(body),
352
+ result !== undefined && receipts.length === 0 && noteText(firstText(result) || "No live peers to broadcast to."),
353
+ (receipts.length > 1 || failed > 0) &&
354
+ node(
355
+ "list",
356
+ { role: "omp.tool.irc.receipts" },
357
+ receipts.map(receipt =>
358
+ node(
359
+ "item",
360
+ {
361
+ label: [span(safe(receipt.to), "toolOutput")],
362
+ value: [span(receipt.outcome, RECEIPT_TONE[receipt.outcome])],
363
+ detail: receipt.error ? [span(safe(receipt.error), "error")] : undefined,
364
+ tone: RECEIPT_TONE[receipt.outcome],
365
+ },
366
+ undefined,
367
+ receipt.to,
368
+ ),
369
+ ),
370
+ ),
371
+ ]);
372
+ return { head, tone: error ? "error" : undefined, body: children };
373
+ }
374
+
375
+ /** TSP view of a `proc://` write (stdin, mode change, kill). */
376
+ export function describeProcWrite(
377
+ id: string,
378
+ action: ProcWriteAction,
379
+ content: string | undefined,
380
+ result: ToolResult | undefined,
381
+ details: ProcWriteDetails | undefined,
382
+ ): NativeToolView {
383
+ const daemon = details && "daemon" in details ? details.daemon : undefined;
384
+ const head = toolHead(
385
+ `Proc ${action}`,
386
+ span(safe(id || "…"), "accent"),
387
+ daemon ? daemonMetaText(daemon) : action === "mode" && content ? safe(content) : undefined,
388
+ );
389
+ if (result?.isError) {
390
+ return { head, tone: "error", body: [errorText(firstText(result) || "Process operation failed.")] };
391
+ }
392
+ const body = compact<NativeChild>([content && action === "stdin" ? quotedPreview(content) : undefined]);
393
+ if (details && "op" in details && details.op === "cancel") {
394
+ const jobs = details.jobs ?? [];
395
+ body.push(
396
+ node(
397
+ "list",
398
+ { role: "omp.tool.proc.cancelled" },
399
+ (details.cancelled ?? []).map(outcome => {
400
+ const job = jobs.find(item => item.id === outcome.id);
401
+ const badge = {
402
+ text: outcome.status,
403
+ tone: outcome.status === "cancelled" ? "warning" : "error",
404
+ } as const;
405
+ return job
406
+ ? jobItem(job, badge)
407
+ : node(
408
+ "item",
409
+ { label: [span(safe(outcome.id), "toolOutput")], value: [span(badge.text, badge.tone)] },
410
+ undefined,
411
+ outcome.id,
412
+ );
413
+ }),
414
+ ),
415
+ );
416
+ }
417
+ return { head, tone: result !== undefined && action === "kill" ? "warning" : undefined, body };
418
+ }
419
+
420
+ /** TSP view of a `proc://` read: job/service detail, logs, or the process table. */
421
+ export function describeProcRead(
422
+ id: string,
423
+ result: ToolResult | undefined,
424
+ details: ProcReadDetails | undefined,
425
+ ): NativeToolView {
426
+ const daemon = details?.daemon;
427
+ const title = id ? "Proc" : "Proc jobs & services";
428
+ const head = toolHead(title, id ? span(safe(id), "accent") : undefined, daemon ? daemonMetaText(daemon) : undefined);
429
+ if (result?.isError) {
430
+ return { head, tone: "error", body: [errorText(firstText(result) || "Process read failed.")] };
431
+ }
432
+ if (!result) return { head };
433
+ if (details?.job) {
434
+ const log = details.log ?? details.job.errorText ?? details.job.resultText ?? "";
435
+ return {
436
+ head,
437
+ body: compact<NativeChild>([
438
+ node("list", {}, [jobItem(details.job)]),
439
+ log.trim().length > 0 && ansi(log, { role: "omp.tool.proc.log" }),
440
+ ]),
441
+ };
442
+ }
443
+ if (daemon) {
444
+ const output = details.terminalRows?.join("\n") ?? details.log ?? "";
445
+ return { head, body: [ansi(output, { follow: daemon.exitedAt === undefined, role: "omp.tool.proc.log" })] };
446
+ }
447
+ if (id && !details?.jobs && !details?.daemons && !details?.agents) {
448
+ return { head, body: compact<NativeChild>([quotedPreview(firstText(result), "toolOutput")]) };
449
+ }
450
+ const jobs = details?.jobs ?? [];
451
+ const services = details?.daemons ?? [];
452
+ const agents = details?.agents ?? [];
453
+ const items: NativeNode[] = [
454
+ ...jobs.map(job => jobItem(job)),
455
+ ...services.map(service =>
456
+ node(
457
+ "item",
458
+ {
459
+ label: [span("service", "accent"), span(" "), span(safe(service.name), "toolOutput")],
460
+ detail: [span(daemonMetaText(service), "muted")],
461
+ tone:
462
+ service.state === "failed"
463
+ ? "error"
464
+ : service.state === "ready" || service.state === "running"
465
+ ? "success"
466
+ : "warning",
467
+ },
468
+ undefined,
469
+ `service:${service.name}`,
470
+ ),
471
+ ),
472
+ ...agents.map(agent =>
473
+ node(
474
+ "item",
475
+ {
476
+ label: [span("agent", agent.live ? "accent" : "warning"), span(" "), span(safe(agent.id), "toolOutput")],
477
+ value: [span(formatDuration(agent.ageMs), "muted")],
478
+ },
479
+ undefined,
480
+ `agent:${agent.id}`,
481
+ ),
482
+ ),
483
+ ];
484
+ const counts = [`${jobs.length} jobs`, `${services.length} services`];
485
+ if (agents.length) counts.push(`${agents.length} agents`);
486
+ return {
487
+ head: toolHead(title, id ? span(safe(id), "accent") : undefined, counts.join(" · ")),
488
+ body: [node("list", { empty: "No background jobs or services.", role: "omp.tool.proc.table" }, items)],
489
+ };
490
+ }