@marimo-team/frontend 0.24.3-dev39 → 0.24.3-dev40

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 (144) hide show
  1. package/dist/assets/ConnectedDataExplorerComponent-CD3m13JH.js +1 -0
  2. package/dist/assets/ErrorBoundary-BA_T1McN.js +2 -0
  3. package/dist/assets/LazyAnyLanguageCodeMirror-C9EGRgI3.js +2 -0
  4. package/dist/assets/RunButton-7xbGmbVZ.js +22 -0
  5. package/dist/assets/{abnfDiagram-VCTEODGH-DAeh_Fhj.js → abnfDiagram-VCTEODGH-Cc6OUOjQ.js} +1 -1
  6. package/dist/assets/{add-cell-with-ai-BqPNrEkg.js → add-cell-with-ai-DUqh2oJw.js} +28 -32
  7. package/dist/assets/{agent-panel-0QpsWJ6N.js → agent-panel-f0L3fZhF.js} +5 -5
  8. package/dist/assets/ai-model-dropdown-8G3RZw6w.js +3 -0
  9. package/dist/assets/alert-dialog-CeE3i3Qa.js +7 -0
  10. package/dist/assets/{any-language-editor-DktznOiF.js → any-language-editor-BUGcoAsy.js} +1 -1
  11. package/dist/assets/app-config-button-Vtv3-4qO.js +1 -0
  12. package/dist/assets/{architectureDiagram-5GKGNRK7-CLV_t53p.js → architectureDiagram-5GKGNRK7-KCzfyuLz.js} +1 -1
  13. package/dist/assets/{blockDiagram-I7D4REHJ-4NgsF8dG.js → blockDiagram-I7D4REHJ-Bh4a9Uit.js} +1 -1
  14. package/dist/assets/cache-panel-B4KmMDKe.js +1 -0
  15. package/dist/assets/cells-DdE_4Bcx.js +220 -0
  16. package/dist/assets/{chat-display-f6K2vP1M.js → chat-display-BuvLDWsS.js} +1 -1
  17. package/dist/assets/{chat-panel-CPSz0Ygy.js → chat-panel-Ca_yEWgH.js} +4 -4
  18. package/dist/assets/chat-ui-LpqYylmY.js +4 -0
  19. package/dist/assets/{chunk-IMKFNOWR-gOOmxUZk.js → chunk-IMKFNOWR-BOe730m-.js} +1 -1
  20. package/dist/assets/{chunk-SHT3W25Y-Vz0rwhW1.js → chunk-SHT3W25Y-CnkGlGWz.js} +1 -1
  21. package/dist/assets/{chunk-SVP7TREG-DXVPjbAe.js → chunk-SVP7TREG-CJoSyWpF.js} +1 -1
  22. package/dist/assets/{chunk-TICWLB2K-DwIBziwV.js → chunk-TICWLB2K-i8qWzFVS.js} +1 -1
  23. package/dist/assets/{chunk-YOKDWASO-f1mURkME.js → chunk-YOKDWASO-CaoEAGJk.js} +4 -4
  24. package/dist/assets/{classDiagram-ZZMXUADV-CyUk9nSP.js → classDiagram-ZZMXUADV-CJeFRXIv.js} +1 -1
  25. package/dist/assets/{classDiagram-v2-VYDZK3BY-CyUk9nSP.js → classDiagram-v2-VYDZK3BY-CJeFRXIv.js} +1 -1
  26. package/dist/assets/code-visibility-B1uPwsV_.js +1 -0
  27. package/dist/assets/command-palette-3VHI_Zn-.js +1 -0
  28. package/dist/assets/{common-CHWS0pGT.js → common-CkW66XKl.js} +1 -1
  29. package/dist/assets/{components-v8nHOj_y.js → components-CgLXIuIx.js} +1 -1
  30. package/dist/assets/{components-B8fYemsk.js → components-S8HMrIzn.js} +1 -1
  31. package/dist/assets/{config-BJ_WNC6h.js → config-CMqNngzA.js} +1 -1
  32. package/dist/assets/{copy-icon-BGwpo8Hs.js → copy-icon-DFhUGBjO.js} +1 -1
  33. package/dist/assets/{cynefinDiagram-5FMLGOSQ-DgdyjbQj.js → cynefinDiagram-5FMLGOSQ-CtaDnIMu.js} +1 -1
  34. package/dist/assets/{dagre-GXQ25YYZ-D-zMjnRl.js → dagre-GXQ25YYZ-c1VYIziP.js} +1 -1
  35. package/dist/assets/{dagre-CPZ1FUhr.js → dagre-NrXVevn8.js} +1 -1
  36. package/dist/assets/{data-grid-overlay-editor-CFK1KT2V.js → data-grid-overlay-editor-DSRW7Kut.js} +1 -1
  37. package/dist/assets/dependency-graph-panel-B551oMpv.js +5 -0
  38. package/dist/assets/{diagram-S7CK7UJ4-DgflUEq5.js → diagram-S7CK7UJ4-DqOZpUvg.js} +1 -1
  39. package/dist/assets/{diagram-UQ7AKVKN-m3R2UDJM.js → diagram-UQ7AKVKN-C5FLa5BP.js} +1 -1
  40. package/dist/assets/{diagram-VX7I27RA-Blh2o8ik.js → diagram-VX7I27RA-C11x_qxv.js} +1 -1
  41. package/dist/assets/{diagram-Z3DM3KII-C4PcKTD6.js → diagram-Z3DM3KII-DTmHJEdb.js} +1 -1
  42. package/dist/assets/dist-CyYN7zJg.js +1 -0
  43. package/dist/assets/{documentation-panel-CoSoUakB.js → documentation-panel-DZyABx3u.js} +1 -1
  44. package/dist/assets/dropdown-menu-VuyoeQOD.js +1 -0
  45. package/dist/assets/{ebnfDiagram-PWID7BFC-BGtaPv5f.js → ebnfDiagram-PWID7BFC-BERjo-QO.js} +1 -1
  46. package/dist/assets/edit-page-YjV5QuiF.js +175 -0
  47. package/dist/assets/{erDiagram-RLTQ6QDP-D8JVfIur.js → erDiagram-RLTQ6QDP-CLaxJ9Nx.js} +1 -1
  48. package/dist/assets/error-entries-8TMYgS7M.js +5 -0
  49. package/dist/assets/{error-panel-CdqCDhu4.js → error-panel-CYAgqocU.js} +1 -1
  50. package/dist/assets/feedback-button-BryDuCda.js +10 -0
  51. package/dist/assets/file-explorer-panel-C2BHQXnG.js +1 -0
  52. package/dist/assets/{file-name-input-BQw4Jo-i.js → file-name-input-DFamvCEI.js} +2 -2
  53. package/dist/assets/{flowDiagram-HODETNUW-DMus6jv_.js → flowDiagram-HODETNUW-BIo2cMfZ.js} +1 -1
  54. package/dist/assets/{gallery-page-_mH_5ChL.js → gallery-page-6FjNLb2K.js} +1 -1
  55. package/dist/assets/glide-data-editor-B7hTvwxl.js +131 -0
  56. package/dist/assets/{graphlib-Sg3tw7ov.js → graphlib-DRqVESqZ.js} +1 -1
  57. package/dist/assets/has-Cv16T6xA.js +1 -0
  58. package/dist/assets/{highlighted-body-KPVGNVTW-Bg554UQB.js → highlighted-body-KPVGNVTW-D9V82ncH.js} +1 -1
  59. package/dist/assets/{home-page-hKIN8akr.js → home-page-DoM0lylR.js} +1 -1
  60. package/dist/assets/index-DUgerA4i.js +62 -0
  61. package/dist/assets/{infoDiagram-27XIBGKW-DYsYx_PP.js → infoDiagram-27XIBGKW-BjPzhD7z.js} +1 -1
  62. package/dist/assets/input-BDakodZ2.js +7 -0
  63. package/dist/assets/{ishikawaDiagram-5VMMS53U-D1Rpw_lT.js → ishikawaDiagram-5VMMS53U-BsgWAUan.js} +1 -1
  64. package/dist/assets/{kanban-definition-UXKFOSKX-CGxkIydR.js → kanban-definition-UXKFOSKX-BbFz76xc.js} +1 -1
  65. package/dist/assets/{logs-panel-C4k8cMGx.js → logs-panel-w5wJQQQl.js} +1 -1
  66. package/dist/assets/mermaid-HWGCJPDP-UrYE0_I-.js +1 -0
  67. package/dist/assets/{mermaid-BLxkTwc2.js → mermaid-Rq-qrJX-.js} +4 -4
  68. package/dist/assets/{mindmap-definition-YA3MSWOX-BiuGfVWP.js → mindmap-definition-YA3MSWOX-FLyXxd_r.js} +1 -1
  69. package/dist/assets/{number-overlay-editor-Ck2sCaO7.js → number-overlay-editor-D_DRYHem.js} +1 -1
  70. package/dist/assets/{outline-panel-Z6FAHcVy.js → outline-panel-2qHnFwb2.js} +1 -1
  71. package/dist/assets/{packages-panel-CgL87fcO.js → packages-panel-1kXiKe65.js} +1 -1
  72. package/dist/assets/panels-Dtl3yI4T.js +33 -0
  73. package/dist/assets/{pegDiagram-XKGWAZYB-Ci7mDvEz.js → pegDiagram-XKGWAZYB-iq1r0G9S.js} +1 -1
  74. package/dist/assets/{pieDiagram-E7YTZNPT-DZbp0Icu.js → pieDiagram-E7YTZNPT-72uzmec3.js} +1 -1
  75. package/dist/assets/process-output-B5FF-e40.js +1 -0
  76. package/dist/assets/{railroadDiagram-O6MQD6OU-CzXIAsPx.js → railroadDiagram-O6MQD6OU-BSZOMALK.js} +1 -1
  77. package/dist/assets/{requirementDiagram-BXWQKSXE-DsIrXWi5.js → requirementDiagram-BXWQKSXE-BYOHjVDS.js} +1 -1
  78. package/dist/assets/{reveal-component-CnW6op6f.js → reveal-component-ChlwzPFi.js} +4 -4
  79. package/dist/assets/run-page-DOESWIjk.js +1 -0
  80. package/dist/assets/{scratchpad-panel-DktgeGw9.js → scratchpad-panel-CtYWu9UC.js} +1 -1
  81. package/dist/assets/{secrets-panel-Di8040gJ.js → secrets-panel-CEdCTqEt.js} +1 -1
  82. package/dist/assets/select-BplWpfFo.js +1 -0
  83. package/dist/assets/{sequenceDiagram-WJ2MYXX4-YEyNvwCq.js → sequenceDiagram-WJ2MYXX4-B2eZmj6C.js} +1 -1
  84. package/dist/assets/session-panel-CdwTrjft.js +1 -0
  85. package/dist/assets/skeleton-CKpBjoLm.js +1 -0
  86. package/dist/assets/snippets-panel-DSOmTAOj.js +1 -0
  87. package/dist/assets/{stateDiagram-D77RDMKH-B3Ja9Vk7.js → stateDiagram-D77RDMKH-Dxjzxwy_.js} +1 -1
  88. package/dist/assets/{stateDiagram-v2-MP3YSRHH-Bn7tPa_c.js → stateDiagram-v2-MP3YSRHH-DiVxo_WD.js} +1 -1
  89. package/dist/assets/{swimlanes-42K2YHIH-DTgRQfmF.js → swimlanes-42K2YHIH-Cu1H_MsS.js} +1 -1
  90. package/dist/assets/{swimlanesDiagram-VR7AAH4N-DKJ2qI6J.js → swimlanesDiagram-VR7AAH4N-CverMF1d.js} +1 -1
  91. package/dist/assets/{swiper-component-CYrf6kVu.js → swiper-component-Dsu9hhfr.js} +1 -1
  92. package/dist/assets/{terminal-CBss1CM1.js → terminal-CY2G-VQ_.js} +3 -3
  93. package/dist/assets/{timeline-definition-24CTP7MA-CKo5fHyB.js → timeline-definition-24CTP7MA-BTVwucN-.js} +1 -1
  94. package/dist/assets/toast-KNfsFUiB.js +1 -0
  95. package/dist/assets/tooltip-DR2Z2N4w.js +1 -0
  96. package/dist/assets/{tracing-BBufraD6.js → tracing-8vY9-6Pe.js} +1 -1
  97. package/dist/assets/tracing-panel-ChY6mG0b.js +2 -0
  98. package/dist/assets/use-restore-focus-B98SEiGc.js +5 -0
  99. package/dist/assets/useCellActionButton-D9N-pQkE.js +1 -0
  100. package/dist/assets/{vega-component-BUKpKmrE.js → vega-component-CcwbASQP.js} +1 -1
  101. package/dist/assets/{vega-embed-container-BgSrb2ci.js → vega-embed-container-BAidu_l4.js} +1 -1
  102. package/dist/assets/{vennDiagram-4TSXK5OY-CA_b78pk.js → vennDiagram-4TSXK5OY-_-2BMmjK.js} +1 -1
  103. package/dist/assets/{wardleyDiagram-VM6X3IG4-CT2UYDxA.js → wardleyDiagram-VM6X3IG4-BewFANz3.js} +1 -1
  104. package/dist/assets/write-secret-modal-CBUZw27N.js +2 -0
  105. package/dist/assets/{xychartDiagram-S5SC5T6Z-BOvLySSM.js → xychartDiagram-S5SC5T6Z-CIsN_xdf.js} +1 -1
  106. package/dist/index.html +32 -31
  107. package/package.json +1 -1
  108. package/src/components/editor/boundary/ErrorBoundary.tsx +38 -16
  109. package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +311 -0
  110. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +94 -0
  111. package/src/components/editor/chrome/components/feedback-button.tsx +53 -33
  112. package/src/components/ui/use-toast.ts +8 -0
  113. package/dist/assets/ConnectedDataExplorerComponent-B52ZeTyE.js +0 -1
  114. package/dist/assets/ErrorBoundary-kab1AKk9.js +0 -1
  115. package/dist/assets/LazyAnyLanguageCodeMirror-DLXghRUF.js +0 -2
  116. package/dist/assets/RunButton-BQonXEus.js +0 -22
  117. package/dist/assets/ai-model-dropdown-JyOkbRgs.js +0 -3
  118. package/dist/assets/alert-dialog-CTZhLA-n.js +0 -11
  119. package/dist/assets/app-config-button-hlzBggjV.js +0 -1
  120. package/dist/assets/cache-panel-JD-3Sv8N.js +0 -1
  121. package/dist/assets/cells-CP3hwqVX.js +0 -220
  122. package/dist/assets/chat-ui-DJskwz2p.js +0 -4
  123. package/dist/assets/command-palette-B8zE6Ssx.js +0 -1
  124. package/dist/assets/dependency-graph-panel-D_AqnRMs.js +0 -5
  125. package/dist/assets/dist-6DMifdoa.js +0 -1
  126. package/dist/assets/dist-Cjbb3ZZt.js +0 -1
  127. package/dist/assets/dropdown-menu-qMsCfCym.js +0 -1
  128. package/dist/assets/edit-page-Qqpz6lsF.js +0 -184
  129. package/dist/assets/file-explorer-panel-DcWEU9mt.js +0 -1
  130. package/dist/assets/glide-data-editor-CFcsGnit.js +0 -131
  131. package/dist/assets/has-DXmEv5FL.js +0 -1
  132. package/dist/assets/index-qY3lu9r4.js +0 -62
  133. package/dist/assets/input-DPJmbuuZ.js +0 -7
  134. package/dist/assets/mermaid-HWGCJPDP-BZ4nvis-.js +0 -1
  135. package/dist/assets/panels-BSvT-tNo.js +0 -33
  136. package/dist/assets/process-output-COWXLjOr.js +0 -1
  137. package/dist/assets/run-page-B_JOrxWI.js +0 -1
  138. package/dist/assets/select-C_hPB6Bz.js +0 -1
  139. package/dist/assets/session-panel-FmN2Ix-x.js +0 -1
  140. package/dist/assets/snippets-panel-BmXCx6yt.js +0 -1
  141. package/dist/assets/tooltip-Dnxk1tcQ.js +0 -1
  142. package/dist/assets/tracing-panel-lUoyxh7t.js +0 -2
  143. package/dist/assets/useCellActionButton-VJCYmjUy.js +0 -1
  144. package/dist/assets/write-secret-modal-B5x3omai.js +0 -2
