@marimo-team/islands 0.24.3-dev4 → 0.24.3-dev41

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 (370) hide show
  1. package/dist/{ConnectedDataExplorerComponent-C9OF_75w.js → ConnectedDataExplorerComponent-KVhjDMSe.js} +1066 -1066
  2. package/dist/ErrorBoundary-Cg8Ff5uL.js +200 -0
  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-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-BB9okzzY.js +138 -0
  46. package/dist/{common-BDlauhCU.js → common-aCHtzRnQ.js} +8853 -12653
  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-yiwy9Vea.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-CfL-qWDi.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-MNFAmb3B.js} +2143 -1910
  105. package/dist/{glide-utils-NShAPPtn.js → glide-utils-B3rUT5PI.js} +15 -15
  106. package/dist/globals-DZfCplvV.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-BZuSsCs5.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-BthxSdRc.js → reveal-component-ONiOVUUx.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/components/chat/acp/__tests__/agent-panel.test.tsx +270 -0
  187. package/src/components/chat/acp/agent-panel.tsx +45 -44
  188. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +2 -6
  189. package/src/components/data-table/column-summary/chart-spec-model.tsx +1 -1
  190. package/src/components/data-table/column-visibility-dropdown.tsx +9 -3
  191. package/src/components/data-table/columns.tsx +64 -67
  192. package/src/components/datasources/components.tsx +4 -2
  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/alerts/connecting-alert.tsx +1 -66
  196. package/src/components/editor/alerts/connection-notice.tsx +140 -0
  197. package/src/components/editor/app-container.tsx +9 -3
  198. package/src/components/editor/boundary/ErrorBoundary.tsx +38 -16
  199. package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +311 -0
  200. package/src/components/editor/cell/code/__tests__/rtc-editor-config.test.ts +50 -0
  201. package/src/components/editor/cell/code/cell-editor.tsx +41 -42
  202. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +94 -0
  203. package/src/components/editor/chrome/components/feedback-button.tsx +63 -42
  204. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +114 -7
  205. package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +165 -0
  206. package/src/components/editor/chrome/panels/packages-panel.tsx +93 -166
  207. package/src/components/editor/chrome/panels/sandbox-controller.tsx +106 -0
  208. package/src/components/editor/chrome/panels/sandbox-panel.tsx +173 -0
  209. package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +3 -1
  210. package/src/components/editor/code/__tests__/readonly-diff.test.tsx +65 -0
  211. package/src/components/editor/code/readonly-diff.tsx +1 -1
  212. package/src/components/editor/dynamic-favicon.tsx +17 -10
  213. package/src/components/editor/file-tree/__tests__/tree-actions.test.tsx +54 -0
  214. package/src/components/editor/file-tree/tree-actions.tsx +11 -14
  215. package/src/components/editor/header/__tests__/status.test.tsx +8 -20
  216. package/src/components/editor/header/filename-input.tsx +2 -0
  217. package/src/components/editor/header/status.tsx +5 -3
  218. package/src/components/editor/notebook-cell.tsx +4 -2
  219. package/src/components/editor/output/JsonOutput.tsx +182 -632
  220. package/src/components/editor/output/Outputs.css +50 -17
  221. package/src/components/editor/output/__tests__/JsonOutput-interactions.test.tsx +254 -0
  222. package/src/components/editor/output/__tests__/JsonOutput-mimetype.test.tsx +41 -46
  223. package/src/components/editor/output/__tests__/{json-output.test.ts → json-output-formatting.test.ts} +113 -75
  224. package/src/components/editor/output/__tests__/json-output-pagination.test.ts +252 -0
  225. package/src/components/editor/output/json-output/formatting.ts +167 -0
  226. package/src/components/editor/output/json-output/pagination.ts +155 -0
  227. package/src/components/editor/output/json-output/renderers.tsx +196 -0
  228. package/src/components/editor/output/json-output/themes.ts +52 -0
  229. package/src/components/editor/renderers/cell-array.tsx +1 -5
  230. package/src/components/home/components.tsx +17 -0
  231. package/src/components/pages/gallery-page.tsx +2 -4
  232. package/src/components/pages/home-page.tsx +2 -4
  233. package/src/components/slides/slide-form.tsx +1 -0
  234. package/src/components/slides/slide-notes-editor.tsx +1 -0
  235. package/src/components/terminal/terminal.tsx +4 -4
  236. package/src/components/tracing/tracing-spec.ts +1 -1
  237. package/src/components/ui/table.tsx +1 -1
  238. package/src/components/ui/use-toast.ts +8 -0
  239. package/src/core/MarimoApp.tsx +0 -2
  240. package/src/core/cells/__tests__/cell.test.ts +61 -0
  241. package/src/core/cells/cell.ts +9 -1
  242. package/src/core/cells/pending-delete-service.ts +12 -16
  243. package/src/core/codemirror/language/__tests__/sql.test.ts +70 -2
  244. package/src/core/codemirror/language/languages/sql/sql.ts +16 -1
  245. package/src/core/codemirror/rtc/extension.ts +5 -2
  246. package/src/core/datasets/__tests__/data-source.test.ts +2 -0
  247. package/src/core/datasets/data-source-connections.ts +15 -10
  248. package/src/core/edit-app.tsx +8 -5
  249. package/src/core/errors/state.ts +1 -2
  250. package/src/core/islands/__tests__/parse.test.ts +140 -7
  251. package/src/core/islands/bootstrap.ts +1 -0
  252. package/src/core/islands/bridge.ts +3 -0
  253. package/src/core/islands/parse.ts +20 -0
  254. package/src/core/network/connection-notice.ts +84 -0
  255. package/src/core/network/requests-lazy.ts +3 -0
  256. package/src/core/network/requests-network.ts +12 -0
  257. package/src/core/network/requests-static.ts +3 -0
  258. package/src/core/network/requests-toasting.tsx +3 -0
  259. package/src/core/network/resolve.ts +2 -1
  260. package/src/core/network/types.ts +7 -0
  261. package/src/core/packages/__tests__/usePackageAction.test.tsx +129 -0
  262. package/src/core/packages/__tests__/useSandboxController.test.tsx +165 -0
  263. package/src/core/packages/package-data.ts +35 -0
  264. package/src/core/packages/sandbox-state.ts +15 -0
  265. package/src/core/packages/toast-components.tsx +11 -0
  266. package/src/core/packages/useInstallPackage.ts +1 -1
  267. package/src/core/packages/usePackageAction.ts +51 -0
  268. package/src/core/packages/usePackageDependencies.ts +22 -0
  269. package/src/core/packages/useSandboxController.ts +188 -0
  270. package/src/core/run-app.tsx +2 -0
  271. package/src/core/runtime/__tests__/runtime.test.ts +11 -0
  272. package/src/core/runtime/runtime.ts +7 -2
  273. package/src/core/wasm/bridge.ts +11 -0
  274. package/src/core/websocket/__tests__/useMarimoKernelConnection.hook.test.tsx +212 -2
  275. package/src/core/websocket/transports/transport.ts +1 -1
  276. package/src/core/websocket/transports/ws.ts +1 -1
  277. package/src/core/websocket/types.ts +11 -1
  278. package/src/core/websocket/useMarimoKernelConnection.tsx +43 -8
  279. package/src/css/app/Cell.css +2 -0
  280. package/src/hooks/useDebounce.ts +2 -0
  281. package/src/plugins/core/BadPlugin.tsx +3 -14
  282. package/src/plugins/core/RenderHTML.tsx +22 -2
  283. package/src/plugins/core/__test__/RenderHTML.test.ts +187 -0
  284. package/src/plugins/core/registerReactComponent.tsx +0 -1
  285. package/src/plugins/impl/FormPlugin.tsx +2 -0
  286. package/src/plugins/impl/MatrixPlugin.tsx +2 -0
  287. package/src/plugins/impl/RangeSliderPlugin.tsx +2 -0
  288. package/src/plugins/impl/SliderPlugin.tsx +2 -0
  289. package/src/plugins/impl/data-editor/__tests__/glide-data-editor.test.tsx +23 -18
  290. package/src/plugins/impl/data-frames/panel.tsx +1 -0
  291. package/src/plugins/layout/AccordionPlugin.tsx +7 -2
  292. package/src/plugins/layout/JsonOutputPlugin.tsx +7 -10
  293. package/src/plugins/layout/__test__/AccordionPlugin.test.tsx +66 -0
  294. package/src/stories/sandbox.stories.tsx +308 -0
  295. package/dist/ErrorBoundary-CR-ZQN_c.js +0 -125
  296. package/dist/_baseMerge-Dv8bBloN.js +0 -73
  297. package/dist/_initCloneObject---vediN2.js +0 -95
  298. package/dist/arc-DOVLrCPd.js +0 -82
  299. package/dist/architecture-TIHT7OUA-MiJpPpQW.js +0 -3
  300. package/dist/array-CApNbSU9.js +0 -6
  301. package/dist/assets/__vite-browser-external-BdKGjRZ4.js +0 -1
  302. package/dist/assets/worker-DlIBfp9S.js +0 -98
  303. package/dist/blockDiagram-VBNYF7ZC-Bc--I65C.js +0 -3158
  304. package/dist/chat-ui-DjTMZRVP.js +0 -8455
  305. package/dist/chunk-3NCLNEKW-BIp_lB_4.js +0 -14
  306. package/dist/chunk-5FCAYU7R-C_HO9A1J.js +0 -23
  307. package/dist/chunk-5HE753X5-Bixm_MV-.js +0 -38
  308. package/dist/chunk-5JV3BV7I-CH5J3iZY.js +0 -54
  309. package/dist/chunk-5TONJI2A-DG6gDiSS.js +0 -62
  310. package/dist/chunk-7BUUIJ7U-5afmIPeo.js +0 -82
  311. package/dist/chunk-BIQX33UG-7TMBUf89.js +0 -23
  312. package/dist/chunk-CQNSW5MT-Cnqqsxt-.js +0 -38
  313. package/dist/chunk-CYSBUYHQ-BAbymFHR.js +0 -23
  314. package/dist/chunk-EMLP6XTP-Bsz-QL77.js +0 -23
  315. package/dist/chunk-J7OUQ5F2-CM_meqZH.js +0 -57
  316. package/dist/chunk-JG7HCLWE-DUnCDgPk.js +0 -62
  317. package/dist/chunk-MOZMSUNE-BG6IHvzT.js +0 -35
  318. package/dist/chunk-OSBZ3O6U-CYwj_bvR.js +0 -23
  319. package/dist/chunk-QBLGF6JB-B4vJ4j8J.js +0 -23
  320. package/dist/chunk-QR6OTTB3-D4wH2ldi.js +0 -3738
  321. package/dist/chunk-R7FJI6CG-Blf8FcmZ.js +0 -64
  322. package/dist/chunk-RYQCIY6F-BWbIlBIH.js +0 -241
  323. package/dist/chunk-U6XO7XAA-COw445DS.js +0 -63
  324. package/dist/chunk-UBXNYLIW-BHigVU4H.js +0 -32
  325. package/dist/chunk-YOTPTUD7-Dn044Q_d.js +0 -30
  326. package/dist/chunk-ZIRB5QZD-BR4TMfOa.js +0 -1153
  327. package/dist/classDiagram-JCYQIIEL-DmXSLxe_.js +0 -30
  328. package/dist/classDiagram-v2-OCEON4UE-CooqVexA.js +0 -30
  329. package/dist/click-outside-container-D_URcm3D.js +0 -167
  330. package/dist/code-block-37QAKDTI-CQrzBOr-.js +0 -107
  331. package/dist/copy-CD7S58CY.js +0 -141
  332. package/dist/cynefin-VYW2F7L2-CeHAxOEX.js +0 -3
  333. package/dist/dagre-VZM6K2ZE-CJggWPTJ.js +0 -328
  334. package/dist/dist-3_o3T78I.js +0 -1360
  335. package/dist/dist-ABQjhuek.js +0 -64
  336. package/dist/dist-CO5R6VMi.js +0 -538
  337. package/dist/dropdown-menu-DhCfcscX.js +0 -5858
  338. package/dist/emotion-is-prop-valid.esm-M57VsT8j.js +0 -14
  339. package/dist/error-banner-CsXbEEjo.js +0 -611
  340. package/dist/eventmodeling-45OFAUF4-B_lWZ-Pd.js +0 -3
  341. package/dist/flowDiagram-UKHOOZJN-g1AmrZzM.js +0 -17
  342. package/dist/gitGraph-TEB2WS4Q-Dj-eXUph.js +0 -3
  343. package/dist/info-DKCQHKI2-Bhb-pe2e.js +0 -3
  344. package/dist/line-CuKjIQa1.js +0 -34
  345. package/dist/map-BJpOfPlL.js +0 -149
  346. package/dist/math-BXtKgYah.js +0 -10
  347. package/dist/mermaid-4DMBBIKO-Ddp9TgNp.js +0 -2
  348. package/dist/mermaid-Bi23Ibnw.js +0 -1173
  349. package/dist/mermaid-parser.core-Din9FvSi.js +0 -99
  350. package/dist/packet-7NZHBO7P-fbkIIyKE.js +0 -3
  351. package/dist/path-BNHuHZP8.js +0 -87
  352. package/dist/pie-RZYD4A2V-CLRIsxY1.js +0 -3
  353. package/dist/purify.es-CB-YO1Hn.js +0 -774
  354. package/dist/radar-I7S5WNFK-BGzCbgXu.js +0 -3
  355. package/dist/railroad-3IZDKUUU-CvQIIcuU.js +0 -3
  356. package/dist/railroad-abnf-AHOZXSZD-CMwtlNtu.js +0 -3
  357. package/dist/railroad-ebnf-EBAXGLYW-n1QUOAsh.js +0 -3
  358. package/dist/railroad-peg-LSFZ7HO6-PjnrpmCs.js +0 -3
  359. package/dist/schemas-DzK6U94N.js +0 -6057
  360. package/dist/stateDiagram-v2-UEYNNEHI-BTRUs8Il.js +0 -30
  361. package/dist/step-CKczO72Q.js +0 -670
  362. package/dist/swimlanesDiagram-ULZ7WXOC-NBmgBl9G.js +0 -31
  363. package/dist/timer-DpDyj9G0.js +0 -596
  364. package/dist/tooltip-Dt77sBeT.js +0 -390
  365. package/dist/treeView-QDETBFTQ-DU8LwHuf.js +0 -3
  366. package/dist/treemap-6X3UGDF4-DUk4-k_O.js +0 -3
  367. package/dist/useTheme-CVJ0UOf2.js +0 -841
  368. package/dist/vega-loader.browser-DEggZzni.js +0 -1083
  369. package/dist/wardley-OPB4EBWU-Db-AaGas.js +0 -3
  370. package/src/components/editor/output/EmotionCacheProvider.tsx +0 -32
