@marimo-team/islands 0.25.3-dev26 → 0.25.3-dev261

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 (796) hide show
  1. package/dist/{ConnectedDataExplorerComponent-DfG3PRaJ.js → ConnectedDataExplorerComponent-DjlwdMQT.js} +120 -116
  2. package/dist/{ErrorBoundary-MDk-fuIJ.js → ErrorBoundary-m3vF1P4J.js} +16 -16
  3. package/dist/_baseSet-BfI5FjBM.js +328 -0
  4. package/dist/{abnfDiagram-VCTEODGH-B3w-XWX8.js → abnfDiagram-VCTEODGH-DzrZZXRD.js} +2 -2
  5. package/dist/any-language-editor-Be7dA2VK.js +75 -0
  6. package/dist/{architectureDiagram-5GKGNRK7-C18U9A6k.js → architectureDiagram-5GKGNRK7-iF_snyFL.js} +1 -1
  7. package/dist/{arrays-CN1djC4k.js → arrays-DoQ-AILx.js} +15 -27
  8. package/dist/assets/__vite-browser-external-BKBpimif.js +1 -0
  9. package/dist/assets/worker-CgoMtD-_.js +113 -0
  10. package/dist/{blockDiagram-I7D4REHJ-Cg25UrxT.js → blockDiagram-I7D4REHJ-Dkhe6_PP.js} +1 -1
  11. package/dist/{button-CvjkwdSk.js → button-0-RqY1DW.js} +229 -218
  12. package/dist/{capabilities-CQ5IjhzL.js → capabilities-B6yy_CBN.js} +2 -2
  13. package/dist/{chat-ui-w8SVynkn.js → chat-ui-Bl_I-evE.js} +822 -755
  14. package/dist/{check-BMKBBrdc.js → check-CSvxZk5I.js} +1 -1
  15. package/dist/{chunk-IMKFNOWR-CrS5bzqW.js → chunk-IMKFNOWR-B7xytD4B.js} +1 -1
  16. package/dist/{chunk-SHT3W25Y-StpvPvUG.js → chunk-SHT3W25Y-I8ZFP5L1.js} +1 -1
  17. package/dist/{chunk-SVP7TREG-CBXjbYZC.js → chunk-SVP7TREG-Di-uAPdT.js} +1 -1
  18. package/dist/{chunk-TICWLB2K-Dp6bIb-q.js → chunk-TICWLB2K-BFpUy0ud.js} +1 -1
  19. package/dist/{chunk-YOKDWASO-DPZk8vhS.js → chunk-YOKDWASO-DKplTrBY.js} +20 -20
  20. package/dist/{classDiagram-ZZMXUADV-BFYuxV5g.js → classDiagram-ZZMXUADV-Cqm4JGpx.js} +2 -2
  21. package/dist/{classDiagram-v2-VYDZK3BY-D_tjXVMl.js → classDiagram-v2-VYDZK3BY-DFHRJpN3.js} +2 -2
  22. package/dist/code-visibility-TqQbHmZ5.js +134 -0
  23. package/dist/{common-Bo1ahZJz.js → common-BY_oazL9.js} +9850 -9619
  24. package/dist/config-mwEjAmvP.js +636 -0
  25. package/dist/{copy-icon-BgUO8jsi.js → copy-icon-DD8bdw4L.js} +3 -3
  26. package/dist/createReducer-C_syF8Td.js +67 -0
  27. package/dist/{cynefinDiagram-5FMLGOSQ-DSgYrHB2.js → cynefinDiagram-5FMLGOSQ-cuGOeTBC.js} +1 -1
  28. package/dist/{dagre-GXQ25YYZ-GYlruCBf.js → dagre-GXQ25YYZ-DJ76aC4k.js} +3 -3
  29. package/dist/{dagre-BGSfXNEb.js → dagre-mqiMAsFY.js} +531 -680
  30. package/dist/{data-grid-overlay-editor-BcbqpDrL.js → data-grid-overlay-editor-CLQPFjyJ.js} +5 -5
  31. package/dist/{data-grid-types-BH_r7g7l.js → data-grid-types-0PJ-9N5n.js} +1 -1
  32. package/dist/{debounce-C3jyATpc.js → debounce-DrhhziJv.js} +2 -2
  33. package/dist/{diagram-S7CK7UJ4-DRu5LX5_.js → diagram-S7CK7UJ4-DLLc0sw7.js} +1 -1
  34. package/dist/{diagram-UQ7AKVKN-DD7uiejP.js → diagram-UQ7AKVKN-Tz_d6qmk.js} +1 -1
  35. package/dist/{diagram-VX7I27RA-ByH9KAJJ.js → diagram-VX7I27RA-D7SzPrDN.js} +1 -1
  36. package/dist/{diagram-Z3DM3KII-BsQHPRke.js → diagram-Z3DM3KII-qr37XV58.js} +1 -1
  37. package/dist/{dialog-Cc479ZEH.js → dialog-BHYPX87J.js} +26 -26
  38. package/dist/{dist-Bvs24R_E.js → dist-11T5wq3_.js} +31 -30
  39. package/dist/{dist-F8Ep36rk.js → dist-17ugwGZc.js} +59 -58
  40. package/dist/{dist-BMQf5zIS.js → dist-7cRjf--y.js} +123 -122
  41. package/dist/{dist-diIx5qJW.js → dist-B8pkfkzc.js} +31 -30
  42. package/dist/{dist-CN_BeG2I.js → dist-B9UoM_wq.js} +58 -57
  43. package/dist/{dist-CLdpGQVr.js → dist-BGuMTs1i.js} +118 -117
  44. package/dist/{dist-BK4Oj99o.js → dist-BHW11fni.js} +18 -17
  45. package/dist/dist-BLY4m1Wi.js +850 -0
  46. package/dist/{dist-PXYI_yuP.js → dist-BNlcVoxs.js} +24 -23
  47. package/dist/{dist-D6d86eNJ.js → dist-BQYe5Bju.js} +47 -46
  48. package/dist/{dist-CkTTIdBe.js → dist-BX1mn8na.js} +337 -337
  49. package/dist/{dist-DiDibOYr.js → dist-Bh0PTKUW.js} +151 -150
  50. package/dist/{dist-CSJ0MDRw.js → dist-CKaXK92p.js} +56 -55
  51. package/dist/{dist-C8fAKSH1.js → dist-CLhwfhpJ.js} +53 -52
  52. package/dist/{dist-DoE4XJBC.js → dist-CYeqK4Xw.js} +9801 -10649
  53. package/dist/{dist-BLfKmR-l.js → dist-Cxlp3WH6.js} +16 -15
  54. package/dist/{dist-D-wwqlzJ.js → dist-DSJPGj42.js} +158 -157
  55. package/dist/{dist-BorMD-uX.js → dist-DU9ICsWZ.js} +75 -74
  56. package/dist/{dist-DBtSl3sf.js → dist-DWv0ALBi.js} +47 -46
  57. package/dist/{dist-OR1OnN-y.js → dist-DiBpWEsB.js} +31 -30
  58. package/dist/{dist-CrSP_H1M.js → dist-DiLFTlnl.js} +242 -242
  59. package/dist/{dist-DpBpA_n1.js → dist-Lm-D-Vr6.js} +3 -3
  60. package/dist/{dist-CSbh1PNP.js → dist-cVDV5IuI.js} +23 -22
  61. package/dist/{dist-BuaRHxOc.js → dist-fRfaOoq8.js} +44 -43
  62. package/dist/{dist-Cg7gzw-a.js → dist-gTTI-9Px.js} +78 -77
  63. package/dist/dropdown-menu-Blu7V6Mk.js +6083 -0
  64. package/dist/{ebnfDiagram-PWID7BFC-CQRK5_eT.js → ebnfDiagram-PWID7BFC-BKOQb4J0.js} +2 -2
  65. package/dist/{erDiagram-RLTQ6QDP-BKtWrDVh.js → erDiagram-RLTQ6QDP-CM15Vq68.js} +1 -1
  66. package/dist/{error-banner-CFPHFw4h.js → error-banner-DbRFOd2O.js} +84 -83
  67. package/dist/error-entries-DFhMo601.js +2505 -0
  68. package/dist/{esm-D2gTsXEV.js → esm-BgKjMvWw.js} +530 -529
  69. package/dist/{esm-AMFssoNp.js → esm-CHjVSexr.js} +328 -329
  70. package/dist/feedback-button-DYk1f0In.js +374 -0
  71. package/dist/{flowDiagram-HODETNUW-1IN-ih2E.js → flowDiagram-HODETNUW-Dt3N5yFT.js} +2 -2
  72. package/dist/{formats-X4mMQWzX.js → formats-gGospKWJ.js} +6 -6
  73. package/dist/{ganttDiagram-EL5Y4UJY-BQT16JSc.js → ganttDiagram-EL5Y4UJY-Dh_4cBJZ.js} +2 -2
  74. package/dist/{glide-data-editor-h-P3W8Rc.js → glide-data-editor-D30zzaiO.js} +417 -415
  75. package/dist/{glide-utils-DM9zBO4W.js → glide-utils-qbkRZpEy.js} +16 -16
  76. package/dist/{globals-4XAS0Mmd.js → globals-BA0s7TxM.js} +3 -3
  77. package/dist/{graphlib-BmY_CCV9.js → graphlib-nlwT3Wvy.js} +177 -220
  78. package/dist/hasIn-C20JsQ2m.js +28 -0
  79. package/dist/{highlighted-body-KPVGNVTW-zwjq21tf.js → highlighted-body-KPVGNVTW-3Ziwfz-V.js} +2 -2
  80. package/dist/{error-entries-Damuuclv.js → html-to-image-BPs9Vo-H.js} +26928 -26781
  81. package/dist/{infoDiagram-27XIBGKW-CkB-zr4p.js → infoDiagram-27XIBGKW-C7axJMCl.js} +1 -1
  82. package/dist/isArrayLikeObject-B-HXCsex.js +626 -0
  83. package/dist/isEmpty-CdX7MTE1.js +14 -0
  84. package/dist/{ishikawaDiagram-5VMMS53U-wlyLjBmM.js → ishikawaDiagram-5VMMS53U-CdC9Eur7.js} +1 -1
  85. package/dist/{kanban-definition-UXKFOSKX-C2usY0i-.js → kanban-definition-UXKFOSKX-BHnMIgD7.js} +1 -1
  86. package/dist/{linear-Cnaq3Tfb.js → linear-DWERh7eI.js} +121 -73
  87. package/dist/{loader-BQOfjTIJ.js → loader-BVEtQ4F3.js} +12 -12
  88. package/dist/main.js +10241 -8111
  89. package/dist/{mermaid-BA-Z6wGL.js → mermaid-DFYN_PXd.js} +54 -54
  90. package/dist/mermaid-HWGCJPDP-Du3-HPQA.js +2 -0
  91. package/dist/{mindmap-definition-YA3MSWOX-nKOWS8RR.js → mindmap-definition-YA3MSWOX-BagHoCGU.js} +1 -1
  92. package/dist/{now-jM8-M7IR.js → now-BKZCLE5P.js} +12 -13
  93. package/dist/{number-overlay-editor-DVBm-B8V.js → number-overlay-editor-B1nffNQ2.js} +3 -3
  94. package/dist/{dist-CN8zI-XC.js → objectWithoutPropertiesLoose-ai5NUqGa.js} +262 -240
  95. package/dist/{objects-CzUgoMIF.js → objects-DCmMvZtn.js} +1 -3
  96. package/dist/{once-BtE-wKRL.js → once-NnpX_HnX.js} +1 -1
  97. package/dist/{pegDiagram-XKGWAZYB-Dac9EIKD.js → pegDiagram-XKGWAZYB-8IIZczip.js} +2 -2
  98. package/dist/pick-tCszMUbm.js +35 -0
  99. package/dist/{pieDiagram-E7YTZNPT-B7S-DsW_.js → pieDiagram-E7YTZNPT-CE6dKBIr.js} +1 -1
  100. package/dist/precisionRound-DhAzeRcm.js +49 -0
  101. package/dist/{process-output-CTPTtxXB.js → process-output-c6xaHokq.js} +4 -4
  102. package/dist/{quadrantDiagram-AXDQQJYC-Ccw0xMjN.js → quadrantDiagram-AXDQQJYC-Blrm7V7_.js} +1 -1
  103. package/dist/{railroadDiagram-O6MQD6OU-Cfa5Q-hr.js → railroadDiagram-O6MQD6OU-CkexPq3b.js} +2 -2
  104. package/dist/{react-vega-BED0DjiB.js → react-vega-C4T9Rb_w.js} +12284 -12270
  105. package/dist/{requirementDiagram-BXWQKSXE-d8zXCJIk.js → requirementDiagram-BXWQKSXE-B0-OkuAe.js} +1 -1
  106. package/dist/{reveal-component-DtPzCmeW.js → reveal-component-fg3-aYjk.js} +430 -407
  107. package/dist/schemas-CdscWNy_.js +4747 -0
  108. package/dist/select-CcidPqlM.js +1200 -0
  109. package/dist/{sequenceDiagram-WJ2MYXX4-b6pei3lJ.js → sequenceDiagram-WJ2MYXX4-Dxysg8DX.js} +1 -1
  110. package/dist/{spec-BJzgmvVa.js → spec-ZwfZcgsm.js} +41 -11
  111. package/dist/{stateDiagram-D77RDMKH-Be-xSpaZ.js → stateDiagram-D77RDMKH-DTEN3-OJ.js} +4 -4
  112. package/dist/{stateDiagram-v2-MP3YSRHH-5Y-FxesJ.js → stateDiagram-v2-MP3YSRHH-vktk3Xc5.js} +2 -2
  113. package/dist/static-state-BldGd99T.js +72 -0
  114. package/dist/strings-BYJNyKmg.js +507 -0
  115. package/dist/style.css +1 -1
  116. package/dist/{swimlanes-42K2YHIH-nRRl4NU0.js → swimlanes-42K2YHIH-Cjveh9OM.js} +1 -1
  117. package/dist/{swimlanesDiagram-VR7AAH4N-BS79510V.js → swimlanesDiagram-VR7AAH4N-Bdr7Ev_2.js} +2 -2
  118. package/dist/{swiper-component-DKntyn8p.js → swiper-component-Dvj-goaD.js} +2 -2
  119. package/dist/{time-BieKwdYS.js → time-BaMbJs4z.js} +18 -18
  120. package/dist/{timeline-definition-24CTP7MA-Cfzf8WPf.js → timeline-definition-24CTP7MA-KIuDcefn.js} +1 -1
  121. package/dist/toast-CkB5Jq9K.js +491 -0
  122. package/dist/{tooltip-CtBZ5q8p.js → tooltip-Bzl4k00l.js} +329 -305
  123. package/dist/use-restore-focus-CmflVLWJ.js +1672 -0
  124. package/dist/{useAsyncData-BD534XmW.js → useAsyncData-DsZMvNXn.js} +15 -14
  125. package/dist/{useDateFormatter-DkajGwwd.js → useDateFormatter-CYo5fm8s.js} +2 -2
  126. package/dist/{useDeepCompareMemoize-C72_RNsu.js → useDeepCompareMemoize-KMBBux8C.js} +1 -1
  127. package/dist/{useIframeCapabilities-DBETvvPl.js → useIframeCapabilities-BIolGsF1.js} +1 -1
  128. package/dist/useLifecycle-GNgvNwI-.js +112 -0
  129. package/dist/useTheme-BZ2GGLgm.js +339 -0
  130. package/dist/utils-DXkj82sK.js +813 -0
  131. package/dist/{vega-component-DfcYgj-Y.js → vega-component-DOtem7Hf.js} +171 -170
  132. package/dist/{vega-embed-container-BNHE18G9.js → vega-embed-container--LYZqguO.js} +2 -2
  133. package/dist/{vega-loader.browser-DNST6uVf.js → vega-loader.browser-B9Pz0EGP.js} +298 -507
  134. package/dist/{vennDiagram-4TSXK5OY-CeY6Z1xZ.js → vennDiagram-4TSXK5OY-DrIOUHfb.js} +1 -1
  135. package/dist/{wardleyDiagram-VM6X3IG4-Cxs9NtVi.js → wardleyDiagram-VM6X3IG4-CJNjf4OH.js} +1 -1
  136. package/dist/{xychartDiagram-S5SC5T6Z-DNWbvPK7.js → xychartDiagram-S5SC5T6Z-DEshFho-.js} +2 -2
  137. package/package.json +16 -20
  138. package/src/__mocks__/document.tsx +63 -0
  139. package/src/__mocks__/notebook.ts +3 -4
  140. package/src/__mocks__/partial.ts +26 -0
  141. package/src/__mocks__/requests.ts +1 -4
  142. package/src/__tests__/fixtures/pair-config.ts +1 -1
  143. package/src/__tests__/main.test.tsx +24 -1
  144. package/src/__tests__/module-entry.test.ts +44 -0
  145. package/src/__tests__/mount.test.ts +1 -21
  146. package/src/__tests__/{host-imports.test.ts → replica-imports.test.ts} +12 -11
  147. package/src/components/ai/__tests__/ai-model-dropdown.test.tsx +63 -0
  148. package/src/components/ai/ai-model-dropdown.tsx +11 -6
  149. package/src/components/app-config/__tests__/state.test.tsx +50 -0
  150. package/src/components/app-config/ai-config.tsx +156 -150
  151. package/src/components/app-config/app-config-button.tsx +6 -5
  152. package/src/components/app-config/app-config-form.tsx +5 -9
  153. package/src/components/app-config/common.tsx +7 -9
  154. package/src/components/app-config/data-form.tsx +112 -113
  155. package/src/components/app-config/mcp-config.tsx +30 -53
  156. package/src/components/app-config/user-config-form.css +91 -0
  157. package/src/components/app-config/user-config-form.tsx +266 -349
  158. package/src/components/chat/__tests__/capabilities-popover.test.tsx +0 -1
  159. package/src/components/chat/__tests__/chat-display.test.tsx +125 -0
  160. package/src/components/chat/__tests__/chat-markdown.test.tsx +43 -0
  161. package/src/components/chat/__tests__/chat-utils.test.ts +51 -1
  162. package/src/components/chat/__tests__/message-queue.test.tsx +17 -0
  163. package/src/components/chat/__tests__/notebook-access-selector.test.tsx +64 -0
  164. package/src/components/chat/acp/__tests__/agent-panel-initialization.test.tsx +1 -1
  165. package/src/components/chat/acp/__tests__/agent-panel.test.tsx +22 -17
  166. package/src/components/chat/acp/__tests__/session-tabs.test.tsx +43 -0
  167. package/src/components/chat/acp/__tests__/state.test.ts +2 -2
  168. package/src/components/chat/acp/agent-panel.tsx +4 -3
  169. package/src/components/chat/acp/blocks.tsx +13 -12
  170. package/src/components/chat/acp/common.tsx +4 -5
  171. package/src/components/chat/acp/model-selector.tsx +1 -1
  172. package/src/components/chat/acp/session-tabs.tsx +8 -3
  173. package/src/components/chat/capabilities-popover.tsx +2 -11
  174. package/src/components/chat/chat-components.tsx +9 -4
  175. package/src/components/chat/chat-display.tsx +51 -6
  176. package/src/components/chat/chat-history-popover.tsx +6 -1
  177. package/src/components/chat/chat-markdown.tsx +15 -0
  178. package/src/components/chat/chat-panel.tsx +119 -214
  179. package/src/components/chat/chat-typography.css +108 -0
  180. package/src/components/chat/chat-utils.ts +12 -11
  181. package/src/components/chat/notebook-access-selector.stories.tsx +22 -0
  182. package/src/components/chat/notebook-access-selector.tsx +100 -0
  183. package/src/components/chat/reasoning-accordion.tsx +3 -3
  184. package/src/components/chat/tool-call/tool-activity-group.tsx +49 -0
  185. package/src/components/chat/tool-call/tool-history-row.tsx +3 -30
  186. package/src/components/chat/tool-call/tool-result.tsx +1 -1
  187. package/src/components/chat/use-chat-generation.ts +19 -0
  188. package/src/components/data-table/TableBottomBar.tsx +4 -1
  189. package/src/components/data-table/TableTopBar.tsx +2 -0
  190. package/src/components/data-table/__tests__/chart-spec-model.test.ts +195 -195
  191. package/src/components/data-table/__tests__/column-explorer.test.tsx +27 -1
  192. package/src/components/data-table/__tests__/columns.test.tsx +105 -0
  193. package/src/components/data-table/__tests__/context-menu-interaction.test.tsx +130 -0
  194. package/src/components/data-table/__tests__/data-table.test.tsx +1 -0
  195. package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
  196. package/src/components/data-table/__tests__/export-actions.test.tsx +105 -0
  197. package/src/components/data-table/__tests__/keyboard-selection.test.tsx +188 -0
  198. package/src/components/data-table/__tests__/pagination.test.tsx +28 -1
  199. package/src/components/data-table/__tests__/search-highlight.test.tsx +109 -0
  200. package/src/components/data-table/__tests__/url-detector.test.tsx +74 -0
  201. package/src/components/data-table/cell-selection/feature.ts +2 -2
  202. package/src/components/data-table/cell-selection/types.ts +2 -2
  203. package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
  204. package/src/components/data-table/charts/__tests__/spec-snapshot.test.ts +20 -20
  205. package/src/components/data-table/charts/__tests__/spec.test.ts +78 -52
  206. package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
  207. package/src/components/data-table/charts/chart-spec/spec.ts +68 -43
  208. package/src/components/data-table/charts/charts.tsx +40 -30
  209. package/src/components/data-table/charts/storage.ts +16 -5
  210. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
  211. package/src/components/data-table/column-formatting/types.ts +1 -2
  212. package/src/components/data-table/column-summary/chart-spec-model.tsx +23 -16
  213. package/src/components/data-table/column-summary/column-summary.tsx +2 -4
  214. package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
  215. package/src/components/data-table/columns.tsx +45 -46
  216. package/src/components/data-table/context-menu.tsx +36 -20
  217. package/src/components/data-table/data-table.tsx +17 -1
  218. package/src/components/data-table/date-popover.tsx +6 -4
  219. package/src/components/data-table/export-actions.tsx +76 -48
  220. package/src/components/data-table/pagination.tsx +44 -33
  221. package/src/components/data-table/range-focus/atoms.ts +4 -6
  222. package/src/components/data-table/range-focus/use-cell-range-selection.ts +65 -38
  223. package/src/components/data-table/range-focus/use-scroll-into-view.ts +21 -2
  224. package/src/components/data-table/renderers.tsx +16 -7
  225. package/src/components/data-table/row-viewer-panel/__tests__/row-viewer.test.tsx +24 -1
  226. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +4 -4
  227. package/src/components/data-table/search-highlight.tsx +79 -0
  228. package/src/components/data-table/types.ts +1 -0
  229. package/src/components/data-table/url-detector.tsx +49 -9
  230. package/src/components/datasources/__tests__/column-actions.test.tsx +97 -0
  231. package/src/components/datasources/__tests__/column-preview.test.tsx +96 -5
  232. package/src/components/datasources/__tests__/datasources-interactions.test.tsx +181 -0
  233. package/src/components/datasources/__tests__/table-list.test.tsx +118 -0
  234. package/src/components/datasources/__tests__/utils.test.ts +57 -6
  235. package/src/components/datasources/column-preview.tsx +17 -12
  236. package/src/components/datasources/datasources.tsx +56 -43
  237. package/src/components/datasources/utils.ts +32 -23
  238. package/src/components/debugger/debugger-code.tsx +5 -0
  239. package/src/components/dependency-graph/custom-node.tsx +1 -1
  240. package/src/components/dependency-graph/dependency-graph-tree.tsx +8 -8
  241. package/src/components/dependency-graph/elements.ts +24 -21
  242. package/src/components/dependency-graph/minimap-content.tsx +13 -19
  243. package/src/components/dependency-graph/panels.tsx +4 -2
  244. package/src/components/dependency-graph/utils/__tests__/layout.test.ts +18 -11
  245. package/src/components/editor/SortableCell.tsx +1 -3
  246. package/src/components/editor/__tests__/Output.test.tsx +50 -32
  247. package/src/{core/attachments/__tests__/toast.test.tsx → components/editor/__tests__/agent-toast.test.tsx} +1 -1
  248. package/src/components/editor/__tests__/data-attributes.test.tsx +28 -14
  249. package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
  250. package/src/components/editor/__tests__/output-persistence.test.tsx +6 -2
  251. package/src/components/editor/__tests__/package-alert.test.tsx +22 -1
  252. package/src/components/editor/actions/__tests__/name-cell-input.test.tsx +69 -0
  253. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +21 -40
  254. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +41 -14
  255. package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +6 -24
  256. package/src/components/editor/actions/__tests__/useCellActionButton.test.tsx +113 -0
  257. package/src/components/editor/actions/name-cell-input.tsx +4 -3
  258. package/src/components/editor/actions/pair-with-agent-commands.ts +10 -7
  259. package/src/components/editor/actions/pair-with-agent-modal.tsx +29 -30
  260. package/src/components/editor/actions/pair-with-agent.tsx +16 -39
  261. package/src/components/editor/actions/useCellActionButton.tsx +37 -32
  262. package/src/components/editor/actions/useConfigActions.tsx +3 -4
  263. package/src/components/editor/actions/useNotebookActions.tsx +25 -29
  264. package/src/components/editor/actions/useRestartKernel.tsx +1 -1
  265. package/src/components/editor/actions/useSetCodeVisibility.ts +11 -12
  266. package/src/components/editor/actions/useSetOutputsExpanded.ts +14 -19
  267. package/src/components/editor/ai/ai-completion-editor.tsx +2 -1
  268. package/src/components/editor/ai/prompt-input.tsx +189 -0
  269. package/src/components/editor/alerts/__tests__/connection-notice.test.tsx +1 -1
  270. package/src/components/editor/alerts/connection-notice.tsx +1 -1
  271. package/src/components/editor/alerts/startup-logs-alert.tsx +1 -0
  272. package/src/components/editor/alerts/stdin-blocking-alert.tsx +1 -1
  273. package/src/components/editor/app-container.tsx +1 -1
  274. package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +1 -1
  275. package/src/components/editor/cell/CreateCellButton.tsx +15 -21
  276. package/src/components/editor/cell/DeleteButton.tsx +3 -2
  277. package/src/components/editor/cell/RunButton.tsx +2 -2
  278. package/src/components/editor/cell/StagedAICell.tsx +13 -5
  279. package/src/components/editor/cell/StopButton.tsx +2 -2
  280. package/src/components/editor/cell/__tests__/useShouldShowInterrupt.test.ts +39 -0
  281. package/src/components/editor/cell/cell-actions.tsx +12 -1
  282. package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
  283. package/src/components/editor/cell/code/cell-editor.tsx +59 -165
  284. package/src/components/editor/cell/code/language-toggle.tsx +8 -7
  285. package/src/components/editor/cell/collapse.tsx +11 -4
  286. package/src/components/editor/cell/useAddCell.ts +4 -8
  287. package/src/components/editor/cell/useDeleteCell.tsx +10 -36
  288. package/src/components/editor/cell/useRunCells.ts +2 -5
  289. package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
  290. package/src/components/editor/cell/useSplitCell.tsx +10 -6
  291. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +1 -1
  292. package/src/components/editor/chrome/components/feedback-button.tsx +2 -8
  293. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +31 -2
  294. package/src/components/editor/chrome/panels/__tests__/runtime-details.test.tsx +1 -1
  295. package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +1 -1
  296. package/src/components/editor/chrome/panels/cache-panel.tsx +1 -0
  297. package/src/components/editor/chrome/panels/dependency-graph-panel.tsx +1 -1
  298. package/src/components/editor/chrome/panels/logs-panel.tsx +2 -1
  299. package/src/components/editor/chrome/panels/outline/__tests__/outline-keyboard.test.tsx +84 -0
  300. package/src/components/editor/chrome/panels/outline/floating-outline.tsx +39 -14
  301. package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +3 -2
  302. package/src/components/editor/chrome/panels/packages-panel.tsx +4 -7
  303. package/src/components/editor/chrome/panels/panel-header.tsx +13 -0
  304. package/src/components/editor/chrome/panels/secrets-panel.tsx +1 -0
  305. package/src/components/editor/chrome/panels/session-panel.tsx +1 -1
  306. package/src/components/editor/chrome/panels/snippets-panel.tsx +10 -12
  307. package/src/components/editor/chrome/panels/variable-panel.tsx +1 -5
  308. package/src/components/editor/chrome/types.ts +1 -1
  309. package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +7 -9
  310. package/src/components/editor/chrome/wrapper/__tests__/document-sync-status.test.tsx +92 -0
  311. package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +102 -35
  312. package/src/components/editor/chrome/wrapper/__tests__/useAskAiAboutCell.test.tsx +58 -0
  313. package/src/components/editor/chrome/wrapper/app-chrome.tsx +89 -72
  314. package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +4 -4
  315. package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +1 -1
  316. package/src/components/editor/chrome/wrapper/footer-items/document-sync-status.tsx +54 -0
  317. package/src/components/editor/chrome/wrapper/footer-items/lsp-status.tsx +1 -1
  318. package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +1 -1
  319. package/src/components/editor/chrome/wrapper/footer-items/runtime-settings.tsx +1 -7
  320. package/src/components/editor/chrome/wrapper/footer.tsx +2 -2
  321. package/src/components/editor/chrome/wrapper/minimap-state.ts +1 -1
  322. package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +17 -10
  323. package/src/components/editor/chrome/wrapper/storage.ts +1 -1
  324. package/src/components/editor/chrome/wrapper/useAskAiAboutCell.ts +36 -0
  325. package/src/components/editor/columns/__tests__/cell-column.test.tsx +1 -1
  326. package/src/components/editor/columns/cell-column.tsx +1 -1
  327. package/src/components/editor/columns/sortable-column.tsx +2 -2
  328. package/src/components/editor/connections/components.tsx +5 -10
  329. package/src/components/editor/controls/Controls.tsx +4 -4
  330. package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
  331. package/src/components/editor/controls/__tests__/keyboard-shortcuts.test.tsx +61 -0
  332. package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +10 -4
  333. package/src/components/editor/controls/command-palette.tsx +22 -10
  334. package/src/components/editor/controls/keyboard-shortcuts.tsx +14 -5
  335. package/src/components/editor/documentation.css +34 -11
  336. package/src/components/editor/dynamic-favicon.tsx +21 -40
  337. package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +25 -20
  338. package/src/components/editor/errors/auto-fix.tsx +4 -8
  339. package/src/components/editor/errors/send-error-report-button.tsx +3 -6
  340. package/src/components/editor/file-tree/__tests__/file-explorer-interactions.test.tsx +6 -0
  341. package/src/components/editor/file-tree/__tests__/file-explorer-navigation.test.tsx +47 -0
  342. package/src/components/editor/file-tree/__tests__/use-file-search.test.tsx +91 -0
  343. package/src/components/editor/file-tree/file-explorer.tsx +48 -15
  344. package/src/components/editor/file-tree/file-name-input.tsx +1 -0
  345. package/src/components/editor/file-tree/file-viewer.tsx +4 -2
  346. package/src/components/editor/file-tree/use-file-search.ts +35 -21
  347. package/src/components/editor/header/__tests__/filename-form.test.tsx +1 -4
  348. package/src/components/editor/header/__tests__/status.test.tsx +5 -3
  349. package/src/components/editor/header/app-header.tsx +1 -1
  350. package/src/components/editor/header/filename-form.tsx +1 -1
  351. package/src/components/editor/header/status.tsx +40 -20
  352. package/src/components/editor/links/__tests__/cell-link.test.tsx +148 -0
  353. package/src/components/editor/links/cell-link-list.tsx +1 -1
  354. package/src/components/editor/links/cell-link.tsx +17 -7
  355. package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
  356. package/src/components/editor/navigation/__tests__/navigation.test.ts +108 -85
  357. package/src/components/editor/navigation/__tests__/selection.test.ts +43 -21
  358. package/src/components/editor/navigation/clipboard.ts +17 -14
  359. package/src/components/editor/navigation/focus-utils.ts +23 -4
  360. package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +17 -33
  361. package/src/components/editor/navigation/navigation.ts +71 -70
  362. package/src/components/editor/navigation/selection.ts +30 -29
  363. package/src/components/editor/notebook-banner.tsx +1 -0
  364. package/src/components/editor/notebook-cell.tsx +29 -32
  365. package/src/components/editor/output/MarimoErrorOutput.tsx +2 -1
  366. package/src/components/editor/output/MarimoTracebackOutput.tsx +19 -17
  367. package/src/components/editor/output/Outputs.css +8 -0
  368. package/src/components/editor/output/VideoOutput.tsx +6 -0
  369. package/src/components/editor/output/__tests__/VideoOutput.test.tsx +131 -0
  370. package/src/components/editor/output/__tests__/traceback.test.tsx +27 -1
  371. package/src/components/editor/output/ansi-reduce.ts +33 -20
  372. package/src/components/editor/output/console/ConsoleOutput.tsx +19 -25
  373. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +125 -69
  374. package/src/components/editor/package-alert.tsx +14 -7
  375. package/src/components/editor/renderers/__tests__/add-cell-buttons.test.tsx +18 -0
  376. package/src/components/editor/renderers/cell-array.tsx +32 -100
  377. package/src/components/editor/renderers/grid-layout/grid-layout.tsx +12 -6
  378. package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +0 -1
  379. package/src/components/editor/renderers/slides-layout/slides-layout.tsx +1 -1
  380. package/src/components/editor/renderers/vertical-layout/__tests__/useFocusFirstEditor.test.ts +4 -4
  381. package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
  382. package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +1 -1
  383. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +1 -1
  384. package/src/components/editor/stdin-blocking-alert.tsx +1 -1
  385. package/src/components/home/components.tsx +17 -31
  386. package/src/components/icons/__tests__/large-spinner.test.tsx +39 -0
  387. package/src/components/icons/large-spinner.tsx +3 -14
  388. package/src/components/icons/spinner.tsx +1 -1
  389. package/src/components/markdown/markdown-renderer.tsx +39 -28
  390. package/src/components/mcp/mcp-status-indicator.tsx +18 -14
  391. package/src/components/pages/__tests__/home-page.test.tsx +116 -0
  392. package/src/components/pages/edit-page.tsx +19 -17
  393. package/src/components/pages/home-page.tsx +164 -91
  394. package/src/components/scratchpad/scratchpad.test.tsx +89 -0
  395. package/src/components/scratchpad/scratchpad.tsx +43 -32
  396. package/src/components/scratchpad/state.ts +7 -0
  397. package/src/components/slides/__tests__/minimap-actions.test.tsx +22 -29
  398. package/src/components/slides/__tests__/minimap.test.ts +38 -19
  399. package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +37 -0
  400. package/src/components/slides/minimap.tsx +17 -12
  401. package/src/components/slides/reveal-component.tsx +58 -26
  402. package/src/components/slides/reveal-slides.css +5 -4
  403. package/src/components/slides/slide-cell-view.tsx +4 -5
  404. package/src/components/slides/slide-form.tsx +1 -0
  405. package/src/components/slides/slide-scroll-hint.tsx +3 -1
  406. package/src/components/sort/SortableCellsProvider.tsx +8 -25
  407. package/src/components/tracing/tracing-keyboard.test.tsx +85 -0
  408. package/src/components/tracing/tracing.tsx +46 -42
  409. package/src/components/ui/__tests__/draggable-popover.test.tsx +24 -0
  410. package/src/components/ui/__tests__/fullscreen.test.tsx +44 -2
  411. package/src/components/ui/__tests__/range-slider.test.tsx +165 -0
  412. package/src/components/ui/alert-dialog.tsx +1 -1
  413. package/src/components/ui/draggable-popover.tsx +24 -2
  414. package/src/components/ui/fullscreen.tsx +25 -1
  415. package/src/components/ui/range-slider.tsx +22 -9
  416. package/src/core/MarimoApp.tsx +3 -1
  417. package/src/core/ai/__tests__/staged-cells.test.ts +15 -482
  418. package/src/core/ai/context/context.ts +2 -0
  419. package/src/core/ai/context/providers/__tests__/cell-output.test.ts +8 -12
  420. package/src/core/ai/context/providers/__tests__/cell.test.ts +49 -0
  421. package/src/core/ai/context/providers/cell-output.ts +2 -2
  422. package/src/core/ai/context/providers/cell.ts +54 -0
  423. package/src/core/ai/context/providers/datasource.ts +6 -2
  424. package/src/core/ai/staged-cells.ts +17 -294
  425. package/src/core/ai/state.ts +3 -0
  426. package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +40 -88
  427. package/src/core/ai/tools/__tests__/registry.test.ts +17 -0
  428. package/src/core/ai/tools/base.ts +18 -15
  429. package/src/core/ai/tools/edit-notebook-tool.ts +86 -80
  430. package/src/core/ai/tools/registry.ts +13 -10
  431. package/src/core/ai/tools/sample-tool.ts +6 -7
  432. package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -37
  433. package/src/core/cells/__tests__/actions.test.ts +624 -35
  434. package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
  435. package/src/core/cells/__tests__/arrange.test.ts +432 -0
  436. package/src/core/cells/__tests__/cell.test.ts +39 -0
  437. package/src/core/cells/__tests__/cells.test.ts +251 -2540
  438. package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
  439. package/src/core/cells/__tests__/document.test.ts +164 -0
  440. package/src/core/cells/__tests__/editor.test.ts +57 -0
  441. package/src/core/cells/__tests__/flush-document.test.ts +40 -0
  442. package/src/core/cells/__tests__/harness.ts +106 -0
  443. package/src/core/cells/__tests__/layout.test.ts +177 -0
  444. package/src/core/cells/__tests__/notebook-outline.test.ts +122 -0
  445. package/src/core/cells/__tests__/outputs.test.tsx +71 -53
  446. package/src/core/cells/__tests__/session.test.ts +445 -211
  447. package/src/core/cells/__tests__/utils.test.ts +9 -108
  448. package/src/core/cells/actions.ts +675 -6
  449. package/src/core/cells/add-missing-import.ts +47 -43
  450. package/src/core/cells/arrange.ts +529 -0
  451. package/src/core/cells/cell.ts +14 -3
  452. package/src/core/cells/cells.ts +126 -1363
  453. package/src/core/cells/columns.ts +38 -0
  454. package/src/core/cells/document.ts +178 -0
  455. package/src/core/cells/edit.ts +30 -0
  456. package/src/core/cells/editor.ts +82 -0
  457. package/src/core/cells/layout.ts +221 -0
  458. package/src/core/cells/outputs.ts +12 -28
  459. package/src/core/cells/pending-delete-service.ts +3 -7
  460. package/src/core/cells/session.ts +76 -53
  461. package/src/core/cells/types.ts +22 -6
  462. package/src/core/cells/utils.ts +10 -8
  463. package/src/core/codemirror/__tests__/format.test.ts +0 -34
  464. package/src/core/codemirror/__tests__/setup.test.ts +61 -29
  465. package/src/core/codemirror/ai/__tests__/resources.test.ts +117 -0
  466. package/src/core/codemirror/ai/resources.ts +1 -1
  467. package/src/core/codemirror/cells/__tests__/extensions.test.ts +2 -6
  468. package/src/core/codemirror/cells/extensions.ts +30 -28
  469. package/src/core/codemirror/cells/state.ts +2 -6
  470. package/src/core/codemirror/cm.ts +5 -1
  471. package/src/core/codemirror/config/types.ts +1 -1
  472. package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +6 -7
  473. package/src/core/codemirror/copilot/getCodes.ts +2 -2
  474. package/src/core/codemirror/format.ts +6 -23
  475. package/src/core/codemirror/keymaps/vim.ts +4 -8
  476. package/src/core/codemirror/language/__tests__/sql.test.ts +22 -20
  477. package/src/core/codemirror/language/__tests__/utils.test.ts +187 -15
  478. package/src/core/codemirror/language/cell-code.ts +114 -0
  479. package/src/core/codemirror/language/extension.ts +52 -35
  480. package/src/core/codemirror/language/languages/markdown.ts +8 -6
  481. package/src/core/codemirror/language/languages/python.ts +19 -13
  482. package/src/core/codemirror/language/languages/sql/sql.ts +16 -24
  483. package/src/core/codemirror/language/panel/panel.tsx +1 -0
  484. package/src/core/codemirror/language/types.ts +7 -7
  485. package/src/core/codemirror/language/utils.ts +9 -39
  486. package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +1 -2
  487. package/src/core/codemirror/lsp/notebook-lsp.ts +6 -5
  488. package/src/core/codemirror/lsp/utils.ts +1 -1
  489. package/src/core/codemirror/misc/__tests__/paste.test.ts +3 -1
  490. package/src/core/codemirror/misc/paste.ts +1 -1
  491. package/src/core/codemirror/placeholder/__tests__/extensions.test.ts +16 -0
  492. package/src/core/codemirror/placeholder/extensions.ts +57 -19
  493. package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
  494. package/src/core/codemirror/readonly/extension.ts +2 -2
  495. package/src/core/codemirror/utils.ts +1 -0
  496. package/src/core/config/__tests__/app-config.test.ts +64 -0
  497. package/src/core/config/__tests__/config-schema.test.ts +56 -6
  498. package/src/core/config/config-schema.ts +17 -4
  499. package/src/core/config/config.ts +65 -20
  500. package/src/core/config/feature-flag.tsx +0 -2
  501. package/src/core/datasets/__tests__/data-source-discovery.test.ts +5 -5
  502. package/src/core/datasets/data-source-discovery.ts +4 -6
  503. package/src/core/documentation/doc-lookup.ts +1 -1
  504. package/src/core/edit-app.tsx +21 -28
  505. package/src/core/errors/error-entries.ts +4 -1
  506. package/src/core/export/hooks.ts +1 -1
  507. package/src/core/export/layout.ts +2 -2
  508. package/src/core/hotkeys/actions.ts +2 -4
  509. package/src/core/hotkeys/hotkeys.ts +2 -1
  510. package/src/core/islands/__tests__/bootstrap.test.ts +69 -17
  511. package/src/core/islands/__tests__/bridge.test.ts +85 -27
  512. package/src/core/islands/bootstrap.ts +46 -53
  513. package/src/core/islands/bridge.ts +84 -25
  514. package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
  515. package/src/core/islands/components/web-components.tsx +1 -1
  516. package/src/core/islands/worker/__tests__/controller.test.ts +62 -4
  517. package/src/core/islands/worker/controller.ts +4 -10
  518. package/src/core/islands/worker/worker.tsx +33 -33
  519. package/src/core/kernel/__tests__/RuntimeState.test.ts +1 -1
  520. package/src/core/kernel/__tests__/handlers.test.ts +7 -153
  521. package/src/core/kernel/handlers.ts +19 -72
  522. package/src/core/meta/__tests__/code-visibility.test.tsx +78 -70
  523. package/src/core/meta/code-visibility.ts +18 -9
  524. package/src/core/network/__tests__/connection.test.ts +1 -1
  525. package/src/core/network/__tests__/requests-lazy.test.ts +1 -3
  526. package/src/core/network/connection-notice.ts +1 -1
  527. package/src/core/network/connection.ts +1 -1
  528. package/src/core/network/requests-lazy.ts +2 -5
  529. package/src/core/network/requests-network.ts +5 -31
  530. package/src/core/network/requests-static.ts +1 -4
  531. package/src/core/network/requests-toasting.tsx +1 -4
  532. package/src/core/network/types.ts +6 -14
  533. package/src/core/network/useConnectionNotice.ts +8 -2
  534. package/src/core/notebook/__tests__/operations.test.ts +51 -0
  535. package/src/core/notebook/attachments.ts +38 -0
  536. package/src/core/notebook/document/__tests__/codemirror.test.ts +759 -0
  537. package/src/core/notebook/document/__tests__/draft.test.ts +363 -0
  538. package/src/core/notebook/document/__tests__/fixtures.ts +92 -0
  539. package/src/core/notebook/document/__tests__/hooks.test.tsx +391 -0
  540. package/src/core/notebook/document/__tests__/lifecycle-scenarios.test.ts +61 -0
  541. package/src/core/notebook/document/__tests__/model.test.ts +247 -0
  542. package/src/core/notebook/document/__tests__/protocol-fixtures.ts +38 -0
  543. package/src/core/notebook/document/__tests__/recovery-scenarios.test.ts +230 -0
  544. package/src/core/notebook/document/__tests__/scenario-fixture.ts +43 -0
  545. package/src/core/notebook/document/__tests__/scenarios.test.ts +205 -0
  546. package/src/core/notebook/document/__tests__/state.test.ts +459 -0
  547. package/src/core/notebook/document/__tests__/submission.test.ts +203 -0
  548. package/src/core/notebook/document/__tests__/test-host.test.ts +92 -0
  549. package/src/core/notebook/document/__tests__/test-host.ts +247 -0
  550. package/src/core/notebook/document/__tests__/test-notebook.ts +149 -0
  551. package/src/core/notebook/document/__tests__/user.ts +61 -0
  552. package/src/core/notebook/document/codemirror.ts +216 -0
  553. package/src/core/notebook/document/draft.ts +502 -0
  554. package/src/core/notebook/document/hooks.tsx +118 -0
  555. package/src/core/notebook/document/index.ts +24 -0
  556. package/src/core/notebook/document/model.ts +102 -0
  557. package/src/core/notebook/document/select.ts +41 -0
  558. package/src/core/notebook/document/state.ts +378 -0
  559. package/src/core/notebook/document/sync.ts +369 -0
  560. package/src/core/notebook/index.ts +19 -0
  561. package/src/core/notebook/operations.ts +30 -0
  562. package/src/core/notebook/replica/AGENTS.md +11 -0
  563. package/src/core/{host → notebook/replica}/__tests__/attachments.test.ts +9 -10
  564. package/src/core/{host → notebook/replica}/__tests__/document.test.ts +18 -16
  565. package/src/core/notebook/replica/__tests__/executions.test.ts +200 -0
  566. package/src/core/notebook/replica/__tests__/fixtures.ts +79 -0
  567. package/src/core/notebook/replica/__tests__/replica.test.ts +559 -0
  568. package/src/core/notebook/replica/__tests__/results.test.ts +193 -0
  569. package/src/core/notebook/replica/__tests__/runtime.test.ts +78 -0
  570. package/src/core/notebook/replica/backend.ts +19 -0
  571. package/src/core/notebook/replica/connection.ts +42 -0
  572. package/src/core/notebook/replica/index.ts +20 -0
  573. package/src/core/notebook/replica/replica.ts +336 -0
  574. package/src/core/{host → notebook/replica}/resources/attachments.ts +6 -3
  575. package/src/core/{host → notebook/replica}/resources/document.ts +3 -3
  576. package/src/core/notebook/replica/resources/executions.ts +157 -0
  577. package/src/core/notebook/replica/resources/results.ts +48 -0
  578. package/src/core/notebook/replica/resources/runtime.ts +14 -0
  579. package/src/core/packages/__tests__/useSandboxController.test.tsx +1 -1
  580. package/src/core/packages/useSandboxController.ts +1 -1
  581. package/src/core/run-app.tsx +48 -51
  582. package/src/core/runtime/__tests__/adapter.test.ts +1 -1
  583. package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
  584. package/src/core/runtime/__tests__/runtime.test.ts +32 -74
  585. package/src/core/runtime/adapter.ts +1 -1
  586. package/src/core/runtime/config.ts +2 -2
  587. package/src/core/runtime/runtime.ts +33 -46
  588. package/src/core/runtime/types.ts +0 -2
  589. package/src/core/saving/__tests__/document.test.tsx +123 -0
  590. package/src/core/saving/__tests__/state.test.ts +111 -0
  591. package/src/core/saving/__tests__/useAutoSave.test.tsx +67 -0
  592. package/src/core/saving/document.ts +33 -0
  593. package/src/core/saving/filename.ts +1 -1
  594. package/src/core/saving/save-component.tsx +39 -60
  595. package/src/core/saving/state.ts +38 -39
  596. package/src/core/saving/useAutoSave.ts +17 -53
  597. package/src/core/session/__tests__/backend.test.ts +236 -0
  598. package/src/core/session/__tests__/useNotebookReplica.hook.test.tsx +184 -0
  599. package/src/core/{websocket → session}/__tests__/useNotebookSession.hook.test.tsx +213 -262
  600. package/src/core/session/active-notebook.ts +28 -0
  601. package/src/core/session/backend.ts +123 -0
  602. package/src/core/session/embedded.ts +7 -0
  603. package/src/core/{websocket → session}/types.ts +2 -2
  604. package/src/core/session/useNotebookReplica.ts +74 -0
  605. package/src/core/{websocket → session}/useNotebookSession.tsx +77 -64
  606. package/src/core/state/__tests__/jotai.test.tsx +108 -0
  607. package/src/core/state/jotai.ts +1 -1
  608. package/src/core/static/__tests__/files.test.ts +38 -10
  609. package/src/core/static/files.ts +2 -0
  610. package/src/core/{websocket → transports}/__tests__/connection-state.test.ts +1 -13
  611. package/src/core/transports/__tests__/server.test.ts +408 -0
  612. package/src/core/transports/__tests__/static.test.ts +306 -0
  613. package/src/core/transports/__tests__/wasm.test.ts +166 -0
  614. package/src/core/{websocket → transports}/connection-state.ts +9 -16
  615. package/src/core/transports/server.ts +152 -0
  616. package/src/core/transports/static.ts +166 -0
  617. package/src/core/transports/wasm.ts +97 -0
  618. package/src/core/vscode/__tests__/vscode-bindings.test.ts +125 -0
  619. package/src/core/vscode/vscode-bindings.ts +14 -2
  620. package/src/core/wasm/__tests__/bridge.test.ts +210 -64
  621. package/src/core/wasm/__tests__/worker.test.ts +188 -0
  622. package/src/core/wasm/bridge.ts +119 -72
  623. package/src/core/wasm/rpc.ts +15 -3
  624. package/src/core/wasm/store.ts +3 -3
  625. package/src/core/wasm/worker/bootstrap.ts +55 -51
  626. package/src/core/wasm/worker/getMarimoWheel.ts +1 -1
  627. package/src/core/wasm/worker/save-worker.ts +9 -10
  628. package/src/core/wasm/worker/types.ts +30 -18
  629. package/src/core/wasm/worker/worker.ts +118 -72
  630. package/src/css/app/codemirror.css +1 -1
  631. package/src/css/common.css +1 -1
  632. package/src/css/globals.css +66 -22
  633. package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
  634. package/src/hooks/__tests__/useDebounce.test.tsx +51 -0
  635. package/src/hooks/__tests__/useDeepCompareMemoize.test.tsx +39 -0
  636. package/src/hooks/__tests__/useDelayElapsed.test.tsx +28 -0
  637. package/src/hooks/__tests__/useInternalStateWithSync.test.tsx +20 -0
  638. package/src/hooks/__tests__/useScript.test.tsx +77 -0
  639. package/src/hooks/__tests__/useStateForKey.test.tsx +257 -0
  640. package/src/hooks/useAsyncData.ts +3 -3
  641. package/src/hooks/useDataSourceDiscovery.ts +6 -4
  642. package/src/hooks/useDebounce.ts +6 -10
  643. package/src/hooks/useDeepCompareMemoize.ts +1 -1
  644. package/src/hooks/useDelayElapsed.ts +14 -10
  645. package/src/hooks/useElapsedTime.ts +3 -3
  646. package/src/hooks/useEventListener.ts +1 -2
  647. package/src/hooks/useInputHistory.ts +4 -7
  648. package/src/hooks/useInternalStateWithSync.ts +6 -6
  649. package/src/hooks/useResizeObserver.ts +4 -7
  650. package/src/hooks/useScript.ts +67 -70
  651. package/src/hooks/useStateForKey.ts +93 -0
  652. package/src/mount.tsx +20 -15
  653. package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
  654. package/src/plugins/core/registerReactComponent.tsx +1 -1
  655. package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
  656. package/src/plugins/impl/DataEditorPlugin.tsx +1 -1
  657. package/src/plugins/impl/DataTablePlugin.tsx +69 -37
  658. package/src/plugins/impl/DropdownPlugin.tsx +2 -6
  659. package/src/plugins/impl/FileBrowserPlugin.tsx +4 -16
  660. package/src/plugins/impl/FormPlugin.tsx +1 -1
  661. package/src/plugins/impl/RangeSliderPlugin.tsx +16 -2
  662. package/src/plugins/impl/RefreshPlugin.tsx +1 -0
  663. package/src/plugins/impl/SliderPlugin.tsx +6 -8
  664. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +387 -1
  665. package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +45 -0
  666. package/src/plugins/impl/__tests__/RangeSliderPlugin.test.tsx +109 -0
  667. package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +24 -3
  668. package/src/plugins/impl/anywidget/__tests__/registry.test.ts +153 -0
  669. package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +241 -2
  670. package/src/plugins/impl/anywidget/model.ts +3 -1
  671. package/src/plugins/impl/anywidget/registry.ts +18 -14
  672. package/src/plugins/impl/anywidget/runtime.ts +21 -9
  673. package/src/plugins/impl/anywidget/widget-binding.ts +160 -82
  674. package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +93 -0
  675. package/src/plugins/impl/chat/chat-ui.tsx +15 -12
  676. package/src/plugins/impl/code/any-language-editor.tsx +2 -2
  677. package/src/plugins/impl/data-editor/glide-data-editor.tsx +8 -5
  678. package/src/plugins/impl/data-editor/glide-utils.ts +3 -1
  679. package/src/plugins/impl/data-explorer/ConnectedDataExplorerComponent.tsx +1 -1
  680. package/src/plugins/impl/data-explorer/components/column-summary.tsx +4 -2
  681. package/src/plugins/impl/data-explorer/state/reducer.ts +1 -1
  682. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -2
  683. package/src/plugins/impl/data-frames/__tests__/sidebar.test.tsx +160 -0
  684. package/src/plugins/impl/data-frames/forms/__tests__/__snapshots__/form.test.tsx.snap +66 -66
  685. package/src/plugins/impl/data-frames/panel.tsx +44 -16
  686. package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +5 -3
  687. package/src/plugins/impl/panel/PanelPlugin.tsx +16 -17
  688. package/src/plugins/impl/panel/__tests__/utils.test.ts +39 -1
  689. package/src/plugins/impl/panel/utils.ts +17 -0
  690. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +2 -5
  691. package/src/plugins/impl/plotly/selection.ts +25 -19
  692. package/src/plugins/impl/vega/VegaPlugin.tsx +2 -3
  693. package/src/plugins/impl/vega/make-selectable.ts +4 -7
  694. package/src/plugins/layout/DownloadPlugin.tsx +7 -11
  695. package/src/plugins/layout/RoutesPlugin.tsx +1 -1
  696. package/src/plugins/layout/__test__/DownloadPlugin.test.tsx +205 -0
  697. package/src/stories/__tests__/editor-story.test.tsx +33 -0
  698. package/src/stories/button.stories.tsx +1 -0
  699. package/src/stories/cell.stories.tsx +2 -5
  700. package/src/stories/data-table.stories.tsx +31 -0
  701. package/src/stories/editor.stories.tsx +24 -17
  702. package/src/stories/form-wrapper.stories.tsx +2 -2
  703. package/src/stories/layout/vertical/one-column.stories.tsx +28 -23
  704. package/src/stories/runtime-story.tsx +23 -17
  705. package/src/stories/select.stories.tsx +2 -2
  706. package/src/stories/switchable-multi-select.stories.tsx +1 -1
  707. package/src/utils/__tests__/arrays.test.ts +35 -0
  708. package/src/utils/__tests__/batch-requests.test.ts +3 -3
  709. package/src/utils/__tests__/{createReducer.test.ts → createReducer.test.tsx} +127 -1
  710. package/src/utils/__tests__/download.test.tsx +183 -23
  711. package/src/utils/__tests__/numbers.test.ts +105 -1
  712. package/src/utils/__tests__/objects.test.ts +21 -0
  713. package/src/utils/arrays.ts +11 -2
  714. package/src/utils/blob.ts +1 -1
  715. package/src/utils/createReducer.ts +115 -79
  716. package/src/utils/download.ts +67 -6
  717. package/src/utils/maps.ts +0 -3
  718. package/src/utils/numbers.ts +79 -18
  719. package/src/utils/objects.ts +4 -9
  720. package/src/utils/tracer.ts +9 -5
  721. package/src/utils/zod-utils.ts +1 -3
  722. package/dist/_baseMerge-BiGRwuqv.js +0 -165
  723. package/dist/any-language-editor-D4q-IFcM.js +0 -76
  724. package/dist/assets/__vite-browser-external-BXYkiFsk.js +0 -1
  725. package/dist/assets/worker-HPY9fbhz.js +0 -114
  726. package/dist/code-visibility-XgDUZz2f.js +0 -138
  727. package/dist/dropdown-menu-DHP9P4VE.js +0 -4678
  728. package/dist/feedback-button-CoWyGXbB.js +0 -379
  729. package/dist/hasIn-o2Us0uVx.js +0 -132
  730. package/dist/html-to-image-BdA59IUD.js +0 -3251
  731. package/dist/isArrayLikeObject-BZl-15ir.js +0 -450
  732. package/dist/isEmpty-BSZ1LaUo.js +0 -35
  733. package/dist/isSymbol-kQcfYbNX.js +0 -8
  734. package/dist/label-DoysmLMW.js +0 -281
  735. package/dist/mermaid-HWGCJPDP-ByCsZnYF.js +0 -2
  736. package/dist/objectWithoutPropertiesLoose-BRDcTsfB.js +0 -23
  737. package/dist/pick-CJeoxYOS.js +0 -51
  738. package/dist/precisionRound-DMIVQrt2.js +0 -97
  739. package/dist/select-DemoKT4G.js +0 -1344
  740. package/dist/toDate-B5mIgxwZ.js +0 -1185
  741. package/dist/toast-PkdZraM8.js +0 -1830
  742. package/dist/use-restore-focus-CKjfFjLM.js +0 -6369
  743. package/dist/useLifecycle-BGWzTwHK.js +0 -169
  744. package/dist/useTheme-BhQvec43.js +0 -904
  745. package/src/components/editor/ai/__tests__/staged-cell-submission.test.ts +0 -106
  746. package/src/components/editor/ai/add-cell-with-ai.tsx +0 -506
  747. package/src/components/editor/ai/staged-cell-submission.ts +0 -46
  748. package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +0 -64
  749. package/src/components/editor/cell/code/__tests__/rtc-editor-config.test.ts +0 -50
  750. package/src/components/editor/chrome/wrapper/footer-items/rtc-status.tsx +0 -65
  751. package/src/components/editor/navigation/__tests__/state.test.ts +0 -81
  752. package/src/components/editor/navigation/state.ts +0 -65
  753. package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +0 -656
  754. package/src/core/ai/tools/run-cells-tool.ts +0 -303
  755. package/src/core/attachments/state.ts +0 -18
  756. package/src/core/cells/__tests__/apply-transaction.test.ts +0 -991
  757. package/src/core/cells/__tests__/document-changes.test.ts +0 -1140
  758. package/src/core/cells/__tests__/document-roundtrip.test.ts +0 -392
  759. package/src/core/cells/document-changes.ts +0 -944
  760. package/src/core/codemirror/rtc/extension.ts +0 -453
  761. package/src/core/codemirror/rtc/loro/__tests__/sync.test.ts +0 -52
  762. package/src/core/codemirror/rtc/loro/awareness.ts +0 -531
  763. package/src/core/codemirror/rtc/loro/colors.ts +0 -38
  764. package/src/core/codemirror/rtc/loro/sync.ts +0 -168
  765. package/src/core/host/AGENTS.md +0 -11
  766. package/src/core/host/__tests__/events.test.ts +0 -46
  767. package/src/core/host/__tests__/fixtures.ts +0 -39
  768. package/src/core/host/__tests__/notebook-client.test.ts +0 -433
  769. package/src/core/host/__tests__/protocol.test.ts +0 -214
  770. package/src/core/host/__tests__/stream.test.ts +0 -209
  771. package/src/core/host/connection.ts +0 -81
  772. package/src/core/host/events.ts +0 -61
  773. package/src/core/host/notebook-client.ts +0 -290
  774. package/src/core/host/protocol.ts +0 -1943
  775. package/src/core/host/resources/resource.ts +0 -47
  776. package/src/core/host/stream.ts +0 -211
  777. package/src/core/rtc/state.ts +0 -34
  778. package/src/core/state/__tests__/jotai.test.ts +0 -25
  779. package/src/core/wasm/worker/message-buffer.ts +0 -33
  780. package/src/core/websocket/__tests__/createConnectionTransport.test.ts +0 -49
  781. package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +0 -170
  782. package/src/core/websocket/state.ts +0 -7
  783. package/src/core/websocket/transports/__tests__/basic.test.ts +0 -275
  784. package/src/core/websocket/transports/__tests__/sse.test.ts +0 -335
  785. package/src/core/websocket/transports/__tests__/transport.test.ts +0 -308
  786. package/src/core/websocket/transports/__tests__/ws.test.ts +0 -125
  787. package/src/core/websocket/transports/basic.ts +0 -102
  788. package/src/core/websocket/transports/create.ts +0 -31
  789. package/src/core/websocket/transports/sse.ts +0 -308
  790. package/src/core/websocket/transports/transport.ts +0 -50
  791. package/src/core/websocket/transports/ws.ts +0 -98
  792. package/src/core/websocket/useNotebookClient.ts +0 -88
  793. package/src/utils/__tests__/id-tree.test.ts +0 -2145
  794. package/src/utils/id-tree.tsx +0 -1134
  795. /package/src/{core/attachments/toast.ts → components/editor/agent-toast.ts} +0 -0
  796. /package/src/core/{websocket → session}/connection-utils.ts +0 -0