package/dist/index.html CHANGED
@@ -66,7 +66,7 @@
66
66
  <marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
67
67
  <!-- /TODO -->
68
68
  <title>{{ title }}</title>
69
- <script type="module" crossorigin src="./assets/index-qY3lu9r4.js"></script>
69
+ <script type="module" crossorigin src="./assets/index-DUgerA4i.js"></script>
70
70
  <link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-B0Z9INg1.js">
71
71
  <link rel="modulepreload" crossorigin href="./assets/react-CUdNIagt.js">
72
72
  <link rel="modulepreload" crossorigin href="./assets/compiler-runtime-BQ9S8nyo.js">
@@ -91,44 +91,45 @@
91
91
  <link rel="modulepreload" crossorigin href="./assets/clsx-DB0hHKMi.js">
92
92
  <link rel="modulepreload" crossorigin href="./assets/cn-ldLVeaqm.js">
93
93
  <link rel="modulepreload" crossorigin href="./assets/fullscreen-BmzAqMKq.js">
94
- <link rel="modulepreload" crossorigin href="./assets/dist-Cjbb3ZZt.js">
94
+ <link rel="modulepreload" crossorigin href="./assets/dist-CyYN7zJg.js">
95
95
  <link rel="modulepreload" crossorigin href="./assets/menu-items-BBdeXCvU.js">