@@ -7,6 +7,7 @@ import {
7
7
  HelpCircleIcon,
8
8
  } from "lucide-react";
9
9
  import React from "react";
10
+ import { connectionNoticeAtom } from "@/core/network/connection-notice";
10
11
  import { useOpenSettingsToTab } from "@/components/app-config/state";
11
12
  import { Spinner } from "@/components/icons/spinner";
12
13
  import { SearchInput } from "@/components/ui/input";
@@ -20,25 +21,22 @@ import {
20
21
  } from "@/components/ui/table";
21
22
  import { Tooltip } from "@/components/ui/tooltip";
22
23
  import { toast } from "@/components/ui/use-toast";
23
- import { useResolvedMarimoConfig } from "@/core/config/config";
24
- import { useRequestClient } from "@/core/network/requests";
24
+ import { isConnectedAtom } from "@/core/network/connection";
25
25
  import type {
26
26
  DependencyTreeNode,
27
27
  DependencyTreeResponse,
28
28
  } from "@/core/network/types";
29
+ import { sandboxAtom, sandboxSyncAtom } from "@/core/packages/sandbox-state";
29
30
  import { stripPackageManagerPrefix } from "@/core/packages/package-input-utils";
30
- import {
31
- showPackageRestartToast,
32
- showRemovePackageToast,
33
- showUpgradePackageToast,
34
- } from "@/core/packages/toast-components";
31
+ import { usePackageAction } from "@/core/packages/usePackageAction";
32
+ import { usePackageDependencies } from "@/core/packages/usePackageDependencies";
35
33
  import { useInstallPackages } from "@/core/packages/useInstallPackage";
