@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
package/src/tools/eval.ts CHANGED
@@ -1,7 +1,18 @@
1
1
  import type { Component } from "../index";
2
2
  import { Markdown, Text } from "../index";
3
3
  import { sanitizeText } from "@oh-my-pi/pi-utils";
4
- import type { RenderResultOptions, ToolRenderer } from "./renderer";
4
+ import type {
5
+ NativeToolHead,
6
+ NativeToolView,
7
+ RenderResultContextOptions,
8
+ RenderResultOptions,
9
+ ToolRenderer,
10
+ } from "./renderer";
11
+ import type { TspSpan } from "@oh-my-pi/pi-wire";
12
+ import { ansi, code as codeNode, compact, keyed, md, node, span, text } from "../native/describe";
13
+ import type { NativeChild, NativeNode } from "../native/node";
14
+ import { plainText } from "../native/spans";
15
+ import { footnoteText, resultText } from "./native-view";
5
16
  import { renderAgentTreeRow } from "./agent-tree";
6
17
  import { truncateToVisualLines } from "../chrome/visual-truncate";
7
18
  import { getMarkdownTheme, type Theme } from "../theme/theme";
@@ -15,6 +26,7 @@ import {
15
26
  JSON_TREE_MAX_LINES_EXPANDED,
16
27
  JSON_TREE_SCALAR_LEN_COLLAPSED,
17
28
  JSON_TREE_SCALAR_LEN_EXPANDED,
29
+ describeJsonTree,
18
30
  renderJsonTreeLines,
19
31
  } from "./json-tree";
20
32
  import { formatStyledTruncationWarning, stripOutputNotice } from "./output-meta";
@@ -546,6 +558,161 @@ function formatCellOutputLines(
546
558
  return { lines: formatted.lines, hiddenCount: formatted.hiddenCount };
547
559
  }
548
560
 
