@marimo-team/islands 0.24.3-dev2 → 0.24.3-dev22

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 (284) hide show
  1. package/dist/{ConnectedDataExplorerComponent-qIKbwYin.js → ConnectedDataExplorerComponent-BLO7UDpo.js} +18 -18
  2. package/dist/{ErrorBoundary-CR-ZQN_c.js → ErrorBoundary-B7uSdDUm.js} +6 -6
  3. package/dist/{ImageComparisonComponent-2a9TMMm2.js → ImageComparisonComponent-RspMflu6.js} +3 -3
  4. package/dist/{Plot-C-9MQeGP.js → Plot-CTyjbQDT.js} +21032 -20666
  5. package/dist/_baseMerge-Bnytch8P.js +165 -0
  6. package/dist/{abnfDiagram-N423BO3Z-CQKwzX8t.js → abnfDiagram-VCTEODGH-DCb2K_RB.js} +17 -18
  7. package/dist/{any-language-editor-CpTnK43-.js → any-language-editor-C0dftc2Z.js} +8 -8
  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-Bb_n642s.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/{channel-CyiYUzJv.js → channel-B5XnTarr.js} +1 -1
  18. package/dist/chat-ui-Cn1TFk66.js +5835 -0
  19. package/dist/{check-CHig47QV.js → check-mcQyZmFG.js} +1 -1
  20. package/dist/{chunk-2Q5K7J3B-BMuJl2jB.js → chunk-2Q5K7J3B-BMkUkeuy.js} +2 -2
  21. package/dist/chunk-4HAMMTFA-D2qv8E0X.js +4188 -0
  22. package/dist/{chunk-5VM5RSS4-Bcq0ftdy.js → chunk-5VM5RSS4-DKsmPCL6.js} +2 -2
  23. package/dist/{chunk-NSK5VX7P-CDTMcJB0.js → chunk-75Z2AOVW-5_HsvXwr.js} +23 -23
  24. package/dist/{chunk-I66GZJ75-BqyTCAPf.js → chunk-DU6HZSFF-BUgAHvnM.js} +21 -4
  25. package/dist/{chunk-2GRJ4B5K-DgO8Qudq.js → chunk-F27PBJKO-DHmYWZXr.js} +4 -4
  26. package/dist/{chunk-KEIR6QF5-C4KX3XYh.js → chunk-FOHPRMQF-BpYR8RqP.js} +4 -4
  27. package/dist/{chunk-WRU74C26-BpWsbiDK.js → chunk-GMAD6QVW-Czynz8aA.js} +486 -258
  28. package/dist/chunk-GVQU2GXP-yQEdulRS.js +37 -0
  29. package/dist/{chunk-5RXB4S5H-tLNUVDdO.js → chunk-IMKFNOWR-Du9BN2Ul.js} +11 -11
  30. package/dist/{chunk-JWPE2WC7-BJwjGUnF.js → chunk-JWPE2WC7-DJvv1t8U.js} +2 -2
  31. package/dist/chunk-L3NEJ4N5-DwRWnDDK.js +245 -0
  32. package/dist/{chunk-7Z6QIM7H-Dc18hFxH.js → chunk-OSK3NFVY-BBKU_Ign.js} +222 -144
  33. package/dist/{chunk-W5SLKNZC-DLnvpEtV.js → chunk-P2QGCYS3-C0iGU29N.js} +20 -20
  34. package/dist/{chunk-KBJHAD2P-BuqWqkcW.js → chunk-POPQ4Y6H-BCbS3Ozc.js} +4 -4
  35. package/dist/{chunk-4I5QYGJK-DpytHuZQ.js → chunk-PWAF6VOD-CTFCL0jI.js} +4 -4
  36. package/dist/{chunk-JQJVKLGR-CgqCwe8E.js → chunk-SHT3W25Y-tUelricH.js} +109 -63
  37. package/dist/{chunk-6Q2QTUOP-DmTcEBMn.js → chunk-SVP7TREG-DK3egkfQ.js} +5 -5
  38. package/dist/{chunk-GF5L2VYU-B0wgCQgS.js → chunk-TICWLB2K-DRANTdnp.js} +13 -13
  39. package/dist/{chunk-XXDRQBXY-D73H4IN0.js → chunk-XXDRQBXY-Dnl5VBqG.js} +3 -3
  40. package/dist/{chunk-Y2CYZVJY-DoegUj_e.js → chunk-Y2CYZVJY-DKKS1VyV.js} +1 -1
  41. package/dist/{chunk-5FQGJX7Z-B85XCPv6.js → chunk-YOKDWASO-DrWbKnxA.js} +6925 -5460
  42. package/dist/classDiagram-ZZMXUADV-7wCSVH7o.js +30 -0
  43. package/dist/classDiagram-v2-VYDZK3BY-QwnvcnhB.js +30 -0
  44. package/dist/{common-C4UahYwr.js → common-DIyUaEO6.js} +7398 -6912
  45. package/dist/{compiler-runtime-CAH9RLw2.js → compiler-runtime-Cj8ZWiNS.js} +2 -2
  46. package/dist/{copy-CD7S58CY.js → copy-C0N4m1lm.js} +4 -4
  47. package/dist/{cose-bilkent-JH36ORCC-FUWHkXFX.js → cose-bilkent-JH36ORCC-_LyRKVqm.js} +2 -2
  48. package/dist/cubic-OaEBhQPK.js +1404 -0
  49. package/dist/cynefin-OW5HDTMX-obq-i80l.js +3 -0
  50. package/dist/{cynefinDiagram-MW4NZA55-BXSFK93J.js → cynefinDiagram-5FMLGOSQ-CB7O4IZB.js} +10 -10
  51. package/dist/{dagre-CGyalH38.js → dagre-DfYd3btw.js} +678 -537
  52. package/dist/dagre-GXQ25YYZ-C-a95ISW.js +425 -0
  53. package/dist/{data-grid-overlay-editor-DZM4BAaI.js → data-grid-overlay-editor-C5eUZVTo.js} +8 -9
  54. package/dist/{data-grid-types-BnZwWG8z.js → data-grid-types-BucVmDDp.js} +1 -1
  55. package/dist/{defaultLocale-DKaU_opG.js → defaultLocale-JI_lnoCe.js} +1 -1
  56. package/dist/{diagram-7IWD3JNH-BjfzDNvj.js → diagram-S7CK7UJ4-BsKLYQaH.js} +40 -39
  57. package/dist/{diagram-UB23O5K3-DDg-7wLA.js → diagram-UQ7AKVKN-ppYdvuTN.js} +10 -10
  58. package/dist/{diagram-B4RE2ZJO-CKccR9eE.js → diagram-VSXAHHWV-BKpmG23x.js} +10 -10
  59. package/dist/{diagram-Q27KOJAE-Zhz01ss7.js → diagram-VX7I27RA-CAMK2l0E.js} +21 -21
  60. package/dist/{diagram-LBJQPF4R-CJ-bOruh.js → diagram-Z3DM3KII-CxQ7MggT.js} +10 -10
  61. package/dist/{dist-dAqZAPcF.js → dist-1HDa70oE.js} +3 -3
  62. package/dist/{dist-3_o3T78I.js → dist-6ChWbo8z.js} +13 -13
  63. package/dist/{dist-Re9sOPOx.js → dist-9x1ZRe-e.js} +2 -2
  64. package/dist/{dist-DEeLqRlU.js → dist-B1vYLK28.js} +1 -1
  65. package/dist/{dist-C5Bn52W4.js → dist-B8D7McG3.js} +3 -3
  66. package/dist/{dist-_XvgytiS.js → dist-BHCHt1NI.js} +1 -1
  67. package/dist/{dist-CRjAdnqF.js → dist-BRxfaJgs.js} +3 -3
  68. package/dist/{dist-Byj2bV8o.js → dist-BVGtK7Ht.js} +1 -1
  69. package/dist/{dist-BIN5LKyE.js → dist-BaHjhkpZ.js} +2 -2
  70. package/dist/{dist-DVFbIwc5.js → dist-BtKIs9N-.js} +1 -1
  71. package/dist/{dist-BrQGcfQ9.js → dist-C2KzV-vf.js} +2 -2
  72. package/dist/{dist-DJFiGP2k.js → dist-C2wDlYdD.js} +2 -2
  73. package/dist/{dist-BVRM2y1P.js → dist-C8xMLVYi.js} +2 -2
  74. package/dist/dist-CMh_W4y4.js +538 -0
  75. package/dist/{dist-BzN60Z2s.js → dist-CPGxfVGX.js} +1 -1
  76. package/dist/{dist-C7v-9nUK.js → dist-Cm3iAFMD.js} +3 -3
  77. package/dist/{dist-CGAxEiaM.js → dist-Cs2FijYk.js} +2 -2
  78. package/dist/{dist-hXd65f0_.js → dist-D1PpnuZB.js} +1 -1
  79. package/dist/{dist-VdvbxG72.js → dist-DHOTQar0.js} +1 -1
  80. package/dist/{dist-DcgzXCfy.js → dist-DPcEtqmG.js} +2 -2
  81. package/dist/{dist-D4Z_qdP4.js → dist-Df0wKI0F.js} +1 -1
  82. package/dist/{dist-qhLI-SHd.js → dist-DszxuxS1.js} +2 -2
  83. package/dist/{dist-BEmkrGoQ.js → dist-Kxgjxakw.js} +1 -1
  84. package/dist/{dist-BbSMhhD2.js → dist-KzZ7WELx.js} +2 -2
  85. package/dist/{dist-jWUab2d1.js → dist-lA1Cttkb.js} +1 -1
  86. package/dist/{dropdown-menu-DhCfcscX.js → dropdown-menu-C73aTomr.js} +184 -184
  87. package/dist/{ebnfDiagram-BXEA7PRR-Dm75pCAS.js → ebnfDiagram-PWID7BFC-DzybELvk.js} +17 -18
  88. package/dist/{erDiagram-JOGREHBK-rVDG3VSQ.js → erDiagram-RLTQ6QDP-BVxV97ld.js} +1037 -798
  89. package/dist/{error-banner-WDhUzJyg.js → error-banner-hCaH06e3.js} +207 -207
  90. package/dist/{esm-CR1nhb1c.js → esm-BElI3qKH.js} +22 -22
  91. package/dist/{esm-C1d0g6Bv.js → esm-G4Fhsgng.js} +51 -37
  92. package/dist/{esm-CesmlDrs.js → esm-blALgIVy.js} +332 -319
  93. package/dist/eventmodeling-NTZA5JFV-D7nP7Uyu.js +3 -0
  94. package/dist/{extends-BPB6_lTK.js → extends-Do6pRuJa.js} +8 -8
  95. package/dist/flowDiagram-HODETNUW-BKvXsWYX.js +16 -0
  96. package/dist/{formats-CJMVUfb3.js → formats-vDAoRpYs.js} +8 -8
  97. package/dist/{ganttDiagram-PKOTCBZU-9D-LXF6P.js → ganttDiagram-EL5Y4UJY-DbzEBLbl.js} +15 -15
  98. package/dist/gitGraph-4MIJSDKK-Dy9uQXGh.js +3 -0
  99. package/dist/{gitGraphDiagram-DS77QQ5N-BfpsXTLf.js → gitGraphDiagram-WWUBYQGX-BMf0iKi1.js} +10 -10
  100. package/dist/{glide-data-editor-sPZ8fUFn.js → glide-data-editor-Bcy8iaZa.js} +2785 -2562
  101. package/dist/{glide-utils-NShAPPtn.js → glide-utils-BMnFm0vZ.js} +4 -4
  102. package/dist/highlighted-body-KPVGNVTW-Ad3MKZ18.js +38 -0
  103. package/dist/{html-to-image-BTYnN4ev.js → html-to-image-CSU-_5BI.js} +5716 -5451
  104. package/dist/info-A6RAGUB7-DKoayiHY.js +3 -0
  105. package/dist/{infoDiagram-6WML65LV-DqCTXHVy.js → infoDiagram-27XIBGKW-B_ucqo-U.js} +7 -7
  106. package/dist/{ishikawaDiagram-WSZJBQD7-BCUYmZ1v.js → ishikawaDiagram-5VMMS53U-BZFx9b-o.js} +8 -8
  107. package/dist/{journeyDiagram-NVQOT4AX-BXB6M4zN.js → journeyDiagram-3NMN7TZE-D2LcKDUO.js} +8 -8
  108. package/dist/{jsx-runtime-CpoKNRgu.js → jsx-runtime-DgDPJV9S.js} +1 -1
  109. package/dist/{kanban-definition-27J2QSJJ-CGRhrDUX.js → kanban-definition-UXKFOSKX-BpIfcu3G.js} +29 -29
  110. package/dist/katex-DFBiSucW.js +21840 -0
  111. package/dist/{label-lwzzBHUW.js → label-e37ixur5.js} +6 -6
  112. package/dist/{linear-D5r_1YqD.js → linear-Cnaq3Tfb.js} +4 -4
  113. package/dist/{loader-VZ__bv4g.js → loader-D2W4oM-3.js} +15 -15
  114. package/dist/main.js +7018 -12382
  115. package/dist/mermaid-B1Jb9HfY.js +3084 -0
  116. package/dist/mermaid-HWGCJPDP-DYCzSILp.js +2 -0
  117. package/dist/mermaid-parser.core-DxuSfYwJ.js +638 -0
  118. package/dist/{mhchem-BjwrxcV-.js → mhchem-DWCF06w9.js} +1 -1
  119. package/dist/{micromark-factory-space-DruVGzeG.js → micromark-factory-space-DGxAzmw8.js} +2 -2
  120. package/dist/{mindmap-definition-FAOFIHXS-C9gRhzZq.js → mindmap-definition-YA3MSWOX-CmpAfv8K.js} +17 -17
  121. package/dist/{node-sql-parser-DesT1xNw.js → node-sql-parser-BiZOJ-FS.js} +0 -3
  122. package/dist/{number-overlay-editor-De2CabLL.js → number-overlay-editor-CFofZaOi.js} +5 -5
  123. package/dist/packet-AYTQ26CC-Yw7ajchJ.js +3 -0
  124. package/dist/{pegDiagram-VL7TDLO6-Df9IUjMD.js → pegDiagram-XKGWAZYB-DO-0Q8SE.js} +19 -20
  125. package/dist/{pick-SnHlmIBN.js → pick-B7vX8zxG.js} +1 -1
  126. package/dist/pie-WAS4IAKB-BKdKOAkL.js +3 -0
  127. package/dist/{pieDiagram-7S7Q4E2Y-BmRzQ8ZP.js → pieDiagram-E7YTZNPT-B1MbuA_g.js} +29 -31
  128. package/dist/{process-output-CsALk6tp.js → process-output-B6HE2ojm.js} +4 -4
  129. package/dist/purify.es-DgKyQviY.js +805 -0
  130. package/dist/{quadrantDiagram-CIZ2JOQS-wFBvWcxS.js → quadrantDiagram-AXDQQJYC-DftINo6g.js} +5 -5
  131. package/dist/radar-RG4KPBEZ-ScR_D_Ts.js +3 -0
  132. package/dist/railroad-74A4TZTK-DQvPSdo5.js +3 -0
  133. package/dist/railroad-abnf-HS5TGJTU-CsJQG2O8.js +3 -0
  134. package/dist/railroad-ebnf-LZEXJU2U-BgEobkSn.js +3 -0
  135. package/dist/railroad-peg-WCYAUIDC-DjLAjofI.js +3 -0
  136. package/dist/{railroadDiagram-AXF67PYL-DxbIatiN.js → railroadDiagram-O6MQD6OU-DPVOQUXC.js} +17 -18
  137. package/dist/{react-dom-C94wmq5w.js → react-dom-BUgJ-ab_.js} +3 -3
  138. package/dist/{react-DMWcHin-.js → react-ofJbxM4x.js} +2 -2
  139. package/dist/{react-vega-DSD5aT7_.js → react-vega-5AcMW8gG.js} +10012 -9369
  140. package/dist/{requirementDiagram-LRYGKXZP-X_x-Y713.js → requirementDiagram-BXWQKSXE-CC7wZ-tM.js} +20 -19
  141. package/dist/{reveal-component-ChYEzi00.js → reveal-component-GEGc56E6.js} +1171 -1105
  142. package/dist/{sankeyDiagram-W5VNT64P-BYJALbbm.js → sankeyDiagram-P5KCCOFB-CDKR5TJH.js} +4 -4
  143. package/dist/schemas-BDZr-nP0.js +5727 -0
  144. package/dist/{select-3qHpFKF9.js → select-UMOSCa3W.js} +246 -246
  145. package/dist/{sequenceDiagram-SI44F4Z6-BiPBe3Sv.js → sequenceDiagram-WJ2MYXX4-DomSyoJI.js} +11 -11
  146. package/dist/{sizeCapture-X5ZJPWSS-BKLDeh5H.js → sizeCapture-INFHLROL-Dx5SpkQF.js} +2 -2
  147. package/dist/{spec-CutWdqo3.js → spec-g740fOWu.js} +4 -4
  148. package/dist/{src-C31ngt98.js → src-CA_m4ONl.js} +298 -303
  149. package/dist/{stateDiagram-OKZ733FA-B7QyNBxH.js → stateDiagram-D77RDMKH-SQLLjdtF.js} +19 -20
  150. package/dist/stateDiagram-v2-MP3YSRHH-Dup4KkIr.js +30 -0
  151. package/dist/style.css +2 -2
  152. package/dist/{swimlanes-SLNWSIFB-B4f8VP3b.js → swimlanes-42K2YHIH-ZXbhyGv6.js} +1501 -1591
  153. package/dist/swimlanesDiagram-VR7AAH4N-CluwxV0g.js +30 -0
  154. package/dist/{swiper-component-C90YjhaV.js → swiper-component-IOUowglM.js} +39 -26
  155. package/dist/{time-aWGfjN8x.js → time-BieKwdYS.js} +42 -42
  156. package/dist/{timeline-definition-Z64GVDOM-Dacq_5lr.js → timeline-definition-24CTP7MA-B8i6B9RR.js} +7 -7
  157. package/dist/{toDate-D-Rx3ux5.js → toDate-C3JOXlJT.js} +10 -9
  158. package/dist/{tooltip-Dt77sBeT.js → tooltip-CdE8k0pS.js} +42 -42
  159. package/dist/treeView-Q6P3EWNA-DuRV97YF.js +3 -0
  160. package/dist/treemap-WGGIJYW6-AsLq-uwC.js +3 -0
  161. package/dist/{use-vega-container-remeasure-DUW4tRxq.js → use-vega-container-remeasure-4DwJbPWu.js} +2 -2
  162. package/dist/{useAsyncData-CH6-CgJF.js → useAsyncData-C0f7qnnN.js} +3 -3
  163. package/dist/{useDateFormatter-Cp9Jdxls.js → useDateFormatter-BKpQHt-W.js} +8 -8
  164. package/dist/{useDeepCompareMemoize-JC87C_jO.js → useDeepCompareMemoize-QCa0HbWB.js} +2 -2
  165. package/dist/{useIframeCapabilities-De3C-9b4.js → useIframeCapabilities-CVtNkI3Y.js} +2 -2
  166. package/dist/{useLifecycle-B4RGlyf0.js → useLifecycle-BGRBkTFT.js} +6 -6
  167. package/dist/useTheme-iQ0VoptU.js +904 -0
  168. package/dist/{vega-component-D-IXRnlx.js → vega-component-DRI4BDLQ.js} +15 -15
  169. package/dist/{vega-embed-container-TJ5z5dZw.js → vega-embed-container-CbnTccZi.js} +6 -6
  170. package/dist/vega-loader.browser-D95WfUcj.js +1139 -0
  171. package/dist/{vennDiagram-T6HMQDX7-D-Rcq3Iu.js → vennDiagram-4TSXK5OY-CS7lHhxI.js} +9 -9
  172. package/dist/wardley-WFR3VGLG-Na-tFhQJ.js +3 -0
  173. package/dist/{wardleyDiagram-T6FBY63Y-Z-Og7_Wd.js → wardleyDiagram-VM6X3IG4-BSm-L8JI.js} +10 -10
  174. package/dist/{xychartDiagram-ELKLHX3M-BDJ2dITA.js → xychartDiagram-S5SC5T6Z-8fKCJGrJ.js} +248 -139
  175. package/package.json +52 -52
  176. package/src/__mocks__/requests.ts +7 -2
  177. package/src/__tests__/__snapshots__/CellStatus.test.tsx.snap +12 -12
  178. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +2 -6
  179. package/src/components/data-table/column-visibility-dropdown.tsx +9 -3
  180. package/src/components/datasources/components.tsx +4 -2
  181. package/src/components/editor/chrome/components/feedback-button.tsx +10 -9
  182. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +143 -0
  183. package/src/components/editor/chrome/panels/packages-panel.tsx +145 -51
  184. package/src/components/editor/code/__tests__/readonly-diff.test.tsx +65 -0
  185. package/src/components/editor/code/readonly-diff.tsx +1 -1
  186. package/src/components/editor/file-tree/__tests__/tree-actions.test.tsx +54 -0
  187. package/src/components/editor/file-tree/tree-actions.tsx +11 -14
  188. package/src/components/editor/output/Outputs.css +1 -0
  189. package/src/components/editor/package-alert.tsx +25 -1
  190. package/src/components/home/components.tsx +17 -0
  191. package/src/components/pages/gallery-page.tsx +2 -4
  192. package/src/components/pages/home-page.tsx +2 -4
  193. package/src/components/terminal/terminal.tsx +4 -4
  194. package/src/components/tracing/tracing-spec.ts +1 -1
  195. package/src/components/ui/table.tsx +1 -1
  196. package/src/core/cells/pending-delete-service.ts +12 -16
  197. package/src/core/codemirror/language/__tests__/sql.test.ts +70 -2
  198. package/src/core/codemirror/language/languages/sql/sql.ts +16 -1
  199. package/src/core/codemirror/rtc/extension.ts +5 -2
  200. package/src/core/datasets/__tests__/data-source.test.ts +2 -0
  201. package/src/core/datasets/data-source-connections.ts +15 -10
  202. package/src/core/islands/__tests__/parse.test.ts +140 -7
  203. package/src/core/islands/parse.ts +20 -0
  204. package/src/core/packages/__tests__/useInstallPackage.test.tsx +47 -1
  205. package/src/core/packages/toast-components.tsx +26 -0
  206. package/src/core/packages/useInstallPackage.ts +7 -2
  207. package/src/core/runtime/__tests__/runtime.test.ts +11 -0
  208. package/src/core/runtime/runtime.ts +7 -2
  209. package/src/core/wasm/bridge.ts +1 -0
  210. package/src/core/websocket/transports/transport.ts +1 -1
  211. package/src/core/websocket/transports/ws.ts +1 -1
  212. package/src/css/app/Cell.css +2 -0
  213. package/src/plugins/core/RenderHTML.tsx +22 -2
  214. package/src/plugins/core/__test__/RenderHTML.test.ts +187 -0
  215. package/src/plugins/layout/AccordionPlugin.tsx +7 -2
  216. package/src/plugins/layout/__test__/AccordionPlugin.test.tsx +66 -0
  217. package/dist/_baseMerge-Dv8bBloN.js +0 -73
  218. package/dist/_initCloneObject---vediN2.js +0 -95
  219. package/dist/arc-DOVLrCPd.js +0 -82
  220. package/dist/architecture-TIHT7OUA-MiJpPpQW.js +0 -3
  221. package/dist/array-CApNbSU9.js +0 -6
  222. package/dist/assets/__vite-browser-external-BdKGjRZ4.js +0 -1
  223. package/dist/assets/worker-DlIBfp9S.js +0 -98
  224. package/dist/blockDiagram-VBNYF7ZC-Bc--I65C.js +0 -3158
  225. package/dist/chat-ui-DttQ-5Ut.js +0 -8455
  226. package/dist/chunk-3NCLNEKW-BIp_lB_4.js +0 -14
  227. package/dist/chunk-5FCAYU7R-C_HO9A1J.js +0 -23
  228. package/dist/chunk-5HE753X5-Bixm_MV-.js +0 -38
  229. package/dist/chunk-5JV3BV7I-CH5J3iZY.js +0 -54
  230. package/dist/chunk-5TONJI2A-DG6gDiSS.js +0 -62
  231. package/dist/chunk-7BUUIJ7U-5afmIPeo.js +0 -82
  232. package/dist/chunk-BIQX33UG-7TMBUf89.js +0 -23
  233. package/dist/chunk-CQNSW5MT-Cnqqsxt-.js +0 -38
  234. package/dist/chunk-CYSBUYHQ-BAbymFHR.js +0 -23
  235. package/dist/chunk-EMLP6XTP-Bsz-QL77.js +0 -23
  236. package/dist/chunk-J7OUQ5F2-CM_meqZH.js +0 -57
  237. package/dist/chunk-JG7HCLWE-DUnCDgPk.js +0 -62
  238. package/dist/chunk-MOZMSUNE-BG6IHvzT.js +0 -35
  239. package/dist/chunk-OSBZ3O6U-CYwj_bvR.js +0 -23
  240. package/dist/chunk-QBLGF6JB-B4vJ4j8J.js +0 -23
  241. package/dist/chunk-QR6OTTB3-D4wH2ldi.js +0 -3738
  242. package/dist/chunk-R7FJI6CG-Blf8FcmZ.js +0 -64
  243. package/dist/chunk-RYQCIY6F-BWbIlBIH.js +0 -241
  244. package/dist/chunk-U6XO7XAA-COw445DS.js +0 -63
  245. package/dist/chunk-UBXNYLIW-BHigVU4H.js +0 -32
  246. package/dist/chunk-YOTPTUD7-Dn044Q_d.js +0 -30
  247. package/dist/chunk-ZIRB5QZD-BR4TMfOa.js +0 -1153
  248. package/dist/classDiagram-JCYQIIEL-DmXSLxe_.js +0 -30
  249. package/dist/classDiagram-v2-OCEON4UE-CooqVexA.js +0 -30
  250. package/dist/click-outside-container-D_URcm3D.js +0 -167
  251. package/dist/code-block-37QAKDTI-CQrzBOr-.js +0 -107
  252. package/dist/cynefin-VYW2F7L2-CeHAxOEX.js +0 -3
  253. package/dist/dagre-VZM6K2ZE-CJggWPTJ.js +0 -328
  254. package/dist/dist-ABQjhuek.js +0 -64
  255. package/dist/dist-CO5R6VMi.js +0 -538
  256. package/dist/eventmodeling-45OFAUF4-B_lWZ-Pd.js +0 -3
  257. package/dist/flowDiagram-UKHOOZJN-g1AmrZzM.js +0 -17
  258. package/dist/gitGraph-TEB2WS4Q-Dj-eXUph.js +0 -3
  259. package/dist/info-DKCQHKI2-Bhb-pe2e.js +0 -3
  260. package/dist/line-CuKjIQa1.js +0 -34
  261. package/dist/map-BJpOfPlL.js +0 -149
  262. package/dist/math-BXtKgYah.js +0 -10
  263. package/dist/mermaid-4DMBBIKO-Ddp9TgNp.js +0 -2
  264. package/dist/mermaid-BsHdQeQf.js +0 -1173
  265. package/dist/mermaid-parser.core-Din9FvSi.js +0 -99
  266. package/dist/packet-7NZHBO7P-fbkIIyKE.js +0 -3
  267. package/dist/path-BNHuHZP8.js +0 -87
  268. package/dist/pie-RZYD4A2V-CLRIsxY1.js +0 -3
  269. package/dist/purify.es-CB-YO1Hn.js +0 -774
  270. package/dist/radar-I7S5WNFK-BGzCbgXu.js +0 -3
  271. package/dist/railroad-3IZDKUUU-CvQIIcuU.js +0 -3
  272. package/dist/railroad-abnf-AHOZXSZD-CMwtlNtu.js +0 -3
  273. package/dist/railroad-ebnf-EBAXGLYW-n1QUOAsh.js +0 -3
  274. package/dist/railroad-peg-LSFZ7HO6-PjnrpmCs.js +0 -3
  275. package/dist/schemas-DzK6U94N.js +0 -6057
  276. package/dist/stateDiagram-v2-UEYNNEHI-BTRUs8Il.js +0 -30
  277. package/dist/step-CKczO72Q.js +0 -670
  278. package/dist/swimlanesDiagram-ULZ7WXOC-NBmgBl9G.js +0 -31
  279. package/dist/timer-DpDyj9G0.js +0 -596
  280. package/dist/treeView-QDETBFTQ-DU8LwHuf.js +0 -3
  281. package/dist/treemap-6X3UGDF4-DUk4-k_O.js +0 -3
  282. package/dist/useTheme-CVJ0UOf2.js +0 -841
  283. package/dist/vega-loader.browser-DEggZzni.js +0 -1083
  284. package/dist/wardley-OPB4EBWU-Db-AaGas.js +0 -3