36
34
  import { isWasm } from "@/core/wasm/utils";
37
- import { useAsyncData } from "@/hooks/useAsyncData";
38
35
  import { ErrorBanner } from "@/plugins/impl/common/error-banner";
39
36
  import { cn } from "@/utils/cn";
40
37
  import { copyToClipboard } from "@/utils/copy";
41
38
  import { Events } from "@/utils/events";
39
+ import { SandboxFooter, SandboxStartupPanel } from "./sandbox-panel";
42
40
  import { PanelEmptyState } from "./empty-state";
43
41
  import { PACKAGES_INPUT_ID, packagesToInstallAtom } from "./packages-utils";
44
42
 
@@ -71,36 +69,44 @@ const PackageActionButton: React.FC<{
71
69
  };
72
70
 
73
71
  const PackagesPanel: React.FC = () => {
74
- const [config] = useResolvedMarimoConfig();
75
- const packageManager = config.package_management.manager;
76
- const { getDependencyTree, getPackageList } = useRequestClient();
72
+ const sandbox = useAtomValue(sandboxAtom);
73
+ const connected = useAtomValue(isConnectedAtom);
74
+ const notice = useAtomValue(connectionNoticeAtom);
75
+ const operation = useAtomValue(sandboxSyncAtom);
76
+ if (sandbox?.backend) {
77
+ return (
78
+ <div className="flex flex-col flex-1 min-h-0 overflow-hidden">
79
+ {notice && (!operation.pending || !connected) ? (
80
+ <SandboxStartupPanel />
81
+ ) : (
82
+ <PackageContents />
83
+ )}
84
+ <SandboxFooter />
85
+ </div>
86
+ );
87
+ }
88
+ if (notice) {
89
+ return (
90
+ <div className="p-4 text-sm text-muted-foreground">
91
+ <div className="flex items-center gap-2">
92
+ {notice.pending && <Spinner className="size-3" />}
93
+ {notice.title}
94
+ </div>
95
+ {notice.error && (
96
+ <pre className="mt-3 text-xs whitespace-pre-wrap break-words max-h-52 overflow-auto">
97
+ {notice.error}
98
+ </pre>
99
+ )}
100
+ </div>
101
+ );
102
+ }
103
+ return <PackageContents />;
104
+ };
77
105
 