96
+ <link rel="modulepreload" crossorigin href="./assets/use-restore-focus-B98SEiGc.js">
96
97
  <link rel="modulepreload" crossorigin href="./assets/button-BoklZTGL.js">
97
- <link rel="modulepreload" crossorigin href="./assets/alert-dialog-CTZhLA-n.js">
98
- <link rel="modulepreload" crossorigin href="./assets/dist-6DMifdoa.js">
99
98
  <link rel="modulepreload" crossorigin href="./assets/createLucideIcon-rHn2EdoM.js">
100
99
  <link rel="modulepreload" crossorigin href="./assets/check-Wea4hZ6R.js">
101
100
  <link rel="modulepreload" crossorigin href="./assets/context-BFOBKCJB.js">
102
101
  <link rel="modulepreload" crossorigin href="./assets/useNumberFormatter-C4-_TnkF.js">
103
- <link rel="modulepreload" crossorigin href="./assets/select-C_hPB6Bz.js">
102
+ <link rel="modulepreload" crossorigin href="./assets/select-BplWpfFo.js">
104
103
  <link rel="modulepreload" crossorigin href="./assets/circle-CeQt3rdW.js">
105
- <link rel="modulepreload" crossorigin href="./assets/tooltip-Dnxk1tcQ.js">
106
- <link rel="modulepreload" crossorigin href="./assets/dist-BczecT6V.js">
107
- <link rel="modulepreload" crossorigin href="./assets/dist-BTskHGpb.js">
108
- <link rel="modulepreload" crossorigin href="./assets/arrays-BqUx5USx.js">
109
- <link rel="modulepreload" crossorigin href="./assets/once-Haz_uxEL.js">
110
- <link rel="modulepreload" crossorigin href="./assets/capabilities-Bj3s1hGN.js">
111
- <link rel="modulepreload" crossorigin href="./assets/cjs-C49f7GXV.js">
112
- <link rel="modulepreload" crossorigin href="./assets/createReducer-BPvK7C_R.js">
113
- <link rel="modulepreload" crossorigin href="./assets/dist-Ccyblc8N.js">
114
- <link rel="modulepreload" crossorigin href="./assets/marked.esm-B_3iMIUq.js">
115
- <link rel="modulepreload" crossorigin href="./assets/strings-BHZPE0Mc.js">
116
- <link rel="modulepreload" crossorigin href="./assets/requests-yTHMxhVa.js">
117
- <link rel="modulepreload" crossorigin href="./assets/dist-BN-7G8qZ.js">
104
+ <link rel="modulepreload" crossorigin href="./assets/toast-KNfsFUiB.js">
105
+ <link rel="modulepreload" crossorigin href="./assets/tooltip-DR2Z2N4w.js">
118
106
  <link rel="modulepreload" crossorigin href="./assets/paths-CzfpItSz.js">
