@marimo-team/frontend 0.25.3-dev12 → 0.25.3-dev122

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 (500) hide show
  1. package/dist/assets/CellStatus-_Aw9_foI.js +1 -0
  2. package/dist/assets/{ConnectedDataExplorerComponent-TprnxZeJ.js → ConnectedDataExplorerComponent-BRgqbAsc.js} +1 -1
  3. package/dist/assets/{ErrorBoundary-CM13wrd8.js → ErrorBoundary-DxSzjvbx.js} +2 -2
  4. package/dist/assets/JsonOutput-B7pGj79O.js +11 -0
  5. package/dist/assets/{LazyAnyLanguageCodeMirror-B4fCknq1.js → LazyAnyLanguageCodeMirror-BPYE76jR.js} +2 -2
  6. package/dist/assets/MarimoErrorOutput-Bzo6Bkp5.js +10 -0
  7. package/dist/assets/{RenderHTML-DX6i99Op.js → RenderHTML-D6AC0IhC.js} +1 -1
  8. package/dist/assets/RunButton-BjYsPiKa.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-CFrR1iW4.js} +6 -6
  12. package/dist/assets/{add-connection-dialog-B1BXCjex.js → add-connection-dialog-CyNAB_W2.js} +1 -1
  13. package/dist/assets/{agent-panel-CDFUc1uu.js → agent-panel-VOrccb5q.js} +3 -3
  14. package/dist/assets/ai-model-dropdown-Bfxv_zvu.js +13 -0
  15. package/dist/assets/{alert-dialog-BaPGzeOK.js → alert-dialog-C-sWmKva.js} +1 -1
  16. package/dist/assets/any-language-editor-DUMe1UCk.js +1 -0
  17. package/dist/assets/{app-config-button-AdV-QDD7.js → app-config-button-BRcjv8A_.js} +1 -1
  18. package/dist/assets/arrays-0R2reF2y.js +1 -0
  19. package/dist/assets/{blob-BG8yoQmx.js → blob-DTYOX-m5.js} +1 -1
  20. package/dist/assets/{button-COI-NGrx.js → button-D8gVKwe-.js} +1 -1
  21. package/dist/assets/{cache-panel-DTY1dqvi.js → cache-panel-BV-c7ed0.js} +1 -1
  22. package/dist/assets/{capabilities-BJvf-MD4.js → capabilities-Pq1YNPlK.js} +1 -1
  23. package/dist/assets/cell-editor-eKgYK8Bd.js +42 -0
  24. package/dist/assets/{cell-link-8Auigi8P.js → cell-link-D3rkqgbU.js} +1 -1
  25. package/dist/assets/{cells-C6YGYGdi.js → cells-2HETnlvE.js} +18 -18
  26. package/dist/assets/{chat-display-DhgI2MS9.js → chat-display-BrT4VJJK.js} +1 -1
  27. package/dist/assets/chat-panel-qpPNEwxV.js +4 -0
  28. package/dist/assets/chat-ui-SAdJxg-k.js +4 -0
  29. package/dist/assets/{circle-DXf-VWZG.js → circle-B6D_6D8w.js} +1 -1
  30. package/dist/assets/{code-visibility-BJImdpDi.js → code-visibility-DYDagVy7.js} +1 -1
  31. package/dist/assets/column-preview-yI7-INkZ.js +1 -0
  32. package/dist/assets/command-palette-DF-B_YpW.js +1 -0
  33. package/dist/assets/{common-Sl3uthjg.js → common-DgXKwblm.js} +1 -1
  34. package/dist/assets/components-CBE8cOLK.js +1 -0
  35. package/dist/assets/{components-3cou6Mka.js → components-CuMhY4Sf.js} +1 -1
  36. package/dist/assets/{components-CskjK6xZ.js → components-DCo7mAWO.js} +1 -1
  37. package/dist/assets/config-CD1IuZFJ.js +1 -0
  38. package/dist/assets/{config-DRIpOKqh.js → config-DMz7oN0r.js} +1 -1
  39. package/dist/assets/{config-CA1V-wjh.js → config-DpY86_Yq.js} +1 -1
  40. package/dist/assets/{copy-D8O_CYCG.js → copy-KlhazlhB.js} +1 -1
  41. package/dist/assets/{copy-icon-BIiRXh_3.js → copy-icon-8-a5vovc.js} +1 -1
  42. package/dist/assets/{createReducer-DgRODTW6.js → createReducer-CaI_Oa0v.js} +1 -1
  43. package/dist/assets/{datasource-DfbNb83e.js → datasource-D9JMcEAP.js} +1 -1
  44. package/dist/assets/{dates-CfmdTL6B.js → dates-CQMwFko2.js} +1 -1
  45. package/dist/assets/{dependency-graph-panel-L5cBE5sl.js → dependency-graph-panel-BVJWPCvw.js} +3 -3
  46. package/dist/assets/{dist-iaThVDkA.js → dist-jlhMTKo_.js} +1 -1
  47. package/dist/assets/{documentation-panel-D7S8JIc2.js → documentation-panel--wI4XHso.js} +1 -1
  48. package/dist/assets/{download-C03FOElq.js → download-Dod42wfD.js} +1 -1
  49. package/dist/assets/{dropdown-menu-C1rnl-0o.js → dropdown-menu-DS6umAnH.js} +1 -1
  50. package/dist/assets/edit-page-Uj9YSRMX.js +9 -0
  51. package/dist/assets/{error-banner-COZ7SfYV.js → error-banner-B5kzVf_0.js} +1 -1
  52. package/dist/assets/{error-entries-CLnPDv7b.js → error-entries-D00nWhWE.js} +1 -1
  53. package/dist/assets/{error-panel-D2xrYLue.js → error-panel-CcN_1PWf.js} +1 -1
  54. package/dist/assets/{es-Cqst59WX.js → es-N9SHpmG7.js} +1 -1
  55. package/dist/assets/{feedback-button-DzPunIqU.js → feedback-button-ByGgqUsX.js} +1 -1
  56. package/dist/assets/feedback-button-tbWwJ_t6.js +1 -0
  57. package/dist/assets/file-explorer-panel-eTEqtMPW.js +1 -0
  58. package/dist/assets/{file-name-input-B4fRaQkI.js → file-name-input-D5SfTNWh.js} +1 -1
  59. package/dist/assets/{floating-outline-B5MaM1JS.js → floating-outline-B-k3P_AO.js} +1 -1
  60. package/dist/assets/{formats-yZ06h1Pl.js → formats-zylfwejq.js} +1 -1
  61. package/dist/assets/{formatting-BqrP-n49.js → formatting-uom1es4b.js} +1 -1
  62. package/dist/assets/{fullscreen-B9tHcfpV.js → fullscreen-BWTs8pYZ.js} +1 -1
  63. package/dist/assets/{gallery-page-BefvdsM7.js → gallery-page-BzbMhDHi.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-BMqhUrHI.js} +2 -2
  66. package/dist/assets/{glide-utils-CIrAxdjv.js → glide-utils-HFqhvWHI.js} +2 -2
  67. package/dist/assets/home-page-DJcYWiga.js +1 -0
  68. package/dist/assets/{hooks-DzML9nez.js → hooks-CGLb_CCz.js} +1 -1
  69. package/dist/assets/{html-to-image-DK9Zl1lU.js → html-to-image-D_0rd3_B.js} +1 -1
  70. package/dist/assets/index-BnhSnwvB.css +2 -0
  71. package/dist/assets/index-bSIORW11.js +30 -0
  72. package/dist/assets/{input-BoBxR50a.js → input-DmHMEZGh.js} +1 -1
  73. package/dist/assets/kiosk-mode-DFS6HopF.js +1 -0
  74. package/dist/assets/{layout-Ck1RoL1B.js → layout-C2XnLAfO.js} +5 -5
  75. package/dist/assets/linear-Bma8J3iM.js +1 -0
  76. package/dist/assets/links-DX2w97N9.js +1 -0
  77. package/dist/assets/{logs-panel-BRytaWaO.js → logs-panel-B3T1GFBk.js} +1 -1
  78. package/dist/assets/{markdown-renderer-DX0Xrrfy.js → markdown-renderer-BhiTvxtL.js} +1 -1
  79. package/dist/assets/{menu-items-BrwnTgyK.js → menu-items-BgUyNUpu.js} +1 -1
  80. package/dist/assets/{mermaid-C4EiVqcd.js → mermaid-BKXlWk4F.js} +2 -2
  81. package/dist/assets/{name-cell-input-DlpTvPLa.js → name-cell-input-CgAObR6N.js} +1 -1
  82. package/dist/assets/numbers-CsZVw3Dc.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-BhBb7Vqw.js} +1 -1
  86. package/dist/assets/{package-data-dv4FBHxR.js → package-data-CKPmBDtg.js} +1 -1
  87. package/dist/assets/packages-panel-Bt0xNpFl.js +1 -0
  88. package/dist/assets/{panel-accordion-state-BqSH5ttk.js → panel-accordion-state-ZsUdpAYn.js} +1 -1
  89. package/dist/assets/panels-DJghvIKo.js +1 -0
  90. package/dist/assets/precisionRound-BxlUs8G4.js +1 -0
  91. package/dist/assets/process-output-CeOMwE17.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-TvOC7ESE.js} +1 -1
  95. package/dist/assets/{readonly-python-code-ggs4hAzC.js → readonly-python-code-Cqkfdeyo.js} +1 -1
  96. package/dist/assets/{renderShortcut-C1JwYcqW.js → renderShortcut-rUwGqKgC.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-CwE6U9oJ.js} +37 -37
  100. package/dist/assets/run-page-CtonWTtJ.js +1 -0
  101. package/dist/assets/{runs-BLp5jezv.js → runs-C49hleBy.js} +1 -1
  102. package/dist/assets/{runtime-details-state-CoL-p0MC.js → runtime-details-state-CKqJSfSR.js} +1 -1
  103. package/dist/assets/{save-worker-BbUSwZRG.js → save-worker-UwdGcNK5.js} +2 -1
  104. package/dist/assets/scratchpad-panel-CwVBedfZ.js +1 -0
  105. package/dist/assets/{scroll-to-bottom-button-1FyowpWV.js → scroll-to-bottom-button-CIkON2WJ.js} +1 -1
  106. package/dist/assets/{secrets-panel-D7KN4tVs.js → secrets-panel-bcfEKxRx.js} +1 -1
  107. package/dist/assets/{select-DTBn5eTb.js → select-3CVGlYrC.js} +1 -1
  108. package/dist/assets/{session-DqoWmb7X.js → session-CMLIzZKw.js} +1 -1
  109. package/dist/assets/session-panel-CdHdKUCF.js +1 -0
  110. package/dist/assets/{snippets-panel-ClGHtEKQ.js → snippets-panel-DYLWOLYw.js} +1 -1
  111. package/dist/assets/{spec-BfSBcO5B.js → spec-DlH4Mp7d.js} +1 -1
  112. package/dist/assets/{state-uwRvJLb8.js → state-3mcyTS9q.js} +1 -1
  113. package/dist/assets/state-B_MCKzBL.js +1 -0
  114. package/dist/assets/{state-C3oDoyFe.js → state-C5WAeuTu.js} +1 -1
  115. package/dist/assets/{state-DxQnC_1I.js → state-Cv2JW3l9.js} +1 -1
  116. package/dist/assets/{state-DtGB7xeJ.js → state-DZN9vZ6z.js} +1 -1
  117. package/dist/assets/state-DgECPVFs.js +107 -0
  118. package/dist/assets/{strings-B2vv-ENv.js → strings-C25fhMR_.js} +1 -1
  119. package/dist/assets/{swiper-component-a07domrZ.js → swiper-component-CRGRy5_O.js} +1 -1
  120. package/dist/assets/{switch-CTaiAjrz.js → switch-DYjBfpNJ.js} +1 -1
  121. package/dist/assets/{tabs-BuQlZFbt.js → tabs-CY8E4r9U.js} +1 -1
  122. package/dist/assets/{terminal-wnSHYT8N.js → terminal-Ca-kubKb.js} +1 -1
  123. package/dist/assets/{time-MgToa8VM.js → time-DswSXBDk.js} +1 -1
  124. package/dist/assets/{toast-BGzLGnvw.js → toast-Gzxi-le_.js} +1 -1
  125. package/dist/assets/tooltip-Brya4Ghn.js +61 -0
  126. package/dist/assets/{tooltip-C9TuY18o.js → tooltip-CkGm8X7m.js} +1 -1
  127. package/dist/assets/tracing-B0J2ctTm.js +1 -0
  128. package/dist/assets/tracing-panel-C1OCpoeE.js +2 -0
  129. package/dist/assets/{tree-actions-DnUokmva.js → tree-actions-sjBxIglc.js} +1 -1
  130. package/dist/assets/{use-restore-focus-BxEGwIbk.js → use-restore-focus-DdS7Tl0F.js} +1 -1
  131. package/dist/assets/{useAddCell-IN24thff.js → useAddCell-CaXnFGki.js} +1 -1
  132. package/dist/assets/useAsyncData-qvoPYHtx.js +1 -0
  133. package/dist/assets/useBoolean-Dd2nWXFJ.js +1 -0
  134. package/dist/assets/useCellActionButton-CJ90CMEj.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-D9N85822.js} +1 -1
  139. package/dist/assets/{useDependencyPanelTab-ImXYINm_.js → useDependencyPanelTab-CzAE0cm-.js} +1 -1
  140. package/dist/assets/{useEvent-Dfcbgjhg.js → useEvent-BDjgaBtz.js} +1 -1
  141. package/dist/assets/{useEventListener-D9cftcHj.js → useEventListener-CjDeLqFC.js} +1 -1
  142. package/dist/assets/{useIframeCapabilities-CwTkczVN.js → useIframeCapabilities-Czr9e4uG.js} +1 -1
  143. package/dist/assets/{useInstallPackage-BW06eter.js → useInstallPackage-wcDq9hYT.js} +1 -1
  144. package/dist/assets/{useInterval--x3s1VpI.js → useInterval-DJdQmXnq.js} +1 -1
  145. package/dist/assets/useNotebookActions-CAMEQ38y.js +1 -0
  146. package/dist/assets/{useRunCells-DSJPXE-j.js → useRunCells-DGakx8hj.js} +1 -1
  147. package/dist/assets/{useSplitCell-DQyMF5gd.js → useSplitCell-AK5BKPGM.js} +1 -1
  148. package/dist/assets/useStateForKey-CGMJQT8x.js +1 -0
  149. package/dist/assets/{useTheme-n8Dj1zH7.js → useTheme-BAA27lh7.js} +1 -1
  150. package/dist/assets/{utils-CaQYvazl.js → utils-DfElfBpz.js} +1 -1
  151. package/dist/assets/vega-component-BeyxAJad.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-BEx-EUlh.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 +12 -12
  159. package/src/__tests__/host-imports.test.ts +1 -0
  160. package/src/__tests__/mount.test.ts +0 -20
  161. package/src/components/app-config/ai-config.tsx +7 -2
  162. package/src/components/chat/__tests__/message-queue.test.tsx +17 -0
  163. package/src/components/chat/acp/__tests__/state.test.ts +2 -2
  164. package/src/components/chat/acp/blocks.tsx +2 -2
  165. package/src/components/chat/chat-components.tsx +2 -0
  166. package/src/components/chat/chat-panel.tsx +9 -8
  167. package/src/components/chat/chat-utils.ts +4 -8
  168. package/src/components/data-table/__tests__/chart-spec-model.test.ts +195 -195
  169. package/src/components/data-table/__tests__/column-explorer.test.tsx +27 -1
  170. package/src/components/data-table/__tests__/columns.test.tsx +105 -0
  171. package/src/components/data-table/__tests__/context-menu-interaction.test.tsx +130 -0
  172. package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
  173. package/src/components/data-table/__tests__/export-actions.test.tsx +105 -0
  174. package/src/components/data-table/__tests__/search-highlight.test.tsx +109 -0
  175. package/src/components/data-table/__tests__/url-detector.test.tsx +74 -0
  176. package/src/components/data-table/cell-selection/feature.ts +2 -2
  177. package/src/components/data-table/cell-selection/types.ts +2 -2
  178. package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
  179. package/src/components/data-table/charts/__tests__/spec-snapshot.test.ts +20 -20
  180. package/src/components/data-table/charts/__tests__/spec.test.ts +78 -52
  181. package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
  182. package/src/components/data-table/charts/chart-spec/spec.ts +68 -43
  183. package/src/components/data-table/charts/charts.tsx +40 -30
  184. package/src/components/data-table/charts/storage.ts +16 -5
  185. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
  186. package/src/components/data-table/column-summary/chart-spec-model.tsx +23 -16
  187. package/src/components/data-table/column-summary/column-summary.tsx +2 -4
  188. package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
  189. package/src/components/data-table/columns.tsx +45 -46
  190. package/src/components/data-table/context-menu.tsx +36 -20
  191. package/src/components/data-table/data-table.tsx +7 -1
  192. package/src/components/data-table/date-popover.tsx +6 -4
  193. package/src/components/data-table/export-actions.tsx +76 -48
  194. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +2 -2
  195. package/src/components/data-table/search-highlight.tsx +79 -0
  196. package/src/components/data-table/types.ts +1 -0
  197. package/src/components/data-table/url-detector.tsx +49 -9
  198. package/src/components/datasources/__tests__/column-actions.test.tsx +97 -0
  199. package/src/components/datasources/__tests__/column-preview.test.tsx +63 -2
  200. package/src/components/datasources/__tests__/table-list.test.tsx +118 -0
  201. package/src/components/datasources/column-preview.tsx +8 -2
  202. package/src/components/datasources/datasources.tsx +47 -35
  203. package/src/components/debugger/debugger-code.tsx +5 -0
  204. package/src/components/dependency-graph/dependency-graph-tree.tsx +8 -8
  205. package/src/components/dependency-graph/elements.ts +24 -21
  206. package/src/components/dependency-graph/panels.tsx +2 -1
  207. package/src/components/dependency-graph/utils/__tests__/layout.test.ts +18 -11
  208. package/src/components/editor/SortableCell.tsx +1 -3
  209. package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
  210. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +24 -0
  211. package/src/components/editor/actions/pair-with-agent-modal.tsx +18 -15
  212. package/src/components/editor/ai/add-cell-with-ai.tsx +3 -3
  213. package/src/components/editor/ai/ai-completion-editor.tsx +1 -0
  214. package/src/components/editor/alerts/startup-logs-alert.tsx +1 -0
  215. package/src/components/editor/cell/CreateCellButton.tsx +8 -10
  216. package/src/components/editor/cell/DeleteButton.tsx +1 -0
  217. package/src/components/editor/cell/__tests__/useShouldShowInterrupt.test.ts +39 -0
  218. package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
  219. package/src/components/editor/cell/code/cell-editor.tsx +1 -1
  220. package/src/components/editor/cell/code/language-toggle.tsx +8 -7
  221. package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
  222. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +30 -1
  223. package/src/components/editor/chrome/panels/cache-panel.tsx +1 -0
  224. package/src/components/editor/chrome/panels/packages-panel.tsx +4 -7
  225. package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +12 -18
  226. package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +58 -1
  227. package/src/components/editor/chrome/wrapper/footer-items/runtime-settings.tsx +1 -7
  228. package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +12 -2
  229. package/src/components/editor/chrome/wrapper/storage.ts +1 -1
  230. package/src/components/editor/connections/components.tsx +1 -1
  231. package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
  232. package/src/components/editor/controls/command-palette.tsx +22 -10
  233. package/src/components/editor/dynamic-favicon.tsx +21 -40
  234. package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +12 -23
  235. package/src/components/editor/file-tree/__tests__/file-explorer-interactions.test.tsx +6 -0
  236. package/src/components/editor/file-tree/__tests__/use-file-search.test.tsx +91 -0
  237. package/src/components/editor/file-tree/file-explorer.tsx +10 -5
  238. package/src/components/editor/file-tree/file-viewer.tsx +4 -2
  239. package/src/components/editor/file-tree/use-file-search.ts +35 -21
  240. package/src/components/editor/notebook-banner.tsx +1 -0
  241. package/src/components/editor/output/MarimoTracebackOutput.tsx +2 -2
  242. package/src/components/editor/output/ansi-reduce.ts +33 -20
  243. package/src/components/editor/output/console/ConsoleOutput.tsx +19 -25
  244. package/src/components/editor/package-alert.tsx +6 -4
  245. package/src/components/editor/renderers/grid-layout/grid-layout.tsx +12 -6
  246. package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
  247. package/src/components/home/components.tsx +17 -31
  248. package/src/components/icons/__tests__/large-spinner.test.tsx +39 -0
  249. package/src/components/icons/large-spinner.tsx +3 -14
  250. package/src/components/icons/spinner.tsx +1 -1
  251. package/src/components/mcp/mcp-status-indicator.tsx +1 -1
  252. package/src/components/pages/__tests__/home-page.test.tsx +116 -0
  253. package/src/components/pages/home-page.tsx +164 -91
  254. package/src/components/scratchpad/scratchpad.tsx +2 -2
  255. package/src/components/slides/reveal-component.tsx +4 -2
  256. package/src/components/slides/slide-cell-view.tsx +1 -1
  257. package/src/components/slides/slide-form.tsx +1 -0
  258. package/src/components/tracing/tracing.tsx +2 -2
  259. package/src/components/ui/alert-dialog.tsx +1 -1
  260. package/src/core/ai/context/providers/datasource.ts +6 -2
  261. package/src/core/ai/tools/base.ts +16 -7
  262. package/src/core/ai/tools/edit-notebook-tool.ts +47 -45
  263. package/src/core/ai/tools/registry.ts +13 -8
  264. package/src/core/ai/tools/sample-tool.ts +6 -7
  265. package/src/core/attachments/state.ts +5 -8
  266. package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -0
  267. package/src/core/cells/__tests__/cell.test.ts +39 -0
  268. package/src/core/cells/__tests__/cells.test.ts +3 -1
  269. package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
  270. package/src/core/cells/__tests__/notebook-outline.test.ts +113 -0
  271. package/src/core/cells/__tests__/session.test.ts +117 -36
  272. package/src/core/cells/cell.ts +14 -3
  273. package/src/core/cells/cells.ts +3 -1
  274. package/src/core/cells/pending-delete-service.ts +2 -6
  275. package/src/core/cells/session.ts +1 -1
  276. package/src/core/cells/types.ts +10 -1
  277. package/src/core/codemirror/__tests__/setup.test.ts +29 -29
  278. package/src/core/codemirror/cells/__tests__/extensions.test.ts +15 -0
  279. package/src/core/codemirror/cells/extensions.ts +7 -3
  280. package/src/core/codemirror/keymaps/vim.ts +2 -6
  281. package/src/core/codemirror/language/__tests__/sql.test.ts +22 -20
  282. package/src/core/codemirror/language/extension.ts +8 -8
  283. package/src/core/codemirror/language/languages/markdown.ts +8 -6
  284. package/src/core/codemirror/language/languages/python.ts +16 -10
  285. package/src/core/codemirror/language/languages/sql/sql.ts +9 -7
  286. package/src/core/codemirror/language/panel/panel.tsx +1 -0
  287. package/src/core/codemirror/language/types.ts +7 -7
  288. package/src/core/codemirror/rtc/extension.ts +24 -12
  289. package/src/core/codemirror/rtc/loro/awareness.ts +34 -19
  290. package/src/core/codemirror/rtc/loro/sync.ts +1 -0
  291. package/src/core/codemirror/utils.ts +1 -0
  292. package/src/core/datasets/__tests__/data-source-discovery.test.ts +4 -4
  293. package/src/core/datasets/data-source-discovery.ts +4 -6
  294. package/src/core/document/__tests__/codemirror.test.ts +483 -0
  295. package/src/core/document/__tests__/draft.test.ts +322 -0
  296. package/src/core/document/__tests__/fixtures.ts +92 -0
  297. package/src/core/document/__tests__/hooks.test.tsx +386 -0
  298. package/src/core/document/__tests__/lifecycle-scenarios.test.ts +61 -0
  299. package/src/core/document/__tests__/model.test.ts +158 -0
  300. package/src/core/document/__tests__/protocol-fixtures.ts +38 -0
  301. package/src/core/document/__tests__/recovery-scenarios.test.ts +230 -0
  302. package/src/core/document/__tests__/scenario-fixture.ts +42 -0
  303. package/src/core/document/__tests__/scenarios.test.ts +205 -0
  304. package/src/core/document/__tests__/state.test.ts +438 -0
  305. package/src/core/document/__tests__/submission.test.ts +203 -0
  306. package/src/core/document/__tests__/test-host.test.ts +92 -0
  307. package/src/core/document/__tests__/test-host.ts +247 -0
  308. package/src/core/document/__tests__/test-notebook.ts +139 -0
  309. package/src/core/document/__tests__/user.ts +61 -0
  310. package/src/core/document/codemirror.ts +311 -0
  311. package/src/core/document/draft.ts +472 -0
  312. package/src/core/document/hooks.tsx +118 -0
  313. package/src/core/document/index.ts +22 -0
  314. package/src/core/document/model.ts +52 -0
  315. package/src/core/document/select.ts +41 -0
  316. package/src/core/document/state.ts +374 -0
  317. package/src/core/document/sync.ts +363 -0
  318. package/src/core/host/AGENTS.md +12 -2
  319. package/src/core/host/__tests__/attachments.test.ts +56 -0
  320. package/src/core/host/__tests__/document.test.ts +126 -0
  321. package/src/core/host/__tests__/fixtures.ts +41 -0
  322. package/src/core/host/__tests__/notebook-client.test.ts +511 -132
  323. package/src/core/host/__tests__/static.test.ts +167 -0
  324. package/src/core/host/__tests__/wasm.test.ts +152 -0
  325. package/src/core/host/backend.ts +10 -0
  326. package/src/core/host/connection.ts +1 -40
  327. package/src/core/host/notebook-client.ts +204 -133
  328. package/src/core/host/resources/attachments.ts +22 -0
  329. package/src/core/host/resources/document.ts +101 -0
  330. package/src/core/host/static.ts +70 -0
  331. package/src/core/host/wasm.ts +92 -0
  332. package/src/core/hotkeys/actions.ts +2 -4
  333. package/src/core/islands/__tests__/bootstrap.test.ts +0 -26
  334. package/src/core/islands/bootstrap.ts +0 -1
  335. package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
  336. package/src/core/kernel/__tests__/RuntimeState.test.ts +1 -1
  337. package/src/core/network/connection.ts +4 -2
  338. package/src/core/network/useConnectionNotice.ts +8 -2
  339. package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
  340. package/src/core/runtime/__tests__/runtime.test.ts +15 -58
  341. package/src/core/runtime/runtime.ts +25 -42
  342. package/src/core/runtime/types.ts +0 -2
  343. package/src/core/state/__tests__/jotai.test.tsx +108 -0
  344. package/src/core/state/jotai.ts +1 -1
  345. package/src/core/static/__tests__/files.test.ts +38 -10
  346. package/src/core/static/files.ts +2 -0
  347. package/src/core/wasm/bridge.ts +38 -10
  348. package/src/core/wasm/store.ts +3 -3
  349. package/src/core/wasm/worker/bootstrap.ts +2 -1
  350. package/src/core/wasm/worker/getMarimoWheel.ts +1 -1
  351. package/src/core/wasm/worker/types.ts +11 -0
  352. package/src/core/wasm/worker/worker.ts +48 -0
  353. package/src/core/websocket/__tests__/connection-state.test.ts +0 -12
  354. package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +153 -70
  355. package/src/core/websocket/__tests__/useNotebookSession.hook.test.tsx +151 -428
  356. package/src/core/websocket/connection-state.ts +0 -10
  357. package/src/core/websocket/state.ts +7 -0
  358. package/src/core/websocket/transports/__tests__/notebook.test.ts +502 -0
  359. package/src/core/websocket/transports/notebook.ts +213 -0
  360. package/src/core/websocket/useNotebookClient.ts +38 -29
  361. package/src/core/websocket/useNotebookSession.tsx +1 -14
  362. package/src/css/globals.css +5 -0
  363. package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
  364. package/src/hooks/__tests__/useDebounce.test.tsx +51 -0
  365. package/src/hooks/__tests__/useDeepCompareMemoize.test.tsx +39 -0
  366. package/src/hooks/__tests__/useDelayElapsed.test.tsx +28 -0
  367. package/src/hooks/__tests__/useInternalStateWithSync.test.tsx +20 -0
  368. package/src/hooks/__tests__/useScript.test.tsx +77 -0
  369. package/src/hooks/__tests__/useStateForKey.test.tsx +257 -0
  370. package/src/hooks/useAsyncData.ts +3 -3
  371. package/src/hooks/useDataSourceDiscovery.ts +6 -4
  372. package/src/hooks/useDebounce.ts +6 -10
  373. package/src/hooks/useDeepCompareMemoize.ts +1 -1
  374. package/src/hooks/useDelayElapsed.ts +14 -10
  375. package/src/hooks/useElapsedTime.ts +3 -3
  376. package/src/hooks/useEventListener.ts +1 -2
  377. package/src/hooks/useInputHistory.ts +4 -7
  378. package/src/hooks/useInternalStateWithSync.ts +6 -6
  379. package/src/hooks/useResizeObserver.ts +4 -7
  380. package/src/hooks/useScript.ts +67 -70
  381. package/src/hooks/useStateForKey.ts +93 -0
  382. package/src/mount.tsx +0 -4
  383. package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
  384. package/src/plugins/core/registerReactComponent.tsx +1 -1
  385. package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
  386. package/src/plugins/impl/DataEditorPlugin.tsx +1 -1
  387. package/src/plugins/impl/DataTablePlugin.tsx +29 -33
  388. package/src/plugins/impl/DropdownPlugin.tsx +2 -6
  389. package/src/plugins/impl/FileBrowserPlugin.tsx +4 -16
  390. package/src/plugins/impl/FormPlugin.tsx +1 -1
  391. package/src/plugins/impl/RangeSliderPlugin.tsx +0 -1
  392. package/src/plugins/impl/RefreshPlugin.tsx +1 -0
  393. package/src/plugins/impl/SliderPlugin.tsx +6 -8
  394. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +117 -1
  395. package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +45 -0
  396. package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +24 -3
  397. package/src/plugins/impl/anywidget/__tests__/registry.test.ts +2 -0
  398. package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +241 -2
  399. package/src/plugins/impl/anywidget/runtime.ts +21 -9
  400. package/src/plugins/impl/anywidget/widget-binding.ts +160 -82
  401. package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +93 -0
  402. package/src/plugins/impl/chat/chat-ui.tsx +12 -10
  403. package/src/plugins/impl/code/any-language-editor.tsx +2 -2
  404. package/src/plugins/impl/data-editor/glide-data-editor.tsx +8 -5
  405. package/src/plugins/impl/data-editor/glide-utils.ts +3 -1
  406. package/src/plugins/impl/data-explorer/ConnectedDataExplorerComponent.tsx +1 -1
  407. package/src/plugins/impl/data-explorer/state/reducer.ts +1 -1
  408. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -2
  409. package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +5 -3
  410. package/src/plugins/impl/panel/PanelPlugin.tsx +16 -17
  411. package/src/plugins/impl/panel/__tests__/utils.test.ts +39 -1
  412. package/src/plugins/impl/panel/utils.ts +17 -0
  413. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +2 -5
  414. package/src/plugins/impl/plotly/selection.ts +25 -19
  415. package/src/plugins/impl/vega/VegaPlugin.tsx +2 -3
  416. package/src/plugins/impl/vega/make-selectable.ts +4 -7
  417. package/src/plugins/layout/RoutesPlugin.tsx +1 -1
  418. package/src/stories/__tests__/editor-story.test.tsx +33 -0
  419. package/src/stories/button.stories.tsx +1 -0
  420. package/src/stories/editor.stories.tsx +24 -17
  421. package/src/stories/form-wrapper.stories.tsx +2 -2
  422. package/src/stories/select.stories.tsx +2 -2
  423. package/src/stories/switchable-multi-select.stories.tsx +1 -1
  424. package/src/utils/__tests__/arrays.test.ts +35 -0
  425. package/src/utils/__tests__/batch-requests.test.ts +3 -3
  426. package/src/utils/__tests__/numbers.test.ts +48 -1
  427. package/src/utils/__tests__/objects.test.ts +21 -0
  428. package/src/utils/arrays.ts +10 -0
  429. package/src/utils/blob.ts +1 -1
  430. package/src/utils/numbers.ts +28 -17
  431. package/src/utils/objects.ts +3 -7
  432. package/src/utils/once.ts +19 -19
  433. package/src/utils/tracer.ts +9 -5
  434. package/src/utils/zod-utils.ts +1 -3
  435. package/dist/assets/CellStatus-DVOHpdeJ.js +0 -1
  436. package/dist/assets/JsonOutput-Cx1iyibB.js +0 -11
  437. package/dist/assets/MarimoErrorOutput-s_5GOX8k.js +0 -10
  438. package/dist/assets/RunButton-BKoh0zYG.js +0 -1
  439. package/dist/assets/__vite-browser-external-CYO_P3S8.js +0 -1
  440. package/dist/assets/__vite-browser-external-FeDVGZU8.js +0 -1
  441. package/dist/assets/ai-model-dropdown-i1vfGeVi.js +0 -13
  442. package/dist/assets/any-language-editor-BdTWdMCI.js +0 -1
  443. package/dist/assets/arrays-BqUx5USx.js +0 -1
  444. package/dist/assets/cell-editor-BKJ06H5F.js +0 -21
  445. package/dist/assets/chat-panel-Cau71Ygr.js +0 -4
  446. package/dist/assets/chat-ui-C5ql1Up-.js +0 -4
  447. package/dist/assets/circle-play-CYIb0qT6.js +0 -1
  448. package/dist/assets/column-preview-BZ_iNhtJ.js +0 -1
  449. package/dist/assets/command-palette-DDC3kBet.js +0 -1
  450. package/dist/assets/components-YBmtV0p6.js +0 -1
  451. package/dist/assets/config-Dy28fDwn.js +0 -1
  452. package/dist/assets/edit-page-D_Rg0gQO.js +0 -9
  453. package/dist/assets/feedback-button-Kla7i5RT.js +0 -1
  454. package/dist/assets/file-explorer-panel-Uk4_QIJQ.js +0 -1
  455. package/dist/assets/home-page-hmvKlc1w.js +0 -4
  456. package/dist/assets/index-6b4mf8Ai.css +0 -2
  457. package/dist/assets/index-ptK1gxmo.js +0 -30
  458. package/dist/assets/kiosk-mode-BZECfg9k.js +0 -1
  459. package/dist/assets/linear-0eij_aAG.js +0 -1
  460. package/dist/assets/link-NuFVR7G9.js +0 -1
  461. package/dist/assets/links-DkkL9DVa.js +0 -1
  462. package/dist/assets/numbers-Mk3-CcoU.js +0 -1
  463. package/dist/assets/packages-panel-CI5ff9b-.js +0 -1
  464. package/dist/assets/panels-BCcZ_yLK.js +0 -107
  465. package/dist/assets/precisionRound-Bq_nmf5u.js +0 -1
  466. package/dist/assets/process-output-f3C3PD0Z.js +0 -1
  467. package/dist/assets/react-vega-C3rYGtP6.js +0 -189
  468. package/dist/assets/requests-CgSY1X4a.js +0 -1
  469. package/dist/assets/run-page-AfZhtEh1.js +0 -1
  470. package/dist/assets/scratchpad-panel-D2rWg4k8.js +0 -1
  471. package/dist/assets/session-panel-CnANhcTo.js +0 -1
  472. package/dist/assets/state-BAJYRhmO.js +0 -1
  473. package/dist/assets/state-CbjBtkdd.js +0 -3
  474. package/dist/assets/tooltip-mT3CGest.js +0 -61
  475. package/dist/assets/tracing-Dz2rYOFL.js +0 -1
  476. package/dist/assets/tracing-panel-DqQY9V91.js +0 -2
  477. package/dist/assets/useAsyncData-C7aJJz0Y.js +0 -1
  478. package/dist/assets/useBoolean-d0Tty94N.js +0 -1
  479. package/dist/assets/useCellActionButton-DmaFZ4oF.js +0 -1
  480. package/dist/assets/useDebounce-B_ccBZTp.js +0 -1
  481. package/dist/assets/useNotebookActions-DHt3s-ia.js +0 -1
  482. package/dist/assets/vega-component-IouMe13t.js +0 -1
  483. package/dist/assets/vega-loader.browser-CLRkNgm7.js +0 -6
  484. package/dist/assets/worker-DTQ7oH2A.js +0 -158
  485. package/dist/assets/ws-BXWY541V.js +0 -22
  486. package/src/core/host/__tests__/events.test.ts +0 -46
  487. package/src/core/host/__tests__/protocol.test.ts +0 -214
  488. package/src/core/host/events.ts +0 -60
  489. package/src/core/host/protocol.ts +0 -1943
  490. package/src/core/state/__tests__/jotai.test.ts +0 -25
  491. package/src/core/websocket/__tests__/createConnectionTransport.test.ts +0 -49
  492. package/src/core/websocket/transports/__tests__/basic.test.ts +0 -275
  493. package/src/core/websocket/transports/__tests__/sse.test.ts +0 -335
  494. package/src/core/websocket/transports/__tests__/transport.test.ts +0 -308
  495. package/src/core/websocket/transports/__tests__/ws.test.ts +0 -125
  496. package/src/core/websocket/transports/basic.ts +0 -102
  497. package/src/core/websocket/transports/create.ts +0 -31
  498. package/src/core/websocket/transports/sse.ts +0 -308
  499. package/src/core/websocket/transports/transport.ts +0 -50
  500. package/src/core/websocket/transports/ws.ts +0 -98
