@opengeni/react 3.1.0 → 3.1.3-canary.38890816741001

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 (863) hide show
  1. package/README.md +769 -22
  2. package/dist/accounts.js +89 -11
  3. package/dist/accounts.js.map +1 -1
  4. package/dist/approvals.d.ts +2 -1
  5. package/dist/artifacts-document.js +5 -3
  6. package/dist/artifacts-presentation.js +5 -3
  7. package/dist/artifacts-spreadsheet.d.ts +1 -1
  8. package/dist/artifacts-spreadsheet.js +5 -3
  9. package/dist/artifacts.d.ts +5 -1
  10. package/dist/artifacts.js +536 -42
  11. package/dist/artifacts.js.map +1 -1
  12. package/dist/browser-viewer-ZWR6MWJ7.js +19 -0
  13. package/dist/capability-catalog-row.d.ts +20 -0
  14. package/dist/capability-logo-fallback.d.ts +3 -0
  15. package/dist/chat-interactive-block-BO2IWXVK.js +14 -0
  16. package/dist/chunk-2DDJ6YH6.js +41 -0
  17. package/dist/chunk-2DDJ6YH6.js.map +1 -0
  18. package/dist/chunk-2HVLQ26H.js +183 -0
  19. package/dist/chunk-2HVLQ26H.js.map +1 -0
  20. package/dist/{chunk-RGALCTWO.js → chunk-2I6R3GCZ.js} +4285 -3980
  21. package/dist/chunk-2I6R3GCZ.js.map +1 -0
  22. package/dist/{chunk-D3UIAJKY.js → chunk-2SFFYIH3.js} +1179 -166
  23. package/dist/chunk-2SFFYIH3.js.map +1 -0
  24. package/dist/chunk-3PVDYTTB.js +24 -0
  25. package/dist/chunk-3PVDYTTB.js.map +1 -0
  26. package/dist/chunk-3UZCWK46.js +298 -0
  27. package/dist/chunk-3UZCWK46.js.map +1 -0
  28. package/dist/chunk-47CKUXTW.js +293 -0
  29. package/dist/chunk-47CKUXTW.js.map +1 -0
  30. package/dist/chunk-4QYP6QUI.js +109 -0
  31. package/dist/chunk-4QYP6QUI.js.map +1 -0
  32. package/dist/chunk-5EY26VZ7.js +1053 -0
  33. package/dist/chunk-5EY26VZ7.js.map +1 -0
  34. package/dist/chunk-5I4VRWBB.js +56 -0
  35. package/dist/chunk-5I4VRWBB.js.map +1 -0
  36. package/dist/chunk-5WOR7UCL.js +191 -0
  37. package/dist/chunk-5WOR7UCL.js.map +1 -0
  38. package/dist/chunk-5YJLGOM5.js +51 -0
  39. package/dist/chunk-5YJLGOM5.js.map +1 -0
  40. package/dist/chunk-6JFN3OWG.js +386 -0
  41. package/dist/chunk-6JFN3OWG.js.map +1 -0
  42. package/dist/chunk-7QJT5O4S.js +35 -0
  43. package/dist/chunk-7QJT5O4S.js.map +1 -0
  44. package/dist/chunk-A55KV72M.js +402 -0
  45. package/dist/chunk-A55KV72M.js.map +1 -0
  46. package/dist/chunk-ADWCLI4G.js +2028 -0
  47. package/dist/chunk-ADWCLI4G.js.map +1 -0
  48. package/dist/chunk-B27E3V37.js +29 -0
  49. package/dist/chunk-B27E3V37.js.map +1 -0
  50. package/dist/chunk-B7TC2A33.js +83 -0
  51. package/dist/chunk-B7TC2A33.js.map +1 -0
  52. package/dist/chunk-BLL56F7R.js +385 -0
  53. package/dist/chunk-BLL56F7R.js.map +1 -0
  54. package/dist/chunk-BOFEQC6K.js +162 -0
  55. package/dist/chunk-BOFEQC6K.js.map +1 -0
  56. package/dist/chunk-CM7LVUKC.js +35 -0
  57. package/dist/chunk-CM7LVUKC.js.map +1 -0
  58. package/dist/chunk-CORUP6JB.js +122 -0
  59. package/dist/chunk-CORUP6JB.js.map +1 -0
  60. package/dist/chunk-CSX5FFKZ.js +35 -0
  61. package/dist/chunk-CSX5FFKZ.js.map +1 -0
  62. package/dist/chunk-EGVHJKGJ.js +3125 -0
  63. package/dist/chunk-EGVHJKGJ.js.map +1 -0
  64. package/dist/{chunk-NEXLLTP4.js → chunk-G76LSA76.js} +6 -5
  65. package/dist/chunk-G76LSA76.js.map +1 -0
  66. package/dist/{chunk-PEI6RANI.js → chunk-GQMRL52F.js} +311 -75
  67. package/dist/chunk-GQMRL52F.js.map +1 -0
  68. package/dist/{chunk-ELIYWBZR.js → chunk-GUUXOISA.js} +1113 -457
  69. package/dist/chunk-GUUXOISA.js.map +1 -0
  70. package/dist/{chunk-HUIKIDM5.js → chunk-I7X2P4FU.js} +225 -116
  71. package/dist/chunk-I7X2P4FU.js.map +1 -0
  72. package/dist/chunk-IGFZFLI2.js +1390 -0
  73. package/dist/chunk-IGFZFLI2.js.map +1 -0
  74. package/dist/{chunk-4MDLEHXL.js → chunk-IMSUVYQB.js} +26 -13
  75. package/dist/chunk-IMSUVYQB.js.map +1 -0
  76. package/dist/chunk-IOYHDEP3.js +38 -0
  77. package/dist/chunk-IOYHDEP3.js.map +1 -0
  78. package/dist/chunk-IZV5FTJC.js +55 -0
  79. package/dist/chunk-IZV5FTJC.js.map +1 -0
  80. package/dist/chunk-KF33GTWN.js +343 -0
  81. package/dist/chunk-KF33GTWN.js.map +1 -0
  82. package/dist/chunk-KSGQ5ODA.js +457 -0
  83. package/dist/chunk-KSGQ5ODA.js.map +1 -0
  84. package/dist/{chunk-OAM4WAAM.js → chunk-KZC6QRNR.js} +1513 -697
  85. package/dist/chunk-KZC6QRNR.js.map +1 -0
  86. package/dist/chunk-LJUMYUBO.js +218 -0
  87. package/dist/chunk-LJUMYUBO.js.map +1 -0
  88. package/dist/chunk-LSW2OJVV.js +380 -0
  89. package/dist/chunk-LSW2OJVV.js.map +1 -0
  90. package/dist/chunk-M357MHH3.js +2 -0
  91. package/dist/chunk-M357MHH3.js.map +1 -0
  92. package/dist/chunk-MK2TQO4Y.js +24 -0
  93. package/dist/chunk-MK2TQO4Y.js.map +1 -0
  94. package/dist/chunk-N7S72EXK.js +25 -0
  95. package/dist/chunk-N7S72EXK.js.map +1 -0
  96. package/dist/{chunk-XXWH2JLC.js → chunk-NKMYZFHA.js} +616 -621
  97. package/dist/chunk-NKMYZFHA.js.map +1 -0
  98. package/dist/chunk-NX4ADH73.js +14 -0
  99. package/dist/chunk-NX4ADH73.js.map +1 -0
  100. package/dist/chunk-O7F6UJO4.js +71 -0
  101. package/dist/chunk-O7F6UJO4.js.map +1 -0
  102. package/dist/chunk-OVB5WIG5.js +14064 -0
  103. package/dist/chunk-OVB5WIG5.js.map +1 -0
  104. package/dist/chunk-OYQQJL3J.js +16 -0
  105. package/dist/chunk-OYQQJL3J.js.map +1 -0
  106. package/dist/{chunk-H5YGYNXS.js → chunk-P4BNUO57.js} +60 -17
  107. package/dist/chunk-P4BNUO57.js.map +1 -0
  108. package/dist/{chunk-JVYQRRC4.js → chunk-PEHTX3V7.js} +21 -1
  109. package/dist/chunk-PEHTX3V7.js.map +1 -0
  110. package/dist/chunk-PMV53IMM.js +26 -0
  111. package/dist/chunk-PMV53IMM.js.map +1 -0
  112. package/dist/{chunk-KCGXPP5V.js → chunk-PYEOPA4M.js} +13 -7
  113. package/dist/chunk-PYEOPA4M.js.map +1 -0
  114. package/dist/{chunk-KZ73RL76.js → chunk-QHUE7E4N.js} +8 -3
  115. package/dist/chunk-QHUE7E4N.js.map +1 -0
  116. package/dist/chunk-QV3DJVRZ.js +11 -0
  117. package/dist/chunk-QV3DJVRZ.js.map +1 -0
  118. package/dist/chunk-R5SBNG7S.js +810 -0
  119. package/dist/chunk-R5SBNG7S.js.map +1 -0
  120. package/dist/chunk-RI42H5IU.js +326 -0
  121. package/dist/chunk-RI42H5IU.js.map +1 -0
  122. package/dist/chunk-S2QH6EZ5.js +211 -0
  123. package/dist/chunk-S2QH6EZ5.js.map +1 -0
  124. package/dist/chunk-SHLZMAJN.js +304 -0
  125. package/dist/chunk-SHLZMAJN.js.map +1 -0
  126. package/dist/chunk-TGXK4BAZ.js +293 -0
  127. package/dist/chunk-TGXK4BAZ.js.map +1 -0
  128. package/dist/{chunk-5YK2ZDIG.js → chunk-TNEZNMSN.js} +4 -10
  129. package/dist/chunk-TNEZNMSN.js.map +1 -0
  130. package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
  131. package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
  132. package/dist/chunk-UNJPZGNK.js +63 -0
  133. package/dist/chunk-UNJPZGNK.js.map +1 -0
  134. package/dist/{chunk-MZ2G2XBA.js → chunk-V5ZUJT2T.js} +205 -45
  135. package/dist/chunk-V5ZUJT2T.js.map +1 -0
  136. package/dist/chunk-VIUEOHXY.js +394 -0
  137. package/dist/chunk-VIUEOHXY.js.map +1 -0
  138. package/dist/chunk-WIUKB3LD.js +1911 -0
  139. package/dist/chunk-WIUKB3LD.js.map +1 -0
  140. package/dist/{chunk-ICA6R6TW.js → chunk-WNN7NO2N.js} +1451 -355
  141. package/dist/chunk-WNN7NO2N.js.map +1 -0
  142. package/dist/{chunk-YJFGAFBD.js → chunk-X5UVUIMF.js} +1892 -1223
  143. package/dist/chunk-X5UVUIMF.js.map +1 -0
  144. package/dist/chunk-XDA5QJE7.js +402 -0
  145. package/dist/chunk-XDA5QJE7.js.map +1 -0
  146. package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
  147. package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
  148. package/dist/chunk-XHF7OYAN.js +1150 -0
  149. package/dist/chunk-XHF7OYAN.js.map +1 -0
  150. package/dist/chunk-YSRBFJMQ.js +43 -0
  151. package/dist/chunk-YSRBFJMQ.js.map +1 -0
  152. package/dist/chunk-ZOZAPAUO.js +174 -0
  153. package/dist/chunk-ZOZAPAUO.js.map +1 -0
  154. package/dist/chunk-ZQV5W7YC.js +809 -0
  155. package/dist/chunk-ZQV5W7YC.js.map +1 -0
  156. package/dist/chunk-ZUWF4NF7.js +13 -0
  157. package/dist/chunk-ZUWF4NF7.js.map +1 -0
  158. package/dist/client.d.ts +16 -7
  159. package/dist/clipboard.js +3 -1
  160. package/dist/commands/types.d.ts +2 -0
  161. package/dist/components/anthropic-mark.d.ts +3 -0
  162. package/dist/components/approval-surface.d.ts +19 -6
  163. package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
  164. package/dist/components/artifacts/artifact-sandbox.d.ts +30 -0
  165. package/dist/components/artifacts/artifact-surface.d.ts +4 -2
  166. package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
  167. package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
  168. package/dist/components/artifacts/document-editor.d.ts +4 -2
  169. package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
  170. package/dist/components/artifacts/editable-artifact-view.d.ts +48 -0
  171. package/dist/components/artifacts/editable-document.d.ts +1 -1
  172. package/dist/components/artifacts/editable-presentation.d.ts +2 -2
  173. package/dist/components/artifacts/editable-spreadsheet.d.ts +8 -3
  174. package/dist/components/artifacts/index.d.ts +9 -2
  175. package/dist/components/artifacts/inline-html-document.d.ts +2 -0
  176. package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
  177. package/dist/components/artifacts/presentation-editor.d.ts +6 -2
  178. package/dist/components/artifacts/published-html-artifact-frame.d.ts +23 -3
  179. package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
  180. package/dist/components/artifacts/site-view.d.ts +26 -0
  181. package/dist/components/artifacts/spreadsheet-command-queue.d.ts +20 -0
  182. package/dist/components/artifacts/spreadsheet-download.d.ts +7 -0
  183. package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
  184. package/dist/components/artifacts/spreadsheet-grid.d.ts +10 -3
  185. package/dist/components/artifacts/spreadsheet-resize.d.ts +50 -0
  186. package/dist/components/artifacts/spreadsheet-submissions.d.ts +9 -0
  187. package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
  188. package/dist/components/browser-select-control.d.ts +16 -0
  189. package/dist/components/browser-viewer.d.ts +11 -2
  190. package/dist/components/chat-composer.d.ts +21 -3
  191. package/dist/components/child-session-link.d.ts +9 -0
  192. package/dist/components/claude-mark.d.ts +3 -0
  193. package/dist/components/code-editor.d.ts +1 -4
  194. package/dist/components/composer-transcription-control.d.ts +7 -0
  195. package/dist/components/composer.d.ts +34 -67
  196. package/dist/components/computer-viewer.d.ts +1 -1
  197. package/dist/components/copy-button.d.ts +3 -1
  198. package/dist/components/desktop-viewer.d.ts +1 -1
  199. package/dist/components/fleet-tile.d.ts +2 -2
  200. package/dist/components/grok-mark.d.ts +26 -0
  201. package/dist/components/human-input-form.d.ts +28 -32
  202. package/dist/components/human-input-surface.d.ts +7 -2
  203. package/dist/components/linkified-text.d.ts +18 -0
  204. package/dist/components/machine-input-display.d.ts +22 -1
  205. package/dist/components/machines/agent-status-icon.d.ts +6 -0
  206. package/dist/components/machines/machine-detail.d.ts +7 -1
  207. package/dist/components/machines/machine-status.d.ts +48 -0
  208. package/dist/components/markdown-table-layout.d.ts +18 -0
  209. package/dist/components/markdown.d.ts +37 -4
  210. package/dist/components/message-timeline.d.ts +86 -7
  211. package/dist/components/model-mark.d.ts +29 -0
  212. package/dist/components/model-policy-picker-menu.d.ts +9 -0
  213. package/dist/components/model-policy-picker.d.ts +41 -25
  214. package/dist/components/new-conversation.d.ts +32 -0
  215. package/dist/components/open-geni-chat.d.ts +73 -0
  216. package/dist/components/open-geni-links.d.ts +68 -0
  217. package/dist/components/openrouter-mark.d.ts +6 -0
  218. package/dist/components/opper-mark.d.ts +7 -0
  219. package/dist/components/preview-loading.d.ts +2 -0
  220. package/dist/components/provider-recovery-notice.d.ts +16 -0
  221. package/dist/components/queue-item-content.d.ts +9 -0
  222. package/dist/components/rehype-secret-refs.d.ts +23 -0
  223. package/dist/components/remark-soft-line-breaks.d.ts +38 -0
  224. package/dist/components/sandbox-files.d.ts +3 -1
  225. package/dist/components/sandbox-workspace.d.ts +18 -0
  226. package/dist/components/secret-question-field.d.ts +31 -0
  227. package/dist/components/secret-ref-chip.d.ts +35 -0
  228. package/dist/components/session-capability-frame.d.ts +37 -0
  229. package/dist/components/session-chrome.d.ts +57 -8
  230. package/dist/components/session-commands-panel.d.ts +6 -0
  231. package/dist/components/session-commands.d.ts +6 -0
  232. package/dist/components/session-connection-request.d.ts +8 -0
  233. package/dist/components/session-conversation.d.ts +157 -0
  234. package/dist/components/session-list.d.ts +39 -0
  235. package/dist/components/session-mcp-capability-card.d.ts +41 -0
  236. package/dist/components/session-proxy-scope.d.ts +35 -0
  237. package/dist/components/session-status.d.ts +4 -1
  238. package/dist/components/session-usage-limit-notice.d.ts +39 -0
  239. package/dist/components/timeline-anchor.d.ts +24 -0
  240. package/dist/components/timeline-annotation-chrome.d.ts +25 -0
  241. package/dist/components/timeline-annotation-layout.d.ts +42 -0
  242. package/dist/components/timeline-annotation-markers.d.ts +8 -0
  243. package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
  244. package/dist/components/timeline-annotation-shared.d.ts +31 -0
  245. package/dist/components/timeline-annotations-dialog.d.ts +3 -2
  246. package/dist/components/timeline-annotations.d.ts +13 -3
  247. package/dist/components/timeline-reading-progress.d.ts +11 -0
  248. package/dist/components/timeline-search.d.ts +34 -0
  249. package/dist/components/timeline-settlement.d.ts +16 -0
  250. package/dist/components/tip-follow.d.ts +16 -0
  251. package/dist/components/tool-action-review.d.ts +47 -0
  252. package/dist/components/tool-review-history.d.ts +25 -0
  253. package/dist/components/usage-limit-notice.d.ts +49 -0
  254. package/dist/components/usage-member-list.d.ts +91 -0
  255. package/dist/components/usage-meter.d.ts +73 -0
  256. package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
  257. package/dist/components/user-message-body.d.ts +10 -1
  258. package/dist/composer-messages.d.ts +74 -0
  259. package/dist/composer-messages.js +9 -0
  260. package/dist/composer-messages.js.map +1 -0
  261. package/dist/composer-voice-events.d.ts +8 -0
  262. package/dist/composer.d.ts +5 -4
  263. package/dist/composer.js +26 -13
  264. package/dist/computer-viewer-GMLDXPON.js +20 -0
  265. package/dist/computer-viewer-GMLDXPON.js.map +1 -0
  266. package/dist/connect-account-identity.d.ts +8 -0
  267. package/dist/connect-accounts.d.ts +15 -0
  268. package/dist/connect-chooser.d.ts +18 -0
  269. package/dist/connect-panel.d.ts +18 -0
  270. package/dist/connect-setup.d.ts +18 -0
  271. package/dist/connect.d.ts +21 -0
  272. package/dist/connect.js +2149 -0
  273. package/dist/connect.js.map +1 -0
  274. package/dist/connection-catalog.d.ts +38 -0
  275. package/dist/connection-discovery.d.ts +12 -0
  276. package/dist/connection-installed.d.ts +17 -0
  277. package/dist/connection-logo.d.ts +9 -0
  278. package/dist/connection-service-logo.d.ts +8 -0
  279. package/dist/connection-service-presentation.d.ts +13 -0
  280. package/dist/connection-skeleton.d.ts +5 -0
  281. package/dist/connection-type-picker.d.ts +6 -0
  282. package/dist/conversation-timeline.d.ts +5 -0
  283. package/dist/desktop.d.ts +7 -0
  284. package/dist/desktop.js +27 -0
  285. package/dist/desktop.js.map +1 -0
  286. package/dist/device-authorization.d.ts +23 -0
  287. package/dist/diffs.d.ts +8 -0
  288. package/dist/diffs.js +15 -0
  289. package/dist/diffs.js.map +1 -0
  290. package/dist/discovery-cache.d.ts +5 -0
  291. package/dist/editor.d.ts +7 -0
  292. package/dist/editor.js +22 -0
  293. package/dist/editor.js.map +1 -0
  294. package/dist/embedded-new-voice-OCRNT6U5.js +18 -0
  295. package/dist/embedded-new-voice-OCRNT6U5.js.map +1 -0
  296. package/dist/embedded-voice-RPHPYVBT.js +18 -0
  297. package/dist/embedded-voice-RPHPYVBT.js.map +1 -0
  298. package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-SI63O5V4.js} +4 -1
  299. package/dist/fleet-decision-row-SI63O5V4.js.map +1 -0
  300. package/dist/hooks/latest-question.d.ts +25 -0
  301. package/dist/hooks/shared-machines-list.d.ts +4 -0
  302. package/dist/hooks/shared-query.d.ts +113 -0
  303. package/dist/hooks/use-attached-browsers.d.ts +1 -1
  304. package/dist/hooks/use-auth-runs.d.ts +1 -4
  305. package/dist/hooks/use-available-models.d.ts +1 -1
  306. package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
  307. package/dist/hooks/use-browser-session.d.ts +12 -1
  308. package/dist/hooks/use-client-config-flags.d.ts +49 -0
  309. package/dist/hooks/use-codex-accounts.d.ts +59 -10
  310. package/dist/hooks/use-composer.d.ts +24 -2
  311. package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
  312. package/dist/hooks/use-computer-input-posture.d.ts +13 -0
  313. package/dist/hooks/use-computer-session.d.ts +4 -0
  314. package/dist/hooks/use-connect.d.ts +23 -0
  315. package/dist/hooks/use-desktop-stream.d.ts +1 -1
  316. package/dist/hooks/use-file-attachments.d.ts +12 -0
  317. package/dist/hooks/use-goal.d.ts +2 -1
  318. package/dist/hooks/use-last-started-turn-policy.d.ts +5 -1
  319. package/dist/hooks/use-new-conversation.d.ts +56 -0
  320. package/dist/hooks/use-new-session-draft.d.ts +74 -0
  321. package/dist/hooks/use-realtime-voice-models.d.ts +7 -0
  322. package/dist/hooks/use-sandbox-files.d.ts +4 -1
  323. package/dist/hooks/use-session-conversation.d.ts +49 -0
  324. package/dist/hooks/use-session-events.d.ts +28 -7
  325. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  326. package/dist/hooks/use-session-model-account.d.ts +48 -0
  327. package/dist/hooks/use-supergrok-accounts.d.ts +7 -1
  328. package/dist/hooks/use-terminal-stream.d.ts +11 -5
  329. package/dist/hooks/use-usage.d.ts +40 -0
  330. package/dist/hooks/use-vaults.d.ts +53 -0
  331. package/dist/hooks/use-voice-input.d.ts +8 -1
  332. package/dist/hooks/use-workspace-edit.d.ts +4 -0
  333. package/dist/hooks/use-workspace-sessions.d.ts +22 -5
  334. package/dist/human-input-model.d.ts +122 -0
  335. package/dist/identity-link-accounts.d.ts +11 -0
  336. package/dist/identity-link-consent.d.ts +18 -0
  337. package/dist/index.d.ts +82 -20
  338. package/dist/index.js +2350 -6605
  339. package/dist/index.js.map +1 -1
  340. package/dist/interaction.d.ts +1 -1
  341. package/dist/interaction.js +14 -24
  342. package/dist/interaction.js.map +1 -1
  343. package/dist/latest-question-R77KWSUP.js +118 -0
  344. package/dist/latest-question-R77KWSUP.js.map +1 -0
  345. package/dist/lib/clipboard.d.ts +7 -0
  346. package/dist/lib/error-message.d.ts +7 -0
  347. package/dist/lib/format.d.ts +58 -4
  348. package/dist/lib/host-theme.d.ts +77 -0
  349. package/dist/lib/interaction-errors.d.ts +3 -0
  350. package/dist/lib/menu-styles.d.ts +22 -0
  351. package/dist/lib/notify-observer.d.ts +2 -0
  352. package/dist/lib/pierre-diffs-loader.d.ts +20 -0
  353. package/dist/lib/provider-recovery.d.ts +55 -0
  354. package/dist/lib/scrollbars.d.ts +11 -0
  355. package/dist/lib/terminal-input-readiness.d.ts +11 -0
  356. package/dist/lib/transient-retry.d.ts +25 -0
  357. package/dist/lib/workbench-peers.d.ts +36 -0
  358. package/dist/lib/xterm-theme.d.ts +7 -5
  359. package/dist/machines.js +9 -5
  360. package/dist/markdown-table-layout-3PV2UAAH.js +113 -0
  361. package/dist/markdown-table-layout-3PV2UAAH.js.map +1 -0
  362. package/dist/mcp-connection-status.d.ts +14 -0
  363. package/dist/model-mark-paths.d.ts +34 -0
  364. package/dist/model-mark-paths.js +16 -0
  365. package/dist/model-mark-paths.js.map +1 -0
  366. package/dist/model-picker-model.d.ts +111 -0
  367. package/dist/model-picker-model.js +25 -0
  368. package/dist/model-picker-model.js.map +1 -0
  369. package/dist/model-policy-picker-menu-7GJ5URPR.js +17 -0
  370. package/dist/model-policy-picker-menu-7GJ5URPR.js.map +1 -0
  371. package/dist/model-policy.d.ts +30 -3
  372. package/dist/model-policy.js +14 -1
  373. package/dist/native-previews.d.ts +28 -0
  374. package/dist/native-previews.js +82 -0
  375. package/dist/native-previews.js.map +1 -0
  376. package/dist/new-session-draft.d.ts +7 -0
  377. package/dist/new-session-draft.js +639 -0
  378. package/dist/new-session-draft.js.map +1 -0
  379. package/dist/notification-text.d.ts +27 -0
  380. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
  381. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
  382. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
  383. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
  384. package/dist/older-history.d.ts +3 -2
  385. package/dist/organization-model.d.ts +32 -0
  386. package/dist/organization-model.js +65 -0
  387. package/dist/organization-model.js.map +1 -0
  388. package/dist/{platform-activity-row-BJHUHXAT.js → platform-activity-row-5OCKOQWZ.js} +16 -78
  389. package/dist/platform-activity-row-5OCKOQWZ.js.map +1 -0
  390. package/dist/plugin-details.d.ts +14 -0
  391. package/dist/plugin-discovery.d.ts +25 -0
  392. package/dist/preview-loading-paint.d.ts +20 -0
  393. package/dist/provider.d.ts +25 -2
  394. package/dist/queue-presentation-model.d.ts +72 -0
  395. package/dist/queue-presentation-model.js +38 -0
  396. package/dist/queue-presentation-model.js.map +1 -0
  397. package/dist/{queue-surface-implementation-BSKUWHRI.js → queue-surface-implementation-GJBH7NKO.js} +65 -265
  398. package/dist/queue-surface-implementation-GJBH7NKO.js.map +1 -0
  399. package/dist/realtime/embedded-new-voice.d.ts +1 -0
  400. package/dist/realtime/embedded-voice.d.ts +1 -0
  401. package/dist/realtime/realtime-control.d.ts +4 -65
  402. package/dist/realtime/session-realtime.d.ts +78 -0
  403. package/dist/realtime.js +25 -1294
  404. package/dist/realtime.js.map +1 -1
  405. package/dist/sandbox-files-O27IPOZW.js +21 -0
  406. package/dist/sandbox-files-O27IPOZW.js.map +1 -0
  407. package/dist/sandbox-label-model.d.ts +30 -0
  408. package/dist/sandbox-label-model.js +20 -0
  409. package/dist/sandbox-label-model.js.map +1 -0
  410. package/dist/scrollbars.d.ts +1 -0
  411. package/dist/scrollbars.js +10 -0
  412. package/dist/scrollbars.js.map +1 -0
  413. package/dist/secret-reference-label.d.ts +14 -0
  414. package/dist/secrets-ui.d.ts +57 -0
  415. package/dist/session-agents-model.d.ts +10 -0
  416. package/dist/session-agents-model.js +25 -0
  417. package/dist/session-agents-model.js.map +1 -0
  418. package/dist/session-attention-model.d.ts +8 -0
  419. package/dist/session-attention-model.js +47 -0
  420. package/dist/session-attention-model.js.map +1 -0
  421. package/dist/session-auth-recommendation.d.ts +5 -0
  422. package/dist/session-capability-policy.d.ts +31 -0
  423. package/dist/session-feedback-model.d.ts +20 -0
  424. package/dist/session-feedback-model.js +56 -0
  425. package/dist/session-feedback-model.js.map +1 -0
  426. package/dist/session-list-model.d.ts +138 -0
  427. package/dist/session-list-model.js +274 -0
  428. package/dist/session-list-model.js.map +1 -0
  429. package/dist/session-realtime-7DJOIHQW.js +21 -0
  430. package/dist/session-realtime-7DJOIHQW.js.map +1 -0
  431. package/dist/session-realtime.d.ts +7 -0
  432. package/dist/session-realtime.js +19 -0
  433. package/dist/session-realtime.js.map +1 -0
  434. package/dist/session-status-model.d.ts +36 -0
  435. package/dist/session-ui.d.ts +39 -1
  436. package/dist/session-ui.js +126 -12
  437. package/dist/session-ui.js.map +1 -1
  438. package/dist/session.d.ts +8 -2
  439. package/dist/session.js +35 -20
  440. package/dist/site-snapshot.d.ts +14 -0
  441. package/dist/sites-ui.d.ts +24 -0
  442. package/dist/sites.d.ts +3 -0
  443. package/dist/sites.js +14 -0
  444. package/dist/sites.js.map +1 -0
  445. package/dist/skill-discovery.d.ts +47 -0
  446. package/dist/terminal.d.ts +8 -0
  447. package/dist/terminal.js +32 -0
  448. package/dist/terminal.js.map +1 -0
  449. package/dist/testing/session-scenarios.d.ts +10 -0
  450. package/dist/testing/session-scenarios.js +367 -0
  451. package/dist/testing/session-scenarios.js.map +1 -0
  452. package/dist/timeline/activity-rail.d.ts +11 -2
  453. package/dist/timeline/agent-identity.d.ts +30 -0
  454. package/dist/timeline/agent-row.d.ts +31 -0
  455. package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
  456. package/dist/timeline/compaction-copy.d.ts +46 -0
  457. package/dist/timeline/entrance.d.ts +13 -1
  458. package/dist/timeline/focus-sequence.d.ts +9 -0
  459. package/dist/timeline/genie-copy.d.ts +3 -0
  460. package/dist/timeline/genie-loading.d.ts +47 -0
  461. package/dist/timeline/index.d.ts +10 -5
  462. package/dist/timeline/knowledge-receipt.d.ts +17 -0
  463. package/dist/timeline/message-sender.d.ts +19 -0
  464. package/dist/timeline/notice-presentation.d.ts +13 -0
  465. package/dist/timeline/parsers.d.ts +11 -0
  466. package/dist/timeline/patch-apply-command.d.ts +18 -0
  467. package/dist/timeline/platform-activity-presentation.d.ts +21 -0
  468. package/dist/timeline/platform-activity-row.d.ts +1 -2
  469. package/dist/timeline/presented-image.d.ts +11 -0
  470. package/dist/timeline/projection.d.ts +31 -2
  471. package/dist/timeline/provider-logo.d.ts +15 -0
  472. package/dist/timeline/question-nav-model.d.ts +23 -0
  473. package/dist/timeline/registry.d.ts +12 -1
  474. package/dist/timeline/retained-image.d.ts +18 -0
  475. package/dist/timeline/retained-loaders.d.ts +27 -0
  476. package/dist/timeline/rolling-activity.d.ts +11 -0
  477. package/dist/timeline/screenshot-lightbox.d.ts +23 -1
  478. package/dist/timeline/session-usage-limit-row.d.ts +11 -0
  479. package/dist/timeline/shared.d.ts +4 -1
  480. package/dist/timeline/startup-dispatch-details.d.ts +5 -0
  481. package/dist/timeline/startup-preference.d.ts +3 -0
  482. package/dist/timeline/startup-timings.d.ts +4 -0
  483. package/dist/timeline/tool-display-name.d.ts +5 -2
  484. package/dist/timeline/tool-presentation.d.ts +172 -0
  485. package/dist/timeline/turn-summary-model.d.ts +95 -0
  486. package/dist/timeline/turn-summary.d.ts +20 -54
  487. package/dist/timeline/types.d.ts +179 -7
  488. package/dist/timeline/work-presentation.d.ts +60 -0
  489. package/dist/timeline-annotation-markers-U3G66KUD.js +166 -0
  490. package/dist/timeline-annotation-markers-U3G66KUD.js.map +1 -0
  491. package/dist/timeline-annotation-selection-BI7QTPTZ.js +242 -0
  492. package/dist/timeline-annotation-selection-BI7QTPTZ.js.map +1 -0
  493. package/dist/timeline-annotations-dialog-FOMHSDTE.js +274 -0
  494. package/dist/timeline-annotations-dialog-FOMHSDTE.js.map +1 -0
  495. package/dist/timeline-model.d.ts +29 -0
  496. package/dist/timeline-model.js +254 -0
  497. package/dist/timeline-model.js.map +1 -0
  498. package/dist/usage/allowance-copy.d.ts +25 -0
  499. package/dist/usage/session-usage-limit.d.ts +88 -0
  500. package/dist/usage/summary.d.ts +35 -0
  501. package/dist/usage.d.ts +17 -0
  502. package/dist/usage.js +1187 -0
  503. package/dist/usage.js.map +1 -0
  504. package/dist/voice-recording-owner.d.ts +7 -0
  505. package/package.json +107 -7
  506. package/src/accounts.tsx +116 -14
  507. package/src/approvals.ts +8 -1
  508. package/src/artifacts-spreadsheet.ts +1 -0
  509. package/src/artifacts.ts +44 -0
  510. package/src/assets/README.md +8 -0
  511. package/src/assets/gmail.ico +0 -0
  512. package/src/assets/outlook.ico +0 -0
  513. package/src/capability-catalog-row.tsx +94 -0
  514. package/src/capability-logo-fallback.ts +22 -0
  515. package/src/client.ts +20 -31
  516. package/src/commands/registry.ts +18 -15
  517. package/src/commands/types.ts +2 -0
  518. package/src/components/anthropic-mark.tsx +10 -0
  519. package/src/components/approval-surface.tsx +401 -138
  520. package/src/components/artifacts/artifact-chrome.tsx +413 -0
  521. package/src/components/artifacts/artifact-sandbox.tsx +189 -0
  522. package/src/components/artifacts/artifact-surface.tsx +40 -20
  523. package/src/components/artifacts/chat-interactive-block.tsx +260 -0
  524. package/src/components/artifacts/deferred-chat-media.tsx +67 -0
  525. package/src/components/artifacts/document-editor.tsx +141 -16
  526. package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
  527. package/src/components/artifacts/editable-artifact-view.tsx +197 -0
  528. package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
  529. package/src/components/artifacts/editable-document.tsx +37 -36
  530. package/src/components/artifacts/editable-presentation.tsx +36 -18
  531. package/src/components/artifacts/editable-spreadsheet.tsx +543 -103
  532. package/src/components/artifacts/index.ts +45 -0
  533. package/src/components/artifacts/inline-html-document.ts +24 -0
  534. package/src/components/artifacts/latest-task-runner.ts +49 -0
  535. package/src/components/artifacts/presentation-editor.tsx +323 -67
  536. package/src/components/artifacts/published-html-artifact-frame.tsx +122 -5
  537. package/src/components/artifacts/session-artifact-viewer.tsx +378 -0
  538. package/src/components/artifacts/site-view.tsx +121 -0
  539. package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
  540. package/src/components/artifacts/spreadsheet-command-queue.ts +184 -0
  541. package/src/components/artifacts/spreadsheet-download.tsx +109 -0
  542. package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
  543. package/src/components/artifacts/spreadsheet-grid.tsx +344 -144
  544. package/src/components/artifacts/spreadsheet-resize.tsx +421 -0
  545. package/src/components/artifacts/spreadsheet-submissions.tsx +46 -0
  546. package/src/components/artifacts/visualization-assets/base.css +1015 -0
  547. package/src/components/artifacts/visualization-assets/helpers.html +349 -0
  548. package/src/components/artifacts/visualization-assets.gen.ts +3 -0
  549. package/src/components/browser-select-control.tsx +312 -0
  550. package/src/components/browser-viewer.tsx +778 -318
  551. package/src/components/chat-composer.tsx +47 -5
  552. package/src/components/child-session-link.tsx +36 -0
  553. package/src/components/claude-mark.tsx +11 -0
  554. package/src/components/code-editor.tsx +13 -16
  555. package/src/components/composer-transcription-control.tsx +128 -30
  556. package/src/components/composer.tsx +404 -195
  557. package/src/components/computer-viewer.tsx +880 -253
  558. package/src/components/copy-button.tsx +13 -5
  559. package/src/components/desktop-viewer.tsx +1 -1
  560. package/src/components/enrollment-consent.tsx +1 -1
  561. package/src/components/enrollment-device-flow.tsx +1 -1
  562. package/src/components/file-browser.tsx +10 -14
  563. package/src/components/fleet-tile.tsx +9 -18
  564. package/src/components/generated-video-player.tsx +4 -2
  565. package/src/components/grok-mark.tsx +34 -0
  566. package/src/components/human-input-form.tsx +590 -283
  567. package/src/components/human-input-surface.tsx +11 -0
  568. package/src/components/interaction-intervention-banner.tsx +2 -2
  569. package/src/components/linkified-text.tsx +79 -0
  570. package/src/components/machine-card.tsx +35 -78
  571. package/src/components/machine-dock-bar.tsx +1 -1
  572. package/src/components/machine-input-display.ts +197 -3
  573. package/src/components/machines/agent-status-icon.tsx +31 -0
  574. package/src/components/machines/machine-detail.tsx +200 -31
  575. package/src/components/machines/machine-operation-policy.tsx +1 -1
  576. package/src/components/machines/machine-status.ts +241 -0
  577. package/src/components/machines-dashboard.tsx +2 -17
  578. package/src/components/markdown-table-layout.ts +143 -0
  579. package/src/components/markdown.tsx +466 -129
  580. package/src/components/message-timeline.tsx +2567 -728
  581. package/src/components/model-mark.tsx +102 -0
  582. package/src/components/model-picker.tsx +15 -4
  583. package/src/components/model-policy-picker-menu.tsx +371 -0
  584. package/src/components/model-policy-picker.tsx +256 -412
  585. package/src/components/new-conversation.tsx +221 -0
  586. package/src/components/open-geni-chat.tsx +309 -0
  587. package/src/components/open-geni-links.tsx +179 -0
  588. package/src/components/openrouter-mark.tsx +13 -0
  589. package/src/components/opper-mark.tsx +18 -0
  590. package/src/components/pierre-diff.tsx +41 -16
  591. package/src/components/pierre-file.tsx +35 -10
  592. package/src/components/preview-loading.tsx +109 -0
  593. package/src/components/provider-recovery-notice.tsx +49 -0
  594. package/src/components/queue-item-content.ts +14 -0
  595. package/src/components/queue-surface-implementation.tsx +51 -356
  596. package/src/components/queue-surface-state.tsx +3 -1
  597. package/src/components/rehype-secret-refs.ts +98 -0
  598. package/src/components/remark-soft-line-breaks.ts +166 -0
  599. package/src/components/sandbox-files.tsx +91 -15
  600. package/src/components/sandbox-terminal.tsx +84 -13
  601. package/src/components/sandbox-workspace.tsx +147 -51
  602. package/src/components/secret-question-field.tsx +324 -0
  603. package/src/components/secret-ref-chip.tsx +185 -0
  604. package/src/components/session-capability-frame.tsx +197 -0
  605. package/src/components/session-chrome.tsx +842 -251
  606. package/src/components/session-commands-panel.tsx +126 -0
  607. package/src/components/session-commands.tsx +18 -0
  608. package/src/components/session-connection-request.tsx +97 -0
  609. package/src/components/session-conversation.tsx +876 -0
  610. package/src/components/session-list.tsx +257 -0
  611. package/src/components/session-mcp-capability-card.tsx +680 -0
  612. package/src/components/session-proxy-scope.tsx +153 -0
  613. package/src/components/session-status.tsx +26 -17
  614. package/src/components/session-usage-limit-notice.tsx +174 -0
  615. package/src/components/timeline-anchor.tsx +119 -0
  616. package/src/components/timeline-annotation-chrome.tsx +196 -0
  617. package/src/components/timeline-annotation-layout.ts +268 -0
  618. package/src/components/timeline-annotation-markers.tsx +185 -0
  619. package/src/components/timeline-annotation-reveal-context.ts +9 -0
  620. package/src/components/timeline-annotation-selection.tsx +106 -54
  621. package/src/components/timeline-annotation-shared.ts +245 -0
  622. package/src/components/timeline-annotations-dialog.tsx +185 -128
  623. package/src/components/timeline-annotations.tsx +189 -45
  624. package/src/components/timeline-reading-progress.ts +80 -0
  625. package/src/components/timeline-search.tsx +168 -0
  626. package/src/components/timeline-settlement.ts +60 -0
  627. package/src/components/tip-follow.ts +52 -0
  628. package/src/components/tool-action-review.tsx +650 -0
  629. package/src/components/tool-review-history.tsx +88 -0
  630. package/src/components/tooltip.tsx +38 -5
  631. package/src/components/usage-limit-notice.tsx +179 -0
  632. package/src/components/usage-member-list.tsx +792 -0
  633. package/src/components/usage-meter.tsx +382 -0
  634. package/src/components/use-viewer-menu-dismiss.ts +33 -0
  635. package/src/components/user-message-body.tsx +27 -2
  636. package/src/components/workspace-dock.tsx +18 -1
  637. package/src/composer-messages.ts +150 -0
  638. package/src/composer-voice-events.ts +12 -0
  639. package/src/composer.ts +6 -1
  640. package/src/connect-account-identity.tsx +34 -0
  641. package/src/connect-accounts.tsx +233 -0
  642. package/src/connect-chooser.tsx +336 -0
  643. package/src/connect-panel.tsx +99 -0
  644. package/src/connect-setup.tsx +355 -0
  645. package/src/connect.ts +60 -0
  646. package/src/connection-assets.d.ts +4 -0
  647. package/src/connection-catalog.tsx +162 -0
  648. package/src/connection-discovery.tsx +238 -0
  649. package/src/connection-installed.tsx +51 -0
  650. package/src/connection-logo.tsx +37 -0
  651. package/src/connection-service-logo.tsx +55 -0
  652. package/src/connection-service-presentation.ts +46 -0
  653. package/src/connection-skeleton.tsx +16 -0
  654. package/src/connection-type-picker.tsx +36 -0
  655. package/src/conversation-timeline.ts +92 -0
  656. package/src/desktop.ts +24 -0
  657. package/src/device-authorization.tsx +98 -0
  658. package/src/diffs.ts +16 -0
  659. package/src/discovery-cache.ts +42 -0
  660. package/src/editor.ts +13 -0
  661. package/src/hooks/internal.ts +3 -2
  662. package/src/hooks/latest-question.ts +164 -0
  663. package/src/hooks/shared-machines-list.ts +34 -1
  664. package/src/hooks/shared-query.ts +721 -0
  665. package/src/hooks/use-attached-browsers.ts +1 -1
  666. package/src/hooks/use-auth-runs.ts +0 -27
  667. package/src/hooks/use-available-models.ts +21 -15
  668. package/src/hooks/use-browser-frame-stream.ts +19 -2
  669. package/src/hooks/use-browser-session.ts +680 -205
  670. package/src/hooks/use-browser-sessions.ts +32 -1
  671. package/src/hooks/use-client-config-flags.ts +118 -0
  672. package/src/hooks/use-codex-accounts.ts +247 -47
  673. package/src/hooks/use-composer.ts +276 -47
  674. package/src/hooks/use-computer-frame-stream.ts +25 -7
  675. package/src/hooks/use-computer-input-posture.ts +94 -0
  676. package/src/hooks/use-computer-session.ts +409 -95
  677. package/src/hooks/use-connect.ts +23 -0
  678. package/src/hooks/use-desktop-stream.ts +19 -28
  679. package/src/hooks/use-file-attachments.ts +80 -4
  680. package/src/hooks/use-goal.ts +107 -13
  681. package/src/hooks/use-last-started-turn-policy.ts +46 -14
  682. package/src/hooks/use-machines.ts +4 -0
  683. package/src/hooks/use-new-conversation.ts +374 -0
  684. package/src/hooks/use-new-session-draft.ts +813 -0
  685. package/src/hooks/use-realtime-voice-models.ts +46 -0
  686. package/src/hooks/use-sandbox-files.ts +68 -20
  687. package/src/hooks/use-session-background-commands.ts +22 -11
  688. package/src/hooks/use-session-capabilities.ts +3 -2
  689. package/src/hooks/use-session-conversation.ts +150 -0
  690. package/src/hooks/use-session-events.ts +703 -382
  691. package/src/hooks/use-session-lineage.ts +20 -16
  692. package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
  693. package/src/hooks/use-session-model-account.ts +174 -0
  694. package/src/hooks/use-session.ts +53 -21
  695. package/src/hooks/use-slash-commands.ts +6 -11
  696. package/src/hooks/use-supergrok-accounts.ts +22 -8
  697. package/src/hooks/use-terminal-stream.ts +153 -27
  698. package/src/hooks/use-transcription.ts +6 -0
  699. package/src/hooks/use-turn-queue.ts +2 -1
  700. package/src/hooks/use-usage.ts +100 -0
  701. package/src/hooks/use-vaults.ts +153 -0
  702. package/src/hooks/use-video-artifact-playback.ts +1 -1
  703. package/src/hooks/use-voice-input.ts +127 -19
  704. package/src/hooks/use-workspace-capture.ts +3 -2
  705. package/src/hooks/use-workspace-edit.ts +23 -5
  706. package/src/hooks/use-workspace-sessions.ts +97 -32
  707. package/src/human-input-model.ts +359 -0
  708. package/src/identity-link-accounts.tsx +148 -0
  709. package/src/identity-link-consent.tsx +192 -0
  710. package/src/index.ts +262 -16
  711. package/src/interaction.ts +1 -0
  712. package/src/lib/clipboard.ts +29 -0
  713. package/src/lib/error-message.ts +37 -0
  714. package/src/lib/format.ts +213 -16
  715. package/src/lib/host-theme.ts +529 -0
  716. package/src/lib/interaction-errors.ts +15 -0
  717. package/src/lib/menu-styles.ts +44 -0
  718. package/src/lib/notify-observer.ts +15 -0
  719. package/src/lib/pierre-diffs-loader.ts +53 -0
  720. package/src/lib/provider-recovery.ts +243 -0
  721. package/src/lib/scrollbars.ts +30 -0
  722. package/src/lib/terminal-input-readiness.ts +51 -0
  723. package/src/lib/transient-retry.ts +99 -0
  724. package/src/lib/workbench-peers.ts +62 -0
  725. package/src/lib/xterm-theme.ts +23 -21
  726. package/src/mcp-connection-status.ts +35 -0
  727. package/src/model-mark-paths.ts +53 -0
  728. package/src/model-picker-model.ts +330 -0
  729. package/src/model-policy.ts +299 -74
  730. package/src/native-previews.ts +100 -0
  731. package/src/new-session-draft.ts +22 -0
  732. package/src/notification-text.ts +81 -0
  733. package/src/older-history.ts +22 -4
  734. package/src/organization-model.ts +118 -0
  735. package/src/plugin-details.tsx +185 -0
  736. package/src/plugin-discovery.tsx +196 -0
  737. package/src/preview-loading-paint.ts +68 -0
  738. package/src/provider.tsx +74 -15
  739. package/src/queue-presentation-model.ts +464 -0
  740. package/src/realtime/dropdown-menu.tsx +19 -12
  741. package/src/realtime/embedded-new-voice.tsx +1 -0
  742. package/src/realtime/embedded-voice.tsx +3 -0
  743. package/src/realtime/realtime-control.tsx +138 -501
  744. package/src/realtime/session-realtime.ts +566 -0
  745. package/src/sandbox-label-model.ts +53 -0
  746. package/src/scrollbars.ts +3 -0
  747. package/src/secret-reference-label.ts +43 -0
  748. package/src/secrets-ui.tsx +59 -0
  749. package/src/session-agents-model.ts +33 -0
  750. package/src/session-attention-model.ts +62 -0
  751. package/src/session-auth-recommendation.ts +48 -0
  752. package/src/session-capability-policy.ts +196 -0
  753. package/src/session-context.ts +3 -4
  754. package/src/session-feedback-model.ts +95 -0
  755. package/src/session-list-model.ts +434 -0
  756. package/src/session-realtime.ts +18 -0
  757. package/src/session-status-model.ts +99 -0
  758. package/src/session-ui.ts +98 -1
  759. package/src/session.ts +17 -1
  760. package/src/site-snapshot.ts +74 -0
  761. package/src/sites-ui.tsx +348 -0
  762. package/src/sites.ts +3 -0
  763. package/src/skill-discovery.tsx +208 -0
  764. package/src/terminal.ts +26 -0
  765. package/src/testing/session-scenarios.ts +404 -0
  766. package/src/timeline/activity-rail.tsx +242 -101
  767. package/src/timeline/agent-identity.tsx +84 -0
  768. package/src/timeline/agent-row.tsx +231 -0
  769. package/src/timeline/allowance-exhausted-row.tsx +86 -0
  770. package/src/timeline/compaction-copy.ts +115 -0
  771. package/src/timeline/entrance.tsx +28 -3
  772. package/src/timeline/fleet-decision-projection.ts +2 -1
  773. package/src/timeline/fleet-decision-row.tsx +1 -0
  774. package/src/timeline/focus-sequence.ts +44 -0
  775. package/src/timeline/genie-copy.ts +19 -0
  776. package/src/timeline/genie-loading.tsx +143 -0
  777. package/src/timeline/index.ts +30 -2
  778. package/src/timeline/knowledge-receipt.tsx +100 -0
  779. package/src/timeline/message-sender.tsx +71 -0
  780. package/src/timeline/notice-presentation.ts +48 -0
  781. package/src/timeline/parsers.ts +42 -2
  782. package/src/timeline/patch-apply-command.tsx +135 -0
  783. package/src/timeline/platform-activity-presentation.ts +166 -0
  784. package/src/timeline/platform-activity-row.tsx +15 -90
  785. package/src/timeline/presented-image.ts +63 -0
  786. package/src/timeline/projection.ts +1746 -76
  787. package/src/timeline/provider-logo.tsx +53 -0
  788. package/src/timeline/question-nav-model.ts +28 -0
  789. package/src/timeline/registry.ts +26 -4
  790. package/src/timeline/retained-image.ts +97 -0
  791. package/src/timeline/retained-loaders.ts +91 -0
  792. package/src/timeline/rolling-activity.tsx +80 -0
  793. package/src/timeline/screenshot-lightbox.tsx +228 -5
  794. package/src/timeline/session-usage-limit-row.tsx +42 -0
  795. package/src/timeline/shared.tsx +42 -15
  796. package/src/timeline/startup-dispatch-details.tsx +36 -0
  797. package/src/timeline/startup-preference.ts +33 -0
  798. package/src/timeline/startup-timings.tsx +145 -0
  799. package/src/timeline/tool-display-name.ts +19 -7
  800. package/src/timeline/tool-presentation.ts +1316 -0
  801. package/src/timeline/tool-renderers.tsx +835 -1138
  802. package/src/timeline/turn-summary-model.ts +343 -0
  803. package/src/timeline/turn-summary.tsx +272 -365
  804. package/src/timeline/types.ts +189 -6
  805. package/src/timeline/work-presentation.ts +189 -0
  806. package/src/timeline-model.ts +143 -0
  807. package/src/usage/allowance-copy.ts +64 -0
  808. package/src/usage/session-usage-limit.ts +266 -0
  809. package/src/usage/summary.ts +93 -0
  810. package/src/usage.ts +70 -0
  811. package/src/voice-recording-owner.ts +22 -0
  812. package/styles/compiled.css +2319 -748
  813. package/styles/connect.css +290 -0
  814. package/styles/connect.d.ts +1 -0
  815. package/styles/effective-tokens.css +1 -0
  816. package/styles/index.css +309 -9
  817. package/styles/responsive.css +99 -7
  818. package/styles/session-capability.css +44 -0
  819. package/styles/tokens.css +134 -66
  820. package/dist/browser-viewer-AEFHUYZK.js +0 -14
  821. package/dist/chunk-4MDLEHXL.js.map +0 -1
  822. package/dist/chunk-5YK2ZDIG.js.map +0 -1
  823. package/dist/chunk-D3UIAJKY.js.map +0 -1
  824. package/dist/chunk-ELIYWBZR.js.map +0 -1
  825. package/dist/chunk-H5YGYNXS.js.map +0 -1
  826. package/dist/chunk-HQVCKCLG.js +0 -9458
  827. package/dist/chunk-HQVCKCLG.js.map +0 -1
  828. package/dist/chunk-HUIKIDM5.js.map +0 -1
  829. package/dist/chunk-ICA6R6TW.js.map +0 -1
  830. package/dist/chunk-JVYQRRC4.js.map +0 -1
  831. package/dist/chunk-KCGXPP5V.js.map +0 -1
  832. package/dist/chunk-KZ73RL76.js.map +0 -1
  833. package/dist/chunk-LAKLF4PA.js +0 -141
  834. package/dist/chunk-LAKLF4PA.js.map +0 -1
  835. package/dist/chunk-MZ2G2XBA.js.map +0 -1
  836. package/dist/chunk-NEXLLTP4.js.map +0 -1
  837. package/dist/chunk-OAM4WAAM.js.map +0 -1
  838. package/dist/chunk-PEI6RANI.js.map +0 -1
  839. package/dist/chunk-RGALCTWO.js.map +0 -1
  840. package/dist/chunk-W6NFJXSA.js +0 -454
  841. package/dist/chunk-W6NFJXSA.js.map +0 -1
  842. package/dist/chunk-WSK7G5LE.js +0 -170
  843. package/dist/chunk-WSK7G5LE.js.map +0 -1
  844. package/dist/chunk-X4A66EWZ.js +0 -223
  845. package/dist/chunk-X4A66EWZ.js.map +0 -1
  846. package/dist/chunk-XXWH2JLC.js.map +0 -1
  847. package/dist/chunk-YFKJ7VZH.js +0 -268
  848. package/dist/chunk-YFKJ7VZH.js.map +0 -1
  849. package/dist/chunk-YJFGAFBD.js.map +0 -1
  850. package/dist/computer-viewer-FWEZISW4.js +0 -16
  851. package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
  852. package/dist/hooks/use-environments.d.ts +0 -41
  853. package/dist/hooks/use-packs.d.ts +0 -32
  854. package/dist/platform-activity-row-BJHUHXAT.js.map +0 -1
  855. package/dist/queue-surface-implementation-BSKUWHRI.js.map +0 -1
  856. package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
  857. package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
  858. package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
  859. package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
  860. package/src/hooks/use-environments.ts +0 -182
  861. package/src/hooks/use-packs.ts +0 -157
  862. /package/dist/{browser-viewer-AEFHUYZK.js.map → browser-viewer-ZWR6MWJ7.js.map} +0 -0
  863. /package/dist/{computer-viewer-FWEZISW4.js.map → chat-interactive-block-BO2IWXVK.js.map} +0 -0
