@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/bash.ts CHANGED
@@ -18,7 +18,16 @@ import {
18
18
  stripRawOutputArtifactNotice,
19
19
  stripTrailingNotice,
20
20
  } from "./output-meta";
21
- import type { RenderResultOptions, ToolRenderer } from "./renderer";
21
+ import type {
22
+ NativeToolHead,
23
+ NativeToolView,
24
+ RenderResultContextOptions,
25
+ RenderResultOptions,
26
+ ToolRenderer,
27
+ } from "./renderer";
28
+ import { ansi, compact, keyed } from "../native/describe";
29
+ import type { NativeChild } from "../native/node";
30
+ import { footnoteText, resultText } from "./native-view";
22
31
 
23
32
  /** Default collapsed shell output preview height. */
24
33
  export const BASH_DEFAULT_PREVIEW_LINES = DEFAULT_TERMINAL_PREVIEW_LINES;
@@ -130,19 +139,51 @@ function unescapePartialJsonString(value: string): string {
130
139
  return output;
131
140
  }
132
141
 
133
- function extractPartialBashEnv(partialJson: string | undefined): Record<string, string> | undefined {
142
+ // One-slot memo: every render path over one streamed args object (call
143
+ // preview, result header, repaint) asks for the same buffer.
144
+ let lastPartialEnvJson: string | undefined;
145
+ let lastPartialEnv: Readonly<Record<string, string>> | undefined;
146
+
147
+ function extractPartialBashEnv(partialJson: string | undefined): Readonly<Record<string, string>> | undefined {
134
148
  if (!partialJson) return undefined;
149
+ if (partialJson === lastPartialEnvJson) return lastPartialEnv;
150
+ let env: Record<string, string> | undefined;
135
151
  const envStart = partialJson.search(/"env"\s*:\s*\{/u);
136
- if (envStart === -1) return undefined;
137
- const objectStart = partialJson.indexOf("{", envStart);
138
- if (objectStart === -1) return undefined;
139
- const envBody = partialJson.slice(objectStart + 1);
140
- const env: Record<string, string> = {};
141
- const matcher = /"([A-Za-z_][A-Za-z0-9_]*)"\s*:\s*"((?:\\.|[^"\\])*)(?:"|$)/gu;
142
- for (const match of envBody.matchAll(matcher)) {
143
- env[match[1]!] = unescapePartialJsonString(match[2]!);
152
+ const objectStart = envStart === -1 ? -1 : partialJson.indexOf("{", envStart);
153
+ if (objectStart !== -1) {
154
+ // Scan only the env object: stop at its closing brace (outside strings)
155
+ // so the keys that follow it are not read as env assignments.
156
+ let objectEnd = partialJson.length;
157
+ let depth = 0;
158
+ for (let i = objectStart + 1; i < partialJson.length; i++) {
159
+ const ch = partialJson.charCodeAt(i);
160
+ if (ch === 0x22) {
161
+ // Skip the string body, honoring escapes; an unterminated string runs to the end.
162
+ for (i++; i < partialJson.length; i++) {
163
+ const inner = partialJson.charCodeAt(i);
164
+ if (inner === 0x5c) i++;
165
+ else if (inner === 0x22) break;
166
+ }
167
+ } else if (ch === 0x7b || ch === 0x5b) {
168
+ depth++;
169
+ } else if (ch === 0x7d || ch === 0x5d) {
170
+ if (depth === 0) {
171
+ objectEnd = i;
172
+ break;
173
+ }
174
+ depth--;
175
+ }
176
+ }
177
+ const envBody = partialJson.slice(objectStart + 1, objectEnd);
178
+ const matcher = /"([A-Za-z_][A-Za-z0-9_]*)"\s*:\s*"((?:\\.|[^"\\])*)(?:"|$)/gu;
179
+ for (const match of envBody.matchAll(matcher)) {
180
+ env ??= {};
181
+ env[match[1]!] = unescapePartialJsonString(match[2]!);
182
+ }
144
183
  }