@@ -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 { notebookClientAtom } 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(notebookClientAtom);
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[] = [
@@ -0,0 +1,113 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { createStore } from "jotai";
4
+ import { afterEach, describe, expect, it, vi } from "vitest";
5
+ import { MockNotebook } from "@/__mocks__/notebook";
6
+ import { cellId } from "@/__tests__/branded";
7
+ import {
8
+ createNotebookActions,
9
+ notebookAtom,
10
+ notebookOutline,
11
+ notebookReducer,
12
+ } from "../cells";
13
+ import { exportedForTesting } from "../document-changes";
14
+ import type { Outline } from "../outline";
15
+
16
+ const first = cellId("first");
17
+ const second = cellId("second");
18
+ const firstOutline: Outline = {
19
+ items: [{ name: "First", level: 1, by: { id: "first" } }],
20
+ };
21
+ const secondOutline: Outline = {
22
+ items: [{ name: "Second", level: 2, by: { id: "second" } }],
23
+ };
24
+
25
+ function setup() {
26
+ const store = createStore();
27
+ store.set(
28
+ notebookAtom,
29
+ MockNotebook.notebookState({
30
+ cellData: { [first]: { code: "x = 1" }, [second]: {} },
31
+ cellRuntime: {
32
+ [first]: { outline: firstOutline },
33
+ [second]: { outline: secondOutline },
34
+ },
35
+ }),
36
+ );
37
+ const actions = createNotebookActions((action) =>
38
+ store.set(notebookAtom, (state) => notebookReducer(state, action)),
39
+ );
40
+ return { store, actions };
41
+ }
42
+
43
+ afterEach(() => {
44
+ exportedForTesting.cancelPendingChanges();
45
+ });
46
+
47
+ describe("notebookOutline", () => {
48
+ it("does not notify outline subscribers when cell code changes", () => {
49
+ const { store, actions } = setup();
50
+ const initial = store.get(notebookOutline);
51
+ const listener = vi.fn();
52
+ const unsubscribe = store.sub(notebookOutline, listener);
53
+
54
+ actions.updateCellCode({
55
+ cellId: first,
56
+ code: "x = 2",
57
+ formattingChange: false,
58
+ });
59
+
60
+ expect(store.get(notebookOutline)).toBe(initial);
61
+ expect(listener).not.toHaveBeenCalled();
62
+ unsubscribe();
63
+ });
64
+
65
+ it("updates headings when runtime outlines change or are removed", () => {
66
+ const { store } = setup();
67
+ const updated: Outline = {
68
+ items: [{ name: "Updated", level: 1, by: { id: "updated" } }],
69
+ };
70
+
71
+ for (const outline of [updated, null]) {
72
+ store.set(notebookAtom, (state) => ({
73
+ ...state,
74
+ cellRuntime: {
75
+ ...state.cellRuntime,
76
+ [first]: { ...state.cellRuntime[first], outline },
77
+ },
78
+ }));
79
+ expect(store.get(notebookOutline)).toEqual({
80
+ items: [...(outline?.items ?? []), ...secondOutline.items],
81
+ });
82
+ }
83
+ });
84
+
85
+ it("keeps headings in cell order after moving and deleting cells", () => {
86
+ const { store, actions } = setup();
87
+ actions.moveCell({ cellId: second, before: true });
88
+ expect(store.get(notebookOutline)).toEqual({
89
+ items: [...secondOutline.items, ...firstOutline.items],
90
+ });
91
+
92
+ actions.deleteCell({ cellId: second });
93
+ expect(store.get(notebookOutline)).toEqual(firstOutline);
94
+ });
95
+
96
+ it("notifies subscribers when output is replaced with the same headings", () => {
97
+ const { store } = setup();
98
+ const listener = vi.fn();
99
+ const unsubscribe = store.sub(notebookOutline, listener);
100
+
101
+ store.set(notebookAtom, (state) => ({
102
+ ...state,
103
+ cellRuntime: {
104
+ ...state.cellRuntime,
105
+ [first]: { ...state.cellRuntime[first], outline: { ...firstOutline } },
106
+ },
107
+ }));
108
+
109
+ // Consumers must reconnect to replacement heading elements in the DOM.
110
+ expect(listener).toHaveBeenCalledOnce();
111
+ unsubscribe();
112
+ });
113
+ });