119
107
  <link rel="modulepreload" crossorigin href="./assets/useLifecycle-DKSBdWUf.js">
120
108
  <link rel="modulepreload" crossorigin href="./assets/toDate-BbJ1_N2T.js">
121
109
  <link rel="modulepreload" crossorigin href="./assets/database-zap-CrkOvbyN.js">
110
+ <link rel="modulepreload" crossorigin href="./assets/alert-dialog-CeE3i3Qa.js">
111
+ <link rel="modulepreload" crossorigin href="./assets/arrays-BqUx5USx.js">
112
+ <link rel="modulepreload" crossorigin href="./assets/once-Haz_uxEL.js">
122
113
  <link rel="modulepreload" crossorigin href="./assets/numbers-DsgsDslU.js">
123
114
  <link rel="modulepreload" crossorigin href="./assets/useDebounce-DMbg9X18.js">
124
- <link rel="modulepreload" crossorigin href="./assets/input-DPJmbuuZ.js">
125
- <link rel="modulepreload" crossorigin href="./assets/uuid-k9DpjH68.js">
115
+ <link rel="modulepreload" crossorigin href="./assets/input-BDakodZ2.js">
126
116
  <link rel="modulepreload" crossorigin href="./assets/use-toast-CC89xOwH.js">
127
- <link rel="modulepreload" crossorigin href="./assets/write-secret-modal-B5x3omai.js">
117
+ <link rel="modulepreload" crossorigin href="./assets/requests-yTHMxhVa.js">
118
+ <link rel="modulepreload" crossorigin href="./assets/uuid-k9DpjH68.js">
119
+ <link rel="modulepreload" crossorigin href="./assets/write-secret-modal-CBUZw27N.js">
128
120
  <link rel="modulepreload" crossorigin href="./assets/plus-gbN72xHe.js">
129
121
  <link rel="modulepreload" crossorigin href="./assets/trash-2-BJG-7Qob.js">
130
- <link rel="modulepreload" crossorigin href="./assets/badge-DFf033uX.js">
131
122
  <link rel="modulepreload" crossorigin href="./assets/preload-helper-HclGiUj8.js">
123
+ <link rel="modulepreload" crossorigin href="./assets/dist-BczecT6V.js">
124
+ <link rel="modulepreload" crossorigin href="./assets/dist-BTskHGpb.js">
125
+ <link rel="modulepreload" crossorigin href="./assets/capabilities-Bj3s1hGN.js">
126
+ <link rel="modulepreload" crossorigin href="./assets/cjs-C49f7GXV.js">
127
+ <link rel="modulepreload" crossorigin href="./assets/createReducer-BPvK7C_R.js">
128
+ <link rel="modulepreload" crossorigin href="./assets/dist-Ccyblc8N.js">
129
+ <link rel="modulepreload" crossorigin href="./assets/marked.esm-B_3iMIUq.js">
130
+ <link rel="modulepreload" crossorigin href="./assets/strings-BHZPE0Mc.js">
131
+ <link rel="modulepreload" crossorigin href="./assets/dist-BN-7G8qZ.js">
132
+ <link rel="modulepreload" crossorigin href="./assets/badge-DFf033uX.js">
132
133
  <link rel="modulepreload" crossorigin href="./assets/dist-CiUBikfn.js">
133
134
  <link rel="modulepreload" crossorigin href="./assets/dist-MRn68vX1.js">
