@marimo-team/islands 0.24.3-dev5 → 0.24.3-dev52

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 (384) hide show
  1. package/dist/{ConnectedDataExplorerComponent-C9OF_75w.js → ConnectedDataExplorerComponent-KVhjDMSe.js} +1066 -1066
  2. package/dist/ErrorBoundary-Bfp74qVG.js +200 -0
  3. package/dist/{ImageComparisonComponent-2a9TMMm2.js → ImageComparisonComponent-Dlm5aWnH.js} +4 -4
  4. package/dist/{Plot-C-9MQeGP.js → Plot-CTyjbQDT.js} +21032 -20666
  5. package/dist/_baseMerge-BiGRwuqv.js +165 -0
  6. package/dist/{abnfDiagram-N423BO3Z-CQKwzX8t.js → abnfDiagram-VCTEODGH-CpN0FRda.js} +17 -18
  7. package/dist/{any-language-editor-DmQ7dyCx.js → any-language-editor-CycIVIeP.js} +17 -17
  8. package/dist/arc-7ra3iNdN.js +81 -0
  9. package/dist/architecture-7GRP2DOG-BWLylgiA.js +3 -0
  10. package/dist/{architectureDiagram-T3A2C74G-CncrDpfa.js → architectureDiagram-5GKGNRK7-DDyj5SRB.js} +25 -25
  11. package/dist/assets/__vite-browser-external-BajL8aoc.js +1 -0
  12. package/dist/assets/worker-BemUy60C.js +109 -0
  13. package/dist/blockDiagram-I7D4REHJ-BbXEXJRu.js +1922 -0
  14. package/dist/{button-CKBkqR9J.js → button-DdXAm8iz.js} +5 -5
  15. package/dist/{c4Diagram-5PPSVZJV-DarUk3Yq.js → c4Diagram-7LVT6UL2-DcLsbQmR.js} +696 -668
  16. package/dist/{capabilities-CMBBJTcc.js → capabilities-B3ce_GNu.js} +1 -1
  17. package/dist/{html-to-image-BhNoIBSU.js → cells-BSgNCBZ8.js} +6740 -10126
  18. package/dist/{channel-CyiYUzJv.js → channel-B5XnTarr.js} +1 -1
  19. package/dist/chat-ui-CygzVJ9s.js +5786 -0
  20. package/dist/{check-CHig47QV.js → check-B7cIK6gb.js} +1 -1
  21. package/dist/{chunk-2Q5K7J3B-BMuJl2jB.js → chunk-2Q5K7J3B-BMkUkeuy.js} +2 -2
  22. package/dist/chunk-4HAMMTFA-D2qv8E0X.js +4188 -0
  23. package/dist/{chunk-5VM5RSS4-Bcq0ftdy.js → chunk-5VM5RSS4-DKsmPCL6.js} +2 -2
  24. package/dist/{chunk-NSK5VX7P-CDTMcJB0.js → chunk-75Z2AOVW-5_HsvXwr.js} +23 -23
  25. package/dist/{chunk-I66GZJ75-BqyTCAPf.js → chunk-DU6HZSFF-BUgAHvnM.js} +21 -4
  26. package/dist/{chunk-2GRJ4B5K-DgO8Qudq.js → chunk-F27PBJKO-DHmYWZXr.js} +4 -4
  27. package/dist/{chunk-KEIR6QF5-C4KX3XYh.js → chunk-FOHPRMQF-BpYR8RqP.js} +4 -4
  28. package/dist/{chunk-WRU74C26-BpWsbiDK.js → chunk-GMAD6QVW-Czynz8aA.js} +486 -258
  29. package/dist/chunk-GVQU2GXP-yQEdulRS.js +37 -0
  30. package/dist/{chunk-5RXB4S5H-tLNUVDdO.js → chunk-IMKFNOWR-BfwTebD0.js} +11 -11
  31. package/dist/{chunk-JWPE2WC7-BJwjGUnF.js → chunk-JWPE2WC7-DJvv1t8U.js} +2 -2
  32. package/dist/chunk-L3NEJ4N5-DwRWnDDK.js +245 -0
  33. package/dist/{chunk-7Z6QIM7H-Dc18hFxH.js → chunk-OSK3NFVY-BBKU_Ign.js} +222 -144
  34. package/dist/{chunk-W5SLKNZC-DLnvpEtV.js → chunk-P2QGCYS3-C0iGU29N.js} +20 -20
  35. package/dist/{chunk-KBJHAD2P-BuqWqkcW.js → chunk-POPQ4Y6H-BCbS3Ozc.js} +4 -4
  36. package/dist/{chunk-4I5QYGJK-DpytHuZQ.js → chunk-PWAF6VOD-CTFCL0jI.js} +4 -4
  37. package/dist/{chunk-JQJVKLGR-CgqCwe8E.js → chunk-SHT3W25Y-BspJEJ5H.js} +109 -63
  38. package/dist/{chunk-6Q2QTUOP-DmTcEBMn.js → chunk-SVP7TREG-DX3rFNTe.js} +5 -5
  39. package/dist/{chunk-GF5L2VYU-B0wgCQgS.js → chunk-TICWLB2K-fVF7Uujg.js} +13 -13
  40. package/dist/{chunk-XXDRQBXY-D73H4IN0.js → chunk-XXDRQBXY-Dnl5VBqG.js} +3 -3
  41. package/dist/{chunk-Y2CYZVJY-DoegUj_e.js → chunk-Y2CYZVJY-DKKS1VyV.js} +1 -1
  42. package/dist/{chunk-5FQGJX7Z-B85XCPv6.js → chunk-YOKDWASO-DrWbKnxA.js} +6925 -5460
  43. package/dist/classDiagram-ZZMXUADV-Fe-V14Sc.js +30 -0
  44. package/dist/classDiagram-v2-VYDZK3BY-xTDg7lOs.js +30 -0
  45. package/dist/code-visibility-qtEE1_Zi.js +138 -0
  46. package/dist/{common-xHoep60C.js → common-BmP252R5.js} +8839 -12646
  47. package/dist/{compiler-runtime-CAH9RLw2.js → compiler-runtime-Cj8ZWiNS.js} +2 -2
  48. package/dist/copy-icon-CLdENY__.js +190 -0
  49. package/dist/{cose-bilkent-JH36ORCC-FUWHkXFX.js → cose-bilkent-JH36ORCC-_LyRKVqm.js} +2 -2
  50. package/dist/cubic-OaEBhQPK.js +1404 -0
  51. package/dist/cynefin-OW5HDTMX-obq-i80l.js +3 -0
  52. package/dist/{cynefinDiagram-MW4NZA55-BXSFK93J.js → cynefinDiagram-5FMLGOSQ-CFQrqzSX.js} +10 -10
  53. package/dist/{dagre-CGyalH38.js → dagre-BGSfXNEb.js} +678 -537
  54. package/dist/dagre-GXQ25YYZ-xHNAUTyG.js +425 -0
  55. package/dist/{data-grid-overlay-editor-DZM4BAaI.js → data-grid-overlay-editor-DtaTjDfe.js} +8 -9
  56. package/dist/{data-grid-types-BnZwWG8z.js → data-grid-types-BucVmDDp.js} +1 -1
  57. package/dist/{defaultLocale-DKaU_opG.js → defaultLocale-JI_lnoCe.js} +1 -1
  58. package/dist/{diagram-7IWD3JNH-BjfzDNvj.js → diagram-S7CK7UJ4-Bt1rPbAx.js} +40 -39
  59. package/dist/{diagram-UB23O5K3-DDg-7wLA.js → diagram-UQ7AKVKN-D1sq5FoZ.js} +10 -10
  60. package/dist/{diagram-B4RE2ZJO-CKccR9eE.js → diagram-VSXAHHWV-BKpmG23x.js} +10 -10
  61. package/dist/{diagram-Q27KOJAE-Zhz01ss7.js → diagram-VX7I27RA-BMwGFVD6.js} +21 -21
  62. package/dist/{diagram-LBJQPF4R-CJ-bOruh.js → diagram-Z3DM3KII--KLDR9Pl.js} +10 -10
  63. package/dist/dialog-CgNq6y9-.js +94 -0
  64. package/dist/{dist-dAqZAPcF.js → dist-1HDa70oE.js} +3 -3
  65. package/dist/{dist-Re9sOPOx.js → dist-9x1ZRe-e.js} +2 -2
  66. package/dist/{dist-DEeLqRlU.js → dist-B1vYLK28.js} +1 -1
  67. package/dist/{dist-C5Bn52W4.js → dist-B8D7McG3.js} +3 -3
  68. package/dist/{dist-_XvgytiS.js → dist-BHCHt1NI.js} +1 -1
  69. package/dist/{dist-CRjAdnqF.js → dist-BRxfaJgs.js} +3 -3
  70. package/dist/{dist-Byj2bV8o.js → dist-BVGtK7Ht.js} +1 -1
  71. package/dist/{dist-BIN5LKyE.js → dist-BaHjhkpZ.js} +2 -2
  72. package/dist/{dist-DVFbIwc5.js → dist-BtKIs9N-.js} +1 -1
  73. package/dist/{dist-BrQGcfQ9.js → dist-C2KzV-vf.js} +2 -2
  74. package/dist/{dist-DJFiGP2k.js → dist-C2wDlYdD.js} +2 -2
  75. package/dist/{dist-BVRM2y1P.js → dist-C8xMLVYi.js} +2 -2
  76. package/dist/dist-CMh_W4y4.js +538 -0
  77. package/dist/{extends-BPB6_lTK.js → dist-CO1AwwG_.js} +516 -561
  78. package/dist/{dist-BzN60Z2s.js → dist-CPGxfVGX.js} +1 -1
  79. package/dist/{dist-C7v-9nUK.js → dist-Cm3iAFMD.js} +3 -3
  80. package/dist/{dist-CGAxEiaM.js → dist-Cs2FijYk.js} +2 -2
  81. package/dist/{dist-hXd65f0_.js → dist-D1PpnuZB.js} +1 -1
  82. package/dist/{dist-VdvbxG72.js → dist-DHOTQar0.js} +1 -1
  83. package/dist/{dist-DcgzXCfy.js → dist-DPcEtqmG.js} +2 -2
  84. package/dist/{dist-D4Z_qdP4.js → dist-Df0wKI0F.js} +1 -1
  85. package/dist/{dist-qhLI-SHd.js → dist-DszxuxS1.js} +2 -2
  86. package/dist/{dist-BEmkrGoQ.js → dist-Kxgjxakw.js} +1 -1
  87. package/dist/{dist-BbSMhhD2.js → dist-KzZ7WELx.js} +2 -2
  88. package/dist/{dist-jWUab2d1.js → dist-lA1Cttkb.js} +1 -1
  89. package/dist/dropdown-menu-CZgjYSAh.js +4502 -0
  90. package/dist/{ebnfDiagram-BXEA7PRR-Dm75pCAS.js → ebnfDiagram-PWID7BFC-WnG4cvSQ.js} +17 -18
  91. package/dist/{erDiagram-JOGREHBK-rVDG3VSQ.js → erDiagram-RLTQ6QDP-DhzKiYHc.js} +1037 -798
  92. package/dist/error-banner-B94dcDmP.js +391 -0
  93. package/dist/error-entries-iJn-Nryx.js +56 -0
  94. package/dist/{esm-CR1nhb1c.js → esm-BElI3qKH.js} +22 -22
  95. package/dist/{esm-C1d0g6Bv.js → esm-G4Fhsgng.js} +51 -37
  96. package/dist/{esm-CesmlDrs.js → esm-h8f7-1CJ.js} +423 -423
  97. package/dist/eventmodeling-NTZA5JFV-D7nP7Uyu.js +3 -0
  98. package/dist/feedback-button-D_YQdd5e.js +380 -0
  99. package/dist/flowDiagram-HODETNUW-6dMdB8pR.js +16 -0
  100. package/dist/{formats-CJMVUfb3.js → formats-BR5iGb4s.js} +8 -8
  101. package/dist/{ganttDiagram-PKOTCBZU-9D-LXF6P.js → ganttDiagram-EL5Y4UJY-DbzEBLbl.js} +15 -15
  102. package/dist/gitGraph-4MIJSDKK-Dy9uQXGh.js +3 -0
  103. package/dist/{gitGraphDiagram-DS77QQ5N-BfpsXTLf.js → gitGraphDiagram-WWUBYQGX-BMf0iKi1.js} +10 -10
  104. package/dist/{glide-data-editor-sPZ8fUFn.js → glide-data-editor-CV4eSJ7N.js} +2143 -1910
  105. package/dist/{glide-utils-NShAPPtn.js → glide-utils-B3rUT5PI.js} +15 -15
  106. package/dist/globals-DdrpcXQY.js +19 -0
  107. package/dist/highlighted-body-KPVGNVTW-Ad3MKZ18.js +38 -0
  108. package/dist/html-to-image-kpuRfdfZ.js +3253 -0
  109. package/dist/info-A6RAGUB7-DKoayiHY.js +3 -0
  110. package/dist/{infoDiagram-6WML65LV-DqCTXHVy.js → infoDiagram-27XIBGKW-BagtCX_5.js} +7 -7
  111. package/dist/{ishikawaDiagram-WSZJBQD7-BCUYmZ1v.js → ishikawaDiagram-5VMMS53U-DByDehYy.js} +8 -8
  112. package/dist/{journeyDiagram-NVQOT4AX-BXB6M4zN.js → journeyDiagram-3NMN7TZE-D2LcKDUO.js} +8 -8
  113. package/dist/{jsx-runtime-CpoKNRgu.js → jsx-runtime-DgDPJV9S.js} +1 -1
  114. package/dist/{kanban-definition-27J2QSJJ-CGRhrDUX.js → kanban-definition-UXKFOSKX-BxwkbBI_.js} +29 -29
  115. package/dist/katex-DFBiSucW.js +21840 -0
  116. package/dist/{label-lwzzBHUW.js → label-BJ49YTvk.js} +6 -6
  117. package/dist/{linear-D5r_1YqD.js → linear-Cnaq3Tfb.js} +4 -4
  118. package/dist/{loader-VZ__bv4g.js → loader-D2W4oM-3.js} +15 -15
  119. package/dist/main.js +8105 -13485
  120. package/dist/mermaid-DPNuhemn.js +3084 -0
  121. package/dist/mermaid-HWGCJPDP-DYCzSILp.js +2 -0
  122. package/dist/mermaid-parser.core-DxuSfYwJ.js +638 -0
  123. package/dist/{mhchem-BjwrxcV-.js → mhchem-DWCF06w9.js} +1 -1
  124. package/dist/{micromark-factory-space-DruVGzeG.js → micromark-factory-space-DGxAzmw8.js} +2 -2
  125. package/dist/{mindmap-definition-FAOFIHXS-C9gRhzZq.js → mindmap-definition-YA3MSWOX-Cgvojw3y.js} +17 -17
  126. package/dist/{node-sql-parser-DesT1xNw.js → node-sql-parser-BiZOJ-FS.js} +0 -3
  127. package/dist/{number-overlay-editor-De2CabLL.js → number-overlay-editor-DXWRr4gK.js} +5 -5
  128. package/dist/objectWithoutPropertiesLoose-BRDcTsfB.js +23 -0
  129. package/dist/packet-AYTQ26CC-Yw7ajchJ.js +3 -0
  130. package/dist/{pegDiagram-VL7TDLO6-Df9IUjMD.js → pegDiagram-XKGWAZYB-DahHhYyN.js} +19 -20
  131. package/dist/{pick-SnHlmIBN.js → pick-CJeoxYOS.js} +1 -1
  132. package/dist/pie-WAS4IAKB-BKdKOAkL.js +3 -0
  133. package/dist/{pieDiagram-7S7Q4E2Y-BmRzQ8ZP.js → pieDiagram-E7YTZNPT-CCtX0oCK.js} +29 -31
  134. package/dist/{process-output-CpK6fX_C.js → process-output-DFe2tVIY.js} +7 -6
  135. package/dist/purify.es-DgKyQviY.js +805 -0
  136. package/dist/{quadrantDiagram-CIZ2JOQS-wFBvWcxS.js → quadrantDiagram-AXDQQJYC-DftINo6g.js} +5 -5
  137. package/dist/radar-RG4KPBEZ-ScR_D_Ts.js +3 -0
  138. package/dist/railroad-74A4TZTK-DQvPSdo5.js +3 -0
  139. package/dist/railroad-abnf-HS5TGJTU-CsJQG2O8.js +3 -0
  140. package/dist/railroad-ebnf-LZEXJU2U-BgEobkSn.js +3 -0
  141. package/dist/railroad-peg-WCYAUIDC-DjLAjofI.js +3 -0
  142. package/dist/{railroadDiagram-AXF67PYL-DxbIatiN.js → railroadDiagram-O6MQD6OU-Du5NsPUb.js} +17 -18
  143. package/dist/{react-dom-C94wmq5w.js → react-dom-BUgJ-ab_.js} +3 -3
  144. package/dist/{react-DMWcHin-.js → react-ofJbxM4x.js} +2 -2
  145. package/dist/{react-vega-DSD5aT7_.js → react-vega-5AcMW8gG.js} +10012 -9369
  146. package/dist/{requirementDiagram-LRYGKXZP-X_x-Y713.js → requirementDiagram-BXWQKSXE-0pmmxL6_.js} +20 -19
  147. package/dist/{reveal-component-DwuC-61O.js → reveal-component-DLxDt6wQ.js} +1303 -1237
  148. package/dist/{sankeyDiagram-W5VNT64P-BYJALbbm.js → sankeyDiagram-P5KCCOFB-CDKR5TJH.js} +4 -4
  149. package/dist/{select-3qHpFKF9.js → select-C6plhmZr.js} +317 -562
  150. package/dist/{sequenceDiagram-SI44F4Z6-BiPBe3Sv.js → sequenceDiagram-WJ2MYXX4-DB-ChWwU.js} +11 -11
  151. package/dist/{sizeCapture-X5ZJPWSS-BKLDeh5H.js → sizeCapture-INFHLROL-Dx5SpkQF.js} +2 -2
  152. package/dist/{spec-CutWdqo3.js → spec-CAYwFeV6.js} +4 -4
  153. package/dist/{src-C31ngt98.js → src-CA_m4ONl.js} +298 -303
  154. package/dist/{stateDiagram-OKZ733FA-B7QyNBxH.js → stateDiagram-D77RDMKH-orN6AwMx.js} +19 -20
  155. package/dist/stateDiagram-v2-MP3YSRHH-o05_rJN8.js +30 -0
  156. package/dist/style.css +2 -2
  157. package/dist/{swimlanes-SLNWSIFB-B4f8VP3b.js → swimlanes-42K2YHIH-BkSDcqDT.js} +1501 -1591
  158. package/dist/swimlanesDiagram-VR7AAH4N-D_nFQfRc.js +30 -0
  159. package/dist/{swiper-component-C90YjhaV.js → swiper-component-IOUowglM.js} +39 -26
  160. package/dist/{time-aWGfjN8x.js → time-BieKwdYS.js} +42 -42
  161. package/dist/{timeline-definition-Z64GVDOM-Dacq_5lr.js → timeline-definition-24CTP7MA-BuqJUIRZ.js} +7 -7
  162. package/dist/{toDate-D-Rx3ux5.js → toDate-WXg1yLcI.js} +10 -9
  163. package/dist/toast-DvY70eFX.js +1834 -0
  164. package/dist/tooltip-qB8NlSqV.js +1742 -0
  165. package/dist/treeView-Q6P3EWNA-DuRV97YF.js +3 -0
  166. package/dist/treemap-WGGIJYW6-AsLq-uwC.js +3 -0
  167. package/dist/use-restore-focus-D5D9xEjZ.js +5946 -0
  168. package/dist/{use-vega-container-remeasure-DUW4tRxq.js → use-vega-container-remeasure-4DwJbPWu.js} +2 -2
  169. package/dist/{useAsyncData-CH6-CgJF.js → useAsyncData-BD6AStMt.js} +3 -3
  170. package/dist/{useDateFormatter-Cp9Jdxls.js → useDateFormatter-BRTPsUK7.js} +8 -8
  171. package/dist/{useDeepCompareMemoize-JC87C_jO.js → useDeepCompareMemoize-D_HNdyvI.js} +2 -2
  172. package/dist/{useIframeCapabilities-De3C-9b4.js → useIframeCapabilities-CVtNkI3Y.js} +2 -2
  173. package/dist/{useLifecycle-B4RGlyf0.js → useLifecycle-DPgiiwwU.js} +6 -6
  174. package/dist/useNumberFormatter-BfDpa21j.js +251 -0
  175. package/dist/useTheme-DzXmYZ5V.js +904 -0
  176. package/dist/{vega-component-CPehZbUb.js → vega-component-D0QXopU8.js} +34 -34
  177. package/dist/{vega-embed-container-TJ5z5dZw.js → vega-embed-container-CbnTccZi.js} +6 -6
  178. package/dist/vega-loader.browser-D95WfUcj.js +1139 -0
  179. package/dist/{vennDiagram-T6HMQDX7-D-Rcq3Iu.js → vennDiagram-4TSXK5OY-CTUlJ2PK.js} +9 -9
  180. package/dist/wardley-WFR3VGLG-Na-tFhQJ.js +3 -0
  181. package/dist/{wardleyDiagram-T6FBY63Y-Z-Og7_Wd.js → wardleyDiagram-VM6X3IG4-3evLUb0M.js} +10 -10
  182. package/dist/{xychartDiagram-ELKLHX3M-BDJ2dITA.js → xychartDiagram-S5SC5T6Z-DL2E3K8-.js} +248 -139
  183. package/package.json +54 -57
  184. package/src/__mocks__/requests.ts +7 -0
  185. package/src/__tests__/__snapshots__/CellStatus.test.tsx.snap +12 -12
  186. package/src/__tests__/fixtures/pair-preview.ts +19 -0
  187. package/src/__tests__/mount.test.ts +18 -0
  188. package/src/components/chat/acp/__tests__/agent-panel.test.tsx +270 -0
  189. package/src/components/chat/acp/agent-panel.tsx +45 -44
  190. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +2 -6
  191. package/src/components/data-table/column-summary/chart-spec-model.tsx +1 -1
  192. package/src/components/data-table/columns.tsx +64 -67
  193. package/src/components/editor/RecoveryButton.tsx +1 -0
  194. package/src/components/editor/__tests__/dynamic-favicon.test.tsx +36 -2
  195. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +115 -0
  196. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +218 -0
  197. package/src/components/editor/actions/pair-with-agent-commands.ts +46 -9
  198. package/src/components/editor/actions/pair-with-agent-modal.tsx +49 -23
  199. package/src/components/editor/ai/add-cell-with-ai.tsx +1 -0
  200. package/src/components/editor/ai/ai-completion-editor.tsx +3 -1
  201. package/src/components/editor/alerts/connecting-alert.tsx +1 -66
  202. package/src/components/editor/alerts/connection-notice.tsx +140 -0
  203. package/src/components/editor/app-container.tsx +9 -3
  204. package/src/components/editor/boundary/ErrorBoundary.tsx +38 -16
  205. package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +311 -0
  206. package/src/components/editor/cell/code/__tests__/rtc-editor-config.test.ts +50 -0
  207. package/src/components/editor/cell/code/cell-editor.tsx +41 -42
  208. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +94 -0
  209. package/src/components/editor/chrome/components/feedback-button.tsx +63 -42
  210. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +114 -7
  211. package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +165 -0
  212. package/src/components/editor/chrome/panels/packages-panel.tsx +93 -166
  213. package/src/components/editor/chrome/panels/sandbox-controller.tsx +106 -0
  214. package/src/components/editor/chrome/panels/sandbox-panel.tsx +173 -0
  215. package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +3 -1
  216. package/src/components/editor/code/__tests__/readonly-diff.test.tsx +65 -0
  217. package/src/components/editor/code/readonly-diff.tsx +1 -1
  218. package/src/components/editor/connections/database/__tests__/__snapshots__/as-code.test.ts.snap +98 -98
  219. package/src/components/editor/connections/database/__tests__/as-code.test.ts +11 -5
  220. package/src/components/editor/dynamic-favicon.tsx +17 -10
  221. package/src/components/editor/file-tree/__tests__/tree-actions.test.tsx +54 -0
  222. package/src/components/editor/file-tree/tree-actions.tsx +11 -14
  223. package/src/components/editor/header/__tests__/status.test.tsx +8 -20
  224. package/src/components/editor/header/filename-input.tsx +2 -0
  225. package/src/components/editor/header/status.tsx +5 -3
  226. package/src/components/editor/notebook-cell.tsx +4 -2
  227. package/src/components/editor/output/JsonOutput.tsx +182 -632
  228. package/src/components/editor/output/Outputs.css +50 -17
  229. package/src/components/editor/output/__tests__/JsonOutput-interactions.test.tsx +254 -0
  230. package/src/components/editor/output/__tests__/JsonOutput-mimetype.test.tsx +41 -46
  231. package/src/components/editor/output/__tests__/{json-output.test.ts → json-output-formatting.test.ts} +113 -75
  232. package/src/components/editor/output/__tests__/json-output-pagination.test.ts +252 -0
  233. package/src/components/editor/output/json-output/formatting.ts +167 -0
  234. package/src/components/editor/output/json-output/pagination.ts +155 -0
  235. package/src/components/editor/output/json-output/renderers.tsx +196 -0
  236. package/src/components/editor/output/json-output/themes.ts +52 -0
  237. package/src/components/editor/renderers/cell-array.tsx +1 -5
  238. package/src/components/home/components.tsx +17 -0
  239. package/src/components/pages/gallery-page.tsx +2 -4
  240. package/src/components/pages/home-page.tsx +2 -4
  241. package/src/components/slides/slide-form.tsx +1 -0
  242. package/src/components/slides/slide-notes-editor.tsx +1 -0
  243. package/src/components/terminal/terminal.tsx +4 -4
  244. package/src/components/tracing/tracing-spec.ts +1 -1
  245. package/src/components/ui/table.tsx +1 -1
  246. package/src/components/ui/use-toast.ts +8 -0
  247. package/src/core/MarimoApp.tsx +0 -2
  248. package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +259 -259
  249. package/src/core/cells/__tests__/cell.test.ts +61 -0
  250. package/src/core/cells/__tests__/cells.test.ts +37 -37
  251. package/src/core/cells/cell.ts +9 -1
  252. package/src/core/cells/pending-delete-service.ts +12 -16
  253. package/src/core/codemirror/language/__tests__/sql.test.ts +70 -2
  254. package/src/core/codemirror/language/languages/sql/sql.ts +16 -1
  255. package/src/core/codemirror/rtc/extension.ts +5 -2
  256. package/src/core/config/pair.ts +19 -0
  257. package/src/core/datasets/__tests__/data-source.test.ts +2 -0
  258. package/src/core/datasets/data-source-connections.ts +15 -10
  259. package/src/core/edit-app.tsx +8 -5
  260. package/src/core/errors/state.ts +1 -2
  261. package/src/core/islands/__tests__/parse.test.ts +140 -7
  262. package/src/core/islands/bootstrap.ts +1 -0
  263. package/src/core/islands/bridge.ts +3 -0
  264. package/src/core/islands/parse.ts +20 -0
  265. package/src/core/network/connection-notice.ts +84 -0
  266. package/src/core/network/requests-lazy.ts +3 -0
  267. package/src/core/network/requests-network.ts +12 -0
  268. package/src/core/network/requests-static.ts +3 -0
  269. package/src/core/network/requests-toasting.tsx +3 -0
  270. package/src/core/network/resolve.ts +2 -1
  271. package/src/core/network/types.ts +7 -0
  272. package/src/core/packages/__tests__/usePackageAction.test.tsx +129 -0
  273. package/src/core/packages/__tests__/useSandboxController.test.tsx +165 -0
  274. package/src/core/packages/package-data.ts +35 -0
  275. package/src/core/packages/sandbox-state.ts +15 -0
  276. package/src/core/packages/toast-components.tsx +11 -0
  277. package/src/core/packages/useInstallPackage.ts +1 -1
  278. package/src/core/packages/usePackageAction.ts +51 -0
  279. package/src/core/packages/usePackageDependencies.ts +22 -0
  280. package/src/core/packages/useSandboxController.ts +188 -0
  281. package/src/core/run-app.tsx +2 -0
  282. package/src/core/runtime/__tests__/runtime.test.ts +11 -0
  283. package/src/core/runtime/runtime.ts +7 -2
  284. package/src/core/wasm/bridge.ts +11 -0
  285. package/src/core/websocket/__tests__/useMarimoKernelConnection.hook.test.tsx +212 -2
  286. package/src/core/websocket/transports/transport.ts +1 -1
  287. package/src/core/websocket/transports/ws.ts +1 -1
  288. package/src/core/websocket/types.ts +11 -1
  289. package/src/core/websocket/useMarimoKernelConnection.tsx +43 -8
  290. package/src/css/app/Cell.css +2 -0
  291. package/src/hooks/useDebounce.ts +2 -0
  292. package/src/mount.tsx +3 -0
  293. package/src/plugins/core/BadPlugin.tsx +3 -14
  294. package/src/plugins/core/RenderHTML.tsx +22 -2
  295. package/src/plugins/core/__test__/RenderHTML.test.ts +187 -0
  296. package/src/plugins/core/registerReactComponent.tsx +0 -1
  297. package/src/plugins/impl/FormPlugin.tsx +2 -0
  298. package/src/plugins/impl/MatrixPlugin.tsx +2 -0
  299. package/src/plugins/impl/RangeSliderPlugin.tsx +2 -0
  300. package/src/plugins/impl/SliderPlugin.tsx +2 -0
  301. package/src/plugins/impl/data-editor/__tests__/glide-data-editor.test.tsx +23 -18
  302. package/src/plugins/impl/data-frames/panel.tsx +1 -0
  303. package/src/plugins/impl/image-comparison/ImageComparisonComponent.tsx +1 -1
  304. package/src/plugins/impl/image-comparison/__tests__/ImageComparisonComponent.test.tsx +15 -0
  305. package/src/plugins/layout/AccordionPlugin.tsx +7 -2
  306. package/src/plugins/layout/JsonOutputPlugin.tsx +7 -10
  307. package/src/plugins/layout/__test__/AccordionPlugin.test.tsx +66 -0
  308. package/src/stories/sandbox.stories.tsx +308 -0
  309. package/dist/ErrorBoundary-CR-ZQN_c.js +0 -125
  310. package/dist/_baseMerge-Dv8bBloN.js +0 -73
  311. package/dist/_initCloneObject---vediN2.js +0 -95
  312. package/dist/arc-DOVLrCPd.js +0 -82
  313. package/dist/architecture-TIHT7OUA-MiJpPpQW.js +0 -3
  314. package/dist/array-CApNbSU9.js +0 -6
  315. package/dist/assets/__vite-browser-external-BdKGjRZ4.js +0 -1
  316. package/dist/assets/worker-DlIBfp9S.js +0 -98
  317. package/dist/blockDiagram-VBNYF7ZC-Bc--I65C.js +0 -3158
  318. package/dist/chat-ui-DjTMZRVP.js +0 -8455
  319. package/dist/chunk-3NCLNEKW-BIp_lB_4.js +0 -14
  320. package/dist/chunk-5FCAYU7R-C_HO9A1J.js +0 -23
  321. package/dist/chunk-5HE753X5-Bixm_MV-.js +0 -38
  322. package/dist/chunk-5JV3BV7I-CH5J3iZY.js +0 -54
  323. package/dist/chunk-5TONJI2A-DG6gDiSS.js +0 -62
  324. package/dist/chunk-7BUUIJ7U-5afmIPeo.js +0 -82
  325. package/dist/chunk-BIQX33UG-7TMBUf89.js +0 -23
  326. package/dist/chunk-CQNSW5MT-Cnqqsxt-.js +0 -38
  327. package/dist/chunk-CYSBUYHQ-BAbymFHR.js +0 -23
  328. package/dist/chunk-EMLP6XTP-Bsz-QL77.js +0 -23
  329. package/dist/chunk-J7OUQ5F2-CM_meqZH.js +0 -57
  330. package/dist/chunk-JG7HCLWE-DUnCDgPk.js +0 -62
  331. package/dist/chunk-MOZMSUNE-BG6IHvzT.js +0 -35
  332. package/dist/chunk-OSBZ3O6U-CYwj_bvR.js +0 -23
  333. package/dist/chunk-QBLGF6JB-B4vJ4j8J.js +0 -23
  334. package/dist/chunk-QR6OTTB3-D4wH2ldi.js +0 -3738
  335. package/dist/chunk-R7FJI6CG-Blf8FcmZ.js +0 -64
  336. package/dist/chunk-RYQCIY6F-BWbIlBIH.js +0 -241
  337. package/dist/chunk-U6XO7XAA-COw445DS.js +0 -63
  338. package/dist/chunk-UBXNYLIW-BHigVU4H.js +0 -32
  339. package/dist/chunk-YOTPTUD7-Dn044Q_d.js +0 -30
  340. package/dist/chunk-ZIRB5QZD-BR4TMfOa.js +0 -1153
  341. package/dist/classDiagram-JCYQIIEL-DmXSLxe_.js +0 -30
  342. package/dist/classDiagram-v2-OCEON4UE-CooqVexA.js +0 -30
  343. package/dist/click-outside-container-D_URcm3D.js +0 -167
  344. package/dist/code-block-37QAKDTI-CQrzBOr-.js +0 -107
  345. package/dist/copy-CD7S58CY.js +0 -141
  346. package/dist/cynefin-VYW2F7L2-CeHAxOEX.js +0 -3
  347. package/dist/dagre-VZM6K2ZE-CJggWPTJ.js +0 -328
  348. package/dist/dist-3_o3T78I.js +0 -1360
  349. package/dist/dist-ABQjhuek.js +0 -64
  350. package/dist/dist-CO5R6VMi.js +0 -538
  351. package/dist/dropdown-menu-DhCfcscX.js +0 -5858
  352. package/dist/emotion-is-prop-valid.esm-M57VsT8j.js +0 -14
  353. package/dist/error-banner-CsXbEEjo.js +0 -611
  354. package/dist/eventmodeling-45OFAUF4-B_lWZ-Pd.js +0 -3
  355. package/dist/flowDiagram-UKHOOZJN-g1AmrZzM.js +0 -17
  356. package/dist/gitGraph-TEB2WS4Q-Dj-eXUph.js +0 -3
  357. package/dist/info-DKCQHKI2-Bhb-pe2e.js +0 -3
  358. package/dist/line-CuKjIQa1.js +0 -34
  359. package/dist/map-BJpOfPlL.js +0 -149
  360. package/dist/math-BXtKgYah.js +0 -10
  361. package/dist/mermaid-4DMBBIKO-Ddp9TgNp.js +0 -2
  362. package/dist/mermaid-Bi23Ibnw.js +0 -1173
  363. package/dist/mermaid-parser.core-Din9FvSi.js +0 -99
  364. package/dist/packet-7NZHBO7P-fbkIIyKE.js +0 -3
  365. package/dist/path-BNHuHZP8.js +0 -87
  366. package/dist/pie-RZYD4A2V-CLRIsxY1.js +0 -3
  367. package/dist/purify.es-CB-YO1Hn.js +0 -774
  368. package/dist/radar-I7S5WNFK-BGzCbgXu.js +0 -3
  369. package/dist/railroad-3IZDKUUU-CvQIIcuU.js +0 -3
  370. package/dist/railroad-abnf-AHOZXSZD-CMwtlNtu.js +0 -3
  371. package/dist/railroad-ebnf-EBAXGLYW-n1QUOAsh.js +0 -3
  372. package/dist/railroad-peg-LSFZ7HO6-PjnrpmCs.js +0 -3
  373. package/dist/schemas-DzK6U94N.js +0 -6057
  374. package/dist/stateDiagram-v2-UEYNNEHI-BTRUs8Il.js +0 -30
  375. package/dist/step-CKczO72Q.js +0 -670
  376. package/dist/swimlanesDiagram-ULZ7WXOC-NBmgBl9G.js +0 -31
  377. package/dist/timer-DpDyj9G0.js +0 -596
  378. package/dist/tooltip-Dt77sBeT.js +0 -390
  379. package/dist/treeView-QDETBFTQ-DU8LwHuf.js +0 -3
  380. package/dist/treemap-6X3UGDF4-DUk4-k_O.js +0 -3
  381. package/dist/useTheme-CVJ0UOf2.js +0 -841
  382. package/dist/vega-loader.browser-DEggZzni.js +0 -1083
  383. package/dist/wardley-OPB4EBWU-Db-AaGas.js +0 -3
  384. package/src/components/editor/output/EmotionCacheProvider.tsx +0 -32