561
+ /** Plain one-line summary of a status event: op plus its scalar fields. */
562
+ function describeStatusEvent(event: EvalStatusEvent): NativeNode {
563
+ const spans: TspSpan[] = [span(event.op, "accent")];
564
+ for (const key in event) {
565
+ if (key === "op" || key === "resolvedThinkingLevel") continue;
566
+ const value = event[key];
567
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
568
+ spans.push(span(` ${key}=`, "muted"), span(sanitizeText(String(value))));
569
+ }
570
+ }
571
+ return text(spans, { truncate: "end", role: "omp.tool.eval.status" });
572
+ }
573
+
574
+ /**
575
+ * The eval head (§7.3): a single cell's title as the verb (else "Eval"; with
576
+ * several cells each section carries its own title), a badge per language in
577
+ * first-use order, a `background` badge for a backgrounded job, and the cell
578
+ * count when there are several.
579
+ */
580
+ function evalToolHead(
581
+ title: string | undefined,
582
+ languages: readonly EvalLanguage[],
583
+ cellCount: number,
584
+ details?: EvalToolDetails,
585
+ ): NativeToolHead {
586
+ const badges: { text: string; title?: string }[] = [...new Set(languages)].map(language => ({ text: language }));
587
+ if (details?.async?.state === "running") {
588
+ badges.push({ text: "background", title: `Backgrounded as job ${details.async.jobId}` });
589
+ }
590
+ return {
591
+ title: (cellCount > 1 ? "" : plainText(title ?? "").trim()) || "Eval",
592
+ badges: badges.length > 0 ? badges : undefined,
593
+ meta: cellCount > 1 ? [`${cellCount} cells`] : undefined,
594
+ };
595
+ }
596
+
597
+ /** Box-drawing `console.table` output split out of plain text: `text` runs and parsed tables, in order. */
598
+ type EvalOutputPart =
599
+ | { readonly kind: "text"; readonly text: string }
600
+ | { readonly kind: "table"; readonly head: readonly string[]; readonly rows: readonly string[][] };
601
+
602
+ /** The cells of a `│ a │ b │` row, trimmed; undefined when the line is not a table row. */
603
+ function tableRowCells(line: string): string[] | undefined {
604
+ const plain = plainText(line).trim();
605
+ if (plain.length < 2 || !plain.startsWith("│") || !plain.endsWith("│")) return undefined;
606
+ return plain
607
+ .slice(1, -1)
608
+ .split("│")
609
+ .map(cell => cell.trim());
610
+ }
611
+
612
+ /**
613
+ * Split `console.table` blocks (`┌…┐` header `├…┤` rows `└…┘`, as Node/Bun
614
+ * print them) out of cell output so they render as a `table`; anything that
615
+ * does not parse as one stays text.
616
+ */
617
+ function splitConsoleTables(output: string): EvalOutputPart[] {
618
+ const lines = output.split("\n");
619
+ const parts: EvalOutputPart[] = [];
620
+ let textStart = 0;
621
+ const flushText = (end: number): void => {
622
+ const chunk = lines
623
+ .slice(textStart, end)
624
+ .join("\n")
625
+ .replace(/^\n+|\s+$/g, "");
626
+ if (chunk.length > 0) parts.push({ kind: "text", text: chunk });
627
+ };
628
+ for (let i = 0; i < lines.length; i++) {
629
+ if (!plainText(lines[i]!).trimStart().startsWith("┌")) continue;
630
+ const head = tableRowCells(lines[i + 1] ?? "");
631
+ if (
632
+ !head ||
633
+ !plainText(lines[i + 2] ?? "")
634
+ .trimStart()
635
+ .startsWith("├")
636
+ )
637
+ continue;
638
+ const rows: string[][] = [];
639
+ let end = i + 3;
640
+ for (; end < lines.length; end++) {
641
+ const cells = tableRowCells(lines[end]!);
642
+ if (!cells) break;
643
+ rows.push(cells);
644
+ }
645
+ if (
646
+ !plainText(lines[end] ?? "")
647
+ .trimStart()
648
+ .startsWith("└")
649
+ )
650
+ continue;
651
+ if (rows.some(row => row.length !== head.length)) continue;
652
+ flushText(i);
653
+ parts.push({ kind: "table", head, rows });
654
+ i = end;
655
+ textStart = end + 1;
656
+ }
657
+ flushText(lines.length);
658
+ return parts;
659
+ }
660
+
661
+ /** One cell's output: markdown, else terminal text with any `console.table` blocks as tables. */
662
+ function evalOutputNodes(output: string, markdown: boolean, running: boolean, error: boolean): NativeNode[] {
663
+ if (output.trim().length === 0) return [];
664
+ if (markdown && !error) return [md(output)];
665
+ const tone = error ? "error" : undefined;
666
+ return splitConsoleTables(output).map(part =>
667
+ part.kind === "text"
668
+ ? ansi(part.text, { follow: running, tone, role: "omp.tool.eval.output" })
669
+ : node("table", {
670
+ // Node's index column header is noise in a real table.
671
+ cols: part.head.map((head, i) => ({ id: `c${i}`, head: head === "(index)" ? "" : head })),
672
+ rows: part.rows.map((cells, r) => ({
673
+ id: `r${r}`,
674
+ cells: Object.fromEntries(cells.map((cell, i) => [`c${i}`, cell])),
675
+ })),
676
+ role: "omp.tool.eval.table",
677
+ }),
678
+ );
679
+ }
680
+
681
+ /** Inputs of one eval cell section. */
682
+ interface EvalCellSection {
683
+ readonly language: EvalLanguage;
684
+ readonly code: string;
685
+ readonly title?: string;
686
+ readonly status?: EvalCellResult["status"];
687
+ readonly durationMs?: number;
688
+ readonly output?: readonly NativeChild[];
689
+ }
690
+
691
+ /**
692
+ * One cell as a borderless section: its highlighted code (no line numbers),
693
+ * then its output. Only multi-cell calls caption the section (`2/3 title ·
694
+ * 1.2s`); a single cell's title is the tool head, never repeated.
695
+ */
696
+ function evalCellSection(cell: EvalCellSection, index: number, total: number): NativeNode {
697
+ let head: TspSpan[] | undefined;
698
+ if (total > 1) {
699
+ head = [span(`${index + 1}/${total}`, "muted")];
700
+ const title = plainText(cell.title ?? "").trim();
701
+ if (title) head.push(span(` ${title}`, "toolTitle"));
702
+ if (cell.status === "error") head.push(span(" · failed", "error"));
703
+ if (cell.durationMs !== undefined) head.push(span(` · ${(cell.durationMs / 1000).toFixed(2)}s`, "muted"));
704
+ }
705
+ return node(
706
+ "section",
707
+ { head, role: "omp.tool.eval.cell", tone: cell.status === "error" ? "error" : undefined },
708
+ [
709
+ keyed(codeNode(cell.code, { lang: languageForHighlighter(cell.language), numbers: false }), "code"),
710
+ ...(cell.output ?? []),
711
+ ],
712
+ `cell-${index}`,
713
+ );
714
+ }
715
+
549
716
  /** Render eval code cells, structured display output, and progress events. */