134
135
  <link rel="modulepreload" crossorigin href="./assets/dist-Bviq_Dee.js">
@@ -138,18 +139,18 @@
138
139
  <link rel="modulepreload" crossorigin href="./assets/useTheme-Ho3YdAx3.js">
139
140
  <link rel="modulepreload" crossorigin href="./assets/useAsyncData-DucTwMkf.js">
140
141
  <link rel="modulepreload" crossorigin href="./assets/purify.es-CYRiAeUx.js">
141
- <link rel="modulepreload" crossorigin href="./assets/cells-CP3hwqVX.js">
142
+ <link rel="modulepreload" crossorigin href="./assets/cells-DdE_4Bcx.js">
142
143
  <link rel="modulepreload" crossorigin href="./assets/get-DjNf4SIX.js">
143
- <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-kab1AKk9.js">
144
- <link rel="modulepreload" crossorigin href="./assets/config-BJ_WNC6h.js">
145
- <link rel="modulepreload" crossorigin href="./assets/chevron-right-DOPs2jx8.js">
146
- <link rel="modulepreload" crossorigin href="./assets/dropdown-menu-qMsCfCym.js">
147
- <link rel="modulepreload" crossorigin href="./assets/LazyAnyLanguageCodeMirror-DLXghRUF.js">
148
144
  <link rel="modulepreload" crossorigin href="./assets/copy-RyCOE8jo.js">
145
+ <link rel="modulepreload" crossorigin href="./assets/copy-BhJktFeI.js">
146
+ <link rel="modulepreload" crossorigin href="./assets/copy-icon-DFhUGBjO.js">
147
+ <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-BA_T1McN.js">
148
+ <link rel="modulepreload" crossorigin href="./assets/config-CMqNngzA.js">
149
+ <link rel="modulepreload" crossorigin href="./assets/chevron-right-DOPs2jx8.js">
150
+ <link rel="modulepreload" crossorigin href="./assets/dropdown-menu-VuyoeQOD.js">
151
+ <link rel="modulepreload" crossorigin href="./assets/LazyAnyLanguageCodeMirror-C9EGRgI3.js">
149
152
  <link rel="modulepreload" crossorigin href="./assets/hat-glasses-DVgK5i5l.js">
150
153
  <link rel="modulepreload" crossorigin href="./assets/package-BeYhVWvM.js">
151
- <link rel="modulepreload" crossorigin href="./assets/copy-BhJktFeI.js">
152
- <link rel="modulepreload" crossorigin href="./assets/copy-icon-BGwpo8Hs.js">
153
154
  <link rel="modulepreload" crossorigin href="./assets/errors-D9vyuMar.js">
154
155
  <link rel="modulepreload" crossorigin href="./assets/defaultLocale-CNPGWpMu.js">
155
156
  <link rel="modulepreload" crossorigin href="./assets/precisionRound-Bq_nmf5u.js">
@@ -157,7 +158,7 @@
157
158
  <link rel="modulepreload" crossorigin href="./assets/vega-loader.browser-CLRkNgm7.js">
158
159
  <link rel="modulepreload" crossorigin href="./assets/tooltip-B1vGi-z4.js">
159
160
  <link rel="modulepreload" crossorigin href="./assets/micromark-factory-space-D9Dr-k4J.js">
160
- <link rel="modulepreload" crossorigin href="./assets/chunk-YOKDWASO-f1mURkME.js">
161
+ <link rel="modulepreload" crossorigin href="./assets/chunk-YOKDWASO-CaoEAGJk.js">
161
162
  <link rel="stylesheet" crossorigin href="./assets/cells-0PFKL3SH.css">
162
163
  <link rel="stylesheet" crossorigin href="./assets/index-B8OSEJVD.css">
163
164
  </head>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/frontend",
3
- "version": "0.24.3-dev39",
3
+ "version": "0.24.3-dev40",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -1,11 +1,21 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
- import type { PropsWithChildren } from "react";
2
+ import { Provider } from "jotai";
3
+ import { type PropsWithChildren, lazy, Suspense, useState } from "react";
3
4
  import {
4
5
  type FallbackProps,
5
6
  ErrorBoundary as ReactErrorBoundary,
6
7
  } from "react-error-boundary";
7
- import { Constants } from "@/core/constants";
8
+ import { store } from "@/core/state/jotai";
8
9
  import { Button } from "../../ui/button";
10
+ import { Dialog, DialogTrigger } from "../../ui/dialog";
11
+ import { Toaster } from "../../ui/toaster";
12
+ import { TooltipProvider } from "../../ui/tooltip";
13
+
14
+ const FeedbackModal = lazy(() =>
15
+ import("../chrome/components/feedback-button").then((mod) => ({
16
+ default: mod.FeedbackModal,
17
+ })),
18
+ );
9
19
 