@@ -640,6 +640,17 @@ export class PyodideBridge implements RunRequests, EditRequests {
640
640
  return response;
641
641
  };
642
642
 
643
+ getSandbox: EditRequests["getSandbox"] = async () => ({
644
+ backend: null,
645
+ manifest: null,
646
+ filename: null,
647
+ });
648
+ updateManifest: EditRequests["updateManifest"] = async () => {
649
+ throw new Error("Sandboxes are not supported in WebAssembly");
650
+ };
651
+ syncSandbox: EditRequests["syncSandbox"] = async () => {
652
+ throw new Error("Sandboxes are not supported in WebAssembly");
653
+ };
643
654
  getDependencyTree: EditRequests["getDependencyTree"] = async () => {
644
655
  // WASM doesn't support dependency trees yet
645
656
  return {
@@ -1,11 +1,25 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  // @vitest-environment jsdom
3
3
 
4
- import { act, renderHook } from "@testing-library/react";
4
+ import {
5
+ act,
6
+ fireEvent,
7
+ render,
8
+ renderHook,
9
+ screen,
10
+ } from "@testing-library/react";
5
11
  import { createStore, Provider as JotaiProvider } from "jotai";
6
12
  import type React from "react";
7
13
  import { ErrorBoundary } from "react-error-boundary";
8
- import { beforeEach, describe, expect, it, type Mock, vi } from "vitest";
14
+ import {
15
+ afterEach,
16
+ beforeEach,
17
+ describe,
18
+ expect,
19
+ it,
20
+ type Mock,
21
+ vi,
22
+ } from "vitest";
9
23
 
10
24
  vi.mock("@/core/websocket/useWebSocket", async () => {
11
25
  const actual =
@@ -26,6 +40,13 @@ vi.mock("@/core/runtime/config", async () => {
26
40
  };
27
41
  });
28
42
 
43
+ import { MockNotebook } from "@/__mocks__/notebook";
44
+ import { cellId } from "@/__tests__/branded";
45
+ import { notebookAtom } from "@/core/cells/cells";
46
+ import { AppConfigSchema } from "@/core/config/config-schema";
47
+ import { ConnectionNotice } from "@/components/editor/alerts/connection-notice";
48
+ import { kernelStartupErrorAtom } from "@/core/errors/state";
49
+ import type { NotificationPayload } from "@/core/kernel/messages";
29
50
  import { useRuntimeManager } from "@/core/runtime/config";
30
51
  import { initialRunCompletedAtom } from "../../kernel/state";
31
52
  import { connectionAtom } from "../../network/connection";
@@ -188,3 +209,192 @@ describe("useMarimoKernelConnection messages", () => {
188
209
  expect(store.get(initialRunCompletedAtom)).toBe(true);
189
210
  });
190
211
  });
212
+
213
+ it.each(["kernel-ready", "reconnected"])(
214
+ "waits for %s before marking the session connected",
215
+ async (op) => {
216
+ const store = createStore();
217
+ store.set(connectionAtom, { state: WebSocketState.CONNECTING });
218
+ vi.mocked(useConnectionTransport).mockClear();
219
+ vi.mocked(useConnectionTransport).mockReturnValue(
220
+ makeTransport(WebSocket.OPEN),
221
+ );
222
+ vi.mocked(useRuntimeManager).mockReturnValue(
223
+ makeRuntimeManager() as unknown as ReturnType<typeof useRuntimeManager>,
224
+ );
225
+ renderConnectionHook(store);
226
+ const options = vi.mocked(useConnectionTransport).mock.calls.at(-1)![0];
227
+
228
+ await act(async () => {
229
+ await options.onOpen(new Event("open"));
230
+ });
231
+ expect(store.get(connectionAtom).state).toBe(WebSocketState.CONNECTING);
232
+
233
+ act(() => {
234
+ options.onMessage(
235
+ new MessageEvent("message", {
236
+ data: JSON.stringify({
237
+ op,
238
+ data: {
239
+ op,
240
+ cell_ids: [],
241
+ codes: [],
242
+ names: [],
243
+ configs: [],
244
+ layout: null,
245
+ resumed: true,
246
+ ui_values: {},
247
+ last_executed_code: {},
248
+ last_execution_time: {},
249
+ app_config: { width: "normal" },
250
+ kiosk: false,
251
+ capabilities: { terminal: false },
252
+ auto_instantiated: false,
253
+ consumer_capabilities: { edit: true, interact: true },
254
+ },
255
+ }),
256
+ }),
257
+ );
258
+ });
259
+ expect(store.get(connectionAtom).state).toBe(WebSocketState.OPEN);
260
+ },
261
+ );
262
+
263
+ describe("connection notice", () => {
264
+ beforeEach(() => vi.useFakeTimers());
265
+ afterEach(() => vi.useRealTimers());
266
+
267
+ function renderNotice() {
268
+ const store = createStore();
269
+ store.set(connectionAtom, { state: WebSocketState.CONNECTING });
270
+ const transport = makeTransport(WebSocket.OPEN);
271
+ vi.mocked(useConnectionTransport).mockReturnValue(transport);
272
+ vi.mocked(useRuntimeManager).mockReturnValue(
273
+ makeRuntimeManager() as unknown as ReturnType<typeof useRuntimeManager>,
274
+ );
275
+ const Connection = () => {
276
+ const { reconnect } = useMarimoKernelConnection({
277
+ sessionId: "test-session" as SessionId,
278
+ autoInstantiate: false,
279
+ setCells: () => {},
280
+ });
281
+ return (
282
+ <ConnectionNotice
283
+ appConfig={AppConfigSchema.parse({})}
284
+ onRetry={reconnect}
285
+ />
286
+ );
287
+ };
288
+ render(
289
+ <JotaiProvider store={store}>
290
+ <ErrorBoundary fallback={null}>
291
+ <Connection />
292
+ </ErrorBoundary>
293
+ </JotaiProvider>,
294
+ );
295
+ const options = vi.mocked(useConnectionTransport).mock.calls.at(-1)![0];
296
+ const send = (data: NotificationPayload["data"]) =>
297
+ act(() => {
298
+ options.onMessage(
299
+ new MessageEvent("message", {
300
+ data: JSON.stringify({ op: data.op, data }),
301
+ }),
302
+ );
303
+ });
304
+ return { store, transport, options, send };
305
+ }
306
+
307
+ it("keeps elapsed time across startup phases and leaves reconnection to the footer once cells are available", () => {
308
+ const { store, options, send } = renderNotice();
309
+ send({ op: "startup-progress", phase: "preparing-environment" });
310
+ expect(
311
+ screen.queryByRole("region", { name: "Notebook startup" }),
312
+ ).not.toBeInTheDocument();
313
+ act(() => vi.advanceTimersByTime(500));
314
+ expect(screen.getByRole("status")).toHaveTextContent(
315
+ "Preparing environment",
316
+ );
317
+ act(() => vi.advanceTimersByTime(35_000));
318
+ expect(screen.getByText("Elapsed 35s")).toBeInTheDocument();
319
+ act(() =>
320
+ store.set(
321
+ notebookAtom,
322
+ MockNotebook.notebookState({
323
+ cellData: { [cellId("test")]: { code: "answer = 42" } },
324
+ }),
325
+ ),
326
+ );
327
+ send({ op: "startup-progress", phase: "starting-kernel" });
328
+ expect(screen.getByRole("status")).toHaveTextContent("Starting notebook");
329
+ expect(screen.getByText("Elapsed 35s")).toBeInTheDocument();
330
+ send({ op: "reconnected" });
331
+ expect(
332
+ screen.queryByRole("region", { name: "Notebook startup" }),
333
+ ).not.toBeInTheDocument();
334
+ act(() => options.onClose(new CloseEvent("close")));
335
+ act(() => vi.advanceTimersByTime(500));
336
+ expect(store.get(connectionAtom)).toEqual({
337
+ state: WebSocketState.CONNECTING,
338
+ phase: "reconnecting",
339
+ });
340
+ expect(
341
+ screen.queryByRole("region", { name: "Notebook startup" }),
342
+ ).not.toBeInTheDocument();
343
+ });
344
+
345
+ it("does not flash a notice when startup finishes within the delay", () => {
346
+ const { send } = renderNotice();
347
+ send({ op: "startup-progress", phase: "preparing-environment" });
348
+ act(() => vi.advanceTimersByTime(200));
349
+ send({ op: "startup-progress", phase: "starting-kernel" });
350
+ act(() => vi.advanceTimersByTime(200));
351
+ expect(
352
+ screen.queryByRole("region", { name: "Notebook startup" }),
353
+ ).not.toBeInTheDocument();
354
+ send({ op: "reconnected" });
355
+ act(() => vi.advanceTimersByTime(500));
356
+ expect(
357
+ screen.queryByRole("region", { name: "Notebook startup" }),
358
+ ).not.toBeInTheDocument();
359
+ });
360
+
361
+ it.each([
362
+ ["preparing-environment", "Sandbox setup failed"],
363
+ ["starting-kernel", "Kernel failed to start"],
364
+ ] as const)(
365
+ "keeps a %s failure available until the user retries",
366
+ async (phase, title) => {
367
+ const { store, transport, options, send } = renderNotice();
368
+ send({ op: "startup-progress", phase });
369
+ const error = "A full diagnostic\nwith <stderr> details";
370
+ send({ op: "kernel-startup-error", error });
371
+ transport.readyState = WebSocket.CLOSED;
372
+ act(() =>
373
+ options.onClose(
374
+ new CloseEvent("close", { reason: "MARIMO_KERNEL_STARTUP_ERROR" }),
375
+ ),
376
+ );
377
+ expect(screen.getByRole("status")).toHaveTextContent(title);
378
+ act(() => vi.advanceTimersByTime(30_000));
379
+ expect(screen.getByRole("status")).toHaveTextContent(title);
380
+ expect(screen.getByLabelText("Error details")).toHaveTextContent(error, {
381
+ normalizeWhitespace: false,
382
+ });
383
+ expect(transport.reconnect).not.toHaveBeenCalled();
384
+ await act(async () =>
385
+ fireEvent.click(screen.getByRole("button", { name: "Try again" })),
386
+ );
387
+ expect(transport.reconnect).toHaveBeenCalledOnce();
388
+ expect(store.get(kernelStartupErrorAtom)).toBeNull();
389
+ expect(
390
+ screen.queryByRole("button", { name: "Try again" }),
391
+ ).not.toBeInTheDocument();
392
+ send({ op: "startup-progress", phase: "preparing-environment" });
393
+ act(() => vi.advanceTimersByTime(500));
394
+ expect(screen.getByRole("status")).toHaveTextContent(
395
+ "Preparing environment",
396
+ );
397
+ expect(screen.getByText("Elapsed 0s")).toBeInTheDocument();
398
+ },
399
+ );
400
+ });
@@ -15,7 +15,7 @@ export type ConnectionTransportCallback<T extends ConnectionEvent> = (
15
15
  export interface IConnectionTransport {
16
16
  reconnect(code?: number | undefined, reason?: string | undefined): void;
17
17
  close(): void;
18
- send(data: string | ArrayBuffer | Blob | ArrayBufferView): void;
18
+ send(data: string | ArrayBuffer | Blob | ArrayBufferView<ArrayBuffer>): void;
19
19
  addEventListener<T extends ConnectionEvent>(
20
20
  event: T,
21
21
  callback: ConnectionTransportCallback<T>,
@@ -42,7 +42,7 @@ export class WsTransport implements IConnectionTransport {
42
42
  this.inner.close();
43
43
  }
44
44
 
45
- send(data: string | ArrayBuffer | Blob | ArrayBufferView): void {
45
+ send(data: string | ArrayBuffer | Blob | ArrayBufferView<ArrayBuffer>): void {
46
46
  this.inner.send(data);
47
47
  }
48
48
 
@@ -1,5 +1,11 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
+ import type { NotificationMessageData } from "../kernel/messages";
4
+
5
+ type ConnectionPhase =
6
+ | NotificationMessageData<"startup-progress">["phase"]
7
+ | "reconnecting";
8
+
3
9
  // TODO: rename to ConnectionState
4
10
  export const WebSocketState = {
5
11
  NOT_STARTED: "NOT_STARTED",
@@ -28,10 +34,14 @@ export type ConnectionStatus =
28
34
  * Human-readable reason for closing the connection.
29
35
  */
30
36
  reason: string;
37
+ phase?: ConnectionPhase;
38
+ }
39
+ | {
40
+ state: typeof WebSocketState.CONNECTING;
41
+ phase?: ConnectionPhase;
31
42
  }
32
43
  | {
33
44
  state:
34
- | typeof WebSocketState.CONNECTING
35
45
  | typeof WebSocketState.OPEN
36
46
  | typeof WebSocketState.CLOSING
37
47
  | typeof WebSocketState.NOT_STARTED;
@@ -1,5 +1,6 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
+ import { invalidatePackageData } from "@/core/packages/package-data";
3
4
  import { useAtom, useAtomValue, useSetAtom } from "jotai";
4
5
  import { useRef } from "react";
5
6
  import { useErrorBoundary } from "react-error-boundary";
@@ -240,7 +241,15 @@ export function useMarimoKernelConnection(opts: {
240
241
  case "reload":
241
242
  reloadSafe();
242
243
  return;
244
+ case "startup-progress":
245
+ setConnection({
246
+ state: WebSocketState.CONNECTING,
247
+ phase: msg.data.phase,
248
+ });
249
+ return;
243
250
  case "kernel-ready": {
251
+ setKernelStartupError(null);
252
+ setConnection({ state: WebSocketState.OPEN });
244
253
  setInitialRunCompleted(
245
254
  Boolean(msg.data.resumed || msg.data.auto_instantiated),
246
255
  );
@@ -363,6 +372,16 @@ export function useMarimoKernelConnection(opts: {
363
372
  });
364
373
  return;
365
374
  case "installing-package-alert":
375
+ if (
376
+ msg.data.source !== "server" &&
377
+ msg.data.log_status !== "append" &&
378
+ msg.data.log_status !== "start" &&
379
+ Object.values(msg.data.packages).some(
380
+ (status) => status === "installed" || status === "restart-required",
381
+ )
382
+ ) {
383
+ invalidatePackageData();
384
+ }
366
385
  addPackageAlert({
367
386
  ...msg.data,
368
387
  kind: "installing",
@@ -439,6 +458,8 @@ export function useMarimoKernelConnection(opts: {
439
458
  return;
440
459
 
441
460
  case "reconnected":
461
+ setKernelStartupError(null);
462
+ setConnection({ state: WebSocketState.OPEN });
442
463
  return;
443
464
 
444
465
  case "focus-cell":
@@ -482,6 +503,7 @@ export function useMarimoKernelConnection(opts: {
482
503
  return;
483
504
  }
484
505
  shouldTryReconnecting.current = true;
506
+ setKernelStartupError(null);
485
507
  setConnection({ state: WebSocketState.CONNECTING });
486
508
  const healthy = await runtimeManager.reconcileFromHealth();
487
509
  if (!healthy) {
@@ -513,17 +535,11 @@ export function useMarimoKernelConnection(opts: {
513
535
  headers: () => runtimeManager.headers(),
514
536
 
515
537
  /**
516
- * Open callback. Set the connection status to open.
538
+ * The transport is open; kernel-ready establishes session readiness.
517
539
  */
518
540
  onOpen: async () => {
519
541
  // If we are open, we can reset our reconnecting flag.
520
542
  shouldTryReconnecting.current = true;
521
-
522
- // DO NOT COMMIT THIS UNCOMMENTED
523
- // Uncomment to emulate a slow connection
524
- // await new Promise((resolve) => setTimeout(resolve, 10_000));
525
-
526
- setConnection({ state: WebSocketState.OPEN });
527
543
  },
528
544
 
529
545
  /**
@@ -565,7 +581,26 @@ export function useMarimoKernelConnection(opts: {
565
581
  onClose: (e) => {
566
582
  Logger.warn("WebSocket closed", e.code, e.reason);
567
583
  const decision = classifyCloseEvent(e);
568
- setConnection(decision.status);
584
+ setConnection((previous) => {
585
+ const status = decision.status;
586
+ if (
587
+ status.state === WebSocketState.CLOSED &&
588
+ status.code === WebSocketClosedReason.KERNEL_STARTUP_ERROR &&
589
+ (previous.state === WebSocketState.CONNECTING ||
590
+ previous.state === WebSocketState.CLOSED)
591
+ ) {
592
+ return { ...status, phase: previous.phase };
593
+ }
594
+ if (
595
+ status.state === WebSocketState.CONNECTING &&
596
+ (previous.state === WebSocketState.OPEN ||
597
+ (previous.state === WebSocketState.CONNECTING &&
598
+ previous.phase === "reconnecting"))
599
+ ) {
600
+ return { ...status, phase: "reconnecting" };
601
+ }
602
+ return status;
603
+ });
569
604
  if (decision.kind === "terminal" && decision.closeTransport) {
570
605
  ws.close(); // close to prevent reconnecting
571
606
  return;
@@ -82,6 +82,7 @@
82
82
  .console-output-area {
83
83
  max-height: 610px;
84
84
  overflow: auto;
85
+ overscroll-behavior: contain;
85
86
  }
86
87
 
87
88
  /* Special case for particular components */
@@ -521,6 +522,7 @@
521
522
  display: flow-root;
522
523
 
523
524
  overflow: auto;
525
+ overscroll-behavior: contain;
524
526
  }
525
527
 
526
528
  .marimo-output-stale,
@@ -48,6 +48,8 @@ export function useDebounceControlledState<T>(opts: {
48
48
 
49
49
  // Handle external changes:
50
50
  useEffect(() => {
51
+ // TODO: Replace this synchronization with a controlled-state primitive.
52
+ // oxlint-disable-next-line react/no-deriving-state-in-effects -- Synchronize the debounced draft when the controlled value changes.
51
53
  setInternalValue(initialValue);
52
54
  }, [initialValue]);
53
55
 
package/src/mount.tsx CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  userConfigAtom,
11
11
  } from "@/core/config/config";
12
12
  import { KnownQueryParams } from "@/core/constants";
13
+ import { pairPreviewAtom, pairPreviewSchema } from "@/core/config/pair";
13
14
  import { getFilenameFromDOM } from "@/core/dom/htmlUtils";
14
15
  import { getMarimoCode } from "@/core/meta/globals";
15
16
  import {
@@ -208,6 +209,7 @@ const mountOptionsSchema = z.object({
208
209
  * marimo config overrides
209
210
  */
210
211
  configOverrides: passthroughObject,
212
+ pairPreview: pairPreviewSchema.optional(),
211
213
  /**
212
214
  * marimo app config
213
215
  */
@@ -345,6 +347,7 @@ function initStore(options: unknown) {
345
347
  );
346
348
  store.set(userConfigAtom, parseUserConfig(parsedOptions.data.config));
347
349
  store.set(appConfigAtom, parseAppConfig(parsedOptions.data.appConfig));
350
+ store.set(pairPreviewAtom, parsedOptions.data.pairPreview);
348
351
 
349
352
  // Runtime config
350
353
  if (parsedOptions.data.runtimeConfig.length > 0) {
@@ -9,21 +9,15 @@ const AccordionTrigger = AccordionPrimitive.Trigger;
9
9
 
10
10
  import type { JSX } from "react";
11
11
  import { ZodError } from "zod";
12
- import { EmotionCacheProvider } from "@/components/editor/output/EmotionCacheProvider";
13
12
  import { JsonOutput } from "@/components/editor/output/JsonOutput";
14
13
  import { Alert, AlertTitle } from "../../components/ui/alert";
15
14
 
16
15
  interface Props {
17
16
  error: ZodError | Error;
18
- shadowRoot: ShadowRoot | null;
19
17
  badData: Record<string, unknown>;
20
18
  }
21
19
 
22
- export const BadPluginData: React.FC<Props> = ({
23
- error,
24
- badData,
25
- shadowRoot,
26
- }) => {
20
+ export const BadPluginData: React.FC<Props> = ({ error, badData }) => {
27
21
  if (error instanceof ZodError) {
28
22
  return (
29
23
  <Alert variant="destructive">
@@ -49,9 +43,7 @@ export const BadPluginData: React.FC<Props> = ({
49
43
  View Data:
50
44
  </AccordionTrigger>
51
45
  <AccordionContent className="text-[0.84375rem]">
52
- <EmotionCacheProvider container={shadowRoot}>
53
- <JsonOutput data={badData} />
54
- </EmotionCacheProvider>
46
+ <JsonOutput data={badData} />
55
47
  </AccordionContent>
56
48
  </AccordionItem>
57
49
  </Accordion>
@@ -65,9 +57,6 @@ export const BadPluginData: React.FC<Props> = ({
65
57
  export function renderError(
66
58
  error: ZodError | Error,
67
59
  badData: Record<string, unknown>,
68
- shadowRoot: ShadowRoot | null,
69
60
  ): JSX.Element {
70
- return (
71
- <BadPluginData error={error} badData={badData} shadowRoot={shadowRoot} />
72
- );
61
+ return <BadPluginData error={error} badData={badData} />;
73
62
  }
@@ -262,9 +262,29 @@ const wrapTooltipTargets: TransformFn = (
262
262
  if (tagName.startsWith("marimo-")) {
263
263
  return undefined;
264
264
  }
265
- const tooltipContent = domNode.attribs["data-tooltip"];
265
+ const tooltipContent = domNode.attribs["data-tooltip"].replace(
266
+ /^[\r\n]+|[\r\n]+$/g,
267
+ "",
268
+ );
266
269
  return (
267
- <Tooltip content={tooltipContent}>{reactNode as JSX.Element}</Tooltip>
270
+ <Tooltip
271
+ content={
272
+ tooltipContent.includes("\n") ? (
273
+ <span className="whitespace-pre-wrap">
274
+ {tooltipContent.split(/\r?\n/).map((line, i) => (
275
+ <React.Fragment key={i}>
276
+ {i > 0 && <br />}
277
+ {line}
278
+ </React.Fragment>
279
+ ))}
280
+ </span>
281
+ ) : (
282
+ tooltipContent
283
+ )
284
+ }
285
+ >
286
+ {reactNode as JSX.Element}
287
+ </Tooltip>
268
288
  );
269
289
  }
270
290
  };