@marimo-team/islands 0.25.3-dev2 → 0.25.3-dev200

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 (690) hide show
  1. package/dist/{ConnectedDataExplorerComponent-CNSxdKyJ.js → ConnectedDataExplorerComponent-BsWiIPFk.js} +22 -20
  2. package/dist/{ErrorBoundary-DWEpirf3.js → ErrorBoundary-UWARECs-.js} +19 -19
  3. package/dist/{abnfDiagram-VCTEODGH-DQDjNXt3.js → abnfDiagram-VCTEODGH-I2x4Yu25.js} +2 -2
  4. package/dist/any-language-editor-BVFHDDQ3.js +75 -0
  5. package/dist/{architectureDiagram-5GKGNRK7-Nmls7Wxn.js → architectureDiagram-5GKGNRK7-1bSQMKzK.js} +1 -1
  6. package/dist/{arrays-CN1djC4k.js → arrays-DoQ-AILx.js} +15 -27
  7. package/dist/assets/__vite-browser-external-BCJsx8QS.js +1 -0
  8. package/dist/assets/worker-DodjWT_Z.js +113 -0
  9. package/dist/{button-CvjkwdSk.js → button-BQRdqQi1.js} +199 -192
  10. package/dist/{capabilities-CQ5IjhzL.js → capabilities-C2QUNRXi.js} +2 -2
  11. package/dist/{chat-ui-BDpymeoe.js → chat-ui-DXDoSuS4.js} +667 -667
  12. package/dist/{check-EDwSwP89.js → check-C9Mp9eCK.js} +1 -1
  13. package/dist/{chunk-IMKFNOWR-CoIFEo-1.js → chunk-IMKFNOWR-fsCGAJ9G.js} +1 -1
  14. package/dist/{chunk-SHT3W25Y-lHiGx3ZC.js → chunk-SHT3W25Y-D2STW4hj.js} +1 -1
  15. package/dist/{chunk-SVP7TREG-BvsHIrY_.js → chunk-SVP7TREG-CiY7cQG-.js} +1 -1
  16. package/dist/{chunk-TICWLB2K-BC8YIm_n.js → chunk-TICWLB2K-C_t5RBp9.js} +1 -1
  17. package/dist/{chunk-YOKDWASO-DPZk8vhS.js → chunk-YOKDWASO-DKplTrBY.js} +20 -20
  18. package/dist/{classDiagram-ZZMXUADV-Bt98lkkv.js → classDiagram-ZZMXUADV-B2JvZAP4.js} +2 -2
  19. package/dist/{classDiagram-v2-VYDZK3BY-D9bfbcC3.js → classDiagram-v2-VYDZK3BY-L8VsZG5A.js} +2 -2
  20. package/dist/{code-visibility-CLNfgCjd.js → code-visibility-33fxfX1p.js} +45 -49
  21. package/dist/{common-fyD_6mT2.js → common-D09oJJ8Z.js} +7354 -6884
  22. package/dist/{copy-icon-Ft7t9bqz.js → copy-icon-De584pZ4.js} +3 -3
  23. package/dist/{cynefinDiagram-5FMLGOSQ-CgWra7wt.js → cynefinDiagram-5FMLGOSQ-DdllC264.js} +1 -1
  24. package/dist/{dagre-GXQ25YYZ-CFZ8-35c.js → dagre-GXQ25YYZ-BaWHw4_f.js} +1 -1
  25. package/dist/{data-grid-overlay-editor-BmqASKep.js → data-grid-overlay-editor-lGsInXfR.js} +5 -5
  26. package/dist/{data-grid-types-BH_r7g7l.js → data-grid-types-0PJ-9N5n.js} +1 -1
  27. package/dist/{diagram-S7CK7UJ4-lCNQrW7d.js → diagram-S7CK7UJ4-pFt-tUDe.js} +1 -1
  28. package/dist/{diagram-UQ7AKVKN-CQPQ6pP_.js → diagram-UQ7AKVKN-DqGJiBp4.js} +1 -1
  29. package/dist/{diagram-VX7I27RA-Cf3b0llz.js → diagram-VX7I27RA-Dr-yzMjf.js} +1 -1
  30. package/dist/{diagram-Z3DM3KII-Bt4QLrpn.js → diagram-Z3DM3KII-8xzJzv-w.js} +1 -1
  31. package/dist/{dialog-CEBFZNyc.js → dialog-DVRfQuhD.js} +25 -25
  32. package/dist/{dist-F8Ep36rk.js → dist-B1M0bGO3.js} +1 -1
  33. package/dist/{dist-D6d86eNJ.js → dist-BA13RJj5.js} +1 -1
  34. package/dist/{dist-Bvs24R_E.js → dist-BJtmSgcE.js} +48 -48
  35. package/dist/{dist-CN_BeG2I.js → dist-Ba2VIn1K.js} +53 -53
  36. package/dist/{dist-PXYI_yuP.js → dist-Bj4bmwUm.js} +12 -12
  37. package/dist/{dist-DoE4XJBC.js → dist-BmS-ZGjl.js} +8626 -8626
  38. package/dist/{dist-BorMD-uX.js → dist-Bzogh7CW.js} +87 -87
  39. package/dist/{dist-CN8zI-XC.js → dist-CThPVKaP.js} +1385 -1382
  40. package/dist/{dist-DiDibOYr.js → dist-CTi5FTiV.js} +87 -87
  41. package/dist/{dist-diIx5qJW.js → dist-Ck_C32ye.js} +2 -2
  42. package/dist/{dist-BLfKmR-l.js → dist-D1fnFp1J.js} +1 -1
  43. package/dist/{dist-OR1OnN-y.js → dist-D3x9__Fu.js} +46 -46
  44. package/dist/{dist-BMQf5zIS.js → dist-D7mrh5sO.js} +36 -36
  45. package/dist/{dist-CSJ0MDRw.js → dist-D9Q3xjiP.js} +1 -1
  46. package/dist/{dist-BuaRHxOc.js → dist-DP60Ubh8.js} +2 -2
  47. package/dist/{dist-CSbh1PNP.js → dist-DTv9KkpW.js} +12 -12
  48. package/dist/{dist-D-wwqlzJ.js → dist-DVVwOfrD.js} +109 -109
  49. package/dist/{dist-C8fAKSH1.js → dist-DYXM73-k.js} +36 -36
  50. package/dist/{dist-DBtSl3sf.js → dist-DjeybPOb.js} +1 -1
  51. package/dist/{dist-CrSP_H1M.js → dist-DtGn9N4h.js} +197 -197
  52. package/dist/{dist-CLdpGQVr.js → dist-KN80qWCP.js} +2 -2
  53. package/dist/{dist-DpBpA_n1.js → dist-Lm-D-Vr6.js} +3 -3
  54. package/dist/{dist-Cg7gzw-a.js → dist-O0qFpEJh.js} +56 -56
  55. package/dist/{dist-CkTTIdBe.js → dist-OUle2RT7.js} +207 -207
  56. package/dist/{dist-BK4Oj99o.js → dist-T5rh6JvL.js} +1 -1
  57. package/dist/{dropdown-menu-CP_qCYHC.js → dropdown-menu-NlnsmNA6.js} +1481 -1433
  58. package/dist/{ebnfDiagram-PWID7BFC-D3NAyPFY.js → ebnfDiagram-PWID7BFC-Br04Wy-E.js} +2 -2
  59. package/dist/{erDiagram-RLTQ6QDP-Tlu09_Nm.js → erDiagram-RLTQ6QDP-D5-XVgvv.js} +1 -1
  60. package/dist/{error-banner-Da600cwz.js → error-banner-DxJ3s8YO.js} +89 -84
  61. package/dist/{cells-C8iCYvLU.js → error-entries-C2Ux0Fjt.js} +7970 -8605
  62. package/dist/{esm-D2gTsXEV.js → esm-Bbw_Njjx.js} +575 -575
  63. package/dist/{esm-AMFssoNp.js → esm-mDQNEFe_.js} +354 -354
  64. package/dist/feedback-button-B0CMhVv7.js +374 -0
  65. package/dist/{flowDiagram-HODETNUW-CAYbpJmV.js → flowDiagram-HODETNUW-CVl2kREF.js} +2 -2
  66. package/dist/{formats-BGh2thRc.js → formats-BCYthwyc.js} +3 -3
  67. package/dist/{ganttDiagram-EL5Y4UJY-BQT16JSc.js → ganttDiagram-EL5Y4UJY-Dh_4cBJZ.js} +2 -2
  68. package/dist/{glide-data-editor-BkjP14aq.js → glide-data-editor-CL535A5q.js} +370 -368
  69. package/dist/{glide-utils-DJyqh0EM.js → glide-utils-D98laidb.js} +16 -16
  70. package/dist/{globals-BN2O0F8N.js → globals-Bsr6T2yD.js} +3 -3
  71. package/dist/{highlighted-body-KPVGNVTW-zwjq21tf.js → highlighted-body-KPVGNVTW-3Ziwfz-V.js} +2 -2
  72. package/dist/{html-to-image-CZY1pIZH.js → html-to-image-CkH7vdBZ.js} +478 -381
  73. package/dist/{infoDiagram-27XIBGKW-XrDxhr0x.js → infoDiagram-27XIBGKW-BJ4vNcZE.js} +1 -1
  74. package/dist/{ishikawaDiagram-5VMMS53U-CD1muzov.js → ishikawaDiagram-5VMMS53U-B_Jy1Dsm.js} +1 -1
  75. package/dist/{kanban-definition-UXKFOSKX-Dg9W142_.js → kanban-definition-UXKFOSKX-C6MkS9vw.js} +1 -1
  76. package/dist/{label-BDKF3Afc.js → label-Qvw1E97W.js} +3 -3
  77. package/dist/{linear-Cnaq3Tfb.js → linear-DWERh7eI.js} +121 -73
  78. package/dist/{loader-BQOfjTIJ.js → loader-DOVB0Syl.js} +12 -12
  79. package/dist/main.js +9706 -7708
  80. package/dist/{mermaid-CiAXjLpA.js → mermaid-Bh918qrq.js} +52 -52
  81. package/dist/mermaid-HWGCJPDP-Du3-HPQA.js +2 -0
  82. package/dist/{mindmap-definition-YA3MSWOX-DgCidgYJ.js → mindmap-definition-YA3MSWOX-BP3ZTuir.js} +1 -1
  83. package/dist/{number-overlay-editor-BEBWJnbL.js → number-overlay-editor-CzbkG4E2.js} +3 -3
  84. package/dist/{objects-CzUgoMIF.js → objects-DCmMvZtn.js} +1 -3
  85. package/dist/{once-BtE-wKRL.js → once-NnpX_HnX.js} +1 -1
  86. package/dist/{pegDiagram-XKGWAZYB-coOYYKB6.js → pegDiagram-XKGWAZYB-nNGOQtnt.js} +2 -2
  87. package/dist/{pieDiagram-E7YTZNPT-BnXTc3bj.js → pieDiagram-E7YTZNPT-CpRz5BZz.js} +1 -1
  88. package/dist/precisionRound-DhAzeRcm.js +49 -0
  89. package/dist/{process-output-e4jj9Ijt.js → process-output-OujAtFW4.js} +4 -4
  90. package/dist/{quadrantDiagram-AXDQQJYC-Ccw0xMjN.js → quadrantDiagram-AXDQQJYC-Blrm7V7_.js} +1 -1
  91. package/dist/{railroadDiagram-O6MQD6OU-B28-u83n.js → railroadDiagram-O6MQD6OU-BqOEN4I0.js} +2 -2
  92. package/dist/{react-vega-BED0DjiB.js → react-vega-C4T9Rb_w.js} +12284 -12270
  93. package/dist/{requirementDiagram-BXWQKSXE-CdYCTMu0.js → requirementDiagram-BXWQKSXE-CEfg6vu9.js} +1 -1
  94. package/dist/{reveal-component-DK69bOki.js → reveal-component-CbEK0sNX.js} +733 -710
  95. package/dist/{select-BButFi-d.js → select-2KOiReNY.js} +536 -457
  96. package/dist/{sequenceDiagram-WJ2MYXX4-CM3aRAe_.js → sequenceDiagram-WJ2MYXX4-IOmpQcOi.js} +1 -1
  97. package/dist/{spec-BwarBpUJ.js → spec-Dkp64vVQ.js} +41 -11
  98. package/dist/{stateDiagram-D77RDMKH-DOZUMVj8.js → stateDiagram-D77RDMKH-tgU-EY9_.js} +2 -2
  99. package/dist/{stateDiagram-v2-MP3YSRHH-CISYxma6.js → stateDiagram-v2-MP3YSRHH-BofhG6q1.js} +2 -2
  100. package/dist/style.css +1 -1
  101. package/dist/{swimlanes-42K2YHIH-BkSppxp8.js → swimlanes-42K2YHIH-DW4vWDBd.js} +1 -1
  102. package/dist/{swimlanesDiagram-VR7AAH4N-c8G5pGxC.js → swimlanesDiagram-VR7AAH4N-BJcrqUJr.js} +2 -2
  103. package/dist/{swiper-component-DKntyn8p.js → swiper-component-BVfnhbnt.js} +2 -2
  104. package/dist/{time-BieKwdYS.js → time-BaMbJs4z.js} +18 -18
  105. package/dist/{timeline-definition-24CTP7MA-CaMQayqK.js → timeline-definition-24CTP7MA-D_QU3NGs.js} +1 -1
  106. package/dist/{toDate-BNJf01u1.js → toDate-BNDEXbfV.js} +77 -74
  107. package/dist/{toast-B9UMEi8u.js → toast-B5t9o6s_.js} +219 -201
  108. package/dist/{tooltip-BO1REbqs.js → tooltip-s4zZxwKe.js} +325 -301
  109. package/dist/{use-restore-focus-BEM7sFWl.js → use-restore-focus-BgDTd2tc.js} +1482 -1433
  110. package/dist/{useAsyncData-Deh5kszT.js → useAsyncData-ASDni9vH.js} +15 -14
  111. package/dist/{useDateFormatter-D8XruNGG.js → useDateFormatter-D3Tkfzej.js} +2 -2
  112. package/dist/{useDeepCompareMemoize-DXwzRINI.js → useDeepCompareMemoize-B1Ogyf53.js} +1 -1
  113. package/dist/{useIframeCapabilities-DBETvvPl.js → useIframeCapabilities-6a_yDNXp.js} +1 -1
  114. package/dist/{useLifecycle-j7D9uD1o.js → useLifecycle-Bfpa2m7k.js} +28 -25
  115. package/dist/{useTheme-CRnjkku0.js → useTheme-5TwyOh3B.js} +522 -314
  116. package/dist/{vega-component-DG29TAB7.js → vega-component-BHS9UOtC.js} +158 -158
  117. package/dist/{vega-embed-container-BNHE18G9.js → vega-embed-container--LYZqguO.js} +2 -2
  118. package/dist/{vega-loader.browser-DNST6uVf.js → vega-loader.browser-B9Pz0EGP.js} +298 -507
  119. package/dist/{vennDiagram-4TSXK5OY-CF8pfaK3.js → vennDiagram-4TSXK5OY-YFYsNIAh.js} +1 -1
  120. package/dist/{wardleyDiagram-VM6X3IG4-dGPu39d-.js → wardleyDiagram-VM6X3IG4-i_n8mAWC.js} +1 -1
  121. package/dist/{xychartDiagram-S5SC5T6Z-CP6-9q56.js → xychartDiagram-S5SC5T6Z-BYGN95wW.js} +2 -2
  122. package/package.json +16 -16
  123. package/src/__mocks__/document.tsx +63 -0
  124. package/src/__mocks__/notebook.ts +3 -4
  125. package/src/__mocks__/partial.ts +26 -0
  126. package/src/__mocks__/requests.ts +0 -3
  127. package/src/__tests__/fixtures/{pair-preview.ts → pair-config.ts} +3 -2
  128. package/src/__tests__/main.test.tsx +24 -1
  129. package/src/__tests__/module-entry.test.ts +44 -0
  130. package/src/__tests__/mount.test.ts +9 -9
  131. package/src/__tests__/{host-imports.test.ts → replica-imports.test.ts} +12 -11
  132. package/src/components/ai/__tests__/ai-model-dropdown.test.tsx +63 -0
  133. package/src/components/ai/ai-model-dropdown.tsx +11 -6
  134. package/src/components/app-config/ai-config.tsx +7 -2
  135. package/src/components/app-config/app-config-form.tsx +5 -9
  136. package/src/components/app-config/user-config-form.tsx +35 -0
  137. package/src/components/chat/__tests__/message-queue.test.tsx +17 -0
  138. package/src/components/chat/__tests__/notebook-access-selector.test.tsx +64 -0
  139. package/src/components/chat/acp/__tests__/session-tabs.test.tsx +43 -0
  140. package/src/components/chat/acp/__tests__/state.test.ts +2 -2
  141. package/src/components/chat/acp/blocks.tsx +3 -2
  142. package/src/components/chat/acp/session-tabs.tsx +8 -3
  143. package/src/components/chat/chat-components.tsx +2 -0
  144. package/src/components/chat/chat-panel.tsx +20 -101
  145. package/src/components/chat/chat-utils.ts +4 -8
  146. package/src/components/chat/notebook-access-selector.stories.tsx +22 -0
  147. package/src/components/chat/notebook-access-selector.tsx +100 -0
  148. package/src/components/data-table/TableBottomBar.tsx +4 -1
  149. package/src/components/data-table/TableTopBar.tsx +2 -0
  150. package/src/components/data-table/__tests__/chart-spec-model.test.ts +195 -195
  151. package/src/components/data-table/__tests__/column-explorer.test.tsx +27 -1
  152. package/src/components/data-table/__tests__/columns.test.tsx +105 -0
  153. package/src/components/data-table/__tests__/context-menu-interaction.test.tsx +130 -0
  154. package/src/components/data-table/__tests__/context-menu.test.ts +176 -0
  155. package/src/components/data-table/__tests__/data-table.test.tsx +1 -0
  156. package/src/components/data-table/__tests__/date-filter-inputs.test.tsx +24 -1
  157. package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
  158. package/src/components/data-table/__tests__/export-actions.test.tsx +434 -6
  159. package/src/components/data-table/__tests__/keyboard-selection.test.tsx +188 -0
  160. package/src/components/data-table/__tests__/pagination.test.tsx +28 -1
  161. package/src/components/data-table/__tests__/search-highlight.test.tsx +109 -0
  162. package/src/components/data-table/__tests__/url-detector.test.tsx +74 -0
  163. package/src/components/data-table/cell-selection/feature.ts +2 -2
  164. package/src/components/data-table/cell-selection/types.ts +2 -2
  165. package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
  166. package/src/components/data-table/charts/__tests__/spec-snapshot.test.ts +20 -20
  167. package/src/components/data-table/charts/__tests__/spec.test.ts +78 -52
  168. package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
  169. package/src/components/data-table/charts/chart-spec/spec.ts +68 -43
  170. package/src/components/data-table/charts/charts.tsx +40 -30
  171. package/src/components/data-table/charts/storage.ts +16 -5
  172. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
  173. package/src/components/data-table/column-summary/chart-spec-model.tsx +23 -16
  174. package/src/components/data-table/column-summary/column-summary.tsx +2 -4
  175. package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
  176. package/src/components/data-table/columns.tsx +45 -46
  177. package/src/components/data-table/context-menu.tsx +161 -46
  178. package/src/components/data-table/data-table.tsx +17 -1
  179. package/src/components/data-table/date-filter-inputs.tsx +15 -42
  180. package/src/components/data-table/date-popover.tsx +6 -4
  181. package/src/components/data-table/export-actions.tsx +267 -163
  182. package/src/components/data-table/pagination.tsx +44 -33
  183. package/src/components/data-table/range-focus/atoms.ts +4 -6
  184. package/src/components/data-table/range-focus/use-cell-range-selection.ts +65 -38
  185. package/src/components/data-table/range-focus/use-scroll-into-view.ts +21 -2
  186. package/src/components/data-table/renderers.tsx +16 -7
  187. package/src/components/data-table/row-viewer-panel/__tests__/row-viewer.test.tsx +24 -1
  188. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +4 -4
  189. package/src/components/data-table/schemas.ts +14 -36
  190. package/src/components/data-table/search-highlight.tsx +79 -0
  191. package/src/components/data-table/types.ts +1 -0
  192. package/src/components/data-table/url-detector.tsx +49 -9
  193. package/src/components/data-table/utils.ts +18 -0
  194. package/src/components/datasources/__tests__/column-actions.test.tsx +97 -0
  195. package/src/components/datasources/__tests__/column-preview.test.tsx +96 -5
  196. package/src/components/datasources/__tests__/datasources-interactions.test.tsx +181 -0
  197. package/src/components/datasources/__tests__/table-list.test.tsx +118 -0
  198. package/src/components/datasources/__tests__/utils.test.ts +57 -6
  199. package/src/components/datasources/column-preview.tsx +17 -12
  200. package/src/components/datasources/datasources.tsx +56 -43
  201. package/src/components/datasources/utils.ts +32 -23
  202. package/src/components/debugger/debugger-code.tsx +5 -0
  203. package/src/components/dependency-graph/custom-node.tsx +1 -1
  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/minimap-content.tsx +13 -19
  207. package/src/components/dependency-graph/panels.tsx +4 -2
  208. package/src/components/dependency-graph/utils/__tests__/layout.test.ts +18 -11
  209. package/src/components/editor/Output.tsx +9 -2
  210. package/src/components/editor/SortableCell.tsx +1 -3
  211. package/src/components/editor/__tests__/Output.test.tsx +50 -32
  212. package/src/components/editor/__tests__/agent-toast.test.tsx +58 -0
  213. package/src/components/editor/__tests__/data-attributes.test.tsx +28 -14
  214. package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
  215. package/src/components/editor/__tests__/output-persistence.test.tsx +6 -2
  216. package/src/components/editor/__tests__/package-alert.test.tsx +22 -1
  217. package/src/components/editor/actions/__tests__/name-cell-input.test.tsx +69 -0
  218. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +80 -252
  219. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +218 -40
  220. package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +2 -6
  221. package/src/components/editor/actions/name-cell-input.tsx +4 -3
  222. package/src/components/editor/actions/pair-with-agent-commands.ts +44 -53
  223. package/src/components/editor/actions/pair-with-agent-modal.tsx +101 -38
  224. package/src/components/editor/actions/useCellActionButton.tsx +26 -31
  225. package/src/components/editor/actions/useConfigActions.tsx +3 -4
  226. package/src/components/editor/actions/useNotebookActions.tsx +19 -23
  227. package/src/components/editor/actions/useRestartKernel.tsx +1 -1
  228. package/src/components/editor/actions/useSetCodeVisibility.ts +11 -12
  229. package/src/components/editor/actions/useSetOutputsExpanded.ts +14 -19
  230. package/src/components/editor/agent-toast.ts +15 -0
  231. package/src/components/editor/ai/add-cell-with-ai.tsx +3 -3
  232. package/src/components/editor/ai/ai-completion-editor.tsx +1 -0
  233. package/src/components/editor/alerts/__tests__/connection-notice.test.tsx +1 -1
  234. package/src/components/editor/alerts/connection-notice.tsx +1 -1
  235. package/src/components/editor/alerts/startup-logs-alert.tsx +1 -0
  236. package/src/components/editor/alerts/stdin-blocking-alert.tsx +1 -1
  237. package/src/components/editor/app-container.tsx +1 -1
  238. package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +1 -1
  239. package/src/components/editor/cell/CreateCellButton.tsx +15 -21
  240. package/src/components/editor/cell/DeleteButton.tsx +3 -2
  241. package/src/components/editor/cell/RunButton.tsx +2 -2
  242. package/src/components/editor/cell/StagedAICell.tsx +10 -2
  243. package/src/components/editor/cell/StopButton.tsx +2 -2
  244. package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +3 -1
  245. package/src/components/editor/cell/__tests__/useShouldShowInterrupt.test.ts +39 -0
  246. package/src/components/editor/cell/cell-actions.tsx +12 -1
  247. package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
  248. package/src/components/editor/cell/code/cell-editor.tsx +36 -43
  249. package/src/components/editor/cell/code/language-toggle.tsx +8 -7
  250. package/src/components/editor/cell/collapse.tsx +11 -4
  251. package/src/components/editor/cell/useAddCell.ts +4 -8
  252. package/src/components/editor/cell/useDeleteCell.tsx +10 -36
  253. package/src/components/editor/cell/useRunCells.ts +2 -5
  254. package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
  255. package/src/components/editor/cell/useSplitCell.tsx +10 -6
  256. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +1 -1
  257. package/src/components/editor/chrome/components/feedback-button.tsx +2 -8
  258. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +31 -2
  259. package/src/components/editor/chrome/panels/__tests__/runtime-details.test.tsx +1 -1
  260. package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +1 -1
  261. package/src/components/editor/chrome/panels/cache-panel.tsx +1 -0
  262. package/src/components/editor/chrome/panels/dependency-graph-panel.tsx +1 -1
  263. package/src/components/editor/chrome/panels/error-panel.tsx +1 -0
  264. package/src/components/editor/chrome/panels/logs-panel.tsx +2 -1
  265. package/src/components/editor/chrome/panels/outline/__tests__/outline-keyboard.test.tsx +84 -0
  266. package/src/components/editor/chrome/panels/outline/floating-outline.tsx +39 -14
  267. package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +3 -2
  268. package/src/components/editor/chrome/panels/packages-panel.tsx +4 -7
  269. package/src/components/editor/chrome/panels/secrets-panel.tsx +1 -0
  270. package/src/components/editor/chrome/panels/session-panel.tsx +1 -1
  271. package/src/components/editor/chrome/panels/snippets-panel.tsx +10 -12
  272. package/src/components/editor/chrome/panels/variable-panel.tsx +1 -5
  273. package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +363 -0
  274. package/src/components/editor/chrome/wrapper/__tests__/document-sync-status.test.tsx +92 -0
  275. package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +61 -2
  276. package/src/components/editor/chrome/wrapper/footer-item.tsx +32 -24
  277. package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +237 -0
  278. package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +1 -1
  279. package/src/components/editor/chrome/wrapper/footer-items/document-sync-status.tsx +54 -0
  280. package/src/components/editor/chrome/wrapper/footer-items/lsp-status.tsx +1 -1
  281. package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +1 -1
  282. package/src/components/editor/chrome/wrapper/footer-items/runtime-settings.tsx +1 -7
  283. package/src/components/editor/chrome/wrapper/footer.tsx +4 -0
  284. package/src/components/editor/chrome/wrapper/minimap-state.ts +1 -1
  285. package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +12 -2
  286. package/src/components/editor/chrome/wrapper/storage.ts +1 -1
  287. package/src/components/editor/columns/__tests__/cell-column.test.tsx +1 -1
  288. package/src/components/editor/columns/cell-column.tsx +1 -1
  289. package/src/components/editor/columns/sortable-column.tsx +2 -2
  290. package/src/components/editor/connections/components.tsx +5 -10
  291. package/src/components/editor/controls/Controls.tsx +4 -4
  292. package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
  293. package/src/components/editor/controls/__tests__/keyboard-shortcuts.test.tsx +61 -0
  294. package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +10 -4
  295. package/src/components/editor/controls/command-palette.tsx +22 -10
  296. package/src/components/editor/controls/keyboard-shortcuts.tsx +14 -5
  297. package/src/components/editor/documentation.css +34 -11
  298. package/src/components/editor/dynamic-favicon.tsx +21 -40
  299. package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +536 -0
  300. package/src/components/editor/errors/auto-fix.tsx +4 -8
  301. package/src/components/editor/errors/send-error-report-button.tsx +66 -0
  302. package/src/components/editor/file-tree/__tests__/file-explorer-interactions.test.tsx +6 -0
  303. package/src/components/editor/file-tree/__tests__/file-explorer-navigation.test.tsx +47 -0
  304. package/src/components/editor/file-tree/__tests__/use-file-search.test.tsx +91 -0
  305. package/src/components/editor/file-tree/file-explorer.tsx +48 -15
  306. package/src/components/editor/file-tree/file-name-input.tsx +1 -0
  307. package/src/components/editor/file-tree/file-viewer.tsx +4 -2
  308. package/src/components/editor/file-tree/use-file-search.ts +35 -21
  309. package/src/components/editor/header/__tests__/status.test.tsx +5 -3
  310. package/src/components/editor/header/app-header.tsx +1 -1
  311. package/src/components/editor/header/status.tsx +40 -20
  312. package/src/components/editor/links/__tests__/cell-link.test.tsx +148 -0
  313. package/src/components/editor/links/cell-link-list.tsx +1 -1
  314. package/src/components/editor/links/cell-link.tsx +17 -7
  315. package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
  316. package/src/components/editor/navigation/__tests__/navigation.test.ts +108 -85
  317. package/src/components/editor/navigation/__tests__/selection.test.ts +43 -21
  318. package/src/components/editor/navigation/clipboard.ts +17 -14
  319. package/src/components/editor/navigation/focus-utils.ts +23 -4
  320. package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +17 -33
  321. package/src/components/editor/navigation/navigation.ts +71 -70
  322. package/src/components/editor/navigation/selection.ts +30 -29
  323. package/src/components/editor/notebook-banner.tsx +1 -0
  324. package/src/components/editor/notebook-cell.tsx +29 -31
  325. package/src/components/editor/output/MarimoErrorOutput.tsx +23 -6
  326. package/src/components/editor/output/MarimoTracebackOutput.tsx +54 -37
  327. package/src/components/editor/output/Outputs.css +8 -0
  328. package/src/components/editor/output/__tests__/ansi-reduce.test.ts +18 -0
  329. package/src/components/editor/output/__tests__/traceback.test.tsx +27 -1
  330. package/src/components/editor/output/ansi-reduce.ts +36 -17
  331. package/src/components/editor/output/console/ConsoleOutput.tsx +19 -25
  332. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +125 -69
  333. package/src/components/editor/package-alert.tsx +14 -7
  334. package/src/components/editor/renderers/cell-array.tsx +22 -33
  335. package/src/components/editor/renderers/grid-layout/grid-layout.tsx +12 -6
  336. package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +0 -1
  337. package/src/components/editor/renderers/slides-layout/slides-layout.tsx +1 -1
  338. package/src/components/editor/renderers/vertical-layout/__tests__/useFocusFirstEditor.test.ts +4 -4
  339. package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
  340. package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +1 -1
  341. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +1 -1
  342. package/src/components/editor/stdin-blocking-alert.tsx +1 -1
  343. package/src/components/home/components.tsx +17 -31
  344. package/src/components/icons/__tests__/large-spinner.test.tsx +39 -0
  345. package/src/components/icons/large-spinner.tsx +3 -14
  346. package/src/components/icons/spinner.tsx +1 -1
  347. package/src/components/markdown/markdown-renderer.tsx +4 -8
  348. package/src/components/mcp/mcp-status-indicator.tsx +1 -1
  349. package/src/components/pages/__tests__/home-page.test.tsx +116 -0
  350. package/src/components/pages/edit-page.tsx +19 -17
  351. package/src/components/pages/home-page.tsx +164 -91
  352. package/src/components/scratchpad/scratchpad.test.tsx +97 -0
  353. package/src/components/scratchpad/scratchpad.tsx +20 -11
  354. package/src/components/slides/__tests__/minimap-actions.test.tsx +22 -29
  355. package/src/components/slides/__tests__/minimap.test.ts +38 -19
  356. package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +37 -0
  357. package/src/components/slides/minimap.tsx +17 -12
  358. package/src/components/slides/reveal-component.tsx +58 -26
  359. package/src/components/slides/reveal-slides.css +5 -4
  360. package/src/components/slides/slide-cell-view.tsx +4 -5
  361. package/src/components/slides/slide-form.tsx +1 -0
  362. package/src/components/slides/slide-scroll-hint.tsx +3 -1
  363. package/src/components/sort/SortableCellsProvider.tsx +8 -25
  364. package/src/components/tracing/tracing-keyboard.test.tsx +85 -0
  365. package/src/components/tracing/tracing.tsx +46 -42
  366. package/src/components/ui/__tests__/draggable-popover.test.tsx +24 -0
  367. package/src/components/ui/__tests__/range-slider.test.tsx +165 -0
  368. package/src/components/ui/alert-dialog.tsx +1 -1
  369. package/src/components/ui/draggable-popover.tsx +24 -2
  370. package/src/components/ui/range-slider.tsx +22 -9
  371. package/src/core/MarimoApp.tsx +1 -1
  372. package/src/core/ai/__tests__/staged-cells.test.ts +27 -26
  373. package/src/core/ai/context/providers/__tests__/cell-output.test.ts +8 -12
  374. package/src/core/ai/context/providers/cell-output.ts +2 -2
  375. package/src/core/ai/context/providers/datasource.ts +6 -2
  376. package/src/core/ai/staged-cells.ts +15 -18
  377. package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +40 -88
  378. package/src/core/ai/tools/__tests__/registry.test.ts +17 -0
  379. package/src/core/ai/tools/base.ts +18 -15
  380. package/src/core/ai/tools/edit-notebook-tool.ts +86 -80
  381. package/src/core/ai/tools/registry.ts +13 -10
  382. package/src/core/ai/tools/sample-tool.ts +6 -7
  383. package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -37
  384. package/src/core/cells/__tests__/actions.test.ts +624 -35
  385. package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
  386. package/src/core/cells/__tests__/arrange.test.ts +432 -0
  387. package/src/core/cells/__tests__/cell.test.ts +39 -0
  388. package/src/core/cells/__tests__/cells.test.ts +256 -2477
  389. package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
  390. package/src/core/cells/__tests__/document.test.ts +341 -0
  391. package/src/core/cells/__tests__/editor.test.ts +57 -0
  392. package/src/core/cells/__tests__/error-report.test.ts +139 -0
  393. package/src/core/cells/__tests__/flush-document.test.ts +40 -0
  394. package/src/core/cells/__tests__/harness.ts +106 -0
  395. package/src/core/cells/__tests__/layout.test.ts +177 -0
  396. package/src/core/cells/__tests__/notebook-outline.test.ts +120 -0
  397. package/src/core/cells/__tests__/outputs.test.tsx +71 -53
  398. package/src/core/cells/__tests__/session.test.ts +493 -210
  399. package/src/core/cells/__tests__/utils.test.ts +9 -108
  400. package/src/core/cells/__tests__/with-document-save.test.ts +67 -0
  401. package/src/core/cells/actions.ts +636 -6
  402. package/src/core/cells/add-missing-import.ts +47 -43
  403. package/src/core/cells/arrange.ts +529 -0
  404. package/src/core/cells/cell.ts +14 -3
  405. package/src/core/cells/cells.ts +120 -1337
  406. package/src/core/cells/columns.ts +38 -0
  407. package/src/core/cells/document.ts +289 -0
  408. package/src/core/cells/edit.ts +30 -0
  409. package/src/core/cells/editor.ts +82 -0
  410. package/src/core/cells/error-report.ts +63 -0
  411. package/src/core/cells/layout.ts +221 -0
  412. package/src/core/cells/outputs.ts +12 -28
  413. package/src/core/cells/pending-delete-service.ts +3 -7
  414. package/src/core/cells/session.ts +104 -54
  415. package/src/core/cells/types.ts +22 -6
  416. package/src/core/cells/utils.ts +10 -8
  417. package/src/core/codemirror/__tests__/setup.test.ts +29 -29
  418. package/src/core/codemirror/ai/__tests__/resources.test.ts +117 -0
  419. package/src/core/codemirror/ai/resources.ts +1 -1
  420. package/src/core/codemirror/cells/__tests__/extensions.test.ts +42 -1
  421. package/src/core/codemirror/cells/extensions.ts +27 -9
  422. package/src/core/codemirror/cells/state.ts +1 -1
  423. package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +6 -7
  424. package/src/core/codemirror/copilot/getCodes.ts +2 -2
  425. package/src/core/codemirror/format.ts +6 -5
  426. package/src/core/codemirror/keymaps/vim.ts +4 -8
  427. package/src/core/codemirror/language/__tests__/sql.test.ts +22 -20
  428. package/src/core/codemirror/language/__tests__/utils.test.ts +187 -15
  429. package/src/core/codemirror/language/cell-code.ts +114 -0
  430. package/src/core/codemirror/language/extension.ts +52 -35
  431. package/src/core/codemirror/language/languages/markdown.ts +8 -6
  432. package/src/core/codemirror/language/languages/python.ts +16 -10
  433. package/src/core/codemirror/language/languages/sql/sql.ts +16 -24
  434. package/src/core/codemirror/language/panel/panel.tsx +1 -0
  435. package/src/core/codemirror/language/types.ts +7 -7
  436. package/src/core/codemirror/language/utils.ts +9 -39
  437. package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +1 -2
  438. package/src/core/codemirror/lsp/notebook-lsp.ts +6 -5
  439. package/src/core/codemirror/lsp/utils.ts +1 -1
  440. package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
  441. package/src/core/codemirror/readonly/extension.ts +2 -2
  442. package/src/core/codemirror/rtc/extension.ts +24 -13
  443. package/src/core/codemirror/rtc/loro/awareness.ts +34 -19
  444. package/src/core/codemirror/rtc/loro/sync.ts +1 -0
  445. package/src/core/codemirror/utils.ts +1 -0
  446. package/src/core/config/__tests__/app-config.test.ts +64 -0
  447. package/src/core/config/__tests__/config-schema.test.ts +13 -6
  448. package/src/core/config/config-schema.ts +13 -3
  449. package/src/core/config/config.ts +26 -12
  450. package/src/core/config/pair.ts +5 -3
  451. package/src/core/datasets/__tests__/data-source-discovery.test.ts +5 -5
  452. package/src/core/datasets/data-source-discovery.ts +4 -6
  453. package/src/core/documentation/doc-lookup.ts +1 -1
  454. package/src/core/edit-app.tsx +21 -28
  455. package/src/core/errors/error-entries.ts +4 -1
  456. package/src/core/export/hooks.ts +1 -1
  457. package/src/core/export/layout.ts +2 -2
  458. package/src/core/hotkeys/actions.ts +2 -4
  459. package/src/core/islands/__tests__/bootstrap.test.ts +69 -17
  460. package/src/core/islands/__tests__/bridge.test.ts +72 -25
  461. package/src/core/islands/bootstrap.ts +46 -53
  462. package/src/core/islands/bridge.ts +74 -23
  463. package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
  464. package/src/core/islands/components/web-components.tsx +1 -1
  465. package/src/core/islands/worker/__tests__/controller.test.ts +62 -4
  466. package/src/core/islands/worker/controller.ts +4 -10
  467. package/src/core/islands/worker/worker.tsx +33 -33
  468. package/src/core/kernel/__tests__/RuntimeState.test.ts +1 -1
  469. package/src/core/kernel/__tests__/handlers.test.ts +7 -153
  470. package/src/core/kernel/handlers.ts +19 -72
  471. package/src/core/meta/__tests__/code-visibility.test.tsx +78 -70
  472. package/src/core/meta/code-visibility.ts +18 -9
  473. package/src/core/network/__tests__/connection.test.ts +1 -1
  474. package/src/core/network/__tests__/requests-lazy.test.ts +1 -3
  475. package/src/core/network/connection-notice.ts +1 -1
  476. package/src/core/network/connection.ts +5 -3
  477. package/src/core/network/requests-lazy.ts +1 -4
  478. package/src/core/network/requests-network.ts +0 -25
  479. package/src/core/network/requests-static.ts +0 -3
  480. package/src/core/network/requests-toasting.tsx +0 -3
  481. package/src/core/network/types.ts +0 -12
  482. package/src/core/network/useConnectionNotice.ts +8 -2
  483. package/src/core/notebook/__tests__/operations.test.ts +51 -0
  484. package/src/core/notebook/attachments.ts +38 -0
  485. package/src/core/notebook/document/__tests__/codemirror.test.ts +586 -0
  486. package/src/core/notebook/document/__tests__/draft.test.ts +363 -0
  487. package/src/core/notebook/document/__tests__/fixtures.ts +92 -0
  488. package/src/core/notebook/document/__tests__/hold.test.ts +88 -0
  489. package/src/core/notebook/document/__tests__/hooks.test.tsx +391 -0
  490. package/src/core/notebook/document/__tests__/lifecycle-scenarios.test.ts +61 -0
  491. package/src/core/notebook/document/__tests__/model.test.ts +247 -0
  492. package/src/core/notebook/document/__tests__/protocol-fixtures.ts +38 -0
  493. package/src/core/notebook/document/__tests__/recovery-scenarios.test.ts +230 -0
  494. package/src/core/notebook/document/__tests__/scenario-fixture.ts +43 -0
  495. package/src/core/notebook/document/__tests__/scenarios.test.ts +205 -0
  496. package/src/core/notebook/document/__tests__/state.test.ts +459 -0
  497. package/src/core/notebook/document/__tests__/submission.test.ts +203 -0
  498. package/src/core/notebook/document/__tests__/test-host.test.ts +92 -0
  499. package/src/core/notebook/document/__tests__/test-host.ts +247 -0
  500. package/src/core/notebook/document/__tests__/test-notebook.ts +149 -0
  501. package/src/core/notebook/document/__tests__/user.ts +61 -0
  502. package/src/core/notebook/document/codemirror.ts +216 -0
  503. package/src/core/notebook/document/draft.ts +502 -0
  504. package/src/core/notebook/document/hooks.tsx +118 -0
  505. package/src/core/notebook/document/index.ts +24 -0
  506. package/src/core/notebook/document/model.ts +105 -0
  507. package/src/core/notebook/document/select.ts +41 -0
  508. package/src/core/notebook/document/state.ts +378 -0
  509. package/src/core/notebook/document/sync.ts +418 -0
  510. package/src/core/notebook/index.ts +19 -0
  511. package/src/core/notebook/operations.ts +30 -0
  512. package/src/core/notebook/replica/AGENTS.md +11 -0
  513. package/src/core/notebook/replica/__tests__/attachments.test.ts +56 -0
  514. package/src/core/notebook/replica/__tests__/document.test.ts +126 -0
  515. package/src/core/notebook/replica/__tests__/fixtures.ts +79 -0
  516. package/src/core/notebook/replica/__tests__/replica.test.ts +550 -0
  517. package/src/core/notebook/replica/backend.ts +19 -0
  518. package/src/core/{websocket/types.ts → notebook/replica/connection.ts} +10 -15
  519. package/src/core/notebook/replica/index.ts +13 -0
  520. package/src/core/notebook/replica/replica.ts +286 -0
  521. package/src/core/notebook/replica/resources/attachments.ts +22 -0
  522. package/src/core/notebook/replica/resources/document.ts +101 -0
  523. package/src/core/packages/__tests__/useSandboxController.test.tsx +1 -1
  524. package/src/core/packages/useSandboxController.ts +1 -1
  525. package/src/core/run-app.tsx +48 -51
  526. package/src/core/runtime/__tests__/adapter.test.ts +1 -1
  527. package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
  528. package/src/core/runtime/__tests__/runtime.test.ts +33 -15
  529. package/src/core/runtime/adapter.ts +1 -1
  530. package/src/core/runtime/config.ts +2 -2
  531. package/src/core/runtime/runtime.ts +39 -30
  532. package/src/core/saving/__tests__/state.test.ts +111 -0
  533. package/src/core/saving/__tests__/useAutoSave.test.tsx +67 -0
  534. package/src/core/saving/filename.ts +1 -1
  535. package/src/core/saving/save-component.tsx +28 -36
  536. package/src/core/saving/state.ts +38 -39
  537. package/src/core/saving/useAutoSave.ts +17 -53
  538. package/src/core/session/__tests__/backend.test.ts +236 -0
  539. package/src/core/session/__tests__/useNotebookReplica.hook.test.tsx +184 -0
  540. package/src/core/{websocket/__tests__/useMarimoKernelConnection.hook.test.tsx → session/__tests__/useNotebookSession.hook.test.tsx} +252 -185
  541. package/src/core/session/active-notebook.ts +22 -0
  542. package/src/core/session/backend.ts +123 -0
  543. package/src/core/session/embedded.ts +7 -0
  544. package/src/core/session/types.ts +17 -0
  545. package/src/core/session/useNotebookReplica.ts +74 -0
  546. package/src/core/{websocket/useMarimoKernelConnection.tsx → session/useNotebookSession.tsx} +120 -273
  547. package/src/core/state/__tests__/jotai.test.tsx +108 -0
  548. package/src/core/state/jotai.ts +1 -1
  549. package/src/core/static/__tests__/files.test.ts +38 -10
  550. package/src/core/static/files.ts +2 -0
  551. package/src/core/{websocket/__tests__/useMarimoKernelConnection.test.ts → transports/__tests__/connection-state.test.ts} +16 -30
  552. package/src/core/transports/__tests__/server.test.ts +408 -0
  553. package/src/core/transports/__tests__/static.test.ts +306 -0
  554. package/src/core/transports/__tests__/wasm.test.ts +166 -0
  555. package/src/core/transports/connection-state.ts +63 -0
  556. package/src/core/transports/server.ts +152 -0
  557. package/src/core/transports/static.ts +166 -0
  558. package/src/core/transports/wasm.ts +97 -0
  559. package/src/core/wasm/__tests__/bridge.test.ts +214 -50
  560. package/src/core/wasm/__tests__/worker.test.ts +187 -0
  561. package/src/core/wasm/bridge.ts +75 -69
  562. package/src/core/wasm/rpc.ts +15 -3
  563. package/src/core/wasm/store.ts +3 -3
  564. package/src/core/wasm/worker/bootstrap.ts +55 -51
  565. package/src/core/wasm/worker/getMarimoWheel.ts +1 -1
  566. package/src/core/wasm/worker/save-worker.ts +9 -10
  567. package/src/core/wasm/worker/types.ts +29 -18
  568. package/src/core/wasm/worker/worker.ts +88 -44
  569. package/src/css/globals.css +66 -22
  570. package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
  571. package/src/hooks/__tests__/useDebounce.test.tsx +51 -0
  572. package/src/hooks/__tests__/useDeepCompareMemoize.test.tsx +39 -0
  573. package/src/hooks/__tests__/useDelayElapsed.test.tsx +28 -0
  574. package/src/hooks/__tests__/useInternalStateWithSync.test.tsx +20 -0
  575. package/src/hooks/__tests__/useScript.test.tsx +77 -0
  576. package/src/hooks/__tests__/useStateForKey.test.tsx +257 -0
  577. package/src/hooks/useAsyncData.ts +3 -3
  578. package/src/hooks/useDataSourceDiscovery.ts +6 -4
  579. package/src/hooks/useDebounce.ts +6 -10
  580. package/src/hooks/useDeepCompareMemoize.ts +1 -1
  581. package/src/hooks/useDelayElapsed.ts +14 -10
  582. package/src/hooks/useElapsedTime.ts +3 -3
  583. package/src/hooks/useEventListener.ts +1 -2
  584. package/src/hooks/useInputHistory.ts +4 -7
  585. package/src/hooks/useInternalStateWithSync.ts +6 -6
  586. package/src/hooks/useResizeObserver.ts +4 -7
  587. package/src/hooks/useScript.ts +67 -70
  588. package/src/hooks/useStateForKey.ts +93 -0
  589. package/src/mount.tsx +23 -14
  590. package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
  591. package/src/plugins/core/registerReactComponent.tsx +1 -1
  592. package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
  593. package/src/plugins/impl/DataEditorPlugin.tsx +1 -1
  594. package/src/plugins/impl/DataTablePlugin.tsx +69 -37
  595. package/src/plugins/impl/DropdownPlugin.tsx +2 -6
  596. package/src/plugins/impl/FileBrowserPlugin.tsx +4 -16
  597. package/src/plugins/impl/FormPlugin.tsx +1 -1
  598. package/src/plugins/impl/RangeSliderPlugin.tsx +16 -2
  599. package/src/plugins/impl/RefreshPlugin.tsx +1 -0
  600. package/src/plugins/impl/SliderPlugin.tsx +6 -8
  601. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +471 -1
  602. package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +45 -0
  603. package/src/plugins/impl/__tests__/RangeSliderPlugin.test.tsx +109 -0
  604. package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +24 -3
  605. package/src/plugins/impl/anywidget/__tests__/registry.test.ts +153 -0
  606. package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +241 -2
  607. package/src/plugins/impl/anywidget/model.ts +3 -1
  608. package/src/plugins/impl/anywidget/registry.ts +18 -14
  609. package/src/plugins/impl/anywidget/runtime.ts +21 -9
  610. package/src/plugins/impl/anywidget/widget-binding.ts +160 -82
  611. package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +93 -0
  612. package/src/plugins/impl/chat/chat-ui.tsx +14 -11
  613. package/src/plugins/impl/code/any-language-editor.tsx +2 -2
  614. package/src/plugins/impl/data-editor/glide-data-editor.tsx +8 -5
  615. package/src/plugins/impl/data-editor/glide-utils.ts +3 -1
  616. package/src/plugins/impl/data-explorer/ConnectedDataExplorerComponent.tsx +1 -1
  617. package/src/plugins/impl/data-explorer/components/column-summary.tsx +4 -2
  618. package/src/plugins/impl/data-explorer/state/reducer.ts +1 -1
  619. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -2
  620. package/src/plugins/impl/data-frames/__tests__/sidebar.test.tsx +160 -0
  621. package/src/plugins/impl/data-frames/forms/__tests__/__snapshots__/form.test.tsx.snap +66 -66
  622. package/src/plugins/impl/data-frames/panel.tsx +43 -16
  623. package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +5 -3
  624. package/src/plugins/impl/panel/PanelPlugin.tsx +16 -17
  625. package/src/plugins/impl/panel/__tests__/utils.test.ts +39 -1
  626. package/src/plugins/impl/panel/utils.ts +17 -0
  627. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +2 -5
  628. package/src/plugins/impl/plotly/selection.ts +25 -19
  629. package/src/plugins/impl/vega/VegaPlugin.tsx +2 -3
  630. package/src/plugins/impl/vega/make-selectable.ts +4 -7
  631. package/src/plugins/layout/RoutesPlugin.tsx +1 -1
  632. package/src/stories/__tests__/editor-story.test.tsx +33 -0
  633. package/src/stories/button.stories.tsx +1 -0
  634. package/src/stories/cell.stories.tsx +2 -5
  635. package/src/stories/data-table.stories.tsx +31 -0
  636. package/src/stories/editor.stories.tsx +24 -17
  637. package/src/stories/form-wrapper.stories.tsx +2 -2
  638. package/src/stories/layout/vertical/one-column.stories.tsx +2 -5
  639. package/src/stories/runtime-story.tsx +23 -17
  640. package/src/stories/select.stories.tsx +2 -2
  641. package/src/stories/switchable-multi-select.stories.tsx +1 -1
  642. package/src/utils/__tests__/arrays.test.ts +35 -0
  643. package/src/utils/__tests__/batch-requests.test.ts +3 -3
  644. package/src/utils/__tests__/{createReducer.test.ts → createReducer.test.tsx} +29 -0
  645. package/src/utils/__tests__/dates.test.ts +116 -0
  646. package/src/utils/__tests__/numbers.test.ts +105 -1
  647. package/src/utils/__tests__/objects.test.ts +21 -0
  648. package/src/utils/arrays.ts +11 -2
  649. package/src/utils/blob.ts +1 -1
  650. package/src/utils/createReducer.ts +53 -26
  651. package/src/utils/dates.ts +94 -0
  652. package/src/utils/maps.ts +0 -3
  653. package/src/utils/numbers.ts +79 -18
  654. package/src/utils/objects.ts +4 -9
  655. package/src/utils/once.ts +19 -19
  656. package/src/utils/tracer.ts +9 -5
  657. package/src/utils/zod-utils.ts +1 -3
  658. package/dist/any-language-editor-B9REGlD9.js +0 -76
  659. package/dist/assets/__vite-browser-external-BXYkiFsk.js +0 -1
  660. package/dist/assets/worker-HPY9fbhz.js +0 -114
  661. package/dist/error-entries-CzoYkIQZ.js +0 -56
  662. package/dist/feedback-button-fND8YT59.js +0 -380
  663. package/dist/mermaid-HWGCJPDP-ByCsZnYF.js +0 -2
  664. package/dist/precisionRound-DMIVQrt2.js +0 -97
  665. package/src/components/editor/navigation/__tests__/state.test.ts +0 -81
  666. package/src/components/editor/navigation/state.ts +0 -65
  667. package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +0 -656
  668. package/src/core/ai/tools/run-cells-tool.ts +0 -303
  669. package/src/core/cells/__tests__/apply-transaction.test.ts +0 -991
  670. package/src/core/cells/__tests__/document-changes.test.ts +0 -1140
  671. package/src/core/cells/__tests__/document-roundtrip.test.ts +0 -392
  672. package/src/core/cells/document-changes.ts +0 -944
  673. package/src/core/host/AGENTS.md +0 -6
  674. package/src/core/host/__tests__/protocol.test.ts +0 -214
  675. package/src/core/host/protocol.ts +0 -1943
  676. package/src/core/state/__tests__/jotai.test.ts +0 -25
  677. package/src/core/wasm/worker/message-buffer.ts +0 -33
  678. package/src/core/websocket/__tests__/useWebSocket.test.ts +0 -49
  679. package/src/core/websocket/transports/__tests__/basic.test.ts +0 -275
  680. package/src/core/websocket/transports/__tests__/sse.test.ts +0 -338
  681. package/src/core/websocket/transports/__tests__/transport.test.ts +0 -308
  682. package/src/core/websocket/transports/__tests__/ws.test.ts +0 -125
  683. package/src/core/websocket/transports/basic.ts +0 -102
  684. package/src/core/websocket/transports/sse.ts +0 -308
  685. package/src/core/websocket/transports/transport.ts +0 -61
  686. package/src/core/websocket/transports/ws.ts +0 -98
  687. package/src/core/websocket/useWebSocket.tsx +0 -88
  688. package/src/utils/__tests__/id-tree.test.ts +0 -2145
  689. package/src/utils/id-tree.tsx +0 -1134
  690. /package/src/core/{websocket → session}/connection-utils.ts +0 -0