@@ -22,9 +22,13 @@ import { Tooltip } from "@/components/ui/tooltip";
22
22
  import { toast } from "@/components/ui/use-toast";
23
23
  import { useResolvedMarimoConfig } from "@/core/config/config";
24
24
  import { useRequestClient } from "@/core/network/requests";
25
- import type { DependencyTreeNode } from "@/core/network/types";
25
+ import type {
26
+ DependencyTreeNode,
27
+ DependencyTreeResponse,
28
+ } from "@/core/network/types";
26
29
  import { stripPackageManagerPrefix } from "@/core/packages/package-input-utils";
27
30
  import {
31
+ showPackageRestartToast,
28
32
  showRemovePackageToast,
29
33
  showUpgradePackageToast,
30
34
  } from "@/core/packages/toast-components";
@@ -39,6 +43,7 @@ import { PanelEmptyState } from "./empty-state";
39
43
  import { PACKAGES_INPUT_ID, packagesToInstallAtom } from "./packages-utils";
40
44
 
41
45
  type ViewMode = "tree" | "list";
46
+ type PackageInstallationContext = DependencyTreeResponse["context"];
42
47
 
43
48
  const PackageActionButton: React.FC<{
44
49
  onClick: () => void;
@@ -77,12 +82,22 @@ const PackagesPanel: React.FC = () => {
77
82
  refetch,
78
83
  isPending,
79
84
  } = useAsyncData(async () => {
80
- const [listPackagesResponse, dependencyTreeResponse] = await Promise.all([
81
- getPackageList(),
82
- getDependencyTree(),
83
- ]);
85
+ // A sandbox's list and tree both inspect the same environment. Wait for
86
+ // the context before issuing the list request so sandboxes do that work
87
+ // only once; non-sandbox managers still need both views.
88
+ const dependencyTreeResponse = await getDependencyTree();
89
+ if (dependencyTreeResponse.context.kind === "sandbox") {
90
+ return {
91
+ list: [],
92
+ context: dependencyTreeResponse.context,
93
+ tree: dependencyTreeResponse.tree,
94
+ };
95
+ }
96
+
97
+ const listPackagesResponse = await getPackageList();
84
98
  return {
85
99
  list: listPackagesResponse.packages,
100
+ context: dependencyTreeResponse.context,
86
101
  tree: dependencyTreeResponse.tree,
87
102
  };
88
103
  }, [packageManager]);
@@ -97,48 +112,66 @@ const PackagesPanel: React.FC = () => {
97
112
  }
98
113
 
99
114
  const isTreeSupported = dependencies.tree != null;
100
- const viewMode = resolveViewMode(userViewMode, isTreeSupported);
101
115
  const name = dependencies.tree?.name;
102
116
  const version = dependencies?.tree?.version;
103
- const isSandbox = name === "<root>"; // name is the project name otherwise
117
+ const sandboxBackend =
118
+ dependencies.context.kind === "sandbox"
119
+ ? dependencies.context.backend
120
+ : null;
121
+ const isSandbox = sandboxBackend !== null;
122
+ const viewMode = isSandbox
123
+ ? "tree"
124
+ : resolveViewMode(userViewMode, isTreeSupported);
125
+ const scopeLabel = sandboxBackend
126
+ ? `${sandboxBackend} sandbox`
127
+ : name && name !== "<root>"
128
+ ? "project"
129
+ : "environment";
130
+ const scopeTitle = sandboxBackend
131
+ ? `Dependencies are managed by the ${sandboxBackend} sandbox selected when marimo started.`
132
+ : scopeLabel;
104
133
 
105
134
  return (
106
135
  <div className="flex-1 flex flex-col overflow-hidden">
107
- <InstallPackageForm packageManager={packageManager} onSuccess={refetch} />
108
- {isTreeSupported && (
136
+ <InstallPackageForm context={dependencies.context} onSuccess={refetch} />
137
+ {(isTreeSupported || isSandbox) && (
109
138
  <div className="flex items-center justify-between px-2 py-1 border-b">
110
- <div className="flex gap-1">
111
- <button
112
- type="button"
113
- className={cn(
114
- "px-2 py-1 text-xs rounded",
115
- viewMode === "list"
116
- ? "bg-accent text-accent-foreground"
117
- : "text-muted-foreground hover:text-foreground",
118
- )}
119
- onClick={() => setUserViewMode("list")}
120
- >
121
- List
122
- </button>
123
- <button
124
- type="button"
125
- className={cn(
126
- "px-2 py-1 text-xs rounded",
127
- viewMode === "tree"
128
- ? "bg-accent text-accent-foreground"
129
- : "text-muted-foreground hover:text-foreground",
130
- )}
131
- onClick={() => setUserViewMode("tree")}
132
- >
133
- Tree
134
- </button>
135
- </div>
139
+ {isTreeSupported && !isSandbox ? (
140
+ <div className="flex gap-1">
141
+ <button
142
+ type="button"
143
+ className={cn(
144
+ "px-2 py-1 text-xs rounded",
145
+ viewMode === "list"
146
+ ? "bg-accent text-accent-foreground"
147
+ : "text-muted-foreground hover:text-foreground",
148
+ )}
149
+ onClick={() => setUserViewMode("list")}
150
+ >
151
+ List
152
+ </button>
153
+ <button
154
+ type="button"
155
+ className={cn(
156
+ "px-2 py-1 text-xs rounded",
157
+ viewMode === "tree"
158
+ ? "bg-accent text-accent-foreground"
159
+ : "text-muted-foreground hover:text-foreground",
160
+ )}
161
+ onClick={() => setUserViewMode("tree")}
162
+ >
163
+ Tree
164
+ </button>
165
+ </div>
166
+ ) : (
167
+ <div />
168
+ )}
136
169
  <div className="flex items-center gap-2">
137
170
  <div
138
171
  className="items-center border px-2 py-0.5 text-xs transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 text-foreground rounded-sm text-ellipsis block overflow-hidden max-w-fit font-medium"
139
- title={isSandbox ? "sandbox" : "project"}
172
+ title={scopeTitle}
140
173
  >
141
- {isSandbox ? "sandbox" : "project"}
174
+ {scopeLabel}
142
175
  </div>
143
176
  {name && !isSandbox && (
144
177
  <span className="text-xs text-muted-foreground">
@@ -155,6 +188,7 @@ const PackagesPanel: React.FC = () => {
155
188
  <DependencyTree
156
189
  tree={dependencies.tree}
157
190
  error={error}
191
+ sandboxBackend={sandboxBackend}
158
192
  onSuccess={refetch}
159
193
  />
160
194
  )}
@@ -165,11 +199,13 @@ const PackagesPanel: React.FC = () => {
165
199
  export default PackagesPanel;
166
200
 
167
201
  const InstallPackageForm: React.FC<{
168
- packageManager: string;
202
+ context: PackageInstallationContext;
169
203
  onSuccess: () => void;
170
- }> = ({ onSuccess, packageManager }) => {
204
+ }> = ({ onSuccess, context }) => {
171
205
  const [input, setInput] = React.useState("");
172
206
  const { handleClick: openSettings } = useOpenSettingsToTab();
207
+ const isSandbox = context.kind === "sandbox";
208
+ const packageManager = isSandbox ? context.backend : context.name;
173
209
 
174
210
  // Get the packages to install from the atom
175
211
  const packagesToInstall = useAtomValue(packagesToInstallAtom);
@@ -201,7 +237,11 @@ const InstallPackageForm: React.FC<{
201
237
  return (
202
238
  <div className="flex items-center w-full border-b">
203
239
  <SearchInput
204
- placeholder={`Install packages with ${packageManager}...`}
240
+ placeholder={
241
+ isSandbox
242
+ ? `Add packages to ${packageManager} sandbox...`
243
+ : `Install packages with ${packageManager}...`
244
+ }
205
245
  id={PACKAGES_INPUT_ID}
206
246
  icon={
207
247
  loading ? (
@@ -209,12 +249,23 @@ const InstallPackageForm: React.FC<{
209
249
  size="small"
210
250
  className="mr-2 h-4 w-4 shrink-0 opacity-50"
211
251
  />
252
+ ) : isSandbox ? (
253
+ <BoxIcon
254
+ aria-hidden="true"
255
+ className="mr-2 h-4 w-4 shrink-0 opacity-50"
256
+ />
212
257
  ) : (
213
- <Tooltip content="Change package manager">
214
- <BoxIcon
258
+ <Tooltip
259
+ content={`Change package manager (currently ${packageManager})`}
260
+ >
261
+ <button
262
+ type="button"
263
+ aria-label="Change package manager"
215
264
  onClick={() => openSettings("packageManagementAndData")}
216
- className="mr-2 h-4 w-4 shrink-0 opacity-50 hover:opacity-80 cursor-pointer"
217
- />
265
+ className="pointer-events-auto mr-2 rounded-sm opacity-50 hover:opacity-80 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring"
266
+ >
267
+ <BoxIcon aria-hidden="true" className="h-4 w-4 shrink-0" />
268
+ </button>
218
269
  </Tooltip>
219
270
  )
220
271
  }
@@ -234,9 +285,21 @@ const InstallPackageForm: React.FC<{
234
285
  align="start"
235
286
  content={
236
287
  <div className="text-sm flex flex-col w-full max-w-[360px]">
237
- Packages are installed using the package manager specified in your
238
- user configuration. Depending on your package manager, you can
239
- install packages with various formats:
288
+ {isSandbox ? (
289
+ <span>
290
+ Packages are recorded in this notebook&apos;s inline metadata
291
+ and synchronized with its {packageManager} sandbox. To switch
292
+ backends, restart marimo with a different --sandbox option.
293
+ </span>
294
+ ) : (
295
+ <span>
296
+ Packages are installed using {packageManager}, selected in your
297
+ user configuration.
298
+ </span>
299
+ )}
300
+ <span className="mt-2">
301
+ You can install packages with various formats:
302
+ </span>
240
303
  <div className="flex flex-col gap-2 mt-2">
241
304
  <div>
242
305
  <span className="font-bold tracking-wide">Package name:</span> A
@@ -379,7 +442,9 @@ const UpgradeButton: React.FC<{
379
442
  upgrade: true,
380
443
  group,
381
444
  });
382
- if (response.success) {
445
+ if (response.restartRequired) {
446
+ showPackageRestartToast();
447
+ } else if (response.success) {
383
448
  onSuccess();
384
449
  showUpgradePackageToast(packageName);
385
450
  } else {
@@ -413,7 +478,9 @@ const RemoveButton: React.FC<{
413
478
  package: packageName,
414
479
  group,
415
480
  });
416
- if (response.success) {
481
+ if (response.restartRequired) {
482
+ showPackageRestartToast();
483
+ } else if (response.success) {
417
484
  onSuccess();
418
485
  showRemovePackageToast(packageName);
419
486
  } else {
@@ -434,8 +501,9 @@ const RemoveButton: React.FC<{
434
501
  const DependencyTree: React.FC<{
435
502
  tree: DependencyTreeNode | null;
436
503
  error?: Error | null;
504
+ sandboxBackend: "uv" | "pixi" | null;
437
505
  onSuccess: () => void;
438
- }> = ({ tree, error, onSuccess }) => {
506
+ }> = ({ tree, error, sandboxBackend, onSuccess }) => {
439
507
  const [expandedNodes, setExpandedNodes] = React.useState<Set<string>>(
440
508
  new Set(),
441
509
  );
@@ -450,10 +518,25 @@ const DependencyTree: React.FC<{
450
518
  }
451
519
 
452
520
  if (!tree) {
453
- return <Spinner size="medium" centered={true} />;
521
+ return (
522
+ <PanelEmptyState
523
+ title="Dependency tree unavailable"
524
+ description="The sandbox did not return a dependency tree."
525
+ icon={<BoxIcon />}
526
+ />
527
+ );
454
528
  }
455
529
 
456
530
  if (tree.dependencies.length === 0) {
531
+ if (sandboxBackend === "pixi") {
532
+ return (
533
+ <PanelEmptyState
534
+ title="No PyPI dependencies"
535
+ description="Conda dependencies are not shown in this panel."
536
+ icon={<BoxIcon />}
537
+ />
538
+ );
539
+ }
457
540
  return (
458
541
  <PanelEmptyState
459
542
  title="No dependencies"
@@ -575,6 +658,17 @@ const DependencyTreeNode: React.FC<{
575
658
  {/* Tags */}
576
659
  <div className="flex items-center gap-1 ml-2">
577
660
  {node.tags.map((tag, index) => {
661
+ if (tag.kind === "dedupe") {
662
+ return (
663
+ <div
664
+ key={index}
665
+ className="items-center border px-2 py-0.5 text-xs transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground rounded-sm text-ellipsis block overflow-hidden max-w-fit font-medium"
666
+ title="Package tree already displayed"
667
+ >
668
+ already in tree
669
+ </div>
670
+ );
671
+ }
578
672
  if (tag.kind === "cycle") {
579
673
  return (
580
674
  <div
@@ -0,0 +1,65 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { render, screen } from "@testing-library/react";
4
+ import { beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { ReadonlyDiff } from "../readonly-diff";
6
+
7
+ const mocks = vi.hoisted(() => ({
8
+ mergeView: vi.fn(),
9
+ useTheme: vi.fn(),
10
+ }));
11
+
12
+ vi.mock("@codemirror/merge", () => ({
13
+ unifiedMergeView: mocks.mergeView,
14
+ }));
15
+
16
+ vi.mock("@uiw/react-codemirror", () => ({
17
+ default: ({ theme, value }: { theme: string; value: string }) => (
18
+ <div data-testid="code-mirror" data-theme={theme} data-value={value} />
19
+ ),
20
+ }));
21
+
22
+ vi.mock("@/theme/useTheme", () => ({
23
+ useTheme: mocks.useTheme,
24
+ }));
25
+
26
+ describe("ReadonlyDiff", () => {
27
+ beforeEach(() => {
28
+ mocks.mergeView.mockReset();
29
+ mocks.mergeView.mockReturnValue([]);
30
+ mocks.useTheme.mockReturnValue({ theme: "light" });
31
+ });
32
+
33
+ it("updates modified code without rebuilding the diff extensions", () => {
34
+ const { rerender } = render(
35
+ <ReadonlyDiff original="before" modified="first revision" />,
36
+ );
37
+
38
+ expect(screen.getByTestId("code-mirror")).toHaveAttribute(
39
+ "data-value",
40
+ "first revision",
41
+ );
42
+ expect(mocks.mergeView).toHaveBeenCalledTimes(1);
43
+
44
+ rerender(<ReadonlyDiff original="before" modified="second revision" />);
45
+
46
+ expect(screen.getByTestId("code-mirror")).toHaveAttribute(
47
+ "data-value",
48
+ "second revision",
49
+ );
50
+ expect(mocks.mergeView).toHaveBeenCalledTimes(1);
51
+ });
52
+
53
+ it("rebuilds diff extensions when the original code changes", () => {
54
+ const { rerender } = render(
55
+ <ReadonlyDiff original="before" modified="after" />,
56
+ );
57
+
58
+ rerender(<ReadonlyDiff original="earlier" modified="after" />);
59
+
60
+ expect(mocks.mergeView).toHaveBeenCalledTimes(2);
61
+ expect(mocks.mergeView).toHaveBeenLastCalledWith(
62
+ expect.objectContaining({ original: "earlier" }),
63
+ );
64
+ });
65
+ });
@@ -21,7 +21,7 @@ export const ReadonlyDiff = memo(
21
21
  },
22
22
  }),
23
23
  ];
24
- }, [props.original, props.modified, theme]);
24
+ }, [props.original]);
25
25
 
26
26
  return (
27
27
  <CodeMirror
@@ -0,0 +1,54 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { act, fireEvent, render, screen } from "@testing-library/react";
4
+ import type React from "react";
5
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
+ import { RefreshIconButton } from "../tree-actions";
7
+
8
+ vi.mock("@/components/ui/tooltip", () => ({
9
+ Tooltip: ({ children }: { children: React.ReactNode }) => children,
10
+ }));
11
+
12
+ describe("RefreshIconButton", () => {
13
+ beforeEach(() => {
14
+ vi.useFakeTimers();
15
+ });
16
+
17
+ afterEach(() => {
18
+ vi.useRealTimers();
19
+ });
20
+
21
+ it("spins for at least 500ms after a refresh completes", async () => {
22
+ const onClick = vi.fn().mockResolvedValue(undefined);
23
+ const { container } = render(<RefreshIconButton onClick={onClick} />);
24
+
25
+ fireEvent.click(screen.getByRole("button"));
26
+
27
+ expect(onClick).toHaveBeenCalledOnce();
28
+ expect(container.querySelector("svg")).toHaveClass("animate-[spin_0.5s]");
29
+
30
+ await act(async () => {
31
+ await vi.advanceTimersByTimeAsync(500);
32
+ });
33
+
34
+ expect(container.querySelector("svg")).not.toHaveClass(
35
+ "animate-[spin_0.5s]",
36
+ );
37
+ });
38
+
39
+ it("uses the latest refresh callback after a rerender", async () => {
40
+ const initialOnClick = vi.fn().mockResolvedValue(undefined);
41
+ const updatedOnClick = vi.fn().mockResolvedValue(undefined);
42
+ const { rerender } = render(<RefreshIconButton onClick={initialOnClick} />);
43
+
44
+ rerender(<RefreshIconButton onClick={updatedOnClick} />);
45
+ fireEvent.click(screen.getByRole("button"));
46
+
47
+ expect(initialOnClick).not.toHaveBeenCalled();
48
+ expect(updatedOnClick).toHaveBeenCalledOnce();
49
+
50
+ await act(async () => {
51
+ await vi.advanceTimersByTimeAsync(500);
52
+ });
53
+ });
54
+ });
@@ -7,7 +7,7 @@ import {
7
7
  MoreVerticalIcon,
8
8
  RefreshCwIcon,
9
9
  } from "lucide-react";
10
- import React, { useCallback, useState } from "react";
10
+ import React, { useState } from "react";
11
11
  import { Button, type ButtonProps } from "@/components/ui/button";
12
12
  import { Tooltip } from "@/components/ui/tooltip";
13
13
  import { cn } from "@/utils/cn";
@@ -41,19 +41,16 @@ export const RefreshIconButton: React.FC<{
41
41
  }> = ({ onClick, tooltip = "Refresh", className, iconClassName }) => {
42
42
  const [isSpinning, setIsSpinning] = useState(false);
43
43
 
44
- const handleClick = useCallback(
45
- async (e: React.MouseEvent) => {
46
- setIsSpinning(true);
47
- // Artificially spin for 500ms to show the user that the button is working.
48
- const minDelay = new Promise<void>((r) => setTimeout(r, 500));
49
- try {
50
- await Promise.all([onClick(e), minDelay]);
51
- } finally {
52
- setIsSpinning(false);
53
- }
54
- },
55
- [onClick],
56
- );
44
+ const handleClick = async (e: React.MouseEvent) => {
45
+ setIsSpinning(true);
46
+ // Artificially spin for 500ms to show the user that the button is working.
47
+ const minDelay = new Promise<void>((r) => setTimeout(r, 500));
48
+ try {
49
+ await Promise.all([onClick(e), minDelay]);
50
+ } finally {
51
+ setIsSpinning(false);
52
+ }
53
+ };
57
54
 
58
55
  const button = (
59
56
  <Button
@@ -72,6 +72,7 @@
72
72
  /* Coarse hack to stop children from overflowing; doesn't seem to affect
73
73
  * margin collapse. */
74
74
  overflow: auto;
75
+ overscroll-behavior: contain;
75
76
  @apply text-xs;
76
77
 
77
78
  .data-key-pair:not(:last-child) {
@@ -10,6 +10,7 @@ import {
10
10
  PackageCheckIcon,
11
11
  PackageXIcon,
12
12
  PlusIcon,
13
+ RotateCwIcon,
13
14
  XIcon,
14
15
  } from "lucide-react";
15
16
  import type React from "react";
@@ -32,6 +33,7 @@ import {
32
33
  import { useResolvedMarimoConfig } from "@/core/config/config";
33
34
  import type { PackageInstallationStatus } from "@/core/kernel/messages";
34
35
  import { useRequestClient } from "@/core/network/requests";
36
+ import { RESTART_REQUIRED_DESCRIPTION } from "@/core/packages/toast-components";
35
37
  import { isWasm } from "@/core/wasm/utils";
36
38
  import { usePackageMetadata } from "@/hooks/usePackageMetadata";
37
39
  import { Banner } from "@/plugins/impl/common/error-banner";
@@ -55,6 +57,12 @@ import {
55
57
  import { ExternalLink } from "../ui/links";
56
58
  import { NativeSelect } from "../ui/native-select";
57
59
  import { Tooltip } from "../ui/tooltip";
60
+ import { useRestartKernel } from "./actions/useRestartKernel";
61
+
62
+ const RestartKernelButton = () => {
63
+ const restartKernel = useRestartKernel();
64
+ return <Button onClick={restartKernel}>Restart Kernel</Button>;
65
+ };
58
66
 
59
67
  function parsePackageSpecifier(spec: string): {
60
68
  name: string;
@@ -251,6 +259,10 @@ export const PackageAlert: React.FC = () => {
251
259
  )}
252
260
  >
253
261
  <p>{description}</p>
262
+ {status !== "installing" &&
263
+ Object.values(packageAlert.packages).includes(
264
+ "restart-required",
265
+ ) && <RestartKernelButton />}
254
266
  <ul className="list-disc ml-2 mt-1">
255
267
  {Object.entries(packageAlert.packages).map(([pkg, st], index) => (
256
268
  <li
@@ -290,7 +302,9 @@ function getInstallationStatusElements(packages: PackageInstallationStatus) {
290
302
  ? "installing"
291
303
  : statuses.has("failed")
292
304
  ? "failed"
293
- : "installed";
305
+ : statuses.has("restart-required")
306
+ ? "restart-required"
307
+ : "installed";
294
308
 
295
309
  if (status === "installing") {
296
310
  return {
@@ -300,6 +314,14 @@ function getInstallationStatusElements(packages: PackageInstallationStatus) {
300
314
  description: "Installing packages:",
301
315
  };
302
316
  }
317
+ if (status === "restart-required") {
318
+ return {
319
+ status,
320
+ title: "Changes saved — restart required",
321
+ titleIcon: <RotateCwIcon className="w-5 h-5 inline-block mr-2" />,
322
+ description: RESTART_REQUIRED_DESCRIPTION,
323
+ };
324
+ }
303
325
  if (status === "installed") {
304
326
  return {
305
327
  status: "installed",
@@ -330,6 +352,8 @@ const ProgressIcon = ({
330
352
  return <CheckIcon size="1rem" />;
331
353
  case "failed":
332
354
  return <XIcon size="1rem" />;
355
+ case "restart-required":
356
+ return <RotateCwIcon size="1rem" />;
333
357
  default:
334
358
  logNever(status);
335
359
  return null;
@@ -31,6 +31,7 @@ import {
31
31
  import { Constants } from "@/core/constants";
32
32
  import { useRequestClient } from "@/core/network/requests";
33
33
  import type { TutorialId } from "@/core/network/types";
34
+ import { Banner } from "@/plugins/impl/common/error-banner";
34
35
  import { openNotebook } from "@/utils/links";
35
36
  import { Objects } from "@/utils/objects";
36
37
  import { MarimoPlusIcon } from "../icons/marimo-icons";
@@ -186,6 +187,22 @@ export const ResourceLinks: React.FC = () => {
186
187
  );
187
188
  };
188
189
 
190
+ /**
191
+ * Shown when the workspace scan stopped early, so the file list the user is
192
+ * looking at is missing files and folders.
193
+ */
194
+ export const TruncatedWorkspaceBanner: React.FC<{
195
+ fileCount: number | undefined;
196
+ }> = ({ fileCount }) => {
197
+ return (
198
+ <Banner kind="warn" className="rounded p-4">
199
+ Showing {fileCount} files. Some files and folders were skipped because
200
+ your workspace is large or deeply nested. Start marimo from a subfolder to
201
+ see them.
202
+ </Banner>
203
+ );
204
+ };
205
+
189
206
  export const Header: React.FC<{
190
207
  Icon: React.FC<React.SVGProps<SVGSVGElement>>;
191
208
  control?: React.ReactNode;
@@ -4,6 +4,7 @@ import { SearchIcon } from "lucide-react";
4
4
  import type React from "react";
5
5
  import { Suspense, useMemo, useState } from "react";
6
6
  import { ErrorBoundary } from "@/components/editor/boundary/ErrorBoundary";
7
+ import { TruncatedWorkspaceBanner } from "@/components/home/components";
7
8
  import { Spinner } from "@/components/icons/spinner";
8
9
  import { Card, CardContent } from "@/components/ui/card";
9
10
  import { Input } from "@/components/ui/input";
@@ -119,10 +120,7 @@ const GalleryPage: React.FC = () => {
119
120
  <ErrorBoundary>
120
121
  <div className="flex flex-col gap-2">
121
122
  {workspace.hasMore && (
122
- <Banner kind="warn" className="rounded p-4">
123
- Showing first {workspace.fileCount} files. Your workspace has
124
- more files.
125
- </Banner>
123
+ <TruncatedWorkspaceBanner fileCount={workspace.fileCount} />
126
124
  )}
127
125
  {formattedFiles.length > SEARCH_THRESHOLD && (
128
126
  <Input
@@ -67,6 +67,7 @@ import {
67
67
  Header,
68
68
  OpenTutorialDropDown,
69
69
  ResourceLinks,
70
+ TruncatedWorkspaceBanner,
70
71
  } from "../home/components";
71
72
  import {
72
73
  expandedFoldersAtom,
@@ -196,10 +197,7 @@ const WorkspaceNotebooks: React.FC<{ onRefreshRecents: () => void }> = ({
196
197
  <WorkspaceContext value={workspaceContextValue}>
197
198
  <div className="flex flex-col gap-2">
198
199
  {workspace.hasMore && (
199
- <Banner kind="warn" className="rounded p-4">
200
- Showing first {workspace.fileCount} files. Your workspace has more
201
- files.
202
- </Banner>
200
+ <TruncatedWorkspaceBanner fileCount={workspace.fileCount} />
203
201
  )}
204
202
  <Header
205
203
  Icon={BookTextIcon}
@@ -254,7 +254,9 @@ const TerminalComponent: React.FC<TerminalComponentProps> = ({
254
254
  try {
255
255
  await waitForConnectionOpen();
256
256
 
257
- const socket = new WebSocket(runtimeManager.getTerminalWsURL());
257
+ // Size the PTY before the shell draws its first prompt.
258
+ fitAddon.fit();
259
+ const socket = new WebSocket(runtimeManager.getTerminalWsURL(terminal));
258
260
  const attachAddon = new AttachAddon(socket);
259
261
  terminal.loadAddon(attachAddon);
260
262
  wsRef.current = socket;
@@ -270,9 +272,7 @@ const TerminalComponent: React.FC<TerminalComponentProps> = ({
270
272
 
271
273
  const handleOpen = () => {
272
274
  updateReadyState();
273
- // Send initial dimensions: the mount-time fit() may have fired
274
- // before the WS was OPEN, dropping the resize message and leaving
275
- // the PTY at its default 0x0 winsize.
275
+ // The container may have resized while the connection was opening.
276
276
  fitAddon.fit();
277
277
  if (terminal.cols > 0 && terminal.rows > 0) {
278
278
  socket.send(
@@ -1,7 +1,7 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import type { TopLevelSpec } from "vega-lite";
4
- import type { TimeUnit } from "vega-typings";
4
+ import type { TimeUnit } from "vega-lite/types_unstable/timeunit.js";
5
5
  import type { CellId } from "@/core/cells/ids";
6
6
  import type { CellRun } from "@/core/cells/runs";
7
7
  import type { ResolvedTheme } from "@/theme/useTheme";