@marimo-team/frontend 0.25.3-dev13 → 0.25.3-dev135

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 (568) hide show
  1. package/dist/assets/CellStatus-Bu_cFOaf.js +1 -0
  2. package/dist/assets/{ConnectedDataExplorerComponent-TprnxZeJ.js → ConnectedDataExplorerComponent-BV1mVpaE.js} +1 -1
  3. package/dist/assets/{ErrorBoundary-CM13wrd8.js → ErrorBoundary-Cy4lxM4U.js} +2 -2
  4. package/dist/assets/JsonOutput-Dnd0uzN4.js +11 -0
  5. package/dist/assets/{LazyAnyLanguageCodeMirror-B4fCknq1.js → LazyAnyLanguageCodeMirror-DoxWX_Wp.js} +2 -2
  6. package/dist/assets/MarimoErrorOutput-DWgmERpO.js +10 -0
  7. package/dist/assets/{RenderHTML-DX6i99Op.js → RenderHTML-BuZ8DdVv.js} +2 -2
  8. package/dist/assets/RunButton-BXXDV5w-.js +1 -0
  9. package/dist/assets/__vite-browser-external-BynxqS4w.js +1 -0
  10. package/dist/assets/__vite-browser-external-DTOT9NDN.js +1 -0
  11. package/dist/assets/{add-cell-with-ai-BpD_790A.js → add-cell-with-ai-DYahRMb_.js} +26 -26
  12. package/dist/assets/{add-connection-dialog-B1BXCjex.js → add-connection-dialog-CjRaQbDW.js} +51 -51
  13. package/dist/assets/{agent-panel-CDFUc1uu.js → agent-panel-Cb9PZdDM.js} +4 -4
  14. package/dist/assets/ai-model-dropdown-Bbr2oylS.js +13 -0
  15. package/dist/assets/alert-dialog-8YiYLrfr.js +1 -0
  16. package/dist/assets/any-language-editor-BWmz0P_C.js +1 -0
  17. package/dist/assets/{app-config-button-AdV-QDD7.js → app-config-button-CPNc_---.js} +1 -1
  18. package/dist/assets/arrays-0R2reF2y.js +1 -0
  19. package/dist/assets/{blob-BG8yoQmx.js → blob-CQAkRxR1.js} +1 -1
  20. package/dist/assets/{button-COI-NGrx.js → button-Cl7haVNh.js} +1 -1
  21. package/dist/assets/{cache-panel-DTY1dqvi.js → cache-panel-DuBsA6oO.js} +1 -1
  22. package/dist/assets/{capabilities-BJvf-MD4.js → capabilities-DcB-Dd0T.js} +1 -1
  23. package/dist/assets/cell-editor-CjvWSYDB.js +42 -0
  24. package/dist/assets/cell-link-DIOanEQB.js +1 -0
  25. package/dist/assets/cells-lwP9-xsQ.js +220 -0
  26. package/dist/assets/{chat-display-DhgI2MS9.js → chat-display-DpCQoui-.js} +1 -1
  27. package/dist/assets/chat-panel-C79_pWxF.js +4 -0
  28. package/dist/assets/chat-ui-DOOiaOcb.js +4 -0
  29. package/dist/assets/circle-B0vOU-Dh.js +1 -0
  30. package/dist/assets/{code-visibility-BJImdpDi.js → code-visibility-D1Wf7-vD.js} +1 -1
  31. package/dist/assets/column-preview-DIvrCqra.js +1 -0
  32. package/dist/assets/command-palette-BYgBVslq.js +1 -0
  33. package/dist/assets/{common-Sl3uthjg.js → common-B7U2CeDc.js} +1 -1
  34. package/dist/assets/{components-CskjK6xZ.js → components-9p_w2C6e.js} +1 -1
  35. package/dist/assets/components-B6gDDccL.js +1 -0
  36. package/dist/assets/{components-3cou6Mka.js → components-Vz1pD133.js} +1 -1
  37. package/dist/assets/config-7IjqNuVp.js +1 -0
  38. package/dist/assets/config-BC32AAdw.js +1 -0
  39. package/dist/assets/{config-CA1V-wjh.js → config-CXnC3MRv.js} +1 -1
  40. package/dist/assets/{copy-D8O_CYCG.js → copy-74EjuZso.js} +1 -1
  41. package/dist/assets/{copy-icon-BIiRXh_3.js → copy-icon-Craaocbu.js} +1 -1
  42. package/dist/assets/{createReducer-DgRODTW6.js → createReducer-B04CIO-e.js} +1 -1
  43. package/dist/assets/{datasource-DfbNb83e.js → datasource-Bp8TnG7a.js} +2 -2
  44. package/dist/assets/{dates-CfmdTL6B.js → dates-CaPZVGtm.js} +1 -1
  45. package/dist/assets/{dependency-graph-panel-L5cBE5sl.js → dependency-graph-panel-B31-YcSF.js} +3 -3
  46. package/dist/assets/dist-gaK_BThd.js +1 -0
  47. package/dist/assets/{documentation-panel-D7S8JIc2.js → documentation-panel-C2MJwSef.js} +1 -1
  48. package/dist/assets/download-J6sWXUJR.js +9 -0
  49. package/dist/assets/dropdown-menu-Cwi17BoX.js +1 -0
  50. package/dist/assets/edit-page-DfxHDnWP.js +9 -0
  51. package/dist/assets/{error-banner-COZ7SfYV.js → error-banner-m3mastc-.js} +1 -1
  52. package/dist/assets/{error-entries-CLnPDv7b.js → error-entries-BcRbOxwK.js} +1 -1
  53. package/dist/assets/{error-panel-D2xrYLue.js → error-panel-jZlFCjdy.js} +1 -1
  54. package/dist/assets/{es-Cqst59WX.js → es-Rg27gAEy.js} +1 -1
  55. package/dist/assets/feedback-button-94vZrmBy.js +1 -0
  56. package/dist/assets/{feedback-button-DzPunIqU.js → feedback-button-C2XmZw_y.js} +2 -2
  57. package/dist/assets/file-explorer-panel-Cg9UovsS.js +1 -0
  58. package/dist/assets/{file-name-input-B4fRaQkI.js → file-name-input-y9ggAMGJ.js} +2 -2
  59. package/dist/assets/floating-outline-CE1olGl0.js +1 -0
  60. package/dist/assets/{formats-yZ06h1Pl.js → formats-CYyvbiZA.js} +1 -1
  61. package/dist/assets/{formatting-BqrP-n49.js → formatting-DW2u7HXI.js} +1 -1
  62. package/dist/assets/fullscreen-D-ldV-19.js +41 -0
  63. package/dist/assets/{gallery-page-BefvdsM7.js → gallery-page-ClEnoAT-.js} +1 -1
  64. package/dist/assets/{ganttDiagram-EL5Y4UJY-2n7Ig5Jm.js → ganttDiagram-EL5Y4UJY-CYqkCfFG.js} +1 -1
  65. package/dist/assets/{glide-data-editor-C3eaYlXg.js → glide-data-editor-Cp0q28Zz.js} +2 -2
  66. package/dist/assets/{glide-utils-CIrAxdjv.js → glide-utils-DsTeJ7WA.js} +2 -2
  67. package/dist/assets/home-page-DJsI6Od_.js +1 -0
  68. package/dist/assets/{hooks-DzML9nez.js → hooks-DGSryuSD.js} +1 -1
  69. package/dist/assets/{html-to-image-DK9Zl1lU.js → html-to-image-BW0fcUS8.js} +1 -1
  70. package/dist/assets/index-BjNf54kO.js +30 -0
  71. package/dist/assets/index-u08m0hQE.css +2 -0
  72. package/dist/assets/{input-BoBxR50a.js → input-DLA5Dhn3.js} +2 -2
  73. package/dist/assets/kiosk-mode-Cbxffiz9.js +1 -0
  74. package/dist/assets/{layout-Ck1RoL1B.js → layout-DRVIFud8.js} +5 -5
  75. package/dist/assets/linear-Bma8J3iM.js +1 -0
  76. package/dist/assets/links-UwsB2RA1.js +1 -0
  77. package/dist/assets/{logs-panel-BRytaWaO.js → logs-panel-Db38azhc.js} +1 -1
  78. package/dist/assets/{markdown-renderer-DX0Xrrfy.js → markdown-renderer-D2td9eFc.js} +1 -1
  79. package/dist/assets/menu-items-yD7IV3V4.js +1 -0
  80. package/dist/assets/{mermaid-C4EiVqcd.js → mermaid-DmekSy8J.js} +2 -2
  81. package/dist/assets/{name-cell-input-DlpTvPLa.js → name-cell-input-CJpi0Kvu.js} +1 -1
  82. package/dist/assets/numbers-DJK15_4S.js +1 -0
  83. package/dist/assets/{objects-snlMn4yk.js → objects-rLPlQ3X_.js} +1 -1
  84. package/dist/assets/{once-Haz_uxEL.js → once-6KNTRW0u.js} +1 -1
  85. package/dist/assets/{outline-panel-B2WIpz-1.js → outline-panel-DxQKP4eN.js} +1 -1
  86. package/dist/assets/{package-data-dv4FBHxR.js → package-data-CKPmBDtg.js} +1 -1
  87. package/dist/assets/packages-panel-BFzN4mNb.js +1 -0
  88. package/dist/assets/{panel-accordion-state-BqSH5ttk.js → panel-accordion-state-D3RiRniG.js} +1 -1
  89. package/dist/assets/panels-CpUpLOy4.js +1 -0
  90. package/dist/assets/precisionRound-BxlUs8G4.js +1 -0
  91. package/dist/assets/process-output-B6v1FE29.js +1 -0
  92. package/dist/assets/{quadrantDiagram-AXDQQJYC-yBhCDI7E.js → quadrantDiagram-AXDQQJYC-D9KH5Zge.js} +1 -1
  93. package/dist/assets/react-vega-BTNeboR2.js +189 -0
  94. package/dist/assets/{readonly-code-display-MnMEoYW5.js → readonly-code-display-Deg2hzFh.js} +1 -1
  95. package/dist/assets/{readonly-python-code-ggs4hAzC.js → readonly-python-code-DPGknu49.js} +1 -1
  96. package/dist/assets/{renderShortcut-C1JwYcqW.js → renderShortcut-Bxv9ZLnD.js} +1 -1
  97. package/dist/assets/{requests-lt0JK8Jt.js → requests-BIFR-h4M.js} +1 -1
  98. package/dist/assets/requests-DuLJN9Tf.js +1 -0
  99. package/dist/assets/{reveal-component-PiV1eQk9.js → reveal-component-CXkDpGxy.js} +37 -37
  100. package/dist/assets/run-page-qp2KKYgs.js +1 -0
  101. package/dist/assets/{runs-BLp5jezv.js → runs-C8uOPNAW.js} +1 -1
  102. package/dist/assets/{runtime-details-state-CoL-p0MC.js → runtime-details-state-BiGF299n.js} +1 -1
  103. package/dist/assets/{save-worker-BbUSwZRG.js → save-worker-UwdGcNK5.js} +2 -1
  104. package/dist/assets/scratchpad-panel-QV0lacAe.js +1 -0
  105. package/dist/assets/{scroll-to-bottom-button-1FyowpWV.js → scroll-to-bottom-button-CidjyqiH.js} +1 -1
  106. package/dist/assets/secrets-panel-ConQpchl.js +1 -0
  107. package/dist/assets/select-CgWQvW1F.js +1 -0
  108. package/dist/assets/{session-DqoWmb7X.js → session-BHgGkjDm.js} +1 -1
  109. package/dist/assets/session-panel-CrWluawa.js +1 -0
  110. package/dist/assets/snippets-panel-CM7g9b6c.js +1 -0
  111. package/dist/assets/{spec-BfSBcO5B.js → spec-DFtwOyXT.js} +1 -1
  112. package/dist/assets/state-BYETGwDZ.js +1 -0
  113. package/dist/assets/{state-uwRvJLb8.js → state-CZu2E2Lb.js} +1 -1
  114. package/dist/assets/{state-C3oDoyFe.js → state-ClBFtZxn.js} +1 -1
  115. package/dist/assets/{state-DxQnC_1I.js → state-CrLrURYG.js} +1 -1
  116. package/dist/assets/{state-DtGB7xeJ.js → state-DhMztz1E.js} +1 -1
  117. package/dist/assets/state-lEPoZS4k.js +107 -0
  118. package/dist/assets/{strings-B2vv-ENv.js → strings-3lNX212T.js} +1 -1
  119. package/dist/assets/{swiper-component-a07domrZ.js → swiper-component-BwGv-Pu1.js} +1 -1
  120. package/dist/assets/switch-D2gdC_ep.js +1 -0
  121. package/dist/assets/tabs-BLczoY3k.js +1 -0
  122. package/dist/assets/{terminal-wnSHYT8N.js → terminal-DLgGyFIP.js} +1 -1
  123. package/dist/assets/{time-MgToa8VM.js → time-DswSXBDk.js} +1 -1
  124. package/dist/assets/toast-trUlkvx3.js +1 -0
  125. package/dist/assets/tooltip-B5lAA_jn.js +1 -0
  126. package/dist/assets/tooltip-BiQdpXA0.js +61 -0
  127. package/dist/assets/tracing-DRA8maZB.js +1 -0
  128. package/dist/assets/tracing-panel-DLxPRadV.js +2 -0
  129. package/dist/assets/{tree-actions-DnUokmva.js → tree-actions-COtU5qy_.js} +1 -1
  130. package/dist/assets/use-restore-focus-DMSzeuUr.js +1 -0
  131. package/dist/assets/{useAddCell-IN24thff.js → useAddCell-BAEOA87M.js} +1 -1
  132. package/dist/assets/useAsyncData-qvoPYHtx.js +1 -0
  133. package/dist/assets/useBoolean-BkeUcn1n.js +1 -0
  134. package/dist/assets/useCellActionButton-BobjsJfu.js +1 -0
  135. package/dist/assets/useDebounce-DwTQ_1Pu.js +1 -0
  136. package/dist/assets/{useDeepCompareMemoize-DFIVN9dn.js → useDeepCompareMemoize-B2DVK2De.js} +1 -1
  137. package/dist/assets/useDelayElapsed-BlsDT4TV.js +1 -0
  138. package/dist/assets/{useDeleteCell-fQlM46Y2.js → useDeleteCell-gedazkBF.js} +1 -1
  139. package/dist/assets/{useDependencyPanelTab-ImXYINm_.js → useDependencyPanelTab-DAJ6BOUm.js} +1 -1
  140. package/dist/assets/{useEvent-Dfcbgjhg.js → useEvent-BDjgaBtz.js} +1 -1
  141. package/dist/assets/{useEventListener-D9cftcHj.js → useEventListener-DPOTkksd.js} +1 -1
  142. package/dist/assets/{useIframeCapabilities-CwTkczVN.js → useIframeCapabilities-sHeZt_EA.js} +1 -1
  143. package/dist/assets/{useInstallPackage-BW06eter.js → useInstallPackage-BfNKN33w.js} +1 -1
  144. package/dist/assets/{useInterval--x3s1VpI.js → useInterval-BcdwHHB5.js} +1 -1
  145. package/dist/assets/useNotebookActions-CnLArLoz.js +1 -0
  146. package/dist/assets/{useRunCells-DSJPXE-j.js → useRunCells-CUknep7p.js} +1 -1
  147. package/dist/assets/{useSplitCell-DQyMF5gd.js → useSplitCell-DeXniINv.js} +1 -1
  148. package/dist/assets/useStateForKey-CGMJQT8x.js +1 -0
  149. package/dist/assets/{useTheme-n8Dj1zH7.js → useTheme-C2dnh2vM.js} +1 -1
  150. package/dist/assets/{utils-CaQYvazl.js → utils-DfElfBpz.js} +1 -1
  151. package/dist/assets/vega-component-DJf6ho22.js +1 -0
  152. package/dist/assets/{vega-embed-container-DJPNkHPb.js → vega-embed-container-DtArSJz1.js} +1 -1
  153. package/dist/assets/vega-loader.browser-Bu25TKax.js +6 -0
  154. package/dist/assets/worker-jm2VC7pS.js +159 -0
  155. package/dist/assets/{write-secret-modal-DzKAInL2.js → write-secret-modal-CBi2vNK_.js} +1 -1
  156. package/dist/assets/{xychartDiagram-S5SC5T6Z-KbGzG6-u.js → xychartDiagram-S5SC5T6Z-CeRnBS5e.js} +1 -1
  157. package/dist/index.html +81 -79
  158. package/package.json +14 -14
  159. package/src/__tests__/host-imports.test.ts +1 -0
  160. package/src/__tests__/module-entry.test.ts +32 -0
  161. package/src/__tests__/mount.test.ts +0 -20
  162. package/src/components/ai/__tests__/ai-model-dropdown.test.tsx +63 -0
  163. package/src/components/ai/ai-model-dropdown.tsx +11 -6
  164. package/src/components/app-config/ai-config.tsx +7 -2
  165. package/src/components/chat/__tests__/message-queue.test.tsx +17 -0
  166. package/src/components/chat/acp/__tests__/session-tabs.test.tsx +43 -0
  167. package/src/components/chat/acp/__tests__/state.test.ts +2 -2
  168. package/src/components/chat/acp/blocks.tsx +3 -2
  169. package/src/components/chat/acp/session-tabs.tsx +8 -3
  170. package/src/components/chat/chat-components.tsx +2 -0
  171. package/src/components/chat/chat-panel.tsx +9 -8
  172. package/src/components/chat/chat-utils.ts +4 -8
  173. package/src/components/data-table/TableTopBar.tsx +2 -0
  174. package/src/components/data-table/__tests__/chart-spec-model.test.ts +195 -195
  175. package/src/components/data-table/__tests__/column-explorer.test.tsx +27 -1
  176. package/src/components/data-table/__tests__/columns.test.tsx +105 -0
  177. package/src/components/data-table/__tests__/context-menu-interaction.test.tsx +130 -0
  178. package/src/components/data-table/__tests__/data-table.test.tsx +1 -0
  179. package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
  180. package/src/components/data-table/__tests__/export-actions.test.tsx +105 -0
  181. package/src/components/data-table/__tests__/keyboard-selection.test.tsx +188 -0
  182. package/src/components/data-table/__tests__/search-highlight.test.tsx +109 -0
  183. package/src/components/data-table/__tests__/url-detector.test.tsx +74 -0
  184. package/src/components/data-table/cell-selection/feature.ts +2 -2
  185. package/src/components/data-table/cell-selection/types.ts +2 -2
  186. package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
  187. package/src/components/data-table/charts/__tests__/spec-snapshot.test.ts +20 -20
  188. package/src/components/data-table/charts/__tests__/spec.test.ts +78 -52
  189. package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
  190. package/src/components/data-table/charts/chart-spec/spec.ts +68 -43
  191. package/src/components/data-table/charts/charts.tsx +40 -30
  192. package/src/components/data-table/charts/storage.ts +16 -5
  193. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
  194. package/src/components/data-table/column-summary/chart-spec-model.tsx +23 -16
  195. package/src/components/data-table/column-summary/column-summary.tsx +2 -4
  196. package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
  197. package/src/components/data-table/columns.tsx +45 -46
  198. package/src/components/data-table/context-menu.tsx +36 -20
  199. package/src/components/data-table/data-table.tsx +13 -1
  200. package/src/components/data-table/date-popover.tsx +6 -4
  201. package/src/components/data-table/export-actions.tsx +76 -48
  202. package/src/components/data-table/range-focus/atoms.ts +4 -6
  203. package/src/components/data-table/range-focus/use-cell-range-selection.ts +65 -38
  204. package/src/components/data-table/range-focus/use-scroll-into-view.ts +21 -2
  205. package/src/components/data-table/renderers.tsx +16 -7
  206. package/src/components/data-table/row-viewer-panel/__tests__/row-viewer.test.tsx +24 -1
  207. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +4 -4
  208. package/src/components/data-table/search-highlight.tsx +79 -0
  209. package/src/components/data-table/types.ts +1 -0
  210. package/src/components/data-table/url-detector.tsx +49 -9
  211. package/src/components/datasources/__tests__/column-actions.test.tsx +97 -0
  212. package/src/components/datasources/__tests__/column-preview.test.tsx +98 -5
  213. package/src/components/datasources/__tests__/datasources-interactions.test.tsx +181 -0
  214. package/src/components/datasources/__tests__/table-list.test.tsx +118 -0
  215. package/src/components/datasources/__tests__/utils.test.ts +57 -6
  216. package/src/components/datasources/column-preview.tsx +13 -4
  217. package/src/components/datasources/datasources.tsx +51 -39
  218. package/src/components/datasources/utils.ts +32 -23
  219. package/src/components/debugger/debugger-code.tsx +5 -0
  220. package/src/components/dependency-graph/dependency-graph-tree.tsx +8 -8
  221. package/src/components/dependency-graph/elements.ts +24 -21
  222. package/src/components/dependency-graph/panels.tsx +2 -1
  223. package/src/components/dependency-graph/utils/__tests__/layout.test.ts +18 -11
  224. package/src/components/editor/SortableCell.tsx +1 -3
  225. package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
  226. package/src/components/editor/__tests__/package-alert.test.tsx +22 -1
  227. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +24 -0
  228. package/src/components/editor/actions/pair-with-agent-modal.tsx +18 -15
  229. package/src/components/editor/ai/add-cell-with-ai.tsx +3 -3
  230. package/src/components/editor/ai/ai-completion-editor.tsx +1 -0
  231. package/src/components/editor/alerts/startup-logs-alert.tsx +1 -0
  232. package/src/components/editor/cell/CreateCellButton.tsx +8 -10
  233. package/src/components/editor/cell/DeleteButton.tsx +1 -0
  234. package/src/components/editor/cell/__tests__/useShouldShowInterrupt.test.ts +39 -0
  235. package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
  236. package/src/components/editor/cell/code/cell-editor.tsx +1 -1
  237. package/src/components/editor/cell/code/language-toggle.tsx +8 -7
  238. package/src/components/editor/cell/collapse.tsx +5 -3
  239. package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
  240. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +30 -1
  241. package/src/components/editor/chrome/panels/cache-panel.tsx +1 -0
  242. package/src/components/editor/chrome/panels/outline/__tests__/outline-keyboard.test.tsx +84 -0
  243. package/src/components/editor/chrome/panels/outline/floating-outline.tsx +39 -14
  244. package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +3 -2
  245. package/src/components/editor/chrome/panels/packages-panel.tsx +4 -7
  246. package/src/components/editor/chrome/panels/secrets-panel.tsx +1 -0
  247. package/src/components/editor/chrome/panels/snippets-panel.tsx +5 -1
  248. package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +12 -18
  249. package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +58 -1
  250. package/src/components/editor/chrome/wrapper/footer-items/runtime-settings.tsx +1 -7
  251. package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +12 -2
  252. package/src/components/editor/chrome/wrapper/storage.ts +1 -1
  253. package/src/components/editor/connections/components.tsx +1 -1
  254. package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
  255. package/src/components/editor/controls/__tests__/keyboard-shortcuts.test.tsx +61 -0
  256. package/src/components/editor/controls/command-palette.tsx +22 -10
  257. package/src/components/editor/controls/keyboard-shortcuts.tsx +14 -5
  258. package/src/components/editor/dynamic-favicon.tsx +21 -40
  259. package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +12 -23
  260. package/src/components/editor/file-tree/__tests__/file-explorer-interactions.test.tsx +6 -0
  261. package/src/components/editor/file-tree/__tests__/file-explorer-navigation.test.tsx +47 -0
  262. package/src/components/editor/file-tree/__tests__/use-file-search.test.tsx +91 -0
  263. package/src/components/editor/file-tree/file-explorer.tsx +45 -8
  264. package/src/components/editor/file-tree/file-name-input.tsx +1 -0
  265. package/src/components/editor/file-tree/file-viewer.tsx +4 -2
  266. package/src/components/editor/file-tree/use-file-search.ts +35 -21
  267. package/src/components/editor/header/status.tsx +28 -5
  268. package/src/components/editor/links/__tests__/cell-link.test.tsx +146 -0
  269. package/src/components/editor/links/cell-link.tsx +14 -5
  270. package/src/components/editor/navigation/focus-utils.ts +4 -4
  271. package/src/components/editor/notebook-banner.tsx +1 -0
  272. package/src/components/editor/notebook-cell.tsx +11 -2
  273. package/src/components/editor/output/MarimoTracebackOutput.tsx +19 -17
  274. package/src/components/editor/output/__tests__/traceback.test.tsx +27 -1
  275. package/src/components/editor/output/ansi-reduce.ts +33 -20
  276. package/src/components/editor/output/console/ConsoleOutput.tsx +19 -25
  277. package/src/components/editor/package-alert.tsx +14 -7
  278. package/src/components/editor/renderers/grid-layout/grid-layout.tsx +12 -6
  279. package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
  280. package/src/components/home/components.tsx +17 -31
  281. package/src/components/icons/__tests__/large-spinner.test.tsx +39 -0
  282. package/src/components/icons/large-spinner.tsx +3 -14
  283. package/src/components/icons/spinner.tsx +1 -1
  284. package/src/components/mcp/mcp-status-indicator.tsx +1 -1
  285. package/src/components/pages/__tests__/home-page.test.tsx +116 -0
  286. package/src/components/pages/home-page.tsx +164 -91
  287. package/src/components/scratchpad/scratchpad.test.tsx +95 -0
  288. package/src/components/scratchpad/scratchpad.tsx +16 -3
  289. package/src/components/slides/reveal-component.tsx +4 -2
  290. package/src/components/slides/slide-cell-view.tsx +1 -1
  291. package/src/components/slides/slide-form.tsx +1 -0
  292. package/src/components/tracing/tracing-keyboard.test.tsx +85 -0
  293. package/src/components/tracing/tracing.tsx +45 -41
  294. package/src/components/ui/__tests__/draggable-popover.test.tsx +24 -0
  295. package/src/components/ui/alert-dialog.tsx +1 -1
  296. package/src/components/ui/draggable-popover.tsx +24 -2
  297. package/src/core/ai/context/providers/datasource.ts +6 -2
  298. package/src/core/ai/tools/base.ts +16 -7
  299. package/src/core/ai/tools/edit-notebook-tool.ts +47 -45
  300. package/src/core/ai/tools/registry.ts +13 -8
  301. package/src/core/ai/tools/sample-tool.ts +6 -7
  302. package/src/core/attachments/state.ts +5 -8
  303. package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -0
  304. package/src/core/cells/__tests__/cell.test.ts +39 -0
  305. package/src/core/cells/__tests__/cells.test.ts +3 -1
  306. package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
  307. package/src/core/cells/__tests__/notebook-outline.test.ts +113 -0
  308. package/src/core/cells/__tests__/session.test.ts +117 -36
  309. package/src/core/cells/cell.ts +14 -3
  310. package/src/core/cells/cells.ts +3 -1
  311. package/src/core/cells/pending-delete-service.ts +2 -6
  312. package/src/core/cells/session.ts +1 -1
  313. package/src/core/cells/types.ts +10 -1
  314. package/src/core/codemirror/__tests__/setup.test.ts +29 -29
  315. package/src/core/codemirror/cells/__tests__/extensions.test.ts +15 -0
  316. package/src/core/codemirror/cells/extensions.ts +7 -3
  317. package/src/core/codemirror/keymaps/vim.ts +2 -6
  318. package/src/core/codemirror/language/__tests__/sql.test.ts +22 -20
  319. package/src/core/codemirror/language/extension.ts +8 -8
  320. package/src/core/codemirror/language/languages/markdown.ts +8 -6
  321. package/src/core/codemirror/language/languages/python.ts +16 -10
  322. package/src/core/codemirror/language/languages/sql/sql.ts +9 -7
  323. package/src/core/codemirror/language/panel/panel.tsx +1 -0
  324. package/src/core/codemirror/language/types.ts +7 -7
  325. package/src/core/codemirror/rtc/extension.ts +24 -12
  326. package/src/core/codemirror/rtc/loro/awareness.ts +34 -19
  327. package/src/core/codemirror/rtc/loro/sync.ts +1 -0
  328. package/src/core/codemirror/utils.ts +1 -0
  329. package/src/core/datasets/__tests__/data-source-discovery.test.ts +4 -4
  330. package/src/core/datasets/data-source-discovery.ts +4 -6
  331. package/src/core/document/__tests__/codemirror.test.ts +485 -0
  332. package/src/core/document/__tests__/draft.test.ts +322 -0
  333. package/src/core/document/__tests__/fixtures.ts +92 -0
  334. package/src/core/document/__tests__/hooks.test.tsx +386 -0
  335. package/src/core/document/__tests__/lifecycle-scenarios.test.ts +61 -0
  336. package/src/core/document/__tests__/model.test.ts +191 -0
  337. package/src/core/document/__tests__/protocol-fixtures.ts +38 -0
  338. package/src/core/document/__tests__/recovery-scenarios.test.ts +230 -0
  339. package/src/core/document/__tests__/scenario-fixture.ts +43 -0
  340. package/src/core/document/__tests__/scenarios.test.ts +205 -0
  341. package/src/core/document/__tests__/state.test.ts +438 -0
  342. package/src/core/document/__tests__/submission.test.ts +203 -0
  343. package/src/core/document/__tests__/test-host.test.ts +92 -0
  344. package/src/core/document/__tests__/test-host.ts +247 -0
  345. package/src/core/document/__tests__/test-notebook.ts +149 -0
  346. package/src/core/document/__tests__/user.ts +61 -0
  347. package/src/core/document/codemirror.ts +311 -0
  348. package/src/core/document/draft.ts +472 -0
  349. package/src/core/document/hooks.tsx +118 -0
  350. package/src/core/document/index.ts +15 -0
  351. package/src/core/document/model.ts +55 -0
  352. package/src/core/document/select.ts +41 -0
  353. package/src/core/document/state.ts +374 -0
  354. package/src/core/document/sync.ts +369 -0
  355. package/src/core/host/AGENTS.md +8 -2
  356. package/src/core/host/__tests__/attachments.test.ts +56 -0
  357. package/src/core/host/__tests__/document.test.ts +126 -0
  358. package/src/core/host/__tests__/fixtures.ts +71 -0
  359. package/src/core/host/__tests__/replica.test.ts +550 -0
  360. package/src/core/host/__tests__/static.test.ts +169 -0
  361. package/src/core/host/__tests__/wasm.test.ts +162 -0
  362. package/src/core/host/backend.ts +19 -0
  363. package/src/core/host/connection.ts +1 -40
  364. package/src/core/host/index.ts +14 -0
  365. package/src/core/host/replica.ts +286 -0
  366. package/src/core/host/resources/attachments.ts +22 -0
  367. package/src/core/host/resources/document.ts +101 -0
  368. package/src/core/host/static.ts +72 -0
  369. package/src/core/host/wasm.ts +102 -0
  370. package/src/core/hotkeys/actions.ts +2 -4
  371. package/src/core/islands/__tests__/bootstrap.test.ts +0 -26
  372. package/src/core/islands/bootstrap.ts +0 -1
  373. package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
  374. package/src/core/kernel/__tests__/RuntimeState.test.ts +1 -1
  375. package/src/core/network/connection.ts +4 -2
  376. package/src/core/network/useConnectionNotice.ts +8 -2
  377. package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
  378. package/src/core/runtime/__tests__/runtime.test.ts +32 -58
  379. package/src/core/runtime/runtime.ts +38 -42
  380. package/src/core/runtime/types.ts +0 -2
  381. package/src/core/state/__tests__/jotai.test.tsx +108 -0
  382. package/src/core/state/jotai.ts +1 -1
  383. package/src/core/static/__tests__/files.test.ts +38 -10
  384. package/src/core/static/files.ts +2 -0
  385. package/src/core/wasm/bridge.ts +38 -10
  386. package/src/core/wasm/store.ts +3 -3
  387. package/src/core/wasm/worker/bootstrap.ts +2 -1
  388. package/src/core/wasm/worker/getMarimoWheel.ts +1 -1
  389. package/src/core/wasm/worker/types.ts +11 -0
  390. package/src/core/wasm/worker/worker.ts +48 -0
  391. package/src/core/websocket/__tests__/backend.test.ts +200 -0
  392. package/src/core/websocket/__tests__/connection-state.test.ts +0 -12
  393. package/src/core/websocket/__tests__/useNotebookReplica.hook.test.tsx +141 -0
  394. package/src/core/websocket/__tests__/useNotebookSession.hook.test.tsx +154 -428
  395. package/src/core/websocket/backend.ts +106 -0
  396. package/src/core/websocket/connection-state.ts +1 -11
  397. package/src/core/websocket/state.ts +7 -0
  398. package/src/core/websocket/transports/__tests__/notebook.test.ts +445 -0
  399. package/src/core/websocket/transports/notebook.ts +190 -0
  400. package/src/core/websocket/types.ts +2 -2
  401. package/src/core/websocket/useNotebookReplica.ts +69 -0
  402. package/src/core/websocket/useNotebookSession.tsx +10 -22
  403. package/src/css/globals.css +5 -0
  404. package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
  405. package/src/hooks/__tests__/useDebounce.test.tsx +51 -0
  406. package/src/hooks/__tests__/useDeepCompareMemoize.test.tsx +39 -0
  407. package/src/hooks/__tests__/useDelayElapsed.test.tsx +28 -0
  408. package/src/hooks/__tests__/useInternalStateWithSync.test.tsx +20 -0
  409. package/src/hooks/__tests__/useScript.test.tsx +77 -0
  410. package/src/hooks/__tests__/useStateForKey.test.tsx +257 -0
  411. package/src/hooks/useAsyncData.ts +3 -3
  412. package/src/hooks/useDataSourceDiscovery.ts +6 -4
  413. package/src/hooks/useDebounce.ts +6 -10
  414. package/src/hooks/useDeepCompareMemoize.ts +1 -1
  415. package/src/hooks/useDelayElapsed.ts +14 -10
  416. package/src/hooks/useElapsedTime.ts +3 -3
  417. package/src/hooks/useEventListener.ts +1 -2
  418. package/src/hooks/useInputHistory.ts +4 -7
  419. package/src/hooks/useInternalStateWithSync.ts +6 -6
  420. package/src/hooks/useResizeObserver.ts +4 -7
  421. package/src/hooks/useScript.ts +67 -70
  422. package/src/hooks/useStateForKey.ts +93 -0
  423. package/src/mount.tsx +0 -4
  424. package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
  425. package/src/plugins/core/registerReactComponent.tsx +1 -1
  426. package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
  427. package/src/plugins/impl/DataEditorPlugin.tsx +1 -1
  428. package/src/plugins/impl/DataTablePlugin.tsx +29 -33
  429. package/src/plugins/impl/DropdownPlugin.tsx +2 -6
  430. package/src/plugins/impl/FileBrowserPlugin.tsx +4 -16
  431. package/src/plugins/impl/FormPlugin.tsx +1 -1
  432. package/src/plugins/impl/RangeSliderPlugin.tsx +0 -1
  433. package/src/plugins/impl/RefreshPlugin.tsx +1 -0
  434. package/src/plugins/impl/SliderPlugin.tsx +6 -8
  435. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +117 -1
  436. package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +45 -0
  437. package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +24 -3
  438. package/src/plugins/impl/anywidget/__tests__/registry.test.ts +2 -0
  439. package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +241 -2
  440. package/src/plugins/impl/anywidget/runtime.ts +21 -9
  441. package/src/plugins/impl/anywidget/widget-binding.ts +160 -82
  442. package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +93 -0
  443. package/src/plugins/impl/chat/chat-ui.tsx +14 -11
  444. package/src/plugins/impl/code/any-language-editor.tsx +2 -2
  445. package/src/plugins/impl/data-editor/glide-data-editor.tsx +8 -5
  446. package/src/plugins/impl/data-editor/glide-utils.ts +3 -1
  447. package/src/plugins/impl/data-explorer/ConnectedDataExplorerComponent.tsx +1 -1
  448. package/src/plugins/impl/data-explorer/components/column-summary.tsx +4 -2
  449. package/src/plugins/impl/data-explorer/state/reducer.ts +1 -1
  450. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -2
  451. package/src/plugins/impl/data-frames/__tests__/sidebar.test.tsx +160 -0
  452. package/src/plugins/impl/data-frames/forms/__tests__/__snapshots__/form.test.tsx.snap +66 -66
  453. package/src/plugins/impl/data-frames/panel.tsx +43 -16
  454. package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +5 -3
  455. package/src/plugins/impl/panel/PanelPlugin.tsx +16 -17
  456. package/src/plugins/impl/panel/__tests__/utils.test.ts +39 -1
  457. package/src/plugins/impl/panel/utils.ts +17 -0
  458. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +2 -5
  459. package/src/plugins/impl/plotly/selection.ts +25 -19
  460. package/src/plugins/impl/vega/VegaPlugin.tsx +2 -3
  461. package/src/plugins/impl/vega/make-selectable.ts +4 -7
  462. package/src/plugins/layout/RoutesPlugin.tsx +1 -1
  463. package/src/stories/__tests__/editor-story.test.tsx +33 -0
  464. package/src/stories/button.stories.tsx +1 -0
  465. package/src/stories/editor.stories.tsx +24 -17
  466. package/src/stories/form-wrapper.stories.tsx +2 -2
  467. package/src/stories/select.stories.tsx +2 -2
  468. package/src/stories/switchable-multi-select.stories.tsx +1 -1
  469. package/src/utils/__tests__/arrays.test.ts +35 -0
  470. package/src/utils/__tests__/batch-requests.test.ts +3 -3
  471. package/src/utils/__tests__/numbers.test.ts +48 -1
  472. package/src/utils/__tests__/objects.test.ts +21 -0
  473. package/src/utils/arrays.ts +10 -0
  474. package/src/utils/blob.ts +1 -1
  475. package/src/utils/numbers.ts +28 -17
  476. package/src/utils/objects.ts +3 -7
  477. package/src/utils/once.ts +19 -19
  478. package/src/utils/tracer.ts +9 -5
  479. package/src/utils/zod-utils.ts +1 -3
  480. package/dist/assets/CellStatus-DVOHpdeJ.js +0 -1
  481. package/dist/assets/JsonOutput-Cx1iyibB.js +0 -11
  482. package/dist/assets/MarimoErrorOutput-s_5GOX8k.js +0 -10
  483. package/dist/assets/RunButton-BKoh0zYG.js +0 -1
  484. package/dist/assets/__vite-browser-external-CYO_P3S8.js +0 -1
  485. package/dist/assets/__vite-browser-external-FeDVGZU8.js +0 -1
  486. package/dist/assets/ai-model-dropdown-i1vfGeVi.js +0 -13
  487. package/dist/assets/alert-dialog-BaPGzeOK.js +0 -1
  488. package/dist/assets/any-language-editor-BdTWdMCI.js +0 -1
  489. package/dist/assets/arrays-BqUx5USx.js +0 -1
  490. package/dist/assets/cell-editor-BKJ06H5F.js +0 -21
  491. package/dist/assets/cell-link-8Auigi8P.js +0 -1
  492. package/dist/assets/cells-C6YGYGdi.js +0 -220
  493. package/dist/assets/chat-panel-Cau71Ygr.js +0 -4
  494. package/dist/assets/chat-ui-C5ql1Up-.js +0 -4
  495. package/dist/assets/circle-DXf-VWZG.js +0 -1
  496. package/dist/assets/circle-play-CYIb0qT6.js +0 -1
  497. package/dist/assets/column-preview-BZ_iNhtJ.js +0 -1
  498. package/dist/assets/command-palette-DDC3kBet.js +0 -1
  499. package/dist/assets/components-YBmtV0p6.js +0 -1
  500. package/dist/assets/config-DRIpOKqh.js +0 -1
  501. package/dist/assets/config-Dy28fDwn.js +0 -1
  502. package/dist/assets/dist-iaThVDkA.js +0 -1
  503. package/dist/assets/download-C03FOElq.js +0 -9
  504. package/dist/assets/dropdown-menu-C1rnl-0o.js +0 -1
  505. package/dist/assets/edit-page-D_Rg0gQO.js +0 -9
  506. package/dist/assets/feedback-button-Kla7i5RT.js +0 -1
  507. package/dist/assets/file-explorer-panel-Uk4_QIJQ.js +0 -1
  508. package/dist/assets/floating-outline-B5MaM1JS.js +0 -1
  509. package/dist/assets/fullscreen-B9tHcfpV.js +0 -41
  510. package/dist/assets/home-page-hmvKlc1w.js +0 -4
  511. package/dist/assets/index-6b4mf8Ai.css +0 -2
  512. package/dist/assets/index-ptK1gxmo.js +0 -30
  513. package/dist/assets/kiosk-mode-BZECfg9k.js +0 -1
  514. package/dist/assets/linear-0eij_aAG.js +0 -1
  515. package/dist/assets/link-NuFVR7G9.js +0 -1
  516. package/dist/assets/links-DkkL9DVa.js +0 -1
  517. package/dist/assets/menu-items-BrwnTgyK.js +0 -1
  518. package/dist/assets/numbers-Mk3-CcoU.js +0 -1
  519. package/dist/assets/packages-panel-CI5ff9b-.js +0 -1
  520. package/dist/assets/panels-BCcZ_yLK.js +0 -107
  521. package/dist/assets/precisionRound-Bq_nmf5u.js +0 -1
  522. package/dist/assets/process-output-f3C3PD0Z.js +0 -1
  523. package/dist/assets/react-vega-C3rYGtP6.js +0 -189
  524. package/dist/assets/requests-CgSY1X4a.js +0 -1
  525. package/dist/assets/run-page-AfZhtEh1.js +0 -1
  526. package/dist/assets/scratchpad-panel-D2rWg4k8.js +0 -1
  527. package/dist/assets/secrets-panel-D7KN4tVs.js +0 -1
  528. package/dist/assets/select-DTBn5eTb.js +0 -1
  529. package/dist/assets/session-panel-CnANhcTo.js +0 -1
  530. package/dist/assets/snippets-panel-ClGHtEKQ.js +0 -1
  531. package/dist/assets/state-BAJYRhmO.js +0 -1
  532. package/dist/assets/state-CbjBtkdd.js +0 -3
  533. package/dist/assets/switch-CTaiAjrz.js +0 -1
  534. package/dist/assets/tabs-BuQlZFbt.js +0 -1
  535. package/dist/assets/toast-BGzLGnvw.js +0 -1
  536. package/dist/assets/tooltip-C9TuY18o.js +0 -1
  537. package/dist/assets/tooltip-mT3CGest.js +0 -61
  538. package/dist/assets/tracing-Dz2rYOFL.js +0 -1
  539. package/dist/assets/tracing-panel-DqQY9V91.js +0 -2
  540. package/dist/assets/use-restore-focus-BxEGwIbk.js +0 -1
  541. package/dist/assets/useAsyncData-C7aJJz0Y.js +0 -1
  542. package/dist/assets/useBoolean-d0Tty94N.js +0 -1
  543. package/dist/assets/useCellActionButton-DmaFZ4oF.js +0 -1
  544. package/dist/assets/useDebounce-B_ccBZTp.js +0 -1
  545. package/dist/assets/useNotebookActions-DHt3s-ia.js +0 -1
  546. package/dist/assets/vega-component-IouMe13t.js +0 -1
  547. package/dist/assets/vega-loader.browser-CLRkNgm7.js +0 -6
  548. package/dist/assets/worker-DTQ7oH2A.js +0 -158
  549. package/dist/assets/ws-BXWY541V.js +0 -22
  550. package/src/core/host/__tests__/events.test.ts +0 -46
  551. package/src/core/host/__tests__/notebook-client.test.ts +0 -191
  552. package/src/core/host/__tests__/protocol.test.ts +0 -214
  553. package/src/core/host/events.ts +0 -60
  554. package/src/core/host/notebook-client.ts +0 -226
  555. package/src/core/host/protocol.ts +0 -1943
  556. package/src/core/state/__tests__/jotai.test.ts +0 -25
  557. package/src/core/websocket/__tests__/createConnectionTransport.test.ts +0 -49
  558. package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +0 -140
  559. package/src/core/websocket/transports/__tests__/basic.test.ts +0 -275
  560. package/src/core/websocket/transports/__tests__/sse.test.ts +0 -335
  561. package/src/core/websocket/transports/__tests__/transport.test.ts +0 -308
  562. package/src/core/websocket/transports/__tests__/ws.test.ts +0 -125
  563. package/src/core/websocket/transports/basic.ts +0 -102
  564. package/src/core/websocket/transports/create.ts +0 -31
  565. package/src/core/websocket/transports/sse.ts +0 -308
  566. package/src/core/websocket/transports/transport.ts +0 -50
  567. package/src/core/websocket/transports/ws.ts +0 -98
  568. package/src/core/websocket/useNotebookClient.ts +0 -80