@@ -1,10 +1,9 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import type { LayoutType } from "@/components/editor/renderers/types";
3
- import { Logger } from "@/utils/Logger";
4
3
  import { Objects } from "@/utils/objects";
5
4
  import type { UIElementId } from "../cells/ids";
6
- import { type CellData, createCell } from "../cells/types";
7
- import { type AppConfig, AppConfigSchema } from "../config/config-schema";
5
+ import type { ReducerCellActions } from "../cells/cells";
6
+ import type { CellData } from "../cells/types";
8
7
  import { UI_ELEMENT_REGISTRY } from "../dom/uiregistry";
9
8
  import { deserializeLayoutState } from "../layout/layout";
10
9
  import type { LayoutData, LayoutState } from "../layout/state";
@@ -19,41 +18,6 @@ import type { KernelState } from "./state";
19
18
 
20
19
  type KernelReadyData = NotificationMessageData<"kernel-ready">;
21
20
 
22
- /**
23
- * Build cells from kernel-ready data.
24
- */
25
- export function buildCellData(data: KernelReadyData): CellData[] {
26
- const {
27
- codes,
28
- names,
29
- configs,
30
- cell_ids,
31
- last_executed_code,
32
- last_execution_time,
33
- } = data;
34
-
35
- const lastExecutedCode = last_executed_code || {};
36
- const lastExecutionTime = last_execution_time || {};
37
-
38
- return codes.map((code, i) => {
39
- const cellId = cell_ids[i];
40
- const lastCodeRun = lastExecutedCode[cellId];
41
-
42
- // A cell is edited if the code has changed since the last time it was run
43
- const edited = lastCodeRun ? lastCodeRun !== code : false;
44
-
45
- return createCell({
46
- id: cellId,
47
- code,
48
- edited,
49
- name: names[i],
50
- lastCodeRun: lastExecutedCode[cellId] ?? null,
51
- lastExecutionTime: lastExecutionTime[cellId] ?? null,
52
- config: configs[i],
53
- });
54
- });
55
- }
56
-
57
21
  /**
58
22
  * Build layout state from kernel-ready data.
59
23
  */