10
20
  export const ErrorBoundary: React.FC<PropsWithChildren> = (props) => {
11
21
  return (
@@ -16,26 +26,38 @@ export const ErrorBoundary: React.FC<PropsWithChildren> = (props) => {
16
26
  };
17
27
 
18
28
  const FallbackComponent: React.FC<FallbackProps> = (props) => {
29
+ const [open, setOpen] = useState(false);
30
+
19
31
  return (
20
- <div className="flex-1 flex items-center justify-center flex-col space-y-4 max-w-2xl mx-auto px-6">
32
+ <div className="flex-1 flex items-center justify-center flex-col space-y-4 max-w-2xl mx-auto px-6 pb-6">
21
33
  <h1 className="text-2xl font-bold">Something went wrong</h1>
22
34
  <pre className="text-xs bg-muted/40 border rounded-md p-4 max-w-[80%] whitespace-normal">
23
35
  {props.error?.message}
24
36
  </pre>
25
- <div>
26
- If this is an issue with marimo, please report it on{" "}
27
- <a href={Constants.issuesPage} target="_blank" className="underline">
28
- GitHub
29
- </a>
30
- .
37
+ <div className="flex flex-wrap items-center justify-center gap-2">
38
+ <Dialog open={open} onOpenChange={setOpen}>
39
+ <DialogTrigger asChild={true}>
40
+ <Button variant="outline">Report an issue</Button>
41
+ </DialogTrigger>
42
+ {open && (
43
+ <Provider store={store}>
44
+ <TooltipProvider>
45
+ <Suspense fallback={null}>
46
+ <FeedbackModal />
47
+ </Suspense>
48
+ <Toaster />
49
+ </TooltipProvider>
50
+ </Provider>
51
+ )}
52
+ </Dialog>
53
+ <Button
54
+ data-testid="reset-error-boundary-button"
55
+ onClick={props.resetErrorBoundary}
56
+ variant="outline"
57
+ >
58
+ Try again
59
+ </Button>
31
60
  </div>
32
- <Button
33
- data-testid="reset-error-boundary-button"
34
- onClick={props.resetErrorBoundary}
35
- variant="outline"
36
- >
37
- Try again
38
- </Button>
39
61
  </div>
40
62
  );
41
63
  };
@@ -0,0 +1,311 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { fireEvent, render, screen, waitFor } from "@testing-library/react";
4
+ import type { PropsWithChildren, ReactNode } from "react";
5
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
+ import { MockRequestClient } from "@/__mocks__/requests";
7
+ import { ModalProvider } from "@/components/modal/ImperativeModal";
8
+ import { TooltipProvider } from "@/components/ui/tooltip";
9
+ import { clearToasts } from "@/components/ui/use-toast";
10
+ import { initialNotebookState, notebookAtom } from "@/core/cells/cells";
11
+ import { viewStateAtom } from "@/core/mode";
12
+ import { connectionAtom } from "@/core/network/connection";
13
+ import { requestClientAtom } from "@/core/network/requests";
14
+ import type { EnvironmentInfo } from "@/core/network/types";
15
+ import { filenameAtom } from "@/core/saving/file-state";
16
+ import { store } from "@/core/state/jotai";
17
+ import { WebSocketState } from "@/core/websocket/types";
18
+ import { ErrorBoundary } from "../ErrorBoundary";
19
+
20
+ vi.mock("@/utils/copy", () => ({
21
+ copyToClipboard: vi.fn().mockResolvedValue(undefined),
22
+ }));
23
+
24
+ const environment: EnvironmentInfo = {
25
+ marimo: "1.2.3",
26
+ editable: false,
27
+ location: "~/.venv/site-packages/marimo",
28
+ OS: "Darwin",
29
+ "OS Version": "25.0",
30
+ Processor: "arm",
31
+ "Python Version": "3.12.9",
32
+ Locale: "en_US",
33
+ Binaries: { Browser: "chrome 140", Node: "v22", uv: "0.11" },
34
+ Dependencies: { click: "8.4.2" },
35
+ "Optional Dependencies": { pandas: "3.0.0" },
36
+ "Experimental Flags": {},
37
+ };
38
+
39
+ const CRASH_MESSAGE = "cell output crashed";
40
+
41
+ function CrashingChild(): never {
42
+ throw new Error(CRASH_MESSAGE);
43
+ }
44
+
45
+ function RecoverableChild({ crash }: { crash: boolean }) {
46
+ if (crash) {
47
+ throw new Error(CRASH_MESSAGE);
48
+ }
49
+ return <p>recovered child</p>;
50
+ }
51
+
52
+ function DescendantProviders({ children }: PropsWithChildren) {
53
+ return (
54
+ <TooltipProvider>
55
+ <ModalProvider>{children}</ModalProvider>
56
+ </TooltipProvider>
57
+ );
58
+ }
59
+
60
+ function isExpectedReactExceptionOutput(args: unknown[]): boolean {
61
+ return args.some((arg) => {
62
+ if (arg instanceof Error) {
63
+ return arg.message.includes(CRASH_MESSAGE);
64
+ }
65
+ return (
66
+ typeof arg === "string" &&
67
+ (arg.includes(CRASH_MESSAGE) ||
68
+ arg.includes("The above error occurred") ||
69
+ arg.includes("React will try to recreate this component tree"))
70
+ );
71
+ });
72
+ }
73
+
74
+ function suppressExpectedReactException() {
75
+ return vi.spyOn(console, "error").mockImplementation((...args) => {
76
+ if (isExpectedReactExceptionOutput(args)) {
77
+ return;
78
+ }
79
+ throw new Error(`Unexpected console.error: ${args.map(String).join(" ")}`);
80
+ });
81
+ }
82
+
83
+ let consoleError: ReturnType<typeof vi.spyOn> | undefined;
84
+
85
+ function renderCrashedBoundary(child: ReactNode = <CrashingChild />) {
86
+ consoleError?.mockRestore();
87
+ consoleError = suppressExpectedReactException();
88
+ return render(<ErrorBoundary>{child}</ErrorBoundary>);
89
+ }
90
+
91
+ function setRequestClient(
92
+ overrides?: Parameters<typeof MockRequestClient.create>[0],
93
+ ) {
94
+ const client = MockRequestClient.create(overrides);
95
+ store.set(requestClientAtom, client);
96
+ return client;
97
+ }
98
+
99
+ async function openReportDialog() {
100
+ const trigger = screen.getByRole("button", { name: "Report an issue" });
101
+ trigger.focus();
102
+ fireEvent.click(trigger);
103
+ return screen.findByRole("dialog");
104
+ }
105
+
106
+ async function expectReportButtonFocused() {
107
+ await waitFor(() => {
108
+ expect(
109
+ screen.getByRole("button", { name: "Report an issue" }),
110
+ ).toHaveFocus();
111
+ });
112
+ }
113
+
114
+ async function closeReportDialog(method: "escape" | "close") {
115
+ const dialog = await screen.findByRole("dialog");
116
+ if (method === "escape") {
117
+ fireEvent.keyDown(dialog, { key: "Escape" });
118
+ } else {
119
+ fireEvent.click(screen.getByRole("button", { name: "Close" }));
120
+ }
121
+ await waitFor(() => {
122
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
123
+ });
124
+ await expectReportButtonFocused();
125
+ }
126
+
127
+ async function expectRealReportModal() {
128
+ const dialog = await openReportDialog();
129
+ expect(dialog).toHaveTextContent("Report an issue");
130
+ expect(screen.getByRole("link", { name: "Open GitHub issue" })).toBeVisible();
131
+ expect(
132
+ screen.getByRole("checkbox", { name: "Include errors" }),
133
+ ).toBeVisible();
134
+ expect(
135
+ screen.getByRole("checkbox", { name: "Include notebook code" }),
136
+ ).toBeVisible();
137
+ await screen.findByText("Environment details");
138
+ return dialog;
139
+ }
140
+
141
+ function resetSharedState() {
142
+ localStorage.clear();
143
+ clearToasts();
144
+ store.set(requestClientAtom, null);
145
+ store.set(notebookAtom, initialNotebookState());
146
+ store.set(viewStateAtom, { mode: "edit", cellAnchor: null });
147
+ store.set(connectionAtom, { state: WebSocketState.OPEN });
148
+ store.set(filenameAtom, "/project/example.py");
149
+ }
150
+
151
+ describe("ErrorBoundary report dialog", () => {
152
+ beforeEach(() => {
153
+ resetSharedState();
154
+ });
155
+
156
+ afterEach(() => {
157
+ consoleError?.mockRestore();
158
+ consoleError = undefined;
159
+ resetSharedState();
160
+ });
161
+
162
+ it("opens the report modal after a child render exception", async () => {
163
+ const { getEnvironmentInfo } = setRequestClient({
164
+ getEnvironmentInfo: vi.fn().mockResolvedValue(environment),
165
+ });
166
+
167
+ renderCrashedBoundary();
168
+
169
+ expect(screen.getByText("Something went wrong")).toBeVisible();
170
+ expect(screen.getByText("cell output crashed")).toBeVisible();
171
+ expect(screen.getByTestId("reset-error-boundary-button")).toBeVisible();
172
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
173
+ expect(getEnvironmentInfo).not.toHaveBeenCalled();
174
+
175
+ await expectRealReportModal();
176
+ await waitFor(() => expect(getEnvironmentInfo).toHaveBeenCalledOnce());
177
+ });
178
+
179
+ it("still opens one report dialog after descendant providers disappear", async () => {
180
+ const { getEnvironmentInfo } = setRequestClient({
181
+ getEnvironmentInfo: vi.fn().mockResolvedValue(environment),
182
+ });
183
+
184
+ renderCrashedBoundary(
185
+ <DescendantProviders>
186
+ <CrashingChild />
187
+ </DescendantProviders>,
188
+ );
189
+
190
+ await expectRealReportModal();
191
+ expect(screen.getAllByRole("dialog")).toHaveLength(1);
192
+ await waitFor(() => expect(getEnvironmentInfo).toHaveBeenCalledOnce());
193
+ });
194
+
195
+ it("shows partial diagnostics when the request client is missing", async () => {
196
+ renderCrashedBoundary();
197
+
198
+ await openReportDialog();
199
+ await screen.findByText("Environment details");
200
+
201
+ expect(
202
+ screen.getByText("Server environment information unavailable"),
203
+ ).toBeVisible();
204
+ expect(
205
+ screen.queryByText("Loading environment details…"),
206
+ ).not.toBeInTheDocument();
207
+ expect(
208
+ screen.queryByRole("button", { name: "Retry" }),
209
+ ).not.toBeInTheDocument();
210
+ expect(
211
+ screen.getByRole("checkbox", { name: "Include notebook code" }),
212
+ ).toBeDisabled();
213
+ expect(screen.getByText("Notebook source is unavailable.")).toBeVisible();
214
+ const link = screen.getByRole("link", { name: "Open GitHub issue" });
215
+ expect(link.getAttribute("href") ?? "").toContain("&env=");
216
+ });
217
+
218
+ it("does not request environment or source while the report dialog is closed", async () => {
219
+ localStorage.setItem(
220
+ "marimo:issue-report:include-code",
221
+ JSON.stringify(true),
222
+ );
223
+ const { getEnvironmentInfo, readCode } = setRequestClient({
224
+ getEnvironmentInfo: vi.fn().mockResolvedValue(environment),
225
+ readCode: vi.fn().mockResolvedValue({ contents: "import marimo" }),
226
+ });
227
+
228
+ renderCrashedBoundary();
229
+
230
+ expect(screen.getByText("Something went wrong")).toBeVisible();
231
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
232
+ expect(getEnvironmentInfo).not.toHaveBeenCalled();
233
+ expect(readCode).not.toHaveBeenCalled();
234
+ });
235
+
236
+ it("restores focus to the report button after closing with Escape", async () => {
237
+ setRequestClient({
238
+ getEnvironmentInfo: vi.fn().mockResolvedValue(environment),
239
+ });
240
+ renderCrashedBoundary();
241
+ await openReportDialog();
242
+ await closeReportDialog("escape");
243
+ expect(screen.getByText(CRASH_MESSAGE)).toBeVisible();
244
+ });
245
+
246
+ it("restores focus to the report button after closing with the close control", async () => {
247
+ setRequestClient({
248
+ getEnvironmentInfo: vi.fn().mockResolvedValue(environment),
249
+ });
250
+ renderCrashedBoundary();
251
+ await openReportDialog();
252
+ await closeReportDialog("close");
253
+ expect(screen.getByText(CRASH_MESSAGE)).toBeVisible();
254
+ });
255
+
256
+ it("reopens the report dialog while the original error remains", async () => {
257
+ setRequestClient({
258
+ getEnvironmentInfo: vi.fn().mockResolvedValue(environment),
259
+ });
260
+ renderCrashedBoundary();
261
+ await openReportDialog();
262
+ await closeReportDialog("escape");
263
+ expect(screen.getByText(CRASH_MESSAGE)).toBeVisible();
264
+ await expectRealReportModal();
265
+ expect(screen.getByText(CRASH_MESSAGE)).toBeVisible();
266
+ });
267
+
268
+ it("restores the child after try again once the failure is cleared", () => {
269
+ setRequestClient({
270
+ getEnvironmentInfo: vi.fn().mockResolvedValue(environment),
271
+ });
272
+ const view = renderCrashedBoundary(<RecoverableChild crash={true} />);
273
+ expect(screen.getByText("Something went wrong")).toBeVisible();
274
+
275
+ view.rerender(
276
+ <ErrorBoundary>
277
+ <RecoverableChild crash={false} />
278
+ </ErrorBoundary>,
279
+ );
280
+ fireEvent.click(screen.getByTestId("reset-error-boundary-button"));
281
+
282
+ expect(screen.getByText("recovered child")).toBeVisible();
283
+ expect(screen.queryByText("Something went wrong")).not.toBeInTheDocument();
284
+ });
285
+
286
+ it("does not read notebook source when opened with fresh inclusion preferences", async () => {
287
+ const { readCode } = setRequestClient({
288
+ getEnvironmentInfo: vi.fn().mockResolvedValue(environment),
289
+ readCode: vi.fn().mockResolvedValue({ contents: "import marimo" }),
290
+ });
291
+
292
+ renderCrashedBoundary();
293
+ await expectRealReportModal();
294
+
295
+ expect(readCode).not.toHaveBeenCalled();
296
+ });
297
+
298
+ it("renders the copy toast after the ancestor toaster is gone", async () => {
299
+ setRequestClient({
300
+ getEnvironmentInfo: vi.fn().mockResolvedValue(environment),
301
+ });
302
+ renderCrashedBoundary();
303
+ await expectRealReportModal();
304
+
305
+ fireEvent.click(
306
+ screen.getByRole("button", { name: "Copy environment JSON" }),
307
+ );
308
+
309
+ expect(await screen.findByText("Environment details copied")).toBeVisible();
310
+ });
311
+ });
@@ -208,4 +208,98 @@ describe("FeedbackModal issue reporting", () => {
208
208
  expect(href).toContain(encodeURIComponent('"marimo": "1.2.3"'));
209
209
  });
210
210
  });