@@ -0,0 +1,1316 @@
1
+ import type { GitFileDiff } from "@opengeni/sdk";
2
+ import { stringifyPayload, tryParseJson } from "../lib/format";
3
+ import {
4
+ applyPatchOpsFromToolItem,
5
+ controlCaret,
6
+ execTruncated,
7
+ isExecSessionLostBanner,
8
+ looksBinary,
9
+ parseExecBannerSessionId,
10
+ parseToolArgs,
11
+ sandboxCommandExitCode,
12
+ stripExecBanner,
13
+ tailPeek,
14
+ unwrapMcpOutput,
15
+ v4aToGitFileDiff,
16
+ type ApplyPatchOperation,
17
+ } from "./parsers";
18
+ import { rawTypeOf } from "./registry";
19
+ import { mcpToolLeaf, toolDisplayName } from "./tool-display-name";
20
+ import type { ToolCallItem } from "./types";
21
+
22
+ /* ----------------------------------------------------------------------------
23
+ Tool row presentation model (renderer-neutral)
24
+
25
+ The collapsed-row decisions every tool renderer makes — icon, tint, title,
26
+ preview, settle chip and what the expanded body holds — expressed as plain
27
+ data so DOM and non-DOM renderers draw the same row from one source of truth.
28
+ Web renderers consume these functions; a change here changes every surface.
29
+ -------------------------------------------------------------------------- */
30
+
31
+ export type ToolIconKind =
32
+ | "terminal"
33
+ | "keyboard"
34
+ | "file-diff"
35
+ | "search"
36
+ | "question"
37
+ | "target"
38
+ | "brain"
39
+ | "sessions"
40
+ | "server"
41
+ | "server-cog"
42
+ | "calendar"
43
+ | "panels"
44
+ | "share"
45
+ | "message"
46
+ | "git"
47
+ | "box"
48
+ | "key"
49
+ | "file-search"
50
+ | "package-search"
51
+ | "plug"
52
+ | "wrench";
53
+
54
+ export type ToolIconTone = "accent" | "failed" | "running" | "muted";
55
+
56
+ export type ToolChip = {
57
+ tone: "ok" | "bad" | "muted" | "interrupted";
58
+ text: string;
59
+ };
60
+
61
+ /** The collapsed-row secondary line. `running` previews carry the pulse locus. */
62
+ export type ToolPreview =
63
+ | { kind: "text"; text: string; running?: boolean | undefined }
64
+ | {
65
+ kind: "path";
66
+ path: string;
67
+ add?: number | undefined;
68
+ del?: number | undefined;
69
+ }
70
+ | { kind: "files"; count: number; add: number; del: number }
71
+ | { kind: "malformed"; name: string };
72
+
73
+ export type ToolPatchFile = {
74
+ key: string;
75
+ path: string;
76
+ file: GitFileDiff | null;
77
+ diff: string;
78
+ };
79
+
80
+ export type WebSearchResult = {
81
+ title: string;
82
+ domain: string;
83
+ snippet: string;
84
+ };
85
+
86
+ /** What the expanded body holds; renderers draw these with their own primitives. */
87
+ export type ToolBody =
88
+ | {
89
+ kind: "term";
90
+ command: string | null;
91
+ workdir: string | null;
92
+ output: string;
93
+ live?: boolean | undefined;
94
+ failed?: boolean | undefined;
95
+ note?: string | undefined;
96
+ }
97
+ | { kind: "note"; text: string; tone?: "error" | undefined }
98
+ | {
99
+ kind: "payloads";
100
+ /** A short explanation above the payloads. */
101
+ note?: string | undefined;
102
+ blocks: Array<{ label: string; value: unknown; failed?: boolean }>;
103
+ }
104
+ | {
105
+ kind: "patch";
106
+ files: ToolPatchFile[];
107
+ /** A single malformed op renders its raw patch without the path caption. */
108
+ bare?: boolean | undefined;
109
+ }
110
+ | { kind: "web-results"; results: WebSearchResult[] | null }
111
+ | {
112
+ /** A short labelled listing (disclosed tools, search hits) above payloads. */
113
+ kind: "listing";
114
+ note?: string | undefined;
115
+ entries: ToolListingEntry[];
116
+ /** Entries beyond the visible list ("+N more"). */
117
+ more?: number | undefined;
118
+ /** Shown instead of the list when it is known to be empty. */
119
+ empty?: string | undefined;
120
+ blocks: Array<{ label: string; value: unknown; failed?: boolean }>;
121
+ };
122
+
123
+ export type ToolListingEntry = {
124
+ key: string;
125
+ title: string;
126
+ /** Quiet leading label (the tool's server). */
127
+ eyebrow?: string | null | undefined;
128
+ mono?: boolean | undefined;
129
+ /** Secondary text under the title (a search snippet). */
130
+ snippet?: string | undefined;
131
+ };
132
+
133
+ export type PresentedToolKind =
134
+ | "exec"
135
+ | "write_stdin"
136
+ | "apply_patch"
137
+ | "web_search"
138
+ | "ask"
139
+ | "run_on"
140
+ | "tool_search"
141
+ | "docs_search"
142
+ | "session_title"
143
+ | "generic";
144
+
145
+ export type ToolRowPresentation = {
146
+ tool: PresentedToolKind;
147
+ icon: ToolIconKind;
148
+ iconTone: ToolIconTone;
149
+ title: string;
150
+ titleMono?: boolean | undefined;
151
+ running?: boolean | undefined;
152
+ preview?: ToolPreview | undefined;
153
+ chip?: ToolChip | undefined;
154
+ failed?: boolean | undefined;
155
+ cancelled?: boolean | undefined;
156
+ body: ToolBody;
157
+ };
158
+
159
+ export type ToolPresentationContext = {
160
+ /** Host-supplied active compute label ("on <label> · …" preview prefix). */
161
+ computeLabel?: string | null | undefined;
162
+ };
163
+
164
+ /** Prefix a collapsed preview with the host-supplied active compute label. */
165
+ export function withComputePreview(label: string | null | undefined, preview: string): string {
166
+ if (!label) {
167
+ return preview;
168
+ }
169
+ return `on ${label} · ${preview}`;
170
+ }
171
+
172
+ export function truncatePreview(text: string, max: number): string {
173
+ const cleaned = text.replace(/\s+/g, " ").trim();
174
+ if (!cleaned) {
175
+ return "";
176
+ }
177
+ return cleaned.length > max ? `${cleaned.slice(0, max - 1)}…` : cleaned;
178
+ }
179
+
180
+ function textPreview(text: string, running?: boolean): ToolPreview {
181
+ return running ? { kind: "text", text, running: true } : { kind: "text", text };
182
+ }
183
+
184
+ /* ---- exec_command ---------------------------------------------------------- */
185
+
186
+ export function execPresentation(
187
+ item: ToolCallItem,
188
+ context: ToolPresentationContext = {},
189
+ ): ToolRowPresentation {
190
+ const args = parseToolArgs(item.arguments);
191
+ const cmd = typeof args.cmd === "string" ? args.cmd : "";
192
+ const workdir = typeof args.workdir === "string" ? args.workdir : null;
193
+ const out = item.output;
194
+ const title = `$ ${cmd}`;
195
+ const computeLabel = context.computeLabel ?? null;
196
+ const base = {
197
+ tool: "exec" as const,
198
+ icon: "terminal" as const,
199
+ title,
200
+ titleMono: true,
201
+ };
202
+
203
+ // No output event ever arrived: the turn failed before the output insert —
204
+ // most likely a NUL byte in the command output prevented storage.
205
+ if (item.status === "failed" && out === undefined) {
206
+ return {
207
+ ...base,
208
+ iconTone: "failed",
209
+ chip: { tone: "bad", text: "failed" },
210
+ preview: textPreview(
211
+ withComputePreview(computeLabel, "output lost — NUL byte could not be stored"),
212
+ ),
213
+ body: {
214
+ kind: "note",
215
+ tone: "error",
216
+ text: "output contained a NUL byte and could not be stored; the turn failed on this tool's output insert — no output event ever arrived.",
217
+ },
218
+ };
219
+ }
220
+
221
+ if (item.status === "failed" && (out == null || out === "")) {
222
+ return {
223
+ ...base,
224
+ iconTone: "failed",
225
+ chip: { tone: "bad", text: "failed" },
226
+ preview: textPreview(withComputePreview(computeLabel, "tool call failed")),
227
+ body: {
228
+ kind: "note",
229
+ tone: "error",
230
+ text: "the tool call failed with no output.",
231
+ },
232
+ };
233
+ }
234
+
235
+ if (item.status === "running") {
236
+ const streamed = typeof out === "string" ? stripExecBanner(out) : "";
237
+ const runningPreview = streamed ? `${streamed.split("\n").length} lines` : "running…";
238
+ return {
239
+ ...base,
240
+ iconTone: "running",
241
+ running: true,
242
+ preview: textPreview(withComputePreview(computeLabel, runningPreview), true),
243
+ body: {
244
+ kind: "term",
245
+ command: null,
246
+ workdir,
247
+ output: streamed,
248
+ live: true,
249
+ },
250
+ };
251
+ }
252
+
253
+ const text = typeof out === "string" ? out : stringifyPayload(out);
254
+ const stripped = stripExecBanner(text);
255
+ const bgSession = parseExecBannerSessionId(text);
256
+ const exitCode = sandboxCommandExitCode(text);
257
+ const binary = looksBinary(stripped);
258
+
259
+ // Color is spent on the exception only: a clean exit earns no chip.
260
+ let chip: ToolChip | undefined;
261
+ let iconTone: ToolIconTone = "muted";
262
+ if (bgSession != null) {
263
+ chip = { tone: "muted", text: `session ${bgSession}` };
264
+ } else if (exitCode != null && exitCode !== 0) {
265
+ chip = { tone: "bad", text: `exit ${exitCode}` };
266
+ iconTone = "failed";
267
+ }
268
+
269
+ const peek = binary ? "binary output" : tailPeek(stripped) || "(no output)";
270
+ const truncated = execTruncated(text);
271
+ const preview = withComputePreview(computeLabel, truncated ? `⋯ truncated · ${peek}` : peek);
272
+ return {
273
+ ...base,
274
+ iconTone,
275
+ ...(chip ? { chip } : {}),
276
+ failed: item.status === "failed",
277
+ cancelled: item.status === "cancelled",
278
+ preview: textPreview(preview),
279
+ body: {
280
+ kind: "term",
281
+ command: null,
282
+ workdir,
283
+ output: binary ? "(binary output suppressed)" : stripped,
284
+ failed: item.status === "failed" || (exitCode != null && exitCode !== 0),
285
+ ...(bgSession != null
286
+ ? {
287
+ note: `↳ session ${bgSession} — a later write_stdin can target this PTY.`,
288
+ }
289
+ : {}),
290
+ },
291
+ };
292
+ }
293
+
294
+ /* ---- write_stdin ----------------------------------------------------------- */
295
+
296
+ export function writeStdinPresentation(item: ToolCallItem): ToolRowPresentation {
297
+ const args = parseToolArgs(item.arguments);
298
+ const sessionId =
299
+ typeof args.session_id === "string" || typeof args.session_id === "number"
300
+ ? args.session_id
301
+ : undefined;
302
+ const text = typeof item.output === "string" ? item.output : stringifyPayload(item.output);
303
+ const lost = isExecSessionLostBanner(text);
304
+ const keys = controlCaret(typeof args.chars === "string" ? args.chars : "");
305
+ const exitCode = sandboxCommandExitCode(text);
306
+ const stripped = stripExecBanner(text);
307
+ const title = `session ${sessionId} ← ${keys || "∅"}`;
308
+ const base = {
309
+ tool: "write_stdin" as const,
310
+ icon: "keyboard" as const,
311
+ title,
312
+ titleMono: true,
313
+ };
314
+
315
+ if (item.status === "running") {
316
+ return {
317
+ ...base,
318
+ iconTone: "running",
319
+ running: true,
320
+ preview: textPreview("sending…", true),
321
+ body: { kind: "note", text: `sending input to session ${sessionId}…` },
322
+ };
323
+ }
324
+
325
+ let chip: ToolChip | undefined;
326
+ if (lost) {
327
+ chip = { tone: "bad", text: "lost" };
328
+ } else if (exitCode != null && exitCode !== 0) {
329
+ chip = { tone: "bad", text: `exit ${exitCode}` };
330
+ }
331
+
332
+ return {
333
+ ...base,
334
+ iconTone: lost ? "failed" : "muted",
335
+ ...(chip ? { chip } : {}),
336
+ failed: item.status === "failed",
337
+ cancelled: item.status === "cancelled",
338
+ preview: textPreview(lost ? `session ${sessionId} PTY vanished` : tailPeek(stripped) || "sent"),
339
+ body: lost
340
+ ? { kind: "note", tone: "error", text: stripped || text }
341
+ : {
342
+ kind: "term",
343
+ command: `write_stdin → session ${sessionId}`,
344
+ workdir: null,
345
+ output: stripped,
346
+ },
347
+ };
348
+ }
349
+
350
+ /* ---- apply_patch ----------------------------------------------------------- */
351
+
352
+ export function patchVerb(op: ApplyPatchOperation | undefined): string {
353
+ if (!op) {
354
+ return "Edited";
355
+ }
356
+ return op.type === "create_file"
357
+ ? "Created"
358
+ : op.type === "delete_file"
359
+ ? "Deleted"
360
+ : op.moveTo
361
+ ? "Renamed"
362
+ : "Edited";
363
+ }
364
+
365
+ export function pathBasename(path: string): string {
366
+ const parts = path.split("/").filter(Boolean);
367
+ return parts.length ? parts[parts.length - 1]! : path;
368
+ }
369
+
370
+ export function pathDirname(path: string): string {
371
+ const idx = path.lastIndexOf("/");
372
+ return idx >= 0 ? path.slice(0, idx + 1) : "";
373
+ }
374
+
375
+ export function safeParsePatchOp(op: ApplyPatchOperation): GitFileDiff | null {
376
+ try {
377
+ return v4aToGitFileDiff(op);
378
+ } catch {
379
+ return null;
380
+ }
381
+ }
382
+
383
+ function patchFiles(
384
+ ops: ApplyPatchOperation[],
385
+ parsed?: Array<GitFileDiff | null>,
386
+ ): ToolPatchFile[] {
387
+ return ops.map((op, index) => ({
388
+ key: `${op.type}:${op.path}:${index}`,
389
+ path: op.path,
390
+ file: parsed ? (parsed[index] ?? null) : safeParsePatchOp(op),
391
+ diff: op.diff ?? "",
392
+ }));
393
+ }
394
+
395
+ /** Returns null when a settled patch has no op (renderers fall back to generic). */
396
+ export function applyPatchPresentation(item: ToolCallItem): ToolRowPresentation | null {
397
+ const ops = applyPatchOpsFromToolItem(item);
398
+ const cancelled = item.status === "cancelled";
399
+ const firstOp = ops[0];
400
+ const base = { tool: "apply_patch" as const, icon: "file-diff" as const };
401
+
402
+ if (item.status === "running") {
403
+ // Show the patch structure from the arguments, marked clearly in-progress.
404
+ const fileCount = ops.length;
405
+ const titleVerb = firstOp ? `Applying ${pathBasename(firstOp.path)}` : "Applying patch";
406
+ return {
407
+ ...base,
408
+ iconTone: "running",
409
+ title: fileCount > 1 ? `Applying ${fileCount} files` : titleVerb,
410
+ running: true,
411
+ preview: textPreview(
412
+ fileCount > 1 ? `${fileCount} files` : firstOp ? firstOp.path : "applying…",
413
+ true,
414
+ ),
415
+ body: { kind: "patch", files: patchFiles(ops) },
416
+ };
417
+ }
418
+
419
+ if (item.status === "failed") {
420
+ return {
421
+ ...base,
422
+ iconTone: "failed",
423
+ title: firstOp ? `${patchVerb(firstOp)} ${pathBasename(firstOp.path)}` : "apply_patch",
424
+ chip: { tone: "bad", text: "failed" },
425
+ preview: textPreview(typeof item.output === "string" ? item.output : "patch failed"),
426
+ body: {
427
+ kind: "payloads",
428
+ blocks: [{ label: "Error", value: item.output, failed: true }],
429
+ },
430
+ };
431
+ }
432
+
433
+ // Multi-file edit: magnitude stays a single muted glyph pair.
434
+ if (ops.length > 1) {
435
+ const parsed = ops.map((op) => safeParsePatchOp(op));
436
+ const goodFiles = parsed.filter((f): f is GitFileDiff => f !== null);
437
+ const add = goodFiles.reduce((n, f) => n + f.additions, 0);
438
+ const del = goodFiles.reduce((n, f) => n + f.deletions, 0);
439
+ return {
440
+ ...base,
441
+ iconTone: "accent",
442
+ title: `Edited ${ops.length} files`,
443
+ cancelled,
444
+ preview: { kind: "files", count: ops.length, add, del },
445
+ body: { kind: "patch", files: patchFiles(ops, parsed) },
446
+ };
447
+ }
448
+
449
+ if (!firstOp) {
450
+ return null;
451
+ }
452
+ if (firstOp.type === "delete_file") {
453
+ return {
454
+ ...base,
455
+ iconTone: "failed",
456
+ title: `Deleted ${pathBasename(firstOp.path)}`,
457
+ cancelled,
458
+ preview: { kind: "path", path: firstOp.path },
459
+ body: { kind: "note", text: "File deleted — no diff to show." },
460
+ };
461
+ }
462
+
463
+ const file = safeParsePatchOp(firstOp);
464
+ if (!file) {
465
+ return {
466
+ ...base,
467
+ iconTone: "accent",
468
+ title: `${patchVerb(firstOp)} ${pathBasename(firstOp.path)}`,
469
+ cancelled,
470
+ preview: { kind: "malformed", name: pathBasename(firstOp.path) },
471
+ body: { kind: "patch", files: patchFiles([firstOp], [null]), bare: true },
472
+ };
473
+ }
474
+
475
+ return {
476
+ ...base,
477
+ iconTone: "accent",
478
+ title: `${patchVerb(firstOp)} ${pathBasename(file.path)}`,
479
+ cancelled,
480
+ preview: {
481
+ kind: "path",
482
+ path: file.path,
483
+ add: file.additions,
484
+ del: file.deletions,
485
+ },
486
+ body: { kind: "patch", files: patchFiles([firstOp], [file]) },
487
+ };
488
+ }
489
+
490
+ /* ---- web search ------------------------------------------------------------ */
491
+
492
+ export function webSearchQueryFromArguments(args: unknown): string | null {
493
+ if (typeof args === "string") {
494
+ const trimmed = args.trim();
495
+ if (!trimmed) {
496
+ return null;
497
+ }
498
+ try {
499
+ return webSearchQueryFromArguments(JSON.parse(trimmed));
500
+ } catch {
501
+ return trimmed;
502
+ }
503
+ }
504
+ if (!args || typeof args !== "object") {
505
+ return null;
506
+ }
507
+ const record = args as Record<string, unknown>;
508
+ if (typeof record.query === "string" && record.query.trim().length > 0) {
509
+ return record.query;
510
+ }
511
+ if (Array.isArray(record.queries)) {
512
+ const first = record.queries.find(
513
+ (value): value is string => typeof value === "string" && value.trim().length > 0,
514
+ );
515
+ if (first) {
516
+ return first;
517
+ }
518
+ }
519
+ return null;
520
+ }
521
+
522
+ export function webSearchPresentation(item: ToolCallItem): ToolRowPresentation {
523
+ const raw = (item.raw ?? {}) as {
524
+ providerData?: {
525
+ action?: {
526
+ type?: string;
527
+ query?: string;
528
+ queries?: string[];
529
+ url?: string;
530
+ pattern?: string;
531
+ };
532
+ };
533
+ };
534
+ const action = raw.providerData?.action ?? {};
535
+ const actionType = action.type ?? "search";
536
+ const queries = (action.queries ?? []).filter(
537
+ (value): value is string => typeof value === "string" && value.trim().length > 0,
538
+ );
539
+ const searchQuery =
540
+ (typeof action.query === "string" && action.query.trim().length > 0 ? action.query : null) ??
541
+ queries[0] ??
542
+ webSearchQueryFromArguments(item.arguments);
543
+ const running = item.status === "running";
544
+ const query =
545
+ actionType === "open_page"
546
+ ? (action.url ?? "(page unavailable)")
547
+ : actionType === "find_in_page"
548
+ ? action.pattern && action.url
549
+ ? `"${action.pattern}" in ${action.url}`
550
+ : (action.pattern ?? action.url ?? "(page unavailable)")
551
+ : // Codex often emits the live card before action.query/queries land.
552
+ (searchQuery ?? (running ? "…" : "(query unavailable)"));
553
+ const variants = queries.length > 1 ? ` +${queries.length - 1} variants` : "";
554
+ const base = { tool: "web_search" as const, icon: "search" as const };
555
+
556
+ if (running) {
557
+ return {
558
+ ...base,
559
+ iconTone: "running",
560
+ title:
561
+ actionType === "open_page"
562
+ ? "Opening web page"
563
+ : actionType === "find_in_page"
564
+ ? "Searching within page"
565
+ : "Searching the web",
566
+ running: true,
567
+ preview: textPreview(`${query}${variants}`, true),
568
+ body: {
569
+ kind: "note",
570
+ text: "searching… results fold into the model context (no output event).",
571
+ },
572
+ };
573
+ }
574
+
575
+ const rawResults = (item.output as { results?: unknown } | undefined)?.results;
576
+ const results = Array.isArray(rawResults)
577
+ ? (rawResults as unknown[]).filter((r): r is WebSearchResult => !!r && typeof r === "object")
578
+ : null;
579
+ return {
580
+ ...base,
581
+ iconTone: "muted",
582
+ title:
583
+ actionType === "open_page"
584
+ ? "Opened web page"
585
+ : actionType === "find_in_page"
586
+ ? "Searched within page"
587
+ : "Searched the web",
588
+ preview: textPreview(`${query}${variants}`),
589
+ failed: item.status === "failed",
590
+ cancelled: item.status === "cancelled",
591
+ body: { kind: "web-results", results },
592
+ };
593
+ }
594
+
595
+ /* ---- MCP-shaped tools: ask, run_on, generic -------------------------------- */
596
+
597
+ export function askToolPreview(args: unknown): string | null {
598
+ const record = args && typeof args === "object" ? (args as Record<string, unknown>) : null;
599
+ const questions = Array.isArray(record?.questions) ? record.questions : null;
600
+ if (!questions || questions.length === 0) {
601
+ return null;
602
+ }
603
+ const first = questions[0];
604
+ if (!first || typeof first !== "object") {
605
+ return null;
606
+ }
607
+ const q = first as Record<string, unknown>;
608
+ const text =
609
+ typeof q.label === "string" && q.label.trim()
610
+ ? q.label.trim()
611
+ : typeof q.prompt === "string" && q.prompt.trim()
612
+ ? q.prompt.trim()
613
+ : null;
614
+ if (!text) {
615
+ return null;
616
+ }
617
+ const preview = truncatePreview(text, 90);
618
+ return questions.length > 1 ? `${preview} · ${questions.length} questions` : preview;
619
+ }
620
+
621
+ export function runOnTargetName(output: unknown): string | null {
622
+ const { text } = unwrapMcpOutput(output);
623
+ const parsed = tryParseJson(text);
624
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
625
+ const name = (parsed as { targetName?: unknown }).targetName;
626
+ if (typeof name === "string" && name.trim()) {
627
+ return name.trim();
628
+ }
629
+ }
630
+ return null;
631
+ }
632
+
633
+ export function runOnOpPreview(args: Record<string, unknown>): string | null {
634
+ const op = args.op;
635
+ if (!op || typeof op !== "object" || Array.isArray(op)) {
636
+ return null;
637
+ }
638
+ const record = op as Record<string, unknown>;
639
+ if (record.kind === "exec" && typeof record.cmd === "string" && record.cmd.trim()) {
640
+ return `$ ${record.cmd.trim()}`;
641
+ }
642
+ if (
643
+ (record.kind === "read" || record.kind === "write") &&
644
+ typeof record.path === "string" &&
645
+ record.path.trim()
646
+ ) {
647
+ return truncatePreview(record.path.trim(), 72);
648
+ }
649
+ return null;
650
+ }
651
+
652
+ export function goalToolPreview(name: string, args: unknown): string | null {
653
+ const leaf = mcpToolLeaf(name);
654
+ if (
655
+ leaf !== "goal_set" &&
656
+ leaf !== "goal_update" &&
657
+ leaf !== "goal_complete" &&
658
+ leaf !== "goal_pause" &&
659
+ leaf !== "wait_for_input"
660
+ ) {
661
+ return null;
662
+ }
663
+ const record = args && typeof args === "object" ? (args as Record<string, unknown>) : null;
664
+ if (!record) {
665
+ return null;
666
+ }
667
+ const text =
668
+ typeof record.text === "string"
669
+ ? record.text
670
+ : typeof record.evidence === "string"
671
+ ? record.evidence
672
+ : typeof record.rationale === "string"
673
+ ? record.rationale
674
+ : typeof record.reason === "string"
675
+ ? record.reason
676
+ : typeof record.progressNote === "string"
677
+ ? record.progressNote
678
+ : null;
679
+ return text ? truncatePreview(text, 90) : null;
680
+ }
681
+
682
+ /** Explicit first-party leaf/prefix → canonical product icon kind. */
683
+ export function genericToolIconKind(name: string): ToolIconKind {
684
+ const leaf = mcpToolLeaf(name);
685
+ return leaf === "request_human_input"
686
+ ? "question"
687
+ : leaf.startsWith("goal_")
688
+ ? "target"
689
+ : leaf.startsWith("memory_") ||
690
+ leaf === "preference_registry_summary" ||
691
+ leaf === "preference_registry_get"
692
+ ? "brain"
693
+ : leaf.startsWith("session_") ||
694
+ leaf === "sessions_list" ||
695
+ leaf === "set_session_title" ||
696
+ leaf === "set_other_session_title"
697
+ ? "sessions"
698
+ : leaf.startsWith("sandbox") || leaf === "sandboxes_list" || leaf === "run_on"
699
+ ? "server"
700
+ : leaf.startsWith("rig_")
701
+ ? "server-cog"
702
+ : leaf.startsWith("scheduled_")
703
+ ? "calendar"
704
+ : leaf.startsWith("artifacts_")
705
+ ? "panels"
706
+ : leaf.startsWith("social_")
707
+ ? "share"
708
+ : leaf.startsWith("slack_")
709
+ ? "message"
710
+ : leaf.startsWith("github_")
711
+ ? "git"
712
+ : leaf.startsWith("variable_")
713
+ ? "box"
714
+ : leaf.startsWith("environment_")
715
+ ? "key"
716
+ : leaf.includes("document") ||
717
+ leaf.includes("knowledge") ||
718
+ leaf === "list_document_bases"
719
+ ? "file-search"
720
+ : leaf === "tool_search"
721
+ ? "package-search"
722
+ : leaf.startsWith("skill_")
723
+ ? "plug"
724
+ : "wrench";
725
+ }
726
+
727
+ type McpRowOptions = {
728
+ tool: PresentedToolKind;
729
+ icon: ToolIconKind;
730
+ title: string;
731
+ /** Preview while running (falls back to `runningFallback`). */
732
+ runningPreview: string | null;
733
+ runningFallback: string;
734
+ /** Settled preview (null → none); ask/run_on also use it as the error fallback. */
735
+ settledPreview: string | null;
736
+ /** Generic shows "Done" when no settled preview exists and skips the error fallback. */
737
+ settledFallback?: string | undefined;
738
+ /** Ask/run_on omit an empty Result block. */
739
+ omitEmptyResult?: boolean | undefined;
740
+ /** Generic shows a goal preview as plain text (no pulse) while running. */
741
+ plainRunningPreview?: boolean | undefined;
742
+ };
743
+
744
+ function mcpRowPresentation(item: ToolCallItem, options: McpRowOptions): ToolRowPresentation {
745
+ const args = parseToolArgs(item.arguments);
746
+ const base = { tool: options.tool, icon: options.icon, title: options.title };
747
+ if (item.status === "running") {
748
+ return {
749
+ ...base,
750
+ iconTone: "running",
751
+ running: true,
752
+ preview:
753
+ options.runningPreview != null && options.plainRunningPreview
754
+ ? textPreview(options.runningPreview)
755
+ : textPreview(options.runningPreview ?? options.runningFallback, true),
756
+ body: { kind: "payloads", blocks: [{ label: "Arguments", value: args }] },
757
+ };
758
+ }
759
+ const { text: outText, isError } = unwrapMcpOutput(item.output);
760
+ // Cancelled is not an error, even if the payload carries an isError flag.
761
+ if ((isError || item.status === "failed") && item.status !== "cancelled") {
762
+ const errorFallback = options.settledFallback === undefined ? options.settledPreview : null;
763
+ return {
764
+ ...base,
765
+ iconTone: "failed",
766
+ chip: { tone: "bad", text: "error" },
767
+ preview: textPreview(truncatePreview(outText, 80) || errorFallback || "Error"),
768
+ body: {
769
+ kind: "payloads",
770
+ blocks: [
771
+ { label: "Arguments", value: args },
772
+ { label: "Error", value: outText, failed: true },
773
+ ],
774
+ },
775
+ };
776
+ }
777
+ const settled =
778
+ item.status === "cancelled"
779
+ ? null
780
+ : (options.settledPreview ?? options.settledFallback ?? null);
781
+ return {
782
+ ...base,
783
+ iconTone: "muted",
784
+ cancelled: item.status === "cancelled",
785
+ ...(settled != null ? { preview: textPreview(settled) } : {}),
786
+ body: {
787
+ kind: "payloads",
788
+ blocks:
789
+ options.omitEmptyResult && !outText
790
+ ? [{ label: "Arguments", value: args }]
791
+ : [
792
+ { label: "Arguments", value: args },
793
+ { label: "Result", value: outText },
794
+ ],
795
+ },
796
+ };
797
+ }
798
+
799
+ export function askPresentation(item: ToolCallItem): ToolRowPresentation {
800
+ const preview = askToolPreview(parseToolArgs(item.arguments));
801
+ return mcpRowPresentation(item, {
802
+ tool: "ask",
803
+ icon: "question",
804
+ title: "Ask",
805
+ runningPreview: preview,
806
+ runningFallback: "Waiting…",
807
+ settledPreview: preview,
808
+ omitEmptyResult: true,
809
+ });
810
+ }
811
+
812
+ export function runOnPresentation(item: ToolCallItem): ToolRowPresentation {
813
+ const targetName = runOnTargetName(item.output);
814
+ const opPreview = runOnOpPreview(parseToolArgs(item.arguments));
815
+ return mcpRowPresentation(item, {
816
+ tool: "run_on",
817
+ icon: "server",
818
+ title: targetName ? `Run on ${targetName}` : "Run on",
819
+ runningPreview: opPreview,
820
+ runningFallback: "Running…",
821
+ settledPreview: opPreview,
822
+ omitEmptyResult: true,
823
+ });
824
+ }
825
+
826
+ /**
827
+ * Baseline craft for unmatched tools: family icon + title-cased leaf + honest
828
+ * status preview (Running… / Done / error snippet).
829
+ */
830
+ export function genericToolPresentation(item: ToolCallItem): ToolRowPresentation {
831
+ const goalPreview = goalToolPreview(item.name, parseToolArgs(item.arguments));
832
+ if (item.status !== "running") {
833
+ const { text: outText, isError } = unwrapMcpOutput(item.output);
834
+ const base = {
835
+ tool: "generic" as const,
836
+ icon: genericToolIconKind(item.name),
837
+ title: toolDisplayName(item.name, item.display),
838
+ };
839
+ const args = parseToolArgs(item.arguments);
840
+ // A permission Block is a decision, not a tool failure: say so plainly instead
841
+ // of the generic "error occurred, please try again" wrapper.
842
+ if (isError && BLOCKED_OUTPUT.test(outText)) {
843
+ return {
844
+ ...base,
845
+ iconTone: "muted",
846
+ chip: { tone: "interrupted", text: "blocked" },
847
+ preview: textPreview("Blocked by your permission settings"),
848
+ body: {
849
+ kind: "payloads",
850
+ note: "Your permission settings block this action, so it did not run. You can change this in the integration's tool permissions.",
851
+ blocks: [{ label: "Arguments", value: args }],
852
+ },
853
+ };
854
+ }
855
+ // An interrupted approved action may have run. Never invite a blind retry.
856
+ if (isError && UNCERTAIN_OUTPUT.test(outText)) {
857
+ return {
858
+ ...base,
859
+ iconTone: "failed",
860
+ chip: { tone: "bad", text: "outcome unknown" },
861
+ preview: textPreview("It may have run"),
862
+ body: {
863
+ kind: "payloads",
864
+ note: "This action may have run. Check the result in the connected app before trying again.",
865
+ blocks: [{ label: "Arguments", value: args }],
866
+ },
867
+ };
868
+ }
869
+ }
870
+ return mcpRowPresentation(item, {
871
+ tool: "generic",
872
+ icon: genericToolIconKind(item.name),
873
+ title: toolDisplayName(item.name, item.display),
874
+ runningPreview: goalPreview,
875
+ runningFallback: "Running…",
876
+ settledPreview: goalPreview,
877
+ settledFallback: "Done",
878
+ plainRunningPreview: true,
879
+ });
880
+ }
881
+
882
+ /** The runtime's exact refusal for a tool whose effective permission is Block. */
883
+ const BLOCKED_OUTPUT = /Connector action was not executed: blocked\b/;
884
+ /** The runtime's refusal to guess whether an approved action ran. */
885
+ const UNCERTAIN_OUTPUT = /Connector action outcome is uncertain\b/;
886
+
887
+ /* ---- tool_search (progressive MCP disclosure) ------------------------------ */
888
+
889
+ export type DisclosedTool = {
890
+ /** Full wire name (`server__leaf` or bare). */
891
+ name: string;
892
+ /** Server / namespace prefix before `__`, when present. */
893
+ source: string | null;
894
+ /** Leaf tool name after `__`. */
895
+ leaf: string;
896
+ };
897
+
898
+ export function splitToolWireName(name: string): DisclosedTool {
899
+ const boundary = name.indexOf("__");
900
+ if (boundary <= 0) {
901
+ return { name, source: null, leaf: name };
902
+ }
903
+ return {
904
+ name,
905
+ source: name.slice(0, boundary),
906
+ leaf: name.slice(boundary + 2),
907
+ };
908
+ }
909
+
910
+ /** Capability query from live tool_search args (object or JSON string). */
911
+ export function toolSearchQuery(item: ToolCallItem): string {
912
+ const fromArgs = parseToolArgs(item.arguments);
913
+ if (typeof fromArgs.query === "string" && fromArgs.query.trim()) {
914
+ return fromArgs.query.trim();
915
+ }
916
+ const raw = item.raw;
917
+ if (raw && typeof raw === "object") {
918
+ const rawArgs = (raw as { arguments?: unknown }).arguments;
919
+ if (typeof rawArgs === "string" && rawArgs.trim()) {
920
+ const parsed = tryParseJson(rawArgs);
921
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
922
+ const query = (parsed as { query?: unknown }).query;
923
+ if (typeof query === "string" && query.trim()) {
924
+ return query.trim();
925
+ }
926
+ }
927
+ } else if (rawArgs && typeof rawArgs === "object" && !Array.isArray(rawArgs)) {
928
+ const query = (rawArgs as { query?: unknown }).query;
929
+ if (typeof query === "string" && query.trim()) {
930
+ return query.trim();
931
+ }
932
+ }
933
+ }
934
+ return "";
935
+ }
936
+
937
+ /**
938
+ * Parse disclosed tools from the runtime event shape.
939
+ * `normalizeSdkEvent` collapses `tool_search_output.tools[]` into text:
940
+ * "Disclosed tools: a, b" | "No matching tools found."
941
+ * Also accept a structured `tools` array when a host/enricher preserves it.
942
+ */
943
+ export function parseDisclosedTools(output: unknown): DisclosedTool[] | null {
944
+ if (output && typeof output === "object" && !Array.isArray(output)) {
945
+ const tools = (output as { tools?: unknown }).tools;
946
+ if (Array.isArray(tools)) {
947
+ return tools
948
+ .map((tool) => {
949
+ if (typeof tool === "string" && tool.trim()) {
950
+ return splitToolWireName(tool.trim());
951
+ }
952
+ if (
953
+ tool &&
954
+ typeof tool === "object" &&
955
+ typeof (tool as { name?: unknown }).name === "string"
956
+ ) {
957
+ const name = (tool as { name: string }).name.trim();
958
+ return name ? splitToolWireName(name) : null;
959
+ }
960
+ return null;
961
+ })
962
+ .filter((tool): tool is DisclosedTool => tool != null);
963
+ }
964
+ }
965
+
966
+ const { text } = unwrapMcpOutput(output);
967
+ const trimmed = text.trim();
968
+ if (!trimmed) {
969
+ return null;
970
+ }
971
+ if (/^no matching tools found\.?$/i.test(trimmed)) {
972
+ return [];
973
+ }
974
+ const disclosed = trimmed.match(/^disclosed tools:\s*(.+)$/i);
975
+ if (disclosed?.[1]) {
976
+ return disclosed[1]
977
+ .split(",")
978
+ .map((part) => part.trim())
979
+ .filter(Boolean)
980
+ .map(splitToolWireName);
981
+ }
982
+ const parsed = tryParseJson(trimmed);
983
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
984
+ return parseDisclosedTools(parsed);
985
+ }
986
+ return null;
987
+ }
988
+
989
+ export function toolSearchPreview(
990
+ tools: DisclosedTool[] | null,
991
+ cancelled: boolean,
992
+ ): string | undefined {
993
+ if (cancelled) {
994
+ return undefined;
995
+ }
996
+ if (!tools) {
997
+ return "Done";
998
+ }
999
+ if (tools.length === 0) {
1000
+ return "No matches";
1001
+ }
1002
+ if (tools.length === 1) {
1003
+ return tools[0]!.leaf;
1004
+ }
1005
+ const head = tools[0]!.leaf;
1006
+ return `${tools.length} tools · ${truncatePreview(head, 28)}`;
1007
+ }
1008
+
1009
+ export function toolSearchPresentation(item: ToolCallItem): ToolRowPresentation {
1010
+ const query = toolSearchQuery(item);
1011
+ const queryPreview = query ? truncatePreview(query, 64) : "";
1012
+ const note = query ? `capability query: ${query}` : undefined;
1013
+ const args = parseToolArgs(item.arguments);
1014
+ const base = { tool: "tool_search" as const, icon: "package-search" as const };
1015
+ if (item.status === "running") {
1016
+ return {
1017
+ ...base,
1018
+ iconTone: "running",
1019
+ title: "Looking up tools",
1020
+ running: true,
1021
+ preview: textPreview(queryPreview || "Matching capabilities…", true),
1022
+ body: { kind: "listing", note, entries: [], blocks: [{ label: "Arguments", value: args }] },
1023
+ };
1024
+ }
1025
+ const { text: outText, isError } = unwrapMcpOutput(item.output);
1026
+ if ((isError || item.status === "failed") && item.status !== "cancelled") {
1027
+ return {
1028
+ ...base,
1029
+ iconTone: "failed",
1030
+ title: "Tool lookup failed",
1031
+ failed: true,
1032
+ preview: textPreview(truncatePreview(outText, 80) || queryPreview || "Lookup failed"),
1033
+ body: {
1034
+ kind: "listing",
1035
+ note,
1036
+ entries: [],
1037
+ blocks: [
1038
+ { label: "Arguments", value: args },
1039
+ { label: "Error", value: outText, failed: true },
1040
+ ],
1041
+ },
1042
+ };
1043
+ }
1044
+ const tools = parseDisclosedTools(item.output);
1045
+ const preview = toolSearchPreview(tools, item.status === "cancelled");
1046
+ return {
1047
+ ...base,
1048
+ iconTone: "muted",
1049
+ title: "Looked up tools",
1050
+ cancelled: item.status === "cancelled",
1051
+ ...(preview ? { preview: textPreview(preview) } : {}),
1052
+ body: {
1053
+ kind: "listing",
1054
+ note,
1055
+ entries: (tools ?? []).slice(0, 12).map((tool) => ({
1056
+ key: tool.name,
1057
+ title: tool.leaf,
1058
+ eyebrow: tool.source,
1059
+ mono: true,
1060
+ })),
1061
+ more: tools && tools.length > 12 ? tools.length - 12 : undefined,
1062
+ empty:
1063
+ tools && tools.length === 0
1064
+ ? "no deferred tools matched this capability query."
1065
+ : undefined,
1066
+ blocks:
1067
+ tools == null && outText
1068
+ ? [
1069
+ { label: "Arguments", value: args },
1070
+ { label: "Result", value: outText },
1071
+ ]
1072
+ : [{ label: "Arguments", value: args }],
1073
+ },
1074
+ };
1075
+ }
1076
+
1077
+ /* ---- docs / knowledge search ----------------------------------------------- */
1078
+
1079
+ export type SearchHit = { title: string; snippet: string };
1080
+
1081
+ export function parseSearchHits(outText: string): SearchHit[] | null {
1082
+ const parsed = tryParseJson(outText);
1083
+ if (parsed == null) {
1084
+ return null;
1085
+ }
1086
+ const list = Array.isArray(parsed)
1087
+ ? parsed
1088
+ : parsed &&
1089
+ typeof parsed === "object" &&
1090
+ Array.isArray((parsed as { results?: unknown }).results)
1091
+ ? (parsed as { results: unknown[] }).results
1092
+ : parsed && typeof parsed === "object" && Array.isArray((parsed as { hits?: unknown }).hits)
1093
+ ? (parsed as { hits: unknown[] }).hits
1094
+ : null;
1095
+ if (!list) {
1096
+ return null;
1097
+ }
1098
+ return list.map((row) => {
1099
+ const r = row && typeof row === "object" ? (row as Record<string, unknown>) : {};
1100
+ const title =
1101
+ (typeof r.title === "string" && r.title) ||
1102
+ (typeof r.name === "string" && r.name) ||
1103
+ (typeof r.documentTitle === "string" && r.documentTitle) ||
1104
+ (typeof r.path === "string" && r.path) ||
1105
+ (typeof r.id === "string" && r.id) ||
1106
+ "Result";
1107
+ const snippet =
1108
+ (typeof r.snippet === "string" && r.snippet) ||
1109
+ (typeof r.text === "string" && r.text) ||
1110
+ (typeof r.content === "string" && r.content) ||
1111
+ "";
1112
+ return { title, snippet: truncatePreview(snippet, 160) };
1113
+ });
1114
+ }
1115
+
1116
+ export function docsSearchPresentation(item: ToolCallItem): ToolRowPresentation {
1117
+ const args = parseToolArgs(item.arguments);
1118
+ const query = typeof args.query === "string" ? args.query.trim() : "";
1119
+ const base = {
1120
+ tool: "docs_search" as const,
1121
+ icon: "file-search" as const,
1122
+ title: query
1123
+ ? `Search \u201c${truncatePreview(query, 48)}\u201d`
1124
+ : toolDisplayName(item.name, item.display),
1125
+ };
1126
+ if (item.status === "running") {
1127
+ return {
1128
+ ...base,
1129
+ iconTone: "running",
1130
+ running: true,
1131
+ preview: textPreview("Searching…", true),
1132
+ body: { kind: "payloads", blocks: [{ label: "Arguments", value: args }] },
1133
+ };
1134
+ }
1135
+ const { text: outText, isError } = unwrapMcpOutput(item.output);
1136
+ if ((isError || item.status === "failed") && item.status !== "cancelled") {
1137
+ return {
1138
+ ...base,
1139
+ iconTone: "failed",
1140
+ failed: true,
1141
+ preview: textPreview(truncatePreview(outText, 80) || "Search failed"),
1142
+ body: {
1143
+ kind: "payloads",
1144
+ blocks: [
1145
+ { label: "Arguments", value: args },
1146
+ { label: "Error", value: outText, failed: true },
1147
+ ],
1148
+ },
1149
+ };
1150
+ }
1151
+ const hits = parseSearchHits(outText);
1152
+ const preview =
1153
+ item.status === "cancelled"
1154
+ ? undefined
1155
+ : hits
1156
+ ? hits.length === 0
1157
+ ? "No hits"
1158
+ : `${hits.length} hit${hits.length === 1 ? "" : "s"}`
1159
+ : "Done";
1160
+ return {
1161
+ ...base,
1162
+ iconTone: "muted",
1163
+ cancelled: item.status === "cancelled",
1164
+ ...(preview ? { preview: textPreview(preview) } : {}),
1165
+ body: {
1166
+ kind: "listing",
1167
+ entries: (hits ?? []).slice(0, 8).map((hit) => ({
1168
+ key: `${hit.title}\u0000${hit.snippet}`,
1169
+ title: hit.title,
1170
+ snippet: hit.snippet || undefined,
1171
+ })),
1172
+ blocks: [
1173
+ { label: "Arguments", value: args },
1174
+ { label: "Result", value: outText },
1175
+ ],
1176
+ },
1177
+ };
1178
+ }
1179
+
1180
+ /* ---- set_session_title / set_other_session_title --------------------------- */
1181
+
1182
+ export function sessionTitlePresentation(item: ToolCallItem): ToolRowPresentation {
1183
+ const args = parseToolArgs(item.arguments);
1184
+ const titleArg = typeof args.title === "string" ? args.title.trim() : "";
1185
+ const previewTitle = titleArg ? truncatePreview(titleArg, 72) : "";
1186
+ const base = {
1187
+ tool: "session_title" as const,
1188
+ icon: "sessions" as const,
1189
+ title: toolDisplayName(item.name, item.display),
1190
+ };
1191
+ if (item.status === "running") {
1192
+ return {
1193
+ ...base,
1194
+ iconTone: "running",
1195
+ running: true,
1196
+ preview: textPreview(previewTitle || "Setting title…", true),
1197
+ body: { kind: "payloads", blocks: [{ label: "Arguments", value: args }] },
1198
+ };
1199
+ }
1200
+ const { text: outText, isError } = unwrapMcpOutput(item.output);
1201
+ if ((isError || item.status === "failed") && item.status !== "cancelled") {
1202
+ return {
1203
+ ...base,
1204
+ iconTone: "failed",
1205
+ failed: true,
1206
+ preview: textPreview(truncatePreview(outText, 80) || "Rename failed"),
1207
+ body: {
1208
+ kind: "payloads",
1209
+ blocks: [
1210
+ { label: "Arguments", value: args },
1211
+ { label: "Error", value: outText, failed: true },
1212
+ ],
1213
+ },
1214
+ };
1215
+ }
1216
+ // Prefer the submitted title; fall back to a title field in the tool result.
1217
+ let settledTitle = previewTitle;
1218
+ if (!settledTitle) {
1219
+ const parsed = tryParseJson(outText);
1220
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
1221
+ const fromResult = (parsed as { title?: unknown }).title;
1222
+ if (typeof fromResult === "string" && fromResult.trim()) {
1223
+ settledTitle = truncatePreview(fromResult.trim(), 72);
1224
+ }
1225
+ }
1226
+ }
1227
+ return {
1228
+ ...base,
1229
+ iconTone: "muted",
1230
+ cancelled: item.status === "cancelled",
1231
+ ...(item.status !== "cancelled" && settledTitle ? { preview: textPreview(settledTitle) } : {}),
1232
+ body: {
1233
+ kind: "payloads",
1234
+ blocks: outText
1235
+ ? [
1236
+ { label: "Arguments", value: args },
1237
+ { label: "Result", value: outText },
1238
+ ]
1239
+ : [{ label: "Arguments", value: args }],
1240
+ },
1241
+ };
1242
+ }
1243
+
1244
+ /* ---- resolution ------------------------------------------------------------ */
1245
+
1246
+ const PRESENTERS_BY_RAW_TYPE: Record<string, PresentedToolKind> = {
1247
+ apply_patch_call: "apply_patch",
1248
+ // Web renders these with richer media renderers; keep them off name matches.
1249
+ computer_call: "generic",
1250
+ tool_search_call: "tool_search",
1251
+ };
1252
+
1253
+ const PRESENTERS_BY_NAME: Record<string, PresentedToolKind> = {
1254
+ exec_command: "exec",
1255
+ request_human_input: "ask",
1256
+ run_on: "run_on",
1257
+ write_stdin: "write_stdin",
1258
+ apply_patch_call: "apply_patch",
1259
+ apply_patch: "apply_patch",
1260
+ web_search_call: "web_search",
1261
+ tool_search: "tool_search",
1262
+ search_documents: "docs_search",
1263
+ knowledge_search: "docs_search",
1264
+ set_session_title: "session_title",
1265
+ set_other_session_title: "session_title",
1266
+ };
1267
+
1268
+ /**
1269
+ * Resolve the shared presenter for a call with the web registry's precedence
1270
+ * (raw.type, exact name, MCP leaf). Tools whose web renderer is richer than the
1271
+ * shared model (computer use, media, knowledge receipts, …) resolve to
1272
+ * `generic`; non-DOM renderers may layer their own presenters on top.
1273
+ */
1274
+ export function presentedToolKind(item: ToolCallItem): PresentedToolKind {
1275
+ const rawType = rawTypeOf(item);
1276
+ if (rawType && PRESENTERS_BY_RAW_TYPE[rawType]) {
1277
+ return PRESENTERS_BY_RAW_TYPE[rawType];
1278
+ }
1279
+ const exact = PRESENTERS_BY_NAME[item.name];
1280
+ if (exact) {
1281
+ return exact;
1282
+ }
1283
+ const leaf = mcpToolLeaf(item.name);
1284
+ if (leaf !== item.name && PRESENTERS_BY_NAME[leaf]) {
1285
+ return PRESENTERS_BY_NAME[leaf];
1286
+ }
1287
+ return "generic";
1288
+ }
1289
+
1290
+ export function toolRowPresentation(
1291
+ item: ToolCallItem,
1292
+ context: ToolPresentationContext = {},
1293
+ ): ToolRowPresentation {
1294
+ switch (presentedToolKind(item)) {
1295
+ case "exec":
1296
+ return execPresentation(item, context);
1297
+ case "write_stdin":
1298
+ return writeStdinPresentation(item);
1299
+ case "apply_patch":
1300
+ return applyPatchPresentation(item) ?? genericToolPresentation(item);
1301
+ case "web_search":
1302
+ return webSearchPresentation(item);
1303
+ case "ask":
1304
+ return askPresentation(item);
1305
+ case "run_on":
1306
+ return runOnPresentation(item);
1307
+ case "tool_search":
1308
+ return toolSearchPresentation(item);
1309
+ case "docs_search":
1310
+ return docsSearchPresentation(item);
1311
+ case "session_title":
1312
+ return sessionTitlePresentation(item);
1313
+ default:
1314
+ return genericToolPresentation(item);
1315
+ }
1316
+ }