@@ -95,57 +59,43 @@ export function handleKernelReady(
95
59
  data: KernelReadyData,
96
60
  opts: {
97
61
  autoInstantiate: boolean;
98
- setCells: (cells: CellData[], layout: LayoutState) => void;
62
+ /** The notebook's cells, as the host document provided them. */
63
+ cells: CellData[];
64
+ setLastRun: ReducerCellActions["setLastRun"];
65
+ resetCellRuntimes: ReducerCellActions["resetCellRuntimes"];
99
66
  setLayoutData: (payload: {
100
67
  layoutView: LayoutType;
101
68
  data: LayoutData;
102
69
  }) => void;
103
70
  setCapabilities: (capabilities: Capabilities) => void;
104
71
  setKernelState: (state: KernelState) => void;
105
- setAppConfig: (config: AppConfig) => void;
106
72
  onError: (error: Error) => void;
107
- /**
108
- * If provided, these cells will be used instead of the cells from
109
- * kernel-ready. This allows preserving local edits made before connecting.
110
- */
111
- existingCells?: CellData[];
112
73
  },
113
- ) {
74
+ ): LayoutState {
114
75
  const {
115
- existingCells,
116
76
  autoInstantiate,
117
- setCells,
77
+ cells,
78
+ setLastRun,
79
+ resetCellRuntimes,
118
80
  setLayoutData,
119
- setAppConfig,
120
81
  setCapabilities,
121
82
  setKernelState,
122
83
  onError,
123
84
  } = opts;
124
- const { resumed, ui_values, app_config, capabilities, auto_instantiated } =
125
- data;
85
+ const { resumed, ui_values, capabilities, auto_instantiated } = data;
126
86
 
127
- // Use existing cells if provided (local pre-connect edits), otherwise build from kernel-ready
128
- // If the kernel was resumed, we don't want to use the existing cells because they may be stale.
129
- const hasExistingCells = existingCells && existingCells.length > 0;
130
- const cells =
131
- hasExistingCells && !resumed ? existingCells : buildCellData(data);
132
-
133
- // Set up layout and cells
87
+ resetCellRuntimes();
88
+ setLastRun({
89
+ lastCodeRun: data.last_executed_code ?? {},
90
+ lastExecutionTime: data.last_execution_time ?? {},
91
+ });
134
92
  const layoutState = buildLayoutState(data, cells, setLayoutData);
135
- setCells(cells, layoutState);
136
93
 
137
- // Set app config and capabilities
138
- const parsedAppConfig = AppConfigSchema.safeParse(app_config);
139
- if (parsedAppConfig.success) {
140
- setAppConfig(parsedAppConfig.data);
141
- } else {
142
- Logger.error("Failed to parse app config", parsedAppConfig.error);
143
- }
144
94
  setCapabilities(capabilities);
145
95
 
146
96
  // If the kernel was already instantiated server-side (e.g. run mode), we're done
147
97
  if (auto_instantiated) {
148
- return;
98
+ return layoutState;
149
99
  }
150
100
 
151
101
  // If resumed, restore UI element values from kernel and we're done
@@ -156,16 +106,13 @@ export function handleKernelReady(
156
106
  const uiObjectId: UIElementId = objectId;
157
107
  UI_ELEMENT_REGISTRY.set(uiObjectId, value);
158
108
  }
159
- return;
109
+ return layoutState;
160
110
  }