550
717
  export const evalToolRenderer = {
551
718
  animatedPendingPreview: true,
@@ -845,6 +1012,95 @@ export const evalToolRenderer = {
845
1012
  };
846
1013
  },
847
1014
 
1015
+ describeCall(args: EvalRenderArgs, _options: RenderResultOptions): NativeToolView {
1016
+ const cells = getRenderCells(args);
1017
+ return {
1018
+ tool: evalToolHead(
1019
+ cells[0]?.title,
1020
+ cells.map(cell => cell.language),
1021
+ cells.length,
1022
+ ),
1023
+ body: cells.map((cell, i) => evalCellSection(cell, i, cells.length)),
1024
+ preview: { lines: EVAL_DEFAULT_PREVIEW_LINES },
1025
+ };
1026
+ },
1027
+
1028
+ describeResult(
1029
+ result: { content: Array<{ type: string; text?: string }>; details?: EvalToolDetails; isError?: boolean },
1030
+ options: RenderResultContextOptions & { renderContext?: EvalRenderContext },
1031
+ args?: EvalRenderArgs,
1032
+ ): NativeToolView {
1033
+ const details = result.details;
1034
+ const isPartial = options.isPartial === true;
1035
+ const previewLines = options.renderContext?.previewLines ?? EVAL_DEFAULT_PREVIEW_LINES;
1036
+ const jsonNodes = (details?.jsonOutputs ?? []).map((value, index) =>
1037
+ keyed(describeJsonTree(value, { hiddenRootKeys: [] }), `display-${index}`),
1038
+ );
1039
+ // A notice and truncation go to one quiet final line (a background job is a head badge).
1040
+ const footer = footnoteText(compact([details?.notice]), details?.meta);
1041
+ const cellResults = details?.cells;
1042
+ let cells: NativeNode[];
1043
+ let head: NativeToolHead;
1044
+ if (cellResults && cellResults.length > 0) {
1045
+ const languages = cellResults.map(cell => cell.language ?? details?.language ?? "python");
1046
+ head = evalToolHead(cellResults[0]!.title, languages, cellResults.length, details);
1047
+ cells = cellResults.map((cell, i) => {
1048
+ const language = languages[i]!;
1049
+ return evalCellSection(
1050
+ {
1051
+ language,
1052
+ code: formatEvalCodeForDisplay(cell.code, language),
1053
+ title: cell.title,
1054
+ status: cell.status,
1055
+ durationMs: cell.durationMs,
1056
+ output: [
1057
+ ...evalOutputNodes(
1058
+ cell.output,
1059
+ cell.hasMarkdown === true,
1060
+ cell.status === "running",
1061
+ cell.status === "error",
1062
+ ),
1063
+ ...(cell.statusEvents ?? []).map(describeStatusEvent),
1064
+ ],
1065
+ },
1066
+ i,
1067
+ cellResults.length,
1068
+ );
1069
+ });
1070
+ } else {
1071
+ // No per-cell results (older details): the call's cells, with the whole output under the last.
1072
+ const argCells = getRenderCells(args);
1073
+ const languages = details?.languages ?? (details?.language ? [details.language] : []);
1074
+ head = evalToolHead(
1075
+ argCells[0]?.title,
1076
+ argCells.length > 0 ? argCells.map(cell => cell.language) : languages,
1077
+ argCells.length,
1078
+ details,
1079
+ );
1080
+ const rawOutput = options.renderContext?.output ?? resultText(result).trimEnd();
1081
+ const output = [
1082
+ ...evalOutputNodes(
1083
+ stripOutputNotice(rawOutput, details?.meta).trimEnd(),
1084
+ false,
1085
+ isPartial,
1086
+ result.isError === true,
1087
+ ),
1088
+ ...(details?.statusEvents ?? []).map(describeStatusEvent),
1089
+ ];
1090
+ cells =
1091
+ argCells.length > 0
1092
+ ? argCells.map((cell, i) =>
1093
+ evalCellSection(i === argCells.length - 1 ? { ...cell, output } : cell, i, argCells.length),
1094
+ )
1095
+ : output;
1096
+ }
1097
+ return {
1098
+ tool: head,
1099
+ body: compact<NativeChild>([...cells, ...jsonNodes, footer]),
1100
+ preview: { lines: previewLines },
1101
+ };
1102
+ },
1103
+
848
1104
  mergeCallAndResult: true,