@@ -1,21 +1,14 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { zodResolver } from "@hookform/resolvers/zod";
4
+ import { useMediaQuery } from "@uidotdev/usehooks";
4
5
  import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
5
- import {
6
- AlertTriangleIcon,
7
- BrainIcon,
8
- CpuIcon,
9
- EditIcon,
10
- FlaskConicalIcon,
11
- FolderCog2,
12
- LayersIcon,
13
- MonitorIcon,
14
- } from "lucide-react";
6
+ import { AlertTriangleIcon, ArrowUpRightIcon } from "lucide-react";
15
7
  import React, { useId, useRef } from "react";
16
8
  import { useLocale } from "react-aria";
17
9
  import { useForm } from "react-hook-form";
18
10
  import type z from "zod";
11
+ import { MinimalShortcut } from "@/components/shortcuts/renderShortcut";
19
12
  import { Button } from "@/components/ui/button";
20
13
  import { Checkbox } from "@/components/ui/checkbox";
21
14
  import { acceptCompletionOnEnterAtom } from "@/core/codemirror/completion/accept-on-enter-atom";
@@ -23,7 +16,6 @@ import {
23
16
  Form,
24
17
  FormControl,
25
18
  FormDescription,
26
- FormField,
27
19
  FormItem,
28
20
  FormLabel,
29
21
  FormMessage,
@@ -31,12 +23,13 @@ import {
31
23
  import { Kbd } from "@/components/ui/kbd";
32
24
  import { NativeSelect } from "@/components/ui/native-select";
33
25
  import { NumberField } from "@/components/ui/number-field";
34
- import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
26
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
35
27
  import { KEYMAP_PRESETS } from "@/core/codemirror/keymaps/keymaps";
36
28
  import { capabilitiesAtom } from "@/core/config/capabilities";
37
29
  import { mergeConfig, useUserConfig } from "@/core/config/config";
38
30
  import {
39
31
  PackageManagerNames,
32
+ TYPE_INFERENCE_MODES,
40
33
  type UserConfig,
41
34
  UserConfigSchema,
42
35
  } from "@/core/config/config-schema";
@@ -49,7 +42,6 @@ import { useDebouncedCallback } from "@/hooks/useDebounce";
49
42
  import { Banner } from "@/plugins/impl/common/error-banner";
50
43
  import { THEMES } from "@/theme/useTheme";
51
44
  import { arrayToggle } from "@/utils/arrays";
52
- import { cn } from "@/utils/cn";
53
45
  import { autoPopulateModels } from "../ai/ai-utils";
54
46
  import { keyboardShortcutsAtom } from "../editor/controls/keyboard-shortcuts";
55
47
  import { Badge } from "../ui/badge";
@@ -65,49 +57,36 @@ import {
65
57
  useConfigOverride,
66
58
  } from "./is-overridden";
67
59
  import { OptionalFeatures } from "./optional-features";
60
+ import "./user-config-form.css";
68
61
 
69
62
  const categories = [
70
63
  {
71
64
  id: "editor",
72
65
  label: "Editor",
73
- Icon: EditIcon,
74
- className: "bg-(--blue-4)",
75
66
  },
76
67
  {
77
68
  id: "display",
78
69
  label: "Display",
79
- Icon: MonitorIcon,
80
- className: "bg-(--grass-4)",
81
70
  },
82
71
  {
83
72
  id: "packageManagementAndData",
84
73
  label: "Packages & Data",
85
- Icon: LayersIcon,
86
- className: "bg-(--red-4)",
87
74
  },
88
75
  {
89
76
  id: "runtime",
90
77
  label: "Runtime",
91
- Icon: CpuIcon,
92
- className: "bg-(--amber-4)",
93
78
  },
94
79
  {
95
80
  id: "ai",
96
81
  label: "AI",
97
- Icon: BrainIcon,
98
- className: "bg-[linear-gradient(45deg,var(--purple-5),var(--cyan-5))]",
99
82
  },
100
83
  {
101
84
  id: "optionalDeps",
102
85
  label: "Optional Dependencies",
103
- Icon: FolderCog2,
104
- className: "bg-(--orange-4)",
105
86
  },
106
87
  {
107
88
  id: "labs",
108
89
  label: "Labs",
109
- Icon: FlaskConicalIcon,
110
- className: "bg-(--slate-4)",
111
90
  },
112
91
  ] as const;
113
92
 
@@ -122,6 +101,7 @@ const LOCALE_SYSTEM_VALUE = "__system__";
122
101
 
123
102
  export const UserConfigForm: React.FC = () => {
124
103
  const [config, setConfig] = useUserConfig();
104
+ const isWideLayout = useMediaQuery("(min-width: 640px)");
125
105
  const [acceptOnEnter, setAcceptOnEnter] = useAtom(
126
106
  acceptCompletionOnEnterAtom,
127
107
  );
@@ -222,9 +202,7 @@ export const UserConfigForm: React.FC = () => {
222
202
  name="save.autosave"
223
203
  render={({ field, override }) => (
224
204
  <FormItem className={formItemClasses}>
225
- <FormLabel className="font-normal">
226
- Autosave enabled
227
- </FormLabel>
205
+ <FormLabel>Autosave</FormLabel>
228
206
  <FormControl>
229
207
  <Checkbox
230
208
  data-testid="autosave-checkbox"
@@ -235,6 +213,9 @@ export const UserConfigForm: React.FC = () => {
235
213
  }}
236
214
  />
237
215
  </FormControl>
216
+ <FormDescription>
217
+ Automatically save changes to the notebook.
218
+ </FormDescription>
238
219
  <FormMessage />
239
220
  <IsOverridden override={override} />
240
221
  </FormItem>
@@ -251,6 +232,9 @@ export const UserConfigForm: React.FC = () => {
251
232
  return (
252
233
  <FormItem className={formItemClasses}>
253
234
  <FormLabel>Autosave delay (seconds)</FormLabel>
235
+ <FormDescription>
236
+ Time to wait after the last change before saving.
237
+ </FormDescription>
254
238
  <FormControl>
255
239
  <NumberField
256
240
  aria-label="Autosave delay"
@@ -283,9 +267,15 @@ export const UserConfigForm: React.FC = () => {
283
267
  control={form.control}
284
268
  name="runtime.default_auto_download"
285
269
  render={({ field, override }) => (
286
- <div className="flex flex-col gap-y-1">
270
+ <div className="settings-field flex flex-col gap-y-1">
287
271
  <FormItem className={formItemClasses}>
288
272
  <FormLabel>Save cell outputs as</FormLabel>
273
+ <FormDescription>
274
+ When enabled, marimo will periodically save notebooks in
275
+ your selected formats (HTML, IPYNB) to a folder named{" "}
276
+ <Kbd className="inline">__marimo__</Kbd> next to your
277
+ notebook file.
278
+ </FormDescription>
289
279
  <FormControl>
290
280
  <div className="flex gap-4">
291
281
  <div className="flex items-center space-x-2">
@@ -333,12 +323,6 @@ export const UserConfigForm: React.FC = () => {
333
323
  <FormMessage />
334
324
  <IsOverridden override={override} />
335
325
  </FormItem>
336
- <FormDescription>
337
- When enabled, marimo will periodically save notebooks in
338
- your selected formats (HTML, IPYNB) to a folder named{" "}
339
- <Kbd className="inline">__marimo__</Kbd> next to your
340
- notebook file.
341
- </FormDescription>
342
326
  </div>
343
327
  )}
344
328
  />
@@ -349,9 +333,7 @@ export const UserConfigForm: React.FC = () => {
349
333
  name="save.format_on_save"
350
334
  render={({ field, override }) => (
351
335
  <FormItem className={formItemClasses}>
352
- <FormLabel className="font-normal">
353
- Format on save
354
- </FormLabel>
336
+ <FormLabel>Format on save</FormLabel>
355
337
  <FormControl>
356
338
  <Checkbox
357
339
  data-testid="format-on-save-checkbox"
@@ -362,6 +344,9 @@ export const UserConfigForm: React.FC = () => {
362
344
  }}
363
345
  />
364
346
  </FormControl>
347
+ <FormDescription>
348
+ Automatically format code when saving the notebook.
349
+ </FormDescription>
365
350
  <FormMessage />
366
351
  <IsOverridden override={override} />
367
352
  </FormItem>
@@ -371,9 +356,12 @@ export const UserConfigForm: React.FC = () => {
371
356
  control={form.control}
372
357
  name="formatting.line_length"
373
358
  render={({ field, override }) => (
374
- <div className="flex flex-col space-y-1">
359
+ <div className="settings-field flex flex-col space-y-1">
375
360
  <FormItem className={formItemClasses}>
376
361
  <FormLabel>Line length</FormLabel>
362
+ <FormDescription>
363
+ Maximum line length when formatting code.
364
+ </FormDescription>
377
365
  <FormControl>
378
366
  <NumberField
379
367
  aria-label="Line length"
@@ -396,24 +384,52 @@ export const UserConfigForm: React.FC = () => {
396
384
  <FormMessage />
397
385
  <IsOverridden override={override} />
398
386
  </FormItem>
399
-
400
- <FormDescription>
401
- Maximum line length when formatting code.
402
- </FormDescription>
403
387
  </div>
404
388
  )}
405
389
  />
390
+ {!isWasmRuntime && (
391
+ <OverriddenFormField
392
+ control={form.control}
393
+ name="formatting.infer_types"
394
+ render={({ field, override }) => (
395
+ <div className="settings-field flex flex-col space-y-1">
396
+ <FormItem className={formItemClasses}>
397
+ <FormLabel>Infer types on save</FormLabel>
398
+ <FormDescription>
399
+ Add inferred type annotations to cell signatures when
400
+ saving.
401
+ </FormDescription>
402
+ <FormControl>
403
+ <NativeSelect
404
+ data-testid="infer-types-select"
405
+ onChange={(e) => field.onChange(e.target.value)}
406
+ value={override.value}
407
+ disabled={field.disabled || override.isOverridden}
408
+ className="inline-flex mr-2"
409
+ >
410
+ {TYPE_INFERENCE_MODES.map((option) => (
411
+ <option value={option} key={option}>
412
+ {option}
413
+ </option>
414
+ ))}
415
+ </NativeSelect>
416
+ </FormControl>
417
+ <FormMessage />
418
+ <IsOverridden override={override} />
419
+ </FormItem>
420
+ </div>
421
+ )}
422
+ />
423
+ )}
406
424
  </SettingGroup>
407
425
  <SettingGroup title="Autocomplete">
408
426
  <OverriddenFormField
409
427
  control={form.control}
410
428
  name="completion.activate_on_typing"
411
429
  render={({ field, override }) => (
412
- <div className="flex flex-col space-y-1">
430
+ <div className="settings-field flex flex-col space-y-1">
413
431
  <FormItem className={formItemClasses}>
414
- <FormLabel className="font-normal">
415
- Autocomplete
416
- </FormLabel>
432
+ <FormLabel>Autocomplete</FormLabel>
417
433
  <FormControl>
418
434
  <Checkbox
419
435
  data-testid="autocomplete-checkbox"
@@ -428,32 +444,21 @@ export const UserConfigForm: React.FC = () => {
428
444
  <IsOverridden override={override} />
429
445
  </FormItem>
430
446
  <FormDescription>
431
- When unchecked, code completion is still available through
432
- a hotkey.
447
+ When unchecked, code completion is still available with{" "}
448
+ <Kbd className="inline-flex">
449
+ <MinimalShortcut
450
+ shortcut="cell.complete"
451
+ className="inline-flex ml-0 tracking-normal opacity-100"
452
+ />
453
+ </Kbd>
454
+ .
433
455
  </FormDescription>
434
-
435
- <div>
436
- <Button
437
- variant="link"
438
- className="mb-0 px-0"
439
- type="button"
440
- onClick={(evt) => {
441
- evt.preventDefault();
442
- evt.stopPropagation();
443
- setActiveCategory("ai");
444
- }}
445
- >
446
- Edit AI autocomplete
447
- </Button>
448
- </div>
449
456
  </div>
450
457
  )}
451
458
  />
452
- <div className="flex flex-col space-y-1">
459
+ <div className="settings-field flex flex-col space-y-1">
453
460
  <FormItem className={formItemClasses}>
454
- <FormLabel className="font-normal">
455
- Accept suggestion on Enter
456
- </FormLabel>
461
+ <FormLabel>Accept suggestion on Enter</FormLabel>
457
462
  <FormControl>
458
463
  <Checkbox
459
464
  data-testid="accept-completion-on-enter-checkbox"
@@ -465,8 +470,9 @@ export const UserConfigForm: React.FC = () => {
465
470
  </FormControl>
466
471
  </FormItem>
467
472
  <FormDescription>
468
- When unchecked, pressing Enter inserts a new line instead of
469
- accepting an autocomplete suggestion. Use Tab to accept
473
+ When unchecked, pressing <Kbd className="inline">Enter</Kbd>{" "}
474
+ inserts a new line instead of accepting an autocomplete
475
+ suggestion. Use <Kbd className="inline">Tab</Kbd> to accept
470
476
  suggestions.
471
477
  </FormDescription>
472
478
  </div>
@@ -474,11 +480,9 @@ export const UserConfigForm: React.FC = () => {
474
480
  control={form.control}
475
481
  name="completion.signature_hint_on_typing"
476
482
  render={({ field, override }) => (
477
- <div className="flex flex-col space-y-1">
483
+ <div className="settings-field flex flex-col space-y-1">
478
484
  <FormItem className={formItemClasses}>
479
- <FormLabel className="font-normal">
480
- Signature hints
481
- </FormLabel>
485
+ <FormLabel>Signature hints</FormLabel>
482
486
  <FormControl>
483
487
  <Checkbox
484
488
  data-testid="signature-hint-on-type-checkbox"
@@ -503,11 +507,9 @@ export const UserConfigForm: React.FC = () => {
503
507
  control={form.control}
504
508
  name="completion.auto_close_pairs"
505
509
  render={({ field, override }) => (
506
- <div className="flex flex-col space-y-1">
510
+ <div className="settings-field flex flex-col space-y-1">
507
511
  <FormItem className={formItemClasses}>
508
- <FormLabel className="font-normal">
509
- Auto-close pairs
510
- </FormLabel>
512
+ <FormLabel>Auto-close pairs</FormLabel>
511
513
  <FormControl>
512
514
  <Checkbox
513
515
  data-testid="auto-close-pairs-checkbox"
@@ -533,15 +535,89 @@ export const UserConfigForm: React.FC = () => {
533
535
  )}
534
536
  />
535
537
  </SettingGroup>
536
- <SettingGroup title="Language Servers">
538
+ <SettingGroup title="Keymap">
539
+ <Button
540
+ variant="link"
541
+ className="h-auto self-start gap-1 p-0"
542
+ type="button"
543
+ onClick={() => setKeyboardShortcutsOpen(true)}
544
+ >
545
+ Edit keyboard shortcuts
546
+ <ArrowUpRightIcon className="h-3.5 w-3.5" aria-hidden={true} />
547
+ </Button>
548
+ <OverriddenFormField
549
+ control={form.control}
550
+ name="keymap.preset"
551
+ render={({ field, override }) => (
552
+ <div className="settings-field flex flex-col space-y-1">
553
+ <FormItem className={formItemClasses}>
554
+ <FormLabel>Keymap</FormLabel>
555
+ <FormControl>
556
+ <NativeSelect
557
+ data-testid="keymap-select"
558
+ onChange={(e) => field.onChange(e.target.value)}
559
+ value={override.value}
560
+ disabled={field.disabled || override.isOverridden}
561
+ className="inline-flex mr-2"
562
+ >
563
+ {KEYMAP_PRESETS.map((option) => (
564
+ <option value={option} key={option}>
565
+ {option}
566
+ </option>
567
+ ))}
568
+ </NativeSelect>
569
+ </FormControl>
570
+ <FormMessage />
571
+ <IsOverridden override={override} />
572
+ </FormItem>
573
+ </div>
574
+ )}
575
+ />
576
+ <OverriddenFormField
577
+ control={form.control}
578
+ name="keymap.destructive_delete"
579
+ render={({ field, override }) => (
580
+ <div className="settings-field flex flex-col space-y-1">
581
+ <FormItem className={formItemClasses}>
582
+ <FormLabel>Destructive delete</FormLabel>
583
+ <FormControl>
584
+ <Checkbox
585
+ data-testid="destructive-delete-checkbox"
586
+ checked={override.value}
587
+ disabled={field.disabled || override.isOverridden}
588
+ onCheckedChange={(checked) => {
589
+ field.onChange(Boolean(checked));
590
+ }}
591
+ />
592
+ </FormControl>
593
+ <FormMessage />
594
+ <IsOverridden override={override} />
595
+ </FormItem>
596
+ <FormDescription className="flex items-center gap-1">
597
+ Allow deleting non-empty cells
598
+ <Tooltip
599
+ content={
600
+ <div className="max-w-xs">
601
+ <strong>Use with caution:</strong> Deleting cells
602
+ with code can lose work and computed results since
603
+ variables are removed from memory.
604
+ </div>
605
+ }
606
+ >
607
+ <AlertTriangleIcon className="w-3 h-3 text-(--amber-11)" />
608
+ </Tooltip>
609
+ </FormDescription>
610
+ </div>
611
+ )}
612
+ />
613
+ </SettingGroup>
614
+ <SettingGroup title="Language servers">
537
615
  <FormDescription>
538
616
  See the{" "}
539
617
  <ExternalLink href="https://docs.marimo.io/guides/editor_features/language_server/">
540
618
  docs
541
619
  </ExternalLink>{" "}
542
- for more information about language server support.
543
- </FormDescription>
544
- <FormDescription>
620
+ for more information about language server support.{" "}
545
621
  <strong>Note:</strong> When using multiple language servers,
546
622
  different features may conflict.
547
623
  </FormDescription>
@@ -550,7 +626,7 @@ export const UserConfigForm: React.FC = () => {
550
626
  control={form.control}
551
627
  name="language_servers.pylsp.enabled"
552
628
  render={({ field, override }) => (
553
- <div className="flex flex-col gap-1">
629
+ <div className="settings-field flex flex-col gap-1">
554
630
  <FormItem className={formItemClasses}>
555
631
  <FormLabel>
556
632
  <Badge variant="defaultOutline" className="mr-2">
@@ -590,7 +666,7 @@ export const UserConfigForm: React.FC = () => {
590
666
  control={form.control}
591
667
  name="language_servers.basedpyright.enabled"
592
668
  render={({ field, override }) => (
593
- <div className="flex flex-col gap-1">
669
+ <div className="settings-field flex flex-col gap-1">
594
670
  <FormItem className={formItemClasses}>
595
671
  <FormLabel>
596
672
  <Badge variant="defaultOutline" className="mr-2">
@@ -630,7 +706,7 @@ export const UserConfigForm: React.FC = () => {
630
706
  control={form.control}
631
707
  name="language_servers.pyrefly.enabled"
632
708
  render={({ field, override }) => (
633
- <div className="flex flex-col gap-1">
709
+ <div className="settings-field flex flex-col gap-1">
634
710
  <FormItem className={formItemClasses}>
635
711
  <FormLabel>
636
712
  <Badge variant="defaultOutline" className="mr-2">
@@ -669,7 +745,7 @@ export const UserConfigForm: React.FC = () => {
669
745
  control={form.control}
670
746
  name="language_servers.ty.enabled"
671
747
  render={({ field, override }) => (
672
- <div className="flex flex-col gap-1">
748
+ <div className="settings-field flex flex-col gap-1">
673
749
  <FormItem className={formItemClasses}>
674
750
  <FormLabel>
675
751
  <Badge variant="defaultOutline" className="mr-2">
@@ -731,91 +807,6 @@ export const UserConfigForm: React.FC = () => {
731
807
  )}
732
808
  />
733
809
  </SettingGroup>
734
-
735
- <SettingGroup title="Keymap">
736
- <OverriddenFormField
737
- control={form.control}
738
- name="keymap.preset"
739
- render={({ field, override }) => (
740
- <div className="flex flex-col space-y-1">
741
- <FormItem className={formItemClasses}>
742
- <FormLabel>Keymap</FormLabel>
743
- <FormControl>
744
- <NativeSelect
745
- data-testid="keymap-select"
746
- onChange={(e) => field.onChange(e.target.value)}
747
- value={override.value}
748
- disabled={field.disabled || override.isOverridden}
749
- className="inline-flex mr-2"
750
- >
751
- {KEYMAP_PRESETS.map((option) => (
752
- <option value={option} key={option}>
753
- {option}
754
- </option>
755
- ))}
756
- </NativeSelect>
757
- </FormControl>
758
- <FormMessage />
759
- <IsOverridden override={override} />
760
- </FormItem>
761
- </div>
762
- )}
763
- />
764
- <OverriddenFormField
765
- control={form.control}
766
- name="keymap.destructive_delete"
767
- render={({ field, override }) => (
768
- <div className="flex flex-col space-y-1">
769
- <FormItem className={formItemClasses}>
770
- <FormLabel className="font-normal">
771
- Destructive delete
772
- </FormLabel>
773
- <FormControl>
774
- <Checkbox
775
- data-testid="destructive-delete-checkbox"
776
- checked={override.value}
777
- disabled={field.disabled || override.isOverridden}
778
- onCheckedChange={(checked) => {
779
- field.onChange(Boolean(checked));
780
- }}
781
- />
782
- </FormControl>
783
- <FormMessage />
784
- <IsOverridden override={override} />
785
- </FormItem>
786
- <FormDescription className="flex items-center gap-1">
787
- Allow deleting non-empty cells
788
- <Tooltip
789
- content={
790
- <div className="max-w-xs">
791
- <strong>Use with caution:</strong> Deleting cells
792
- with code can lose work and computed results since
793
- variables are removed from memory.
794
- </div>
795
- }
796
- >
797
- <AlertTriangleIcon className="w-3 h-3 text-(--amber-11)" />
798
- </Tooltip>
799
- </FormDescription>
800
-
801
- <div>
802
- <Button
803
- variant="link"
804
- className="mb-0 px-0"
805
- type="button"
806
- onClick={(evt) => {
807
- evt.preventDefault();
808
- evt.stopPropagation();
809
- setKeyboardShortcutsOpen(true);
810
- }}
811
- >
812
- Edit Keyboard Shortcuts
813
- </Button>
814
- </div>
815
- </div>
816
- )}
817
- />
818
- </SettingGroup>
819
810
  </>
820
811
  );
821
812
  case "display":
@@ -826,9 +817,13 @@ export const UserConfigForm: React.FC = () => {
826
817
  control={form.control}
827
818
  name="display.default_width"
828
819
  render={({ field, override }) => (
829
- <div className="flex flex-col space-y-1">
820
+ <div className="settings-field flex flex-col space-y-1">
830
821
  <FormItem className={formItemClasses}>
831
822
  <FormLabel>Default width</FormLabel>
823
+ <FormDescription>
824
+ The default app width for new notebooks; overridden by
825
+ "width" in the application config.
826
+ </FormDescription>
832
827
  <FormControl>
833
828
  <NativeSelect
834
829
  data-testid="user-config-width-select"
@@ -847,11 +842,6 @@ export const UserConfigForm: React.FC = () => {
847
842
  <FormMessage />
848
843
  <IsOverridden override={override} />
849
844
  </FormItem>
850
-
851
- <FormDescription>
852
- The default app width for new notebooks; overridden by
853
- "width" in the application config.
854
- </FormDescription>
855
845
  </div>
856
846
  )}
857
847
  />
@@ -859,9 +849,13 @@ export const UserConfigForm: React.FC = () => {
859
849
  control={form.control}
860
850
  name="display.theme"
861
851
  render={({ field, override }) => (
862
- <div className="flex flex-col space-y-1">
852
+ <div className="settings-field flex flex-col space-y-1">
863
853
  <FormItem className={formItemClasses}>
864
854
  <FormLabel>Theme</FormLabel>
855
+ <FormDescription>
856
+ This theme will be applied to the user's configuration;
857
+ it does not affect theme when sharing the notebook.
858
+ </FormDescription>
865
859
  <FormControl>
866
860
  <NativeSelect
867
861
  data-testid="theme-select"
@@ -880,11 +874,6 @@ export const UserConfigForm: React.FC = () => {
880
874
  <FormMessage />
881
875
  <IsOverridden override={override} />
882
876
  </FormItem>
883
-
884
- <FormDescription>
885
- This theme will be applied to the user's configuration; it
886
- does not affect theme when sharing the notebook.
887
- </FormDescription>
888
877
  </div>
889
878
  )}
890
879
  />
@@ -921,9 +910,14 @@ export const UserConfigForm: React.FC = () => {
921
910
  control={form.control}
922
911
  name="display.locale"
923
912
  render={({ field, override }) => (
924
- <div className="flex flex-col space-y-1">
913
+ <div className="settings-field flex flex-col space-y-1">
925
914
  <FormItem className={formItemClasses}>
926
915
  <FormLabel>Locale</FormLabel>
916
+ <FormDescription>
917
+ The locale to use for the notebook. If your desired
918
+ locale is not listed, you can change it manually via{" "}
919
+ <Kbd className="inline">marimo config show</Kbd>.
920
+ </FormDescription>
927
921
  <FormControl>
928
922
  <NativeSelect
929
923
  data-testid="locale-select"
@@ -949,12 +943,6 @@ export const UserConfigForm: React.FC = () => {
949
943
  <FormMessage />
950
944
  <IsOverridden override={override} />
951
945
  </FormItem>
952
-
953
- <FormDescription>
954
- The locale to use for the notebook. If your desired locale
955
- is not listed, you can change it manually via{" "}
956
- <Kbd className="inline">marimo config show</Kbd>.
957
- </FormDescription>
958
946
  </div>
959
947
  )}
960
948
  />
@@ -962,7 +950,7 @@ export const UserConfigForm: React.FC = () => {
962
950
  control={form.control}
963
951
  name="display.reference_highlighting"
964
952
  render={({ field, override }) => (
965
- <div className="flex flex-col space-y-1">
953
+ <div className="settings-field flex flex-col space-y-1">
966
954
  <FormItem className={formItemClasses}>
967
955
  <FormLabel>Reference highlighting</FormLabel>
968
956
  <FormControl>
@@ -988,7 +976,7 @@ export const UserConfigForm: React.FC = () => {
988
976
  control={form.control}
989
977
  name="display.code_lens"
990
978
  render={({ field, override }) => (
991
- <div className="flex flex-col space-y-1">
979
+ <div className="settings-field flex flex-col space-y-1">
992
980
  <FormItem className={formItemClasses}>
993
981
  <FormLabel>Code lens</FormLabel>
994
982
  <FormControl>
@@ -1016,9 +1004,12 @@ export const UserConfigForm: React.FC = () => {
1016
1004
  control={form.control}
1017
1005
  name="display.cell_output"
1018
1006
  render={({ field, override }) => (
1019
- <div className="flex flex-col space-y-1">
1007
+ <div className="settings-field flex flex-col space-y-1">
1020
1008
  <FormItem className={formItemClasses}>
1021
1009
  <FormLabel>Cell output area</FormLabel>
1010
+ <FormDescription>
1011
+ Where to display cell's output.
1012
+ </FormDescription>
1022
1013
  <FormControl>
1023
1014
  <NativeSelect
1024
1015
  data-testid="cell-output-select"
@@ -1037,10 +1028,6 @@ export const UserConfigForm: React.FC = () => {
1037
1028
  <FormMessage />
1038
1029
  <IsOverridden override={override} />
1039
1030
  </FormItem>
1040
-
1041
- <FormDescription>
1042
- Where to display cell's output.
1043
- </FormDescription>
1044
1031
  </div>
1045
1032
  )}
1046
1033
  />
@@ -1050,15 +1037,31 @@ export const UserConfigForm: React.FC = () => {
1050
1037
  case "packageManagementAndData":
1051
1038
  return (
1052
1039
  <>
1053
- <SettingGroup title="Package Management">
1040
+ <SettingGroup title="Package management">
1054
1041
  <OverriddenFormField
1055
1042
  control={form.control}
1056
1043
  disabled={isWasmRuntime}
1057
1044
  name="package_management.manager"
1058
1045
  render={({ field, override }) => (
1059
- <div className="flex flex-col space-y-1">
1046
+ <div className="settings-field flex flex-col space-y-1">
1060
1047
  <FormItem className={formItemClasses}>
1061
1048
  <FormLabel>Manager</FormLabel>
1049
+ <FormDescription>
1050
+ When marimo comes across a module that is not installed,
1051
+ you will be prompted to install it using your preferred
1052
+ package manager. Learn more in the{" "}
1053
+ <ExternalLink href="https://docs.marimo.io/guides/editor_features/package_management.html">
1054
+ docs
1055
+ </ExternalLink>
1056
+ .
1057
+ <br />
1058
+ <br />
1059
+ Running marimo in a{" "}
1060
+ <ExternalLink href="https://docs.marimo.io/guides/package_management/inlining_dependencies.html">
1061
+ sandboxed environment
1062
+ </ExternalLink>{" "}
1063
+ is only supported by <Kbd className="inline">uv</Kbd>
1064
+ </FormDescription>
1062
1065
  <FormControl>
1063
1066
  <NativeSelect
1064
1067
  data-testid="package-manager-select"
@@ -1077,30 +1080,11 @@ export const UserConfigForm: React.FC = () => {
1077
1080
  <FormMessage />
1078
1081
  <IsOverridden override={override} />
1079
1082
  </FormItem>
1080
-
1081
- <FormDescription>
1082
- When marimo comes across a module that is not installed,
1083
- you will be prompted to install it using your preferred
1084
- package manager. Learn more in the{" "}
1085
- <ExternalLink href="https://docs.marimo.io/guides/editor_features/package_management.html">
1086
- docs
1087
- </ExternalLink>
1088
- .
1089
- <br />
1090
- <br />
1091
- Running marimo in a{" "}
1092
- <ExternalLink href="https://docs.marimo.io/guides/package_management/inlining_dependencies.html">
1093
- sandboxed environment
1094
- </ExternalLink>{" "}
1095
- is only supported by <Kbd className="inline">uv</Kbd>
1096
- </FormDescription>
1097
1083
  </div>
1098
1084
  )}
1099
1085
  />
1100
1086
  </SettingGroup>
1101
- <SettingGroup title="Data">
1102
- <DataForm form={form} onSubmit={onSubmit} />
1103
- </SettingGroup>
1087
+ <DataForm form={form} onSubmit={onSubmit} />
1104
1088
  </>
1105
1089
  );
1106
1090
  case "runtime":
@@ -1110,11 +1094,9 @@ export const UserConfigForm: React.FC = () => {
1110
1094
  control={form.control}
1111
1095
  name="runtime.auto_instantiate"
1112
1096
  render={({ field, override }) => (
1113
- <div className="flex flex-col gap-y-1">
1097
+ <div className="settings-field flex flex-col gap-y-1">
1114
1098
  <FormItem className={formItemClasses}>
1115
- <FormLabel className="font-normal">
1116
- Autorun on startup
1117
- </FormLabel>
1099
+ <FormLabel>Autorun on startup</FormLabel>
1118
1100
  <FormControl>
1119
1101
  <Checkbox
1120
1102
  data-testid="auto-instantiate-checkbox"
@@ -1137,11 +1119,16 @@ export const UserConfigForm: React.FC = () => {
1137
1119
  control={form.control}
1138
1120
  name="runtime.on_cell_change"
1139
1121
  render={({ field, override }) => (
1140
- <div className="flex flex-col gap-y-1">
1122
+ <div className="settings-field flex flex-col gap-y-1">
1141
1123
  <FormItem className={formItemClasses}>
1142
- <FormLabel className="font-normal">
1143
- On cell change
1144
- </FormLabel>
1124
+ <FormLabel>On cell change</FormLabel>
1125
+ <FormDescription>
1126
+ Whether marimo should automatically run cells or just mark
1127
+ them as stale. If "autorun", marimo will automatically run
1128
+ affected cells when a cell is run or a UI element is
1129
+ interacted with; if "lazy", marimo will mark affected
1130
+ cells as stale but won't re-run them.
1131
+ </FormDescription>
1145
1132
  <FormControl>
1146
1133
  <NativeSelect
1147
1134
  data-testid="on-cell-change-select"
@@ -1160,13 +1147,6 @@ export const UserConfigForm: React.FC = () => {
1160
1147
  <FormMessage />
1161
1148
  <IsOverridden override={override} />
1162
1149
  </FormItem>
1163
- <FormDescription>
1164
- Whether marimo should automatically run cells or just mark
1165
- them as stale. If "autorun", marimo will automatically run
1166
- affected cells when a cell is run or a UI element is
1167
- interacted with; if "lazy", marimo will mark affected cells
1168
- as stale but won't re-run them.
1169
- </FormDescription>
1170
1150
  </div>
1171
1151
  )}
1172
1152
  />
@@ -1174,11 +1154,15 @@ export const UserConfigForm: React.FC = () => {
1174
1154
  control={form.control}
1175
1155
  name="runtime.auto_reload"
1176
1156
  render={({ field, override }) => (
1177
- <div className="flex flex-col gap-y-1">
1157
+ <div className="settings-field flex flex-col gap-y-1">
1178
1158
  <FormItem className={formItemClasses}>
1179
- <FormLabel className="font-normal">
1180
- On module change
1181
- </FormLabel>
1159
+ <FormLabel>On module change</FormLabel>
1160
+ <FormDescription>
1161
+ Whether marimo should automatically reload modules before
1162
+ executing cells. If "lazy", marimo will mark cells
1163
+ affected by module modifications as stale; if "autorun",
1164
+ affected cells will be automatically re-run.
1165
+ </FormDescription>
1182
1166
  <FormControl>
1183
1167
  <NativeSelect
1184
1168
  data-testid="auto-reload-select"
@@ -1197,12 +1181,6 @@ export const UserConfigForm: React.FC = () => {
1197
1181
  <FormMessage />
1198
1182
  <IsOverridden override={override} />
1199
1183
  </FormItem>
1200
- <FormDescription>
1201
- Whether marimo should automatically reload modules before
1202
- executing cells. If "lazy", marimo will mark cells affected
1203
- by module modifications as stale; if "autorun", affected
1204
- cells will be automatically re-run.
1205
- </FormDescription>
1206
1184
  </div>
1207
1185
  )}
1208
1186
  />
@@ -1211,11 +1189,9 @@ export const UserConfigForm: React.FC = () => {
1211
1189
  control={form.control}
1212
1190
  name="runtime.reactive_tests"
1213
1191
  render={({ field, override }) => (
1214
- <div className="flex flex-col gap-y-1">
1192
+ <div className="settings-field flex flex-col gap-y-1">
1215
1193
  <FormItem className={formItemClasses}>
1216
- <FormLabel className="font-normal">
1217
- Autorun Unit Tests
1218
- </FormLabel>
1194
+ <FormLabel>Autorun Unit Tests</FormLabel>
1219
1195
  <FormControl>
1220
1196
  <Checkbox
1221
1197
  data-testid="reactive-test-checkbox"
@@ -1238,7 +1214,7 @@ export const UserConfigForm: React.FC = () => {
1238
1214
  />
1239
1215
 
1240
1216
  <FormDescription>
1241
- Learn more in the{" "}
1217
+ Learn more about how marimo runs cells in the{" "}
1242
1218
  <ExternalLink href="https://docs.marimo.io/guides/reactivity/#configuring-how-marimo-runs-cells">
1243
1219
  docs
1244
1220
  </ExternalLink>
@@ -1252,74 +1228,19 @@ export const UserConfigForm: React.FC = () => {
1252
1228
  return <OptionalFeatures />;
1253
1229
  case "labs":
1254
1230
  return (
1255
- <SettingGroup title="Experimental Features">
1256
- <p className="text-sm text-muted-secondary mb-4">
1231
+ <SettingGroup title="Experimental features">
1232
+ <p className="text-sm text-muted-foreground mb-4">
1257
1233
  ⚠️ These features are experimental and may require restarting your
1258
1234
  notebook to take effect.
1259
1235
  </p>
1260
1236
 
1261
- <FormField
1262
- control={form.control}
1263
- name="experimental.rtc_v2"
1264
- render={({ field }) => (
1265
- <div className="flex flex-col gap-y-1">
1266
- <FormItem className={formItemClasses}>
1267
- <FormLabel className="font-normal">
1268
- Real-Time Collaboration
1269
- </FormLabel>
1270
- <FormControl>
1271
- <Checkbox
1272
- data-testid="rtc-checkbox"
1273
- checked={field.value === true}
1274
- onCheckedChange={field.onChange}
1275
- />
1276
- </FormControl>
1277
- </FormItem>
1278
-
1279
- <FormDescription>
1280
- Enable experimental real-time collaboration. This change
1281
- requires a page refresh to take effect.
1282
- </FormDescription>
1283
- </div>
1284
- )}
1285
- />
1286
- <OverriddenFormField
1287
- control={form.control}
1288
- name="experimental.external_agents"
1289
- render={({ field, override }) => (
1290
- <div className="flex flex-col gap-y-1">
1291
- <FormItem className={formItemClasses}>
1292
- <FormLabel className="font-normal">
1293
- External Agents
1294
- </FormLabel>
1295
- <FormControl>
1296
- <Checkbox
1297
- data-testid="external-agents-checkbox"
1298
- checked={override.value === true}
1299
- disabled={override.isOverridden}
1300
- onCheckedChange={field.onChange}
1301
- />
1302
- </FormControl>
1303
- </FormItem>
1304
- <IsOverridden override={override} />
1305
- <FormDescription>
1306
- Enable experimental external agents such as Claude Code and
1307
- Codex. Learn more in the{" "}
1308
- <ExternalLink href="https://docs.marimo.io/guides/editor_features/agents/">
1309
- docs
1310
- </ExternalLink>
1311
- .
1312
- </FormDescription>
1313
- </div>
1314
- )}
1315
- />
1316
1237
  <OverriddenFormField
1317
1238
  control={form.control}
1318
1239
  name="experimental.debugger"
1319
1240
  render={({ field, override }) => (
1320
- <div className="flex flex-col gap-y-1">
1241
+ <div className="settings-field flex flex-col gap-y-1">
1321
1242
  <FormItem className={formItemClasses}>
1322
- <FormLabel className="font-normal">Debugger</FormLabel>
1243
+ <FormLabel>Debugger</FormLabel>
1323
1244
  <FormControl>
1324
1245
  <Checkbox
1325
1246
  data-testid="debugger-checkbox"
@@ -1343,9 +1264,9 @@ export const UserConfigForm: React.FC = () => {
1343
1264
  control={form.control}
1344
1265
  name="experimental.line_timing"
1345
1266
  render={({ field, override }) => (
1346
- <div className="flex flex-col gap-y-1">
1267
+ <div className="settings-field flex flex-col gap-y-1">
1347
1268
  <FormItem className={formItemClasses}>
1348
- <FormLabel className="font-normal">Line Timing</FormLabel>
1269
+ <FormLabel>Line Timing</FormLabel>
1349
1270
  <FormControl>
1350
1271
  <Checkbox
1351
1272
  data-testid="line-timing-checkbox"
@@ -1371,9 +1292,7 @@ export const UserConfigForm: React.FC = () => {
1371
1292
  };
1372
1293
 
1373
1294
  const configMessage = (
1374
- <p className="text-muted-secondary">
1375
- User configuration is stored in <Kbd className="inline">marimo.toml</Kbd>
1376
- <br />
1295
+ <p className="text-muted-foreground">
1377
1296
  Run <Kbd className="inline">marimo config show</Kbd> in your terminal to
1378
1297
  show your current configuration and file location.
1379
1298
  </p>
@@ -1384,49 +1303,47 @@ export const UserConfigForm: React.FC = () => {
1384
1303
  <form
1385
1304
  ref={formElement}
1386
1305
  onChange={form.handleSubmit((values) => onSubmit(values))}
1387
- className="flex text-pretty overflow-hidden"
1306
+ className="user-config-form flex min-h-0 flex-1 text-sm overflow-hidden"
1388
1307
  >
1389
1308
  <Tabs
1390
1309
  value={activeCategory}
1391
1310
  onValueChange={(value) =>
1392
1311
  setActiveCategory(value as SettingCategoryId)
1393
1312
  }
1394
- orientation="vertical"
1395
- className="w-1/3 border-r h-full overflow-auto p-3"
1313
+ orientation={isWideLayout ? "vertical" : "horizontal"}
1314
+ className="flex min-h-0 min-w-0 flex-1 flex-col sm:flex-row"
1396
1315
  >
1397
- <TabsList className="self-start max-h-none flex flex-col gap-2 shrink-0 bg-background flex-1 min-h-full">
1398
- {categories.map((category) => (
1399
- <TabsTrigger
1400
- key={category.id}
1401
- value={category.id}
1402
- className="w-full text-left p-2 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground justify-start"
1403
- >
1404
- <div className="flex gap-4 items-center text-lg overflow-hidden">
1405
- <span
1406
- className={cn(
1407
- category.className,
1408
- "w-8 h-8 rounded flex items-center justify-center text-muted-foreground shrink-0",
1409
- )}
1410
- >
1411
- <category.Icon className="w-4 h-4" />
1412
- </span>
1413
- <span className="truncate">{category.label}</span>
1414
- </div>
1415
- </TabsTrigger>
1416
- ))}
1417
-
1418
- <div className="p-2 text-xs text-muted-foreground self-start flex flex-col gap-1">
1419
- <span>Version: {marimoVersion}</span>
1420
- <span>Locale: {locale}</span>
1316
+ <aside className="flex shrink-0 flex-col border-b bg-muted/20 p-3 sm:w-52 sm:overflow-y-auto sm:border-b-0 sm:border-r">
1317
+ <TabsList
1318
+ aria-label="Settings categories"
1319
+ className="max-h-none justify-start gap-1 overflow-x-auto rounded-none bg-transparent p-0 sm:flex-col sm:items-stretch"
1320
+ >
1321
+ {categories.map((category) => (
1322
+ <TabsTrigger
1323
+ key={category.id}
1324
+ value={category.id}
1325
+ className="justify-start px-3 py-2 text-left font-normal hover:bg-muted/60 hover:text-foreground data-[state=active]:bg-muted data-[state=active]:font-medium data-[state=active]:shadow-none"
1326
+ >
1327
+ {category.label}
1328
+ </TabsTrigger>
1329
+ ))}
1330
+ </TabsList>
1331
+ <div className="mt-auto hidden pt-6 px-3 text-xs leading-relaxed text-muted-foreground sm:flex sm:flex-col sm:gap-3">
1332
+ {!isWasm() && configMessage}
1333
+ <div>
1334
+ <div>Version: {marimoVersion}</div>
1335
+ <div>Locale: {locale}</div>
1336
+ </div>
1421
1337
  </div>
1422
-
1423
- <div className="flex-1" />
1424
- {!isWasm() && configMessage}
1425
- </TabsList>
1338
+ </aside>
1339
+ <TabsContent
1340
+ key={activeCategory}
1341
+ value={activeCategory}
1342
+ className="settings-content m-0 min-h-0 min-w-0 flex-1 overflow-auto p-5 sm:p-6"
1343
+ >
1344
+ <div className="flex flex-col gap-6">{renderBody()}</div>
1345
+ </TabsContent>
1426
1346
  </Tabs>
1427
- <div className="w-2/3 pl-6 gap-2 flex flex-col overflow-auto p-6">
1428
- {renderBody()}
1429
- </div>
1430
1347
  </form>
1431
1348
  </Form>
1432
1349
  );