161
111
 
162
112
  // If we already have values for some objects, we should
163
113
  // send them to the kernel. This may happen after re-connecting
164
114
  // to the kernel after the computer wakes from sleep.
165
115
  const { objectIds, values } = collectUIElementValues();
166
- const codesToSend = hasExistingCells
167
- ? Object.fromEntries(existingCells.map((c) => [c.id, c.code]))
168
- : undefined;
169
116
 
170
117
  // Send instantiate request to kernel
171
118
  void getRequestClient()
@@ -173,7 +120,6 @@ export function handleKernelReady(
173
120
  objectIds,
174
121
  values,
175
122
  autoRun: autoInstantiate,
176
- codes: codesToSend,
177
123
  })
178
124
  .then(() => {
179
125
  setKernelState({ isInstantiated: true, error: null });
@@ -182,6 +128,7 @@ export function handleKernelReady(
182
128
  setKernelState({ isInstantiated: false, error: error });
183
129
  onError(new Error("Failed to instantiate", { cause: error }));
184
130
  });
131
+ return layoutState;
185
132
  }
186
133
 
187
134
  export function handleRemoveUIElements(
@@ -1,17 +1,21 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { renderHook } from "@testing-library/react";
4
- import { createStore, Provider } from "jotai";
4
+ import type * as Protocol from "@marimo-team/client/protocol";
5
+ import { atom, createStore, Provider } from "jotai";
5
6
  import type { ReactNode } from "react";
6
7
  import { afterEach, beforeEach, describe, expect, it } from "vitest";
8
+ import { partial } from "@/__mocks__/partial";
7
9
  import { showCodeInRunModeAtom } from "@/core/meta/state";
8
10
  import { type AppMode, kioskModeAtom, viewStateAtom } from "@/core/mode";
11
+ import type { Document, NotebookReplica } from "@/core/notebook/replica";
9
12
  import {
10
13
  remoteAdapter,
11
14
  runtimeAdapterAtom,
12
15
  staticAdapter,
13
16
  type RuntimeAdapter,
14
17
  } from "@/core/runtime/adapter";
18
+ import { activeNotebookReplicaAtom } from "@/core/session/active-notebook";
15
19
  import { useNotebookCodeAvailable } from "../code-visibility";
16
20
 
17
21
  interface StoreOpts {
@@ -19,6 +23,39 @@ interface StoreOpts {
19
23
  kiosk?: boolean;
20
24
  showInRunMode?: boolean;
21
25
  runtime?: RuntimeAdapter;
26
+ /** Each cell's source as the host sent it; null is withheld. */
27
+ codes?: ReadonlyArray<string | null>;
28
+ }
29
+
30
+ function document(codes: ReadonlyArray<string | null>): Document {
31
+ const cells = codes.map((code, index): Protocol.Cell => ({
32
+ id: `cell-${index}` as Protocol.CellId,
33
+ notebook_id: "nb",
34
+ code,
35
+ name: "_",
36
+ config: {
37
+ column: null,
38
+ disabled: false,
39
+ hide_code: false,
40
+ expand_output: false,
41
+ },
42
+ etag: `etag-${index}`,
43
+ code_hash: `hash-${index}`,
44
+ version: 1,
45
+ }));
46
+ return {
47
+ revision: {
48
+ notebook_id: "nb",
49
+ order: cells.map((cell) => cell.id),
50
+ app_config: {},
51
+ etag: "etag",
52
+ saved_etag: "etag",
53
+ order_etag: "order",
54
+ app_config_etag: "config",
55
+ version: 1,
56
+ },
57
+ cells: new Map(cells.map((cell) => [cell.id, cell])),
58
+ };
22
59
  }
23
60
 
24
61
  function makeStore({
@@ -26,23 +63,32 @@ function makeStore({
26
63
  kiosk = false,
27
64
  showInRunMode = true,
28
65
  runtime = remoteAdapter,
66
+ codes = ["x = 1", ""],
29
67
  }: StoreOpts = {}) {
30
68
  const store = createStore();
31
69
  store.set(viewStateAtom, { mode, cellAnchor: null });
32
70
  store.set(kioskModeAtom, kiosk);
33
71
  store.set(showCodeInRunModeAtom, showInRunMode);
34
72
  store.set(runtimeAdapterAtom, runtime);
73
+ store.set(
74
+ activeNotebookReplicaAtom,
75
+ partial<NotebookReplica>(
76
+ { documentAtom: atom(document(codes)) },
77
+ "replica",
78
+ ),
79
+ );
35
80
  return store;
36
81
  }
37
82
 
38
- function wrap(store: ReturnType<typeof createStore>) {
39
- return ({ children }: { children: ReactNode }) => (
83
+ function render(store: ReturnType<typeof createStore>) {
84
+ const wrapper = ({ children }: { children: ReactNode }) => (
40
85
  <Provider store={store}>{children}</Provider>
41
86
  );
87
+ return renderHook(() => useNotebookCodeAvailable(), { wrapper }).result
88
+ .current;
42
89
  }
43
90
 
44
- const cellsWithCode = [{ code: "x = 1" }, { code: "" }];
45
- const cellsWithoutCode = [{ code: "" }, { code: "" }];
91
+ const withheld = [null, null];
46
92
 
47
93
  const originalHref = window.location.href;
48
94
 
@@ -60,21 +106,11 @@ describe("useNotebookCodeAvailable", () => {
60
106
  });
61
107
 
62
108
  it("returns true in edit mode regardless of cells", () => {
63
- const store = makeStore({ mode: "edit" });
64
- const { result } = renderHook(
65
- () => useNotebookCodeAvailable(cellsWithoutCode),
66
- { wrapper: wrap(store) },
67
- );
68
- expect(result.current).toBe(true);
109
+ expect(render(makeStore({ mode: "edit", codes: withheld }))).toBe(true);
69
110
  });
70
111
 
71
112
  it("returns true in present mode (only reachable from edit)", () => {
72
- const store = makeStore({ mode: "present" });
73
- const { result } = renderHook(
74
- () => useNotebookCodeAvailable(cellsWithoutCode),
75
- { wrapper: wrap(store) },
76
- );
77
- expect(result.current).toBe(true);
113
+ expect(render(makeStore({ mode: "present", codes: withheld }))).toBe(true);
78
114
  });
79
115
 
80
116
  it("returns true in kiosk mode even when read mode and no code", () => {
@@ -82,88 +118,60 @@ describe("useNotebookCodeAvailable", () => {
82
118
  mode: "read",
83
119
  kiosk: true,
84
120
  showInRunMode: false,
121
+ codes: withheld,
85
122
  });
86
- const { result } = renderHook(
87
- () => useNotebookCodeAvailable(cellsWithoutCode),
88
- { wrapper: wrap(store) },
89
- );
90
- expect(result.current).toBe(true);
123
+ expect(render(store)).toBe(true);
91
124
  });
92
125
 
93
126
  it("returns true in read mode when at least one cell has code", () => {
94
- const store = makeStore({ mode: "read" });
95
- const { result } = renderHook(
96
- () => useNotebookCodeAvailable(cellsWithCode),
97
- { wrapper: wrap(store) },
98
- );
99
- expect(result.current).toBe(true);
127
+ expect(render(makeStore({ mode: "read" }))).toBe(true);
128
+ });
129
+
130
+ it("counts an empty cell as code the host sent", () => {
131
+ expect(render(makeStore({ mode: "read", codes: ["", null] }))).toBe(true);
132
+ });
133
+
134
+ it("returns false in read mode when the host withheld every source", () => {
135
+ expect(render(makeStore({ mode: "read", codes: withheld }))).toBe(false);
100
136
  });
101
137
 
102
- it("returns false in read mode when every cell.code is empty (server stripped)", () => {
138
+ it("returns false in read mode before a document arrives", () => {
103
139
  const store = makeStore({ mode: "read" });
104
- const { result } = renderHook(
105
- () => useNotebookCodeAvailable(cellsWithoutCode),
106
- { wrapper: wrap(store) },
107
- );
108
- expect(result.current).toBe(false);
140
+ store.set(activeNotebookReplicaAtom, null);
141
+ expect(render(store)).toBe(false);
109
142
  });
110
143
 
111
144
  it("returns false in read mode when host opts out via showAppCode", () => {
112
- const store = makeStore({ mode: "read", showInRunMode: false });
113
- const { result } = renderHook(
114
- () => useNotebookCodeAvailable(cellsWithCode),
115
- { wrapper: wrap(store) },
145
+ expect(render(makeStore({ mode: "read", showInRunMode: false }))).toBe(
146
+ false,
116
147
  );
117
- expect(result.current).toBe(false);
118
148
  });
119
149
 
120
150
  it("returns false in read mode when ?include-code=false", () => {
121
151
  setSearch("?include-code=false");
122
- const store = makeStore({ mode: "read" });
123
- const { result } = renderHook(
124
- () => useNotebookCodeAvailable(cellsWithCode),
125
- { wrapper: wrap(store) },
126
- );
127
- expect(result.current).toBe(false);
152
+ expect(render(makeStore({ mode: "read" }))).toBe(false);
128
153
  });
129
154
 
130
155
  it("ignores ?include-code=false in kiosk mode", () => {
131
156
  setSearch("?include-code=false");
132
- const store = makeStore({ mode: "read", kiosk: true });
133
- const { result } = renderHook(
134
- () => useNotebookCodeAvailable(cellsWithoutCode),
135
- { wrapper: wrap(store) },
136
- );
137
- expect(result.current).toBe(true);
157
+ expect(
158
+ render(makeStore({ mode: "read", kiosk: true, codes: withheld })),
159
+ ).toBe(true);
138
160
  });
139
161
 
140
162
  it("checks embedded code in a static kiosk", () => {
141
- const store = makeStore({
163
+ const options = {
142
164
  mode: "read",
143
165
  kiosk: true,
144
166
  runtime: staticAdapter,
145
- });
146
-
147
- const withoutCode = renderHook(
148
- () => useNotebookCodeAvailable(cellsWithoutCode),
149
- { wrapper: wrap(store) },
150
- );
151
- const withCode = renderHook(() => useNotebookCodeAvailable(cellsWithCode), {
152
- wrapper: wrap(store),
153
- });
154
-
155
- expect(withoutCode.result.current).toBe(false);
156
- expect(withCode.result.current).toBe(true);
167
+ } as const;
168
+ expect(render(makeStore({ ...options, codes: withheld }))).toBe(false);
169
+ expect(render(makeStore(options))).toBe(true);
157
170
  });
158
171
 
159
172
  it("returns false for non-edit/non-read modes (home, gallery)", () => {
160
173
  for (const mode of ["home", "gallery"] as const) {
161
- const store = makeStore({ mode });
162
- const { result } = renderHook(
163
- () => useNotebookCodeAvailable(cellsWithCode),
164
- { wrapper: wrap(store) },
165
- );
166
- expect(result.current).toBe(false);
174
+ expect(render(makeStore({ mode }))).toBe(false);
167
175
  }
168
176
  });
169
177
  });
@@ -1,22 +1,31 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import { useAtomValue } from "jotai";
3
+ import { atom, useAtomValue } from "jotai";
4
4
  import { KnownQueryParams } from "@/core/constants";
5
5
  import { showCodeInRunModeAtom } from "@/core/meta/state";
6
6
  import { kioskModeAtom, viewStateAtom } from "@/core/mode";
7
7
  import { runtimeAdapterAtom } from "@/core/runtime/adapter";
8
+ import { confirmedDocumentAtom } from "@/core/session/active-notebook";
8
9
  import { logNever } from "@/utils/assertNever";
9
10
 
11
+ /** Whether any cell's source reached this client. A host withholds source as null. */
12
+ export const codeAvailableAtom = atom((get) => {
13
+ const document = get(confirmedDocumentAtom);
14
+ return (
15
+ document !== null &&
16
+ [...document.cells.values()].some((cell) => cell.code !== null)
17
+ );
18
+ });
19
+
10
20
  /**
11
- * Whether the notebook source code reached the frontend and can be rendered.
21
+ * Whether the notebook source code can be rendered.
12
22
  *
13
- * In `marimo run` the server omits cell sources unless `--include-code` is
14
- * set (every `cell.code` arrives as `""`). Use this to gate any "show code"
15
- * / "copy code" / "download .py" affordance.
23
+ * In `marimo run` the server withholds cell sources unless `--include-code`
24
+ * is set. Use this to gate any "show code" / "copy code" / "download .py"
25
+ * affordance.
16
26
  */
17
- export function useNotebookCodeAvailable(
18
- cells: ReadonlyArray<{ code: string }>,
19
- ): boolean {
27
+ export function useNotebookCodeAvailable(): boolean {
28
+ const available = useAtomValue(codeAvailableAtom);
20
29
  const kioskMode = useAtomValue(kioskModeAtom);
21
30
  const { mode } = useAtomValue(viewStateAtom);
22
31
  const showInRunMode = useAtomValue(showCodeInRunModeAtom);
@@ -41,7 +50,7 @@ export function useNotebookCodeAvailable(
41
50
  if (params.get(KnownQueryParams.includeCode) === "false") {
42
51
  return false;
43
52
  }
44
- return cells.some((cell) => Boolean(cell.code));
53
+ return available;
45
54
  }
46
55
  default:
47
56
  logNever(mode);
@@ -3,7 +3,7 @@
3
3
  import { afterEach, describe, expect, it } from "vitest";
4
4
  import { initialModeAtom } from "@/core/mode";
5
5
  import { store } from "@/core/state/jotai";
6
- import { ConnectionState } from "../../websocket/types";
6
+ import { ConnectionState } from "../../session/types";
7
7
  import { connectionAtom, waitForConnectionOpenIfNotebook } from "../connection";
8
8
 
9
9
  const NEVER = Symbol("never");
@@ -53,7 +53,6 @@ describe("createLazyRequests", () => {
53
53
  sendInstantiate: vi.fn().mockResolvedValue({ instantiated: true }),
54
54
  sendFunctionRequest: vi.fn().mockResolvedValue({ result: "data" }),
55
55
  sendRestart: vi.fn().mockResolvedValue({ restarted: true }),
56
- sendDeleteCell: vi.fn().mockResolvedValue({ deleted: true }),
57
56
  sendInterrupt: vi.fn().mockResolvedValue({ interrupted: true }),
58
57
  sendPdb: vi.fn().mockResolvedValue({ pdb: true }),
59
58
  sendRunScratchpad: vi.fn().mockResolvedValue({ run: true }),
@@ -320,7 +319,6 @@ describe("createLazyRequests", () => {
320
319
  cellIds: [cellId("cell1")],
321
320
  codes: ["code"],
322
321
  });
323
- await lazyRequests.sendDeleteCell({ cellId: cellId("cell2") });
324
322
  await lazyRequests.sendInstantiate({
325
323
  objectIds: [uiElementId("obj1")],
326
324
  values: [],
@@ -328,7 +326,7 @@ describe("createLazyRequests", () => {
328
326
 
329
327
  // Init should only be called once
330
328
  expect(mockInit).toHaveBeenCalledTimes(1);
331
- expect(mockGetRuntimeManager).toHaveBeenCalledTimes(3);
329
+ expect(mockGetRuntimeManager).toHaveBeenCalledTimes(2);
332
330
  });
333
331
  });
334
332
  });
@@ -6,7 +6,7 @@ import {
6
6
  type ConnectionPhase,
7
7
  WebSocketClosedReason,
8
8
  ConnectionState,
9
- } from "@/core/websocket/types";
9
+ } from "@/core/session/types";
10
10
  import { connectionAtom } from "./connection";
11
11
 
12
12
  export interface ConnectionNotice {
@@ -4,11 +4,13 @@ import { atomWithReducer } from "jotai/utils";
4
4
  import type { NotificationMessageData } from "../kernel/messages";
5
5
  import { isNotebookPage } from "../mode";
6
6
  import { waitFor } from "../state/jotai";
7
- import { type ConnectionStatus, ConnectionState } from "../websocket/types";
7
+ import { type ConnectionStatus, ConnectionState } from "../session/types";
8
8
 
9
9
  /**
10
- * Atom for storing the connection status.
11
- * Initialized to NOT_STARTED.
10
+ * Shared application state, not the actual event-stream status.
11
+ *
12
+ * TODO(MO-8051) Expose read-only connection state and derive UI availability
13
+ * separately.
12
14
  */
13
15
  export const connectionAtom = atom<ConnectionStatus>({
14
16
  state: ConnectionState.NOT_STARTED,
@@ -7,7 +7,7 @@ import { memoizeLastValue } from "@/utils/once";
7
7
  import { waitForKernelToBeInstantiated } from "../kernel/state";
8
8
  import type { RuntimeManager } from "../runtime/runtime";
9
9
  import { store } from "../state/jotai";
10
- import { ConnectionState } from "../websocket/types";
10
+ import { ConnectionState } from "../session/types";
11
11
  import { connectionAtom, waitForConnectionOpen } from "./connection";
12
12
  import type { EditRequests, RunRequests } from "./types";
13
13
 
@@ -52,10 +52,8 @@ const ACTIONS: Record<keyof AllRequests, Action> = {
52
52
  sendModelValue: "startConnection",
53
53
  sendInstantiate: "startConnectionWithoutKernel",
54
54
  sendRun: "startConnection",
55
- sendDeleteCell: "startConnection",
56
55
  sendRunScratchpad: "startConnection",
57
56
  saveAppConfig: "startConnection",
58
- saveCellConfig: "startConnection",
59
57
  discoverDataSources: "startConnection",
60
58
 
61
59
  // Export operations start a connection
@@ -144,7 +142,6 @@ const ACTIONS: Record<keyof AllRequests, Action> = {
144
142
  downloadStorage: "waitForConnectionOpen",
145
143
 
146
144
  // Sync operations that wait for connection
147
- sendDocumentTransaction: "waitForConnectionOpen",
148
145
  sendCodeCompletionRequest: "waitForConnectionOpen",
149
146
  };
150
147
 
@@ -70,15 +70,6 @@ export function createNetworkRequests(): EditRequests & RunRequests {
70
70
  })
71
71
  .then(handleResponseReturnNull);
72
72
  },
73
- sendDocumentTransaction: async (request) => {
74
- await waitForConnectionOpen();
75
- return getClient()
76
- .POST("/api/document/transaction", {
77
- body: request,
78
- params: getParams(),
79
- })
80
- .then(handleResponseReturnNull);
81
- },
82
73
  sendRename: (request) => {
83
74
  return getClient()
84
75
  .POST("/api/kernel/rename", {
@@ -151,14 +142,6 @@ export function createNetworkRequests(): EditRequests & RunRequests {
151
142
  })
152
143
  .then(handleResponseReturnNull);
153
144
  },
154
- sendDeleteCell: (request) => {
155
- return getClient()
156
- .POST("/api/kernel/delete", {
157
- body: request,
158
- params: getParams(),
159
- })
160
- .then(handleResponseReturnNull);
161
- },
162
145
  sendCodeCompletionRequest: async (request) => {
163
146
  await waitForConnectionOpen();
164
147
  return getClient()
@@ -184,14 +167,6 @@ export function createNetworkRequests(): EditRequests & RunRequests {
184
167
  })
185
168
  .then(handleResponseReturnNull);
186
169
  },
187
- saveCellConfig: (request) => {
188
- return getClient()
189
- .POST("/api/kernel/set_cell_config", {
190
- body: request,
191
- params: getParams(),
192
- })
193
- .then(handleResponseReturnNull);
194
- },
195
170
  sendFunctionRequest: (request) => {
196
171
  return getClient()
197
172
  .POST("/api/kernel/function_call", {
@@ -40,7 +40,6 @@ export function createStaticRequests(): EditRequests & RunRequests {
40
40
  return null;
41
41
  },
42
42
  sendRestart: throwNotInEditMode,
43
- sendDocumentTransaction: throwNotInEditMode,
44
43
  sendRun: throwNotInEditMode,
45
44
  sendRunScratchpad: throwNotInEditMode,
46
45
  sendRename: throwNotInEditMode,
@@ -49,11 +48,9 @@ export function createStaticRequests(): EditRequests & RunRequests {
49
48
  sendInterrupt: throwNotInEditMode,
50
49
  sendShutdown: throwNotInEditMode,
51
50
  sendFormat: throwNotInEditMode,
52
- sendDeleteCell: throwNotInEditMode,
53
51
  sendCodeCompletionRequest: throwNotInEditMode,
54
52
  saveUserConfig: throwNotInEditMode,
55
53
  saveAppConfig: throwNotInEditMode,
56
- saveCellConfig: throwNotInEditMode,
57
54
  sendStdin: throwNotInEditMode,
58
55
  readCode: throwNotInEditMode,
59
56
  readSnippets: throwNotInEditMode,
@@ -21,7 +21,6 @@ export function createErrorToastingRequests(
21
21
  sendInstantiate: "Failed to instantiate",
22
22
  sendFunctionRequest: "Failed to send function request",
23
23
  sendRestart: "Failed to restart",
24
- sendDocumentTransaction: "Failed to sync document transaction",
25
24
  sendRun: "Failed to run",
26
25
  sendRunScratchpad: "Failed to run scratchpad",
27
26
  sendRename: "Failed to rename",
@@ -30,11 +29,9 @@ export function createErrorToastingRequests(
30
29
  sendInterrupt: "Failed to interrupt",
31
30
  sendShutdown: "Failed to shutdown",
32
31
  sendFormat: "Failed to format",
33
- sendDeleteCell: "Failed to delete cell",
34
32
  sendCodeCompletionRequest: "Failed to complete code",
35
33
  saveUserConfig: "Failed to save user config",
36
34
  saveAppConfig: "Failed to save app config",
37
- saveCellConfig: "Failed to save cell config",
38
35
  sendStdin: "Failed to send stdin",
39
36
  readCode: "Failed to read code",
40
37
  readSnippets: "Failed to fetch snippets",
@@ -1,6 +1,5 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import type { components, paths } from "@marimo-team/marimo-api";
3
- import type { CellId } from "../cells/ids";
4
3
 
5
4
  export type schemas = components["schemas"];
6
5
  export type AiCompletionRequest = schemas["AiCompletionRequest"];
@@ -16,7 +15,6 @@ export type CellConfig = schemas["CellConfig"];
16
15
  */
17
16
  export type RuntimeState = schemas["CellNotification"]["status"];
18
17
  export type CodeCompletionRequest = schemas["CodeCompletionRequest"];
19
- export type DeleteCellRequest = schemas["DeleteCellRequest"];
20
18
  export type AutoExportAsIPYNBRequest = schemas["AutoExportAsIPYNBRequest"];
21
19
  export type AutoExportAsMarkdownRequest =
22
20
  schemas["AutoExportAsMarkdownRequest"];
@@ -101,9 +99,6 @@ export type SaveNotebookRequest = schemas["SaveNotebookRequest"];
101
99
  export type CopyNotebookRequest = schemas["CopyNotebookRequest"];
102
100
  export type SaveUserConfigurationRequest =
103
101
  schemas["SaveUserConfigurationRequest"];
104
- export interface SetCellConfigRequest {
105
- configs: Record<CellId, Partial<CellConfig>>;
106
- }
107
102
  /**
108
103
  * Client-side shape for creating a file/directory/notebook. The HTTP
109
104
  * transport sends this as multipart/form-data; the WASM bridge base64-encodes
@@ -117,8 +112,6 @@ export interface FileCreateInput {
117
112
  }
118
113
  export type UpdateUIElementRequest = schemas["UpdateUIElementRequest"];
119
114
  export type ModelRequest = schemas["ModelRequest"];
120
- export type NotebookDocumentTransactionRequest =
121
- schemas["NotebookDocumentTransactionRequest"];
122
115
  export type UpdateUserConfigRequest = schemas["UpdateUserConfigRequest"];
123
116
  export type ShutdownSessionRequest = schemas["ShutdownSessionRequest"];
124
117
  export type Snippet = schemas["Snippet"];
@@ -173,15 +166,10 @@ export interface EditRequests {
173
166
  sendInterrupt: () => Promise<null>;
174
167
  sendShutdown: () => Promise<null>;
175
168
  sendFormat: (request: FormatCellsRequest) => Promise<FormatResponse>;
176
- sendDeleteCell: (request: DeleteCellRequest) => Promise<null>;
177
169
  sendCodeCompletionRequest: (request: CodeCompletionRequest) => Promise<null>;
178
170
  saveUserConfig: (request: SaveUserConfigurationRequest) => Promise<null>;
179
171
  saveAppConfig: (request: SaveAppConfigurationRequest) => Promise<null>;
180
- saveCellConfig: (request: SetCellConfigRequest) => Promise<null>;
181
172
  sendRestart: () => Promise<null>;
182
- sendDocumentTransaction: (
183
- request: NotebookDocumentTransactionRequest,
184
- ) => Promise<null>;
185
173
  sendInstallMissingPackages: (
186
174
  request: InstallPackagesRequest,
187
175
  ) => Promise<null>;