211
+
212
+ it("shows partial environment details when the request client is missing", async () => {
213
+ store.set(requestClientAtom, null);
214
+ render(<FeedbackModal onClose={vi.fn()} />, { wrapper });
215
+
216
+ await screen.findByText("Environment details");
217
+ expect(
218
+ screen.getByText("Server environment information unavailable"),
219
+ ).toBeInTheDocument();
220
+ expect(
221
+ screen.queryByText("Loading environment details…"),
222
+ ).not.toBeInTheDocument();
223
+ expect(
224
+ screen.queryByRole("button", { name: "Retry" }),
225
+ ).not.toBeInTheDocument();
226
+
227
+ const link = screen.getByRole("link", { name: "Open GitHub issue" });
228
+ const href = link.getAttribute("href") ?? "";
229
+ expect(href).toContain("&env=");
230
+ expect(href).toContain(encodeURIComponent("Environment Collection Error"));
231
+
232
+ fireEvent.click(
233
+ screen.getByRole("button", { name: "Copy environment JSON" }),
234
+ );
235
+ await waitFor(() =>
236
+ expect(copyModule.copyToClipboard).toHaveBeenCalledWith(
237
+ expect.stringContaining("Environment Collection Error"),
238
+ ),
239
+ );
240
+ });
241
+
242
+ it("disables source collection when the request client is missing", async () => {
243
+ localStorage.setItem(
244
+ "marimo:issue-report:include-code",
245
+ JSON.stringify(true),
246
+ );
247
+ store.set(connectionAtom, { state: WebSocketState.CONNECTING });
248
+ store.set(requestClientAtom, null);
249
+ render(<FeedbackModal onClose={vi.fn()} />, { wrapper });
250
+
251
+ await screen.findByText("Environment details");
252
+ expect(
253
+ screen.getByRole("checkbox", { name: "Include notebook code" }),
254
+ ).toBeDisabled();
255
+ expect(
256
+ screen.getByText("Notebook source is unavailable."),
257
+ ).toBeInTheDocument();
258
+ expect(
259
+ screen.queryByText("Connect the notebook to include its source."),
260
+ ).not.toBeInTheDocument();
261
+ const link = screen.getByRole("link", { name: "Open GitHub issue" });
262
+ expect(link.getAttribute("href") ?? "").not.toContain("reproduction-code=");
263
+ });
264
+
265
+ it("preserves partial diagnostics when the environment request throws", async () => {
266
+ store.set(
267
+ requestClientAtom,
268
+ MockRequestClient.create({
269
+ getEnvironmentInfo: vi.fn().mockImplementation(() => {
270
+ throw new Error("offline");
271
+ }),
272
+ }),
273
+ );
274
+ render(<FeedbackModal onClose={vi.fn()} />, { wrapper });
275
+
276
+ await screen.findByText("Server environment information unavailable");
277
+ expect(screen.getByRole("button", { name: "Retry" })).toBeInTheDocument();
278
+ expect(
279
+ screen.getByText(/Environment Collection Error/),
280
+ ).toBeInTheDocument();
281
+ });
282
+
283
+ it("replaces partial diagnostics after a successful environment retry", async () => {
284
+ const getEnvironmentInfo = vi
285
+ .fn()
286
+ .mockRejectedValueOnce(new Error("offline"))
287
+ .mockResolvedValueOnce(environment);
288
+ store.set(
289
+ requestClientAtom,
290
+ MockRequestClient.create({ getEnvironmentInfo }),
291
+ );
292
+ render(<FeedbackModal onClose={vi.fn()} />, { wrapper });
293
+
294
+ await screen.findByText("Server environment information unavailable");
295
+ fireEvent.click(screen.getByRole("button", { name: "Retry" }));
296
+
297
+ await screen.findByText(/"marimo": "1.2.3"/);
298
+ expect(
299
+ screen.queryByText("Server environment information unavailable"),
300
+ ).not.toBeInTheDocument();
301
+ expect(
302
+ screen.queryByRole("button", { name: "Retry" }),
303
+ ).not.toBeInTheDocument();
304
+ });
211
305
  });