849
1105
  inline: true,
850
1106
  } satisfies ToolRenderer<EvalRenderArgs, EvalToolDetails>;
@@ -1,15 +1,25 @@
1
1
  import { isReadableUrlPath, readSelectorRangeStart } from "./read";
2
2
  import type { Component } from "../tui";
3
3
  import { Text } from "../components/text";
4
- import type { RenderResultOptions } from "./renderer";
4
+ import type { NativeToolHead, NativeToolView, RenderResultOptions } from "./renderer";
5
+ import type { TspSpan } from "@oh-my-pi/pi-wire";
6
+ import { compact, span, text } from "../native/describe";
7
+ import { plainText } from "../native/spans";
8
+ import { errorText, noteText, resultText, statsText } from "./native-view";
5
9
  import { type Theme, theme } from "../theme/theme";
6
10
  import type { OutputMeta } from "./output-meta";
7
11
  import { truncate } from "@oh-my-pi/pi-utils";
8
12
  import { renderStatusLine, urlHyperlink } from "../render";
9
13
  import { framedToolCard } from "../render/tool-card";
10
- import { formatExpandHint, getDomain, sanitizeDisplayLines } from "../render/render-utils";
14
+ import {
15
+ formatExpandHint,
16
+ formatMoreItems,
17
+ getDomain,
18
+ PREVIEW_LIMITS,
19
+ sanitizeDisplayLines,
20
+ } from "../render/render-utils";
11
21
  import { applyListLimit } from "./list-limit";
12
- import { formatStyledArtifactReference } from "./output-meta";
22
+ import { formatFullOutputReference, formatStyledArtifactReference } from "./output-meta";
13
23
 
14
24
  /** Display metadata for fetch tool results. */