106
+ const PackageContents: React.FC = () => {
107
+ const { pending: syncing } = useAtomValue(sandboxSyncAtom);
78
108
  const [userViewMode, setUserViewMode] = React.useState<ViewMode | null>(null);
79
- const {
80
- data: dependencies,
81
- error,
82
- refetch,
83
- isPending,
84
- } = useAsyncData(async () => {
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();
98
- return {
99
- list: listPackagesResponse.packages,
100
- context: dependencyTreeResponse.context,
101
- tree: dependencyTreeResponse.tree,
102
- };
103
- }, [packageManager]);
109
+ const { data: dependencies, error, isPending } = usePackageDependencies();
104
110
 
105
111
  // Only show on the first load
106
112
  if (isPending) {
@@ -122,58 +128,49 @@ const PackagesPanel: React.FC = () => {
122
128
  const viewMode = isSandbox
123
129
  ? "tree"
124
130
  : 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;
131
+ const scopeLabel = name && name !== "<root>" ? "project" : "environment";
133
132
 
134
133
  return (
135
134
  <div className="flex-1 flex flex-col overflow-hidden">
136
- <InstallPackageForm context={dependencies.context} onSuccess={refetch} />
137
- {(isTreeSupported || isSandbox) && (
135
+ <fieldset disabled={syncing} className="contents">
136
+ <InstallPackageForm context={dependencies.context} />
137
+ </fieldset>
138
+ {isTreeSupported && !isSandbox && (
138
139
  <div className="flex items-center justify-between px-2 py-1 border-b">
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
- )}
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>
169
166
  <div className="flex items-center gap-2">
170
167
  <div
171
168
  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"
172
- title={scopeTitle}
169
+ title={scopeLabel}
173
170
  >
174
171
  {scopeLabel}
175
172
  </div>
176
- {name && !isSandbox && (
173
+ {name && (
177
174
  <span className="text-xs text-muted-foreground">
178
175
  {name}
179
176
  {version && ` v${version}`}
@@ -183,13 +180,12 @@ const PackagesPanel: React.FC = () => {
183
180
  </div>
184
181
  )}
185
182
  {viewMode === "list" ? (
186
- <PackagesList packages={dependencies.list} onSuccess={refetch} />
183
+ <PackagesList packages={dependencies.list} />
187
184
  ) : (
188
185
  <DependencyTree
189
186
  tree={dependencies.tree}
190
187
  error={error}
191
188
  sandboxBackend={sandboxBackend}
192
- onSuccess={refetch}
193
189
  />
194
190
  )}
195
191
  </div>
@@ -200,8 +196,7 @@ export default PackagesPanel;
200
196
 
201
197
  const InstallPackageForm: React.FC<{
202
198
  context: PackageInstallationContext;
203
- onSuccess: () => void;
204
- }> = ({ onSuccess, context }) => {
199
+ }> = ({ context }) => {
205
200
  const [input, setInput] = React.useState("");
206
201
  const { handleClick: openSettings } = useOpenSettingsToTab();
207
202
  const isSandbox = context.kind === "sandbox";
@@ -222,7 +217,6 @@ const InstallPackageForm: React.FC<{
222
217
 
223
218
  const { loading, handleInstallPackages } = useInstallPackages();
224
219
  const onSuccessInstallPackages = () => {
225
- onSuccess();
226
220
  setInput("");
227
221
  };
228
222
 
@@ -363,9 +357,8 @@ const InstallPackageForm: React.FC<{
363
357
  };
364
358
 
365
359
  const PackagesList: React.FC<{
366
- onSuccess: () => void;
367
360
  packages: { name: string; version: string }[];
368
- }> = ({ onSuccess, packages }) => {
361
+ }> = ({ packages }) => {
369
362
  // Sort case-insensitively so packages are strictly alphabetical
370
363
  // regardless of capitalization (package managers sort inconsistently).
371
364
  const sortedPackages = React.useMemo(
@@ -410,8 +403,8 @@ const PackagesList: React.FC<{
410
403
  <TableCell>{item.name}</TableCell>
411
404
  <TableCell>{item.version}</TableCell>
412
405
  <TableCell className="flex justify-end">
413
- <UpgradeButton packageName={item.name} onSuccess={onSuccess} />
414
- <RemoveButton packageName={item.name} onSuccess={onSuccess} />
406
+ <UpgradeButton packageName={item.name} />
407
+ <RemoveButton packageName={item.name} />
415
408
  </TableCell>
416
409
  </TableRow>
417
410
  ))}
@@ -423,40 +416,14 @@ const PackagesList: React.FC<{
423
416
  const UpgradeButton: React.FC<{
424
417
  packageName: string;
425
418
  tags?: { kind: string; value: string }[];
426
- onSuccess: () => void;
427
- }> = ({ packageName, tags, onSuccess }) => {
428
- const [loading, setLoading] = React.useState(false);
429
- const { addPackage } = useRequestClient();
430
-
431
- // Hide upgrade button in WASM
419
+ }> = ({ packageName, tags }) => {
420
+ const { loading, run } = usePackageAction("upgrade", packageName, tags);
432
421
  if (isWasm()) {
433
422
  return null;
434
423
  }
435
424
 
436
- const handleUpgradePackage = async () => {
437
- try {
438
- setLoading(true);
439
- const group = tags?.find((tag) => tag.kind === "group")?.value;
440
- const response = await addPackage({
441
- package: packageName,
442
- upgrade: true,
443
- group,
444
- });
445
- if (response.restartRequired) {
446
- showPackageRestartToast();
447
- } else if (response.success) {
448
- onSuccess();
449
- showUpgradePackageToast(packageName);
450
- } else {
451
- showUpgradePackageToast(packageName, response.error);
452
- }
453
- } finally {
454
- setLoading(false);
455
- }
456
- };
457
-
458
425
  return (
459
- <PackageActionButton onClick={handleUpgradePackage} loading={loading}>
426
+ <PackageActionButton onClick={run} loading={loading}>
460
427
  Upgrade
461
428
  </PackageActionButton>
462
429
  );
@@ -465,34 +432,14 @@ const UpgradeButton: React.FC<{
465
432
  const RemoveButton: React.FC<{
466
433
  packageName: string;
467
434
  tags?: { kind: string; value: string }[];
468
- onSuccess: () => void;
469
- }> = ({ packageName, tags, onSuccess }) => {
470
- const [loading, setLoading] = React.useState(false);
471
- const { removePackage } = useRequestClient();
472
-
473
- const handleRemovePackage = async () => {
474
- try {
475
- setLoading(true);
476
- const group = tags?.find((tag) => tag.kind === "group")?.value;
477
- const response = await removePackage({
478
- package: packageName,
479
- group,
480
- });
481
- if (response.restartRequired) {
482
- showPackageRestartToast();
483
- } else if (response.success) {
484
- onSuccess();
485
- showRemovePackageToast(packageName);
486
- } else {
487
- showRemovePackageToast(packageName, response.error);
488
- }
489
- } finally {
490
- setLoading(false);
491
- }
492
- };
435
+ }> = ({ packageName, tags }) => {
436
+ const { loading, run } = usePackageAction("remove", packageName, tags);
437
+ if (packageName.toLowerCase() === "marimo") {
438
+ return null;
439
+ }
493
440
 
494
441
  return (
495
- <PackageActionButton onClick={handleRemovePackage} loading={loading}>
442
+ <PackageActionButton onClick={run} loading={loading}>
496
443
  Remove
497
444
  </PackageActionButton>
498
445
  );
@@ -502,8 +449,7 @@ const DependencyTree: React.FC<{
502
449
  tree: DependencyTreeNode | null;
503
450
  error?: Error | null;
504
451
  sandboxBackend: "uv" | "pixi" | null;
505
- onSuccess: () => void;
506
- }> = ({ tree, error, sandboxBackend, onSuccess }) => {
452
+ }> = ({ tree, error, sandboxBackend }) => {
507
453
  const [expandedNodes, setExpandedNodes] = React.useState<Set<string>>(
508
454
  new Set(),
509
455
  );
@@ -570,7 +516,6 @@ const DependencyTree: React.FC<{
570
516
  isTopLevel={true}
571
517
  expandedNodes={expandedNodes}
572
518
  onToggle={toggleNode}
573
- onSuccess={onSuccess}
574
519
  />
575
520
  </div>
576
521
  ))}
@@ -586,16 +531,7 @@ const DependencyTreeNode: React.FC<{
586
531
  isTopLevel?: boolean;
587
532
  expandedNodes: Set<string>;
588
533
  onToggle: (nodeId: string) => void;
589
- onSuccess: () => void;
590
- }> = ({
591
- nodeId,
592
- node,
593
- level,
594
- isTopLevel = false,
595
- expandedNodes,
596
- onToggle,
597
- onSuccess,
598
- }) => {
534
+ }> = ({ nodeId, node, level, isTopLevel = false, expandedNodes, onToggle }) => {
599
535
  const hasChildren = node.dependencies.length > 0;
600
536
  const isExpanded = expandedNodes.has(nodeId);
601
537
  const indent = isTopLevel ? 0 : 16 + level * 16; // Top-level uses CSS padding, children use calculated indent
@@ -709,17 +645,9 @@ const DependencyTreeNode: React.FC<{
709
645
  {/* Actions for top-level packages */}
710
646
  {isTopLevel && (
711
647
  <div className="flex gap-1 invisible group-hover:visible">
712
- <UpgradeButton
713
- packageName={node.name}
714
- tags={node.tags}
715
- onSuccess={onSuccess}
716
- />
648
+ <UpgradeButton packageName={node.name} tags={node.tags} />
717
649
 
718
- <RemoveButton
719
- packageName={node.name}
720
- tags={node.tags}
721
- onSuccess={onSuccess}
722
- />
650
+ <RemoveButton packageName={node.name} tags={node.tags} />
723
651
  </div>
724
652
  )}
725
653
  </div>
@@ -736,7 +664,6 @@ const DependencyTreeNode: React.FC<{
736
664
  isTopLevel={false}
737
665
  expandedNodes={expandedNodes}
738
666
  onToggle={onToggle}
739
- onSuccess={onSuccess}
740
667
  />
741
668
  ))}
742
669
  </div>
@@ -0,0 +1,106 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import { Suspense } from "react";
3
+ import { Spinner } from "@/components/icons/spinner";
4
+ import { Button } from "@/components/ui/button";
5
+ import {
6
+ Dialog,
7
+ DialogContent,
8
+ DialogDescription,
9
+ DialogFooter,
10
+ DialogHeader,
11
+ DialogTitle,
12
+ } from "@/components/ui/dialog";
13
+ import { useSandboxController } from "@/core/packages/useSandboxController";
14
+ import { LazyAnyLanguageCodeMirror } from "@/plugins/impl/code/LazyAnyLanguageCodeMirror";
15
+ import { useTheme } from "@/theme/useTheme";
16
+ import { Paths } from "@/utils/paths";
17
+ import { SandboxErrorOutput } from "./sandbox-panel";
18
+
19
+ export function SandboxController({
20
+ onReconnect,
21
+ }: {
22
+ onReconnect: () => Promise<void>;
23
+ }) {
24
+ const {
25
+ filename,
26
+ open,
27
+ setOpen,
28
+ draft,
29
+ setDraft,
30
+ dirty,
31
+ loading,
32
+ saving,
33
+ pending,
34
+ error,
35
+ diagnostic,
36
+ conflict,
37
+ loadManifest,
38
+ saveAndSync,
39
+ } = useSandboxController(onReconnect);
40
+ const { theme } = useTheme();
41
+ return (
42
+ <Dialog open={open} onOpenChange={setOpen}>
43
+ <DialogContent className="sm:max-w-xl grid-cols-1 max-h-[80vh] overflow-auto">
44
+ <DialogHeader>
45
+ <DialogTitle>Edit manifest</DialogTitle>
46
+ <DialogDescription className="font-mono text-xs">
47
+ {Paths.basename(filename ?? "Untitled notebook")} · script metadata
48
+ </DialogDescription>
49
+ </DialogHeader>
50
+ {draft !== null && !loading ? (
51
+ <Suspense fallback={<Spinner />}>
52
+ <LazyAnyLanguageCodeMirror
53
+ language="toml"
54
+ theme={theme}
55
+ value={draft}
56
+ onChange={setDraft}
57
+ editable={!pending}
58
+ height="260px"
59
+ basicSetup={{ lineNumbers: false, foldGutter: false }}
60
+ className="border rounded overflow-hidden"
61
+ aria-label="Notebook manifest"
62
+ />
63
+ </Suspense>
64
+ ) : (
65
+ !error && <Spinner />
66
+ )}
67
+ {diagnostic && <SandboxErrorOutput error={diagnostic} />}
68
+ {conflict && (
69
+ <Button variant="text" size="sm" onClick={loadManifest}>
70
+ Discard draft and reload manifest
71
+ </Button>
72
+ )}
73
+ <DialogFooter className="items-center sm:justify-between gap-3">
74
+ <span className="text-xs text-muted-foreground mr-auto">
75
+ {loading
76
+ ? "Loading…"
77
+ : dirty
78
+ ? "Unsaved changes"
79
+ : draft !== null
80
+ ? "Saved"
81
+ : ""}
82
+ </span>
83
+ <Button variant="text" size="sm" onClick={() => setOpen(false)}>
84
+ Close
85
+ </Button>
86
+ <Button
87
+ size="sm"
88
+ disabled={draft === null || pending}
89
+ onClick={saveAndSync}
90
+ >
91
+ {pending && <Spinner className="size-3 mr-2" />}
92
+ {loading
93
+ ? "Loading…"
94
+ : saving
95
+ ? "Saving…"
96
+ : pending
97
+ ? "Syncing…"
98
+ : dirty
99
+ ? "Save & sync"
100
+ : "Sync"}
101
+ </Button>
102
+ </DialogFooter>
103
+ </DialogContent>
104
+ </Dialog>
105
+ );
106
+ }
@@ -0,0 +1,173 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import { useAtomValue } from "jotai";
3
+ import {
4
+ AlertCircleIcon,
5
+ ChevronUpIcon,
6
+ FileCodeIcon,
7
+ RefreshCwIcon,
8
+ } from "lucide-react";
9
+ import { connectionNoticeAtom } from "@/core/network/connection-notice";
10
+ import { Spinner } from "@/components/icons/spinner";
11
+ import { Button } from "@/components/ui/button";
12
+ import {
13
+ DropdownMenu,
14
+ DropdownMenuContent,
15
+ DropdownMenuItem,
16
+ DropdownMenuTrigger,
17
+ } from "@/components/ui/dropdown-menu";
18
+ import { Tooltip } from "@/components/ui/tooltip";
19
+ import { isConnectedAtom } from "@/core/network/connection";
20
+ import {
21
+ sandboxActionsAtom,
22
+ sandboxAtom,
23
+ sandboxSyncAtom,
24
+ } from "@/core/packages/sandbox-state";
25
+ import { cn } from "@/utils/cn";
26
+
27
+ export function SandboxErrorOutput({ error }: { error: string }) {
28
+ return (
29
+ <pre
30
+ tabIndex={0}
31
+ aria-label="Error details"
32
+ className="mt-3 p-3 rounded border bg-muted/30 text-xs text-muted-foreground whitespace-pre min-w-0 max-w-full max-h-52 overflow-auto"
33
+ >
34
+ {error}
35
+ </pre>
36
+ );
37
+ }
38
+
39
+ export function SandboxStartupPanel() {
40
+ const notice = useAtomValue(connectionNoticeAtom);
41
+ const sandbox = useAtomValue(sandboxAtom);
42
+ const actions = useAtomValue(sandboxActionsAtom);
43
+ if (!notice) {
44
+ return null;
45
+ }
46
+ return (
47
+ <div className="flex-1 min-h-0 overflow-auto p-4 text-sm">
48
+ <div
49
+ className={cn(
50
+ "flex items-center gap-2",
51
+ notice.pending
52
+ ? "text-muted-foreground"
53
+ : "font-medium text-(--red-11)",
54
+ )}
55
+ >
56
+ {notice.pending ? (
57
+ <Spinner className="size-4 shrink-0" aria-hidden={true} />
58
+ ) : (
59
+ <AlertCircleIcon className="size-4 shrink-0" aria-hidden={true} />
60
+ )}
61
+ <h2>{notice.title}</h2>
62
+ </div>
63
+ {!notice.pending && (
64
+ <>
65
+ <p className="mt-2 text-foreground">{notice.description}</p>
66
+ {notice.error && <SandboxErrorOutput error={notice.error} />}
67
+ <div className="flex items-center gap-2 mt-3">
68
+ <Button
69
+ variant="outline"
70
+ size="xs"
71
+ disabled={!actions || sandbox?.manifest == null}
72
+ onClick={() => actions?.editManifest()}
73
+ >
74
+ Edit manifest…
75
+ </Button>
76
+ <Button
77
+ variant="text"
78
+ size="xs"
79
+ disabled={!actions}
80
+ onClick={() => actions?.sync()}
81
+ >
82
+ Retry sync
83
+ </Button>
84
+ </div>
85
+ {sandbox?.manifest == null && (
86
+ <p className="mt-3 text-xs text-muted-foreground">
87
+ A manifest will be available once this new notebook starts.
88
+ </p>
89
+ )}
90
+ </>
91
+ )}
92
+ </div>
93
+ );
94
+ }
95
+
96
+ export function SandboxFooter() {
97
+ const sandbox = useAtomValue(sandboxAtom);
98
+ const connected = useAtomValue(isConnectedAtom);
99
+ const actions = useAtomValue(sandboxActionsAtom);
100
+ const operation = useAtomValue(sandboxSyncAtom);
101
+ const notice = useAtomValue(connectionNoticeAtom);
102
+ if (!sandbox?.backend) {
103
+ return null;
104
+ }
105
+ const pending = operation.pending || notice?.pending;
106
+ const status = operation.pending
107
+ ? "Syncing sandbox…"
108
+ : (notice?.title ?? (connected ? "Sandbox ready" : "Sandbox not started"));
109
+ return (
110
+ <div className="border-t p-1.5 shrink-0">
111
+ <DropdownMenu>
112
+ <Tooltip content={status}>
113
+ <DropdownMenuTrigger asChild={true}>
114
+ <button
115
+ type="button"
116
+ className="flex items-center gap-2 w-full px-2 py-1.5 rounded text-xs text-muted-foreground hover:bg-accent data-[state=open]:bg-accent"
117
+ aria-label={`${sandbox.backend} sandbox actions`}
118
+ >
119
+ <span
120
+ role="status"
121
+ aria-label={status}
122
+ className={cn(
123
+ "size-1.5 shrink-0 rounded-full",
124
+ pending
125
+ ? "bg-amber-500 motion-safe:animate-pulse"
126
+ : notice
127
+ ? "bg-(--red-9)"
128
+ : connected
129
+ ? "bg-emerald-500"
130
+ : "bg-muted-foreground",
131
+ )}
132
+ />
133
+ <span>{sandbox.backend} sandbox</span>
134
+ <span className="ml-auto">
135
+ {pending
136
+ ? operation.pending
137
+ ? "Syncing…"
138
+ : notice?.title
139
+ : ""}
140
+ </span>
141
+ <ChevronUpIcon className="size-3" />
142
+ </button>
143
+ </DropdownMenuTrigger>
144
+ </Tooltip>
145
+ <DropdownMenuContent
146
+ side="top"
147
+ align="start"
148
+ className="w-52"
149
+ sideOffset={8}
150
+ >
151
+ <DropdownMenuItem
152
+ disabled={pending || !actions}
153
+ onSelect={() => {
154
+ void actions?.sync();
155
+ }}
156
+ >
157
+ <RefreshCwIcon className="size-3.5 mr-2" />
158
+ Sync
159
+ </DropdownMenuItem>
160
+ <DropdownMenuItem
161
+ disabled={!actions || sandbox.manifest === null}
162
+ onSelect={() => {
163
+ void actions?.editManifest();
164
+ }}
165
+ >
166
+ <FileCodeIcon className="size-3.5 mr-2" />
167
+ Edit manifest…
168
+ </DropdownMenuItem>
169
+ </DropdownMenuContent>
170
+ </DropdownMenu>
171
+ </div>
172
+ );
173
+ }