@@ -52,6 +52,7 @@ export const Tracing: React.FC = () => {
52
52
 
53
53
  const { theme } = useTheme();
54
54
  const [chartPosition, setChartPosition] = useState<ChartPosition>("above");
55
+ const chartPositionId = React.useId();
55
56
  const panelSection = usePanelSection();
56
57
 
57
58
  const toggleChartPosition = () => {
@@ -76,11 +77,12 @@ export const Tracing: React.FC = () => {
76
77
  <div className="py-1 px-2 overflow-y-scroll h-full">
77
78
  <div className="flex flex-row justify-start gap-3">
78
79
  <div className="flex flex-row gap-1 items-center">
79
- <label htmlFor="chartPosition" className="text-xs">
80
+ <label htmlFor={chartPositionId} className="text-xs">
80
81
  Inline chart
81
82
  </label>
82
83
  <input
83
84
  type="checkbox"
85
+ id={chartPositionId}
84
86
  name="chartPosition"
85
87
  data-testid="chartPosition"
86
88
  onClick={toggleChartPosition}
@@ -145,11 +147,11 @@ const TraceBlock: React.FC<{
145
147
  isMostRecentRun: boolean;
146
148
  chartPosition: ChartPosition;
147
149
  theme: ResolvedTheme;
148
- }> = ({ run, isMostRecentRun, chartPosition, isExpanded, theme }) => {
150
+ }> = ({ run, isMostRecentRun, chartPosition, isExpanded: expanded, theme }) => {
149
151
  const setExpandedRuns = useSetAtom(expandedRunsAtom);
150
152
  // We prefer the user's last click, but if they haven't clicked on this run,
151
153
  // we expand the most recent run by default, otherwise we collapse it.
152
- isExpanded = isExpanded ?? isMostRecentRun;
154
+ const isExpanded = expanded ?? isMostRecentRun;
153
155
 
154
156
  const onToggleExpanded = () => {
155
157
  setExpandedRuns((prev) => {
@@ -163,28 +165,31 @@ const TraceBlock: React.FC<{
163
165
  const chevron = <Icon height={16} className="inline" />;
164
166
 
165
167
  const traceTitle = (
166
- <span className="text-sm cursor-pointer" onClick={onToggleExpanded}>
168
+ <button
169
+ type="button"
170
+ aria-expanded={isExpanded}
171
+ className="text-sm cursor-pointer"
172
+ onClick={onToggleExpanded}
173
+ >
167
174
  Run - {formatLogTimestamp(run.runStartTime)}
168
175
  {chevron}
169
- </span>
176
+ </button>
170
177
  );
171
178
 
172
- if (!isExpanded) {
173
- return (
174
- <div key={run.runId} className="flex flex-col">
175
- <pre className="font-mono font-semibold">{traceTitle}</pre>
176
- </div>
177
- );
178
- }
179
-
180
179
  return (
181
- <TraceBlockBody
182
- key={run.runId}
183
- run={run}
184
- chartPosition={chartPosition}
185
- theme={theme}
186
- title={traceTitle}
187
- />
180
+ <div
181
+ className={cn(
182
+ "grid grid-cols-1",
183
+ isExpanded &&
184
+ chartPosition === "sideBySide" &&
185
+ "grid-cols-[auto_minmax(0,1fr)] grid-rows-[auto_1fr]",
186
+ )}
187
+ >
188
+ <pre className="font-mono font-semibold">{traceTitle}</pre>
189
+ {isExpanded && (
190
+ <TraceBlockBody run={run} chartPosition={chartPosition} theme={theme} />
191
+ )}
192
+ </div>
188
193
  );
189
194
  };
190
195
 
@@ -192,8 +197,7 @@ const TraceBlockBody: React.FC<{
192
197
  run: Run;
193
198
  chartPosition: ChartPosition;
194
199
  theme: ResolvedTheme;
195
- title: React.ReactNode;
196
- }> = ({ run, chartPosition, theme, title }) => {
200
+ }> = ({ run, chartPosition, theme }) => {
197
201
  const [hoveredCellId, setHoveredCellId] = useState<CellId | null>();
198
202
  const vegaRef = useRef<HTMLDivElement>(null);
199
203
  const { ref, width = 300 } = useResizeObserver<HTMLDivElement>();
@@ -264,16 +268,22 @@ const TraceBlockBody: React.FC<{
264
268
  }, [embed]);
265
269
 
266
270
  const traceRows = (
267
- <TraceRows
268
- run={run}
269
- hoveredCellId={hoveredCellId}
270
- hiddenInputElementId={hiddenInputElementId}
271
- />
271
+ <div className="font-mono font-semibold">
272
+ <TraceRows
273
+ run={run}
274
+ hoveredCellId={hoveredCellId}
275
+ hiddenInputElementId={hiddenInputElementId}
276
+ />
277
+ </div>
272
278
  );
273
279
 
274
280
  const chartElement = (
275
281
  <div
276
- className={chartPosition === "sideBySide" ? "-mt-0.5 flex-1" : ""}
282
+ className={
283
+ chartPosition === "sideBySide"
284
+ ? "-mt-0.5 col-start-2 row-start-1 row-span-2 min-w-0"
285
+ : "min-w-0"
286
+ }
277
287
  ref={ref}
278
288
  >
279
289
  <Suspense>
@@ -284,24 +294,18 @@ const TraceBlockBody: React.FC<{
284
294
 
285
295
  if (chartPosition === "above") {
286
296
  return (
287
- <div key={run.runId} className="flex flex-col">
288
- <pre className="font-mono font-semibold">
289
- {title}
290
- {chartElement}
291
- {traceRows}
292
- </pre>
293
- </div>
297
+ <>
298
+ {chartElement}
299
+ {traceRows}
300
+ </>
294
301
  );
295
302
  }
296
303
 
297
304
  return (
298
- <div key={run.runId} className="flex flex-row">
299
- <pre className="font-mono font-semibold">
300
- {title}
301
- {traceRows}
302
- </pre>
305
+ <>
306
+ {traceRows}
303
307
  {chartElement}
304
- </div>
308
+ </>
305
309
  );
306
310
  };
307
311
 
@@ -0,0 +1,24 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { fireEvent, render, screen } from "@testing-library/react";
4
+ import { expect, it } from "vitest";
5
+ import { DraggablePopover } from "../draggable-popover";
6
+
7
+ it("moves from the keyboard handle without intercepting child input arrows", () => {
8
+ render(
9
+ <DraggablePopover open={true}>
10
+ <input aria-label="Filter" />
11
+ </DraggablePopover>,
12
+ );
13
+ const handle = screen.getByRole("button", {
14
+ name: "Move popup with arrow keys",
15
+ });
16
+ const popup = screen.getByRole("dialog");
17
+ fireEvent.keyDown(handle, { key: "ArrowRight" });
18
+ fireEvent.keyDown(handle, { key: "ArrowDown" });
19
+ expect(popup).toHaveStyle({ left: "10px", top: "10px" });
20
+ expect(
21
+ fireEvent.keyDown(screen.getByRole("textbox"), { key: "ArrowLeft" }),
22
+ ).toBe(true);
23
+ expect(popup).toHaveStyle({ left: "10px", top: "10px" });
24
+ });
@@ -28,7 +28,7 @@ AlertDialogPortal.displayName = AlertDialogPrimitive.Portal.displayName;
28
28
  const AlertDialogOverlay = React.forwardRef<
29
29
  React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
30
30
  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
31
- >(({ className, children, ...props }, ref) => (
31
+ >(({ className, children: _children, ...props }, ref) => (
32
32
  <AlertDialogPrimitive.Overlay
33
33
  className={cn(
34
34
  "fixed inset-0 z-50 bg-background/80 backdrop-blur-xs transition-opacity animate-in fade-in",
@@ -53,14 +53,36 @@ export const DraggablePopover = ({
53
53
  top: position.y,
54
54
  }}
55
55
  >
56
- <div
56
+ <button
57
+ type="button"
58
+ aria-label="Move popup with arrow keys"
57
59
  onMouseDown={handleMouseDown}
60
+ onKeyDown={(e) => {
61
+ const directions: Record<
62
+ string,
63
+ { x: number; y: number } | undefined
64
+ > = {
65
+ ArrowLeft: { x: -10, y: 0 },
66
+ ArrowRight: { x: 10, y: 0 },
67
+ ArrowUp: { x: 0, y: -10 },
68
+ ArrowDown: { x: 0, y: 10 },
69
+ };
70
+ const offset = directions[e.key];
71
+ if (offset) {
72
+ e.preventDefault();
73
+ e.stopPropagation();
74
+ setPosition((previous) => ({
75
+ x: previous.x + offset.x,
76
+ y: previous.y + offset.y,
77
+ }));
78
+ }
79
+ }}
58
80
  className={`flex items-center justify-center absolute top-0 left-1/2 -translate-x-1/2 ${
59
81
  isDragging ? "cursor-grabbing" : "cursor-grab"
60
82
  }`}
61
83
  >
62
84
  <GripHorizontalIcon className="h-5 w-5 mt-1 text-muted-foreground/40" />
63
- </div>
85
+ </button>
64
86
  {children}
65
87
  </PopoverContent>
66
88
  </Popover>
@@ -98,8 +98,12 @@ export class DatasourceContextProvider extends AIContextProvider<DatasourceConte
98
98
  public formatContext(item: DatasourceContextItem): string {
99
99
  const data = item.data;
100
100
  // Remove certain fields that are not needed in the context
101
- const { name, display_name, source, ...filteredDatasource } =
102
- data.connection;
101
+ const {
102
+ name,
103
+ display_name: _displayName,
104
+ source: _source,
105
+ ...filteredDatasource
106
+ } = data.connection;
103
107
 
104
108
  let datasource = filteredDatasource;
105
109
  const isInternalEngine = INTERNAL_SQL_ENGINES.has(name as ConnectionName);
@@ -20,9 +20,11 @@ export type StatusValue = "success" | "error" | "warning";
20
20
  * @example
21
21
  * throw new ToolExecutionError(
22
22
  * "Failed to fetch data",
23
- * "FETCH_ERROR",
24
- * true,
25
- * "Check your network connection"
23
+ * {
24
+ * code: "FETCH_ERROR",
25
+ * isRetryable: true,
26
+ * suggestedFix: "Check your network connection",
27
+ * }
26
28
  * );
27
29
  */
28
30
  export class ToolExecutionError extends Error {
@@ -33,10 +35,17 @@ export class ToolExecutionError extends Error {
33
35
 
34
36
  public constructor(
35
37
  message: string,
36
- code = "TOOL_ERROR",
37
- isRetryable = false,
38
- suggestedFix?: string,
39
- meta?: Record<string, unknown>,
38
+ {
39
+ code = "TOOL_ERROR",
40
+ isRetryable = false,
41
+ suggestedFix,
42
+ meta,
43
+ }: {
44
+ code?: string;
45
+ isRetryable?: boolean;
46
+ suggestedFix?: string;
47
+ meta?: Record<string, unknown>;
48
+ } = {},
40
49
  ) {
41
50
  super(message);
42
51
  this.name = "ToolExecutionError";
@@ -94,19 +94,17 @@ export class EditNotebookTool implements AiTool<
94
94
  const cellId = position.cellId as CellId | undefined;
95
95
 
96
96
  if (!cellId) {
97
- throw new ToolExecutionError(
98
- "Cell ID is required for update_cell",
99
- "CELL_ID_REQUIRED_FOR_UPDATE_CELL",
100
- true,
101
- "Provide a cell ID to update",
102
- );
97
+ throw new ToolExecutionError("Cell ID is required for update_cell", {
98
+ code: "CELL_ID_REQUIRED_FOR_UPDATE_CELL",
99
+ isRetryable: true,
100
+ suggestedFix: "Provide a cell ID to update",
101
+ });
103
102
  } else if (!code) {
104
- throw new ToolExecutionError(
105
- "Code is required for update_cell",
106
- "CODE_REQUIRED_FOR_UPDATE_CELL",
107
- true,
108
- "Provide the new code to update the cell",
109
- );
103
+ throw new ToolExecutionError("Code is required for update_cell", {
104
+ code: "CODE_REQUIRED_FOR_UPDATE_CELL",
105
+ isRetryable: true,
106
+ suggestedFix: "Provide the new code to update the cell",
107
+ });
110
108
  }
111
109
 
112
110
  const notebook = store.get(notebookAtom);
@@ -157,18 +155,22 @@ export class EditNotebookTool implements AiTool<
157
155
  if (!cellId) {
158
156
  throw new ToolExecutionError(
159
157
  "Cell ID is required for add_cell with relative position",
160
- "TOOL_ERROR",
161
- true,
162
- "Provide a cell ID to add the cell before",
158
+ {
159
+ code: "TOOL_ERROR",
160
+ isRetryable: true,
161
+ suggestedFix: "Provide a cell ID to add the cell before",
162
+ },
163
163
  );
164
164
  }
165
165
 
166
166
  if (position.before === undefined) {
167
167
  throw new ToolExecutionError(
168
168
  "Before is required for add_cell with relative position",
169
- "TOOL_ERROR",
170
- true,
171
- `Provide a boolean value for before, true to add before cell ${cellId}, false to add after the cell`,
169
+ {
170
+ code: "TOOL_ERROR",
171
+ isRetryable: true,
172
+ suggestedFix: `Provide a boolean value for before, true to add before cell ${cellId}, false to add after the cell`,
173
+ },
172
174
  );
173
175
  }
174
176
 
@@ -181,9 +183,12 @@ export class EditNotebookTool implements AiTool<
181
183
  if (!position.columnIndex) {
182
184
  throw new ToolExecutionError(
183
185
  "Column index is required for add_cell with column_end position",
184
- "TOOL_ERROR",
185
- true,
186
- "Provide a column index to add the cell at the end of",
186
+ {
187
+ code: "TOOL_ERROR",
188
+ isRetryable: true,
189
+ suggestedFix:
190
+ "Provide a column index to add the cell at the end of",
191
+ },
187
192
  );
188
193
  }
189
194
 
@@ -218,12 +223,11 @@ export class EditNotebookTool implements AiTool<
218
223
  const cellId = position.cellId as CellId | undefined;
219
224
 
220
225
  if (!cellId) {
221
- throw new ToolExecutionError(
222
- "Cell ID is required for delete_cell",
223
- "CELL_ID_REQUIRED_FOR_DELETE_CELL",
224
- true,
225
- "Provide a cell ID to delete",
226
- );
226
+ throw new ToolExecutionError("Cell ID is required for delete_cell", {
227
+ code: "CELL_ID_REQUIRED_FOR_DELETE_CELL",
228
+ isRetryable: true,
229
+ suggestedFix: "Provide a cell ID to delete",
230
+ });
227
231
  }
228
232
 
229
233
  const notebook = store.get(notebookAtom);
@@ -255,12 +259,11 @@ export class EditNotebookTool implements AiTool<
255
259
  private validateCellIdExists(cellId: CellId, notebook: NotebookState) {
256
260
  const cellIds = notebook.cellIds;
257
261
  if (!cellIds.getColumns().some((column) => column.idSet.has(cellId))) {
258
- throw new ToolExecutionError(
259
- "Cell not found",
260
- "CELL_NOT_FOUND",
261
- false,
262
- "Check which cells exist in the notebook",
263
- );
262
+ throw new ToolExecutionError("Cell not found", {
263
+ code: "CELL_NOT_FOUND",
264
+ isRetryable: false,
265
+ suggestedFix: "Check which cells exist in the notebook",
266
+ });
264
267
  }
265
268
  }
266
269
 
@@ -272,12 +275,12 @@ export class EditNotebookTool implements AiTool<
272
275
  const columns = cellIds.getColumns();
273
276
 
274
277
  if (columnIndex < 0 || columnIndex >= columns.length) {
275
- throw new ToolExecutionError(
276
- "Column index is out of range",
277
- "COLUMN_INDEX_OUT_OF_RANGE",
278
- true,
279
- "Choose a column index between 0 and the number of columns in the notebook (0-based)",
280
- );
278
+ throw new ToolExecutionError("Column index is out of range", {
279
+ code: "COLUMN_INDEX_OUT_OF_RANGE",
280
+ isRetryable: true,
281
+ suggestedFix:
282
+ "Choose a column index between 0 and the number of columns in the notebook (0-based)",
283
+ });
281
284
  }
282
285
  return columns[columnIndex].id;
283
286
  }
@@ -289,12 +292,11 @@ export class EditNotebookTool implements AiTool<
289
292
  const cellHandles = notebook.cellHandles;
290
293
  const cellHandle = cellHandles[cellId].current;
291
294
  if (!cellHandle?.editorView) {
292
- throw new ToolExecutionError(
293
- "Cell editor not found",
294
- "CELL_EDITOR_NOT_FOUND",
295
- false,
296
- "Internal error, ask the user to report this error",
297
- );
295
+ throw new ToolExecutionError("Cell editor not found", {
296
+ code: "CELL_EDITOR_NOT_FOUND",
297
+ isRetryable: false,
298
+ suggestedFix: "Internal error, ask the user to report this error",
299
+ });
298
300
  }
299
301
  return cellHandle.editorView;
300
302
  }
@@ -73,9 +73,11 @@ export class FrontendToolRegistry {
73
73
  const strError = z.prettifyError(inputResponse.error);
74
74
  throw new ToolExecutionError(
75
75
  `Tool ${toolName} returned invalid input: ${strError}`,
76
- "INVALID_ARGUMENTS",
77
- true,
78
- "Please check the arguments and try again.",
76
+ {
77
+ code: "INVALID_ARGUMENTS",
78
+ isRetryable: true,
79
+ suggestedFix: "Please check the arguments and try again.",
80
+ },
79
81
  );
80
82
  }
81
83
  const args = inputResponse.data;
@@ -110,12 +112,15 @@ export class FrontendToolRegistry {
110
112
  // Handle unknown/generic errors
111
113
  const genericError = new ToolExecutionError(
112
114
  error instanceof Error ? error.message : String(error),
113
- "TOOL_ERROR",
114
- false,
115
- "Check the error message and try again with valid arguments.",
116
115
  {
117
- args: rawArgs,
118
- errorType: error?.constructor?.name ?? typeof error,
116
+ code: "TOOL_ERROR",
117
+ isRetryable: false,
118
+ suggestedFix:
119
+ "Check the error message and try again with valid arguments.",
120
+ meta: {
121
+ args: rawArgs,
122
+ errorType: error?.constructor?.name ?? typeof error,
123
+ },
119
124
  },
120
125
  );
121
126
  return {
@@ -50,13 +50,12 @@ export class TestFrontendTool implements AiTool<Input, Output> {
50
50
  public async handler({ name }: Input): Promise<Output> {
51
51
  // Example: Validate input and throw ToolExecutionError on invalid data
52
52
  if (!name.trim()) {
53
- throw new ToolExecutionError(
54
- "Name cannot be empty",
55
- "INVALID_INPUT",
56
- false,
57
- "Please provide a non-empty name",
58
- { field: "name", received: name },
59
- );
53
+ throw new ToolExecutionError("Name cannot be empty", {
54
+ code: "INVALID_INPUT",
55
+ isRetryable: false,
56
+ suggestedFix: "Please provide a non-empty name",
57
+ meta: { field: "name", received: name },
58
+ });
60
59
  }
61
60
 
62
61
  return {
@@ -1,17 +1,14 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import type { components } from "@marimo-team/marimo-api";
4
3
  import { atom } from "jotai";
5
- import { isConnectedAtom } from "@/core/network/connection";
4
+ import type { Attachment } from "@marimo-team/client/protocol";
5
+ import { notebookReplicaAtom } from "@/core/websocket/state";
6
6
 
7
- export type Attachment = components["schemas"]["Attachment"];
7
+ export type { Attachment } from "@marimo-team/client/protocol";
8
8
 
9
- export const attachmentsAtom = atom<Attachment[]>([]);
10
9
  export const agentAttachmentsAtom = atom((get) => {
11
- if (!get(isConnectedAtom)) {
12
- return [];
13
- }
14
- return get(attachmentsAtom).filter(
10
+ const notebook = get(notebookReplicaAtom);
11
+ return (notebook ? get(notebook.attachmentsAtom) : []).filter(
15
12
  (attachment) => attachment.kind === "agent",
16
13
  );
17
14
  });
@@ -139,6 +139,7 @@ exports[`cell reducer > can initialize stdin > second stdin requested 1`] = `
139
139
  {
140
140
  "channel": "stdin",
141
141
  "data": "what is your name?",
142
+ "id": 2,
142
143
  "mimetype": "text/plain",
143
144
  "response": "Marimo!",
144
145
  "timestamp": 2,
@@ -146,6 +147,7 @@ exports[`cell reducer > can initialize stdin > second stdin requested 1`] = `
146
147
  {
147
148
  "channel": "stdin",
148
149
  "data": "how old are you?",
150
+ "id": 3,
149
151
  "mimetype": "text/plain",
150
152
  "timestamp": 3,
151
153
  },
@@ -189,6 +191,7 @@ exports[`cell reducer > can initialize stdin > stdin answered 1`] = `
189
191
  {
190
192
  "channel": "stdin",
191
193
  "data": "what is your name?",
194
+ "id": 2,
192
195
  "mimetype": "text/plain",
193
196
  "response": "Marimo!",
194
197
  "timestamp": 2,
@@ -233,6 +236,7 @@ exports[`cell reducer > can initialize stdin > stdin requested 1`] = `
233
236
  {
234
237
  "channel": "stdin",
235
238
  "data": "what is your name?",
239
+ "id": 2,
236
240
  "mimetype": "text/plain",
237
241
  "timestamp": 2,
238
242
  },
@@ -219,6 +219,45 @@ describe("transitionCell serialization", () => {
219
219
  });
220
220
  });
221
221
 
222
+ describe("transitionCell console output ids", () => {
223
+ const output = (
224
+ data: string,
225
+ channel: OutputMessage["channel"] = "stdout",
226
+ ): OutputMessage => ({
227
+ channel,
228
+ mimetype: "text/plain",
229
+ data,
230
+ timestamp: 0,
231
+ });
232
+
233
+ it("assigns increasing ids to appended outputs", () => {
234
+ let cell = createCellRuntimeState({ status: "running" });
235
+ cell = transitionCell(cell, { console: output("a") } as CellMessage);
236
+ cell = transitionCell(cell, {
237
+ console: output("b", "stderr"),
238
+ } as CellMessage);
239
+ expect(cell.consoleOutputs.map((o) => o.id)).toEqual([1, 2]);
240
+ });
241
+
242
+ it("continues from the surviving maximum after a collapse", () => {
243
+ let cell = createCellRuntimeState({ status: "running" });
244
+ cell = transitionCell(cell, { console: output("a") } as CellMessage);
245
+ cell = transitionCell(cell, { console: output("b") } as CellMessage);
246
+ expect(cell.consoleOutputs.map((o) => o.id)).toEqual([1]);
247
+ cell = transitionCell(cell, {
248
+ console: output("c", "stderr"),
249
+ } as CellMessage);
250
+ expect(cell.consoleOutputs.map((o) => o.id)).toEqual([1, 2]);
251
+ });
252
+
253
+ it("assigns ids when the kernel replaces the whole console", () => {
254
+ const cell = transitionCell(createCellRuntimeState({ status: "running" }), {
255
+ console: [output("a"), output("b", "stderr")],
256
+ } as CellMessage);
257
+ expect(cell.consoleOutputs.map((o) => o.id)).toEqual([1, 2]);
258
+ });
259
+ });
260
+
222
261
  describe("transitionCell stdin resolution", () => {
223
262
  describe.each([
224
263
  {
@@ -1579,7 +1579,9 @@ describe("cell reducer", () => {
1579
1579
  response: secret,
1580
1580
  });
1581
1581
 
1582
- expect(cells[0].consoleOutputs).toEqual([{ ...prompt, response: "" }]);
1582
+ expect(cells[0].consoleOutputs).toEqual([
1583
+ { ...prompt, id: 1, response: "" },
1584
+ ]);
1583
1585
  expect(JSON.stringify(cells[0].consoleOutputs)).not.toContain(secret);
1584
1586
  });
1585
1587
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { describe, expect, it } from "vitest";
4
4
  import { StatefulOutputMessage } from "@/components/editor/output/ansi-reduce";
5
+ import type { ConsoleOutputMessage } from "@/core/cells/types";
5
6
  import type { OutputMessage } from "@/core/kernel/messages";
6
7
  import {
7
8
  collapseConsoleOutputs,
@@ -279,6 +280,59 @@ describe("collapseConsoleOutputs", () => {
279
280
  expect(result[0].data).toContain("Streaming output truncated");
280
281
  });
281
282
 
283
+ it("keeps the first id when collapsing outputs", () => {
284
+ const consoleOutputs = [
285
+ {
286
+ mimetype: "text/plain",
287
+ channel: "output",
288
+ data: "Hello ",
289
+ timestamp: 0,
290
+ id: 7,
291
+ },
292
+ {
293
+ mimetype: "text/plain",
294
+ channel: "output",
295
+ data: "World",
296
+ timestamp: 0,
297
+ id: 8,
298
+ },
299
+ ] satisfies ConsoleOutputMessage[];
300
+ const result = collapseConsoleOutputs(consoleOutputs);
301
+ expect(result).toHaveLength(1);
302
+ expect(result[0].data).toBe("Hello World");
303
+ expect((result[0] as ConsoleOutputMessage).id).toBe(7);
304
+ });
305
+
306
+ it("keeps ids on outputs that survive truncation", () => {
307
+ const consoleOutputs = [
308
+ {
309
+ mimetype: "text/plain",
310
+ channel: "output",
311
+ data: "one\ntwo",
312
+ timestamp: 0,
313
+ id: 1,
314
+ },
315
+ {
316
+ mimetype: "text/plain",
317
+ channel: "stderr",
318
+ data: "three\nfour",
319
+ timestamp: 0,
320
+ id: 2,
321
+ },
322
+ {
323
+ mimetype: "text/plain",
324
+ channel: "output",
325
+ data: "five",
326
+ timestamp: 0,
327
+ id: 3,
328
+ },
329
+ ] satisfies ConsoleOutputMessage[];
330
+ const result = collapseConsoleOutputs(consoleOutputs, 3);
331
+ const ids = result.map((output) => (output as ConsoleOutputMessage).id);
332
+ expect(result[0].data).toContain("Streaming output truncated");
333
+ expect(ids).toEqual([undefined, 2, 3]);
334
+ });
335
+
282
336
  describe("ANSI escape sequences", () => {
283
337
  it("should handle cursor movement with collapse", () => {
284
338
  const consoleOutputs: OutputMessage[] = [