145
- return Object.keys(env).length > 0 ? env : undefined;
184
+ lastPartialEnvJson = partialJson;
185
+ lastPartialEnv = env ? Object.freeze(env) : undefined;
186
+ return lastPartialEnv;
146
187
  }
147
188
 
148
189
  function formatWallTimeSeconds(wallTimeMs: number): string {
@@ -229,6 +270,122 @@ export function formatBashCommandLines(args: BashRenderArgs, uiTheme: Theme): st
229
270
  return highlightedLines.map((line, i) => (i === 0 ? `${prefix}${line}` : line));
230
271
  }
231
272
 
273
+ /**
274
+ * Plain (unstyled) command line for native views: `cd <dir> && NAME="…" <command>`,
275
+ * built from the same decoded display args (incl. streamed `__partialJson` env) as the ANSI path.
276
+ */
277
+ export function formatBashCommandText(args: BashRenderArgs): string {
278
+ const displayWorkdir = formatToolWorkingDirectory(args.cwd, getProjectDir());
279
+ const envAssignments = formatBashEnvAssignments(getBashEnvForDisplay(args));
280
+ const parts: string[] = [];
281
+ if (displayWorkdir) parts.push(`cd ${displayWorkdir} &&`);
282
+ if (envAssignments) parts.push(envAssignments);
283
+ parts.push(args.command || "…");
284
+ return parts.join(" ");
285
+ }
286
+
287
+ /** Bash output with the LLM-facing notices (background, exit, wall time, artifact, truncation) removed. */
288
+ function stripBashNotices(
289
+ rawOutput: string,
290
+ details: BashToolDetails | undefined,
291
+ ): { text: string; artifactId?: string } {
292
+ const withoutBackground =
293
+ details?.async?.state === "running"
294
+ ? stripTrailingNotice(rawOutput, formatBackgroundNotice(details.async.jobId))
295
+ : rawOutput;
296
+ const strippedOutput = stripOutputNotice(withoutBackground, details?.meta);
297
+ const withoutExit =
298
+ details?.exitCode === undefined
299
+ ? strippedOutput
300
+ : stripTrailingNotice(strippedOutput, formatExitCodeNotice(details.exitCode));
301
+ const withoutWall =
302
+ details?.wallTimeMs === undefined
303
+ ? withoutExit
304
+ : stripTrailingNotice(withoutExit, formatWallTimeNotice(details.wallTimeMs));
305
+ return stripRawOutputArtifactNotice(withoutWall);
306
+ }
307
+ /** `Wall: 1.20s`, `Timeout: 30s`, … metadata parts shown under bash output. */
308
+ function bashStatsParts(
309
+ details: BashToolDetails | undefined,
310
+ contextTimeout: number | undefined,
311
+ artifactId: string | undefined,
312
+ isError: boolean,
313
+ ): string[] {
314
+ const timeoutDisabled = details?.timeoutDisabled === true || contextTimeout === 0;
315
+ const timeoutSeconds = timeoutDisabled ? undefined : (details?.timeoutSeconds ?? contextTimeout);
316
+ const requestedTimeoutSeconds = details?.requestedTimeoutSeconds;
317
+ const wallTimeMs = details?.wallTimeMs;
318
+ const statsParts: string[] = [];
319
+ if (details?.async?.state === "running") {
320
+ statsParts.push(`Backgrounded: ${details.async.jobId}`);
321
+ }
322
+ if (details?.service) {
323
+ const service = details.service;
324
+ statsParts.push(`Service: ${service.name}`, `State: ${service.state}`);
325
+ statsParts.push(`Ready: ${service.ready ? "yes" : service.timedOut ? "timed out" : "no"}`);
326
+ if (service.pid !== undefined) statsParts.push(`PID: ${service.pid}`);
327
+ }
328
+ if (wallTimeMs !== undefined) {
329
+ statsParts.push(`Wall: ${formatWallTimeSeconds(wallTimeMs)}s`);
330
+ }
331
+ if (timeoutDisabled) {
332
+ statsParts.push("Timeout: disabled");
333
+ }
334
+ if (typeof timeoutSeconds === "number") {
335
+ statsParts.push(
336
+ requestedTimeoutSeconds !== undefined && requestedTimeoutSeconds !== timeoutSeconds
337
+ ? `Timeout: ${timeoutSeconds}s (requested ${requestedTimeoutSeconds}s clamped)`
338
+ : `Timeout: ${timeoutSeconds}s`,
339
+ );
340
+ }
341
+ if (artifactId) {
342
+ statsParts.push(`Artifact: ${artifactId}`);
343
+ }
344
+ if (isError && typeof details?.exitCode === "number") {
345
+ statsParts.push(`Exit: ${details.exitCode}`);
346
+ }
347
+ return statsParts;
348
+ }
349
+
350
+ /**
351
+ * Native head facts of a shell call: title, the command once (`cd`/env
352
+ * prefix included), a `background` badge for a backgrounded job, the
353
+ * `exit N` chip and a `timed out` note only when the deadline hit.
354
+ */
355
+ function shellToolHead(
356
+ title: string,
357
+ command: string,
358
+ details: BashToolDetails | undefined,
359
+ settled: boolean,
360
+ ): NativeToolHead {
361
+ const exit = settled && details?.exitCode !== undefined && details.exitCode !== 0 ? details.exitCode : undefined;
362
+ return {
363
+ title,
364
+ target: command,
365
+ targetKind: "command",
366
+ lang: "bash",
367
+ badges:
368
+ details?.async?.state === "running"
369
+ ? [{ text: "background", title: `Backgrounded as job ${details.async.jobId}` }]
370
+ : undefined,
371
+ exit,
372
+ note: settled && details?.timedOut === true ? "timed out" : undefined,
373
+ };
374
+ }
375
+
376
+ /** The quiet final line's facts under shell output: service state and the full-output artifact. */
377
+ function shellFootParts(details: BashToolDetails | undefined, artifactId: string | undefined): string[] {
378
+ const parts: string[] = [];
379
+ const service = details?.service;
380
+ if (service) {
381
+ parts.push(`Service ${service.name}`, service.state);
382
+ parts.push(service.ready ? "ready" : service.timedOut ? "ready timed out" : "not ready");
383
+ if (service.pid !== undefined) parts.push(`PID ${service.pid}`);
384
+ }
385
+ if (artifactId) parts.push(`Artifact ${artifactId}`);
386
+ return parts;
387
+ }
388
+
232
389
  function toBashRenderArgs<TArgs>(args: TArgs | undefined, config: ShellRendererConfig<TArgs>): BashRenderArgs {
233
390
  return {
234
391
  command: config.resolveCommand?.(args),
@@ -243,8 +400,12 @@ export function createShellRenderer<TArgs>(config: ShellRendererConfig<TArgs>) {
243
400
  return {
244
401
  renderCall(args: TArgs, options: RenderResultOptions, uiTheme: Theme): Component {
245
402
  const renderArgs = toBashRenderArgs(args, config);
246
- const cmdLines = formatBashCommandLines(renderArgs, uiTheme);
403
+ // Highlighting the whole (possibly still-streaming) command is the
404
+ // expensive part: defer it to the first paint, once per component,
405
+ // so a rebuild that is replaced before painting never pays for it.
406
+ let cmdLines: string[] | undefined;
247
407
  return framedToolCard(uiTheme, () => {
408
+ cmdLines ??= formatBashCommandLines(renderArgs, uiTheme);
248
409
  const header =
249
410
  config.showHeader === false
250
411
  ? undefined
@@ -275,7 +436,7 @@ export function createShellRenderer<TArgs>(config: ShellRendererConfig<TArgs>) {
275
436
  args?: TArgs,
276
437
  ): Component {
277
438
  const renderArgs = toBashRenderArgs(args, config);
278
- const cmdLines = args ? formatBashCommandLines(renderArgs, uiTheme) : undefined;
439
+ let cmdLines: string[] | undefined;
279
440
  const isError = result.isError === true;
280
441
  const isPartial = options.isPartial === true;
281
442
  const success = !isPartial && !isError;
@@ -342,58 +503,17 @@ export function createShellRenderer<TArgs>(config: ShellRendererConfig<TArgs>) {
342
503
  ) {
343
504
  return cachedSnapshot;
344
505
  }
345
- const withoutBackground =
346
- details?.async?.state === "running"
347
- ? stripTrailingNotice(rawOutput, formatBackgroundNotice(details.async.jobId))
348
- : rawOutput;
349
- const strippedOutput = stripOutputNotice(withoutBackground, details?.meta);
350
- const withoutExit =
351
- details?.exitCode === undefined
352
- ? strippedOutput
353
- : stripTrailingNotice(strippedOutput, formatExitCodeNotice(details.exitCode));
354
- const withoutWall =
355
- details?.wallTimeMs === undefined
356
- ? withoutExit
357
- : stripTrailingNotice(withoutExit, formatWallTimeNotice(details.wallTimeMs));
358
- const rawOutputArtifact = stripRawOutputArtifactNotice(withoutWall);
506
+ const rawOutputArtifact = stripBashNotices(rawOutput, details);
359
507
  const output = rawOutputArtifact.text;
360
508
  const displayOutput = output.trimEnd();
361
509
  const showingFullOutput = expanded && renderContext?.isFullOutput === true;
362
510
 
363
- // Build truncation warning
364
- const timeoutDisabled = details?.timeoutDisabled === true || renderContext?.timeout === 0;
365
- const timeoutSeconds = timeoutDisabled ? undefined : (details?.timeoutSeconds ?? renderContext?.timeout);
366
- const requestedTimeoutSeconds = details?.requestedTimeoutSeconds;
367
- const wallTimeMs = details?.wallTimeMs;
368
- const statsParts: string[] = [];
369
- if (details?.async?.state === "running") {
370
- statsParts.push(`Backgrounded: ${details.async.jobId}`);
371
- }
372
- if (details?.service) {
373
- const service = details.service;
374
- statsParts.push(`Service: ${service.name}`, `State: ${service.state}`);
375
- statsParts.push(`Ready: ${service.ready ? "yes" : service.timedOut ? "timed out" : "no"}`);
376
- if (service.pid !== undefined) statsParts.push(`PID: ${service.pid}`);
377
- }
378
- if (wallTimeMs !== undefined) {
379
- statsParts.push(`Wall: ${formatWallTimeSeconds(wallTimeMs)}s`);
380
- }
381
- if (timeoutDisabled) {
382
- statsParts.push("Timeout: disabled");
383
- }
384
- if (typeof timeoutSeconds === "number") {
385
- statsParts.push(
386
- requestedTimeoutSeconds !== undefined && requestedTimeoutSeconds !== timeoutSeconds
387
- ? `Timeout: ${timeoutSeconds}s (requested ${requestedTimeoutSeconds}s clamped)`
388
- : `Timeout: ${timeoutSeconds}s`,
389
- );
390
- }
391
- if (rawOutputArtifact.artifactId) {
392
- statsParts.push(`Artifact: ${rawOutputArtifact.artifactId}`);
393
- }
394
- if (isError && typeof details?.exitCode === "number") {
395
- statsParts.push(`Exit: ${details.exitCode}`);
396
- }
511
+ const statsParts = bashStatsParts(
512
+ details,
513
+ renderContext?.timeout,
514
+ rawOutputArtifact.artifactId,
515
+ isError,
516
+ );
397
517
  const timeoutLine =
398
518
  statsParts.length > 0
399
519
  ? uiTheme.fg(
@@ -438,7 +558,11 @@ export function createShellRenderer<TArgs>(config: ShellRendererConfig<TArgs>) {
438
558
  {
439
559
  // Viewport-sized tail window in every state — streaming and final
440
560
  // render identically; only ctrl+o uncaps.
441
- content: capPreviewLines(cmdLines ?? [], uiTheme, { expanded }),
561
+ content: capPreviewLines(
562
+ args ? (cmdLines ??= formatBashCommandLines(renderArgs, uiTheme)) : [],
563
+ uiTheme,
564
+ { expanded },
565
+ ),
442
566
  },
443
567
  { label: uiTheme.fg("toolTitle", "Output"), content: outputLines },
444
568
  ],
@@ -466,6 +590,53 @@ export function createShellRenderer<TArgs>(config: ShellRendererConfig<TArgs>) {
466
590
  },
467
591
  );
468
592
  },
593
+ describeCall(args: TArgs, options: RenderResultOptions): NativeToolView {
594
+ const command = formatBashCommandText(toBashRenderArgs(args, config));
595
+ // The command shows once, in the head; the body is only the output.
596
+ return {
597
+ tool: shellToolHead(config.resolveTitle(args, options), command, undefined, false),
598
+ preview: { tail: BASH_DEFAULT_PREVIEW_LINES },
599
+ };
600
+ },
601
+
602
+ describeResult(
603
+ result: {
604
+ content: Array<{ type: string; text?: string }>;
605
+ details?: BashToolDetails;
606
+ isError?: boolean;
607
+ },
608
+ options: RenderResultContextOptions & { renderContext?: BashRenderContext },
609
+ args?: TArgs,
610
+ ): NativeToolView {
611
+ const details = result.details;
612
+ const renderContext = options.renderContext;
613
+ const isError = result.isError === true;
614
+ const isPartial = options.isPartial === true;
615
+ const rawOutput = renderContext?.output ?? resultText(result);
616
+ const stripped = stripBashNotices(rawOutput, details);
617
+ const output = stripped.text.trimEnd();
618
+ const expanded = renderContext?.expanded ?? options.expanded;
619
+ const showingFullOutput = expanded && renderContext?.isFullOutput === true;
620
+ const command = formatBashCommandText(toBashRenderArgs(args, config));
621
+ const previewLines = renderContext?.previewLines ?? BASH_DEFAULT_PREVIEW_LINES;
622
+ // Wall time is the head timer, the timeout a note only when hit, the exit a head chip:
623
+ // what is left (service state, artifact, truncation) is one quiet final line.
624
+ const meta = details?.meta;
625
+ const body: NativeChild[] = compact([
626
+ output.trim().length > 0 &&
627
+ keyed(ansi(output, { follow: isPartial, role: "omp.tool.bash.output" }), "output"),
628
+ footnoteText(shellFootParts(details, stripped.artifactId), {
629
+ ...meta,
630
+ truncation: showingFullOutput ? undefined : meta?.truncation,
631
+ }),
632
+ ]);
633
+ return {
634
+ tool: shellToolHead(config.resolveTitle(args, options), command, details, !isPartial),
635
+ body,
636
+ tone: !isPartial && isError && details?.timedOut === true ? "warning" : undefined,
637
+ preview: { tail: previewLines },
638
+ };
639
+ },
469
640
  mergeCallAndResult: true,
470
641
  inline: true,
471
642
  } satisfies ToolRenderer<TArgs, BashToolDetails>;
@@ -16,8 +16,11 @@ import {
16
16
  } from "../render/render-utils";
17
17
  import { highlightCode, type Theme } from "../theme/theme";
18
18
  import { parseCfgUrl } from "./cfg-url";
19
- import type { RenderResultOptions } from "./renderer";
19
+ import type { NativeToolView, RenderResultOptions } from "./renderer";
20
20
  import { card, type CardToolResult, firstText, safe } from "./result-card";
21
+ import { code, compact, span, text } from "../native/describe";
22
+ import { plainText } from "../native/spans";
23
+ import { errorView, toolHead } from "./native-view";
21
24
 
22
25
  /** Summary of a `cfg://` read, attached to read tool details. */
23
26
  export interface CfgReadDetails {
@@ -77,6 +80,68 @@ export function renderCfgRead(
77
80
  }, options);
78
81
  }
79
82
 
83
+ /** TSP view of `read cfg://…`: path and counts in the head, the listing as YAML. */
84
+ export function describeCfgRead(
85
+ url: string,
86
+ result: CardToolResult | undefined,
87
+ details: CfgReadDetails | undefined,
88
+ ): NativeToolView {
89
+ const description = (details?.path ?? parseCfgUrl(url)?.segments.join(".")) || "all settings";
90
+ const meta: string[] = [];
91
+ if (details) {
92
+ meta.push(details.count === 1 ? "1 setting" : `${details.count} settings`);
93
+ if (details.modified) meta.push(`${details.modified} modified`);
94
+ }
95
+ if (result?.isError) return errorView("Config", firstText(result) || "Settings read failed.", description, ...meta);
96
+ const head = toolHead("Config", description, ...meta);
97
+ if (!result) return { head };
98
+ const listing = plainText(safe(firstText(result).trimEnd()));
99
+ return {
100
+ head,
101
+ body: listing ? [code(listing, { lang: "yaml" })] : undefined,
102
+ preview: { lines: PREVIEW_LIMITS.COLLAPSED_ITEMS },
103
+ };
104
+ }
105
+
106
+ /** TSP view of `write cfg://…[/save]`: scope/outcome in the head, then `previous → value`. */
107
+ export function describeCfgWrite(
108
+ url: string,
109
+ content: string | undefined,
110
+ result: CardToolResult | undefined,
111
+ details: CfgWriteDetails | undefined,
112
+ ): NativeToolView {
113
+ const target = parseCfgUrl(url);
114
+ const path = details?.path ?? target?.segments.join(".");
115
+ const save = details?.save ?? target?.save ?? false;
116
+ if (result?.isError) return errorView("Config", firstText(result) || "Settings write failed.", path);
117
+ const head = toolHead("Config", path);
118
+ head.push(span(" "), span(save ? "persist" : "session", save ? "accent strong" : "muted"));
119
+ if (details?.outcome === "declined") head.push(span(" "), span("declined", "warning strong"));
120
+ if (details?.outcome === "unchanged") head.push(span(" "), span("unchanged", "muted"));
121
+ const next = span(plainText(details?.value ?? content?.trim() ?? "…"), "toolOutput");
122
+ const change = details
123
+ ? [span(plainText(details.previous), "dim"), span(" → ", "dim"), next]
124
+ : [span("→ ", "dim"), next];
125
+ return {
126
+ head,
127
+ tone: details?.outcome === "declined" ? "warning" : undefined,
128
+ body: compact([
129
+ text(change, { wrap: "word" }),
130
+ details?.effective !== undefined
131
+ ? text(
132
+ [
133
+ span(
134
+ `still ${plainText(details.effective)}: a higher-precedence layer overrides the saved value`,
135
+ "warning",
136
+ ),
137
+ ],
138
+ { wrap: "word" },
139
+ )
140
+ : undefined,
141
+ ]),
142
+ };
143
+ }
144
+
80
145
  /** Render `write cfg://…[/save]`: the proposed value while pending, then the approved/declined change. */
81
146
  export function renderCfgWrite(
82
147
  url: string,
@@ -11,7 +11,11 @@ import {
11
11
  TRUNCATE_LENGTHS,
12
12
  truncateToWidth,
13
13
  } from "../render/render-utils";
14
- import type { RenderResultOptions, ToolRenderer } from "./renderer";
14
+ import type { NativeToolView, RenderResultOptions, ToolRenderer, ToolRenderResult } from "./renderer";
15
+ import { ansi, kv } from "../native/describe";
16
+ import type { NativeChild } from "../native/node";
17
+ import { OwnerMemo } from "../native/memo";
18
+ import { errorView, noteText, resultText, toolHead } from "./native-view";
15
19
 
16
20
  /** Display fields captured from a debugger session. */
17
21
  export interface DebugSessionSnapshot {
@@ -115,6 +119,68 @@ function summarizeDebugCall(args: DebugRenderArgs): string {
115
119
  return action;
116
120
  }
117
121
 
122
+ /** Untruncated `[action, target]` for native heads; mirrors {@link summarizeDebugCall}'s field precedence. */
123
+ function debugCallParts(args: DebugRenderArgs | undefined, fallbackAction: string): [string, string | undefined] {
124
+ const action = (args?.action ?? fallbackAction).replaceAll("_", " ");
125
+ if (!args) return [action, undefined];
126
+ const target =
127
+ args.program ||
128
+ (args.file && args.line !== undefined ? `${args.file}:${args.line}` : undefined) ||
129
+ args.function ||
130
+ args.expression ||
131
+ args.command ||
132
+ args.memory_reference ||
133
+ args.instruction_reference ||
134
+ args.data_id ||
135
+ args.name ||
136
+ undefined;
137
+ return [action, target];
138
+ }
139
+
140
+ function describeDebugResult(
141
+ result: ToolRenderResult<DebugToolDetails>,
142
+ args: DebugRenderArgs | undefined,
143
+ ): NativeToolView {
144
+ const [action, target] = debugCallParts(args, result.details?.action ?? "debug");
145
+ const output = resultText(result);
146
+ if (result.isError) return errorView("Debug", output || "Debug failed", action, target);
147
+ const snapshot = result.details?.snapshot;
148
+ const body: NativeChild[] = [];
149
+ let sessionRows = 0;
150
+ if (snapshot) {
151
+ const location = formatLocation(snapshot);
152
+ const rows: [string, string | undefined][] = [
153
+ ["Session", snapshot.id],
154
+ ["Adapter", snapshot.adapter],
155
+ ["Status", snapshot.status],
156
+ ["CWD", snapshot.cwd],
157
+ ["Program", snapshot.program],
158
+ ["Stop reason", snapshot.stopReason],
159
+ ["Frame", snapshot.frameName],
160
+ ["Instruction pointer", snapshot.instructionPointerReference],
161
+ ["Location", location ?? undefined],
162
+ [
163
+ "Configuration",
164
+ snapshot.needsConfigurationDone ? "pending configurationDone; set breakpoints, then continue." : undefined,
165
+ ],
166
+ ["Exit code", snapshot.exitCode !== undefined ? String(snapshot.exitCode) : undefined],
167
+ ];
168
+ const grid = kv(rows);
169
+ if (grid) {
170
+ body.push(grid);
171
+ sessionRows = rows.filter(([, value]) => value).length;
172
+ }
173
+ }
174
+ body.push(output ? ansi(output) : noteText("No output"));
175
+ return {
176
+ head: toolHead("Debug", action, target),
177
+ body,
178
+ preview: { lines: sessionRows + PREVIEW_LIMITS.COLLAPSED_LINES },
179
+ };
180
+ }
181
+
182
+ const debugResultMemo = new OwnerMemo<NativeToolView | undefined>();
183
+
118
184
  /** Renders debugger calls and captured execution snapshots. */
119
185
  export const debugToolRenderer = {
120
186
  animatedPartialResult: true,
@@ -162,6 +228,17 @@ export const debugToolRenderer = {
162
228
  };
163
229
  });
164
230
  },
231
+ describeCall(args: DebugRenderArgs): NativeToolView {
232
+ const [action, target] = debugCallParts(args, "request");
233
+ return { head: toolHead("Debug", action, target) };
234
+ },
235
+ describeResult(
236
+ result: ToolRenderResult<DebugToolDetails>,
237
+ _options: RenderResultOptions,
238
+ args?: DebugRenderArgs,
239
+ ): NativeToolView | undefined {
240
+ return debugResultMemo.get(result, [], () => describeDebugResult(result, args));
241
+ },
165
242
  mergeCallAndResult: true,
166
243
  inline: true,
167
244
  } satisfies ToolRenderer<DebugRenderArgs, DebugToolDetails>;
@@ -1,12 +1,15 @@
1
1
  import type { Component } from "../index";
2
2
  import { isRecord } from "@oh-my-pi/pi-utils";
3
- import type { RenderResultOptions } from "./renderer";
3
+ import type { NativeToolHead, NativeToolView, RenderResultOptions } from "./renderer";
4
+ import { ansi } from "../native/describe";
5
+ import { noteText } from "./native-view";
4
6
  import type { Theme } from "../theme/theme";
5
7
  import { formatOutputPaneLines, styleToolOutputLine } from "../render/output-pane";
6
8
  import { renderStatusLine, type StatusLineOptions } from "../render/status-line";
7
9
  import { plainToolCard, type ToolCardPhase } from "../render/tool-card";
8
10
  import { truncateToWidth } from "../render/render-utils";
9
11
  import {
12
+ describeJsonTree,
10
13
  formatArgsInline,
11
14
  JSON_TREE_MAX_DEPTH_COLLAPSED,
12
15
  JSON_TREE_MAX_DEPTH_EXPANDED,
@@ -159,6 +162,37 @@ export function formatDefaultToolExecution(
159
162
  return [renderStatusLine(snapshot.status, uiTheme), ...snapshot.body].join("\n");
160
163
  }
161
164
 
165
+ /** Inline args summary budget in characters (a data cap, not a width). */
166
+ const NATIVE_ARGS_SUMMARY_CHARS = 160;
167
+ /** Result text kept for the native card body. */
168
+ const NATIVE_RESULT_MAX_CHARS = 64 * 1024;
169
+
170
+ /**
171
+ * TSP view of the generic fallback card: the tool label with a one-line args
172
+ * summary as the head target; the result as a JSON tree or raw `ansi` output.
173
+ */
174
+ export function describeDefaultToolExecution(input: DefaultToolRenderInput): NativeToolView {
175
+ const { result } = input;
176
+ const args = isRecord(input.args) ? input.args : undefined;
177
+ const summary =
178
+ args && Object.keys(args).length > 0
179
+ ? formatArgsInline(args, NATIVE_ARGS_SUMMARY_CHARS, { characterBudget: true })
180
+ : undefined;
181
+ const tool: NativeToolHead = { title: input.label, target: summary || undefined, targetKind: "text" };
182
+ if (!result) return { tool };
183
+ const output = result.output.trimEnd().slice(0, NATIVE_RESULT_MAX_CHARS);
184
+ const tone = result.skipped ? "info" : result.isError ? "error" : undefined;
185
+ if (!output) return { tool, tone, body: [noteText("(no output)")] };
186
+ if (output.startsWith("{") || output.startsWith("[")) {
187
+ try {
188
+ return { tool, tone, body: [describeJsonTree(JSON.parse(output))] };
189
+ } catch {
190
+ // Not JSON: shown as raw output below.
191
+ }
192
+ }
193
+ return { tool, tone, body: [ansi(output)] };
194
+ }
195
+
162
196
  /** Render the generic fallback as the state-tinted card used by direct custom tools. */
163
197
  export function renderDefaultToolExecution(input: DefaultToolRenderInput, uiTheme: Theme): Component {
164
198
  return plainToolCard(