15
25
  export interface ReadUrlToolDetails {
@@ -98,6 +108,15 @@ function formatReadUrlDescription(input: string): string {
98
108
  return urlHyperlink(target, label);
99
109
  }
100
110
 
111
+ /** Link span for a URL read target: `domain /path`, linked to the resolved target. */
112
+ function readUrlLinkSpan(input: string): TspSpan {
113
+ const target = readUrlLinkTarget(input);
114
+ const displayUrl = target.match(/^www\./i) ? `https://${target}` : target;
115
+ const urlPath = displayUrl.replace(/^https?:\/\/[^/]+/, "");
116
+ const label = `${getDomain(displayUrl)}${urlPath ? ` ${urlPath}` : ""}`.trim() || target;
117
+ return span(plainText(label), "link", { href: target });
118
+ }
119
+
101
120
  function formatReadUrlMetadataValue(url: string, uiTheme: Theme): string {
102
121
  return urlHyperlink(url, uiTheme.fg("mdLinkUrl", url));
103
122
  }
@@ -116,6 +135,86 @@ export function renderReadUrlCall(
116
135
  return new Text(text, 0, 0);
117
136
  }
118
137
 
138
+ /** Native head of a URL read: `Read` plus the linked, one-line URL. */
139
+ function readUrlHead(input: string, meta: readonly string[] = []): NativeToolHead {
140
+ const link = input ? readUrlLinkSpan(input) : undefined;
141
+ return {
142
+ title: "Read",
143
+ target: link?.t || undefined,
144
+ targetKind: "text",
145
+ href: link?.href,
146
+ meta: meta.length > 0 ? meta : undefined,
147
+ };
148
+ }
149
+
150
+ /** TSP call view of a URL read: the head only, inline while pending. */
151
+ export function describeReadUrlCall(args: { path?: string; url?: string; raw?: boolean }): NativeToolView {
152
+ return { tool: readUrlHead(args.path ?? args.url ?? "", args.raw ? ["raw"] : []), inline: true };
153
+ }
154
+
155
+ /** TSP result view of a URL read: a bounded content preview over one quiet stats line. */
156
+ export function describeReadUrlResult(result: {
157
+ content: Array<{ type: string; text?: string }>;
158
+ details?: ReadUrlToolDetails;
159
+ isError?: boolean;
160
+ }): NativeToolView {
161
+ const details = result.details;
162
+ if (result.isError || !details) {
163
+ const urlText = details?.finalUrl ?? details?.url ?? "";
164
+ const message = plainText(resultText(result) || "No response data").replace(/^Error:\s*/, "");
165
+ return {
166
+ tool: readUrlHead(urlText),
167
+ tone: "error",
168
+ body: [errorText(message.trim() || "Read failed")],
169
+ };
170
+ }
171
+
172
+ const truncation = details.meta?.truncation;
173
+ const truncated = Boolean(details.truncated || truncation);
174
+ const contentText = result.content[0]?.text ?? "";
175
+ const contentBody = contentText.includes("---\n\n")
176
+ ? contentText.split("---\n\n").slice(1).join("---\n\n")
177
+ : contentText;
178
+ const contentLines = contentBody.split("\n").filter(l => l.trim());
179
+ const shown = contentLines.slice(0, PREVIEW_LIMITS.EXPANDED_LINES);
180
+ const hidden = contentLines.length - shown.length;
181
+ const redirected = details.url !== details.finalUrl;
182
+
183
+ const stats = statsText(
184
+ [
185
+ plainText(details.contentType || "unknown"),
186
+ details.method ? plainText(details.method) : "",
187
+ `${contentLines.length} line${contentLines.length === 1 ? "" : "s"}`,
188
+ `${contentBody.trim().length} chars`,
189
+ hidden > 0 ? formatMoreItems(hidden, "line") : "",
190
+ ...details.notes.map(note => plainText(note)),
191
+ ].filter(Boolean),
192
+ );
193
+ return {
194
+ tool: readUrlHead(details.finalUrl, redirected ? [`from ${plainText(getDomain(details.url))}`] : []),
195
+ tone: truncated ? "warning" : undefined,
196
+ body: compact([
197
+ shown.length > 0
198
+ ? text([span(plainText(shown.map(line => line.trimEnd()).join("\n")), "dim")], { wrap: "word" })
199
+ : noteText("(no content)"),
200
+ stats,
201
+ truncated
202
+ ? text(
203
+ [
204
+ span(
205
+ truncation?.artifactId
206
+ ? `Output truncated · ${formatFullOutputReference(truncation.artifactId)}`
207
+ : "Output truncated",
208
+ "warning",
209
+ ),
210
+ ],
211
+ { wrap: "word", role: "omp.tool.notice" },
212
+ )
213
+ : undefined,
214
+ ]),
215
+ };
216
+ }
217
+
119
218
  /** Render URL read result with tree-based layout */
120
219
  export function renderReadUrlResult(
121
220
  result: { content: Array<{ type: string; text?: string }>; details?: ReadUrlToolDetails; isError?: boolean },
package/src/tools/find.ts CHANGED
@@ -27,7 +27,12 @@ import {
27
27
  import type { Theme, ThemeColor } from "../theme/theme";
28
28
  import type { Component } from "../tui";
29
29
  import type { OutputMeta } from "./output-meta";
30
- import type { RenderResultOptions, ToolRenderer } from "./renderer";
30
+ import type { NativeToolHead, NativeToolView, RenderResultOptions, ToolRenderer } from "./renderer";
31
+ import type { TspTone } from "@oh-my-pi/pi-wire";
32
+ import { code, col, compact, keyed, node, span, text } from "../native/describe";
33
+ import type { NativeChild, NativeNode } from "../native/node";
34
+ import { getLanguageFromPath } from "../lang-from-path";
35
+ import { fileHref, fileRow, inlineErrorView } from "./native-view";
31
36
  import { splitUrlScheme } from "./url-scheme-host";
32
37
 
33
38
  /** A verified line range with its yes-probability and a one-line preview. */
@@ -148,6 +153,49 @@ function renderHit(hit: FindHit, rangeLimit: number, cwd: string | undefined, th
148
153
  return lines;
149
154
  }
150
155
 
156
+ function scoreTone(p: number): TspTone {
157
+ return p >= STRONG ? "success" : p >= PLAUSIBLE ? "warning" : "muted";
158
+ }
159
+
160
+ /**
161
+ * One hit (§7.3 find): a 22px row of the score bar, the path and `12 lines
162
+ * judged`, then its strongest ranges as numbered `code` (no path header).
163
+ */
164
+ function describeHit(hit: FindHit, rangeLimit: number, cwd: string | undefined): NativeNode {
165
+ const ranges = [...hit.ranges].sort((a, b) => b.p - a.p || a.start - b.start).slice(0, rangeLimit);
166
+ const tone = scoreTone(hit.contentScore);
167
+ const score = hit.contentScore.toFixed(2);
168
+ const isUrlHit = splitUrlScheme(hit.rel) !== undefined;
169
+ const head = fileRow(hit.rel, {
170
+ lead: node("progress", { value: hit.contentScore, tone, title: `score ${score}`, max: { w: 40 } }),
171
+ detail: [
172
+ span(score, tone),
173
+ span(
174
+ hit.truncated ? ` · ${hit.linesSeen} lines judged, partial` : ` · ${hit.linesSeen} lines judged`,
175
+ "muted",
176
+ ),
177
+ ],
178
+ href: isUrlHit || cwd === undefined ? undefined : fileHref(path.join(cwd, hit.rel)),
179
+ key: "hit",
180
+ });
181
+ const lang = getLanguageFromPath(hit.rel);
182
+ const snippets = ranges.map(range =>
183
+ keyed(
184
+ code(range.snippet.trimEnd(), { lang, start: range.start, numbers: true, title: range.p.toFixed(2) }),
185
+ `${range.start}-${range.end}`,
186
+ ),
187
+ );
188
+ return keyed(col([head, ...snippets], { gap: "xs", role: "omp.tool.find.hit" }), hit.rel);
189
+ }
190
+
191
+ /** Native find head: the query, then `meta` (result counts), or the call's keywords and scope. */
192
+ function findNativeHead(
193
+ query: string | undefined,
194
+ meta: readonly NonNullable<NativeToolHead["meta"]>[number][],
195
+ ): NativeToolHead {
196
+ return { title: "Find", target: query ?? "", targetKind: "query", meta };
197
+ }
198
+
151
199
  function quoteQuery(query: string | undefined): string | undefined {
152
200
  return query === undefined ? undefined : `"${query}"`;
153
201
  }
@@ -263,6 +311,84 @@ export const findToolRenderer = {
263
311
  { paddingX: 1 },
264
312
  );
265
313
  },
314
+ describeCall(args: FindRenderArgs): NativeToolView {
315
+ const keywords = args.grep_keywords ?? [];
316
+ return {
317
+ tool: findNativeHead(
318
+ args.query,
319
+ compact([keywords.length > 0 && keywords.join(" "), args.path && `in ${args.path}`]),
320
+ ),
321
+ inline: true,
322
+ };
323
+ },
324
+
325
+ /**
326
+ * Inline (§7.3 find): `Find “query” 2 hits · 8 files`, then per hit its
327
+ * score bar, path and coverage over the strongest snippets. The search
328
+ * accounting (τ, tokens, cost, time) is the footnote's tooltip.
329
+ */
330
+ describeResult(
331
+ result: { content: Array<{ type: string; text?: string }>; details?: FindToolDetails; isError?: boolean },
332
+ options: RenderResultOptions,
333
+ args?: FindRenderArgs,
334
+ ): NativeToolView {
335
+ const details = result.details;
336
+ const progress = result.content?.find(c => c.type === "text")?.text ?? "";
337
+ const query = args?.query ?? details?.query;
338
+ if (result.isError) return inlineErrorView(findNativeHead(query, []), progress || "Unknown error");
339
+ if (options.isPartial || details === undefined) {
340
+ return {
341
+ tool: findNativeHead(query, progress ? [[span(progress, "muted", { fx: "shimmer" })]] : []),
342
+ inline: true,
343
+ };
344
+ }
345
+ const { hits, stats, threshold } = details;
346
+ const scope = details.scopePath === undefined ? undefined : `in ${details.scopePath}`;
347
+ const failed = stats.errors > 0 ? [span(`${stats.errors} failed`, "warning")] : undefined;
348
+ const accounting = [
349
+ `${stats.filesRead} files read`,
350
+ `τ ${threshold.toFixed(2)}`,
351
+ `${formatNumber(stats.inputTokens)} tokens`,
352
+ `$${stats.cost.toFixed(4)}`,
353
+ formatDuration(details.elapsedMs),
354
+ ].join(" · ");
355
+ const failures = stats.failures.map((failure, i) =>
356
+ keyed(text([span(failure, "warning")], { wrap: "word", role: "omp.tool.notice" }), `fail${i}`),
357
+ );
358
+ if (hits.length === 0) {
359
+ return {
360
+ tool: findNativeHead(query, compact(["0 hits", scope, failed])),
361
+ tone: "warning",
362
+ inline: true,
363
+ body: failures.length > 0 ? failures : undefined,
364
+ };
365
+ }
366
+ const shown = options.expanded ? hits : hits.slice(0, COLLAPSED_HITS);
367
+ const rangeLimit = options.expanded ? RANGES_EXPANDED : RANGES_COLLAPSED;
368
+ const hidden = hits.length - shown.length;
369
+ const footParts = compact([
370
+ hidden > 0 && formatCount("more hit", hidden),
371
+ `keywords: ${details.keywords.join(", ")}`,
372
+ ]);
373
+ // One quiet last line; the accounting ANSI prints in the head rides its tooltip.
374
+ const foot = keyed(
375
+ text([span(footParts.join(" · "), "muted")], { wrap: "word", role: "omp.tool.stats", title: accounting }),
376
+ "foot",
377
+ );
378
+ return {
379
+ tool: findNativeHead(
380
+ query,
381
+ compact([`${formatCount("hit", hits.length)} · ${formatCount("file", stats.filesRead)}`, scope, failed]),
382
+ ),
383
+ inline: true,
384
+ body: compact<NativeChild>([
385
+ ...shown.map(hit => describeHit(hit, rangeLimit, details.cwd)),
386
+ ...failures,
387
+ foot,
388
+ ]),
389
+ preview: { lines: PREVIEW_LIMITS.EXPANDED_LINES },
390
+ };
391
+ },
266
392
  mergeCallAndResult: true,
267
393
  animatedPendingPreview: true,
268
394
  animatedPartialResult: true,